memPartLib.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. * memPartLib.c
  3. *
  4. * We undefine the public functions
  5. * (just in case they've been MACRO overriden
  6. */
  7. #undef free
  8. #undef malloc
  9. #undef memAddToPool
  10. #undef memPartAddToPool
  11. #undef memPartAlignedAlloc
  12. #undef memPartAlloc
  13. #undef memPartBlockIsValid
  14. #undef memPartCreate
  15. #undef memPartFree
  16. #undef memPartInit
  17. #undef memPartLibInit
  18. #include <string.h>
  19. #include <memPartLib.h>
  20. #define __PROTOTYPE_5_0
  21. #include <semLib.h>
  22. #include <logLib.h>
  23. #include <taskLib.h>
  24. #include "private.h"
  25. /* partition used for the system heap */
  26. static partition_t memSysPartition;
  27. /* this must be assigned at initialisation as clients classes can be
  28. * initialised before the memory library, and require the value of this
  29. * to be set (even though they don't use the pool at that point)
  30. */
  31. PART_ID memSysPartId = (PART_ID)&memSysPartition;
  32. static int memPartLibInstalled;
  33. static OBJ_CLASS memPartClass;
  34. CLASS_ID memPartClassId = &memPartClass;
  35. static OBJ_CLASS memPartInstrClass;
  36. CLASS_ID memPartInstClassId = &memPartInstrClass;
  37. unsigned memPartOptionsDefault =
  38. (MEM_BLOCK_CHECK | MEM_ALLOC_ERROR_LOG_FLAG | MEM_BLOCK_ERROR_LOG_FLAG);
  39. /*-------------------------------------------------------- */
  40. static void
  41. memPartAllocError(partition_t *this,
  42. const char *where,
  43. size_t size)
  44. {
  45. logMsg("%s: block too big - %d in partition %#x\n",
  46. where,
  47. size,
  48. this);
  49. }
  50. /*-------------------------------------------------------- */
  51. static void
  52. memPartBlockError(partition_t *this,
  53. const char *where,
  54. void *block)
  55. {
  56. logMsg("%s: invalid block %#x in partition %#x\n",
  57. where,
  58. block,
  59. this);
  60. }
  61. /*-------------------------------------------------------- */
  62. void
  63. lubheap_vxworks_check_status(partition_t *this,
  64. lub_heap_status_t status,
  65. const char *where,
  66. void *block,
  67. size_t size)
  68. {
  69. switch(status)
  70. {
  71. /*------------------------------------------------- */
  72. case LUB_HEAP_CORRUPTED:
  73. case LUB_HEAP_INVALID_POINTER:
  74. case LUB_HEAP_DOUBLE_FREE:
  75. {
  76. if(this->options & MEM_BLOCK_CHECK)
  77. {
  78. if(this->options & MEM_BLOCK_ERROR_LOG_FLAG)
  79. {
  80. memPartBlockError(this,where,block);
  81. }
  82. if(this->options & MEM_BLOCK_ERROR_SUSPEND_FLAG)
  83. {
  84. taskSuspend(taskIdSelf());
  85. }
  86. }
  87. break;
  88. }
  89. /*------------------------------------------------- */
  90. case LUB_HEAP_FAILED:
  91. {
  92. if(this->options & MEM_ALLOC_ERROR_LOG_FLAG)
  93. {
  94. memPartAllocError(this,where,size);
  95. }
  96. if(this->options & MEM_ALLOC_ERROR_SUSPEND_FLAG)
  97. {
  98. taskSuspend(taskIdSelf());
  99. }
  100. break;
  101. }
  102. /*------------------------------------------------- */
  103. case LUB_HEAP_OK:
  104. {
  105. break;
  106. }
  107. /*------------------------------------------------- */
  108. }
  109. }
  110. /*-------------------------------------------------------- */
  111. void
  112. free(void *ptr)
  113. {
  114. memPartFree(memSysPartId,ptr);
  115. }
  116. /*-------------------------------------------------------- */
  117. void *
  118. malloc(size_t nBytes)
  119. {
  120. return memPartAlloc(memSysPartId,nBytes);
  121. }
  122. /*-------------------------------------------------------- */
  123. void
  124. memAddToPool(char *pPool,
  125. unsigned poolSize)
  126. {
  127. memPartAddToPool(memSysPartId,pPool,poolSize);
  128. }
  129. /*-------------------------------------------------------- */
  130. STATUS
  131. memPartAddToPool(PART_ID partId,
  132. char *pPool,
  133. unsigned poolSize)
  134. {
  135. partition_t *this = (partition_t*)partId;
  136. semTake(&this->sem,WAIT_FOREVER);
  137. lub_heap_add_segment(this->heap,pPool,poolSize);
  138. semGive(&this->sem);
  139. return OK;
  140. }
  141. /*-------------------------------------------------------- */
  142. void *
  143. memPartAlignedAlloc(PART_ID partId,
  144. unsigned nBytes,
  145. unsigned alignment)
  146. {
  147. partition_t *this = (partition_t*)partId;
  148. char *ptr = NULL;
  149. lub_heap_status_t status = LUB_HEAP_OK;
  150. lub_heap_align_t align = LUB_HEAP_ALIGN_NATIVE;
  151. switch(alignment)
  152. {
  153. case 4: align = LUB_HEAP_ALIGN_2_POWER_2; break;
  154. case 8: align = LUB_HEAP_ALIGN_2_POWER_3; break;
  155. case 16: align = LUB_HEAP_ALIGN_2_POWER_4; break;
  156. case 32: align = LUB_HEAP_ALIGN_2_POWER_5; break;
  157. case 64: align = LUB_HEAP_ALIGN_2_POWER_6; break;
  158. case 128: align = LUB_HEAP_ALIGN_2_POWER_7; break;
  159. case 256: align = LUB_HEAP_ALIGN_2_POWER_8; break;
  160. case 512: align = LUB_HEAP_ALIGN_2_POWER_9; break;
  161. case 1024: align = LUB_HEAP_ALIGN_2_POWER_10; break;
  162. case 2048: align = LUB_HEAP_ALIGN_2_POWER_11; break;
  163. case 4096: align = LUB_HEAP_ALIGN_2_POWER_12; break;
  164. case 8192: align = LUB_HEAP_ALIGN_2_POWER_13; break;
  165. case 16384: align = LUB_HEAP_ALIGN_2_POWER_14; break;
  166. case 32768: align = LUB_HEAP_ALIGN_2_POWER_15; break;
  167. case 65536: align = LUB_HEAP_ALIGN_2_POWER_16; break;
  168. case 131072: align = LUB_HEAP_ALIGN_2_POWER_17; break;
  169. case 262144: align = LUB_HEAP_ALIGN_2_POWER_18; break;
  170. case 524288: align = LUB_HEAP_ALIGN_2_POWER_19; break;
  171. case 1048576: align = LUB_HEAP_ALIGN_2_POWER_20; break;
  172. case 2097152: align = LUB_HEAP_ALIGN_2_POWER_21; break;
  173. case 4194304: align = LUB_HEAP_ALIGN_2_POWER_22; break;
  174. case 8388608: align = LUB_HEAP_ALIGN_2_POWER_23; break;
  175. case 16777216: align = LUB_HEAP_ALIGN_2_POWER_24; break;
  176. case 33554432: align = LUB_HEAP_ALIGN_2_POWER_25; break;
  177. case 67108864: align = LUB_HEAP_ALIGN_2_POWER_26; break;
  178. case 134217728: align = LUB_HEAP_ALIGN_2_POWER_27; break;
  179. default: status = LUB_HEAP_FAILED; break;
  180. }
  181. if(LUB_HEAP_OK == status)
  182. {
  183. semTake(&this->sem,WAIT_FOREVER);
  184. status = lub_heap_realloc(this->heap,&ptr,nBytes,align);
  185. semGive(&this->sem);
  186. }
  187. lubheap_vxworks_check_status(this,
  188. status,
  189. "memPartAlignedAlloc",
  190. NULL,
  191. nBytes);
  192. return ptr;
  193. }
  194. /*-------------------------------------------------------- */
  195. void *
  196. memPartAlloc(PART_ID partId,
  197. unsigned nBytes)
  198. {
  199. partition_t *this = (partition_t*)partId;
  200. char *ptr = NULL;
  201. lub_heap_status_t status;
  202. semTake(&this->sem,WAIT_FOREVER);
  203. status = lub_heap_realloc(this->heap,&ptr,nBytes,LUB_HEAP_ALIGN_NATIVE);
  204. semGive(&this->sem);
  205. lubheap_vxworks_check_status(this,status,"memPartAlloc",NULL,nBytes);
  206. return ptr;
  207. }
  208. /*-------------------------------------------------------- */
  209. BOOL
  210. memPartBlockIsValid(PART_ID partId,
  211. BLOCK_HDR *pHdr,
  212. BOOL isFree)
  213. {
  214. partition_t *this = (partition_t*)partId;
  215. bool_t result;
  216. semTake(&this->sem,WAIT_FOREVER);
  217. result = lub_heap_validate_pointer(this->heap,(char*)pHdr);
  218. semGive(&this->sem);
  219. return (BOOL_TRUE == result) ? TRUE : FALSE;
  220. }
  221. /*-------------------------------------------------------- */
  222. PART_ID
  223. memPartCreate(char *pPool,
  224. unsigned poolSize)
  225. {
  226. partition_t *this = objAlloc(memPartClassId);
  227. memPartInit((PART_ID)this,pPool,poolSize);
  228. return (PART_ID)this;
  229. }
  230. /*-------------------------------------------------------- */
  231. static void
  232. memPartDestroy(PART_ID partId)
  233. {
  234. partition_t *this = (partition_t*)partId;
  235. semTake(&this->sem,WAIT_FOREVER);
  236. lub_heap_destroy(this->heap);
  237. this->heap = 0;
  238. objCoreTerminate(&this->objCore);
  239. semGive(&this->sem);
  240. objFree(memPartClassId,(char*)this);
  241. }
  242. /*-------------------------------------------------------- */
  243. STATUS
  244. memPartFree(PART_ID partId,
  245. char *pBlock)
  246. {
  247. partition_t *this = (partition_t*)partId;
  248. lub_heap_status_t status;
  249. if(OK == OBJ_VERIFY(pBlock,memPartClassId))
  250. {
  251. /* we are releasing a memory partition */
  252. memPartDestroy((PART_ID)pBlock);
  253. status = LUB_HEAP_OK;
  254. }
  255. else
  256. {
  257. /* we are simply releasing memory */
  258. semTake(&this->sem,WAIT_FOREVER);
  259. status = lub_heap_realloc(this->heap,&pBlock,0,LUB_HEAP_ALIGN_NATIVE);
  260. semGive(&this->sem);
  261. }
  262. lubheap_vxworks_check_status(this,status,"memPartFree",pBlock,0);
  263. return (LUB_HEAP_OK == status) ? OK : ERROR;
  264. }
  265. /*-------------------------------------------------------- */
  266. void
  267. memPartInit(PART_ID partId,
  268. char *pPool,
  269. unsigned poolSize)
  270. {
  271. partition_t *this = (partition_t*)partId;
  272. memset(this,0,sizeof(partition_t));
  273. /* initialise the core object */
  274. objCoreInit(&this->objCore,memPartClassId);
  275. /* set the default options */
  276. this->options = memPartOptionsDefault;
  277. /* initialise the semaphore for the partition */
  278. semMInit(&this->sem,
  279. SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
  280. /* create the heap */
  281. this->heap = lub_heap_create(pPool,poolSize);
  282. }
  283. /*-------------------------------------------------------- */
  284. STATUS
  285. memPartLibInit(char *pPool,
  286. unsigned poolSize)
  287. {
  288. if(!memPartLibInstalled)
  289. {
  290. memPartLibInstalled = 1;
  291. classInit(memPartClassId,
  292. sizeof(partition_t),
  293. offsetof(partition_t,objCore),
  294. (FUNCPTR)memPartCreate,
  295. (FUNCPTR)memPartInit,
  296. (FUNCPTR)memPartDestroy);
  297. classInstrument(memPartClassId,memPartInstClassId);
  298. /* now initialise the system partition instance */
  299. memPartInit((PART_ID)&memSysPartition,
  300. pPool,
  301. poolSize);
  302. }
  303. return OK;
  304. }
  305. /*-------------------------------------------------------- */