diff options
author | Pradeep Venkatasubbarao | 2014-09-10 03:19:51 -0500 |
---|---|---|
committer | Pradeep Venkatasubbarao | 2014-09-15 22:21:03 -0500 |
commit | a3d80923055402a339464292746908967c72bb07 (patch) | |
tree | 55abb228fb00d4168518a63fd9b286b41555a361 | |
parent | 1916cfef94c4ee41c2beedc9cd87b8916ad29895 (diff) | |
download | repo-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.c | 48 |
1 files changed, 39 insertions, 9 deletions
@@ -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 | ||
124 | static int __inline getCoreIndexFromEngine(Engine_Handle engine) | 124 | static 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 | */ |
198 | static void dce_ipc_deinit(int core) | 203 | static 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 | ||
228 | static 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 | ||
279 | EXIT: | 307 | EXIT: |
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 | ||
320 | EXIT: | 349 | EXIT: |
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); |