summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPradeep Venkatasubbarao2014-09-10 03:19:51 -0500
committerPradeep Venkatasubbarao2014-09-15 22:21:03 -0500
commita3d80923055402a339464292746908967c72bb07 (patch)
tree55abb228fb00d4168518a63fd9b286b41555a361
parent1916cfef94c4ee41c2beedc9cd87b8916ad29895 (diff)
downloadrepo-libdce-a3d80923055402a339464292746908967c72bb07.tar.gz
repo-libdce-a3d80923055402a339464292746908967c72bb07.tar.xz
repo-libdce-a3d80923055402a339464292746908967c72bb07.zip
Fix multi threaded logic for client indexing
Client count was being used for indexing into an empty slot in table holding clients' engine handles. In the case of multi-threaded scenario, there is a possibility of out of order creation and deletions of clients in which case the client indexing should search for an empty slot in the table rather than assuming that the index defined by number of clients points to an empty slot in the table. This patch fixes this issue by decoupling client count from table indexing. Now the table indexing is done by finding the empty slot identified by a '0' in the entry. This also forces filling '0' during client deletion which is also taken care of in the patch. Change-Id: I3d4c8d744c3912a6fae5809f445039d39b762f91 Signed-off-by: Pradeep Venkatasubbarao <pradeepv@ti.com>
-rw-r--r--libdce.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/libdce.c b/libdce.c
index 7f15344..2d12c20 100644
--- a/libdce.c
+++ b/libdce.c
@@ -37,7 +37,7 @@
37#include <errno.h> 37#include <errno.h>
38 38
39/* IPC Headers */ 39/* IPC Headers */
40#include <MmRpc.h> 40#include <ti/ipc/mm/MmRpc.h>
41 41
42/* DCE Headers */ 42/* DCE Headers */
43#include "libdce.h" 43#include "libdce.h"
@@ -121,17 +121,22 @@ static int __inline getCoreIndexFromCodec(int codec_id)
121 return INVALID_CORE; 121 return INVALID_CORE;
122} 122}
123 123
124static int __inline getCoreIndexFromEngine(Engine_Handle engine) 124static int __inline getCoreIndexFromEngine(Engine_Handle engine, int *tabIdx)
125{ 125{
126 int i; 126 int i;
127 int core = INVALID_CORE; 127 int core = INVALID_CORE;
128 128
129
130 *tabIdx = -1;
131
129 for(i = 0; i < MAX_INSTANCES ; i++) { 132 for(i = 0; i < MAX_INSTANCES ; i++) {
130 if(engine == gEngineHandle[i][IPU]) { 133 if(engine == gEngineHandle[i][IPU]) {
131 core = IPU; 134 core = IPU;
135 *tabIdx = i;
132 break; 136 break;
133 } 137 }
134 else if(engine == gEngineHandle[i][DSP]) { 138 else if(engine == gEngineHandle[i][DSP]) {
139 *tabIdx = i;
135 core = DSP; 140 core = DSP;
136 break; 141 break;
137 } 142 }
@@ -195,13 +200,18 @@ EXIT:
195/** dce_ipc_deinit : DeInitialize MmRpc. This function is called within 200/** dce_ipc_deinit : DeInitialize MmRpc. This function is called within
196 * Engine_close(). 201 * Engine_close().
197 */ 202 */
198static void dce_ipc_deinit(int core) 203static void dce_ipc_deinit(int core, int tableIdx)
199{ 204{
205 /*
206 There is no need to validate tableIdx as tableIdx is guaranteed to have
207 valid value when core is valid. core is already validated before coming here.
208 */
200 if(__ClientCount[core] == 0) { 209 if(__ClientCount[core] == 0) {
201 DEBUG("Nothing to be done: a spurious call\n"); 210 DEBUG("Nothing to be done: a spurious call\n");
202 return; 211 return;
203 } 212 }
204 __ClientCount[core]--; 213 __ClientCount[core]--;
214 gEngineHandle[tableIdx][core] = 0;
205 if( __ClientCount[core] > 0 ) { 215 if( __ClientCount[core] > 0 ) {
206 goto EXIT; 216 goto EXIT;
207 } 217 }
@@ -215,6 +225,21 @@ EXIT:
215 return; 225 return;
216} 226}
217 227
228static inline int update_clients_table(Engine_Handle engine, int core)
229{
230 int i;
231 for(i = 0; i < MAX_INSTANCES; i++)
232 {
233 if(gEngineHandle[i][core] == 0) {
234 gEngineHandle[i][core] = engine;
235 return i;
236 }
237 }
238 return -1;
239}
240
241
242
218/*===============================================================*/ 243/*===============================================================*/
219/** Engine_open : Open Codec Engine. 244/** Engine_open : Open Codec Engine.
220 * 245 *
@@ -232,6 +257,7 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
232 Engine_Attrs *engine_attrs = NULL; 257 Engine_Attrs *engine_attrs = NULL;
233 Engine_Handle engine_handle = NULL; 258 Engine_Handle engine_handle = NULL;
234 int coreIdx = INVALID_CORE; 259 int coreIdx = INVALID_CORE;
260 int tabIdx = -1;
235 261
236 262
237 /*Acquire permission to use IPC*/ 263 /*Acquire permission to use IPC*/
@@ -267,14 +293,16 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
267 293
268 /* Invoke the Remote function through MmRpc */ 294 /* Invoke the Remote function through MmRpc */
269 eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, (int32_t *)(&engine_handle)); 295 eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, (int32_t *)(&engine_handle));
270 gEngineHandle[__ClientCount[coreIdx] - 1][coreIdx] = engine_handle;
271
272 /* In case of Error, the Application will get a NULL Engine Handle */
273 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL);
274 296
275 if( ec ) { 297 if( ec ) {
276 *ec = engine_open_msg->error_code; 298 *ec = engine_open_msg->error_code;
277 } 299 }
300 /* In case of Error, the Application will get a NULL Engine Handle */
301 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL);
302
303 /*Update table*/
304 tabIdx = update_clients_table(engine_handle, coreIdx);
305 _ASSERT((tabIdx != -1), DCE_EINVALID_INPUT);
278 306
279EXIT: 307EXIT:
280 memplugin_free(engine_open_msg); 308 memplugin_free(engine_open_msg);
@@ -299,6 +327,7 @@ Void Engine_close(Engine_Handle engine)
299 int32_t fxnRet; 327 int32_t fxnRet;
300 dce_error_status eError = DCE_EOK; 328 dce_error_status eError = DCE_EOK;
301 int32_t coreIdx = INVALID_CORE; 329 int32_t coreIdx = INVALID_CORE;
330 int tableIdx = -1;
302 331
303 332
304 /*Acquire permission to use IPC*/ 333 /*Acquire permission to use IPC*/
@@ -310,7 +339,7 @@ Void Engine_close(Engine_Handle engine)
310 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL); 339 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
311 Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine); 340 Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine);
312 341
313 coreIdx = getCoreIndexFromEngine(engine); 342 coreIdx = getCoreIndexFromEngine(engine, &tableIdx);
314 _ASSERT(coreIdx != INVALID_CORE,DCE_EINVALID_INPUT); 343 _ASSERT(coreIdx != INVALID_CORE,DCE_EINVALID_INPUT);
315 344
316 /* Invoke the Remote function through MmRpc */ 345 /* Invoke the Remote function through MmRpc */
@@ -318,7 +347,8 @@ Void Engine_close(Engine_Handle engine)
318 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); 347 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
319 348
320EXIT: 349EXIT:
321 dce_ipc_deinit(coreIdx); 350 if(coreIdx != INVALID_CORE)
351 dce_ipc_deinit(coreIdx, tableIdx);
322 352
323 /*Relinquish IPC*/ 353 /*Relinquish IPC*/
324 pthread_mutex_unlock(&ipc_mutex); 354 pthread_mutex_unlock(&ipc_mutex);