4 #if _SDCC_MALLOC_TYPE_MLH
6 typedef struct _MEMHEADER MEMHEADER;
16 #define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
18 /* These variables are defined through the crt0 functions. */
19 /* Base of this variable is the first byte of the heap. */
20 extern MEMHEADER _sdcc_heap_start;
21 /* Address of this variable is the last byte of the heap. */
22 extern char _sdcc_heap_end;
27 MEMHEADER *pbase = &_sdcc_heap_start;
28 unsigned int size = &_sdcc_heap_end - (char *)pbase;
30 pbase->next = (MEMHEADER *)((char *)pbase + size - HEADER_SIZE);
31 pbase->next->next = NULL; //And mark it as last
32 pbase->prev = NULL; //and mark first as first
33 pbase->len = 0; //Empty and ready.
37 malloc (unsigned int size)
39 MEMHEADER * current_header;
40 MEMHEADER * new_header;
42 if (size>(0xFFFF-HEADER_SIZE))
44 return NULL; //To prevent overflow in next line
47 size += HEADER_SIZE; //We need a memory for header too
48 current_header = &_sdcc_heap_start;
55 //....*****.........******....
59 if ((((unsigned int)current_header->next) -
60 ((unsigned int)current_header) -
61 current_header->len) >= size)
63 break; //if spare is more than need
65 current_header = current_header->next; //else try next
66 if (!current_header->next)
68 return NULL; //if end_of_list reached
72 if (!current_header->len)
73 { //This code works only for first_header in the list and only
74 current_header->len = size; //for first allocation
75 return ¤t_header->mem;
79 //else create new header at the begin of spare
80 new_header = (MEMHEADER * )((char *)current_header + current_header->len);
81 new_header->next = current_header->next; //and plug it into the chain
82 new_header->prev = current_header;
83 current_header->next = new_header;
86 new_header->next->prev = new_header;
88 new_header->len = size; //mark as used
89 return &new_header->mem;
95 //--------------------------------------------------------------------
96 //Written by Dmitry S. Obukhov, 1997
98 //--------------------------------------------------------------------
99 //Modified for SDCC by Sandeep Dutta, 1999
100 //sandeep.dutta@usa.net
101 //--------------------------------------------------------------------
102 //malloc and free functions implementation for embedded system
103 //Non-ANSI keywords are C51 specific.
104 // xdata - variable in external memory (just RAM)
105 //--------------------------------------------------------------------
107 #define HEADER_SIZE sizeof(MEMHEADER)
109 MEMHEADER xdata * _sdcc_first_memheader;
111 void init_dynamic_memory(void xdata * heap, unsigned int size)
114 //This function MUST be called after the RESET.
115 //Parameters: heap - pointer to memory allocated by the linker
116 // size - size of this memory pool
118 // #define DYNAMIC_MEMORY_SIZE 0x2000
120 // unsigned char xdata dynamic_memory_pool[DYNAMIC_MEMORY_SIZE];
121 // unsigned char xdata * current_buffer;
126 // init_dynamic_memory(dynamic_memory_pool,DYNAMIC_MEMORY_SIZE);
127 // Now it is possible to use malloc.
129 // current_buffer = malloc(0x100);
132 MEMHEADER xdata * array = (MEMHEADER xdata *)heap;
134 if ( !array ) //Reserved memory starts at 0x0000 but that's NULL...
135 { //So, we lost one byte!
136 array = (MEMHEADER xdata * )((char xdata * ) array + 1) ;
139 _sdcc_first_memheader = array;
140 //Reserve a mem for last header
141 array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - sizeof(MEMHEADER xdata *));
142 array->next->next = (MEMHEADER xdata * ) NULL; //And mark it as last
143 array->len = 0; //Empty and ready.
146 void xdata * malloc (unsigned int size)
148 register MEMHEADER xdata * current_header;
149 register MEMHEADER xdata * new_header;
151 if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
152 size += HEADER_SIZE; //We need a memory for header too
153 current_header = _sdcc_first_memheader;
160 //....*****.........******....
164 if ((((unsigned int)current_header->next) -
165 ((unsigned int)current_header) -
166 current_header->len) >= size) break; //if spare is more than need
167 current_header = current_header->next; //else try next
168 if (!current_header->next) return (void xdata *) NULL; //if end_of_list reached
170 if (!current_header->len)
171 { //This code works only for first_header in the list and only
172 current_header->len = size; //for first allocation
173 return current_header->mem;
174 } //else create new header at the begin of spare
175 new_header = (MEMHEADER xdata * )((char xdata *)current_header + current_header->len);
176 new_header->next = current_header->next; //and plug it into the chain
177 current_header->next = new_header;
178 new_header->len = size; //mark as used
179 return new_header->mem;