ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / Examples / Multiplatform / Protocol / VP_Os / vp_os_malloc.c
1 /**
2  * @file malloc.c
3  * @author aurelien.morelle@parrot.fr
4  * @date 2006/12/19
5  */
6
7 #include <VP_Os/vp_os_malloc.h>
8
9
10 #undef calloc
11 #undef malloc
12 #undef memset
13 #undef free
14 #undef realloc
15
16
17 void *
18 vp_os_calloc(size_t nmemb, size_t size)
19 {
20 #ifdef DEBUG_MODE
21   void *res = calloc(nmemb, size);
22   assert(res);
23   return (res);
24 #else // ! DEBUG_MODE
25   return calloc(nmemb, size);
26 #endif // <- DEBUG_MODE
27 }
28
29 void *
30 vp_os_malloc(size_t size)
31 {
32 #ifdef DEBUG_MODE
33   void *res = malloc(size);
34   assert(res);
35   return (res);
36 #else // ! DEBUG_MODE
37   return malloc(size);
38 #endif // <- DEBUG_MODE
39 }
40
41 void *
42 vp_os_malloc_no_assert(size_t size)
43 {
44   return malloc(size);
45 }
46
47 void
48 vp_os_free(void *ptr)
49 {
50 #ifdef DEBUG_MODE
51   assert(ptr);
52   free(ptr);
53 #else // ! DEBUG_MODE
54   free(ptr);
55 #endif // <- DEBUG_MODE
56 }
57
58 // align_size has to be a power of two !!!
59 //
60 // The basic working of this algorithm is to allocate a bigger chunk of data than requested.
61 // This chunk of data must be big enough to contain an address aligned on requested boundary
62 // We also alloc 2 more words to keep base ptr (bptr) & requested size (size) of allocation
63 // bptr is the base pointer of this allocation
64 // _____ ______ ______ __________
65 //  ... | bptr | size |   ....   |
66 // _____|______|______|__________|
67 // 
68 void* vp_os_aligned_malloc(size_t size, size_t align_size)
69 {
70   char *ptr, *aligned_ptr;
71   int* ptr2;
72   int allocation_size;
73   size_t align_mask = align_size - 1;
74
75   // Check if align_size is a power of two
76   // If the result of this test is non zero then align_size is not a power of two
77   if( align_size & align_mask )
78     return NULL;
79
80   // Allocation size is :
81   //    - Requested user size
82   //    - a size (align_size) to make sure we can align on the requested boundary
83   //    - 8 more bytes to register base adress & allocation size 
84   allocation_size = size + align_size + 2*sizeof(int);
85
86   ptr = (char*) vp_os_malloc(allocation_size);
87   if(ptr == NULL)
88     return NULL;
89
90   ptr2 = (int*)(ptr + 2*sizeof(int));
91   aligned_ptr = ptr + 2*sizeof(int) + (align_size - ((size_t) ptr2 & align_mask));
92
93   ptr2    = (int*)(aligned_ptr - 2*sizeof(int));
94   *ptr2++ = (int) (aligned_ptr - ptr);
95   *ptr2   = size;
96
97   return aligned_ptr;
98 }
99
100 void vp_os_aligned_free(void *ptr)
101 {
102   int* ptr2 = (int*)ptr - 2;
103
104   vp_os_free( ((char*)ptr - *ptr2) );
105 }
106
107 void*
108 vp_os_aligned_realloc(void* ptr, size_t size, size_t align_size)
109 {
110   void* ptr_ret;
111   void* aligned_ptr;
112
113   if( size == 0 )
114   {
115     ptr_ret = NULL;
116     if( ptr != NULL )
117       vp_os_aligned_free(ptr);
118   }
119   else
120   {
121     if( ptr != NULL )
122     {
123       int* ptr2 = (int*)ptr - 1;
124       size_t old_size;
125
126       aligned_ptr = ptr;
127
128       old_size = *ptr2--;
129
130       ptr_ret = vp_os_aligned_malloc(size, align_size);
131
132       // Compute smallest size
133       if( size > old_size )
134       {
135         size = old_size;
136       }
137
138       // Copy old data
139       vp_os_memcpy( ptr_ret, aligned_ptr, size );
140
141       vp_os_free( ((char*)ptr - *ptr2) );
142     }
143     else
144     {
145       ptr_ret = vp_os_aligned_malloc(size, align_size);
146     }
147   }
148
149   return ptr_ret;
150 }
151
152 void*
153 vp_os_realloc(void *ptr, size_t size)
154 {
155 #ifdef DEBUG_MODE
156   void *res = realloc(ptr, size);
157   assert(res);
158   return (res);
159 #else // ! DEBUG_MODE
160   return realloc(ptr, size);
161 #endif // <- DEBUG_MODE
162 }
163