コード例 #1
0
ファイル: fs.c プロジェクト: jpbottaro/minios
/* read/write (flag) to 'buf' 'n' bytes from position 'pos' of the file 'ino' */
int copy_file(char *buf, unsigned int n, unsigned int pos, struct inode_s *ino,
                                                                          int flag)
{
    unsigned int size, off;
    block_t blocknr;
    struct buf_s *block;

    while (n > 0) {
        if ( (blocknr = read_map(ino, pos, flag)) == NO_BLOCK)
            return ERROR;
        block = get_block(blocknr);

        off = pos % BLOCK_SIZE;
        size = MIN(n, BLOCK_SIZE - off);

        if (flag == FS_WRITE) {
            mymemcpy(block->b_buffer + off, buf, size);
            block->b_dirty = 1;
        } else {
            mymemcpy(buf, block->b_buffer + off, size);
        }

        n -= size;
        pos += size;
        buf += size;
        release_block(block);
    }

    return pos;
}
コード例 #2
0
ファイル: fs.c プロジェクト: claytondus/cdnwsh
//******** rmdir ********************
int8_t cnrmdir(const char* name)
{
	char parent_name[512];
	char entry_name[256];
	dir_entry* entry;
	inode dir_inode;
	memset(&dir_inode, 0, sizeof(inode));

	strcpy(parent_name, name);
	strcat(parent_name, "/..");

	dir_ptr* parent = cnopendir(parent_name);
	check(parent != NULL, "Cannot open parent directory");

	//Copy the entire directory minus the entry
	dir_ptr* new_parent = calloc(1,sizeof(dir_ptr));
	new_parent->data = calloc(parent->inode_st.blocks, sizeof(block));
	dir_entry* new_dir_entry = (dir_entry*)new_parent->data;
	new_parent->inode_st = parent->inode_st;
	new_parent->inode_id = parent->inode_id;
	new_parent->inode_st.size = 0;
	new_parent->index = 0;

	while((entry = cnreaddir(parent)))
	{
		memcpy(entry_name, entry->name, entry->name_len);
		entry_name[entry->name_len] = 0;
		if(strcmp(entry_name, name) == 0)  //If this is the directory we want
		{
			inode_read(entry->inode, &dir_inode);
			check(dir_inode.size == 24, "Directory is not empty");
			release_block(dir_inode.data0[0]);  //Release target directory block
			release_inode(entry->inode);        //Release target inode
			continue;
		}
		new_dir_entry->entry_len = entry->entry_len;
		new_dir_entry->name_len = entry->name_len;
		new_dir_entry->file_type = entry->file_type;
		new_dir_entry->inode = entry->inode;
		memcpy(new_dir_entry->name, entry->name, entry->name_len);
		new_parent->inode_st.size += entry->entry_len;
		new_parent->index += entry->entry_len;
		new_dir_entry = (dir_entry*)((uint8_t*)new_parent->data+new_parent->index);
	}

	inode_write(new_parent->inode_id, &new_parent->inode_st);
	llwrite(&new_parent->inode_st, new_parent->data);

	free(new_parent->data);
	free(new_parent);
	cnclosedir(parent);
	return 0;
error:
	if(new_parent != NULL && new_parent->data != NULL) free(new_parent->data);
	if(new_parent != NULL) free(new_parent);
	if(parent != NULL) cnclosedir(parent);
	return -1;
}
コード例 #3
0
block_t *DeRefLink(block_t *volatile *link) {
  for(;;) {
    block_t *q = *link;
    if(q == NULL) return q;
    __sync_fetch_and_add(&(q->refcount), 2);
    if(q == *link) return q;
    release_block(q); 
  }
}
コード例 #4
0
QUEUE_ELEMTY *dequeue(local_block_t *l) {
  int tail = l->threadTail;
  block_t *block = l->threadTailBlock;
  for(;;) {
    if(tail==BLOCK_SIZE) {
      block_t *oldBlock = block;
      block->tail = tail;
      block=DeRefLink(&block->next);
      if(block == NULL)
        return NULL;
      else {
        if(!oldBlock->deleted) {
          while(globalTailBlock != oldBlock && !oldBlock->deleted) {
            block_t *tailBlock= DeRefLink(&globalTailBlock);
            if(tailBlock->next != oldBlock) continue;
            if(__sync_bool_compare_and_swap(&globalTailBlock,tailBlock,oldBlock))
              release_block(tailBlock);
          }
          if(__sync_bool_compare_and_swap(&oldBlock->deleted,0,1)) {
            if(__sync_bool_compare_and_swap(&globalTailBlock,oldBlock,block))
              release_block(oldBlock);
          }
        }
        if(block->deleted)
          block=DeRefLink(&globalTailBlock);
      }
      l->threadTailBlock = block;
      tail = block->tail;
    }
    else {
      void *data = block->nodes[tail];
      if(data== (void *) NULL2)
        tail++;
      else if(data==NULL && __sync_bool_compare_and_swap(&block->nodes[tail],NULL,NULL)) {
        l->threadTail = tail;
        return NULL;
      }
      else if(__sync_bool_compare_and_swap(&block->nodes[tail],data,NULL2)) {
        l->threadTail = tail+1;
        return data;
      }
    }
  }
}
コード例 #5
0
void release_block(block_t *node) {
  __sync_fetch_and_add(&(node->refcount),-2);
  if(__sync_bool_compare_and_swap(&node->refcount,0,1)) {
    if(node->next) release_block(node->next);
    block_t *q; do {
      q = freeList;
      node->next = q;
    } while(!__sync_bool_compare_and_swap(&freeList,q,node));
  }
}
コード例 #6
0
ファイル: pool.cpp プロジェクト: LenxWei/libproton
void seg_pool::reg_empty_block(pool_block* p)
{
    // keep only one largest empty block.
    // [TODO] use simpler structure to record empty block.
    PROTON_POOL_THROW_IF(!p->empty(), "try to reg a not empty block into empty_blocks:"<<p);
    if(_empty_blocks.empty()){
        p->insert_after(&_empty_blocks);
        return;
    }
    else{
        pool_block* ba=get_block(_empty_blocks.next());
        if(ba->block_size() < p->block_size()){
            release_block(ba);
            p->insert_after(&_empty_blocks);
        }
        else{
            release_block(p);
        }
    }
}
コード例 #7
0
ファイル: iter.c プロジェクト: yunxiaoxiao110/haiku
status_t csi_release_block(struct csi *csi)
{
    status_t err;

    if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
        return EINVAL;

    err = release_block(csi->vol->fd, _csi_to_block_(csi));
    ASSERT(err == B_OK);
    return err;
}
コード例 #8
0
block_t *new_node() {
  for(;;) {
    block_t *p = freeList;
    if(!p) p = calloc(1, sizeof(block_t));
    __sync_fetch_and_add(&(p->refcount), 2);
    if(__sync_bool_compare_and_swap(&freeList,p,p->next)) {
      __sync_fetch_and_add(&(p->refcount),-1);
      return p;
    }
    release_block(p);
  }
}
コード例 #9
0
ファイル: superblk.c プロジェクト: GeekSivan/smash
// NOTE : dev unused
error_t
init_super_block(dev_t dev)
{
    error_t ret = 0;
    zone_t pos = get_super_block_begin(dev);
    BlockBuffer *buffer = get_block(dev, pos);
    memcpy(&super_blk[0], buffer->bf_data, sizeof(super_blk));
    if (super_blk[0].sb_magic != MINIX_V2 ) {
        printk("only minifs v2 is supported\n");
        ret = -1;
    }
    release_block(buffer);
    return ret;
}
コード例 #10
0
ファイル: cache.c プロジェクト: ysei/Atari_ST_Sources
/******************************************
* release a block of memory by removing it from the data chain
* called by user
* NB: p0 is pointer to the data, need to find pointer to MemHdr first
*/
void release_mem( void *const p0 )
{
register tMemHdr *const p = ((tMemHdr*)( (uint32)p0 - offsetof(tMemHdr, data) )); /* <<< size_t */

   assert( head_mem != NULL );	/* there must be a cache !! */
   assert( p->magic == MAGIC );	/* must be a valid block */
   assert( ISDATA(p) );          /* must be a data block */
   assert( head_data != NULL );  /* data chain can't be empty */
   assert( tail_data != NULL );
   assert( p->next_list != NULL || p == tail_data );
   assert( p->prev_list != NULL || p == head_data );
   assert( check_block(p) );

   release_block( p );

} /* release_mem() */
コード例 #11
0
void JNIHandleBlock::release_block(JNIHandleBlock* block, Thread* thread) {
  assert(thread == NULL || thread == Thread::current(), "sanity check");
  JNIHandleBlock* pop_frame_link = block->pop_frame_link();
  // Put returned block at the beginning of the thread-local free list.
  // Note that if thread == NULL, we use it as an implicit argument that
  // we _don't_ want the block to be kept on the free_handle_block.
  // See for instance JavaThread::exit().
  if (thread != NULL ) {
    if (ZapJNIHandleArea) block->zap();
    JNIHandleBlock* freelist = thread->free_handle_block();
    block->_pop_frame_link = NULL;
    thread->set_free_handle_block(block);

    // Add original freelist to end of chain
    if ( freelist != NULL ) {
      while ( block->_next != NULL ) block = block->_next;
      block->_next = freelist;
    }
    block = NULL;
  }
  if (block != NULL) {
    // Return blocks to free list
    // locking with safepoint checking introduces a potential deadlock:
    // - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
    // - another would hold Threads_lock (jni_AttachCurrentThread) and then
    //   JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
    MutexLockerEx ml(JNIHandleBlockFreeList_lock,
                     Mutex::_no_safepoint_check_flag);
    while (block != NULL) {
      if (ZapJNIHandleArea) block->zap();
      JNIHandleBlock* next = block->_next;
      block->_next = _block_free_list;
      _block_free_list = block;
      block = next;
    }
  }
  if (pop_frame_link != NULL) {
    // As a sanity check we release blocks pointed to by the pop_frame_link.
    // This should never happen (only if PopLocalFrame is not called the
    // correct number of times).
    release_block(pop_frame_link, thread);
  }
}
コード例 #12
0
void enqueue(local_block_t *l, QUEUE_ELEMTY *item) {

  int head = l->threadHead;
  block_t *block = l->threadHeadBlock;
  for(;;) {
    if(head==BLOCK_SIZE) {
      block_t *oldBlock = block;
      block->head = head;
      block = DeRefLink(&block->next);
      if(block == NULL) {
        block = (block_t *) new_block();
        while(globalHeadBlock != oldBlock && oldBlock->next==NULL) {
          block_t *headBlock = DeRefLink(&globalHeadBlock);
          if(headBlock->next != oldBlock) break;
          if(__sync_bool_compare_and_swap(&globalHeadBlock,headBlock,oldBlock)) break;
        }
        if(__sync_bool_compare_and_swap(&oldBlock->next,NULL,block))
          __sync_bool_compare_and_swap(&globalHeadBlock,oldBlock,block);
        else {
          release_block(block);
          block = DeRefLink(&oldBlock->next);
        }
      }
      else if(block->head==BLOCK_SIZE && block->next!=NULL)
        block = DeRefLink(&globalHeadBlock);
      l->threadHeadBlock = block;
      head = block->head;
    }
    else if(block->nodes[head]==NULL) {
      if(__sync_bool_compare_and_swap(&block->nodes[head],NULL,item)) {
        l->threadHead = head+1;
        return;
      }
    }
    else head++;
  }
}
コード例 #13
0
ファイル: cache.c プロジェクト: ysei/Atari_ST_Sources
/*********************************************
* create new block of requested size by removing oldest memory blocks
* block contents are not initialised
* size is rounded up to exact nr longs
* base for removed blocks is set to NULL
* *pbase := adr of block, 
*       or null if cache is unable to supply enough memory
* return null
*/
void find_mem( uint32 rq_size, void **const base )
{
register tMemHdr *tr;
register tMemHdr *t0;
register tMemHdr *t1;

   assert( head_mem != NULL );	/* there must be a cache !! */
   assert( base != NULL );

   assert( rq_size <= ((rq_size+3)&~3) );
   assert( rq_size+4 > ((rq_size+3)&~3) );
   rq_size = (rq_size+3)&~3;

   if(( rq_size > total_size) ) {
      /* request fails - it is too large for cache */
      dprintf(( "requested mem (%ld) larger than cache size (%ld)\n", rq_size, total_size ));
      *base = NULL;
      return;
   } /* if */

   /** loop to remove old data until there is enough free space for current request **/

   dprintf(( "rq_size is %ld\n", (long)rq_size ));
   assert( head_free != NULL || total_free == 0 );

   /* note the special case when total free == 0 (so head_free == NULL)
   ** and rq_size is 0. */

   while( rq_size > total_free || total_free == 0 ) {

      dprintf(("need to remove lru data block(%ld), size (%ld)\n", (long)head_data->data[0], (long)head_data->size ));
      assert( head_data != NULL || rq_size <= total_free );
      assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );

      assert( head_data->prev_list == NULL );
      release_block( head_data );      /* remove lru data block */

      assert( head_data != NULL || rq_size <= total_free );
      assert( head_data != NULL || total_used == 0 );
      assert( head_data == NULL || head_data->prev_list == NULL);

   } /* while */

   assert( total_free >= rq_size );
   assert( head_free != NULL );

   /**********************************************************
   * there is now enough space in the cache to fulfil the request
   * but it may need to be gathered together into one block
   * move all data blocks down to the start of the cache 
   * this leaves one free block at the end of the cache
   **********************************************************/

   if( head_free->size < rq_size ) {
   register uint32 *free_p;	/** free space pointer **/

      /* the memory is fragmented, so move all data down memory
      ** to concentrate the free mem into one block at the end
      ** note: fragmented ==> at least one data block & 2 free blocks */

      #ifdef TEST
      conc++;
      dprintf(( "concentrating data...(this is the %ldth time)\n", conc ));
      #endif

      assert( head_data != NULL );

      t1 = head_mem;
      while( ISDATA(t1) ) {
         assert( check_block(t1) );
         assert( t1->next_mem != NULL );	/* there are at least two free blocks following */
         t1 = t1->next_mem;
      } /* while */

      assert( ISFREE(t1) );

      free_p = (uint32*)t1;   		/* the first free area */
      t0 = t1->prev_mem;	   /* the last data block so far, or NULL */
      assert( t0 == NULL || check_block(t0) );
      assert( t0 == NULL || ISDATA(t0) );
      assert( t0 == NULL || (uint32*)free_p == (uint32*)(t0->next_mem) );

      /** loop to copy data blocks down
      **  t1 scans thru mem blocks,
      **  t0 follows one behind, it is the latest concentrated block
      **/
      do {
         assert( t1->magic == MAGIC ); /* t1->prev?? may have been overwritten */
         if( ISDATA(t1) ) {
         register int32 i = t1->size + sizeof(tMemHdr); /* nr bytes to move */
         register uint32 *s1 = (uint32*)t1;             /* src address */

            /**** 
            ** move data block at t1 down to free_p, 
            ** adjust t0 = new conc'd data block, adjust t1
            *****/

            assert( t0 == NULL || (uint32*)free_p == (uint32*)(t0->next_mem) );

            tr = (tMemHdr*) free_p;  /* relocate block pointer */
            assert( tr != NULL );
            assert( tr < t1 );	/* there is a gap between end of t0 & start of t1 */
            t1 = t1->next_mem;	/* data at t1 will be overwritten if data size > gap too free_p */

            assert( (i&3) == 0 );	/* data & header both exact nr longs */
            i >>= 2; /* nr longs */
            while( --i >= 0 ) {	/* copy header & data of block */
               *free_p++ = *s1++;
            } /* if */

            /* note: free_p now points to new free area, at end of tr */

            assert( (uint32)tr->data + tr->size == (uint32)free_p );

            *tr->pbase = tr->data;
            tr->next_mem = (tMemHdr*)free_p;	/* adjust links */
            tr->prev_mem = t0;
            assert( (t0 == NULL && tr == head_mem) || t0->next_mem == tr );
            if( tr->next_list != NULL ) {
               tr->next_list->prev_list = tr;
            }
            else {
               tail_data = tr;
            } /* if */
            if( tr->prev_list != NULL ) {
               tr->prev_list->next_list = tr;
            }
            else {
               head_data = tr;
            } /* if */

            t0 = tr;
            assert( ISDATA(t0) );
            assert( check_block(t0) );
            assert( t0->prev_mem == NULL || t0->prev_mem->next_mem == t0);
         }
         else {
            nr_blocks--;   /* removed a free block */
            total_free += sizeof(tMemHdr);
            t1 = t1->next_mem;
         } /* if */
      } while( t1 != NULL );
      assert( t0 != NULL );

      /** now create one free block at the end of the cache */

      t1 = head_free = t0->next_mem;
      assert( head_free == (tMemHdr*)free_p );
      t1->next_mem = t1->next_list = t1->prev_list = NULL;
      t1->prev_mem = t0;
      total_free -= sizeof(tMemHdr);
      assert( total_free == (uint32)head_mem + total_size - (uint32)t1);
      t1->size = total_free;
      t1->pbase = NULL;
      #ifndef NDEBUG
      t1->magic = MAGIC;
      t1->data[0] = -2;
      #endif

      nr_blocks++;
      assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );
   } /* if */
