Exemple #1
0
int main()
{
	struct mallinfo status;
	void *p1, *p2;

	status = mallinfo();
//	malloc_status(status);

	/* Allocate small block */
	printf("\nAllocating 1000 bytes\n");
	p1 = alloc_block(1000);
	status = mallinfo();
	malloc_status(status);
	getchar();

	printf("\nFree 1000 bytes\n");
	free(p1);
	status = mallinfo();
	malloc_status(status);
	getchar();
	
	/* Allocate huge block */
	printf("\nAllocating 128KB\n");
	p2 = alloc_block(140*1024);	/* 140 KB */
	status = mallinfo();
	malloc_status(status);
	getchar();

	printf("\nFree 140KB\n");
	free(p2);
	status = mallinfo();
	malloc_status(status);

}
Exemple #2
0
//get an empty dir_entry under a dir
struct dir_entry *empty_dir(int direct_inum)
{
    inode_cache *dir = read_inode(direct_inum);
    if (dir->data.type!=INODE_DIRECTORY) return NULL;
    int i,block_num;

    //check direct blocks
    for (i=0; i<NUM_DIRECT; i++) {
        if (dir->data.direct[i]<=0) break;
        block_num = dir->data.direct[i];
        block_cache *b = read_block(block_num);
        struct dir_entry *d = (struct dir_entry*)(b->data);
        int j;
        for (j=0; j<DIRS_PER_BLOCK; j++) {
            if (d[j].inum==0) {
                b->dirty = 1;
                return &d[j];
            }
        }
    }
    if (i<NUM_DIRECT) {
        dir->data.direct[i] = alloc_block();
        block_num = dir->data.direct[i];
        block_cache *b = read_block(block_num);
        b->dirty = 1;
        return (struct dir_entry*)(b->data);
    }
    
