/* add buffer (chunk) of specific size to cache */ static struct chunk* dscache_alloc( struct dscache* cache, size_t chunklen ) { struct chunk *chnk = freelist_alloc( cache, chunklen ); if( !chnk ) chnk = heap_alloc( cache, chunklen ); if( !chnk ) { LTRACE( (void)tmfprintf( g_flog, "%s: cannot allocate chunk", __func__ ) ); return NULL; } chnk->next = NULL; if( NULL == cache->head ) cache->head = chnk; if( NULL != cache->tail ) cache->tail->next = chnk; cache->tail = chnk; return chnk; }
void *freelist_alloc( size_t length ) { char buf[20]; pmeta walker = NULL; pmeta newone = NULL; /// If there isn't a block on the free list then initialize one /// This should only be the case on the first allocation request if ( lookaside[0] == NULL ) { init_freelist(); } walker = (pmeta)lookaside[0]; // Walk while looking for the smallest useable while ( walker ) { if ( walker->length < length ) { walker = walker->next; } else { break; } } if ( walker == NULL ) { //printf("no blocks found\n"); add_freelist_block( length ); return freelist_alloc(length); } else { //printf("foudn block size: $d\n", walker->length ); unlink(walker); /// If the block is less than the size needed for at /// least an 8 byte block then return the whole thing /// That means sizeof(meta) prev and next total 8 bytes /// bytes on the lookaside list if ( walker->length - length < sizeof(meta) ) { /// Skip the 4 byte length return ((char*)walker) + 4; } /// Break the chunk off newone = (pmeta) ( ((char*)walker) + 4 + length ); newone->length = walker->length - (length+4); //printf("Broke $d into $d and $d\n", walker->length, length, newone->length); walker->length = length; link(newone); //printf("Returning size: $d\n", walker->length); return ((char*)walker) + 4; } return NULL; }
void *malloc( size_t length ) { int bucket = 0; pmeta outb = NULL; // The minimum size for a valid request is 8 bytes if ( length < 8 ) { length = 8; } // Round up to nearest 8 length = (length+7) & 0xfffffff8; bucket = BUCKET(length); if ( bucket == 0 ) { outb = freelist_alloc(length); return outb; } else { while ( bucket < 128 ) { if ( lookaside[ bucket] != NULL ) { break; } bucket++; } } if ( bucket == 128 ) { //printf("No available buckets freelist alloc\n"); return freelist_alloc( length ); } else { //printf("Found bucket: $d\n", bucket); outb = lookaside[ bucket ]; lookaside[bucket] = outb->next; return ( (char*)outb ) + 4; } return NULL; }