3 #if _SDCC_MALLOC_TYPE_MLH
6 typedef struct _MEMHEADER MEMHEADER;
16 #define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
19 /* These veriables are defined through the crt0 functions. */
20 /* Base of this variable is the first byte of the heap. */
21 extern MEMHEADER _sdcc_heap_start;
22 /* Address of this variable is the last byte of the heap. */
23 extern char _sdcc_heap_end;
28 MEMHEADER *pbase = &_sdcc_heap_start;
29 unsigned int size = &_sdcc_heap_end - (char *)pbase;
31 pbase->next = (MEMHEADER *)((char *)pbase + size - HEADER_SIZE);
32 pbase->next->next = NULL; //And mark it as last
33 pbase->prev = NULL; //and mark first as first
34 pbase->len = 0; //Empty and ready.
38 malloc (unsigned int size)
40 MEMHEADER * current_header;
41 MEMHEADER * new_header;
43 if (size>(0xFFFF-HEADER_SIZE))
45 return NULL; //To prevent overflow in next line
48 size += HEADER_SIZE; //We need a memory for header too
49 current_header = &_sdcc_heap_start;
56 //....*****.........******....
60 if ((((unsigned int)current_header->next) -
61 ((unsigned int)current_header) -
62 current_header->len) >= size)
64 break; //if spare is more than need
66 current_header = current_header->next; //else try next
67 if (!current_header->next)
69 return NULL; //if end_of_list reached
73 if (!current_header->len)
74 { //This code works only for first_header in the list and only
75 current_header->len = size; //for first allocation
76 return ¤t_header->mem;
80 //else create new header at the begin of spare
81 new_header = (MEMHEADER * )((char *)current_header + current_header->len);
82 new_header->next = current_header->next; //and plug it into the chain
83 new_header->prev = current_header;
84 current_header->next = new_header;
87 new_header->next->prev = new_header;
89 new_header->len = size; //mark as used
90 return &new_header->mem;
97 MEMHEADER *prev_header, *pthis;
99 if ( p ) //For allocated pointers only!
101 pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header
102 if ( pthis->prev ) // For the regular header
104 prev_header = pthis->prev;
105 prev_header->next = pthis->next;
108 pthis->next->prev = prev_header;
113 pthis->len = 0; //For the first header
120 //--------------------------------------------------------------------
121 //Written by Dmitry S. Obukhov, 1997
123 //--------------------------------------------------------------------
124 //Modified for SDCC by Sandeep Dutta, 1999
125 //sandeep.dutta@usa.net
126 //--------------------------------------------------------------------
127 //malloc and free functions implementation for embedded system
128 //Non-ANSI keywords are C51 specific.
129 // xdata - variable in external memory (just RAM)
130 //--------------------------------------------------------------------
132 #define MEMHEADER struct MAH// Memory Allocation Header
136 MEMHEADER xdata * next;
137 MEMHEADER xdata * prev;
142 #define HEADER_SIZE (sizeof(MEMHEADER)-1)
143 #define NULL (void xdata * ) 0
146 //Static here means: can be accessed from this module only
147 static MEMHEADER xdata * FIRST_MEMORY_HEADER_PTR;
148 void init_dynamic_memory(MEMHEADER xdata * array, unsigned int size)
151 //This function MUST be called after the RESET.
152 //Parameters: array - pointer to memory allocated by the linker
153 // size - size of this memory pool
155 // #define DYNAMIC_MEMORY_SIZE 0x2000
157 // unsigned char xdata dynamic_memory_pool[DYNAMIC_MEMORY_SIZE];
158 // unsigned char xdata * current_buffer;
163 // init_dynamic_memory(dynamic_memory_pool,DYNAMIC_MEMORY_SIZE);
164 // Now it is possible to use malloc.
166 // current_buffer = malloc(0x100);
170 if ( !array ) /*Reserved memory starts on 0x0000 but it's NULL...*/
171 { //So, we lost one byte!
172 array = (MEMHEADER xdata * )((char xdata * ) array + 1) ;
175 FIRST_MEMORY_HEADER_PTR = array;
176 //Reserve a mem for last header
177 array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - HEADER_SIZE);
178 array->next->next = NULL; //And mark it as last
179 array->prev = NULL; //and mark first as first
180 array->len = 0; //Empty and ready.
183 void xdata * malloc (unsigned int size)
185 register MEMHEADER xdata * current_header;
186 register MEMHEADER xdata * new_header;
188 if (size>(0xFFFF-HEADER_SIZE)) return NULL; //To prevent overflow in next line
189 size += HEADER_SIZE; //We need a memory for header too
190 current_header = FIRST_MEMORY_HEADER_PTR;
197 //....*****.........******....
201 if ((((unsigned int)current_header->next) -
202 ((unsigned int)current_header) -
203 current_header->len) >= size) break; //if spare is more than need
204 current_header = current_header->next; //else try next
205 if (!current_header->next) return NULL; //if end_of_list reached
207 if (!current_header->len)
208 { //This code works only for first_header in the list and only
209 current_header->len = size; //for first allocation
210 return ((xdata *)&(current_header->mem));
211 } //else create new header at the begin of spare
212 new_header = (MEMHEADER xdata * )((char xdata *)current_header + current_header->len);
213 new_header->next = current_header->next; //and plug it into the chain
214 new_header->prev = current_header;
215 current_header->next = new_header;
216 if (new_header->next) new_header->next->prev = new_header;
217 new_header->len = size; //mark as used
218 return ((xdata *)&(new_header->mem));
221 void free (MEMHEADER xdata * p)
223 register MEMHEADER xdata * prev_header;
224 if ( p ) //For allocated pointers only!
226 p = (MEMHEADER xdata * )((char xdata *) p - HEADER_SIZE); //to start of header
227 if ( p->prev ) // For the regular header
229 prev_header = p->prev;
230 prev_header->next = p->next;
231 if (p->next) p->next->prev = prev_header;
233 else p->len = 0; //For the first header