void * dkbtalloc(size_t n){ /* * The memory we search for has to include the memory control header, but * the user of malloc doesn't need to know this, so we'll just add it in * for them. */ n=n+sizeof(node_t); node_t *p= AVAIL->nlink; /* from the free list head */ node_t * q=NULL; /* to store the block after spliting */ while(p!=NULL){ if (p->size==n){ /* exaclly the same size */ block_remove(p); /* remove p from dll */ set_block_used(p); /* mark p as allocated */ set_prev_used(get_block_pnxt(p));/* set p's next physical block */ return (void*) p; /* return block p */ } if (p->size>n){ /* suitable block is bigger than n */ q=block_split(p,n); /* splict p, q is the new block(right part) */ set_block_free(q); /* set new left block as free */ set_prev_used(q); /* the previous of q is used */ set_block_used(p); block_remove(p); return (void*)p; } p=p->nlink; /* move step further */ } return NULL; }
void testBlock_splitBlock(CuTest* testCase) { cactusBlockTestSetup(); Block *leftBlock, *rightBlock; block_split(block, 2, &leftBlock, &rightBlock); CuAssertIntEquals(testCase, 2, block_getLength(leftBlock)); CuAssertIntEquals(testCase, 1, block_getLength(rightBlock)); CuAssertIntEquals(testCase, 3, block_getInstanceNumber(leftBlock)); CuAssertIntEquals(testCase, 3, block_getInstanceNumber(rightBlock)); Block *leftLeftBlock, *leftRightBlock; block_split(leftBlock, 1, &leftLeftBlock, &leftRightBlock); CuAssertIntEquals(testCase, 1, block_getLength(leftLeftBlock)); CuAssertIntEquals(testCase, 1, block_getLength(leftRightBlock)); CuAssertIntEquals(testCase, 3, block_getInstanceNumber(leftLeftBlock)); CuAssertIntEquals(testCase, 3, block_getInstanceNumber(leftRightBlock)); //doesn't currently check the instances. cactusBlockTestTeardown(); }
void * kmalloc(size_t n) { list_item *cur_node; block_info *best; if(n == 0) { return NULL; } /* Round the size to keep blocks aligned */ n = ((KALLOC_ALIGN * n) + (KALLOC_ALIGN - 1)) / KALLOC_ALIGN; /* Find the best fitting free block */ cur_node = &(first_block->node); best = NULL; while(cur_node) { block_info *b; b = LIST_GET_OBJECT(cur_node, block_info, node); if((b->state == STATE_FREE) && (usable_block_size(b) >= n)) { if(best == NULL) { best = b; } else if(block_size(b) < block_size(best)) { /* This one fits best */ best = b; } } cur_node = cur_node->next; } /* Search is finished */ if(best == NULL) { return NULL; } /* We have found a block, split it to the requested size */ block_split(best, n); /* Mark block as used and return the pointer to usable data */ best->state = STATE_USED; return (best + 1); }