]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cunit/lib/common/Framework/MyMem.c
Update
[l4.git] / l4 / pkg / cunit / lib / common / Framework / MyMem.c
1 /*!
2  * \file   lib/src/Framework/MyMem.c
3  * \brief  
4  *
5  * \date   01/30/2007
6  * \author Bjoern Doebel <doebel@os.inf.tu-dresden.de
7  *
8  */
9 /*
10  * (c) 2007-2009 Technische Universität Dresden
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  */
15 /*
16  *  CUnit - A Unit testing framework library for C.
17  *  Copyright (C) 2001            Anil Kumar
18  *  Copyright (C) 2004,2005,2006  Anil Kumar, Jerry St.Clair
19  *
20  *  This library is free software; you can redistribute it and/or
21  *  modify it under the terms of the GNU Library General Public
22  *  License as published by the Free Software Foundation; either
23  *  version 2 of the License, or (at your option) any later version.
24  *
25  *  This library is distributed in the hope that it will be useful,
26  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
27  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28  *  Library General Public License for more details.
29  *
30  *  You should have received a copy of the GNU Library General Public
31  *  License along with this library; if not, write to the Free Software
32  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33  */
34
35 /*
36  *  Memory management functions used throughout CUnit.
37  *
38  *  13/Oct/2001   Moved some of the generic functions definitions from other
39  *                files to this one so as to use the functions consitently.
40  *                This file is not included in the distribution headers because
41  *                it is used internally by CUnit. (AK)
42  *
43  *  18-Jul-2004   New interface, doxygen comments, made local functions &
44  *                constants static, fixed reporting of memory tracking (valid
45  *                vs invalid cycles), restructured memory tracking to detect 
46  *                reallocations & multiple deletions. (JDS)
47  *
48  *  24-Apr-2005   Changed type of allocated sizes to size_t to avoid
49  *                signed-unsigned mismatch. (JDS)
50  */
51
52 /** @file
53  * Memory management & reporting functions (implementation).
54  */
55 /** @addtogroup Framework
56  @{
57 */
58
59 #ifndef DDE_LINUX
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <ctype.h>
63 #include <errno.h>
64 #include <assert.h>
65 #include <string.h>
66 #include <time.h>
67 #else
68 #include "dde_support.h"
69 #endif /* DDE_LINUX */
70
71 #include <CUnit.h>
72 #include <MyMem.h>
73
74 #ifdef MEMTRACE
75
76 #define MAX_FILE_NAME_LENGTH  256
77
78 /** Default name for memory dump file. */
79 static const char* f_szDefaultDumpFileName = "CUnit-Memory-Dump.xml";
80 /**< Default name for memory dump file. */
81
82 #ifdef CUNIT_BUILD_TESTS
83 /** For testing use (only) to simulate memory exhaustion -
84  * if CU_FALSE, allocation requests will always fail and return NULL.
85  */
86 static CU_BOOL f_bTestCunitMallocActive = CU_TRUE;
87 #endif
88
89 /** Structure holding the details of a memory allocation/deallocation event. */
90 typedef struct mem_event {
91   size_t            Size;
92   unsigned int      AllocLine;
93   char              AllocFilename[MAX_FILE_NAME_LENGTH];
94   unsigned int      DeallocLine;
95   char              DeallocFilename[MAX_FILE_NAME_LENGTH];
96   struct mem_event* pNext;
97 } MEMORY_EVENT;
98 typedef MEMORY_EVENT* PMEMORY_EVENT;
99
100 #define NOT_ALLOCATED 0
101 #define NOT_DELETED 0
102
103 /** Structure holding the details of a memory node having allocation/deallocation events. */
104 typedef struct mem_node {
105   void*             pLocation;
106   unsigned int      EventCount;
107   PMEMORY_EVENT     pFirstEvent;
108   struct mem_node*  pNext;
109 } MEMORY_NODE;
110 typedef MEMORY_NODE* PMEMORY_NODE;
111
112 static PMEMORY_NODE f_pMemoryTrackerHead = NULL;  /**< Head of double-linked list of memory nodes. */
113 static unsigned int f_nMemoryNodes = 0;           /**< Counter for memory nodes created. */
114 /*------------------------------------------------------------------------*/
115 /** Locate the memory node for the specified memory location (returns NULL if none). */
116 static PMEMORY_NODE find_memory_node(void* pLocation)
117 {
118   PMEMORY_NODE pMemoryNode = f_pMemoryTrackerHead;
119   while (NULL != pMemoryNode) {
120     if (pLocation == pMemoryNode->pLocation) {
121       break;
122     }
123     pMemoryNode = pMemoryNode->pNext;
124   }
125
126   return pMemoryNode;
127 }
128 /*------------------------------------------------------------------------*/
129 /** Create a new memory node for the specified memory location. */
130 static PMEMORY_NODE create_memory_node(void* pLocation)
131 {
132   PMEMORY_NODE pTempNode = NULL;
133   PMEMORY_NODE pMemoryNode = find_memory_node(pLocation);
134
135   /* a memory node for pLocation should not exist yet */
136   if (NULL == pMemoryNode) {
137
138     pMemoryNode = (PMEMORY_NODE)malloc(sizeof(MEMORY_NODE));
139     assert(NULL != pMemoryNode);
140
141     pMemoryNode->pLocation = pLocation;
142     pMemoryNode->EventCount = 0;
143     pMemoryNode->pFirstEvent = NULL;
144     pMemoryNode->pNext = NULL;
145
146     /* add new node to linked list */
147     pTempNode = f_pMemoryTrackerHead;
148     if (NULL == pTempNode) {
149       f_pMemoryTrackerHead = pMemoryNode;
150     }
151     else {
152       while (NULL != pTempNode->pNext) {
153         pTempNode = pTempNode->pNext;
154       }
155       pTempNode->pNext = pMemoryNode;
156     }
157
158     ++f_nMemoryNodes;
159   }
160   return pMemoryNode;
161 }
162 /*------------------------------------------------------------------------*/
163 /** Add a new memory event having the specified parameters. */
164 static PMEMORY_EVENT add_memory_event(PMEMORY_NODE pMemoryNode,
165                                       size_t size,
166                                       unsigned int alloc_line,
167                                       const char* alloc_filename)
168 {
169   PMEMORY_EVENT pMemoryEvent = NULL;
170   PMEMORY_EVENT pTempEvent = NULL;
171
172   assert (NULL != pMemoryNode);
173
174   /* create and set up the new event */
175   pMemoryEvent = malloc(sizeof(MEMORY_EVENT));
176   assert(NULL != pMemoryEvent);
177
178   pMemoryEvent->Size = size;
179   pMemoryEvent->AllocLine = alloc_line;
180   strncpy(pMemoryEvent->AllocFilename, alloc_filename, (size_t) MAX_FILE_NAME_LENGTH-1);
181   pMemoryEvent->AllocFilename[MAX_FILE_NAME_LENGTH-1] = (char)0;
182   pMemoryEvent->DeallocLine = NOT_DELETED;
183   pMemoryEvent->DeallocFilename[0] = (char)0;
184   pMemoryEvent->pNext = NULL;
185
186   /* add the new event to the end of the linked list */
187   pTempEvent = pMemoryNode->pFirstEvent;
188   if (NULL == pTempEvent) {
189     pMemoryNode->pFirstEvent = pMemoryEvent;
190   }
191   else {
192     while (NULL != pTempEvent->pNext) {
193       pTempEvent = pTempEvent->pNext;
194     }
195     pTempEvent->pNext = pMemoryEvent;
196   }
197
198   ++pMemoryNode->EventCount;
199
200   return pMemoryEvent;
201 }
202 /*------------------------------------------------------------------------*/
203 /** Record memory allocation event. */
204 static PMEMORY_NODE allocate_memory(size_t nSize,
205                                     void* pLocation,
206                                     unsigned int uiAllocationLine,
207                                     const char* szAllocationFile)
208 {
209   PMEMORY_NODE pMemoryNode = NULL;
210
211   /* attempt to locate an existing record for this pLocation */
212   pMemoryNode = find_memory_node(pLocation);
213
214   /* pLocation not found - create a new event record */
215   if (NULL == pMemoryNode) {
216     pMemoryNode = create_memory_node(pLocation);
217   }
218
219   /* add the new event record */
220   add_memory_event(pMemoryNode, nSize, uiAllocationLine, szAllocationFile);
221
222   return pMemoryNode;
223 }
224
225 /*------------------------------------------------------------------------*/
226 /** Record memory deallocation event. */
227 static void deallocate_memory(void* pLocation, unsigned int uiDeletionLine, const char* szDeletionFileName)
228 {
229   PMEMORY_NODE  pMemoryNode = NULL;
230   PMEMORY_EVENT pTempEvent = NULL;
231
232   assert(0 != uiDeletionLine);
233   assert(NULL != szDeletionFileName);
234
235   /* attempt to locate an existing record for this pLocation */
236   pMemoryNode = find_memory_node(pLocation);
237
238   /* if no entry, then an unallocated pointer was freed */
239   if (NULL == pMemoryNode) {
240     pMemoryNode = create_memory_node(pLocation);
241     pTempEvent = add_memory_event(pMemoryNode, 0, NOT_ALLOCATED, "");
242   }
243   else {
244     /* there should always be at least 1 event for an existing memory node */
245     assert(NULL != pMemoryNode->pFirstEvent);
246
247     /* locate last memory event for this pLocation */
248     pTempEvent = pMemoryNode->pFirstEvent;
249     while (NULL != pTempEvent->pNext) {
250       pTempEvent = pTempEvent->pNext;
251     }
252
253     /* if pointer has already been freed, create a new event for double deletion */
254     if (NOT_DELETED != pTempEvent->DeallocLine) {
255       pTempEvent = add_memory_event(pMemoryNode, pTempEvent->Size, NOT_ALLOCATED, "");
256     }
257   }
258
259   pTempEvent->DeallocLine = uiDeletionLine;
260   strncpy(pTempEvent->DeallocFilename, szDeletionFileName, MAX_FILE_NAME_LENGTH-1);
261   pTempEvent->DeallocFilename[MAX_FILE_NAME_LENGTH-1] = (char)0;
262 }
263
264 /*------------------------------------------------------------------------*/
265 /** Custom calloc function with memory event recording. */
266 void* CU_calloc(size_t nmemb, size_t size, unsigned int uiLine, const char* szFileName)
267 {
268   void* pVoid = NULL;
269
270 #ifdef CUNIT_BUILD_TESTS
271   if (CU_FALSE == f_bTestCunitMallocActive) {
272     return NULL;
273   }
274 #endif
275
276   pVoid = calloc(nmemb, size);
277   if (NULL != pVoid) {
278     allocate_memory(nmemb * size, pVoid, uiLine, szFileName);
279   }
280
281   return pVoid;
282 }
283
284 /*------------------------------------------------------------------------*/
285 /** Custom malloc function with memory event recording. */
286 void* CU_malloc(size_t size, unsigned int uiLine, const char* szFileName)
287 {
288   void* pVoid = NULL;
289
290 #ifdef CUNIT_BUILD_TESTS
291   if (CU_FALSE == f_bTestCunitMallocActive) {
292     return NULL;
293   }
294 #endif
295
296   pVoid = malloc(size);
297   if (NULL != pVoid) {
298     allocate_memory(size, pVoid, uiLine, szFileName);
299   }
300
301   return pVoid;
302 }
303
304 /*------------------------------------------------------------------------*/
305 /** Custom free function with memory event recording. */
306 void CU_free(void *ptr, unsigned int uiLine, const char* szFileName)
307 {
308   deallocate_memory(ptr, uiLine, szFileName);
309   free(ptr);
310 }
311
312 /*------------------------------------------------------------------------*/
313 /** Custom realloc function with memory event recording. */
314 void* CU_realloc(void *ptr, size_t size, unsigned int uiLine, const char* szFileName)
315 {
316   void* pVoid = NULL;
317
318   deallocate_memory(ptr, uiLine, szFileName);
319
320 #ifdef CUNIT_BUILD_TESTS
321   if (CU_FALSE == f_bTestCunitMallocActive) {
322     free(ptr);
323     return NULL;
324   }
325 #endif
326
327   pVoid = realloc(ptr, size);
328
329   if (NULL != pVoid) {
330     allocate_memory(size, pVoid, uiLine, szFileName);
331   }
332
333   return pVoid;
334 }
335
336 /*------------------------------------------------------------------------*/
337 /** Print a report of memory events to file. */
338 void CU_dump_memory_usage(const char* szFilename)
339 {
340   char* szDumpFileName = (char*)f_szDefaultDumpFileName;
341   unsigned int nValid;
342   unsigned int nInvalid;
343   PMEMORY_NODE pTempNode = NULL;
344   PMEMORY_EVENT pTempEvent = NULL;
345   FILE* pFile = NULL;
346   time_t tTime = 0;
347
348   /* use the specified file name, if supplied) */
349   if ((NULL != szFilename) && strlen(szFilename) > 0) {
350     szDumpFileName = (char*)szFilename;
351   }
352
353   if (NULL == (pFile = fopen(szDumpFileName, "w"))) {
354     fprintf(stderr, "Failed to open file \"%s\" : %s", szDumpFileName, strerror(errno));
355     return;
356   }
357
358   setvbuf(pFile, NULL, _IONBF, 0);
359
360   fprintf(pFile, "<\?xml version=\"1.0\" \?>");
361   fprintf(pFile, "\n<\?xml-stylesheet type=\"text/xsl\" href=\"Memory-Dump.xsl\" \?>");
362   fprintf(pFile, "\n<!DOCTYPE MEMORY_DUMP_REPORT SYSTEM \"Memory-Dump.dtd\">");
363   fprintf(pFile, "\n<MEMORY_DUMP_REPORT>");
364   fprintf(pFile, "\n  <MD_HEADER/>");
365   fprintf(pFile, "\n  <MD_RUN_LISTING>");
366
367   nValid = 0;
368   nInvalid = 0;
369   pTempNode = f_pMemoryTrackerHead;
370   while (NULL != pTempNode) {
371     fprintf(pFile, "\n    <MD_RUN_RECORD>");
372     fprintf(pFile, "\n      <MD_POINTER> %p </MD_POINTER>", pTempNode->pLocation);
373     fprintf(pFile, "\n      <MD_EVENT_COUNT> %u </MD_EVENT_COUNT>", pTempNode->EventCount);
374
375     pTempEvent = pTempNode->pFirstEvent;
376     while (NULL != pTempEvent) {
377       fprintf(pFile, "\n      <MD_EVENT_RECORD>");
378       fprintf(pFile, "\n        <MD_SIZE> %u </MD_SIZE>", pTempEvent->Size);
379       fprintf(pFile, "\n        <MD_ALLOC_FILE> %s </MD_ALLOC_FILE>", pTempEvent->AllocFilename);
380       fprintf(pFile, "\n        <MD_ALLOC_LINE> %u </MD_ALLOC_LINE>", pTempEvent->AllocLine);
381       fprintf(pFile, "\n        <MD_DEALLOC_FILE> %s </MD_DEALLOC_FILE>", pTempEvent->DeallocFilename);
382       fprintf(pFile, "\n        <MD_DEALLOC_LINE> %u </MD_DEALLOC_LINE>", pTempEvent->DeallocLine);
383       fprintf(pFile, "\n      </MD_EVENT_RECORD>");
384
385       if ((0 != pTempEvent->AllocLine) && (0 != pTempEvent->DeallocLine)) {
386         ++nValid;
387       }
388       else {
389         ++nInvalid;
390       }
391
392       pTempEvent = pTempEvent->pNext;
393     }
394
395     fprintf(pFile, "\n    </MD_RUN_RECORD>");
396     pTempNode = pTempNode->pNext;
397   }
398
399   fprintf(pFile, "\n  </MD_RUN_LISTING>");
400
401   fprintf(pFile, "\n  <MD_SUMMARY>");
402   fprintf(pFile, "\n    <MD_SUMMARY_VALID_RECORDS> %u </MD_SUMMARY_VALID_RECORDS>", nValid);
403   fprintf(pFile, "\n    <MD_SUMMARY_INVALID_RECORDS> %u </MD_SUMMARY_INVALID_RECORDS>", nInvalid);
404   fprintf(pFile, "\n    <MD_SUMMARY_TOTAL_RECORDS> %u </MD_SUMMARY_TOTAL_RECORDS>", nValid + nInvalid);
405   fprintf(pFile, "\n  </MD_SUMMARY>");
406
407   time(&tTime);
408   fprintf(pFile, "\n  <MD_FOOTER> Memory Trace for CUnit Run at %s </MD_FOOTER>", ctime(&tTime));
409   fprintf(pFile, "</MEMORY_DUMP_REPORT>");
410
411   fclose(pFile);
412 }
413
414 #endif  /* MEMTRACE */
415
416 /** @} */
417
418 #ifdef CUNIT_BUILD_TESTS
419 #include "test_cunit.h"
420
421 /** Deactivate CUnit memory allocation
422  * After calling this function, all Cunit memory
423  * allocation routines will fail and return NULL.
424  */
425 void test_cunit_deactivate_malloc(void)
426 {
427   f_bTestCunitMallocActive = CU_FALSE;
428 }
429
430 /** Activate CUnit memory allocation
431  * After calling this function, all Cunit memory
432  * allocation routines will behave normally (allocating
433  * memory if it is available).
434  */
435 void test_cunit_activate_malloc(void)
436 {
437   f_bTestCunitMallocActive = CU_TRUE;
438 }
439
440 /** Retrieve the number of memory events recorded for a given pointer. */
441 unsigned int test_cunit_get_n_memevents(void* pLocation)
442 {
443   PMEMORY_NODE pNode = find_memory_node(pLocation);
444   return (pNode) ? pNode->EventCount : 0;
445 }
446
447 /** Retrieve the number of memory allocations recorded for a given pointer. */
448 unsigned int test_cunit_get_n_allocations(void* pLocation)
449 {
450   PMEMORY_NODE pNode = find_memory_node(pLocation);
451   PMEMORY_EVENT pEvent = NULL;
452   int result = 0;
453
454   if (NULL != pNode) {
455     pEvent = pNode->pFirstEvent;
456     while (NULL != pEvent) {
457       if (pEvent->AllocLine != NOT_ALLOCATED)
458         ++result;
459       pEvent = pEvent->pNext;
460     }
461   }
462
463   return result;
464 }
465
466 /** Retrieve the number of memory deallocations recorded for a given pointer. */
467 unsigned int test_cunit_get_n_deallocations(void* pLocation)
468 {
469   PMEMORY_NODE pNode = find_memory_node(pLocation);
470   PMEMORY_EVENT pEvent = NULL;
471   int result = 0;
472
473   if (NULL != pNode) {
474     pEvent = pNode->pFirstEvent;
475     while (NULL != pEvent) {
476       if (pEvent->DeallocLine != NOT_DELETED)
477         ++result;
478       pEvent = pEvent->pNext;
479     }
480   }
481
482   return result;
483 }
484
485 void test_CU_calloc(void)
486 {
487   void* ptr1 = NULL;
488   void* ptr2 = calloc(2, sizeof(int));
489   unsigned int n2 = test_cunit_get_n_memevents(ptr2);
490
491   /* test allocation failure */
492   test_cunit_deactivate_malloc();
493   ptr1 = CU_CALLOC(2, sizeof(int));
494   TEST(NULL == ptr1);
495   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
496   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
497   test_cunit_activate_malloc();
498
499   /* normal allocation */
500   ptr1 = CU_CALLOC(2, sizeof(int));
501   TEST_FATAL(NULL != ptr1);
502   TEST(test_cunit_get_n_allocations(ptr1) != test_cunit_get_n_deallocations(ptr1));
503   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
504
505   CU_FREE(ptr1);
506   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
507   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
508   TEST(n2 == test_cunit_get_n_memevents(ptr2));
509
510   free(ptr2);
511 }
512
513 void test_CU_malloc(void)
514 {
515   void* ptr1 = NULL;
516   void* ptr2 = malloc(sizeof(int));
517   unsigned int n2 = test_cunit_get_n_memevents(ptr2);
518
519   /* test allocation failure */
520   test_cunit_deactivate_malloc();
521   ptr1 = CU_MALLOC(sizeof(int));
522   TEST(NULL == ptr1);
523   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
524   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
525   test_cunit_activate_malloc();
526
527   /* normal allocation */
528   ptr1 = CU_MALLOC(sizeof(int));
529   TEST_FATAL(NULL != ptr1);
530   TEST(test_cunit_get_n_allocations(ptr1) != test_cunit_get_n_deallocations(ptr1));
531   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
532
533   CU_FREE(ptr1);
534   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
535   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
536   TEST(n2 == test_cunit_get_n_memevents(ptr2));
537
538   free(ptr2);
539 }
540
541 void test_CU_free(void)
542 {
543   /* covered by other test functions */
544 }
545
546 void test_CU_realloc(void)
547 {
548   void* ptr1 = CU_MALLOC(sizeof(int));
549   void* ptr2 = malloc(sizeof(int));
550   void* ptr3;
551   void* ptr4;
552   unsigned int n2 = test_cunit_get_n_memevents(ptr2);
553
554   /* test allocation failure */
555   test_cunit_deactivate_malloc();
556   ptr1 = CU_REALLOC(ptr1, sizeof(long int));
557   TEST(NULL == ptr1);
558   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
559   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
560   test_cunit_activate_malloc();
561
562   /* normal allocation */
563   ptr3 = CU_MALLOC(sizeof(int));
564   TEST_FATAL(NULL != ptr3);
565   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
566   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
567   TEST(test_cunit_get_n_allocations(ptr3) != test_cunit_get_n_deallocations(ptr3));
568
569   ptr4 = CU_REALLOC(ptr3, sizeof(long int));
570   TEST_FATAL(NULL != ptr4);
571   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
572   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
573   if (ptr3 != ptr4)
574     TEST(test_cunit_get_n_allocations(ptr3) == test_cunit_get_n_deallocations(ptr3));
575   TEST(test_cunit_get_n_allocations(ptr4) != test_cunit_get_n_deallocations(ptr4));
576
577   CU_FREE(ptr4);
578   TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
579   TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
580   TEST(test_cunit_get_n_allocations(ptr3) == test_cunit_get_n_deallocations(ptr3));
581   TEST(test_cunit_get_n_allocations(ptr4) == test_cunit_get_n_deallocations(ptr4));
582   TEST(n2 == test_cunit_get_n_memevents(ptr2));
583
584   free(ptr2);
585 }
586
587 /** The main internal testing function for MyMem.c. */
588 void test_cunit_MyMem(void)
589 {
590   test_cunit_start_tests("MyMem.c");
591
592   test_CU_calloc();
593   test_CU_malloc();
594   test_CU_free();
595   test_CU_realloc();
596
597   test_cunit_end_tests();
598 }
599
600 #endif    /* CUNIT_BUILD_TESTS */