Ejemplo n.º 1
0
/* Initialize bitset as copy of another bitset. */
ILIAS_NET2_EXPORT int
net2_bitset_init_copy(struct net2_bitset *s, const struct net2_bitset *src)
{
	if (src->sz > BITS) {
		if ((s->indir = malloc(SIZE_TO_BYTES(src->sz))) == NULL)
			return ENOMEM;
		memcpy(s->indir, src->indir, SIZE_TO_BYTES(src->sz));
		s->sz = src->sz;
	} else
		*s = *src;	/* Struct copy. */
	return 0;
}
Ejemplo n.º 2
0
bitset *bitset_new(int nbits)
{
        bitset *b;

        b = (bitset *)malloc(sizeof(bitset));

        b->bs_nbits = nbits;
        b->bs_size = BIT_INDEX(nbits-1) + 1;
        b->bs_bits = (bits *)malloc(SIZE_TO_BYTES(b->bs_size));
        memset(b->bs_bits, 0, SIZE_TO_BYTES(b->bs_size));

        return b;
}
Ejemplo n.º 3
0
/* Change the size of the bitset. */
ILIAS_NET2_EXPORT int
net2_bitset_resize(struct net2_bitset *s, size_t newsz, int new_is_set)
{
	size_t		 need, have, i;
	uintptr_t	*list;

	if (newsz <= BITS) {
		if (s->sz > BITS) {
			list = s->indir;
			s->immed = list[0];
			free(s->indir);
		}

		goto init_data;
	}

	if (s->sz > BITS)
		list = s->indir;
	else
		list = NULL;
	need = SIZE_TO_BYTES(newsz);
	have = SIZE_TO_BYTES(s->sz);
	if (newsz > SIZE_MAX / sizeof(*list))
		return ENOMEM;	/* size_t overflow detected. */

	if (need != have) {
		if (list == NULL) {
			if ((list = malloc(need)) == NULL)
				return ENOMEM;
			list[0] = s->immed;
		} else if ((list = realloc(list, need)) == NULL)
			return ENOMEM;
		s->indir = list;
	}

init_data:
	if (s->sz >= newsz) {
		/* Truncated list. */
		s->sz = newsz;
	} else {
		/* Grown list. */
		i = s->sz;
		s->sz = newsz;
		while (i < newsz) {
			net2_bitset_set(s, i, new_is_set, NULL);
			i++;
		}
	}
	return 0;
}
Ejemplo n.º 4
0
/*
 * Find the first bit set in the bitset.
 *
 * NOTE: ffs() assumes an integer argument. If sizeof(bits) is anything
 * else this will need to be fixed.
 */