    //check indirect bloc
    if (dir->data.indirect==0) {
        dir->data.indirect = alloc_block();
    }
    block_num = dir->data.indirect;
    block_cache *b = read_block(block_num);
    int j;
    block_cache *tmp;
    for (j=0; j<BLOCKSIZE; j+=4) {
        block_num = *(int*)(b->data+j);
        if (block_num!=0) {
            tmp = read_block(block_num);
            struct dir_entry *d = (struct dir_entry*)(tmp->data);
            int k;
            for (k=0; k<DIRS_PER_BLOCK; k++) {
                if (d[j].inum==0) {
                    tmp->dirty = 1;
                    return d;
                }
            }
        }
        else break;
    }
    if (j==BLOCKSIZE) return NULL;
    block_num = alloc_block();
    *(int*)(b->data+j) = block_num;
    b->dirty = 1;
    tmp = read_block(block_num);
    tmp->dirty = 1;
    return (struct dir_entry*)(tmp->data);
}
Exemple #3
0
int main(int argc,char *argv[]){
	int i;
 	FILE * disk=fopen("data.disk","wb");	
	memset(bitmap_d.mask,0,sizeof(bitmap_d.mask));
	memset(directory_d.entries,0,sizeof(directory_d.entries));
	for(i=0;i<257;i++)
		SET_BIT(i);
	for(i=1;i<argc;i++){
		FILE *fp=fopen(argv[i],"rb");
		//printf("argv[%d]=%s\n",i,argv[i]);
		/*if(!fp) {
			system("pwd");
			perror("failed:");
		}*/

		assert(fp);
		fseek(fp,0,SEEK_END);
		unsigned int filesz=ftell(fp);
		rewind(fp);
		strcpy(directory_d.entries[i-1].filename,argv[i]);
		directory_d.entries[i-1].file_size=filesz;
		unsigned int inode_index=alloc_block();
		directory_d.entries[i-1].inode_offset=inode_index;

		//write in file data
		struct inode node;
		char buf[512];
		int count=0;
		while(fread(buf,1,512,fp)){
			unsigned int bias=alloc_block();
			node.data_block_offsets[count]=bias;
			fseek(disk,bias*512,SEEK_SET);
			fwrite(buf,1,512,disk);
			rewind(disk);
			count++;
		}
		//write in inode
		fseek(disk,inode_index*512,SEEK_SET);
		fwrite(&node,1,512,disk);
		rewind(disk);
		fclose(fp);
	}
	fseek(disk,512*256,SEEK_SET);
	fwrite(directory_d.entries,1,512,disk);
	rewind(disk);
	fseek(disk,0,SEEK_SET);
	fwrite(bitmap_d.mask,1,512*256,disk);
	rewind(disk);
	fclose(disk);
	return 0;
}
Exemple #4
0
static int hash_add_entry (uint8_t *string, HASH_TABLE *htbl, void *data)
{
    hash_bucket_t *hentry = NULL;
    int bucket = -1;

    if (!htbl)
        return NULL;

    if (!(hentry = find_hash_entry (string, htbl))) {

        bucket = htbl->hash_index_gen (string);

        if (bucket > htbl->nbuckets) {
            return -1;
        }

        hentry = htbl->bucket_array[bucket];

        while (hentry && hentry->next)
            hentry = hentry->next;

        if (hentry) {
            hentry->next = alloc_block (htbl->hmem_pool_id);
            if (!hentry->next) {
                return -1;
            }
            hentry = hentry->next;
        }
        else {
            htbl->bucket_array[bucket] = alloc_block (htbl->hmem_pool_id);
            hentry = htbl->bucket_array[bucket];
            if (!hentry)
                return -1;
        }

        hentry->data = data;
        hentry->next = NULL;
        hentry->key  = malloc (htbl->key_len);
        {
            int i = 0;
            for (; i < htbl->key_len; i++)
                hentry->key[i] = string[i];
        }

        htbl->nentries++;
    }

    return 0;
}
Exemple #5
0
/* splits the index node at the given level of the given path */
PRIVATE int split_index_node(struct root *r, struct path *p, int level) {
	int slot = p->slots[level];
	struct cache *left = p->nodes[level];
	int nritems = left->u.node.header.nritems;
	int nrstaying = nritems/2;			/* smaller half stays on the left */
	int nrmoving = nritems - nrstaying;	/* larger half moves to the right */
	struct cache *right;
	blocknr_t rightnr;

	assert(left->will_write);	/* was ensured on tree descent */
	rightnr = alloc_block(r->fs_info, left, left->u.node.header.type);
	if (!rightnr) return -ENOSPC;
	right = init_node(rightnr, left->u.node.header.type, level);
	if (!right) return -errno;
	if(is_root_level(level, p)) {	/* no node above, so need to grow tree */
		blocknr_t new_rootnr;
		struct cache *c;

		assert(level < MAX_LEVEL - 1);	/* has room to add another level */
		new_rootnr = alloc_block(r->fs_info, right, right->u.node.header.type);
		if (!new_rootnr) return -ENOSPC;
		c = init_node(new_rootnr, right->u.node.header.type, level + 1);
		if (!c) return -errno;
		p->nodes[level + 1] = c;
		p->slots[level + 1] = 0;	/* path on the left node */
		insert_key_ptr(r, p, level + 1,
						key_for(left, 0), left->write_blocknr);
		r->blocknr = new_rootnr;
	}
	memmove(&right->u.node.u.key_ptrs[0],	/* move larger half to right node */
			&left->u.node.u.key_ptrs[nrstaying],
			nrmoving * sizeof(struct key_ptr));
	right->u.node.header.nritems = nrmoving;
	memset(&left->u.node.u.key_ptrs[nrstaying], 0,	/* clear moved in left */
			nrmoving * sizeof(struct key_ptr));
	left->u.node.header.nritems = nrstaying;
	p->slots[level + 1]++;		/* temporarily, for inserting in parent node */
	insert_key_ptr(r, p, level + 1, key_for(right, 0), rightnr);
	if (slot >= nrstaying) {		/* need to change path to the right */
		p->nodes[level] = right;
		p->slots[level] = slot - nrstaying;
		put_block(left);			/* free left since it's now off the path */
	} else {
		p->slots[level + 1]--;		/* path back to left node in parent node */
		put_block(right);			/* free right since it's not on the path */
	}
	return SUCCESS;
}
int file_get_block(struct File *f, uint32_t file_blockno, int *pblk)
{

  if(file_blockno >= NDIRECT * ENTRY)
  {
	 printf("\nFile Size Exceeded\n");
	 return -1;
  }


  if(file_blockno%ENTRY == 0)
  {
	 f->f_direct[file_blockno/ENTRY] = super->tail_db;
	 super->tail_db = super->tail_db + BLKSIZE;
	 if(file_blockno/ENTRY > 0)
	 {
		 int addr = f->f_direct[(file_blockno/ENTRY) - 1];
		 fseek(fp,addr,SEEK_SET);
		 fwrite(block_entries, BLKSIZE, 1, fp);
		 memset(block_entries, 0, ENTRY);
	 }
  }

  int offset = file_blockno%ENTRY;
  block_entries[offset] = super->tail_db;

  if(alloc_block(pblk) < 0)
  {
	  printf("\n error in block allocation for write");
	  return -1;
  }

  return 0;
}
static void place(void *bp, size_t asize)   {
	//dbg_printf("place%p\n",bp);
    size_t csize = GET_SIZE(HDRP(bp));   
//	void *remain_blk;
size_t remain_size=csize-asize;
    if ((remain_size) >= 16) {
	void *remain_blk; 
		delete_free_block(bp);	
//		size_t predoff=get_pred_offset(bp);
//		size_t succoff=get_succ_offset(bp);
		alloc_block(bp,asize);
		remain_blk= NEXT_BLKP(bp);
		PUT(HDRP(remain_blk), PACK(remain_size, 0));
		PUT(FTRP(remain_blk), PACK(remain_size, 0));
		add_free_block(remain_blk,remain_size);
		/*size_t re_off=get_offset(remain_blk);
		set_succ(remain_blk,succoff);
		set_pred(remain_blk,predoff);
//	if (predoff){
		set_succ(get_addr(predoff),re_off);
//	}
//	else free_list=remain_blk;
	if (succoff){
		set_pred(get_addr(succoff),re_off);
		}*/
    }
    else { 
		delete_free_block(bp);
		PUT(HDRP(bp), PACK(csize, 1));
		PUT(FTRP(bp), PACK(csize, 1));
    }
}
/*************************************************
* Allocation                                     *
*************************************************/
void* Pooling_Allocator::allocate(u32bit n)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   Mutex_Holder lock(mutex);

   if(n <= BITMAP_SIZE * BLOCK_SIZE)
      {
      const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;

      byte* mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      get_more_core(PREF_SIZE);

      mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      throw Memory_Exhaustion();
      }

   void* new_buf = alloc_block(n);
   if(new_buf)
      return new_buf;

   throw Memory_Exhaustion();
   }