コード例 #14
0
ファイル: ts-mem-test.c プロジェクト: caizongchao/open-mika
static void ts_mem_check(void * arg) {

  t_mchecker mc = arg;
  x_thread thread = mc->thread;
  x_size size;
  x_size old_size;
  x_size blocks_in_use = 0;
  t_Block Initial;
  t_block initial = &Initial;
  t_block block;
  x_int command;
  x_size discards = 0;
  x_size frees = 0;
  x_size allocs = 0;
  x_size reallocs_g = 0;
  x_size reallocs_s = 0;

  /*
  ** Initialize our own list.
  */

  initial->size = 1024 * 1024 * 30;
  x_list_init(initial);

  /*
  ** ... and check dynamic allocation and deallocation forever ...
  */

  while (1) {
  
    /*
    ** Select the operation: 0 and 1 = allocation, 2 = reallocation, 3 = change owner and 4 = free or discard
    */
    
    command = x_random() % 5;
    block = NULL;

    if (force_next_is_release || global_force_release) {
      command = 4;
      force_next_is_release = 0;
    }
    else if (force_next_is_allocation) {
      command = 0;
    }

    /*
    ** If we have released all our blocks due to a global force release command and
    ** we have no blocks left, we sleep so that other threads can start dumping their
    ** blocks.
    */

    if (global_force_release && blocks_in_use == 0) {
      x_thread_sleep(2);
    }

    /*
    ** Only do allocations when we have not all blocks in use.
    */

    if ((command == 1 || command == 0) && (blocks_in_use < max_blocks_in_use)) { 
      size = random_size();

      block = allocate_block(mc, initial, size, x_random() & 0x00000001);
      allocs += 1;
      if (block == NULL) {
        force_next_is_release = 1;
        global_force_release = 1;
        oempa("No more memory for %d bytes. Global force releasing enabled, %d bytes in use.\n", size, global_in_use);
        continue;
      }
      
      blocks_in_use += 1;
      allocations += 1;

      if (force_next_is_allocation) {
        force_next_is_allocation = 0;
      }

    }
    else if (command == 2) {
      block = initial->next;
      if (block != initial) {
        size = random_size();
        old_size = block->size;
        block = reallocate_block(mc, initial, block, size);
        if (old_size < size) {
          reallocs_g += 1;
        }
        else {
          reallocs_s += 1;
        }
        allocs += 1;
        if (block == NULL) {
          force_next_is_release = 1;
          global_force_release = 1;
          continue;
        }
      
        reallocations += 1;

      }
    }
    else if (command == 3) {
      block = initial->next;
    }
    else {
      block = initial->next;
      if (block != initial) {
        if (x_random() % 5 == 0) {
          release_block(mc, block, true, 1);
          discards += 1;
        }
        else {
          release_block(mc, block, true, 0);
          frees += 1;
        }
        blocks_in_use -= 1;
        releases += 1;
      }
    }

    if (allocs > 0 && allocs % 4000 == 0) {
      oempa("Thread %p: A %d Rg %d Rs %d D %d F %d\n", thread, allocs, reallocs_g, reallocs_s, discards, frees);
      force_next_is_allocation = 1;
    }

    if (allocs > 0 && allocs % 2000 == 0) {
      x_thread_sleep((x_random() % 10) + 10);
    }

  }
  
}
コード例 #15
0
ファイル: pool.cpp プロジェクト: LenxWei/libproton
void seg_pool::purge_circle(list_header* lh)
{
    while(!lh->empty()){
        release_block(get_block(lh->next()));
    }
}