unsigned int bitset_firstset(bitset *b)
{
	unsigned int	i;

	for (i = 0; i < b->bs_size; i++)
		if (b->bs_bits[i] != 0)
			break;

	if (i == b->bs_size)
		return -1;

	return (SIZE_TO_BYTES(i) << 3) + ffs(b->bs_bits[i]) - 1;
}
Ejemplo n.º 5
0
void minor_sweep_phase_young() 
{
  int size, perc;
  int reclaiming = 0;
  int alive = 0;

  old_bytes_in_young_blocks_since_last_major = 0;
  
  for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) {
    Block *prev_block = NULL;
    Block *next_block;
    ATerm old_freelist;

    Block *block = at_blocks[size];
    header_type *end = top_at_blocks[size];

      /* empty the freelist*/
    at_freelist[size] = NULL;
        
    while(block) {
        /* set empty = 0 to avoid recycling*/
      int empty = 1;
      int alive_in_block = 0;
      int dead_in_block  = 0;
      int free_in_block  = 0;
      int old_in_block  = 0;
      int capacity = (end-(block->data))/size;
      header_type *cur;
      
      assert(block->size == size);
      
      old_freelist = at_freelist[size];
      for(cur=block->data ; cur<end ; cur+=size) {
	ATerm t = (ATerm)cur;
	if(IS_MARKED(t->header) || IS_OLD(t->header)) {
          if(IS_OLD(t->header)) {
            old_in_block++;
          }
	  CLR_MARK(t->header);
          alive_in_block++;
          empty = 0;
          assert(!IS_MARKED(t->header));
	} else {
	  switch(ATgetType(t)) {
              case AT_FREE:
                /* AT_freelist[size] is not empty: so DO NOT ADD t*/
                t->aterm.next = at_freelist[size];
                at_freelist[size] = t;
                free_in_block++;
                break;
              case AT_INT:
              case AT_REAL:
              case AT_APPL:
              case AT_LIST:
              case AT_PLACEHOLDER:
              case AT_BLOB:
                AT_freeTerm(size, t);
                t->header = FREE_HEADER;
                t->aterm.next   = at_freelist[size];
                at_freelist[size] = t;
                
                dead_in_block++;
                break;
              case AT_SYMBOL:
                AT_freeSymbol((SymEntry)t);
                t->header = FREE_HEADER;
                t->aterm.next   = at_freelist[size];
                at_freelist[size] = t;
                dead_in_block++;
                break;

              default:
                ATabort("panic in sweep phase\n");
	  }
          assert(!IS_MARKED(t->header));
	}
      }

      assert(alive_in_block + dead_in_block + free_in_block == capacity);
      next_block    = block->next_by_size;

#ifndef NDEBUG
      if(empty) {
        for(cur=block->data; cur<end; cur+=size) {
          assert(ATgetType((ATerm)cur) == AT_FREE);
        }
      }
#endif

      /* Do not reclaim frozen blocks */
      if(IS_FROZEN(block)) {
        at_freelist[size] = old_freelist;
      }
      
       /* TODO: create freeList Old*/
      if(0 && empty) {
        at_freelist[size] = old_freelist;
        reclaim_empty_block(at_blocks, size, block, prev_block);
      } else if(0 && 100*old_in_block/capacity >= TO_OLD_RATIO) {
        promote_block_to_old(size, block, prev_block);
      } else {
        old_bytes_in_young_blocks_since_last_major += (old_in_block*SIZE_TO_BYTES(size));
        prev_block = block;
      }

      block = next_block;
      if(block) {
        end = block->end;
      }
      alive += alive_in_block;
      reclaiming += dead_in_block;
    }

#ifndef NDEBUG
    if(at_freelist[size]) {
      ATerm data;
      /*fprintf(stderr,"minor_sweep_phase_young: ensure empty freelist[%d]\n",size);*/
      for(data = at_freelist[size] ; data ; data=data->aterm.next) {
        if(!EQUAL_HEADER(data->header,FREE_HEADER)) {
          fprintf(stderr,"data = %p header = %x\n",data,(unsigned int) data->header);
        }
        assert(EQUAL_HEADER(data->header,FREE_HEADER)); 
        assert(ATgetType(data) == AT_FREE);   
      }
    }
#endif
    
  }
  if(alive) {
    perc = (100*reclaiming)/alive;
    STATS(reclaim_perc, perc);
  }
}
Ejemplo n.º 6
0
void major_sweep_phase_young() 
{
  int perc;
  int reclaiming = 0;
  int alive = 0;
  int size;

  old_bytes_in_young_blocks_since_last_major = 0;
  
  for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) {
    Block *prev_block = NULL;
    Block *next_block;
    ATerm old_freelist;

    Block *block      = at_blocks[size];
    header_type *end  = top_at_blocks[size];

    while(block) {
      int empty = 1;
      int alive_in_block = 0;
      int dead_in_block  = 0;
      int free_in_block  = 0;
      int old_in_block   = 0;
      int young_in_block = 0;
      int capacity = (end-(block->data))/size;
      header_type *cur;
      
      assert(block->size == size);

      old_freelist = at_freelist[size];
      for(cur=block->data ; cur<end ; cur+=size) {
	ATerm t = (ATerm)cur;
	if(IS_MARKED(t->header)) {
	  CLR_MARK(t->header);
          alive_in_block++;
          empty = 0;
          if(IS_OLD(t->header)) {
            old_in_block++;
          } else {
            young_in_block++;
          }
	} else {
	  switch(ATgetType(t)) {
              case AT_FREE:
                t->aterm.next = at_freelist[size];
                at_freelist[size] = t;
                free_in_block++;
                break;
              case AT_INT:
              case AT_REAL:
              case AT_APPL:
              case AT_LIST:
              case AT_PLACEHOLDER:
              case AT_BLOB:
                AT_freeTerm(size, t);
                t->header = FREE_HEADER;
                t->aterm.next = at_freelist[size];
                at_freelist[size] = t;
                dead_in_block++;
                break;
              case AT_SYMBOL:
                AT_freeSymbol((SymEntry)t);
                t->header = FREE_HEADER;
                t->aterm.next = at_freelist[size];
                at_freelist[size] = t;
                
                dead_in_block++;
                break;
              default:
                ATabort("panic in sweep phase\n");
	  }
	}
      }
      assert(alive_in_block + dead_in_block + free_in_block == capacity);
      
      next_block = block->next_by_size;

#ifndef NDEBUG
      if(empty) {
        for(cur=block->data; cur<end; cur+=size) {
          assert(ATgetType((ATerm)cur) == AT_FREE);
        }
      }
#endif

#ifdef GC_VERBOSE
        /*fprintf(stderr,"old_cell_in_young_block ratio = %d\n",100*old_in_block/capacity);*/
#endif
       
      if(end==block->end && empty) {
#ifdef GC_VERBOSE
        fprintf(stderr,"MAJOR YOUNG: reclaim empty block %p\n",block);
#endif
        at_freelist[size] = old_freelist;
	reclaim_empty_block(at_blocks, size, block, prev_block);
      } else if(end==block->end && 100*old_in_block/capacity >= TO_OLD_RATIO) {
        if(young_in_block == 0) {
#ifdef GC_VERBOSE
          fprintf(stderr,"MAJOR YOUNG: promote block %p to old\n",block);
#endif
          at_freelist[size] = old_freelist;
          promote_block_to_old(size, block, prev_block);
          old_bytes_in_old_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size));
        } else {
#ifdef GC_VERBOSE
          fprintf(stderr,"MAJOR YOUNG: freeze block %p\n",block);
#endif
          SET_FROZEN(block);
          old_bytes_in_young_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size));
          at_freelist[size] = old_freelist;
          prev_block = block;
        }
      } else {
        old_bytes_in_young_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size));
        prev_block = block;
      }

      block = next_block;
      if(block) {
        end = block->end;
      }

      alive += alive_in_block;
      reclaiming += dead_in_block;
    }

