diff options
Diffstat (limited to 'apps/plugins/pdbox/dbestfit-3.3/bmalloc.c')
-rw-r--r-- | apps/plugins/pdbox/dbestfit-3.3/bmalloc.c | 371 |
1 files changed, 0 insertions, 371 deletions
diff --git a/apps/plugins/pdbox/dbestfit-3.3/bmalloc.c b/apps/plugins/pdbox/dbestfit-3.3/bmalloc.c deleted file mode 100644 index f0ac7312a4..0000000000 --- a/apps/plugins/pdbox/dbestfit-3.3/bmalloc.c +++ /dev/null @@ -1,371 +0,0 @@ -/***************************************************************************** - * - * Big (best-fit) Memory Allocation - * - * Author: Daniel Stenberg - * Date: March 5, 1997 - * Version: 2.0 - * Email: Daniel.Stenberg@sth.frontec.se - * - * - * Read 'thoughts' for theories and details in implementation. - * - * Routines meant to replace the most low level functions of an Operting - * System - * - * v2.0 - * - Made all size-routines get moved out from this file. This way, the size - * functions can much more easily get replaced. - * - Improved how new memory blocks get added to the size-sorted list. When - * not adding new pools, there should never ever be any list traversing - * since all information is dynamically gathered. - * - ****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> - -#include "bysize.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* #define DEBUG */ - -#define BMEM_ALIGN 64 /* resolution */ - -#define BMEMERR_TOOSMALL -1 - -/* this struct will be stored in all CHUNKS and AREAS */ -struct BlockInfo { - struct BlockInfo *lower; /* previous block in memory (lower address) */ - struct BlockInfo *higher; /* next block in memory (higher address) */ - unsigned long info; /* 31 bits size: 1 bit free boolean */ -#define INFO_FREE 1 -#define INFO_SIZE (~ INFO_FREE) /* inverted FREE bit pattern */ - - /* FREE+SIZE Could be written to use ordinary bitfields if using a smart - (like gcc) compiler in a manner like: - int size:31; - int free:1; - - The 'higher' pointer COULD be removed completely if the size is used as - an index to the higher one. This would then REQUIRE the entire memory - pool to be contiguous and it needs a 'terminating' "node" or an extra - flag that informs about the end of the list. - */ -}; - -/* the BLOCK list should be sorted in a lower to higher address order */ -struct BlockInfo *blockHead=NULL; /* nothing from the start */ - -void print_lists(void); - - -/*********************************************************************** - * - * remove_block() - * - * Remove the block from the address-sorted list. - * - ***********************************************************************/ - -void remove_block(struct BlockInfo *block) -{ - if(block->lower) - block->lower->higher = block->higher; - else - blockHead = block->higher; - if(block->higher) - block->higher->lower = block->lower; -} - -/**************************************************************************** - * - * add_blocktolists() - * - * Adds the specified block at the specified place in the address-sorted - * list and at the appropriate place in the size-sorted. - * - ***************************************************************************/ -void add_blocktolists(struct BlockInfo *block, - struct BlockInfo *newblock, - size_t newsize) -{ - struct BlockInfo *temp; /* temporary storage variable */ - if(block) { - /* `block' is now a lower address than 'newblock' */ - - /* - * Check if the new CHUNK is wall-to-wall with the lower addressed - * one (if *that* is free) - */ - if(block->info&INFO_FREE) { - if((char *)block + (block->info&INFO_SIZE) == (char *)newblock) { - /* yes sir, this is our lower address neighbour, enlarge that one - pick it out from the list and recursively add that chunk and - then we escape */ - - /* remove from size-sorted list: */ - remove_chunksize((char*)block+sizeof(struct BlockInfo)); - - block->info += newsize; /* newsize is an even number and thus the FREE - bit is untouched */ - - remove_block(block); /* unlink the block address-wise */ - - /* recursively check our lower friend(s) */ - add_blocktolists(block->lower, block, block->info&INFO_SIZE); - return; - } - } - - temp = block->higher; - - block->higher = newblock; - newblock->lower = block; - newblock->higher = temp; - if(newblock->higher) - newblock->higher->lower = newblock; - } - else { - /* this block should preceed the heading one */ - temp = blockHead; - - /* check if this is our higher addressed neighbour */ - if((char *)newblock + newsize == (char *)temp) { - - /* yes, we are wall-to-wall with the higher CHUNK */ - if(temp->info&INFO_FREE) { - /* and the neighbour is even free, remove that one and enlarge - ourselves, call add_pool() recursively and then escape */ - - remove_block(temp); /* unlink 'temp' from list */ - - /* remove from size-sorted list: */ - remove_chunksize((char*)temp+sizeof(struct BlockInfo) ); - - /* add the upper block's size on ourselves */ - newsize += temp->info&INFO_SIZE; - - /* add the new, bigger block */ - add_blocktolists(block, newblock, newsize); - return; - } - } - - blockHead = newblock; - newblock->higher = temp; - newblock->lower = NULL; /* there is no lower one */ - if(newblock->higher) - newblock->higher->lower = newblock; - } - - newblock->info = newsize | INFO_FREE; /* we do assume size isn't using the - FREE bit */ - insert_bysize((char *)newblock+sizeof(struct BlockInfo), newsize); -} - -/*********************************************************************** - * - * findblockbyaddr() - * - * Find the block that is just before the input block in memory. Returns NULL - * if none is. - * - ***********************************************************************/ - -static struct BlockInfo *findblockbyaddr(struct BlockInfo *block) -{ - struct BlockInfo *test = blockHead; - struct BlockInfo *lower = NULL; - - while(test && (test < block)) { - lower = test; - test = test->higher; - } - return lower; -} - -/*********************************************************************** - * - * add_pool() - * - * This function should be the absolutely first function to call. It sets up - * the memory bounds of the [first] CHUNK(s). It should be possible to call - * this function several times to add more CHUNKs to the pool of free - * memory. This allows the bmalloc system to deal with a non-contigous memory - * area. - * - * Returns non-zero if an error occured. The memory was not added then. - * - ***********************************************************************/ - -int add_pool(void *start, - size_t size) -{ - struct BlockInfo *newblock = (struct BlockInfo *)start; - struct BlockInfo *block; - - if(size < BMEM_ALIGN) - return BMEMERR_TOOSMALL; - - block = findblockbyaddr( newblock ); - /* `block' is now a lower address than 'newblock' or NULL */ - - if(size&1) - size--; /* only add even sizes */ - - add_blocktolists(block, newblock, size); - - return 0; -} - - -#ifdef DEBUG -static void bmalloc_failed(size_t size) -{ - printf("*** " __FILE__ " Couldn't allocate %d bytes\n", size); - print_lists(); -} -#else -#define bmalloc_failed(x) -#endif - -#ifdef DEBUG -void print_lists() -{ - struct BlockInfo *block = blockHead; -#if 1 - printf("List of BLOCKS (in address order):\n"); - while(block) { - printf(" START %p END %p SIZE %ld FLAG %s\n", - (char *)block, - (char *)block+(block->info&INFO_SIZE), block->info&INFO_SIZE, - (block->info&INFO_FREE)?"free":"used"); - block = block->higher; - } - printf("End of BLOCKS:\n"); -#endif - print_sizes(); -} -#endif /* DEBUG */ - -void *bmalloc(size_t size) -{ - void *mem; - -#ifdef DEBUG - { - static int count=0; - int realsize = size + sizeof(struct BlockInfo); - if(realsize%4096) - realsize = ((size / BMEM_ALIGN)+1) * BMEM_ALIGN; - printf("%d bmalloc(%d) [%d]\n", count++, size, realsize); - } -#endif - - size += sizeof(struct BlockInfo); /* add memory for our header */ - - if(size&(BMEM_ALIGN-1)) /* a lot faster than %BMEM_ALIGN but this MUST be - changed if the BLOCKSIZE is not 2^X ! */ - size = ((size / BMEM_ALIGN)+1) * BMEM_ALIGN; /* align like this */ - - /* get a CHUNK from the list with this size */ - mem = obtainbysize ( size ); - if(mem) { - /* the memory block we have got is the "best-fit" and it is already - un-linked from the free list */ - - /* now do the math to get the proper block pointer */ - struct BlockInfo *block= (struct BlockInfo *) - ((char *)mem - sizeof(struct BlockInfo)); - - block->info &= ~INFO_FREE; - /* not free anymore */ - - if( size != (block->info&INFO_SIZE)) { - /* split this chunk into two pieces and return the one that fits us */ - size_t othersize = (block->info&INFO_SIZE) - size; - - if(othersize > BMEM_ALIGN) { - /* prevent losing small pieces of memory due to weird alignments - of the memory pool */ - - block->info = size; /* set new size (leave FREE bit cleared) */ - - /* Add the new chunk to the lists: */ - add_blocktolists(block, - (struct BlockInfo *)((char *)block + size), - othersize ); - } - } - - /* Return the memory our parent may use: */ - return (char *)block+sizeof(struct BlockInfo); - } - else { - bmalloc_failed(size); - return NULL; /* can't find any memory, fail hard */ - } - return NULL; -} - -void bfree(void *ptr) -{ - struct BlockInfo *block = (struct BlockInfo *) - ((char *)ptr - sizeof(struct BlockInfo)); - size_t size; - - /* setup our initial higher and lower pointers */ - struct BlockInfo *lower = block->lower; - struct BlockInfo *higher = block->higher; - -#ifdef DEBUG - static int freecount=0; - printf("%d bfree(%p)\n", freecount++, ptr); -#endif - - /* bind together lower addressed FREE CHUNKS */ - if(lower && (lower->info&INFO_FREE) && - ((char *)lower + (lower->info&INFO_SIZE) == (char *)block)) { - size = block->info&INFO_SIZE; /* original size */ - - /* remove from size-link: */ - remove_chunksize((char *)lower+sizeof(struct BlockInfo)); - - remove_block(block); /* unlink from address list */ - block = lower; /* new base area pointer */ - block->info += size; /* append the new size (the FREE bit - will remain untouched) */ - - lower = lower->lower; /* new lower pointer */ - } - /* bind together higher addressed FREE CHUNKS */ - if(higher && (higher->info&INFO_FREE) && - ((char *)block + (block->info&INFO_SIZE) == (char *)higher)) { - /* append higher size, the FREE bit won't be affected */ - block->info += (higher->info&INFO_SIZE); - - /* unlink from size list: */ - remove_chunksize((char *)higher+sizeof(struct BlockInfo)); - remove_block(higher); /* unlink from address list */ - higher = higher->higher; /* the new higher link */ - block->higher = higher; /* new higher link */ - } - block->info |= INFO_FREE; /* consider this FREE! */ - - block->lower = lower; - block->higher = higher; - - insert_bysize((char *)block+sizeof(struct BlockInfo), block->info&INFO_SIZE); - -#ifdef DEBUG - print_lists(); -#endif - -} |