* Christmas edition *; fixed irc /os command; small cleanup in fd.c; improvements...
[ZeXOS.git] / libc / stdlib / memory.c
blob889a7c9b8ee0b21f15cacc4d537c5552edaa9be4
1 /*
2 * ZeX/OS
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/>.
20 #include <x86.h>
21 #include <string.h>
23 #define _32BIT 1
25 /* use small (32K) heap for 16-bit compilers,
26 large (500K) heap for 32-bit compilers */
27 #if defined(_32BIT)
28 #define HEAP_SIZE 16384u //500000uL
29 #else
30 #define HEAP_SIZE 32768u
31 #endif
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 */
40 unsigned used : 1;
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;
50 malloc_t *m;
51 int total;
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");
58 if (m->used)
60 blks_used++;
61 bytes_used += m->size;
63 else
65 blks_free++;
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
85 void *sbrk(int incr);
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 ---------------------- ------------ ------------ -------------
94 POSIX? yes yes NO
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
101 given more memory
102 than you wanted? no no yes
103 *****************************************************************************/
104 static void *kbrk (int *delta)
106 static char heap[HEAP_SIZE];
107 /**/
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)
119 return NULL;
120 /* too high: return NULL */
121 if(new_brk >= g_heap_top)
122 return NULL;
123 /* success: adjust brk value... */
124 old_brk = g_kbrk;
125 g_kbrk = new_brk;
126 /* ...return actual delta... (for this sbrk(), they are the same)
127 (*delta) = (*delta); */
128 /* ...return old brk value */
129 return old_brk;
132 /*****************************************************************************
133 malloc() and free() use g_heap_bot, but not g_kbrk nor g_heap_top
134 *****************************************************************************/
135 void *malloc (size_t size)
137 void *p = 0;
139 asm volatile (
140 "movl $14, %%eax;"
141 "movl %1, %%ebx;"
142 "int $0x80;"
143 "movl %%eax, %0;": "=g" (p) : "g" ((unsigned) size) : "%eax", "%ebx");
145 return (void *) p;
147 /*****************************************************************************
148 *****************************************************************************/
149 void free (void *blk)
151 asm volatile (
152 "movl $43, %%eax;"
153 "movl %0, %%ebx;"
154 "int $0x80;" :: "b" (blk) : "%eax", "memory");
156 /*****************************************************************************
157 *****************************************************************************/
158 void *realloc (void *blk, size_t size)
160 void *p = 0;
162 asm volatile (
163 "movl $44, %%eax;"
164 "movl %1, %%ebx;"
165 "movl %2, %%ecx;"
166 "int $0x80;"
167 "movl %%eax, %0;": "=g" (p) : "b" (blk), "g" ((unsigned) size) : "%eax", "memory", "%ecx");
169 return (void *) p;
171 /*****************************************************************************
172 *****************************************************************************/