Exemple #9
0
/* Create a series of blocks, and optionally the single-, double-, and/or
   triple-indirect blocks that refer to them. level specifies how many steps
   away from data blocks we are (between 0 and 3), map is an array into which
   the logical/physical associations of data blocks should be stored, next
   refers to the next logical block number, and nblocks is the number of logical
   blocks that are to be created. */
static int create_blocks(ext2_filesystem *fs, int level, uint32_t *map,
                         int *next, int nblocks)
{
  if (*next >= nblocks)
    return 0;

  /* Allocate the next block */
  int blockno = alloc_block(fs);
  if (0 == level) {

    /* If this is a data block (as opposed to an indirect block), record the
       logical->physical mapping, and increment the next logical block number */
    if (map)
      map[*next] = blockno;
    (*next)++;
  }
  if (0 < level) {
    /* Create a series of data or indirect blocks one level down, and store
       references to them in the current indirect block */
    buffer *indirect_buf;
    try(bufcache_get(fs->bc,blockno,&indirect_buf));
    int i;
    uint32_t *table = (uint32_t*)indirect_buf->data;
    for (i = 0; i < RPB; i++)
      table[i] = create_blocks(fs,level-1,map,next,nblocks);
    bufcache_release(fs->bc,indirect_buf,1);
  }
  return blockno;
}
Exemple #10
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	// LAB 5: Your code here.
	int r;
	void *addr = NULL;

	if (filebno >= NDIRECT + NINDIRECT){
		return -E_INVAL;
	}
	if (filebno < NDIRECT){
		*ppdiskbno = &f->f_direct[filebno];
		return 0;
	}

	if (f->f_indirect == 0){
		if (!alloc){
			return -E_NOT_FOUND;
		}
		if((r = alloc_block()) == -E_NO_DISK){
			return -E_NO_DISK;
		}
		f->f_indirect = r;
		// Clear this indirect block
		memset(diskaddr(r), 0, BLKSIZE);
		flush_block(diskaddr(r));
	}
	// Remember fileno - NDIRECT
	addr = diskaddr(f->f_indirect);
	*ppdiskbno = ((uint32_t *)addr + filebno - NDIRECT);
	return 0;
}
Exemple #11
0
int
dir_try_enter(zone_t z, ino_t child, char const *name)
{
  struct direct *dir_entry = alloc_block();
  int r = 0;
  block_t b;
  int i, l;

  b = z << zone_shift;
  for (l = 0; l < zone_per_block; l++, b++) {
	get_block(b, dir_entry);

	for (i = 0; i < NR_DIR_ENTRIES(block_size); i++)
		if (!dir_entry[i].d_ino)
			break;

	if(i < NR_DIR_ENTRIES(block_size)) {
		r = 1;
		dir_entry[i].d_ino = child;
		assert(sizeof(dir_entry[i].d_name) == MFS_DIRSIZ);
		if (verbose && strlen(name) > MFS_DIRSIZ)
			fprintf(stderr, "File name %s is too long, truncated\n", name);
		strncpy(dir_entry[i].d_name, name, MFS_DIRSIZ);
		put_block(b, dir_entry);
		break;
	}
  }

  free(dir_entry);

  return r;
}
Exemple #12
0
/* Increment the file-size in inode n */
void
incr_size(ino_t n, size_t count)
{
  block_t b;
  int off;

  b = ((n - 1) / inodes_per_block) + inode_offset;
  off = (n - 1) % inodes_per_block;
  {
	struct inode *inodes;

	assert(inodes_per_block * sizeof(*inodes) == block_size);
	if(!(inodes = alloc_block()))
		err(1, "couldn't allocate a block of inodes");

	get_block(b, inodes);
	/* Check overflow; avoid compiler spurious warnings */
	if (inodes[off].i_size+(int)count < inodes[off].i_size ||
	    inodes[off].i_size > MAX_MAX_SIZE-(int)count)
		pexit("File has become too big to be handled by MFS");
	inodes[off].i_size += count;
	put_block(b, inodes);
	free(inodes);
  }
}
Exemple #13
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.  
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	// LAB 5: Your code here.
    int blkno;
    uint32_t *vindirect;

    if (NDIRECT + NINDIRECT <= filebno)
        return -E_INVAL;

    if (NDIRECT > filebno) {
        if (NULL != ppdiskbno)
            *ppdiskbno = &(f->f_direct[filebno]);
        return 0;
    }

    if (0 == f->f_indirect) {
        if (!alloc)
            return -E_NOT_FOUND;
        blkno = alloc_block();
        if (0 > blkno)
            return -E_NO_DISK;
        f->f_indirect = blkno;

        vindirect = (uint32_t *)(DISKMAP + BLKSIZE * f->f_indirect);
        memset((void *)vindirect, 0, PGSIZE);
    }
    else
        vindirect = (uint32_t *)(DISKMAP + BLKSIZE * f->f_indirect);

    if (NULL != ppdiskbno)
        *ppdiskbno = &vindirect[filebno-NDIRECT];

    return 0;
}
Exemple #14
0
void*
kma_malloc(kma_size_t size)
{
    if(buffer_entry == NULL)
      init_buffer_list();
    return alloc_block(size);
}
Exemple #15
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_NO_MEM if there's no space in memory for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.  
int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	int r;
	uint32_t *ptr;
	char *blk;

	if (filebno < NDIRECT)
		ptr = &f->f_direct[filebno];
	else if (filebno < NINDIRECT) {
		if (f->f_indirect == 0) {
			if (alloc == 0)
				return -E_NOT_FOUND;
			if ((r = alloc_block()) < 0)
				return r;
			f->f_indirect = r;
		} else
			alloc = 0;	// we did not allocate a block
		if ((r = read_block(f->f_indirect, &blk)) < 0)
			return r;
		assert(blk != 0);
		if (alloc)		// must clear any block we allocated
			memset(blk, 0, BLKSIZE);
		ptr = (uint32_t*)blk + filebno;
	} else
		return -E_INVAL;

	*ppdiskbno = ptr;
	return 0;
}
Exemple #16
0
Fichier : fs.c Projet : MG47/JOS-MG
// Set *blk to the address in memory where the filebno'th
// block of file 'f' would be mapped.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
// Hint: Use file_block_walk and alloc_block.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
       // code for lab 5- M.G
       //      panic("file_get_block not implemented");

    uint32_t *ppdiskbno;
    uint32_t new_block_no;

    int return_value;    

    if ((return_value = file_block_walk(f, filebno, &ppdiskbno,true)) < 0)
    {
        return return_value;
    }    

    if (!*ppdiskbno)
    {
		if ((new_block_no = alloc_block()) < 0)
        {
			return -E_NO_DISK;
        }
	    *ppdiskbno = new_block_no;
    }   
    
    *blk = diskaddr(*ppdiskbno);

    return 0;
}
Exemple #17
0
/* Increment the link count to inode n */
void
incr_link(ino_t n)
{
  int off;
  static int enter = 0;
  static struct inode *inodes = NULL;
  block_t b;

  if (enter++) pexit("internal error: recursive call to incr_link()");

  b = ((n - 1) / inodes_per_block) + inode_offset;
  off = (n - 1) % inodes_per_block;
  {
	assert(sizeof(*inodes) * inodes_per_block == block_size);
	if(!inodes && !(inodes = alloc_block()))
		err(1, "couldn't allocate a block of inodes");

	get_block(b, inodes);
	inodes[off].i_nlinks++;
	/* Check overflow (particularly on V1)... */
	if (inodes[off].i_nlinks <= 0)
		pexit("Too many links to a directory");
	put_block(b, inodes);
  }
  enter = 0;
}
Exemple #18
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
//  Note, for the read-only file system (lab 5 without the challenge), 
//        alloc will always be false.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
	{
		// LAB 5: Your code here.
	
		if (filebno < NDIRECT) {
			// Block can be found directly.
			*ppdiskbno = &f->f_direct[filebno];
			return 0;
		} else if (filebno < NDIRECT + NINDIRECT) {
			// Block must be found indirectly.
			if (!f->f_indirect) {
				if (!alloc)
					return -E_NOT_FOUND;
				
				// Allocate indirect block.
				f->f_indirect = alloc_block();
				if (!f->f_indirect)
					return -E_NO_DISK;
	
				// Clear block.
				memset(diskaddr(f->f_indirect), 0, BLKSIZE);
			}
	
			uint32_t *ind_blk = (uint32_t *)diskaddr(f->f_indirect);
			*ppdiskbno = &ind_blk[filebno - NDIRECT];
			return 0;
		} else {
			// There is no so many blocks.
			return -E_INVAL;
		}
		
		// panic("file_block_walk not implemented");
	}
