Ejemplo n.º 1
0
int gc_mark(cell value)
{
  int index,incr,incridx,mask;
  cell v,t;
  unsigned char *minorbyte;

  if (SharedGC.table==NULL)
    return GC_ERR_INIT;
  if (SharedGC.count>=(1<<SharedGC.exponent)) {
    int err;
    if ((SharedGC.flags & GC_AUTOGROW)==0)
      return GC_ERR_TABLEFULL;
    err=gc_settable(SharedGC.exponent+1,SharedGC.flags);
    if (err!=GC_ERR_NONE)
      return err;
  } /* if */
  assert(SharedGC.count<(1<<SharedGC.exponent));

  /* first "fold" the value, to make maximum use of all bits */
  v=value;
  if (SharedGC.exponent<SHIFT1)
    v=FOLD1(v);
  if (SharedGC.exponent<SHIFT2)
    v=FOLD2(v);
  if (SharedGC.exponent<SHIFT3)
    v=FOLD3(v);
  /* swap the bits of the minor byte */
  minorbyte=(unsigned char*)&v;
  *minorbyte=inverse[*minorbyte];
  /* truncate the value to the required number of bits */
  mask=MASK(SharedGC.exponent);
  index=(v & mask);

  incridx= (SharedGC.exponent<sizeof increments / sizeof increments[0]) ?
              SharedGC.exponent :
              (sizeof increments / sizeof increments[0]) - 1;
  assert(incridx<sizeof increments / sizeof increments[0]);
  incr=increments[incridx];
  while ((t=SharedGC.table[index].value)!=0 && t!=value) {
    assert(incr>0);
    index=(index+incr) & mask;
    if (incridx>0)
      incr=increments[--incridx];
  } /* while */

  if (t!=0) {
    assert(t==value);
    assert(SharedGC.table[index].value==value);
    return GC_ERR_DUPLICATE;
  } /* if */

  SharedGC.table[index].value=value;
  assert(SharedGC.table[index].count==0);

  return GC_ERR_NONE;
}
Ejemplo n.º 2
0
static
void garbagecollect(AMX amx[], int number)
{
  int exp, usage, n;

  /* see whether it may be a good time to increase the table size */
  gc_tablestat(&exp, &usage);
  if (usage > 50) {
    if (gc_settable(exp+1, GC_AUTOGROW) != GC_ERR_NONE)
      fprintf(stderr, "Warning, memory low\n");
  } /* if */

  /* scan all abstract machines */
  for (n = 0; n < number; n++)
    gc_scan(&amx[n]);

  /* clean up unused references */
  gc_clean();
}
Ejemplo n.º 3
0
int main(int argc,char *argv[])
{
  AMX amx;
  cell ret = 0;
  int err;

  if (argc != 2)
    PrintUsage(argv[0]);        /* function "usage" aborts the program */

  /* Load the program and initialize the abstract machine. */
  err = aux_LoadProgram(&amx, argv[1], NULL, srun_Monitor);
  if (err != AMX_ERR_NONE) {
    /* try adding an extension */
    char filename[_MAX_PATH];
    strcpy(filename, argv[1]);
    strcat(filename, ".amx");
    err = aux_LoadProgram(&amx, filename, NULL, srun_Monitor);
    if (err != AMX_ERR_NONE)
      PrintUsage(argv[0]);
  } /* if */

  /* Initialize two core extension modules (more extension modules may be
   * loaded & initialized automatically as DLLs or shared libraries.
   */
  amx_ConsoleInit(&amx);
  amx_CoreInit(&amx);
  /* register functions for the bstring library */
  err = amx_Register(&amx, bstring_Natives, -1);
  ExitOnError(&amx, err);

  /* Initialize the garbage collector, start with a small table. */
  gc_setcallback((GC_FREE)bdestroy);
  err = gc_settable(7, GC_AUTOGROW);
  ExitOnError(&amx, err);

  /* Run the compiled script and time it. The "sleep" instruction causes the
   * abstract machine to return in a "restartable" state (it restarts from
   * the point that it stopped. This enables for a kind of light-weight
   * cooperative multi-tasking. As native functions (or the debug hook) can
   * also force an abstract machine to "sleep", you can also use it to create
   * "latent functions": functions that allow the host application to continue
   * processing, and/or other abstract machines to run, while they wait for
   * some resource.
   * In this example, there are no other abstract machines (there is just one)
   * and this "host" program has nothing else to do than run the abstract
   * machine. So if it detects a "sleep" it just restarts the abstract machine
   * immediately.
   */
  err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN, 0);
  while (err == AMX_ERR_SLEEP)
    err = amx_Exec(&amx, &ret, AMX_EXEC_CONT, 0);
  ExitOnError(&amx, err);

  /* Free the compiled script and resources. This also unloads and DLLs or
   * shared libraries that were registered automatically by amx_Init().
   */
  aux_FreeProgram(&amx);

  /* Free the garbarge collector data and tables. */
  gc_settable(0);

  /* Print the return code of the compiled script (often not very useful). */
  if (ret!=0)
    printf("\nReturn value: %ld\n", (long)ret);

  #if defined AMX_TERMINAL
    /* This is likely a graphical terminal, which should not be closed
     * automatically
     */
    {
      extern int amx_termctl(int,int);
      while (amx_termctl(4,0))
        /* nothing */;
    }
  #endif

  return 0;
}