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