Exemple #19
0
/* Insert one bit into the bitmap */
void
insert_bit(block_t map, bit_t bit)
{
  int boff, w, s;
  unsigned int bits_per_block;
  block_t map_block;
  bitchunk_t *buf;

  buf = alloc_block();

  bits_per_block = FS_BITS_PER_BLOCK(block_size);
  map_block = map + bit / bits_per_block;
  if (map_block >= inode_offset)
	pexit("insertbit invades inodes area - this cannot happen");
  boff = bit % bits_per_block;

  assert(boff >=0);
  assert(boff < FS_BITS_PER_BLOCK(block_size));
  get_block(map_block, buf);
  w = boff / FS_BITCHUNK_BITS;
  s = boff % FS_BITCHUNK_BITS;
  buf[w] |= (1 << s);
  put_block(map_block, buf);

  free(buf);
}
static void
alloc_and_assign_internal_structures(struct s_net **original_net,
				     struct s_block **original_block,
				     int *original_num_nets,
				     int *original_num_blocks)
{
    /*allocate new data structures to hold net, and block info */

    *original_net = clb_net;
    *original_num_nets = num_nets;
    num_nets = NET_COUNT;
    alloc_net();

    *original_block = block;
    *original_num_blocks = num_blocks;
    num_blocks = BLOCK_COUNT;
    alloc_block();


    /* [0..num_nets-1][1..num_pins-1] */
    net_delay =
	(float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1,
			       sizeof(float));
    net_slack =
	(float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1,
			       sizeof(float));

    reset_placement();
}
Exemple #21
0
void Profiler::init(int max_block_num)
{
    blocks_ = COMMON_ALLOC(ProfilerBlock, max_block_num);
    memset(blocks_, 0x00, sizeof(ProfilerBlock) * max_block_num);
    root_ = alloc_block("Root");
    current_ = root_;
}
Exemple #22
0
IndexSet::IndexSet (IndexSet *set) {
#ifdef ASSERT
  _serial_number = _serial_count++;
  set->check_watch("copied", _serial_number);
  check_watch("initialized by copy", set->_serial_number);
  _max_elements = set->_max_elements;
#endif
  _count = set->_count;
  _max_blocks = set->_max_blocks;
  if (_max_blocks <= preallocated_block_list_size) {
    _blocks = _preallocated_block_list;
  } else {
    _blocks =
      (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
  }
  for (uint i = 0; i < _max_blocks; i++) {
    BitBlock *block = set->_blocks[i];
    if (block == &_empty_block) {
      set_block(i, &_empty_block);
    } else {
      BitBlock *new_block = alloc_block();
      memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block);
      set_block(i, new_block);
    }
  }
}
Exemple #23
0
// Set *blk to point at the filebno'th block in file 'f'.
// Allocate the block if it doesn't yet exist.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
// Hint: Use file_block_walk and alloc_block.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
	// LAB 5: Your code here.
	int r;
	uint32_t *pblkno;

	if ((r = file_block_walk(f, filebno, &pblkno, 1)) < 0){
		return r;
	}

	// if not exist
	if (*pblkno == 0){
		if ((r = alloc_block()) < 0){
			return -E_NO_DISK;
		}
		*pblkno = r;
		// Clear this block
		 memset(diskaddr(r), 0, BLKSIZE);
		// flush this empty block into disk
		flush_block(diskaddr(r));
	}
	*blk = diskaddr(*pblkno);
	return 0;
}
Exemple #24
0
int i915_mem_alloc(struct drm_device *dev, void *data,
		   struct drm_file *file_priv)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_mem_alloc_t *alloc = data;
	struct mem_block *block, **heap;

	if (!dev_priv) {
		DRM_ERROR("called with no initialization\n");
		return -EINVAL;
	}

	heap = get_heap(dev_priv, alloc->region);
	if (!heap || !*heap)
		return -EFAULT;

	
	if (alloc->alignment < 12)
		alloc->alignment = 12;

	block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);

	if (!block)
		return -ENOMEM;

	mark_block(dev, block, 1);

	if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
			     sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}

	return 0;
}
Exemple #25
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
       // LAB 5: Your code here.
    int r;
    if (filebno >= NDIRECT + NINDIRECT)
        return -E_INVAL;
    if (filebno <= NDIRECT)
    {
        *ppdiskbno = &(f->f_direct[filebno]);
    }
    else
    {
        if (f->f_indirect != 0)
        {
            *ppdiskbno = &((uint32_t *) diskaddr(f->f_indirect))[filebno - NDIRECT];
        }
        else if (alloc)
        {
            if((r = f->f_indirect = alloc_block()) < 0)
                return r; // -E_NO_DISK
            memset(diskaddr(f->f_indirect), 0, BLKSIZE);
            *ppdiskbno = &((uint32_t *) diskaddr(f->f_indirect))[filebno - NDIRECT];
        }
        else
            return -E_NOT_FOUND;
    }
    return 0;

}
Exemple #26
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
       // LAB 5: Your code here.
       // panic("file_block_walk not implemented");
    if (filebno < NDIRECT) {
        *ppdiskbno = &f->f_direct[filebno];
    } else if (filebno < NDIRECT + NINDIRECT) {
        if (!f->f_indirect) {
            if (!alloc) {
                return -E_NOT_FOUND;
            }
            f->f_indirect = alloc_block();
            if (f->f_indirect < 0)
                return -E_NO_DISK;
            memset(diskaddr(f->f_indirect), 0, BLKSIZE);
        }

        uint32_t *ptr = (uint32_t *)diskaddr(f->f_indirect);
        *ppdiskbno = &ptr[filebno - NDIRECT];
    } else {
        return -E_INVAL;
    }
    return 0;
}
/*************************************************
* Allocate more memory for the pool              *
*************************************************/
void Pooling_Allocator::get_more_core(u32bit in_bytes)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   const u32bit TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE;

   const u32bit in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE;
   const u32bit to_allocate = in_blocks * TOTAL_BLOCK_SIZE;

   void* ptr = alloc_block(to_allocate);
   if(ptr == 0)
      throw Memory_Exhaustion();

   allocated.push_back(std::make_pair(ptr, to_allocate));

   for(u32bit j = 0; j != in_blocks; ++j)
      {
      byte* byte_ptr = static_cast<byte*>(ptr);
      blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE));
      }

   std::sort(blocks.begin(), blocks.end());
   last_used = std::lower_bound(blocks.begin(), blocks.end(),
                                Memory_Block(ptr));
   }
