summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-18 09:19:10 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-18 09:19:10 +0000
commitf1952f0996f0586abe1d987e35e594c2b9cce31e (patch)
tree282fd2361db44db9e96b56c6c21972daa81c3f9f /libc
parent3bc8ac7796cf6f3ab67316e6df5aa8915a6bb03e (diff)
Rework, reduce the size, add proper locking
-Erik
Diffstat (limited to 'libc')
-rw-r--r--libc/stdlib/malloc-930716/Makefile4
-rw-r--r--libc/stdlib/malloc-930716/calloc.c5
-rw-r--r--libc/stdlib/malloc-930716/free.c156
-rw-r--r--libc/stdlib/malloc-930716/malloc.c361
-rw-r--r--libc/stdlib/malloc-930716/malloc.h63
-rw-r--r--libc/stdlib/malloc-930716/memalign.c61
-rw-r--r--libc/stdlib/malloc-930716/morecore.c28
-rw-r--r--libc/stdlib/malloc-930716/realloc.c131
-rw-r--r--libc/stdlib/malloc-930716/valloc.c62
9 files changed, 342 insertions, 529 deletions
diff --git a/libc/stdlib/malloc-930716/Makefile b/libc/stdlib/malloc-930716/Makefile
index 444581b9b..b9dfea9f2 100644
--- a/libc/stdlib/malloc-930716/Makefile
+++ b/libc/stdlib/malloc-930716/Makefile
@@ -24,11 +24,11 @@
TOPDIR=../../../
include $(TOPDIR)Rules.mak
-CSRC=calloc.c free.c malloc.c memalign.c morecore.c realloc.c valloc.c
+CSRC=calloc.c malloc.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
MSRC=../malloc/alloc.c
-MOBJ=malloc_dbg.o free_dbg.o calloc_dbg.o
+MOBJ=#malloc_dbg.o free_dbg.o calloc_dbg.o
OBJS=$(COBJS) $(MOBJ)
all: $(OBJS) $(LIBC)
diff --git a/libc/stdlib/malloc-930716/calloc.c b/libc/stdlib/malloc-930716/calloc.c
index 152fe09c6..55d22ac11 100644
--- a/libc/stdlib/malloc-930716/calloc.c
+++ b/libc/stdlib/malloc-930716/calloc.c
@@ -8,13 +8,12 @@
WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */
+#include <stdlib.h>
#include <string.h>
-#include "malloc.h"
/* Allocate space for the given number of elements of the given
size, initializing the whole region to binary zeroes. */
-void *
-calloc(size_t nelem, size_t size)
+void * calloc(size_t nelem, size_t size)
{
void *result;
diff --git a/libc/stdlib/malloc-930716/free.c b/libc/stdlib/malloc-930716/free.c
deleted file mode 100644
index fbc98b714..000000000
--- a/libc/stdlib/malloc-930716/free.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* free.c - C standard library routine.
- Copyright (c) 1989, 1993 Michael J. Haertel
- You may redistribute this library under the terms of the
- GNU Library General Public License (version 2 or any later
- version) as published by the Free Software Foundation.
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
- WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR
- WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
- SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include "malloc.h"
-
-/* Return memory to the heap. */
-void
-_free_internal (void *ptr)
-{
- int block, blocks, i, type;
- struct list *prev, *next;
-
- if (!ptr)
- return;
-
- block = BLOCK(ptr);
-
- switch (type = _heapinfo[block].busy.type) {
- case 0:
- /* Find the free cluster previous to this one in the free list.
- Start searching at the last block referenced; this may benefit
- programs with locality of allocation. */
- i = _heapindex;
- if (i > block)
- while (i > block)
- i = _heapinfo[i].free.prev;
- else {
- do
- i = _heapinfo[i].free.next;
- while (i > 0 && i < block);
- i = _heapinfo[i].free.prev;
- }
-
- /* Determine how to link this block into the free list. */
- if (block == i + _heapinfo[i].free.size) {
- /* Coalesce this block with its predecessor. */
- _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
- block = i;
- } else {
- /* Really link this block back into the free list. */
- _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
- _heapinfo[block].free.next = _heapinfo[i].free.next;
- _heapinfo[block].free.prev = i;
- _heapinfo[i].free.next = block;
- _heapinfo[_heapinfo[block].free.next].free.prev = block;
- }
-
- /* Now that the block is linked in, see if we can coalesce it
- with its successor (by deleting its successor from the list
- and adding in its size). */
- if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) {
- _heapinfo[block].free.size
- += _heapinfo[_heapinfo[block].free.next].free.size;
- _heapinfo[block].free.next
- = _heapinfo[_heapinfo[block].free.next].free.next;
- _heapinfo[_heapinfo[block].free.next].free.prev = block;
- }
-
- /* Now see if we can return stuff to the system. */
- blocks = _heapinfo[block].free.size;
- if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
- && (*__morecore)(0) == ADDRESS(block + blocks)) {
- _heaplimit -= blocks;
- (*__morecore)(-blocks * BLOCKSIZE);
- _heapinfo[_heapinfo[block].free.prev].free.next
- = _heapinfo[block].free.next;
- _heapinfo[_heapinfo[block].free.next].free.prev
- = _heapinfo[block].free.prev;
- block = _heapinfo[block].free.prev;
- }
-
- /* Set the next search to begin at this block. */
- _heapindex = block;
- break;
-
- default:
- /* Get the address of the first free fragment in this block. */
- prev = (struct list *) ((char *) ADDRESS(block)
- + (_heapinfo[block].busy.info.frag.first
- << type));
-
- if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1
- && _fragblocks[type] > 1) {
- /* If all fragments of this block are free, remove them
- from the fragment list and free the whole block. */
- --_fragblocks[type];
- for (next = prev, i = 1; i < BLOCKSIZE >> type; ++i)
- next = next->next;
- prev->prev->next = next;
- if (next)
- next->prev = prev->prev;
- _heapinfo[block].busy.type = 0;
- _heapinfo[block].busy.info.size = 1;
- free(ADDRESS(block));
- } else if (_heapinfo[block].busy.info.frag.nfree) {
- /* If some fragments of this block are free, link this fragment
- into the fragment list after the first free fragment of
- this block. */
- next = ptr;
- next->next = prev->next;
- next->prev = prev;
- prev->next = next;
- if (next->next)
- next->next->prev = next;
- ++_heapinfo[block].busy.info.frag.nfree;
- } else {
- /* No fragments of this block are free, so link this fragment
- into the fragment list and announce that it is the first
- free fragment of this block. */
- prev = (struct list *) ptr;
- _heapinfo[block].busy.info.frag.nfree = 1;
- _heapinfo[block].busy.info.frag.first
- = (unsigned int) ((char *) ptr - (char *) NULL) % BLOCKSIZE
- >> type;
- prev->next = _fraghead[type].next;
- prev->prev = &_fraghead[type];
- prev->prev->next = prev;
- if (prev->next)
- prev->next->prev = prev;
- }
- break;
- }
-}
-
-struct alignlist *_aligned_blocks = NULL;
-
-void
-free (void *ptr)
-{
- register struct alignlist *l;
-
- if (ptr == NULL)
- return;
-
- for (l = _aligned_blocks; l != NULL; l = l->next)
- {
- if (l->aligned == ptr)
- {
- l->aligned = NULL; /* Mark the slot in the list as free. */
- ptr = l->exact;
- break;
- }
- }
-
- _free_internal (ptr);
-}
diff --git a/libc/stdlib/malloc-930716/malloc.c b/libc/stdlib/malloc-930716/malloc.c
index 88c9251ad..f4c147f0c 100644
--- a/libc/stdlib/malloc-930716/malloc.c
+++ b/libc/stdlib/malloc-930716/malloc.c
@@ -8,42 +8,69 @@
WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */
+#define _GNU_SOURCE
+#include <features.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "malloc.h"
+#define MIN(x,y) ({ \
+ const typeof(x) _x = (x); \
+ const typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t malloclock = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK pthread_mutex_lock(&malloclock)
+# define UNLOCK pthread_mutex_unlock(&malloclock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static void * malloc_unlocked (size_t size);
+static void free_unlocked(void *ptr);
+static void * __default_morecore_init(long size);
+
/* How to really get more memory. */
-void *(*__morecore)(long) = __default_morecore_init;
+static void *(*__morecore)(long) = __default_morecore_init;
/* Pointer to the base of the first block. */
-char *_heapbase;
+static char *_heapbase;
/* Block information table. */
-union info *_heapinfo;
+static union info *_heapinfo;
/* Number of info entries. */
-static int heapsize;
+static size_t heapsize;
/* Search index in the info table. */
-int _heapindex;
+static size_t _heapindex;
/* Limit of valid info table indices. */
-int _heaplimit;
+static size_t _heaplimit;
/* Count of large blocks allocated for each fragment size. */
-int _fragblocks[BLOCKLOG];
+static size_t _fragblocks[BLOCKLOG];
/* Free lists for each fragment size. */
-struct list _fraghead[BLOCKLOG];
+static struct list _fraghead[BLOCKLOG];
/* Are we experienced? */
static int initialized;
-/* Aligned allocation. */
-static void *
-align(size_t size)
+
+
+/* Aligned allocation.
+ * Called within the lock in initialize() and morecore(),
+ * so no explicit locking needed... */
+static void * align(size_t size)
{
void *result;
unsigned int adj;
@@ -57,14 +84,16 @@ align(size_t size)
return result;
}
-/* Set everything up and remember that we have. */
-static int
-initialize(void)
+/* Set everything up and remember that we have.
+ * Called within the lock in malloc(), so no
+ * explicit locking needed... */
+static int initialize(void)
{
heapsize = HEAP / BLOCKSIZE;
_heapinfo = align(heapsize * sizeof (union info));
- if (!_heapinfo)
+ if (!_heapinfo) {
return 0;
+ }
memset(_heapinfo, 0, heapsize * sizeof (union info));
_heapinfo[0].free.size = 0;
_heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
@@ -74,14 +103,15 @@ initialize(void)
return 1;
}
-/* Get neatly aligned memory, initializing or growing the
- heap info table as necessary. */
-static void *
-morecore(size_t size)
+/* Get neatly aligned memory, initializing or growing the
+ * heap info table as necessary.
+ * Called within a lock in malloc() and free(),
+ * so no explicit locking needed... */
+static void * morecore(size_t size)
{
void *result;
union info *newinfo, *oldinfo;
- int newsize;
+ size_t newsize;
result = align(size);
if (!result)
@@ -104,11 +134,7 @@ morecore(size_t size)
newinfo[BLOCK(oldinfo)].busy.info.size
= BLOCKIFY(heapsize * sizeof (union info));
_heapinfo = newinfo;
-#if 0
- free(oldinfo);
-#else
- _free_internal (oldinfo);
-#endif
+ free_unlocked(oldinfo);
heapsize = newsize;
}
@@ -116,16 +142,42 @@ morecore(size_t size)
return result;
}
+/* Note that morecore has to take a signed argument so
+ that negative values can return memory to the system. */
+static void * __default_morecore_init(long size)
+{
+ void *result;
+
+ result = sbrk(size);
+ if (result == (void *) -1)
+ return NULL;
+ return result;
+}
+
/* Allocate memory from the heap. */
-void *
-malloc (size_t size)
+void * malloc (size_t size)
+{
+ void * ptr;
+ LOCK;
+ ptr = malloc_unlocked(size);
+ UNLOCK;
+ return(ptr);
+}
+
+static void * malloc_unlocked (size_t size)
{
void *result;
- int log, block, blocks, i, lastblocks, start;
+ size_t log, block, blocks, i, lastblocks, start;
struct list *next;
- if (!initialized && !initialize())
+#if 1
+ /* Some programs will call malloc (0). Lets be strict and return NULL */
+ if (size == 0)
return NULL;
+#endif
+
+ if (size < sizeof (struct list))
+ size = sizeof (struct list);
#if 1
/* Some programs will call malloc (0). Lets be strict and return NULL */
@@ -136,6 +188,10 @@ malloc (size_t size)
if (size < sizeof (struct list))
size = sizeof (struct list);
+ if (!initialized && !initialize()) {
+ return NULL;
+ }
+
/* Determine the allocation policy based on the request size. */
if (size <= BLOCKSIZE / 2) {
/* Small allocation to receive a fragment of a block. Determine
@@ -162,9 +218,10 @@ malloc (size_t size)
} else {
/* No free fragments of the desired size, so get a new block
and break it into fragments, returning the first. */
- result = malloc(BLOCKSIZE);
- if (!result)
+ result = malloc_unlocked(BLOCKSIZE);
+ if (!result) {
return NULL;
+ }
++_fragblocks[log];
/* Link all fragments but the first into the free list. */
@@ -213,8 +270,9 @@ malloc (size_t size)
continue;
}
result = morecore(blocks * BLOCKSIZE);
- if (!result)
+ if (!result) {
return NULL;
+ }
block = BLOCK(result);
_heapinfo[block].busy.type = 0;
_heapinfo[block].busy.info.size = blocks;
@@ -252,3 +310,242 @@ malloc (size_t size)
return result;
}
+
+
+
+/* Return memory to the heap. */
+void free(void *ptr)
+{
+ LOCK;
+ free_unlocked(ptr);
+ UNLOCK;
+}
+
+static void free_unlocked(void *ptr)
+{
+ int block, blocks, i, type;
+ struct list *prev, *next;
+
+ if (ptr == NULL)
+ return;
+
+ block = BLOCK(ptr);
+
+ switch (type = _heapinfo[block].busy.type) {
+ case 0:
+ /* Find the free cluster previous to this one in the free list.
+ Start searching at the last block referenced; this may benefit
+ programs with locality of allocation. */
+ i = _heapindex;
+ if (i > block)
+ while (i > block)
+ i = _heapinfo[i].free.prev;
+ else {
+ do
+ i = _heapinfo[i].free.next;
+ while (i > 0 && i < block);
+ i = _heapinfo[i].free.prev;
+ }
+
+ /* Determine how to link this block into the free list. */
+ if (block == i + _heapinfo[i].free.size) {
+ /* Coalesce this block with its predecessor. */
+ _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
+ block = i;
+ } else {
+ /* Really link this block back into the free list. */
+ _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
+ _heapinfo[block].free.next = _heapinfo[i].free.next;
+ _heapinfo[block].free.prev = i;
+ _heapinfo[i].free.next = block;
+ _heapinfo[_heapinfo[block].free.next].free.prev = block;
+ }
+
+ /* Now that the block is linked in, see if we can coalesce it
+ with its successor (by deleting its successor from the list
+ and adding in its size). */
+ if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) {
+ _heapinfo[block].free.size
+ += _heapinfo[_heapinfo[block].free.next].free.size;
+ _heapinfo[block].free.next
+ = _heapinfo[_heapinfo[block].free.next].free.next;
+ _heapinfo[_heapinfo[block].free.next].free.prev = block;
+ }
+
+ /* Now see if we can return stuff to the system. */
+ blocks = _heapinfo[block].free.size;
+ if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
+ && (*__morecore)(0) == ADDRESS(block + blocks)) {
+ _heaplimit -= blocks;
+ (*__morecore)(-blocks * BLOCKSIZE);
+ _heapinfo[_heapinfo[block].free.prev].free.next
+ = _heapinfo[block].free.next;
+ _heapinfo[_heapinfo[block].free.next].free.prev
+ = _heapinfo[block].free.prev;
+ block = _heapinfo[block].free.prev;
+ }
+
+ /* Set the next search to begin at this block. */
+ _heapindex = block;
+ break;
+
+ default:
+ /* Get the address of the first free fragment in this block. */
+ prev = (struct list *) ((char *) ADDRESS(block)
+ + (_heapinfo[block].busy.info.frag.first
+ << type));
+
+ if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1
+ && _fragblocks[type] > 1) {
+ /* If all fragments of this block are free, remove them
+ from the fragment list and free the whole block. */
+ --_fragblocks[type];
+ for (next = prev, i = 1; i < BLOCKSIZE >> type; ++i)
+ next = next->next;
+ prev->prev->next = next;
+ if (next)
+ next->prev = prev->prev;
+ _heapinfo[block].busy.type = 0;
+ _heapinfo[block].busy.info.size = 1;
+ free_unlocked(ADDRESS(block));
+ } else if (_heapinfo[block].busy.info.frag.nfree) {
+ /* If some fragments of this block are free, link this fragment
+ into the fragment list after the first free fragment of
+ this block. */
+ next = ptr;
+ next->next = prev->next;
+ next->prev = prev;
+ prev->next = next;
+ if (next->next)
+ next->next->prev = next;
+ ++_heapinfo[block].busy.info.frag.nfree;
+ } else {
+ /* No fragments of this block are free, so link this fragment
+ into the fragment list and announce that it is the first
+ free fragment of this block. */
+ prev = (struct list *) ptr;
+ _heapinfo[block].busy.info.frag.nfree = 1;
+ _heapinfo[block].busy.info.frag.first
+ = (unsigned int) ((char *) ptr - (char *) NULL) % BLOCKSIZE
+ >> type;
+ prev->next = _fraghead[type].next;
+ prev->prev = &_fraghead[type];
+ prev->prev->next = prev;
+ if (prev->next)
+ prev->next->prev = prev;
+ }
+ break;
+ }
+}
+
+/* Resize the given region to the new size, returning a pointer
+ to the (possibly moved) region. This is optimized for speed;
+ some benchmarks seem to indicate that greater compactness is
+ achieved by unconditionally allocating and copying to a
+ new region. */
+void * realloc (void *ptr, size_t size)
+{
+ void *result, *previous;
+ size_t block, blocks, type;
+ size_t oldlimit;
+
+ if (!ptr)
+ return malloc(size);
+ if (!size) {
+ LOCK;
+ free_unlocked(ptr);
+ result = malloc_unlocked(0);
+ UNLOCK;
+ return(result);
+ }
+
+ LOCK;
+ block = BLOCK(ptr);
+
+ switch (type = _heapinfo[block].busy.type) {
+ case 0:
+ /* Maybe reallocate a large block to a small fragment. */
+ if (size <= BLOCKSIZE / 2) {
+ if ((result = malloc_unlocked(size)) != NULL) {
+ memcpy(result, ptr, size);
+ free(ptr);
+ }
+ UNLOCK;
+ return result;
+ }
+
+ /* The new size is a large allocation as well; see if
+ we can hold it in place. */
+ blocks = BLOCKIFY(size);
+ if (blocks < _heapinfo[block].busy.info.size) {
+ /* The new size is smaller; return excess memory
+ to the free list. */
+ _heapinfo[block + blocks].busy.type = 0;
+ _heapinfo[block + blocks].busy.info.size
+ = _heapinfo[block].busy.info.size - blocks;
+ _heapinfo[block].busy.info.size = blocks;
+ free(ADDRESS(block + blocks));
+ UNLOCK;
+ return ptr;
+ } else if (blocks == _heapinfo[block].busy.info.size) {
+ /* No size change necessary. */
+ UNLOCK;
+ return ptr;
+ } else {
+ /* Won't fit, so allocate a new region that will. Free
+ the old region first in case there is sufficient adjacent
+ free space to grow without moving. */
+ blocks = _heapinfo[block].busy.info.size;
+ /* Prevent free from actually returning memory to the system. */
+ oldlimit = _heaplimit;
+ _heaplimit = 0;
+ free(ptr);
+ _heaplimit = oldlimit;
+ result = malloc_unlocked(size);
+ if (!result) {
+ /* Now we're really in trouble. We have to unfree
+ the thing we just freed. Unfortunately it might
+ have been coalesced with its neighbors. */
+ if (_heapindex == block)
+ malloc_unlocked(blocks * BLOCKSIZE);
+ else {
+ previous = malloc_unlocked((block - _heapindex) * BLOCKSIZE);
+ malloc_unlocked(blocks * BLOCKSIZE);
+ free(previous);
+ }
+ UNLOCK;
+ return NULL;
+ }
+ if (ptr != result)
+ memmove(result, ptr, blocks * BLOCKSIZE);
+ UNLOCK;
+ return result;
+ }
+ break;
+
+ default:
+ /* Old size is a fragment; type is logarithm to base two of
+ the fragment size. */
+ if ((size > 1 << (type - 1)) && (size <= 1 << type)) {
+ /* New size is the same kind of fragment. */
+ UNLOCK;
+ return ptr;
+ }
+ else {
+ /* New size is different; allocate a new space, and copy
+ the lesser of the new size and the old. */
+ result = malloc_unlocked(size);
+ if (!result) {
+ UNLOCK;
+ return NULL;
+ }
+ memcpy(result, ptr, MIN(size, (size_t)(1 << type)));
+ free(ptr);
+ UNLOCK;
+ return result;
+ }
+ break;
+ }
+ UNLOCK;
+}
+
diff --git a/libc/stdlib/malloc-930716/malloc.h b/libc/stdlib/malloc-930716/malloc.h
index 34458c062..fc21a13cc 100644
--- a/libc/stdlib/malloc-930716/malloc.h
+++ b/libc/stdlib/malloc-930716/malloc.h
@@ -10,23 +10,13 @@
#include <sys/cdefs.h>
-/* Underlying allocation function; successive calls should return
- contiguous pieces of memory. */
-extern void *(*__morecore)(long);
-
-/* Default value of previous. */
-extern void *__default_morecore_init(long);
-extern void *__default_morecore(long);
-
/* The allocator divides the heap into blocks of fixed size; large
requests receive one or more whole blocks, and small requests
receive a fragment of a block. Fragment sizes are powers of two,
and all fragments of a block are the same size. When all the
fragments in a block have been freed, the block itself is freed.
- WARNING: BLOCKSIZE must be set greater than or equal to the
- machine's page size for valloc() to work correctly. The default
- definition here is 4096 bytes. */
-#define INT_BIT (CHAR_BIT * sizeof (int))
+ */
+#define INT_BIT (CHAR_BIT * sizeof (size_t))
#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
#define BLOCKSIZE (1 << BLOCKLOG)
#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
@@ -42,66 +32,31 @@ extern void *__default_morecore(long);
/* Data structure giving per-block information. */
union info {
struct {
- int type; /* Zero for a large block, or positive
+ size_t type; /* Zero for a large block, or positive
giving the logarithm to the base two
of the fragment size. */
union {
struct {
- int nfree; /* Free fragments in a fragmented block. */
- int first; /* First free fragment of the block. */
+ size_t nfree; /* Free fragments in a fragmented block. */
+ size_t first; /* First free fragment of the block. */
} frag;
- int size; /* Size (in blocks) of a large cluster. */
+ size_t size; /* Size (in blocks) of a large cluster. */
} info;
} busy;
struct {
- int size; /* Size (in blocks) of a free cluster. */
- int next; /* Index of next free cluster. */
- int prev; /* Index of previous free cluster. */
+ size_t size; /* Size (in blocks) of a free cluster. */
+ size_t next; /* Index of next free cluster. */
+ size_t prev; /* Index of previous free cluster. */
} free;
};
-/* Pointer to first block of the heap. */
-extern char *_heapbase;
-
-/* Table indexed by block number giving per-block information. */
-extern union info *_heapinfo;
-
/* Address to block number and vice versa. */
#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + _heapbase))
-/* Current search index for the heap table. */
-extern int _heapindex;
-
-/* Limit of valid info table indices. */
-extern int _heaplimit;
-
/* Doubly linked lists of free fragments. */
struct list {
struct list *next;
struct list *prev;
};
-/* Count of blocks for each fragment size. */
-extern int _fragblocks[];
-
-/* Free list headers for each fragment size. */
-extern struct list _fraghead[];
-
-/* List of blocks allocated with `memalign' (or `valloc'). */
-struct alignlist
-{
- struct alignlist *next;
- __ptr_t aligned; /* The address that memaligned returned. */
- __ptr_t exact; /* The address that malloc returned. */
-};
-extern struct alignlist *_aligned_blocks;
-
-extern void _free_internal __P ((__ptr_t __ptr));
-
-extern void free (void *);
-extern void * malloc (size_t);
-extern void * calloc (size_t, size_t);
-extern void * valloc (size_t);
-extern void * memalign (size_t, size_t);
-extern void * realloc (void *, size_t);
diff --git a/libc/stdlib/malloc-930716/memalign.c b/libc/stdlib/malloc-930716/memalign.c
deleted file mode 100644
index 1098f5890..000000000
--- a/libc/stdlib/malloc-930716/memalign.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <stdlib.h>
-#include "malloc.h"
-
-__ptr_t
-memalign (alignment, size)
- size_t alignment;
- size_t size;
-{
- __ptr_t result;
- unsigned long int adj;
-
- result = malloc (size + alignment - 1);
- if (result == NULL)
- return NULL;
- adj = (unsigned long int) ((unsigned long int) ((char *) result -
- (char *) NULL)) % alignment;
- if (adj != 0)
- {
- struct alignlist *l;
- for (l = _aligned_blocks; l != NULL; l = l->next)
- if (l->aligned == NULL)
- /* This slot is free. Use it. */
- break;
- if (l == NULL)
- {
- l = (struct alignlist *) malloc (sizeof (struct alignlist));
- if (l == NULL)
- {
-#if 1
- free (result);
-#else
- _free_internal (result);
-#endif
- return NULL;
- }
- l->next = _aligned_blocks;
- _aligned_blocks = l;
- }
- l->exact = result;
- result = l->aligned = (char *) result + alignment - adj;
- }
-
- return result;
-}
diff --git a/libc/stdlib/malloc-930716/morecore.c b/libc/stdlib/malloc-930716/morecore.c
deleted file mode 100644
index e2ad4464b..000000000
--- a/libc/stdlib/malloc-930716/morecore.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* morecore.c - C library support routine for UNIX.
- Copyright (c) 1989, 1993 Michael J. Haertel
- You may redistribute this library under the terms of the
- GNU Library General Public License (version 2 or any later
- version) as published by the Free Software Foundation.
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
- WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR
- WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
- SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */
-
-#include <limits.h>
-#include <stddef.h>
-#include "malloc.h"
-
-extern void *sbrk(int);
-
-/* Note that morecore has to take a signed argument so
- that negative values can return memory to the system. */
-void *
-__default_morecore_init(long size)
-{
- void *result;
-
- result = sbrk(size);
- if (result == (void *) -1)
- return NULL;
- return result;
-}
diff --git a/libc/stdlib/malloc-930716/realloc.c b/libc/stdlib/malloc-930716/realloc.c
deleted file mode 100644
index 1453e813c..000000000
--- a/libc/stdlib/malloc-930716/realloc.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* realloc.c - C standard library routine.
- Copyright (c) 1989, 1993 Michael J. Haertel
- You may redistribute this library under the terms of the
- GNU Library General Public License (version 2 or any later
- version) as published by the Free Software Foundation.
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
- WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR
- WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
- SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include "malloc.h"
-
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-
-/* Resize the given region to the new size, returning a pointer
- to the (possibly moved) region. This is optimized for speed;
- some benchmarks seem to indicate that greater compactness is
- achieved by unconditionally allocating and copying to a
- new region. */
-void *
-realloc (void *ptr, size_t size)
-{
- void *result, *previous;
- int block, blocks, type;
- int oldlimit;
-
- if (!ptr)
- return malloc(size);
- if (!size) {
- free(ptr);
- return malloc(0);
- }
-
- block = BLOCK(ptr);
-
- switch (type = _heapinfo[block].busy.type) {
- case 0:
- /* Maybe reallocate a large block to a small fragment. */
- if (size <= BLOCKSIZE / 2) {
- if ((result = malloc(size)) != NULL) {
- memcpy(result, ptr, size);
-#if 1
- free(ptr);
-#else
- _free_internal(ptr);
-#endif
-
- }
- return result;
- }
-
- /* The new size is a large allocation as well; see if
- we can hold it in place. */
- blocks = BLOCKIFY(size);
- if (blocks < _heapinfo[block].busy.info.size) {
- /* The new size is smaller; return excess memory
- to the free list. */
- _heapinfo[block + blocks].busy.type = 0;
- _heapinfo[block + blocks].busy.info.size
- = _heapinfo[block].busy.info.size - blocks;
- _heapinfo[block].busy.info.size = blocks;
-#if 1
- free(ADDRESS(block + blocks));
-#else
- _free_internal(ADDRESS(block + blocks));
-#endif
- return ptr;
- } else if (blocks == _heapinfo[block].busy.info.size)
- /* No size change necessary. */
- return ptr;
- else {
- /* Won't fit, so allocate a new region that will. Free
- the old region first in case there is sufficient adjacent
- free space to grow without moving. */
- blocks = _heapinfo[block].busy.info.size;
- /* Prevent free from actually returning memory to the system. */
- oldlimit = _heaplimit;
- _heaplimit = 0;
-#if 1
- free(ptr);
-#else
- _free_internal(ptr);
-#endif
- _heaplimit = oldlimit;
- result = malloc(size);
- if (!result) {
- /* Now we're really in trouble. We have to unfree
- the thing we just freed. Unfortunately it might
- have been coalesced with its neighbors. */
- if (_heapindex == block)
- malloc(blocks * BLOCKSIZE);
- else {
- previous = malloc((block - _heapindex) * BLOCKSIZE);
- malloc(blocks * BLOCKSIZE);
-#if 1
- free(previous);
-#else
- _free_internal(previous);
-#endif
- }
- return NULL;
- }
- if (ptr != result)
- memmove(result, ptr, blocks * BLOCKSIZE);
- return result;
- }
- break;
-
- default:
- /* Old size is a fragment; type is logarithm to base two of
- the fragment size. */
- if ((size > 1 << (type - 1)) && (size <= 1 << type))
- /* New size is the same kind of fragment. */
- return ptr;
- else {
- /* New size is different; allocate a new space, and copy
- the lesser of the new size and the old. */
- result = malloc(size);
- if (!result)
- return NULL;
- memcpy(result, ptr, MIN(size, 1 << type));
- free(ptr);
- return result;
- }
- break;
- }
-}
diff --git a/libc/stdlib/malloc-930716/valloc.c b/libc/stdlib/malloc-930716/valloc.c
deleted file mode 100644
index dad12a1d2..000000000
--- a/libc/stdlib/malloc-930716/valloc.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Allocate memory on a page boundary.
- Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
-
- The author may be reached (Email) at the address mike@ai.mit.edu,
- or (US mail) as Mike Haertel c/o Free Software Foundation. */
-
-#include <stdlib.h>
-#include "malloc.h"
-
-#ifdef emacs
-#include "config.h"
-#endif
-
-#ifdef __GNU_LIBRARY__
-extern size_t __getpagesize __P ((void));
-#else
-#ifndef USG
-extern size_t getpagesize __P ((void));
-#define __getpagesize() getpagesize()
-#else
-#include <sys/param.h>
-#ifdef EXEC_PAGESIZE
-#define __getpagesize() EXEC_PAGESIZE
-#else /* No EXEC_PAGESIZE. */
-#ifdef NBPG
-#ifndef CLSIZE
-#define CLSIZE 1
-#endif /* No CLSIZE. */
-#define __getpagesize() (NBPG * CLSIZE)
-#else /* No NBPG. */
-#define __getpagesize() NBPC
-#endif /* NBPG. */
-#endif /* EXEC_PAGESIZE. */
-#endif /* USG. */
-#endif
-
-static size_t pagesize;
-
-__ptr_t
-valloc (size)
- size_t size;
-{
- if (pagesize == 0)
- pagesize = __getpagesize ();
-
- return memalign (pagesize, size);
-}