Beispiel #1
0
Datei: gc.c Projekt: jbulow/tort
static void *_tort_object_alloc_smal(tort_mtable *mtable, size_t size)
{
  if ( mtable ) {
    if ( ! mtable->gc_data )
      mtable->gc_data = _type_for_size(size);
    if ( ++ allocs_since_gc > allocs_per_gc ) {
      tort_gc_collect();
      allocs_since_gc = 0;
    }
    return smal_alloc(mtable->gc_data);
  }
  return smal_alloc(_type_for_size(size));
}
Beispiel #2
0
smal_finalizer * smal_finalizer_create(void *ptr, void (*func)(smal_finalizer *finalizer))
{
  smal_finalized *finalized = 0;
  smal_finalizer *finalizer;

  if ( ! ptr ) return 0;

  if ( smal_unlikely(! initialized) ) initialize();

  smal_thread_mutex_lock(&referred_table_mutex);
  if ( ! (finalized = find_finalized_by_referred(ptr)) ) {
    if ( ! (finalized = smal_alloc(smal_finalized_type_)) ) {
      smal_thread_mutex_unlock(&referred_table_mutex);
      return 0;
    }
    finalized->referred = ptr;
    finalized->finalizers = 0;
    finalized->next = 0;
    smal_thread_mutex_init(&finalized->mutex);
    add_finalized(finalized);
  }
  smal_thread_mutex_unlock(&referred_table_mutex);

  smal_thread_mutex_lock(&finalized->mutex);

  if ( (finalizer = smal_alloc(smal_finalizer_type_)) ) {
    finalizer->referred = ptr;
    finalizer->func = func;
    finalizer->data = 0;
    
    finalizer->next = finalized->finalizers;
    finalized->finalizers = finalizer;
  }

  smal_thread_mutex_unlock(&finalized->mutex);
  return finalizer;
}
Beispiel #3
0
int main(int argc, char **argv)
{
  int alloc_id = 0;
  int alloc_n = 4000;
  my_cons *x = 0, *y = 0;
  smal_roots_2(x, y);
  
  my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0);
  
  fprintf(stderr, "allocing for x list\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type);
    c->car = (void*) 1;
    c->cdr = x;
    x = c;
  }
  my_print_stats();
  
  fprintf(stderr, "allocing for y list\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type);
    c->car = (void*) 2;
    c->cdr = y;
    y = c;
  }
  my_print_stats();

  fprintf(stderr, "dropping some of x\n");
  {
    my_cons *c;
    for ( c = x; c; c = c->cdr ) {
      if ( rand() % 10 > 5 ) {
	c->cdr = c->cdr ? ((my_cons*) c->cdr)->cdr : 0;
      }
    }
  }
  smal_collect();
  my_print_stats();

  fprintf(stderr, "allocing more for y list\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type);
    c->car = (void*) 2;
    c->cdr = y;
    y = c;
  }
  smal_collect();
  my_print_stats();
  
  x = y = 0;
  smal_collect();
  fprintf(stderr, "dereference all\n");
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.alloc_id == 12000);
    assert(stats.free_id == stats.alloc_id);
    assert(stats.capacity_n == 0);
    assert(stats.buffer_n == 0);
  }

  smal_roots_end();
  
  fprintf(stdout, "\nOK\n");
  
  fprintf(stderr, "\n%s OK\n", argv[0]);
  return 0;
}
Beispiel #4
0
static
void run_test()
{
  int alloc_id;
  my_cons *x = 0, *y = 0;

  my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0);
  
  for ( alloc_id = 0; alloc_id < 10000000; ++ alloc_id ) {
    int action = rand() % 10;
    x = smal_alloc(my_cons_type);
    ++ smal_alloc_n;
    
    x->car = x->cdr = 0;
    
    switch ( action ) {
    case 0:
      y = x; 
      break;
    case 1:
      if ( y )
	y->car = x;
      else
	y = x;
      break;
    case 2:
      if ( y )
	y->cdr = x;
      else
	y = x;
      break;
    }

#if 0
    fprintf(stderr, "%d", action);
    fflush(stderr);
#endif

#if 0
    if ( rand() % 100 == 0 ) {
      // fprintf(stderr, "\nGC\n");
      smal_collect();
      ++ smal_collect_n;
      // my_print_stats();
    }
    
    if ( rand() % 100 == 0 ) {
      int obj_count = 0;
      smal_each_object(my_count_object, &obj_count);
      ++ smal_each_object_n;
      {
	smal_stats stats = { 0 };
	smal_global_stats(&stats);
	assert(obj_count == stats.live_n);
      }
      // my_print_stats();
      // fprintf(stderr, "  object_count = %d\n", obj_count);
    }
#endif
  }
  
  fprintf(stderr, "\nDONE\n");
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.alloc_id == smal_alloc_n);
    assert(stats.free_id < stats.alloc_id);
  }

  x = y = 0;  
}
Beispiel #5
0
int main(int argc, char **argv)
{
  int i = 0;
  int ncollect = 2;
  int alloc_id = 0;
  int alloc_n = 100;
  my_cons *x = 0, *y = 0;
  my_cons *xp = 0, *yp = 0;
  smal_type *my_cons_type_mu; /* mostly_unchanging */
  smal_roots_4(x, y, xp, yp);

  smal_debug_set_level(smal_debug_mprotect, 9);
  smal_debug_set_level(smal_debug_mmap, 9);
  
  my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0);
  {
    smal_type_descriptor desc;
    memset(&desc, 0, sizeof(desc));
    desc.object_size = sizeof(my_cons);
    desc.mark_func = my_cons_mark;
    desc.mostly_unchanging = 1;
    my_cons_type_mu = smal_type_for_desc(&desc);
  }

  fprintf(stderr, "allocing for x list\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type);
    c->car = (void*) 1;
    c->cdr = x;
    x = c;
  }
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 0);
  }

  fprintf(stderr, "collecting x after list\n");
  smal_collect();
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 0);
  }

  fprintf(stderr, "allocing for y list (mostly_unchanging)\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type_mu);
    fprintf(stderr, "  c = %p\n", c);
    c->car = (void*) 2;
    c->cdr = y;
    y = c;
  }
  my_print_stats();

  fprintf(stderr, "collecting after x and y list\n");
  smal_collect();
  my_print_stats();

  fprintf(stderr, "mutating y list\n");
  xp = x; yp = y;
  while ( yp ) {
    yp->car = xp;
    yp = yp->cdr;
    xp = xp->cdr;
  }

  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 1);
  }

  fprintf(stderr, "collecting after mutating y list\n");
  smal_collect();
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 1);
  }

  fprintf(stderr, "mutating y list, again\n");
  xp = x; yp = y;
  while ( yp ) {
    yp->car = xp;
    yp = yp->cdr;
    xp = xp->cdr;
  }

  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 2);
  }

  fprintf(stderr, "collecting after mutating y list, again\n");
  smal_collect();
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.buffer_mutations == 2);
  }

