3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /* use small (32K) heap for 16-bit compilers,
26 large (500K) heap for 32-bit compilers */
28 #define HEAP_SIZE 16384u //500000uL
30 #define HEAP_SIZE 32768u
33 #define MALLOC_MAGIC 0x6D92 /* must be < 0x8000 */
35 typedef struct _malloc
/* Turbo C DJGPP */
37 size_t size
; /* 2 bytes 4 bytes */
38 struct _malloc
*next
; /* 2 bytes 4 bytes */
39 unsigned magic
: 15; /* 2 bytes total 4 bytes total */
41 } malloc_t
; /* total 6 bytes 12 bytes */
43 static char *g_heap_bot
, *g_kbrk
, *g_heap_top
;
44 /*****************************************************************************
45 *****************************************************************************/
46 static void dump_heap (void)
48 unsigned blks_used
= 0, blks_free
= 0;
49 size_t bytes_used
= 0, bytes_free
= 0;
53 for (m
= (malloc_t
*)g_heap_bot
; m
!= NULL
; m
= m
->next
)
55 //DPRINT ("blk %5p: %6u bytes %s\n", m,
56 // m->size, m->used ? "used" : "free");
61 bytes_used
+= m
->size
;
66 bytes_free
+= m
->size
;
70 /*DPRINT ("blks: %6u used, %6u free, %6u total\n", blks_used,
71 blks_free, blks_used + blks_free);
72 DPRINT ("bytes: %6u used, %6u free, %6u total\n", bytes_used,
73 bytes_free, bytes_used + bytes_free);
74 DPRINT ("g_heap_bot=0x%p, g_kbrk=0x%p, g_heap_top=0x%p\n",
75 g_heap_bot, g_kbrk, g_heap_top);*/
77 total
= (bytes_used
+ bytes_free
) +
78 (blks_used
+ blks_free
) * sizeof(malloc_t
);
80 //if(total != g_kbrk - g_heap_bot)
81 //DPRINT ("*** some heap memory is not accounted for\n");
83 /*****************************************************************************
84 POSIX sbrk() looks like this
86 Mine is a bit different so I can signal the calling function
87 if more memory than desired was allocated (e.g. in a system with paging)
88 If your kbrk()/sbrk() always allocates the amount of memory you ask for,
89 this code can be easily changed.
91 int brk( void *sbrk( void *kbrk(
92 function void *adr); int delta); int *delta);
93 ---------------------- ------------ ------------ -------------
95 return value if error -1 -1 NULL
96 get break value . sbrk(0) int x=0; kbrk(&x);
97 set break value to X brk(X) sbrk(X - sbrk(0)) int x=X, y=0; kbrk(&x) - kbrk(&y);
98 enlarge heap by N bytes . sbrk(+N) int x=N; kbrk(&x);
99 shrink heap by N bytes . sbrk(-N) int x=-N; kbrk(&x);
100 can you tell if you're
102 than you wanted? no no yes
103 *****************************************************************************/
104 static void *kbrk (int *delta
)
106 static char heap
[HEAP_SIZE
];
108 char *new_brk
, *old_brk
;
110 /* heap doesn't exist yet */
111 if(g_heap_bot
== NULL
)
113 g_heap_bot
= g_kbrk
= heap
;
114 g_heap_top
= g_heap_bot
+ HEAP_SIZE
;
116 new_brk
= g_kbrk
+ (*delta
);
117 /* too low: return NULL */
118 if(new_brk
< g_heap_bot
)
120 /* too high: return NULL */
121 if(new_brk
>= g_heap_top
)
123 /* success: adjust brk value... */
126 /* ...return actual delta... (for this sbrk(), they are the same)
127 (*delta) = (*delta); */
128 /* ...return old brk value */
132 /*****************************************************************************
133 malloc() and free() use g_heap_bot, but not g_kbrk nor g_heap_top
134 *****************************************************************************/
135 void *malloc (size_t size
)
143 "movl %%eax, %0;": "=g" (p
) : "g" ((unsigned) size
) : "%eax", "%ebx");
147 /*****************************************************************************
148 *****************************************************************************/
149 void free (void *blk
)
154 "int $0x80;" :: "b" (blk
) : "%eax", "memory");
156 /*****************************************************************************
157 *****************************************************************************/
158 void *realloc (void *blk
, size_t size
)
167 "movl %%eax, %0;": "=g" (p
) : "b" (blk
), "g" ((unsigned) size
) : "%eax", "memory", "%ecx");
171 /*****************************************************************************
172 *****************************************************************************/