Beispiel #1
0
void *list_next(list_t *l)
{  
  int v;

  if(l->q>=l->m)
    {
      if( (l->mode & LIST_FIXEDMODE)!=0)
	{ assert(0); return NULL; }
      
      if( (l->mode & LIST_EXPMODE)!=0) 
	{
	  if(l->s<(1024*1024))
	    {
	      if((l->m*l->s)>(1024*1024*16))
		list_hint(l,l->m+((1024*1024*16)/l->s));
	      else
		list_hint(l,2*( (l->m==0)?16:l->m) );
	    }
	  else list_hint(l,l->m+1);
	}
      else
	{
	  v=l->m+(l->mode&LIST_MODECHUNK);
	  if(v<l->m)v=l->m+1;
	  list_hint(l, v);
	}
    }
  return ((char *)(l->d))+(l->s * l->q++);
}
Beispiel #2
0
static void
note_new_vars( int line, const char *file ) {
  list new_arenas;
  list new_free;
  int err;
  const where *w;

  if ( !file ) {
    return;
  }
#ifdef SANITY
  free_list_sane(  );
#endif

  w = get_where( line, file );

  /*fprintf(stderr, "note_new_vars(%d, \"%s\")\n", line, file); */

  if ( err =
       list_build( &new_arenas, PL_sv_arenaroot,
                   list_hint( &current_arenas ) ), ERR_None != err ) {
    nomem(  );
  }

  if ( err =
       list_build( &new_free, PL_sv_root, list_hint( &current_free ) ),
       ERR_None != err ) {
    nomem(  );
  }

  if ( note_init_done ) {
    /* Scan the lists looking for new arenas and deleted
     * free slots. A deleted free slot implies the creation of a new
     * variable.
     */

    list_true_diff( &current_arenas, &new_arenas, w, new_arena,
                    free_arena );
    list_true_diff( &new_free, &current_free, w, new_var, free_var );

    list_delete( &current_arenas );
    list_delete( &current_free );
  }

  /* Roll round to new versions of lists */
  current_arenas = new_arenas;
  current_free = new_free;
  note_init_done = 1;
}
Beispiel #3
0
/* Sanity check - compare the free list with the list of free SVs in the arenas */
static void
free_list_sane( void ) {
  list real_free;
  list comp_free;
  int err;
  SV *sva;
  long diff;

  /* Get the real free list */
  if ( err =
       list_build( &real_free, PL_sv_root, list_hint( &current_free ) ),
       ERR_None != err ) {
    nomem(  );
  }

  /* Get the list of all the free SVs in all the arenas */
  if ( err =
       list_init( &comp_free, list_hint( &real_free ) ),
       ERR_None != err ) {
    nomem(  );
  }

  for ( sva = PL_sv_arenaroot; sva; sva = ( SV * ) SvANY( sva ) ) {
    SV *sv = sva + 1;
    SV *svend = &sva[SvREFCNT( sva )];

    while ( sv < svend ) {
      if ( free_sv( sv ) ) {
        if ( err = list_append( &comp_free, sv ), ERR_None != err ) {
          nomem(  );
        }
      }
      ++sv;
    }
  }

  diff =
      list_true_diff( &real_free, &comp_free, NULL, in_free_only,
                      in_comp_only );

  if ( diff != 0 ) {
    fprintf( stderr, "Lists have %ld differences, stopping\n", diff );
    fprintf( stderr,
             "%ld items in free list, %ld free items in arenas\n",
             ( long ) list_used( &real_free ),
             ( long ) list_used( &comp_free ) );
    exit( 1 );
  }
}
Beispiel #4
0
void list_dup(list_t *newl, list_t *oldl)
{
  void *d;
  list_copyfrom(newl,oldl);
  list_hint(newl,oldl->q);
  d=list_block_next(newl,oldl->q);
  memcpy(d,oldl->d,oldl->s*oldl->q);
}
Beispiel #5
0
void list_append(list_t *growing, list_t *copyfrom)
{
  void *d;
  if(copyfrom==NULL)return;
  assert(growing->s==copyfrom->s);
  if(copyfrom->q==0)return;
  list_hint(growing,growing->q+copyfrom->q);
  d=list_block_next(growing,copyfrom->q);
  memcpy(d,copyfrom->d,copyfrom->s*copyfrom->q);
}
Beispiel #6
0
void *list_block_next(list_t *l, int qty)
{
  void *r;
  if((l->q+qty)>=l->m)
    list_hint(l, l->q+qty);
  
  r=((char*)l->d)+(l->s*l->q);
  l->q+=qty;
  return r;
}
Beispiel #7
0
void list_shrink(list_t *l)
{
  list_hint(l,l->q);
}