// Allocations are done in 'quantas' of header size. // The search for a free block of adequate size begins at the point 'freep' // where the last block was found. // If a too-big block is found, it is split and the tail is returned (this // way the header of the original needs only to have its size adjusted). // The pointer returned to the user points to the free space within the block, // which begins one quanta after the header. // void *memmgr_alloc(ulong nbytes, int *err) { mem_header_t *p; mem_header_t *prevp; *err = 0; // Calculate how many quantas are required: we need enough to house all // the requested bytes, plus the header. The -1 and +1 are there to make sure // that if nbytes is a multiple of nquantas, we don't allocate too much // ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1; // First alloc call, and no free list yet ? Use 'base' for an initial // denegerate block of size 0, which points to itself // if ((prevp = freep) == 0) { base.s.next = freep = prevp = &base; base.s.size = 0; } for (p = prevp->s.next;; prevp = p, p = p->s.next) { // big enough ? if (p->s.size >= nquantas) { // exactly ? if (p->s.size == nquantas) { // just eliminate this block from the free list by pointing // its prev's next to its next // prevp->s.next = p->s.next; } else // too big { p->s.size -= nquantas; p += p->s.size; p->s.size = nquantas; } freep = prevp; return (void *)(p + 1); } // Reached end of free list ? // Try to allocate the block from the pool. If that succeeds, // get_mem_from_pool adds the new block to the free list and // it will be found in the following iterations. If the call // to get_mem_from_pool doesn't succeed, we've run out of // memory // else if (p == freep) { if ((p = get_mem_from_pool(nquantas)) == 0) { *err = 1; return 0; } } } }
// Allocations are done in 'quantas' of header size. // The search for a free block of adequate size begins at the point 'memmgr.freep' // where the last block was found. // If a too-big block is found, it is split and the tail is returned (this // way the header of the original needs only to have its size adjusted). // The pointer returned to the user points to the free space within the block, // which begins one quanta after the header. // void* memmgr_alloc(size_t nuint8_ts) { MemMgrState& memmgr = get_local_memmgr(); mem_header_t* p; mem_header_t* prevp; // Calculate how many quantas are required: we need enough to house all // the requested uint8_ts, plus the header. The -1 and +1 are there to make sure // that if nuint8_ts is a multiple of nquantas, we don't allocate too much // size_t nquantas = (nuint8_ts + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1; // First alloc call, and no free list yet ? Use 'base' for an initial // degenerate block of size 0, which points to itself // if ((prevp = memmgr.freep) == 0) { memmgr.base.s.next = memmgr.freep = prevp = &memmgr.base; memmgr.base.s.size = 0; } for (p = prevp->s.next; ; prevp = p, p = p->s.next) { // big enough ? if (p->s.size >= nquantas) { // exactly ? if (p->s.size == nquantas) { // just eliminate this block from the free list by pointing // its prev's next to its next // prevp->s.next = p->s.next; } else // too big { p->s.size -= nquantas; p += p->s.size; p->s.size = nquantas; } memmgr.freep = prevp; return (void*) (p + 1); } // Reached end of free list ? // Try to allocate the block from the memmgr.pool. If that succeeds, // get_mem_from_pool adds the new block to the free list and // it will be found in the following iterations. If the call // to get_mem_from_pool doesn't succeed, we've run out of // memory // else if (p == memmgr.freep) { if ((p = get_mem_from_pool(memmgr, nquantas)) == 0) { #ifdef DEBUG_MEMMGR_FATAL printf("!! Memory allocation failed !!\n"); #endif #ifdef MEMMGR_EXIT_OOM exit(38); #endif return 0; } } } }
// Allocations are done in 'quantas' of header size. // The search for a free block of adequate size begins at the point 'freep' // where the last block was found. // If a too-big block is found, it is split and the tail is returned (this // way the header of the original needs only to have its size adjusted). // The pointer returned to the user points to the free space within the block, // which begins one quanta after the header. // void * s16mem_alloc (unsigned long nbytes) { void * m; mem_header_t * p; mem_header_t * prevp; /* We first try to use the system malloc. */ if ((m = malloc (nbytes))) return m; // Calculate how many quantas are required: we need enough to house all // the requested bytes, plus the header. The -1 and +1 are there to make // sure // that if nbytes is a multiple of nquantas, we don't allocate too much // unsigned long nquantas = (nbytes + sizeof (mem_header_t) - 1) / sizeof (mem_header_t) + 1; // First alloc call, and no free list yet ? Use 'base' for an initial // denegerate block of size 0, which points to itself // if ((prevp = freep) == 0) { base.s.next = freep = prevp = &base; base.s.size = 0; } for (p = prevp->s.next;; prevp = p, p = p->s.next) { // big enough ? if (p->s.size >= nquantas) { // exactly ? if (p->s.size == nquantas) { // just eliminate this block from the free list by pointing // its prev's next to its next // prevp->s.next = p->s.next; } else // too big { p->s.size -= nquantas; p += p->s.size; p->s.size = nquantas; } freep = prevp; return (void *)(p + 1); } // Reached end of free list ? // Try to allocate the block from the pool. If that succeeds, // get_mem_from_pool adds the new block to the free list and // it will be found in the following iterations. else if (p == freep) { if ((p = get_mem_from_pool (nquantas)) == 0) { /* now we really are in trouble. this should NEVER happen. */ exit (1); fprintf (stderr, "!! Memory allocation failed !!\n"); return 0; } } } }