Release 0.1.0
[wine/hacks.git] / heap.c
blobfa061241ac43648f0b2c41763bf799f5a884f6b6
1 static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "prototypes.h"
7 #include "segmem.h"
8 #include "heap.h"
10 MDESC *LOCAL_FreeList;
12 /**********************************************************************
13 * HEAP_Init
15 void
16 HEAP_Init(MDESC **free_list, void *start, int length)
18 *free_list = (MDESC *) start;
19 (*free_list)->prev = NULL;
20 (*free_list)->next = NULL;
21 (*free_list)->length = length - sizeof(MDESC);
24 /**********************************************************************
25 * HEAP_Alloc
27 void *
28 HEAP_Alloc(MDESC **free_list, int flags, int bytes)
30 MDESC *m, *m_new;
32 #ifdef DEBUG_HEAP
33 printf("HeapAlloc: free_list %08x, flags %x, bytes %d\n",
34 free_list, flags, bytes);
35 #endif
38 * Find free block big enough.
40 for (m = *free_list; m != NULL; m = m->next)
42 if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
44 break;
46 else if (m->length > bytes)
48 m_new = m + (bytes / sizeof(MDESC)) + 2;
49 if (m->prev == NULL)
50 *free_list = m_new;
51 else
52 m->prev->next = m_new;
54 if (m->next != NULL)
55 m->next->prev = m_new;
57 m_new->next = m->next;
58 m_new->prev = m->prev;
59 m_new->length = m->length - ((int) m_new - (int) m);
60 m->length -= (m_new->length + sizeof(MDESC));
62 m->prev = m;
63 m->next = m;
64 return (void *) (m + 1);
68 if (m != NULL)
70 if (m->prev == NULL)
71 *free_list = m->next;
72 else
73 m->prev->next = m->next;
75 if (m->next != NULL)
76 m->next->prev = m->prev;
78 m->prev = m;
79 m->next = m;
80 return (void *) (m + 1);
83 return 0;
86 /**********************************************************************
87 * HEAP_Free
89 void
90 HEAP_Free(MDESC **free_list, void *block)
92 MDESC *m_free;
93 MDESC *m;
94 MDESC *m_prev;
97 * Validate pointer.
99 m_free = (MDESC *) block - 1;
100 if (m_free->prev != m_free || m_free->next != m_free ||
101 ((int) m_free & 0xffff0000) != ((int) *free_list & 0xffff0000))
103 #ifdef DEBUG_HEAP
104 printf("Attempt to free bad pointer,"
105 "m_free = %08x, *free_list = %08x\n",
106 m_free, free_list);
107 #endif
108 return;
112 * Find location in free list.
114 m_prev = NULL;
115 for (m = *free_list; m != NULL && m < m_free; m = m->next)
116 m_prev = m;
118 if (m_prev != NULL && (int) m_prev + m_prev->length > (int) m_free)
120 #ifdef DEBUG_HEAP
121 printf("Attempt to free bad pointer,"
122 "m_free = %08x, m_prev = %08x (length %x)\n",
123 m_free, m_prev, m_prev->length);
124 #endif
125 return;
128 if ((m != NULL && (int) m_free + m_free->length > (int) m) ||
129 (int) m_free + m_free->length > ((int) m_free | 0xffff))
131 #ifdef DEBUG_HEAP
132 printf("Attempt to free bad pointer,"
133 "m_free = %08x (length %x), m = %08x\n",
134 m_free, m_free->length, m);
135 #endif
136 return;
140 * Put block back in free list.
141 * Does it merge with the previos block?
143 if (m_prev != NULL)
145 if ((int) m_prev + m_prev->length == (int) m_free)
147 m_prev->length += sizeof(MDESC) + m_free->length;
148 m_free = m_prev;
150 else
152 m_prev->next = m_free;
153 m_free->prev = m_prev;
156 else
158 *free_list = m_free;
159 m_free->prev = NULL;
163 * Does it merge with the next block?
165 if (m != NULL)
167 if ((int) m_free + m_free->length == (int) m)
169 m_free->length += sizeof(MDESC) + m->length;
170 m_free->next = m->next;
172 else
174 m->prev = m_free;
175 m_free->next = m;
178 else
180 m_free->next = NULL;
184 /**********************************************************************
185 * HEAP_LocalInit
187 void
188 HEAP_LocalInit(void *start, int length)
190 HEAP_Init(&LOCAL_FreeList, start, length);
193 /**********************************************************************
194 * HEAP_LocalAlloc
196 void *
197 HEAP_LocalAlloc(int flags, int bytes)
199 void *m;
201 #ifdef DEBUG_HEAP
202 printf("LocalAlloc: flags %x, bytes %d\n", flags, bytes);
203 #endif
205 m = HEAP_Alloc(&LOCAL_FreeList, flags, bytes);
207 #ifdef DEBUG_HEAP
208 printf("LocalAlloc: returning %x\n", (int) m);
209 #endif
210 return m;