コード例 #1
0
ファイル: dllskin.c プロジェクト: S0043640wipro/RiCRiPInt
static int dllskin_meminit(SWSTART *start)
{
  int32 i ;
  mps_arena_t dllskin_arena = NULL ;

  /* Spy on the memory configuration tags to find the arena */
  for ( i = 0 ; dllskin_arena == NULL && start[i].tag != SWEndTag ; ++i ) {
    switch ( start[i].tag ) {
    case SWMemoryTag:
      dllskin_arena = ((SWSTART_MEMORY *)start[i].value.pointer_value)->arena;
      break ;
    case SWMemCfgTag:
      dllskin_arena = ((SWSTART_MEMCFG *)start[i].value.pointer_value)->arena;
      break ;
    }
  }

  if ( dllskin_arena != NULL ) {
    mps_res_t res = mps_pool_create(&dllskin_pool, dllskin_arena, mps_class_mvff(),
                                    (size_t)65536, (size_t)32, (size_t)8,
                                    EPDR_LIKE);
    if ( res == MPS_RES_OK ) {
      mps_word_t label = mps_telemetry_intern("DLLskin pool");
      mps_telemetry_label((mps_addr_t)dllskin_pool, label);
    } else {
      SecurityExit(1, (uint8 *)"Unicode memory pool initialisation failed");
      return FALSE ;
    }
  }
  return TRUE ;
}
コード例 #2
0
ファイル: 232.c プロジェクト: Ravenbrook/mps
static void test(void *stack_pointer)
{
  mps_arena_t arena;
  mps_pool_t pool;
  mps_addr_t block[ITERATIONS];
  unsigned i;

  MPS_ARGS_BEGIN(args) {
    MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, CHUNKSIZE);
    die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "arena_create");
  } MPS_ARGS_END(args);

  MPS_ARGS_BEGIN(args) {
    MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0);
    die(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool_create");
  } MPS_ARGS_END(args);
  check_chunks(arena, 1);

  for (i = 0; i < ITERATIONS; ++i) {
    die(mps_alloc(&block[i], pool, CHUNKSIZE), "mps_alloc");
    check_chunks(arena, i + 2);
  }

  for (i = ITERATIONS; i > 0; --i) {
    mps_free(pool, block[i - 1], CHUNKSIZE);
    mps_arena_collect(arena); /* ensure ArenaCompact is called */
    check_chunks(arena, i);
  }

  mps_pool_destroy(pool);
  mps_arena_destroy(arena);
}
コード例 #3
0
ファイル: mpmss.c プロジェクト: clojit/rust-mps-obj
static void testInArena(mps_arena_class_t arena_class, mps_arg_s *arena_args,
                        mps_pool_debug_option_s *options)
{
  mps_arena_t arena;

  die(mps_arena_create_k(&arena, arena_class, arena_args),
      "mps_arena_create");

  MPS_ARGS_BEGIN(args) {
    mps_align_t align = sizeof(void *) << (rnd() % 4);
    MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double());
    die(stress(arena, NULL, randomSize8, align, "MVFF",
               mps_class_mvff(), args), "stress MVFF");
  } MPS_ARGS_END(args);

  MPS_ARGS_BEGIN(args) {
    mps_align_t align = sizeof(void *) << (rnd() % 4);
    MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE);
    MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double());
    MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options);
    die(stress(arena, options, randomSize8, align, "MVFF debug",
               mps_class_mvff_debug(), args), "stress MVFF debug");
  } MPS_ARGS_END(args);

  MPS_ARGS_BEGIN(args) {
    mps_align_t align = (mps_align_t)1 << (rnd() % 6);
    MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
    die(stress(arena, NULL, randomSize, align, "MV",
               mps_class_mv(), args), "stress MV");
  } MPS_ARGS_END(args);

  MPS_ARGS_BEGIN(args) {
    mps_align_t align = (mps_align_t)1 << (rnd() % 6);
    MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
    MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options);
    die(stress(arena, options, randomSize, align, "MV debug",
               mps_class_mv_debug(), args), "stress MV debug");
  } MPS_ARGS_END(args);

  MPS_ARGS_BEGIN(args) {
    fixedSizeSize = 1 + rnd() % 64;
    MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, fixedSizeSize);
    MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, 100000);
    die(stress(arena, NULL, fixedSize, MPS_PF_ALIGN, "MFS",
               mps_class_mfs(), args), "stress MFS");
  } MPS_ARGS_END(args);

  /* Manual allocation should not cause any garbage collections. */
  Insist(mps_collections(arena) == 0);
  mps_arena_destroy(arena);
}
コード例 #4
0
ファイル: locbwcss.c プロジェクト: ben01122/mps-temporary
static void testInArena(mps_arena_t arena)
{
    mps_pool_t lopool, hipool;
    PoolStatStruct lostruct;  /* stats about lopool */
    PoolStatStruct histruct;  /* stats about lopool */
    PoolStat lostat = &lostruct;
    PoolStat histat = &histruct;
    int i;

    die(mps_pool_create(&hipool, arena, mps_class_mvff(),
                        chunkSize, chunkSize,
                        (mps_align_t)1024,
                        TRUE, TRUE, TRUE),
        "Create HI MFFV");

    die(mps_pool_create(&lopool, arena, mps_class_mvff(),
                        chunkSize, chunkSize,
                        (mps_align_t)1024,
                        FALSE, FALSE, TRUE),
        "Create LO MFFV");

    poolStatInit(lostat, lopool, chunkSize);
    poolStatInit(histat, hipool, chunkSize);

    /* iterate, allocating objects */
    for (i=0; i<iterationCount; ++i) {
        allocMultiple(lostat);
        allocMultiple(histat);
    }

    /* report results */
    reportResults(lostat, "the low MVFF pool");
    reportResults(histat, "the high MVFF pool");

    if (lostat->max > histat->min) {
        error("\nFOUND PROBLEM - low range overlaps high\n");
    } else {
        printf("\nNo problems detected.\n");
    }

    mps_pool_destroy(hipool);
    mps_pool_destroy(lopool);
}
コード例 #5
0
ファイル: 163.c プロジェクト: Ravenbrook/mps
static void test(void *stack_pointer)
{
 mps_thr_t thread;
 mps_pool_t pool;
 unsigned int i;
 unsigned long nLarge;

 cdie(mps_arena_create(&arena, mps_arena_class_vm(),
  (size_t) (1024*1024*50)), "create arena");
 cdie(mps_thread_reg(&thread, arena), "register thread");

 mps_arena_commit_limit_set(arena, COMLIMIT1);

 die(mps_pool_create(&pool, arena, mps_class_mvff(),
                     (size_t)EXTENDBY, (size_t)8, (mps_align_t)MPS_PF_ALIGN,
                     (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1),
     "create MVFF pool");

 for (i = 0; i < NSMALL; i++) {
  die(mps_alloc(&smallObjects[i], pool, SMALLSIZE), "small alloc failed");
 }

 nLarge = 0;
 while (mps_alloc(&largeObjects[nLarge], pool, BIGSIZE) == MPS_RES_OK) {
  nLarge ++;
 }

 report("nLarge", "%lu", nLarge);

 for (i = 0; i < NSMALL; i += 2) {
  mps_free(pool, smallObjects[i], SMALLSIZE);
 }

 comment("Freed every other small object.");

 /* The CBS should be in emergency mode now. */

 for (i = 0; i < nLarge; i += 2) {
  mps_free(pool, largeObjects[i], BIGSIZE);
 }

 comment("Freed every other large object.");

 /* Now there should be lots of big blocks on the CBS. */

 mps_arena_commit_limit_set(arena, COMLIMIT2);

 comment("Raised the commit limit. Will attempt free and alloc.");
 mps_free(pool, largeObjects[1], BIGSIZE);
 die(mps_alloc(&largeObjects[0], pool, BIGSIZE), "alloc failed");

 mps_pool_destroy(pool);
 mps_thread_dereg(thread);
 mps_arena_destroy(arena);
}
コード例 #6
0
ファイル: 228.c プロジェクト: bhanug/mps
static void test(void)
{
  mps_arena_t arena;
  mps_pool_t pool;
  mps_addr_t p;

  die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none),
      "arena_create");
  die(mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none),
      "pool_create");
  die(mps_alloc(&p, pool, 4096), "alloc");
  die(mps_finalize(arena, &p), "finalize");

  mps_pool_destroy(pool);
  mps_arena_destroy(arena);
}
コード例 #7
0
ファイル: 59.c プロジェクト: Ravenbrook/mps
static void test(void *stack_pointer)
{
 mps_arena_t arena;
 mps_pool_t pool;
 mps_addr_t obj;

 cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");

 cdie(mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none), "pool");

 cdie(mps_alloc(&obj, pool, 152), "allocate");

 mps_free(pool, obj, 512);

 mps_pool_destroy(pool);
 mps_arena_destroy(arena);
}
コード例 #8
0
ファイル: mmreserve.c プロジェクト: S0043640wipro/RiCRiPInt
Bool mm_reserve_create(void)
{
  mps_word_t sym;
  Bool res;
  unsigned level;

  HQASSERT(mm_arena, "mm_reserve_create called without valid mm_arena");
  HQASSERT(mm_pool_reserve == NULL,
           "mm_reserve_create called when mm_pool_reserve already created");

#ifdef REGAIN_AT_FREE
  multi_mutex_init(&reserve_mutex, RESERVE_LOCK_INDEX, FALSE,
                   SW_TRACE_RESERVE_ACQUIRE, SW_TRACE_RESERVE_HOLD);
#endif
  if ( mps_pool_create(&mm_pool_reserve, mm_arena,
                       mps_class_mvff(), DL_POOL_PARAMS, FALSE, FALSE, TRUE)
       != MPS_RES_OK ) {
#ifdef REGAIN_AT_FREE
    multi_mutex_destroy(&reserve_mutex) ;
#endif
    return FALSE;
  }

  mm_reserve_level =
    mm_reserve_numlevels = MM_RESERVE_MAXLEVELS; /* No reserve yet */
  for ( level = mm_reserve_level ; level < mm_reserve_numlevels-1 ; level++ )
    HQASSERT(mm_cost_less_than(mm_reserve_table[level].cost, mm_cost_normal),
             "Normal cost doesn't include reserve.");
  HQASSERT(!mm_cost_less_than(mm_reserve_table[mm_reserve_numlevels-1].cost,
                              mm_cost_normal),
           "Normal cost includes final reserve.");

  sym = mps_telemetry_intern("MM reserve pool");
  mps_telemetry_label((mps_addr_t)mm_pool_reserve, sym);

  res = mm_reserve_get(mm_cost_below_reserves);
  /* This effectively asserts mm_cost_below_reserves is small enough. */
  HQASSERT( res, "init: didn't get reserve!" );

  res = low_mem_handler_register(&reserve_pool_handler);
  if ( !res )
    mps_pool_destroy(mm_pool_reserve);
  return res;
}
コード例 #9
0
ファイル: fmtpstst.c プロジェクト: S0043640wipro/RiCRiPInt
mps_res_t ps_init(mps_arena_t arena, mps_pool_t pool0, mps_pool_t pool1)
{
  size_t i;
  mps_res_t res;

  pool[0] = pool0; pool[1] = pool1;
  for (i = 0; i < MAXSAVELEVELS; ++i)
    saves[i] = NULL;
  res = mps_root_create(&saveRoot, arena, mps_rank_exact(), 0,
                        scan_saves, NULL, 0);
  if (res != MPS_RES_OK) return res;
  res = mps_pool_create(&savePool, arena, mps_class_mvff(), 8192,
                        sizeof(saveRecord), (mps_align_t)sizeof(OBJECT),
                        TRUE, TRUE, TRUE);
  if (res != MPS_RES_OK) goto failPool;

  Context.savelevel = 0; ps_save(); /* ps_*_init assume global savelevel */
  namepurges = NULL;
  return MPS_RES_OK;

failPool:
  mps_root_destroy(saveRoot);
  return res;
}
コード例 #10
0
ファイル: locusss.c プロジェクト: sionescu/mps-temporary
static void testInArena(mps_arena_t arena,
                        mps_bool_t failcase,
                        mps_bool_t usefulFailcase)
{
  mps_pool_t lopool, hipool, temppool;
  PoolStatStruct lostruct;  /* stats about lopool */
  PoolStatStruct histruct;  /* stats about lopool */
  PoolStatStruct tempstruct;  /* stats about temppool */
  PoolStat lostat = &lostruct;
  PoolStat histat = &histruct;
  PoolStat tempstat = &tempstruct;
  int i;

  die(mps_pool_create(&hipool, arena, mps_class_mvff(),
                      chunkSize, chunkSize, (size_t)1024,
                      TRUE, TRUE, TRUE),
      "Create HI MFFV");

  die(mps_pool_create(&lopool, arena, mps_class_mvff(),
                      chunkSize, chunkSize, (size_t)1024,
                      FALSE, FALSE, TRUE),
      "Create LO MFFV");

  die(mps_pool_create(&temppool, arena, mps_class_mv(),
                      chunkSize, chunkSize, chunkSize),
      "Create TEMP");

  if(failcase) {
    if(usefulFailcase) {
      /* describe a useful failure case */
    } else {
      /* describe a misleading failure case */
    }
  }

  poolStatInit(lostat, lopool, chunkSize);
  poolStatInit(histat, hipool, chunkSize);
  poolStatInit(tempstat, temppool, chunkSize);

  /* iterate, allocating objects */
  for (i=0; i<iterationCount; ++i) {
    mps_res_t res;
    res = allocMultiple(lostat);
    if (res != MPS_RES_OK)
      break;
    res = allocMultiple(histat);
    if (res != MPS_RES_OK)
      break;
    res = allocMultiple(tempstat);
    if (res != MPS_RES_OK)
      break;
  }

  /* report results */
  reportResults(lostat, "the low MVFF pool");
  reportResults(histat, "the high MVFF pool");
  reportResults(tempstat, "the temp pool");

  mps_pool_destroy(hipool);
  mps_pool_destroy(lopool);
  mps_pool_destroy(temppool);

}
コード例 #11
0
ファイル: 23.c プロジェクト: Ravenbrook/mps
static void test(void *stack_pointer)
{
 mps_arena_t arena;
 mps_pool_t poolMVFF, poolAMC;
 mps_thr_t thread;

 mps_fmt_t format;
 mps_chain_t chain;
 mps_ap_t ap;
 mps_res_t r;

 mycell *a;
 mps_addr_t p;

 int i;
 int s1, s2, s3;

 cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE),
      "create arena");

 cdie(mps_thread_reg(&thread, arena), "register thread");

 die(mps_fmt_create_A(&format, arena, &fmtA), "create format");
 cdie(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");

 formatcomments = 0;

 die(mmqa_pool_create_chain(&poolAMC, arena, mps_class_amc(), format, chain),
      "create pool");

 cdie(
  mps_ap_create(&ap, poolAMC, mps_rank_exact()),
  "create ap");

 comment("Sizes in megabytes:");

 MPS_ARGS_BEGIN(args) {
   MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY);
   MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE);
   cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args),
        "create MVFF pool");
 } MPS_ARGS_END(args);
 i = 0;
 while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++;
 report("refuse1", "%s", err_text(r));
 report("size1", "%i", i);
 s1 = i;
 mps_pool_destroy(poolMVFF);

 MPS_ARGS_BEGIN(args) {
   MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY);
   MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE);
   cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args),
        "create MVFF pool");
 } MPS_ARGS_END(args);
 i = 0;
 while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++;
 report("refuse2", "%s", err_text(r));
 report("size2", "%i", i);
 s2 = i;
 mps_pool_destroy(poolMVFF);

 a = allocdumb(ap, 1024*1024*30); /* allocate 30 M object */


 MPS_ARGS_BEGIN(args) {
   MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY);
   MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE);
   cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args),
        "create MVFF pool");
 } MPS_ARGS_END(args);
 i=0;
 while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++;
 report("refuse3", "%s", err_text(r));
 report("size3", "%i", i);
 s3 = i;

 report("diff12", "%i", s1-s2);
 report("diff23", "%i", s2-s3);

 for(i = 0; i < 10; i++) {
  r = mps_alloc(&p, poolMVFF, 1024*1024);
  report("refuse4", "%s", err_text(r));
 }

 mps_arena_park(arena);
 mps_pool_destroy(poolMVFF);

 mps_ap_destroy(ap);

 mps_pool_destroy(poolAMC);
 comment("Destroyed pool.");

 mps_chain_destroy(chain);
 mps_fmt_destroy(format);
 mps_thread_dereg(thread);
 mps_arena_destroy(arena);
 comment("Destroyed arena.");
}
コード例 #12
0
static void test(void)
{
 mps_pool_t poolhi, poollo;
 mps_thr_t thread;

 unsigned long com0, com1;

/* create a VM arena of 30MB */

 cdie(mps_arena_create(&arena, mps_arena_class_vmnz(), (size_t) (1024*1024*40)),
  "create arena");


/* set the commit limit to 100MB, i.e. let the arena do the limiting */

 mps_arena_commit_limit_set(arena, (size_t) (1024ul*1024ul*100ul));

 cdie(mps_thread_reg(&thread, arena), "register thread");

 cdie(
  mps_pool_create(&poolhi, arena, mps_class_mvff(), MVFF_HI_PARMS),
  "create high pool");

 cdie(
  mps_pool_create(&poollo, arena, mps_class_mvff(), MVFF_LO_PARMS),
  "create low pool");

/* set the spare commit limit to something very big */
 mps_arena_spare_commit_limit_set(arena, (size_t)-1);

/* allocate a jolly big object, clamp the commit limit down, leaving
   64KB space, then free it */

 die(mps_alloc(&objs[0], poollo, BIGSIZE), "alloc");
 com0 = mps_arena_committed(arena);
 mps_arena_commit_limit_set(arena, com0+(1024*64));

 mps_free(poollo, objs[0], BIGSIZE);
 com1 = mps_arena_committed(arena);

/* the free shouldn't have reduced the total amount committed */
 report("reduce1", "%ld", com0-com1);

/* it should be possible to reallocate the object */
 die(mps_alloc(&objs[0], poollo, BIGSIZE), "alloc lo");

 mps_free(poollo, objs[0], BIGSIZE);

/* it should equally be possible to allocate an object in a different
 segment (poolhi). This ought to flush the spare. */
 die(mps_alloc(&objs[0], poolhi, BIGSIZE), "alloc hi");

 mps_free(poolhi, objs[0], BIGSIZE);

 comment("Finishing off.");

 mps_pool_destroy(poolhi);
 mps_pool_destroy(poollo);
 comment("Destroyed pool.");

 mps_thread_dereg(thread);
 comment("Deregistered thread.");

 mps_arena_destroy(arena);
 comment("Destroyed arena.");

}
コード例 #13
0
ファイル: 200.c プロジェクト: Ravenbrook/mps
static void dt(int kind,
   size_t extendBy, size_t avgSize,
   unsigned long mins, unsigned long maxs, int number, int iter)
{
 mps_pool_t pool;
 int i, hd;
 clock_t time0, time1;
 size_t size;
 double secs;

 asserts(number <= MAXNUMBER, "number too big");

 time0 = clock();
 asserts(time0 != -1, "processor time not available");

 MPS_ARGS_BEGIN(args) {
   MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, extendBy);
   MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, avgSize);
   cdie(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool");
 } MPS_ARGS_END(args);

 for(hd=0; hd<number; hd++)
 {
  size = ranrange(mins, maxs);
  if ((ranint(2) && (kind & 2)) || (kind==DUMMY))
  {
   queue[hd].addr=NULL;
  }
  else
  {
   die(mps_alloc(&queue[hd].addr, pool, size), "alloc");
   setobj(queue[hd].addr, size, (unsigned char) (hd%256));
   queue[hd].size = size;
  }
 };

 hd=-1;

 for(i=0; i<iter; i++)
 {
   if (kind & 1) hd = ranint(number);
   else {ranint(number); hd=(hd+1)%number;} /* call raninit anyway
                                               to use same time */

   if (queue[hd].addr != NULL)
   {
    asserts(chkobj(queue[hd].addr, queue[hd].size, (unsigned char) (hd%256)),
      "corrupt at %x (%s: %x, %x, %lx, %lx, %i, %i)",
      queue[hd].addr,
      tdesc[kind], (int) extendBy, (int) avgSize,
      mins, maxs, number, iter);
    mps_free(pool, queue[hd].addr, queue[hd].size);
   }
   size = ranrange(mins, maxs);

   if ((ranint(2) && (kind & 2)) || (kind==DUMMY))
   {
    queue[hd].addr=NULL;
   }
   else
   {
    die(mps_alloc(&queue[hd].addr, pool, size),"alloc");
    setobj(queue[hd].addr, size, (unsigned char) (hd%256));
    queue[hd].size = size;
   }
 }

 mps_pool_destroy(pool);

 time1=clock();
 secs=(time1-time0)/(double)CLOCKS_PER_SEC;

 comment("%s test (%x, %x, %lx, %lx, %i, %i) in %.2f s",
  tdesc[kind], (int) extendBy, (int) avgSize,
  mins, maxs, number, iter, secs);
}
コード例 #14
0
ファイル: 170.c プロジェクト: BarAgent/mps-temporary
static void t_alloc(int spare, int spare_total, int commit, int obj_size) { 
 size_t size, hisize, comsize, comlimit;
 size_t spsize = 0, losize = 0; /* stop warnings */
 mps_res_t res, res_expected;

 if (obj_size == OBJ_SMALL) size = SMALL_SIZE; else size = BIG_SIZE;

 switch (spare_total) {
 case SPARE_EMPTY:
  spsize = 0;
  break;
 case SPARE_LESS:
  if (size > DIFF_SIZE) {
   spsize = size-DIFF_SIZE;
  } else {
   spsize = 0;
  }
  break;
 case SPARE_EXACT:
  spsize = size;
  break;
 case SPARE_MORE:
  spsize = size+DIFF_SIZE;
  break;
 default:
  error("Illegal spare.\n");
  break;
 }

 switch (spare) {
 case SPARE_EMPTY:
  losize = 0;
  break;
 case SPARE_LESS:
  if (size > DIFF_SIZE) {
   losize = size-DIFF_SIZE;
  } else {
   losize = 0;
  }
  break;
 case SPARE_EXACT:
  losize = size;
  break;
 case SPARE_MORE:
  losize = size+DIFF_SIZE;
  break;
 }

 if (losize > spsize) {
  losize = spsize;
  hisize = 0;
 } else {
  hisize = spsize-losize;
 }

 /* turn off commit limit for a moment */
 mps_arena_commit_limit_set(arena, HUGE);

 /* create low and high pools */
 
 die(
  mps_pool_create(&poolhi, arena, mps_class_mvff(), MVFF_HI_PARMS),
  "create high pool");

 die(
  mps_pool_create(&poollo, arena, mps_class_mvff(), MVFF_LO_PARMS),
  "create low pool");

 /* flush hysteresis fund, then set limit */

 mps_arena_spare_commit_limit_set(arena, SPARE_ZERO);
 mps_arena_spare_commit_limit_set(arena, SPARE_LIMIT);

 /* allocate something in each pool (to reduce risk of subsidiary
    allocation being neede later */

 die(mps_alloc(&objlo, poollo, EXTEND), "low alloc");
 die(mps_alloc(&objhi, poolhi, EXTEND), "high alloc");

 /* set up spare committed the way we want it */

 if (losize>0) {
  die(mps_alloc(&objlo, poollo, losize), "low setup");
  mps_free(poollo, objlo, losize);
 }

 if (hisize>0) {
  die(mps_alloc(&objhi, poolhi, hisize), "high setup");
  mps_free(poolhi, objhi, hisize);
 }

 /* spare is now set up correctly */
 /* now we need to set the commit limit correctly */

 comsize = arena_committed_and_used(arena);

 /* allow for 1/16th memory overhead in setting commit limit */

 if (commit == COMMIT_EXACT) {
  comlimit = comsize+size+(size/16);
 } else if (commit == COMMIT_NOCHANGE) {
  comlimit = mps_arena_committed(arena);
 } else if (commit == COMMIT_PLENTY) {
  comlimit = HUGE;
 } else /* commit == COMMIT_LITTLE */ {
  if (size > DIFF_SIZE) {
   comlimit = comsize+size+(size/16)+DIFF_SIZE;
  } else {
   comlimit = comsize+size+(size/16);
  }
 }

 die(mps_arena_commit_limit_set(arena, comlimit), "commit limit set");

 res = mps_alloc(&objlo, poollo, size);

 asserts(comlimit >= comsize, "comlimit was less than comsize!");

 if (size <= (comlimit-comsize)) {
  res_expected = MPS_RES_OK;
 } else {
  res_expected = MPS_RES_COMMIT_LIMIT;
 }

 if (res != res_expected) {
  comment("Spare useful/total %i/%i. Limit %i. Size %i. Expected %s. Got %s", spare, spare_total, commit, obj_size, err_text(res_expected), err_text(res));
  report("failed", "yes");
 }

 mps_pool_destroy(poollo);
 mps_pool_destroy(poolhi);
}