#if 0
  fprintf(stderr, "dropping some of x\n");
  {
    my_cons *c;
    for ( c = x; c; c = c->cdr ) {
      if ( rand() % 10 > 5 ) {
	c->cdr = c->cdr ? ((my_cons*) c->cdr)->cdr : 0;
      }
    }
  }
  smal_collect();
  my_print_stats();

  fprintf(stderr, "allocing more for y list\n");
  for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) {
    my_cons *c = smal_alloc(my_cons_type);
    c->car = (void*) 2;
    c->cdr = y;
    y = c;
  }
  smal_collect();
  my_print_stats();
  
#endif

  x = y = 0;
  // smal_debug_level = 9;
  for ( i = 0; i < ncollect; ++ i ) {
    smal_collect();
    fprintf(stderr, "dereference all %d\n", i);
  }
  my_print_stats();
  {
    smal_stats stats = { 0 };
    smal_global_stats(&stats);
    assert(stats.alloc_id == alloc_n * 2);
    assert(stats.free_id == stats.alloc_id);
    assert(stats.capacity_n == 0);
    assert(stats.buffer_n == 0);
    assert(stats.buffer_mutations == 2);
  }

  smal_roots_end();
  
  fprintf(stderr, "\n%s OK\n", argv[0]);
  return 0;
}