[LIBDCE] Mutual exclusion of Engine_open and Engine_close
authorSaurabh Bipin Chandra <a0131926@ti.com>
Tue, 3 Sep 2013 09:50:45 +0000 (15:20 +0530)
committerSaurabh Bipin Chandra <a0131926@ti.com>
Thu, 5 Sep 2013 15:47:20 +0000 (21:17 +0530)
This patch uses semaphores to mutually exclude:
1. dce_init() and Engine_open() IPU call.
   This solves a hang on IPU side during multiple
   instances.
   pthread mutex used within dce_init is replaced with
   semaphores as mutex is valid only across
   threads and not processes.
2. dce_deinit() and Engine_close().
   This solves a hang on IPU side during multiple
   instances.

Change-Id: Ia4d31582ebf0536142dee389e9601eae0169fb22
Signed-off-by: Saurabh Bipin Chandra <a0131926@ti.com>
libdce.c
libdce.h

index cd10b71c2936dbd081538f14f2e5238c0ba24155..f791e18cc13a9d8630de6a7818ae6e24c4124302 100644 (file)
--- a/libdce.c
+++ b/libdce.c
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include <pthread.h>
 #include <errno.h>
+#include <fcntl.h>        /* For O_* constants */
+#include <sys/stat.h>     /* For mode constants */
+#include <semaphore.h>
 
 #include <xdc/std.h>
 
@@ -84,7 +86,7 @@
 /********************* GLOBALS ***********************/
 /* Hande used for Remote Communication                               */
 static MmRpc_Handle       MmRpcHandle = NULL;
-static pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;
+sem_t                    *dce_semaphore = NULL;
 static int                count = 0;
 
 
@@ -157,8 +159,6 @@ static int dce_ipc_init(void)
 
     printf(" >> dce_ipc_init\n");
 
-    pthread_mutex_lock(&mutex);
-
     count++;
     /* Check if already Initialized */
     _ASSERT(count == 1, DCE_EOK);
@@ -173,7 +173,6 @@ static int dce_ipc_init(void)
     printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
 
 EXIT:
-    pthread_mutex_unlock(&mutex);
     return (eError);
 }
 
@@ -183,8 +182,6 @@ EXIT:
  */
 static void dce_ipc_deinit()
 {
-    pthread_mutex_lock(&mutex);
-
     count--;
     if( count > 0 ) {
         goto EXIT;
@@ -196,7 +193,6 @@ static void dce_ipc_deinit()
     MmRpcHandle = NULL;
 
 EXIT:
-    pthread_mutex_unlock(&mutex);
     return;
 }
 
@@ -219,6 +215,12 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
 
     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
 
+    if( dce_semaphore == NULL ) {
+        _ASSERT((dce_semaphore = sem_open("/dce_semaphore", O_CREAT, S_IRWXU | S_IRWXO | S_IRWXG, 1)) != SEM_FAILED, DCE_ESEMAPHORE_FAIL);
+    }
+    /* Lock dce_ipc_init() and Engine_open() IPU call to prevent hang*/
+    _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
+
     /* Initialize IPC. In case of Error Deinitialize them */
     _ASSERT_AND_EXECUTE(dce_ipc_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_ipc_deinit());
 
@@ -252,7 +254,11 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
     if( ec ) {
         *ec = engine_open_msg->error_code;
     }
+
 EXIT:
+    /* Unlock dce_ipc_init() and Engine_open() IPU call */
+    _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
+
     memplugin_free(engine_open_msg, TILER_1D_BUFFER);
     if( engine_attrs ) {
         memplugin_free(engine_attrs, TILER_1D_BUFFER);
@@ -273,6 +279,9 @@ Void Engine_close(Engine_Handle engine)
 
     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
 
+    /* Lock dce_ipc_deinit() and Engine_close() IPU call */
+    _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
+
     /* Marshall function arguments into the send buffer */
     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
     Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine);
@@ -284,6 +293,11 @@ Void Engine_close(Engine_Handle engine)
 
 EXIT:
     dce_ipc_deinit();
+
+    /* Unlock dce_ipc_deinit() and Engine_close() IPU call */
+    _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
+    sem_close(dce_semaphore);
+
     return;
 }
 
index 5d4ffa85dc538a97ff926bb406f41004afb1eb71..b008e2891600a85765013d15849ab17e45a51971 100644 (file)
--- a/libdce.h
+++ b/libdce.h
@@ -54,7 +54,8 @@ typedef enum dce_error_status {
     DCE_EIPC_CREATE_FAIL = -4,
     DCE_EIPC_CALL_FAIL = -5,
     DCE_EINVALID_INPUT = -6,
-    DCE_EOMAPDRM_FAIL = -7
+    DCE_EOMAPDRM_FAIL = -7,
+    DCE_ESEMAPHORE_FAIL = -8
 } dce_error_status;