Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/i386/libsa/zalloc.c

Source at commit 214 created 13 years 5 months ago.
By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings.
1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT Computer, Inc.
26 * All rights reserved.
27 *
28 * Sam's simple memory allocator.
29 *
30 */
31
32#include "libsa.h"
33//#include "saio_internal.h" - Azi: needed for ZDEBUG (printf)
34#include "memory.h"
35
36#define ZDEBUG 0 //Azi: booter doesn't load with this enabled; instant reboot at "boot1: ..."
37
38#if ZDEBUG
39int zout;
40#endif
41
42typedef struct {
43char * start;
44size_t size;
45} zmem;
46
47static zmem * zalloced;
48static zmem * zavailable;
49static short availableNodes, allocedNodes, totalNodes;
50static char * zalloc_base;
51static char * zalloc_end;
52static void (*zerror)(char *, size_t, const char *, int);
53
54static void zallocate(char * start,int size);
55static void zinsert(zmem * zp, int ndx);
56static void zdelete(zmem * zp, int ndx);
57static void zcoalesce(void);
58
59#if ZDEBUG
60size_t zalloced_size;
61#endif
62
63#define ZALLOC_NODES16384
64
65static void malloc_error(char *addr, size_t size, const char *file, int line)
66{
67#ifdef i386
68 asm volatile ("hlt");
69#endif
70}
71
72// define the block of memory that the allocator will use
73void malloc_init(char * start, int size, int nodes, void (*malloc_err_fn)(char *, size_t, const char *, int))
74{
75zalloc_base = start ? start : (char *)ZALLOC_ADDR;
76totalNodes = nodes ? nodes : ZALLOC_NODES;
77zalloced = (zmem *) zalloc_base;
78zavailable = (zmem *) zalloc_base + sizeof(zmem) * totalNodes;
79zavailable[0].start = (char *)zavailable + sizeof(zmem) * totalNodes;
80 if (size == 0) size = ZALLOC_LEN;
81zavailable[0].size = size - (zavailable[0].start - zalloc_base);
82 zalloc_end = zalloc_base + size;
83availableNodes = 1;
84allocedNodes = 0;
85 zerror = malloc_err_fn ? malloc_err_fn : malloc_error;
86}
87
88#define BEST_FIT 1
89
90void * safe_malloc(size_t size, const char *file, int line)
91{
92int i;
93#if BEST_FIT
94 int bestFit;
95 size_t smallestSize;
96#endif
97char * ret = 0;
98
99if ( !zalloc_base )
100{
101// this used to follow the bss but some bios' corrupted it...
102malloc_init((char *)ZALLOC_ADDR, ZALLOC_LEN, ZALLOC_NODES, malloc_error);
103}
104
105size = ((size + 0xf) & ~0xf);
106
107 if (size == 0) {
108 if (zerror) (*zerror)((char *)0xdeadbeef, 0, file, line);
109 }
110#if BEST_FIT
111 smallestSize = 0;
112 bestFit = -1;
113#endif
114
115for (i = 0; i < availableNodes; i++)
116{
117// find node with equal size, or if not found,
118 // then smallest node that fits.
119if ( zavailable[i].size == size )
120{
121zallocate(ret = zavailable[i].start, size);
122zdelete(zavailable, i); availableNodes--;
123goto done;
124}
125#if BEST_FIT
126 else
127 {
128 if ((zavailable[i].size > size) &&
129 ((smallestSize == 0) ||
130 (zavailable[i].size < smallestSize)))
131 {
132 bestFit = i;
133 smallestSize = zavailable[i].size;
134 }
135 }
136
137#else
138else if ( zavailable[i].size > size )
139{
140zallocate(ret = zavailable[i].start, size);
141zavailable[i].start += size;
142zavailable[i].size -= size;
143goto done;
144}
145#endif
146 }
147#if BEST_FIT
148 if (bestFit != -1)
149 {
150 zallocate(ret = zavailable[bestFit].start, size);
151 zavailable[bestFit].start += size;
152 zavailable[bestFit].size -= size;
153 }
154#endif
155
156done:
157if ((ret == 0) || (ret + size >= zalloc_end))
158 {
159if (zerror) (*zerror)(ret, size, file, line);
160 }
161if (ret != 0)
162 {
163bzero(ret, size);
164 }
165#if ZDEBUG
166 zalloced_size += size;
167#endif
168return (void *) ret;
169}
170
171void free(void * pointer)
172{
173 unsigned long rp;
174int i, found = 0;
175 size_t tsize = 0;
176char * start = pointer;
177
178#if i386
179 // Get return address of our caller,
180 // in case we have to report an error below.
181 asm volatile ("movl %%esp, %%eax\n\t"
182 "subl $4, %%eax\n\t"
183 "movl 0(%%eax), %%eax" : "=a" (rp) );
184#else
185 rp = 0;
186#endif
187
188if ( !start ) return;
189
190for (i = 0; i < allocedNodes; i++)
191{
192if ( zalloced[i].start == start )
193{
194tsize = zalloced[i].size;
195#if ZDEBUG
196zout -= tsize;
197printf(" zz out %d\n",zout);
198#endif
199zdelete(zalloced, i); allocedNodes--;
200found = 1;
201#if ZDEBUG
202 memset(pointer, 0x5A, tsize);
203#endif
204break;
205}
206}
207if ( !found ) {
208 if (zerror) (*zerror)(pointer, rp, "free", 0);
209 else return;
210 }
211#if ZDEBUG
212 zalloced_size -= tsize;
213#endif
214
215for (i = 0; i < availableNodes; i++)
216{
217if ((start + tsize) == zavailable[i].start) // merge it in
218{
219zavailable[i].start = start;
220zavailable[i].size += tsize;
221zcoalesce();
222return;
223}
224
225if ((i > 0) &&
226 (zavailable[i-1].start + zavailable[i-1].size == start))
227{
228zavailable[i-1].size += tsize;
229zcoalesce();
230return;
231}
232
233if ((start + tsize) < zavailable[i].start)
234{
235 if (++availableNodes > totalNodes) {
236 if (zerror) (*zerror)((char *)0xf000f000, 0, "free", 0);
237 }
238zinsert(zavailable, i);
239zavailable[i].start = start;
240zavailable[i].size = tsize;
241return;
242}
243}
244
245 if (++availableNodes > totalNodes) {
246 if (zerror) (*zerror)((char *)0xf000f000, 1, "free", 0);
247 }
248zavailable[i].start = start;
249zavailable[i].size = tsize;
250zcoalesce();
251return;
252}
253
254static void
255zallocate(char * start,int size)
256{
257#if ZDEBUG
258zout += size;
259printf(" alloc %d, total 0x%x\n",size,zout);
260#endif
261zalloced[allocedNodes].start = start;
262zalloced[allocedNodes].size = size;
263if (++allocedNodes > totalNodes) {
264 if (zerror) (*zerror)((char *)0xf000f000, 2, "zallocate", 0);
265 };
266}
267
268static void
269zinsert(zmem * zp, int ndx)
270{
271int i;
272zmem *z1, *z2;
273
274i = totalNodes-2;
275z1 = zp + i;
276z2 = z1 + 1;
277
278for (; i >= ndx; i--, z1--, z2--)
279{
280 *z2 = *z1;
281}
282}
283
284static void
285zdelete(zmem * zp, int ndx)
286{
287int i;
288zmem *z1, *z2;
289
290z1 = zp + ndx;
291z2 = z1 + 1;
292
293for (i = ndx; i < totalNodes-1; i++, z1++, z2++)
294{
295 *z1 = *z2;
296}
297}
298
299static void
300zcoalesce(void)
301{
302int i;
303
304for (i = 0; i < availableNodes-1; i++)
305{
306if ( zavailable[i].start + zavailable[i].size ==
307 zavailable[i+1].start )
308{
309zavailable[i].size += zavailable[i+1].size;
310zdelete(zavailable, i+1); availableNodes--;
311return;
312}
313}
314}
315
316/* This is the simplest way possible. Should fix this. */
317void * realloc(void * start, size_t newsize)
318{
319 void * newstart = safe_malloc(newsize, __FILE__, __LINE__);
320 bcopy(start, newstart, newsize);
321 free(start);
322 return newstart;
323}
324

Archive Download this file

Revision: 214