]>
git.saurik.com Git - apple/boot.git/blob - i386/libsa/zalloc.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 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 1.1 (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
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
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright 1993 NeXT Computer, Inc.
26 * All rights reserved.
28 * Sam's simple memory allocator.
46 static zmem
* zalloced
;
47 static zmem
* zavailable
;
48 static short availableNodes
, allocedNodes
, totalNodes
;
49 static char * zalloc_base
;
50 static char * zalloc_end
;
51 static void (*zerror
)(char *, size_t);
53 static void zallocate(char * start
,int size
);
54 static void zinsert(zmem
* zp
, int ndx
);
55 static void zdelete(zmem
* zp
, int ndx
);
56 static void zcoalesce(void);
62 #define ZALLOC_NODES 16384
64 static void malloc_error(char *addr
, size_t size
)
71 // define the block of memory that the allocator will use
72 void malloc_init(char * start
, int size
, int nodes
, void (*malloc_err_fn
)(char *, size_t))
74 zalloc_base
= start
? start
: (char *)ZALLOC_ADDR
;
75 totalNodes
= nodes
? nodes
: ZALLOC_NODES
;
76 zalloced
= (zmem
*) zalloc_base
;
77 zavailable
= (zmem
*) zalloc_base
+ sizeof(zmem
) * totalNodes
;;
78 zavailable
[0].start
= (char *)zavailable
+ sizeof(zmem
) * totalNodes
;
79 if (size
== 0) size
= ZALLOC_LEN
;
80 zavailable
[0].size
= size
- (zavailable
[0].start
- zalloc_base
);
81 zalloc_end
= zalloc_base
+ size
;
84 zerror
= malloc_err_fn
? malloc_err_fn
: malloc_error
;
89 void * malloc(size_t size
)
100 // this used to follow the bss but some bios' corrupted it...
101 malloc_init((char *)ZALLOC_ADDR
, ZALLOC_LEN
, ZALLOC_NODES
, malloc_error
);
104 size
= ((size
+ 0xf) & ~0xf);
107 if (zerror
) (*zerror
)((char *)0xdeadbeef, 0);
114 for (i
= 0; i
< availableNodes
; i
++)
116 // find node with equal size, or if not found,
117 // then smallest node that fits.
118 if ( zavailable
[i
].size
== size
)
120 zallocate(ret
= zavailable
[i
].start
, size
);
121 zdelete(zavailable
, i
); availableNodes
--;
127 if ((zavailable
[i
].size
> size
) &&
128 ((smallestSize
== 0) ||
129 (zavailable
[i
].size
< smallestSize
)))
132 smallestSize
= zavailable
[i
].size
;
137 else if ( zavailable
[i
].size
> size
)
139 zallocate(ret
= zavailable
[i
].start
, size
);
140 zavailable
[i
].start
+= size
;
141 zavailable
[i
].size
-= size
;
149 zallocate(ret
= zavailable
[bestFit
].start
, size
);
150 zavailable
[bestFit
].start
+= size
;
151 zavailable
[bestFit
].size
-= size
;
156 if ((ret
== 0) || (ret
+ size
>= zalloc_end
))
158 if (zerror
) (*zerror
)(ret
, size
);
165 zalloced_size
+= size
;
170 void free(void * pointer
)
175 char * start
= pointer
;
178 // Get return address of our caller,
179 // in case we have to report an error below.
180 asm("movl %%esp, %%eax\n\t"
182 "movl 0(%%eax), %%eax" : "=a" (rp
) );
187 if ( !start
) return;
189 for (i
= 0; i
< allocedNodes
; i
++)
191 if ( zalloced
[i
].start
== start
)
193 tsize
= zalloced
[i
].size
;
196 printf(" zz out %d\n",zout
);
198 zdelete(zalloced
, i
); allocedNodes
--;
201 memset(pointer
, 0x5A, tsize
);
207 if (zerror
) (*zerror
)(pointer
, rp
);
211 zalloced_size
-= tsize
;
214 for (i
= 0; i
< availableNodes
; i
++)
216 if ((start
+ tsize
) == zavailable
[i
].start
) // merge it in
218 zavailable
[i
].start
= start
;
219 zavailable
[i
].size
+= tsize
;
225 (zavailable
[i
-1].start
+ zavailable
[i
-1].size
== start
))
227 zavailable
[i
-1].size
+= tsize
;
232 if ((start
+ tsize
) < zavailable
[i
].start
)
234 if (++availableNodes
> totalNodes
) {
235 if (zerror
) (*zerror
)((char *)0xf000f000, 0);
237 zinsert(zavailable
, i
);
238 zavailable
[i
].start
= start
;
239 zavailable
[i
].size
= tsize
;
244 if (++availableNodes
> totalNodes
) {
245 if (zerror
) (*zerror
)((char *)0xf000f000, 1);
247 zavailable
[i
].start
= start
;
248 zavailable
[i
].size
= tsize
;
254 zallocate(char * start
,int size
)
258 printf(" alloc %d, total 0x%x\n",size
,zout
);
260 zalloced
[allocedNodes
].start
= start
;
261 zalloced
[allocedNodes
].size
= size
;
262 if (++allocedNodes
> totalNodes
) {
263 if (zerror
) (*zerror
)((char *)0xf000f000, 2);
268 zinsert(zmem
* zp
, int ndx
)
277 for (; i
>= ndx
; i
--, z1
--, z2
--)
284 zdelete(zmem
* zp
, int ndx
)
292 for (i
= ndx
; i
< totalNodes
-1; i
++, z1
++, z2
++)
303 for (i
= 0; i
< availableNodes
-1; i
++)
305 if ( zavailable
[i
].start
+ zavailable
[i
].size
==
306 zavailable
[i
+1].start
)
308 zavailable
[i
].size
+= zavailable
[i
+1].size
;
309 zdelete(zavailable
, i
+1); availableNodes
--;
315 /* This is the simplest way possible. Should fix this. */
316 void * realloc(void * start
, size_t newsize
)
318 void * newstart
= malloc(newsize
);
319 bcopy(start
, newstart
, newsize
);