void *malloc(uint64_t size) { int index; void *ptr; struct boundary_tag *tag = NULL; liballoc_lock(); if ( l_initialized == 0 ) { for ( index = 0; index < MAXEXP; index++ ) { l_freePages[index] = NULL; l_completePages[index] = 0; } l_initialized = 1; } index = getexp( size ) + MODE; if ( index < MINEXP ) index = MINEXP; // Find one big enough. tag = l_freePages[ index ]; // Start at the front of the list. while ( tag != NULL ) { // If there's enough space in this tag. if ( (tag->real_size - sizeof(struct boundary_tag)) >= (size + sizeof(struct boundary_tag) ) ) { break; } tag = tag->next; } // No page found. Make one. if ( tag == NULL ) { if ( (tag = allocate_new_tag( size )) == NULL ) { liballoc_unlock(); return NULL; } index = getexp( tag->real_size - sizeof(struct boundary_tag) ); } else { remove_tag( tag ); if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) l_completePages[ index ] -= 1; } // We have a free page. Remove it from the free pages list. tag->size = size; // Removed... see if we can re-use the excess space. unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ ) { int childIndex = getexp( remainder ); if ( childIndex >= 0 ) { struct boundary_tag *new_tag = split_tag( tag ); new_tag = new_tag; // Get around the compiler warning about unused variables. } } ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) ); liballoc_unlock(); return ptr; }
void *malloc(size_t size) { int index; void *ptr; struct boundary_tag *tag = NULL; liballoc_lock(); if ( l_initialized == 0 ) { #ifdef DEBUG printf("%s\n","liballoc initializing."); #endif for ( index = 0; index < MAXEXP; index++ ) { l_freePages[index] = NULL; l_completePages[index] = 0; } l_initialized = 1; } index = getexp( size ) + MODE; if ( index < MINEXP ) index = MINEXP; // Find one big enough. tag = l_freePages[ index ]; // Start at the front of the list. while ( tag != NULL ) { // If there's enough space in this tag. if ( (tag->real_size - sizeof(struct boundary_tag)) >= (size + sizeof(struct boundary_tag) ) ) { #ifdef DEBUG printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) ); #endif break; } tag = tag->next; } // No page found. Make one. if ( tag == NULL ) { if ( (tag = allocate_new_tag( size )) == NULL ) { liballoc_unlock(); return NULL; } index = getexp( tag->real_size - sizeof(struct boundary_tag) ); } else { remove_tag( tag ); if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) l_completePages[ index ] -= 1; } // We have a free page. Remove it from the free pages list. tag->size = size; // Removed... see if we can re-use the excess space. #ifdef DEBUG printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index ); #endif unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ ) { int childIndex = getexp( remainder ); if ( childIndex >= 0 ) { #ifdef DEBUG printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) ); #endif struct boundary_tag *new_tag = split_tag( tag ); new_tag = new_tag; // Get around the compiler warning about unused variables. #ifdef DEBUG printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index ); #endif } } ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) ); #ifdef DEBUG l_inuse += size; printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 ); dump_array(); #endif liballoc_unlock(); return ptr; }