1 #include "MsTypes.h"
2 #include "utopia_private.h"
3 #include <stdlib.h>
4 #include "MsOS.h"
5 #include <stdio.h>
6 #include "utopia.h"
7 #include <string.h>
8 #include "utopia_dapi.h"
9
10 #define PRINT_DEBUG_INFO 0
11 #if PRINT_DEBUG_INFO
12 #define PRINT_INFO(fmt, args...) printf("[Utopia Info]" fmt, ## args)
13 #else
14 #define PRINT_INFO(fmt, args...)
15 #endif
16
17 // length should be the same to definition
18 extern char moduleNames[][40];
19 extern char rpoolNames[][40];
20 extern char ResourceNames[][40];
21
22 struct shm_info {
23 void* va;
24 char name[40]; // FIXME: array length should be unify
25 };
26
27 /*
28 * could be equal to MAX_CLIENT_NUM=32 defined in MsOS_eCos.c
29 * cause we ues shm id as table index, there may be holes in the table
30 */
31 #define SHM_INFO_TABLE_LENGTH 200
32 struct shm_info shm_info_table[SHM_INFO_TABLE_LENGTH] = {{NULL, ""}};
33
34 extern UTOPIA_PRIVATE* psUtopiaPrivate;
35
36 //############################
37 //## Static Functions Start ##
38 //############################
39 enum eObjectType
40 {
41 E_TYPE_INSTANCE,
42 E_TYPE_MODULE,
43 E_TYPE_MODULE_SHM,
44 E_TYPE_RESOURCE_POOL,
45 E_TYPE_RESOURCE,
46 };
47
obtain_sem(MS_U32 u32SemID)48 static void obtain_sem(MS_U32 u32SemID)
49 {
50 /* Perform down operation */
51 MsOS_ObtainSemaphore(u32SemID, MSOS_WAIT_FOREVER);
52 }
53
release_sem(MS_U32 u32SemID)54 static void release_sem(MS_U32 u32SemID)
55 {
56 /* Perform down operation */
57 MsOS_ReleaseSemaphore(u32SemID);
58 }
59
60
shmid2va(MS_U32 u32ShmID)61 static inline void* shmid2va(MS_U32 u32ShmID)
62 {
63 if (u32ShmID == 0xFFFFFFFF)
64 return NULL;
65 return shm_info_table[u32ShmID].va;
66 }
67
isFirstCreation(void * pUnknown,enum eObjectType eObjectType)68 static inline int isFirstCreation(void* pUnknown, enum eObjectType eObjectType)
69 {
70 switch(eObjectType)
71 {
72 case E_TYPE_MODULE_SHM:
73 return TO_MODULE_SHM_PTR(pUnknown)->shmid_self.ID == 0;
74 case E_TYPE_RESOURCE:
75 return TO_RESOURCE_PTR(pUnknown)->shmid_self.ID == 0;
76 case E_TYPE_RESOURCE_POOL:
77 return TO_RPOOL_PTR(pUnknown)->shmid_self.ID == 0;
78 default:
79 printf("[utopia error] type is not supported\n");
80 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
81 }
82 }
83
84 /*
85 * u32ShmSize: user specified shared memory size
86 * shmName: user specified shared memory name
87 * p32RetShmID: for returning shared memory id
88 * return: shared memory address in virtual
89 */
shm_malloc(MS_U32 u32ShmSize,char * shmName,MS_U32 * pu32RetShmID)90 static void* shm_malloc(MS_U32 u32ShmSize, char* shmName, MS_U32* pu32RetShmID)
91 {
92 MS_U32 u32RetShmID=0, u32RetAddr=0, u32RetShmSize=0;
93 MS_U32 u32Ret;
94
95 /* check param. */
96 if (strcmp(shmName, "") == 0)
97 {
98 printf("shmem name string should not be empty\n");
99 while(1);
100 }
101
102 /*
103 * u32Ret: 0 for not found
104 * 1 for existence
105 * u32RetShmID: 0 for not found(original value)
106 * n for created share mem id, start from 1
107 */
108 u32Ret = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
109
110 /*
111 * MsOS_SHM_GetId need to be called for each process
112 * to set up per-process shmid2va table
113 * it's ok for duplicated calls with same shmName
114 */
115 MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
116
117 /*
118 * check whether table limit is reached?
119 */
120 // shm_info_table is for the shm_id and shm_addr mapping
121 if(u32RetShmID >= SHM_INFO_TABLE_LENGTH)
122 {
123 printf("[%s error] returned shm id %d exceeds shm-info table length %d\n"
124 , __FUNCTION__, (int)u32RetShmID, SHM_INFO_TABLE_LENGTH);
125 while(1);
126 }
127 if(shm_info_table[u32RetShmID].va != NULL)
128 {
129 printf("error: register duplicated shared memory ID %d: %s@%p\n"
130 , (int)u32RetShmID, shm_info_table[u32RetShmID].name, shm_info_table[u32RetShmID].va);
131 while(1);
132 }
133 else
134 {
135 shm_info_table[u32RetShmID].va = (void*)u32RetAddr;
136 strncpy(shm_info_table[u32RetShmID].name, shmName, sizeof(shm_info_table[u32RetShmID].name)); // FIXME: potential bug
137 if(!(0 == strcmp(shm_info_table[u32RetShmID].name, shmName)))
138 {
139 printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __FUNCTION__, __LINE__);
140 while(1);
141 }
142 PRINT_INFO("shm_info_table[%d] = %s@%p\n", (int)u32RetShmID, shmName, (void*)u32RetAddr);
143 }
144
145 // u32Ret: TRUE for success, FALSE for failure
146 // if failure --> first time allocation, memset to 0
147 if(u32Ret != 1)
148 memset((void*)u32RetAddr, 0, u32RetShmSize);
149
150 *pu32RetShmID = u32RetShmID;
151 return (void*)u32RetAddr;
152 }
153
next_resource(void * pUnkown,enum eObjectType eObjectType)154 static UTOPIA_RESOURCE* next_resource(void* pUnkown, enum eObjectType eObjectType)
155 {
156 switch(eObjectType)
157 {
158 case E_TYPE_RESOURCE_POOL:
159 return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
160 case E_TYPE_RESOURCE:
161 return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
162 default:
163 printf("%s, %d, %s, [utopia error] type is not supported\n", __FUNCTION__, __LINE__, __FILE__);
164 RET_OR_BLOCK(NULL);
165 }
166 }
167
168 /* return located module address or NULL if not found */
locate_module(MS_U32 u32ModuleID)169 static void* locate_module(MS_U32 u32ModuleID)
170 {
171 UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
172
173 while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
174 pLocatedModule = pLocatedModule->psNext;
175
176 return pLocatedModule;
177 }
178
179 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
180 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
181 // case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
locate_resource_pool(UTOPIA_MODULE * pModule,MS_U32 u32LocatedRPoolID,UTOPIA_RESOURCE_POOL ** ppRPool,UTOPIA_RESOURCE_POOL ** ppRPoolPrev)182 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
183 , UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
184 {
185 UTOPIA_RESOURCE_POOL* pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
186 UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
187
188 while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
189 {
190 pRPoolPrev = pRPool;
191 pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
192 }
193
194 *ppRPool = pRPool;
195 *ppRPoolPrev = pRPoolPrev;
196 return 0;
197 }
198
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppResource,UTOPIA_RESOURCE ** ppResourcePrev)199 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool, MS_U32 u32LocatedResourceID
200 , UTOPIA_RESOURCE** ppResource, UTOPIA_RESOURCE** ppResourcePrev)
201 {
202 UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
203 UTOPIA_RESOURCE* pResourcePrev = NULL;
204
205 while (pResource != NULL && (pResource->shmid_self.ID != u32LocatedResourceID))
206 {
207 pResourcePrev = pResource;
208 pResource = TO_RESOURCE_PTR(shmid2va(pResource->shmid_next_resource.ID));
209 }
210
211 *ppResource = pResource;
212 *ppResourcePrev = pResourcePrev;
213 return 0;
214 }
215
check_rpool_semaphore(MS_U32 u32ModuleID)216 int check_rpool_semaphore(MS_U32 u32ModuleID)
217 {
218 /* locate target module in stupid way */
219 UTOPIA_MODULE* pModule = NULL;
220 pModule = psUtopiaPrivate->psModuleHead;
221 while (pModule != NULL && pModule->u32ModuleID != u32ModuleID)
222 {
223 pModule = pModule->psNext;
224 }
225
226 /* locate corresponding rpool in stupid way */
227 UTOPIA_RESOURCE_POOL* pRPool = NULL;
228 if (pModule != NULL) /* found */
229 {
230 pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
231 }
232 else
233 {
234 printf("[utopia error] module of u32ModuleID isn't found\n");
235 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
236 }
237
238 /* check rpool semaphore one by one */
239 while (pRPool != NULL)
240 {
241 if (!(pRPool->u32ResourcesSemaphore))
242 {
243 printf("[utopia error] resource pool %s has no semaphore\n", pRPool->shmid_self.name);
244 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
245 }
246 pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
247 }
248
249 return 0;
250 }
251 //##########################
252 //## Static Functions End ##
253 //##########################
254
255 //#############################
256 //## Instance Functions Start ##
257 //#############################
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)258 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
259 {
260 UTOPIA_INSTANCE* pInstance = NULL;
261
262 /* check param. */
263 if (ppInstance == NULL)
264 {
265 printf("[utopia error] instance ppointer should not be null\n");
266 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
267 }
268
269 pInstance = malloc(sizeof(UTOPIA_INSTANCE));
270 memset(pInstance, 0, sizeof(UTOPIA_INSTANCE));
271 pInstance->pPrivate = malloc(u32PrivateSize);
272 memset(pInstance->pPrivate, 0, u32PrivateSize);
273 PRINT_INFO("create instance at %p with private size %d bytes at %p\n" \
274 , pInstance, (int)u32PrivateSize, pInstance->pPrivate);
275
276 *ppInstance = pInstance;
277 return UTOPIA_STATUS_SUCCESS;
278 }
279
UtopiaInstanceDelete(void * pInstance)280 MS_U32 UtopiaInstanceDelete(void* pInstance)
281 {
282 free(TO_INSTANCE_PTR(pInstance)->pPrivate);
283 free(pInstance);
284
285 return UTOPIA_STATUS_SUCCESS;
286 }
287
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)288 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
289 {
290 /* check param. */
291 if (pInstance == NULL)
292 {
293 printf("[utopia error] instance pointer should not be null\n");
294 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
295 }
296 if (ppPrivate == NULL)
297 {
298 printf("[utopia error] private ppointer should not be null\n");
299 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
300 }
301
302 *ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
303 return UTOPIA_STATUS_SUCCESS;
304 }
305
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)306 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
307 {
308 /* check param. */
309 if (pInstance == NULL)
310 {
311 printf("[uopia error] instance pointer should not be null\n");
312 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
313 }
314 if (ppModule == NULL)
315 {
316 printf("[utopia error] module ppointer should not be null\n");
317 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
318 }
319
320 *ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
321 return UTOPIA_STATUS_SUCCESS;
322 }
323
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)324 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
325 {
326 *pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
327 return UTOPIA_STATUS_SUCCESS;
328 }
329
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)330 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
331 {
332 *pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
333 return UTOPIA_STATUS_SUCCESS;
334 }
335
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)336 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance, MS_U32* pu32ModuleVersion)
337 {
338 *pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
339 return UTOPIA_STATUS_SUCCESS;
340 }
341 //###########################
342 //## Instant Functions End ##
343 //###########################
344
345 //############################
346 //## Module Functions Start ##
347 //############################
348 // assume one module for each driver, otherwise they have to pass module name as parameter
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)349 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID, MS_U32 u32PrivateSize, void** ppModule)
350 {
351 MS_U32 u32ShmID;
352 UTOPIA_MODULE_SHM* pModuleShm = NULL;
353 UTOPIA_MODULE* pModule = NULL;
354 void* pPrivate = NULL;
355 char privateName[50]; // FIXME: potential bug
356
357 /* 1. create module@shm */
358 pModuleShm = shm_malloc(sizeof(UTOPIA_MODULE_SHM), moduleNames[u32ModuleID], &u32ShmID);
359 if (isFirstCreation(pModuleShm, E_TYPE_MODULE_SHM))
360 {
361 pModuleShm->shmid_self.ID = u32ShmID;
362 strcpy(pModuleShm->shmid_self.name, moduleNames[u32ModuleID]);
363 pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
364 }
365 PRINT_INFO("create module@shm %s at %p\n", moduleNames[u32ModuleID], pModuleShm);
366
367 /* 2. create module */
368 pModule = malloc(sizeof(UTOPIA_MODULE));
369 memset(pModule, 0, sizeof(UTOPIA_MODULE));
370 pModule->u32ModuleID = u32ModuleID;
371 pModule->psModuleShm = pModuleShm;
372 PRINT_INFO("create module %s at %p\n", moduleNames[u32ModuleID], pModule);
373
374 /* 3. create private of module */
375 sprintf(privateName, "%s_PRI", moduleNames[u32ModuleID]); // FIXME: potential bug
376 pPrivate = shm_malloc(u32PrivateSize, privateName, &(pModule->shmid_private.ID));
377 PRINT_INFO("create private of module %s at %p\n", privateName, pPrivate);
378
379 *ppModule = pModule;
380 return UTOPIA_STATUS_SUCCESS;
381 }
382
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)383 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
384 {
385 *ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
386 return UTOPIA_STATUS_SUCCESS;
387 }
388
UtopiaModuleRegister(void * pModuleTmp)389 MS_U32 UtopiaModuleRegister(void* pModuleTmp)
390 {
391 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
392 UTOPIA_MODULE* pLocatedModule = NULL;
393
394 /* check para. */
395 if (pModule == NULL)
396 {
397 printf("module pointer can't be null\n");
398 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
399 }
400
401 pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
402 if (pLocatedModule == NULL) /* module is not yet registered */
403 {
404 /* insert module into list head */
405 PRINT_INFO("register module: %s\n", moduleNames[pModule->u32ModuleID]);
406 pModule->psNext = psUtopiaPrivate->psModuleHead;
407 psUtopiaPrivate->psModuleHead = pModule;
408 return UTOPIA_STATUS_SUCCESS;
409 }
410 else /* module is already registered */
411 {
412 printf("error: register duplicated module: %s\n", moduleNames[pModule->u32ModuleID]);
413 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
414 }
415 }
416
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)417 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
418 {
419 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
420
421 PRINT_INFO("setup function pointers of module %s\n", moduleNames[pModule->u32ModuleID]);
422 pModule->fpOpen = fpOpen;
423 pModule->fpClose = fpClose;
424 pModule->fpIoctl = fpIoctl;
425
426 return UTOPIA_STATUS_SUCCESS;
427 }
428
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)429 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
430 {
431 TO_MODULE_PTR(pModule)->u32Version = u32Version;
432
433 return UTOPIA_STATUS_SUCCESS;
434 }
435
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)436 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
437 {
438 *pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
439 return UTOPIA_STATUS_SUCCESS;
440 }
441
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)442 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
443 {
444 *ppModule = locate_module(u32ModuleID);
445
446 return UTOPIA_STATUS_SUCCESS;
447 }
448 //##########################
449 //## Module Functions End ##
450 //##########################
451
452 //##############################
453 //## Resource Functions Start ##
454 //##############################
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)455 MS_U32 UtopiaResourceCreate(char* resourceName, MS_U32 u32PrivateSize, void** ppResource)
456 {
457 MS_U32 u32RetShmID;
458 UTOPIA_RESOURCE* pResource = NULL;
459 char privateName[50]; // FIXME: potential bug
460
461 /* 1. create resource */
462 PRINT_INFO("create resource %s\n", resourceName);
463 pResource = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName, &(u32RetShmID));
464 if (isFirstCreation(pResource, E_TYPE_RESOURCE))
465 {
466 pResource->shmid_self.ID = u32RetShmID;
467 pResource->shmid_next_resource.ID = 0xFFFFFFFF;
468 }
469 *ppResource = pResource;
470
471 /* 2. create resource private */
472 sprintf(privateName, "%s_PRI", resourceName); // FIXME: potential bug
473 PRINT_INFO("create private %s of resource %s\n", privateName, resourceName);
474 shm_malloc(u32PrivateSize, privateName, &(pResource->shmid_private.ID));
475
476 return UTOPIA_STATUS_SUCCESS;
477 }
478
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)479 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
480 {
481 *ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
482 return 0;
483 }
484
485 // case 1: no resource pool -> create resource pool & attach resource to it. combine with case 2
486 // case 2: resource pool exists, but no mathcing resource pool -> create resource pool & attach resource to it. combine with case 1
487 // case 3: resource pool exists, and there's matching resource pool -> attach resource to it
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)488 MS_U32 UtopiaResourceRegister(void* pModuleTmp, void* pResourceTmp, MS_U32 u32RPoolID)
489 {
490 //lock(u32ResourcePoolsMutex)
491 //insert psResouce into psModuleNode->psResourcePoolHeads->psResourceHeads->psResource
492
493 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
494 UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
495 char rpoolName[50];
496
497 /* 1. deal with resource pool */
498 UTOPIA_RESOURCE_POOL* pRPool = NULL;
499 UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
500 locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
501
502 /* rpool semaphore has been created */
503 if (pRPool != NULL && pRPool->u32ResourcesSemaphore != 0) // if rpool semaphore has been created
504 {
505 printf("%s has already created semaphroe for %s\n", moduleNames[pModule->u32ModuleID], pRPool->shmid_self.name);
506 return UTOPIA_STATUS_FAIL;
507 }
508
509 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
510 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
511 // case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
512 if (pRPool == NULL) { // case 1 or 2
513 MS_U32 u32RetRPoolShmID;
514 MS_U32 u32ModuleID = pModule->u32ModuleID;
515
516 sprintf(rpoolName, "%s_%d", rpoolNames[u32ModuleID], (int)u32RPoolID);
517 pRPool = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName, &u32RetRPoolShmID);
518 if (isFirstCreation(pRPool, E_TYPE_RESOURCE_POOL))
519 {
520 pRPool->shmid_self.ID = u32RetRPoolShmID;
521 strncpy(pRPool->shmid_self.name, rpoolName, sizeof(pRPool->shmid_self.name)); // FIXME: potential bug
522 if(!(0 == strcmp(pRPool->shmid_self.name, rpoolName)))
523 {
524 printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __FUNCTION__, __LINE__);
525 while(1);
526 }
527 pRPool->u32PoolID = u32RPoolID;
528 pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
529 pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
530 pRPool->u32MutexID = MsOS_CreateMutex(E_MSOS_FIFO, rpoolName, MSOS_PROCESS_SHARED);
531 }
532 PRINT_INFO("create resource pool %s at %p\n", rpoolName, pRPool);
533 /* check param. */
534 if (pResource->shmid_rpool.ID != 0)
535 {
536 return UTOPIA_STATUS_SUCCESS;
537 }
538
539 /* set up connection */
540 if (pRPoolPrev == NULL) // case 1
541 {
542 pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
543 }
544 else /* case 2 */
545 {
546 pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
547 }
548
549 pModule->psModuleShm->u32ResourcePoolTotal++;
550 }
551
552 /* 2. deal with resource */
553 pResource->shmid_rpool = pRPool->shmid_self;
554
555 UTOPIA_RESOURCE* pLocatedResource = NULL;
556 UTOPIA_RESOURCE* pLocatedResourcePrev = NULL;
557 locate_resource(pRPool, pResource->shmid_self.ID, &pLocatedResource, &pLocatedResourcePrev);
558 // case 1: there's no resource in pool --> pLocatedResource = NULL, pLocatedResourcePrev = NULL
559 // case 2: at least one resource exists, but not the located one --> pLocatedResource = NULL, pLocatedResourcePrev != NULL
560 // case 3: at least one resource exists, and so is the located one --> pLocatedResource != NULL, pLocatedResourcePrev doesn't matter
561 if (pLocatedResource == NULL) // case 1 or 2
562 {
563 PRINT_INFO("register resource into pool %s\n", rpoolName);
564 if (pLocatedResourcePrev == NULL) // case 1
565 {
566 pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
567 }
568 else /* case 2 */
569 {
570 pLocatedResourcePrev->shmid_next_resource.ID = pResource->shmid_self.ID;
571 }
572 pRPool->u32ResourceTotal++;
573
574 return UTOPIA_STATUS_SUCCESS;
575 }
576 else /* case 3 */
577 {
578 /* duplicated registration: it may be registered by other process */
579 return UTOPIA_STATUS_FAIL;
580 }
581 }
582
UtopiaResourceTryObtain(void * pModuleTmp,MS_U32 u32RPoolID,void ** ppResource)583 MS_U32 UtopiaResourceTryObtain(void* pModuleTmp, MS_U32 u32RPoolID, void** ppResource)
584 {
585 //Search and get one resource from psModuleNode->psResourcePoolHeads
586 //set flag bit0 to 1 for using
587
588 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
589 UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
590 UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
591 UTOPIA_RESOURCE* pAvailResource = NULL;
592 locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
593
594 /* to avoid obtaining resource before UtopiaModuleAddResourceEnd() */
595 //check_rpool_semaphore(pModule->u32ModuleID);
596 if (!(pLocatedRPool->u32ResourceAvail))
597 return UTOPIA_STATUS_FAIL;
598 obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
599
600 pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
601 MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
602 while (pAvailResource != NULL)
603 {
604 if (!(pAvailResource->bInUse))
605 {
606 pAvailResource->bInUse = true;
607 *ppResource = pAvailResource;
608 pLocatedRPool->u32ResourceAvail--;
609 MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
610 return UTOPIA_STATUS_SUCCESS;
611 }
612 else
613 {
614 pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
615 }
616 }
617 MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
618
619 return UTOPIA_STATUS_FAIL;
620 }
621
UtopiaResourceObtain(void * pModTmp,MS_U32 u32RPoolID,void ** ppResource)622 MS_U32 UtopiaResourceObtain(void* pModTmp, MS_U32 u32RPoolID, void** ppResource)
623 {
624 //Search and get one resource from psModuleNode->psResourcePoolHeads
625 //set flag bit0 to 1 for using
626
627 /* check param. */
628 if (pModTmp == NULL)
629 {
630 printf("module pointer should not be null\n");
631 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
632 }
633 if (ppResource == NULL)
634 {
635 printf("resource ppointer should not be null\n");
636 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
637 }
638
639 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModTmp);
640 UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
641 UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
642 UTOPIA_RESOURCE* pAvailResource = NULL;
643 locate_resource_pool(pModule, u32RPoolID
644 , &pLocatedRPool, &pLocatedRPoolPrev);
645
646 // to avoid obtaining resource before UtopiaModuleAddResourceEnd()
647 PRINT_INFO("%s try to obtain %s semaphore\n", moduleNames[pModule->u32ModuleID], pLocatedRPool->shmid_self.name);
648 //check_rpool_semaphore(pModule->u32ModuleID);
649 obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
650
651 pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
652 MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
653 while (pAvailResource != NULL)
654 {
655 if (!(pAvailResource->bInUse))
656 {
657 pAvailResource->bInUse = true;
658 *ppResource = pAvailResource;
659 pLocatedRPool->u32ResourceAvail--;
660 MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
661 return UTOPIA_STATUS_SUCCESS;
662 }
663 else
664 {
665 pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
666 }
667 }
668 MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
669
670 return UTOPIA_STATUS_FAIL;
671 }
672
UtopiaResourceRelease(void * pResource)673 MS_U32 UtopiaResourceRelease(void* pResource)
674 {
675 UTOPIA_RESOURCE_POOL* pRPool = RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
676
677 // modify resource before releasing it, to avoid race condition
678 MsOS_ObtainMutex(pRPool->u32MutexID, MSOS_WAIT_FOREVER);
679 TO_RESOURCE_PTR(pResource)->bInUse = false;
680 pRPool->u32ResourceAvail++;
681 release_sem(pRPool->u32ResourcesSemaphore);
682 MsOS_ReleaseMutex(pRPool->u32MutexID);
683
684 return UTOPIA_STATUS_SUCCESS;
685 }
686
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)687 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
688 {
689 return UTOPIA_STATUS_SUCCESS;
690 }
691
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)692 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
693 {
694 int u32SemaphoreID;
695 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
696
697 UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
698 UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
699 locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
700
701 /* Check RPool Semaphore ID*/
702 if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
703 {
704 printf("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
705 return UTOPIA_STATUS_FAIL;
706 }
707
708 /* Create RPOOL Semaphore */
709 u32SemaphoreID = MsOS_CreateSemaphore(pLocatedRPool->u32ResourceTotal, E_MSOS_FIFO , "dont care");
710 if (u32SemaphoreID < 0)
711 {
712 printf("[utopia error] create semaphore fail\n");
713 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
714 }
715 pLocatedRPool->u32ResourceAvail = pLocatedRPool->u32ResourceTotal;
716
717 pLocatedRPool->u32ResourcesSemaphore = u32SemaphoreID;
718 return UTOPIA_STATUS_SUCCESS;
719 }
720 //############################
721 //## Resource Functions End ##
722 //############################
723
724 #if 0
725
726 UTOPIA_HIBERNATE_HEADER* pHibernateHeaderStartVA=NULL;
727 UTOPIA_HIBERNATE_BLOCK* pHibernateBlockStartVA=NULL;
728 MS_U32 u32HibernateMaxBlock=0;
729 MS_U32 u32HibernateHeaderSizeTotal = 0;
730 MS_U32 u32HibernateBlockSizeTotal = 0;
731 MS_U32 u32HibernateCurrentBlkNum = 0;
732 MS_U32 u32HibernateCurrentFileNum = 0;
733 MS_BOOL bHibernateInit=false;
734
735
736 MS_U32 _serch_empyblock(void)
737 {
738 UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA;
739 MS_U32 ret = 0;
740 MS_U32 u32Count=0;
741 while(pBlockVA->u32NextBlock != 0x0 && u32Count <= u32HibernateMaxBlock )
742 {
743 u32Count+=1;
744 pBlockVA = pHibernateBlockStartVA + sizeof(UTOPIA_HIBERNATE_BLOCK)*u32Count;
745
746 }
747
748 if(u32Count == u32HibernateMaxBlock)
749 ret = u32HibernateMaxBlock;
750
751 return ret;
752 }
753
754
755 void _EndOfFile(MS_U32 u32BlockNum)
756 {
757 UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
758 pBlockVA->u32NextBlock = END_OF_BLOCK_LINKLIST;
759 }
760
761
762
763 MS_U32 UtopiaHibernateInit(MS_U8 u8MiuSel,MS_U32 pBAddrMem,MS_U32 u32size,MS_BOOL bFormat) //return: Sucessed
764 {
765
766
767
768 if(MsOS_MPool_Mapping(u8MiuSel, pBAddrMem, u32size, 0) == false)
769 {
770 printf("[%s] MsOS_MPool_Mapping fail\n",__FUNCTION__);
771 return false;
772 }
773
774 u32HibernateHeaderSizeTotal = sizeof(UTOPIA_HIBERNATE_HEADER)*MAX_FILE_NUM;
775
776 if(u32HibernateHeaderSizeTotal>u32size)
777 {
778 return UTOPIA_STATUS_FAIL;
779 }
780
781
782
783 u32HibernateBlockSizeTotal = u32size - u32HibernateHeaderSizeTotal;
784 u32HibernateMaxBlock = u32HibernateBlockSizeTotal/BLOCK_SIZE;
785
786 pHibernateHeaderStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem);
787 pHibernateBlockStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem+u32HibernateHeaderSizeTotal);
788
789 if(bFormat)
790 {
791 memset(pHibernateHeaderStartVA,u32size,0);
792 }
793
794 bHibernateInit=UTOPIA_STATUS_SUCCESS;
795 return UTOPIA_STATUS_SUCCESS;
796
797
798 }
799
800
801
802 MS_U32 UtopiaHibernateCreate(char* hibernateName) //return: Sucessed
803 {
804 UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
805 MS_U32 ret = UTOPIA_STATUS_FAIL;
806 MS_U32 u32CountTmp=0;
807
808 if(pHibernateHeaderStartVA == NULL)
809 return ret;
810
811 for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
812 {
813 TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
814 if(TEMPaa->u32HibernateFileExist != 0x0)
815 {
816 if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
817 ret = UTOPIA_STATUS_SHM_EXIST ;
818 break;
819 }else
820 {
821 TEMPaa->u32HibernateFileExist=0x1;
822 strcpy(TEMPaa->HibernateName,hibernateName);
823 //TEMPaa->u32FirstBlock= _serch_empyblock();
824 u32HibernateCurrentFileNum = u32HibernateCurrentFileNum +1;
825 ret = UTOPIA_STATUS_SUCCESS ;
826 break;
827 }
828 }
829
830 return ret;
831
832
833 }
834
835
836 MS_U32 UtopiaHibernateOpen(char* hibernateName)//return: ID
837 { MS_U32 ret = -1;
838 UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
839 MS_U32 u32CountTmp=0;
840
841 if(pHibernateHeaderStartVA == NULL )
842 return ret;
843
844 for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
845 {
846 TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
847 if(TEMPaa->u32HibernateFileExist != 0x0)
848 {
849 if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
850 {
851 TEMPaa->bUSE=1;
852 ret = u32CountTmp;
853 }
854 }else
855 break;
856 }
857
858 return ret;
859
860
861 }
862
863
864 MS_U32 UtopiaHibernateWrite(MS_U32 FILEid, void* buff, MS_U32 size) //return: size
865 {
866 MS_U32 ret=0;
867 UTOPIA_HIBERNATE_HEADER* TEMPaa = NULL;
868 UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
869 MS_U32 u32BlockNum=0;
870 void* pTemBuff = buff;
871 //MS_U32 u32NextBlockNum=0;
872 //MS_U32 u32writeCount=size;
873 //MS_U8 u8ArrayBlockContact[BLOCK_CONTACT_SIZE] = {0};
874
875 MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
876 MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
877
878 TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;;
879
880 if(TEMPaa->bUSE ==0 || bHibernateInit == false || size==0)
881 return ret;
882
883 if((u32HibernateMaxBlock-u32HibernateCurrentFileNum) < u32BlockNumOfFile)
884 return ret;
885
886
887 TEMPaa->u32FirstBlock=_serch_empyblock();
888 u32BlockNum = TEMPaa->u32FirstBlock;
889
890 TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
891
892 // u32BlockNum
893 while(u32BlockNumOfFile>0)
894 {
895 // u32BlockNum = _serch_empyblock();
896 if(u32BlockNum>=u32HibernateMaxBlock)
897 break;
898 pTemBuff = (void*)((MS_U32)pTemBuff +ret);
899 memcpy((void*)TEMPBLKaa->u8File,pTemBuff,BLOCK_CONTACT_SIZE);
900 _EndOfFile(u32BlockNum);
901 ret = ret+BLOCK_CONTACT_SIZE;
902 u32BlockNumOfFile=u32BlockNumOfFile-1;
903
904 if(u32BlockNumOfFile==0)
905 break;
906
907 u32BlockNum = _serch_empyblock();
908 TEMPBLKaa->u32NextBlock = u32BlockNum;
909 TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
910
911 }
912
913
914
915
916
917 if(u32RemanderOfFile > 0)
918 {
919 u32BlockNum = _serch_empyblock();
920 TEMPBLKaa->u32NextBlock = u32BlockNum;
921 TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
922
923 pTemBuff = (void*)((MS_U32)pTemBuff +ret);
924 memcpy((void*)TEMPBLKaa->u8File,pTemBuff,u32RemanderOfFile);
925 _EndOfFile(u32BlockNum);
926 ret+=u32RemanderOfFile;
927 }
928
929 return ret;
930
931 }
932
933
934 MS_U32 UtopiaHibernateRead(MS_U32 FILEid,void* buff , MS_U32 size) ////return: size
935 {
936 MS_U32 ret=0;
937 UTOPIA_HIBERNATE_HEADER* TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;
938 UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
939 //MS_U32 u32writeCount=size;
940 MS_U32 u32BlockNum=0;
941
942 MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
943 MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
944
945 void* pTemBuff = buff;
946
947
948 if(TEMPaa->bUSE ==0)
949 return ret;
950
951 if(u32RemanderOfFile>0)
952 u32BlockNumOfFile = u32BlockNumOfFile + 1;
953
954
955 u32BlockNum = TEMPaa->u32FirstBlock;
956 TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
957
958 while((TEMPBLKaa->u32NextBlock != 0) && (u32BlockNumOfFile > 0))
959 {
960 if(TEMPBLKaa->u32NextBlock ==END_OF_BLOCK_LINKLIST )
961 {
962 pTemBuff = (void*)((MS_U32)pTemBuff +ret);
963 if(u32RemanderOfFile == 0)
964 {
965 memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
966 ret = ret + BLOCK_CONTACT_SIZE;
967 }
968 else
969 {
970 memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,u32RemanderOfFile);
971 ret = ret + u32RemanderOfFile;
972 }
973
974 u32BlockNumOfFile = u32BlockNumOfFile -1;
975
976
977
978 }else
979 {
980 pTemBuff = (void*)((MS_U32)pTemBuff +ret);
981 memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
982 ret = ret + BLOCK_CONTACT_SIZE;
983 u32BlockNumOfFile = u32BlockNumOfFile -1;
984 u32BlockNum = TEMPBLKaa->u32NextBlock;
985 TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
986
987 }
988 }
989
990
991
992 return ret;
993
994
995 }
996
997 #endif
998