From 87ec87b5f570eeebb4b699140838ecd484ef8c1a Mon Sep 17 00:00:00 2001 From: kcwu Date: Sun, 27 May 2007 14:08:31 +0000 Subject: * import dietlibc's allocator. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3518 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- mbbsd/Makefile | 2 +- mbbsd/alloc.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 mbbsd/alloc.c (limited to 'mbbsd') diff --git a/mbbsd/Makefile b/mbbsd/Makefile index fb7d1638..70775694 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -18,7 +18,7 @@ OBJS= admin.o announce.o args.o assess.o bbs.o board.o cache.o cal.o card.o\ pmore.o chess.o .if defined(DIET) -OBJS+= random.o time.o +OBJS+= random.o time.o alloc.o DIETCC= diet -Os .endif #CFLAGS+=-g diff --git a/mbbsd/alloc.c b/mbbsd/alloc.c new file mode 100644 index 00000000..06b84177 --- /dev/null +++ b/mbbsd/alloc.c @@ -0,0 +1,236 @@ +/* + * malloc/free by O.Dreesen + * + * first TRY: + * lists w/magics + * and now the second TRY + * let the kernel map all the stuff (if there is something to do) + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include /* for PAGE_SIZE */ + + +/* -- HELPER CODE --------------------------------------------------------- */ + +#ifndef MAP_FAILED +#define MAP_FAILED ((void*)-1) +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif + +typedef struct { + void* next; + size_t size; +} __alloc_t; + +#define BLOCK_START(b) (((void*)(b))-sizeof(__alloc_t)) +#define BLOCK_RET(b) (((void*)(b))+sizeof(__alloc_t)) + +#define MEM_BLOCK_SIZE PAGE_SIZE +#define PAGE_ALIGN(s) (((s)+MEM_BLOCK_SIZE-1)&(unsigned long)(~(MEM_BLOCK_SIZE-1))) + +/* a simple mmap :) */ +#if defined(__i386__) +#define REGPARM(x) __attribute__((regparm(x))) +#else +#define REGPARM(x) +#endif + +static void REGPARM(1) *do_mmap(size_t size) { + return mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (size_t)0); +} + +/* -- SMALL MEM ----------------------------------------------------------- */ + +static __alloc_t* __small_mem[8]; + +#define __SMALL_NR(i) (MEM_BLOCK_SIZE/(i)) + +#define __MIN_SMALL_SIZE __SMALL_NR(256) /* 16 / 32 */ +#define __MAX_SMALL_SIZE __SMALL_NR(2) /* 2048 / 4096 */ + +#define GET_SIZE(s) (__MIN_SMALL_SIZE<>__ind_shift(); + while(size) { size>>=1; ++idx; } +// } + return idx; +} + +/* small mem */ +static void __small_free(void*_ptr,size_t _size) REGPARM(2); + +static void REGPARM(2) __small_free(void*_ptr,size_t _size) { + __alloc_t* ptr=BLOCK_START(_ptr); + size_t size=_size; + size_t idx=get_index(size); + + memset(ptr,0,size); /* allways zero out small mem */ + + ptr->next=__small_mem[idx]; + __small_mem[idx]=ptr; +} + +static void* REGPARM(1) __small_malloc(size_t _size) { + __alloc_t *ptr; + size_t size=_size; + size_t idx; + + idx=get_index(size); + ptr=__small_mem[idx]; + + if (ptr==0) { /* no free blocks ? */ + register int i,nr; + ptr=do_mmap(MEM_BLOCK_SIZE); + if (ptr==MAP_FAILED) return MAP_FAILED; + + __small_mem[idx]=ptr; + + nr=__SMALL_NR(size)-1; + for (i=0;inext=(((void*)ptr)+size); + ptr=ptr->next; + } + ptr->next=0; + + ptr=__small_mem[idx]; + } + + /* get a free block */ + __small_mem[idx]=ptr->next; + ptr->next=0; + + return ptr; +} + +/* -- PUBLIC FUNCTIONS ---------------------------------------------------- */ + +static void _alloc_libc_free(void *ptr) { + register size_t size; + if (ptr) { + size=((__alloc_t*)BLOCK_START(ptr))->size; + if (size) { + if (size<=__MAX_SMALL_SIZE) + __small_free(ptr,size); + else + munmap(BLOCK_START(ptr),size); + } + } +} +void __libc_free(void *ptr) __attribute__((alias("_alloc_libc_free"))); +void free(void *ptr) __attribute__((weak,alias("_alloc_libc_free"))); +void if_freenameindex(void* ptr) __attribute__((alias("free"))); + +#ifdef WANT_MALLOC_ZERO +static __alloc_t zeromem[2]; +#endif + +static void* _alloc_libc_malloc(size_t size) { + __alloc_t* ptr; + size_t need; +#ifdef WANT_MALLOC_ZERO + if (!size) return BLOCK_RET(zeromem); +#else + if (!size) goto err_out; +#endif + size+=sizeof(__alloc_t); + if (sizesize=need; + return BLOCK_RET(ptr); +err_out: + (*__errno_location())=ENOMEM; + return 0; +} +void* __libc_malloc(size_t size) __attribute__((alias("_alloc_libc_malloc"))); +void* malloc(size_t size) __attribute__((weak,alias("_alloc_libc_malloc"))); + +void* __libc_calloc(size_t nmemb, size_t _size); +void* __libc_calloc(size_t nmemb, size_t _size) { + register size_t size=_size*nmemb; + if (nmemb && size/nmemb!=_size) { + (*__errno_location())=ENOMEM; + return 0; + } + return malloc(size); +} +void* calloc(size_t nmemb, size_t _size) __attribute__((weak,alias("__libc_calloc"))); + +void* __libc_realloc(void* ptr, size_t _size); +void* __libc_realloc(void* ptr, size_t _size) { + register size_t size=_size; + if (ptr) { + if (size) { + __alloc_t* tmp=BLOCK_START(ptr); + size+=sizeof(__alloc_t); + if (sizesize!=size) { + if ((tmp->size<=__MAX_SMALL_SIZE)) { + void *new=_alloc_libc_malloc(_size); + if (new) { + register __alloc_t* foo=BLOCK_START(new); + size=foo->size; + if (size>tmp->size) size=tmp->size; + if (size) memcpy(new,ptr,size-sizeof(__alloc_t)); + _alloc_libc_free(ptr); + } + ptr=new; + } + else { + register __alloc_t* foo; + size=PAGE_ALIGN(size); + foo=mremap(tmp,tmp->size,size,MREMAP_MAYMOVE); + if (foo==MAP_FAILED) { +retzero: + (*__errno_location())=ENOMEM; + ptr=0; + } + else { + foo->size=size; + ptr=BLOCK_RET(foo); + } + } + } + } + else { /* size==0 */ + _alloc_libc_free(ptr); + ptr = NULL; + } + } + else { /* ptr==0 */ + if (size) { + ptr=_alloc_libc_malloc(size); + } + } + return ptr; +} +void* realloc(void* ptr, size_t size) __attribute__((weak,alias("__libc_realloc"))); + -- cgit v1.2.3