1N/A * See the file LICENSE for redistribution information. 1N/A * Copyright (c) 1996, 1997, 1998 1N/A * Sleepycat Software. All rights reserved. 1N/A#
endif /* not lint */ 1N/A * Implement shared memory region allocation, using simple first-fit algorithm. 1N/A * The model is that we take a "chunk" of shared memory store and begin carving 1N/A * it up into areas, similarly to how malloc works. We do coalescing on free. 1N/A * The "len" field in the __data struct contains the length of the free region 1N/A * (less the size_t bytes that holds the length). We use the address provided 1N/A * by the caller to find this length, which allows us to free a chunk without 1N/A * requiring that the caller pass in the length of the chunk they're freeing. 1N/A * __db_shalloc_init -- 1N/A * Initialize the area as one large chunk. 1N/A * PUBLIC: void __db_shalloc_init __P((void *, size_t)); 1N/A * Allocate some space from the shared region. 1N/A * PUBLIC: int __db_shalloc __P((void *, size_t, size_t, void *)); 1N/A * We never allocate less than the size of a struct __data, align 1N/A * to less than a size_t boundary, or align to something that's not 1N/A * a multiple of a size_t. 1N/A /* Walk the list, looking for a slot. */ 1N/A * Calculate the value of the returned pointer if we were to 1N/A * + Find the end of the chunk. 1N/A * + Subtract the memory the user wants. 1N/A * + Find the closest previous correctly-aligned address. 1N/A * Rp may now point before elp->links, in which case the chunk 1N/A * was too small, and we have to try again. 1N/A * If there are at least SHALLOC_FRAGMENT additional bytes of 1N/A * memory, divide the chunk into two chunks. 1N/A * Otherwise, we return the entire chunk, wasting some amount 1N/A * of space to keep the list compact. However, because the 1N/A * address we're returning to the user may not be the address 1N/A * of the start of the region for alignment reasons, set the 1N/A * size_t length fields back to the "real" length field to a 1N/A * flag value, so that we can find the real length during free. 1N/A /* Nothing found large enough; need to grow the region. */ 1N/A * __db_shalloc_free -- 1N/A * Free a shared memory allocation. 1N/A * PUBLIC: void __db_shalloc_free __P((void *, void *)); 1N/A * Step back over flagged length fields to find the beginning of 1N/A * the object and its real size. 1N/A /* Trash the returned memory. */ 1N/A * Walk the list, looking for where this entry goes. 1N/A * We keep the free list sorted by address so that coalescing is 1N/A * Probably worth profiling this to see how expensive it is. 1N/A * Elp is either NULL (we reached the end of the list), or the slot 1N/A * after the one that's being returned. Lastp is either NULL (we're 1N/A * returning the first element of the list) or the element before the 1N/A * one being returned. 1N/A * Check for coalescing with the next element. 1N/A /* Check for coalescing with the previous element. */ 1N/A * If we have already put the new element into the list take 1N/A * it back off again because it's just been merged with the 1N/A * __db_shalloc_count -- 1N/A * Return the amount of memory on the free list. 1N/A * PUBLIC: size_t __db_shalloc_count __P((void *)); 1N/A * Return the size of a shalloc'd piece of memory. 1N/A * PUBLIC: size_t __db_shsizeof __P((void *)); 1N/A * Step back over flagged length fields to find the beginning of 1N/A * the object and its real size. 1N/A * __db_shalloc_dump -- 1N/A * PUBLIC: void __db_shalloc_dump __P((void *, FILE *)); 1N/A /* Make it easy to call from the debugger. */