#ifndef NDEBUG
    if(at_freelist[size]) {
      ATerm data;
      for(data = at_freelist[size] ; data ; data=data->aterm.next) {
        assert(EQUAL_HEADER(data->header,FREE_HEADER)); 
        assert(ATgetType(data) == AT_FREE);   
      } 
    }
#endif
    
  }
  if(alive) {
    perc = (100*reclaiming)/alive;
    STATS(reclaim_perc, perc);
  }
}
Ejemplo n.º 7
0
void major_sweep_phase_old() 
{
  int size, perc;
  int reclaiming = 0;
  int alive = 0;

  for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) {
    Block *prev_block = NULL;
    Block *next_block;

    Block *block = at_old_blocks[size];

    while(block) {
      /* set empty = 0 to avoid recycling*/
      int empty = 1;
      int alive_in_block = 0;
      int dead_in_block  = 0;
      int free_in_block  = 0;
      int capacity = ((block->end)-(block->data))/size;
      header_type *cur;

      assert(block->size == size);

      for(cur=block->data ; cur<block->end ; cur+=size) {
          /* TODO: Optimisation*/
	ATerm t = (ATerm)cur;
	if(IS_MARKED(t->header)) {
	  CLR_MARK(t->header);
          alive_in_block++;
          empty = 0;
          assert(IS_OLD(t->header));
	} else {
	  switch(ATgetType(t)) {
              case AT_FREE:
                assert(IS_YOUNG(t->header));
                free_in_block++;
                break;
              case AT_INT:
              case AT_REAL:
              case AT_APPL:
              case AT_LIST:
              case AT_PLACEHOLDER:
              case AT_BLOB:
                assert(IS_OLD(t->header));
                AT_freeTerm(size, t);
                t->header=FREE_HEADER;
                dead_in_block++;
                break;
              case AT_SYMBOL:
                assert(IS_OLD(t->header));
                AT_freeSymbol((SymEntry)t);
                t->header=FREE_HEADER;
                dead_in_block++;
                break;
              default:
                ATabort("panic in sweep phase\n");
	  }
	}
      }
      assert(alive_in_block + dead_in_block + free_in_block == capacity);
      
      next_block = block->next_by_size;
      
#ifndef NDEBUG
      if(empty) {
        for(cur=block->data; cur<block->end; cur+=size) {
          assert(ATgetType((ATerm)cur) == AT_FREE);
        }
      }
#endif
      
      if(empty) {
          /* DO NOT RESTORE THE FREE LIST: free cells have not been inserted*/
          /* at_freelist[size] = old_freelist;*/
        assert(top_at_blocks[size] < block->data || top_at_blocks[size] > block->end);
#ifdef GC_VERBOSE
        fprintf(stderr,"MAJOR OLD: reclaim empty block %p\n",block);
#endif
        reclaim_empty_block(at_old_blocks, size, block, prev_block);
      } else if(0 && 100*alive_in_block/capacity <= TO_YOUNG_RATIO) {
        promote_block_to_young(size, block, prev_block);
        old_bytes_in_young_blocks_after_last_major += (alive_in_block*SIZE_TO_BYTES(size));
      } else {
        old_bytes_in_old_blocks_after_last_major += (alive_in_block*SIZE_TO_BYTES(size));
        
        /* DO NOT FORGET THIS LINE*/
        /* update the previous block*/
        prev_block = block;
      }

      block = next_block;
      alive += alive_in_block;
      reclaiming += dead_in_block;
    }
  }
  if(alive) {
    perc = (100*reclaiming)/alive;
    STATS(reclaim_perc, perc);
  }
}
Ejemplo n.º 8
0
void bitset_clear(bitset *b)
{
	memset(b->bs_bits, 0, SIZE_TO_BYTES(b->bs_size));
}
Ejemplo n.º 9
0
void bitset_copy(bitset *b1, bitset *b2)
{
	memcpy(b1->bs_bits, b2->bs_bits, MIN(SIZE_TO_BYTES(b1->bs_size), SIZE_TO_BYTES(b2->bs_size)));
}