Exemple #28
0
// Set *blk to point at the filebno'th block in file 'f'.
// Allocate the block if it doesn't yet exist.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
// Hint: Use file_block_walk and alloc_block.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
	// LAB 5: Your code here.
	//panic("file_get_block not implemented");
	uint32_t *pdiskbno;
	int result;

	if((result=file_block_walk(f, filebno, &pdiskbno, 1)) < 0)
	{
		return result;
	}
	
	if(*pdiskbno == 0) 
	{
		if((result=alloc_block()) < 0)
		{
			return -E_NO_DISK;
		}
		else
		{	
			*pdiskbno=result;
			memset(diskaddr(result), 0, BLKSIZE);

			flush_block(diskaddr (result));
		}
	}
		
	*blk=diskaddr(*pdiskbno);
		
	return 0;
}
Exemple #29
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.  
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	// LAB 5: Your code here.
	if(filebno >= NDIRECT + NINDIRECT)
		return -E_INVAL;
	if(filebno < NDIRECT)
	{
		*ppdiskbno = &(f->f_direct[filebno]);
		return 0;
	}
	if(f->f_indirect == 0 && !alloc)
		return -E_NOT_FOUND;
	if(f->f_indirect == 0)
	{
		int status = 0;
		if((status = alloc_block()) < 0)
		{
			return status;
		}
		f->f_indirect = status;
		memset((int*)diskaddr(f->f_indirect), 0, BLKSIZE);
	}
	uint32_t* baddr = (uint32_t*)diskaddr(f->f_indirect);

	*ppdiskbno = (uint32_t*)(baddr + filebno - NDIRECT);
	return 0;
	//panic("file_block_walk not implemented");

}
Exemple #30
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
       // LAB 5: Your code here.
       int r;

       if (filebno >= NDIRECT + NINDIRECT)
         return -E_INVAL;

       if (filebno < NDIRECT) {
         *ppdiskbno = &f->f_direct[filebno];
       } else {
         if (!f->f_indirect){
           if (!alloc)
             return -E_NOT_FOUND;
           else {
             if ((r = alloc_block()) < 0)
               return r;
             f->f_indirect = r;
             memset(diskaddr(f->f_indirect), 0, BLKSIZE);
           }
         }
         *ppdiskbno = (uint32_t*)diskaddr(f->f_indirect) + filebno - NDIRECT;
       }
       return 0;
}