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; }
static int recurse_helper(block_if bi, block_no b, int nlevels, int *n_blocks) { block_t read_block; struct ufs_state *us = bi->state; if(*n_blocks == 0) { return 0; } //Nlevels = 0, reached a data block - set it to zero if(nlevels == 0) { if((*us->below->write)(us->below, b, &null_block) < 0) { return -1; } set_block_free(bi, b); (*n_blocks)--; return 0; } //Indirect block, read it if((*us->below->read)(us->below, b, &read_block) < 0) { return -1; } //Call the function recursively on every reference in the indirect block int j = 0; struct ufs_indirblock *indir = (struct ufs_indirblock *) &read_block; while(j < REFS_PER_BLOCK) { if(indir->refs[j] != 0) recurse_helper(bi, indir->refs[j], nlevels - 1, n_blocks); else (*n_blocks)--; j++; } //Set the block to 0 if((*us->below->write)(us->below, b, &null_block) < 0) { return -1; } else { set_block_free(bi, b); } return 0; }
/* relase po with size N to AVAIL list */ void dkbtfree(void * x){ assert(x!=NULL); node_t * po=x; node_t * block; block=block_merge_left(get_block_pprv(po), po); block=block_merge_right(block, get_block_pnxt(block));/* return new block */ set_block_free(block); set_prev_free(get_block_pnxt(block)); set_prev_used(block); block_insert(block); /*insert into dll */ }
/* initially, AVAIL points to a free block */ void dkbtinit( ){ node_t * p= (node_t*) malloc((MAX_WORDS)*( sizeof(void *))); AVAIL= (node_t* )(void*)malloc(sizeof(node_t)); AVAIL->size=sizeof(node_t); AVAIL->nlink=p; AVAIL->plink=NULL; p->nlink=NULL; p->plink=AVAIL; p->pprv=AVAIL; p->size=MAX_WORDS; set_block_free(p); /* set block as free*/ // p->psize=0; }