Res ThreadRegister(Thread *threadReturn, Arena arena)
{
    Res res;
    Thread thread;
    Ring ring;
    void *p;

    AVER(threadReturn != NULL);

    res = ControlAlloc(&p, arena, sizeof(ThreadStruct),
                       /* withReservoirPermit */ FALSE);
    if(res != ResOK) return res;
    thread = (Thread)p;

    thread->arena = arena;
    RingInit(&thread->arenaRing);

    thread->sig = ThreadSig;
    thread->serial = arena->threadSerial;
    ++arena->threadSerial;

    AVERT(Thread, thread);

    ring = ArenaThreadRing(arena);
    AVER(RingCheckSingle(ring));  /* .single */

    RingAppend(ring, &thread->arenaRing);

    *threadReturn = thread;
    return ResOK;
}
Exemple #2
0
Res BufferCreate(Buffer *bufferReturn, BufferClass klass,
                 Pool pool, Bool isMutator, ArgList args)
{
  Res res;
  Buffer buffer;
  Arena arena;
  void *p;

  AVER(bufferReturn != NULL);
  AVERT(BufferClass, klass);
  AVERT(Pool, pool);

  arena = PoolArena(pool);

  /* Allocate memory for the buffer descriptor structure. */
  res = ControlAlloc(&p, arena, klass->size);
  if (res != ResOK)
    goto failAlloc;
  buffer = p;

  /* Initialize the buffer descriptor structure. */
  res = BufferInit(buffer, klass, pool, isMutator, args);
  if (res != ResOK)
    goto failInit;

  *bufferReturn = buffer;
  return ResOK;

failInit:
  ControlFree(arena, buffer, klass->size);
failAlloc:
  return res;
}
Exemple #3
0
Res PoolCreate(Pool *poolReturn, Arena arena,
               PoolClass klass, ArgList args)
{
  Res res;
  Pool pool;
  void *base;

  AVER(poolReturn != NULL);
  AVERT(Arena, arena);
  AVERT(PoolClass, klass);

  /* .space.alloc: Allocate the pool instance structure with the size */
  /* requested  in the pool class.  See .space.free */
  res = ControlAlloc(&base, arena, klass->size);
  if (res != ResOK)
    goto failControlAlloc;
  pool = (Pool)base;

  /* Initialize the pool. */ 
  res = PoolInit(pool, arena, klass, args);
  if (res != ResOK)
    goto failPoolInit;
 
  *poolReturn = pool; 
  return ResOK;

failPoolInit:
  ControlFree(arena, base, klass->size);
failControlAlloc:
  return res;
}
Exemple #4
0
Res ThreadRegister(Thread *threadReturn, Arena arena)
{
  Res res;
  Thread thread;
  Ring ring;
  void *p;

  AVER(threadReturn != NULL);

  res = ControlAlloc(&p, arena, sizeof(ThreadStruct));
  if (res != ResOK)
    return res;
  thread = (Thread)p;

  thread->arena = arena;
  RingInit(&thread->arenaRing);

  thread->serial = arena->threadSerial;
  ++arena->threadSerial;
  thread->alive = TRUE;
  thread->forking = FALSE;
  thread->port = mach_thread_self();
  AVER(MACH_PORT_VALID(thread->port));
  thread->sig = ThreadSig;
  AVERT(Thread, thread);

  ProtThreadRegister();

  ring = ArenaThreadRing(arena);

  RingAppend(ring, &thread->arenaRing);

  *threadReturn = thread;
  return ResOK;
}
Res ThreadRegister(Thread *threadReturn, Arena arena)
{
  Res res;
  Thread thread;
  void *p;

  AVER(threadReturn != NULL);
  AVERT(Arena, arena);

  res = ControlAlloc(&p, arena, sizeof(ThreadStruct),
                     /* withReservoirPermit */ FALSE);
  if(res != ResOK)
    return res;
  thread = (Thread)p;

  thread->id = pthread_self();

  RingInit(&thread->arenaRing);

  thread->sig = ThreadSig;
  thread->serial = arena->threadSerial;
  ++arena->threadSerial;
  thread->arena = arena;
  thread->mfc = NULL;

  PThreadextInit(&thread->thrextStruct, thread->id);

  AVERT(Thread, thread);

  RingAppend(ArenaThreadRing(arena), &thread->arenaRing);

  *threadReturn = thread;
  return ResOK;
}
Exemple #6
0
Res TraceIdMessagesCreate(Arena arena, TraceId ti)
{
  void *p;
  TraceStartMessage tsMessage;
  TraceMessage tMessage;
  Res res;
  
  /* Ensure we don't leak memory */
  AVER(!arena->tsMessage[ti]);
  AVER(!arena->tMessage[ti]);
  
  res = ControlAlloc(&p, arena, sizeof(TraceStartMessageStruct));
  if(res != ResOK)
    goto failTraceStartMessage;
  tsMessage = p;

  res = ControlAlloc(&p, arena, sizeof(TraceMessageStruct));
  if(res != ResOK)
    goto failTraceMessage;
  tMessage = p;

  traceStartMessageInit(arena, tsMessage);
  AVERT(TraceStartMessage, tsMessage);

  traceMessageInit(arena, tMessage);
  AVERT(TraceMessage, tMessage);

  arena->tsMessage[ti] = tsMessage;
  arena->tMessage[ti] = tMessage;
  
  AVER(TraceIdMessagesCheck(arena, ti));
  
  return ResOK;

failTraceMessage:
  ControlFree(arena, tsMessage, sizeof(TraceStartMessageStruct));
failTraceStartMessage:
  AVER(TraceIdMessagesCheck(arena, ti));
  return res;
}
Exemple #7
0
Res SegAlloc(Seg *segReturn, SegClass klass, LocusPref pref,
             Size size, Pool pool, ArgList args)
{
  Res res;
  Arena arena;
  Seg seg;
  Addr base;
  void *p;

  AVER(segReturn != NULL);
  AVERT(SegClass, klass);
  AVERT(LocusPref, pref);
  AVER(size > (Size)0);
  AVERT(Pool, pool);

  arena = PoolArena(pool);
  AVERT(Arena, arena);
  AVER(SizeIsArenaGrains(size, arena));

  /* allocate the memory from the arena */
  res = ArenaAlloc(&base, pref, size, pool);
  if (res != ResOK)
    goto failArena;

  /* allocate the segment object from the control pool */
  res = ControlAlloc(&p, arena, klass->size);
  if (res != ResOK)
    goto failControl;
  seg = p;

  res = SegInit(seg, klass, pool, base, size, args);
  if (res != ResOK)
    goto failInit;

  EVENT5(SegAlloc, arena, seg, SegBase(seg), size, pool);
  *segReturn = seg;
  return ResOK;

failInit:
  ControlFree(arena, seg, klass->size);
failControl:
  ArenaFree(base, size, pool);
failArena:
  EVENT3(SegAllocFail, arena, size, pool);
  return res;
}
Exemple #8
0
Res ThreadRegister(Thread *threadReturn, Arena arena)
{
    Res res;
    Thread thread;
    HANDLE procHandle;
    BOOL b;
    void *p;

    AVER(threadReturn != NULL);
    AVERT(Arena, arena);

    res = ControlAlloc(&p, arena, sizeof(ThreadStruct),
                       /* withReservoirPermit */ FALSE);
    if(res != ResOK)
        return res;
    thread = (Thread)p; /* avoid pun */

    /* Duplicate handle gives us a new handle with updated privileges.
     * .thread.handle describes the ones needed.
     */
    procHandle = GetCurrentProcess();

    b = DuplicateHandle(procHandle, GetCurrentThread(), procHandle,
                        &thread->handle,
                        THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT,
                        FALSE, 0);
    if(!b)
        return ResRESOURCE;

    thread->id = GetCurrentThreadId();

    RingInit(&thread->arenaRing);

    thread->sig = ThreadSig;
    thread->serial = arena->threadSerial;
    ++arena->threadSerial;
    thread->arena = arena;

    AVERT(Thread, thread);

    RingAppend(ArenaThreadRing(arena), &thread->arenaRing);

    *threadReturn = thread;
    return ResOK;
}
Exemple #9
0
Res BTCreate(BT *btReturn, Arena arena, Count length)
{
  Res res;
  BT bt;
  void *p;

  AVER(btReturn != NULL);
  AVERT(Arena, arena);
  AVER(length > 0);

  res = ControlAlloc(&p, arena, BTSize(length),
                     /* withReservoirPermit */ FALSE);
  if (res != ResOK)
    return res;
  bt = (BT)p;

  *btReturn = bt;
  return ResOK;
}
Exemple #10
0
static Res arenaRememberSummaryOne(Globals global, Addr base, RefSet summary)
{
  Arena arena;
  RememberedSummaryBlock block;

  AVER(summary != RefSetUNIV);

  arena = GlobalsArena(global);

  if(global->rememberedSummaryIndex == 0) {
    void *p;
    RememberedSummaryBlock newBlock;
    int res;

    res = ControlAlloc(&p, arena, sizeof *newBlock);
    if(res != ResOK) {
      return res;
    }
    newBlock = p;
    rememberedSummaryBlockInit(newBlock);
    RingAppend(GlobalsRememberedSummaryRing(global),
      &newBlock->globalRing);
  }
  block = RING_ELT(RememberedSummaryBlock, globalRing,
    RingPrev(GlobalsRememberedSummaryRing(global)));
  AVER(global->rememberedSummaryIndex < RememberedSummaryBLOCK);
  AVER(block->the[global->rememberedSummaryIndex].base == (Addr)0);
  AVER(block->the[global->rememberedSummaryIndex].summary == RefSetUNIV);
  block->the[global->rememberedSummaryIndex].base = base;
  block->the[global->rememberedSummaryIndex].summary = summary;
  ++ global->rememberedSummaryIndex;
  if(global->rememberedSummaryIndex >= RememberedSummaryBLOCK) {
    AVER(global->rememberedSummaryIndex == RememberedSummaryBLOCK);
    global->rememberedSummaryIndex = 0;
  }

  return ResOK;
}
Exemple #11
0
extern int main(int argc, char *argv[])
{
  mps_arena_t mpsArena;
  Arena arena; /* the ANSI arena which we use to allocate the BT */
  FBMStateStruct state;
  void *p;
  Addr dummyBlock;
  BT allocTable;
  FreelistStruct flStruct;
  CBSStruct cbsStruct;
  Align align;

  randomize(argc, argv);
  align = (1 << rnd() % 4) * MPS_PF_ALIGN;

  NAllocateTried = NAllocateSucceeded = NDeallocateTried =
    NDeallocateSucceeded = 0;

  die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE),
      "mps_arena_create");
  arena = (Arena)mpsArena; /* avoid pun */

  die((mps_res_t)BTCreate(&allocTable, arena, ArraySize),
      "failed to create alloc table");

  /* We're not going to use this block, but I feel unhappy just */
  /* inventing addresses. */
  die((mps_res_t)ControlAlloc(&p, arena, ArraySize * align,
                              /* withReservoirPermit */ FALSE),
      "failed to allocate block");
  dummyBlock = p; /* avoid pun */

  if (verbose) {
    printf("Allocated block [%p,%p)\n", (void*)dummyBlock,
           (char *)dummyBlock + ArraySize);
  }

  die((mps_res_t)CBSInit(&cbsStruct, arena, arena, align,
                         /* fastFind */ TRUE, /* zoned */ FALSE, mps_args_none),
      "failed to initialise CBS");
  state.type = FBMTypeCBS;
  state.align = align;
  state.block = dummyBlock;
  state.allocTable = allocTable;
  state.the.cbs = &cbsStruct;
  test(&state, nCBSOperations);
  CBSFinish(&cbsStruct);

  die((mps_res_t)FreelistInit(&flStruct, align),
      "failed to initialise Freelist");
  state.type = FBMTypeFreelist;
  state.the.fl = &flStruct;
  test(&state, nFLOperations);
  FreelistFinish(&flStruct);

  mps_arena_destroy(arena);

  printf("\nNumber of allocations attempted: %ld\n", NAllocateTried);
  printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded);
  printf("Number of deallocations attempted: %ld\n", NDeallocateTried);
  printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded);
  printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
  return 0;
}
Exemple #12
0
static Res MVFFInit(Pool pool, va_list arg)
{
  Size extendBy, avgSize, align;
  Bool slotHigh, arenaHigh, firstFit;
  MVFF mvff;
  Arena arena;
  Res res;
  void *p;
  ZoneSet zones;

  AVERT(Pool, pool);

  /* .arg: class-specific additional arguments; see */
  /* <design/poolmvff/#method.init> */
  /* .arg.check: we do the same checks here and in MVFFCheck */
  /* except for arenaHigh, which is stored only in the segPref. */
  extendBy = va_arg(arg, Size);
  avgSize = va_arg(arg, Size);
  align = va_arg(arg, Size);
  slotHigh = va_arg(arg, Bool);
  arenaHigh = va_arg(arg, Bool);
  firstFit = va_arg(arg, Bool);
  AVER(extendBy > 0);           /* .arg.check */
  AVER(avgSize > 0);            /* .arg.check */
  AVER(avgSize <= extendBy);    /* .arg.check */
  AVER(BoolCheck(slotHigh));
  AVER(BoolCheck(arenaHigh));
  AVER(BoolCheck(firstFit));

  mvff = Pool2MVFF(pool);
  arena = PoolArena(pool);

  mvff->extendBy = extendBy;
  if (extendBy < ArenaAlign(arena))
    mvff->minSegSize = ArenaAlign(arena);
  else
    mvff->minSegSize = extendBy;
  mvff->avgSize = avgSize;
  pool->alignment = align;
  mvff->slotHigh = slotHigh;
  mvff->firstFit = firstFit;

  res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE);
  if (res != ResOK)
    return res;

  mvff->segPref = (SegPref)p;
  *mvff->segPref = *SegPrefDefault();
  SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL);
  /* If using zoneset placement, just put it apart from the others. */
  zones = ZoneSetComp(ArenaDefaultZONESET);
  SegPrefExpress(mvff->segPref, SegPrefZoneSet, (void *)&zones);

  mvff->total = 0;
  mvff->free = 0;

  res = CBSInit(arena, CBSOfMVFF(mvff), (void *)mvff, NULL, NULL, NULL, NULL,
                mvff->extendBy, align, TRUE, TRUE);

  if (res != ResOK)
    goto failInit;

  mvff->sig = MVFFSig;
  AVERT(MVFF, mvff);
  EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align,
                 slotHigh, arenaHigh, firstFit);
  return ResOK;

failInit:
  ControlFree(arena, p, sizeof(SegPrefStruct));
  return res;
}
Exemple #13
0
Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
              SACClasses classes)
{
  void *p;
  SAC sac;
  Res res;
  Index i, j;
  Index middleIndex;  /* index of the size in the middle */
  Size prevSize;
  unsigned totalFreq = 0;
  mps_sac_t esac;

  AVER(sacReturn != NULL);
  AVERT(Pool, pool);
  AVER(classesCount > 0);
  /* In this cache type, there is no upper limit on classesCount. */
  prevSize = sizeof(Addr) - 1; /* must large enough for freelist link */
  /* @@@@ It would be better to dynamically adjust the smallest class */
  /* to be large enough, but that gets complicated, if you have to */
  /* merge classes because of the adjustment. */
  for (i = 0; i < classesCount; ++i) {
    AVER(classes[i]._block_size > 0);
    AVER(SizeIsAligned(classes[i]._block_size, PoolAlignment(pool)));
    AVER(prevSize < classes[i]._block_size);
    prevSize = classes[i]._block_size;
    /* no restrictions on count */
    /* no restrictions on frequency */
  }

  /* Calculate frequency scale */
  for (i = 0; i < classesCount; ++i) {
    unsigned oldFreq = totalFreq;
    totalFreq += classes[i]._frequency;
    AVER(oldFreq <= totalFreq); /* check for overflow */
    UNUSED(oldFreq); /* <code/mpm.c#check.unused> */
  }

  /* Find middle one */
  totalFreq /= 2;
  for (i = 0; i < classesCount; ++i) {
    if (totalFreq < classes[i]._frequency) break;
    totalFreq -= classes[i]._frequency;
  }
  if (totalFreq <= classes[i]._frequency / 2)
    middleIndex = i;
  else
    middleIndex = i + 1; /* there must exist another class at i+1 */

  /* Allocate SAC */
  res = ControlAlloc(&p, PoolArena(pool), sacSize(middleIndex, classesCount),
                     FALSE);
  if(res != ResOK)
    goto failSACAlloc;
  sac = p;

  /* Move classes in place */
  /* It's important this matches SACFind. */
  esac = ExternalSACOfSAC(sac);
  for (j = middleIndex + 1, i = 0; j < classesCount; ++j, i += 2) {
    esac->_freelists[i]._size = classes[j]._block_size;
    esac->_freelists[i]._count = 0;
    esac->_freelists[i]._count_max = classes[j]._cached_count;
    esac->_freelists[i]._blocks = NULL;
  }
  esac->_freelists[i]._size = SizeMAX;
  esac->_freelists[i]._count = 0;
  esac->_freelists[i]._count_max = 0;
  esac->_freelists[i]._blocks = NULL;
  for (j = middleIndex, i = 1; j > 0; --j, i += 2) {
    esac->_freelists[i]._size = classes[j-1]._block_size;
    esac->_freelists[i]._count = 0;
    esac->_freelists[i]._count_max = classes[j]._cached_count;
    esac->_freelists[i]._blocks = NULL;
  }
  esac->_freelists[i]._size = 0;
  esac->_freelists[i]._count = 0;
  esac->_freelists[i]._count_max = classes[j]._cached_count;
  esac->_freelists[i]._blocks = NULL;

  /* finish init */
  esac->_trapped = FALSE;
  esac->_middle = classes[middleIndex]._block_size;
  sac->pool = pool;
  sac->classesCount = classesCount;
  sac->middleIndex = middleIndex;
  sac->sig = SACSig;
  AVERT(SAC, sac);
  *sacReturn = sac;
  return ResOK;

failSACAlloc:
  return res;
}
static void topMessageType(MessageType *typeReturn, Arena arena)
{
  cdie(MessageQueueType(typeReturn, arena), "Queue empty");
}


/* postDummyMessage -- post a dummy message */

static void postDummyMessage(Arena arena, MessageClass class,
                             MessageType type)
{
  void *p;
  Message message;

  die((mps_res_t)ControlAlloc(&p, arena, sizeof(MessageStruct), FALSE),
      "AllocMessage");
  message = (Message)p;
  MessageInit(arena, message, class, type);
  MessagePost(arena, message);
  return;
}


/* postFinalizationMessage -- post dummy finalization message */

static void postFinalizationMessage(Arena arena)
{
  postDummyMessage(arena, &DFMessageClassStruct, MessageTypeFINALIZATION);
}
Exemple #15
0
static Res MVFFInit(Pool pool, ArgList args)
{
  Size extendBy = MVFF_EXTEND_BY_DEFAULT;
  Size avgSize = MVFF_AVG_SIZE_DEFAULT;
  Size align = MVFF_ALIGN_DEFAULT;
  Bool slotHigh = MVFF_SLOT_HIGH_DEFAULT;
  Bool arenaHigh = MVFF_ARENA_HIGH_DEFAULT;
  Bool firstFit = MVFF_FIRST_FIT_DEFAULT;
  MVFF mvff;
  Arena arena;
  Res res;
  void *p;
  ArgStruct arg;

  AVERT(Pool, pool);
  arena = PoolArena(pool);

  /* .arg: class-specific additional arguments; see */
  /* <design/poolmvff/#method.init> */
  /* .arg.check: we do the same checks here and in MVFFCheck */
  /* except for arenaHigh, which is stored only in the segPref. */
  
  if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY))
    extendBy = arg.val.size;
  
  if (ArgPick(&arg, args, MPS_KEY_MEAN_SIZE))
    avgSize = arg.val.size;
  
  if (ArgPick(&arg, args, MPS_KEY_ALIGN))
    align = arg.val.align;

  if (ArgPick(&arg, args, MPS_KEY_MVFF_SLOT_HIGH))
    slotHigh = arg.val.b;
  
  if (ArgPick(&arg, args, MPS_KEY_MVFF_ARENA_HIGH))
    arenaHigh = arg.val.b;
  
  if (ArgPick(&arg, args, MPS_KEY_MVFF_FIRST_FIT))
    firstFit = arg.val.b;

  AVER(extendBy > 0);           /* .arg.check */
  AVER(avgSize > 0);            /* .arg.check */
  AVER(avgSize <= extendBy);    /* .arg.check */
  AVER(SizeIsAligned(align, MPS_PF_ALIGN));
  AVERT(Bool, slotHigh);
  AVERT(Bool, arenaHigh);
  AVERT(Bool, firstFit);

  mvff = Pool2MVFF(pool);

  mvff->extendBy = extendBy;
  if (extendBy < ArenaAlign(arena))
    mvff->minSegSize = ArenaAlign(arena);
  else
    mvff->minSegSize = extendBy;
  mvff->avgSize = avgSize;
  pool->alignment = align;
  mvff->slotHigh = slotHigh;
  mvff->firstFit = firstFit;

  res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE);
  if (res != ResOK)
    return res;

  mvff->segPref = (SegPref)p;
  SegPrefInit(mvff->segPref);
  SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL);

  mvff->total = 0;
  mvff->free = 0;

  res = FreelistInit(FreelistOfMVFF(mvff), align);
  if (res != ResOK)
    goto failInit;

  res = CBSInit(CBSOfMVFF(mvff), arena, (void *)mvff, align,
                /* fastFind */ TRUE, /* zoned */ FALSE, args);
  if (res != ResOK)
    goto failInit;

  mvff->sig = MVFFSig;
  AVERT(MVFF, mvff);
  EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align,
         BOOL(slotHigh), BOOL(arenaHigh), BOOL(firstFit));
  return ResOK;

failInit:
  ControlFree(arena, p, sizeof(SegPrefStruct));
  return res;
}
Exemple #16
0
static void shieldQueue(Arena arena, Seg seg)
{
  Shield shield;
  
  /* <design/trace/#fix.noaver> */
  AVERT_CRITICAL(Arena, arena);
  shield = ArenaShield(arena);
  SHIELD_AVERT_CRITICAL(Seg, seg);

  if (SegIsSynced(seg) || seg->queued)
    return;

  if (SegIsExposed(seg)) {
    /* This can occur if the mutator isn't suspended, we expose a
       segment, then raise the shield on it.  In this case, the
       mutator isn't allowed to see the segment, but we don't need to
       queue it until its covered. */
    shieldSuspend(arena);
    return;
  }

  /* Allocate or extend the shield queue if necessary. */
  if (shield->next >= shield->length) {
    void *p;
    Res res;
    Count length;

    AVER(shield->next == shield->length);

    if (shield->length == 0)
      length = ShieldQueueLENGTH;
    else
      length = shield->length * 2;
    
    res = ControlAlloc(&p, arena, length * sizeof shield->queue[0]);
    if (res != ResOK) {
      AVER(ResIsAllocFailure(res));
      /* Carry on with the existing queue. */
    } else {
      if (shield->length > 0) {
        Size oldSize = shield->length * sizeof shield->queue[0];
        AVER(shield->queue != NULL);
        mps_lib_memcpy(p, shield->queue, oldSize);
        ControlFree(arena, shield->queue, oldSize);
      }
      shield->queue = p;
      shield->length = length;
    }
  }

  /* Queue unavailable, so synchronize now.  Or if the mutator is not
     yet suspended and the code raises the shield on a covered
     segment, protect it now, because that's probably better than
     suspending the mutator. */
  if (shield->length == 0 || !shield->suspended) {
    shieldSync(shield, seg);
    return;
  }

  AVER_CRITICAL(shield->limit <= shield->length);
  AVER_CRITICAL(shield->next <= shield->limit);

  /* If we failed to extend the shield queue array, degrade to an LRU
     circular buffer. */
  if (shield->next >= shield->length)
    shield->next = 0;
  AVER_CRITICAL(shield->next < shield->length);

  AVER_CRITICAL(shield->length > 0);

  /* If the limit is less than the length, then the queue array has
     yet to be filled, and next is an uninitialized entry.
     Otherwise it's the tail end from last time around, and needs to
     be flushed. */
  if (shield->limit >= shield->length) {
    AVER_CRITICAL(shield->limit == shield->length);
    shieldFlushEntry(shield, shield->next);
  }

  shield->queue[shield->next] = seg;
  ++shield->next;
  seg->queued = TRUE;

  if (shield->next >= shield->limit)
    shield->limit = shield->next;
}
Exemple #17
0
extern int main(int argc, char *argv[])
{
  unsigned i;
  Addr base, limit;
  mps_arena_t mpsArena;
  Arena arena; /* the ANSI arena which we use to allocate the BT */
  CBSStruct cbsStruct;
  CBS cbs;
  void *p;
  Addr dummyBlock;
  BT allocTable;
  Size size;
  Bool high;
  CBSFindDelete findDelete = CBSFindDeleteNONE;

  randomize(argc, argv);

  NAllocateTried = NAllocateSucceeded = NDeallocateTried =
    NDeallocateSucceeded = NNewBlocks = NDeleteBlocks =
    NGrowBlocks = NShrinkBlocks = 0;

  clearExpectations();

  die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE),
      "mps_arena_create");
  arena = (Arena)mpsArena; /* avoid pun */

  die((mps_res_t)BTCreate(&allocTable, arena, ArraySize),
      "failed to create alloc table");

  die((mps_res_t)CBSInit(arena, &cbsStruct, NULL, &cbsNewCallback,
                         &cbsDeleteCallback, &cbsGrowCallback,
                         &cbsShrinkCallback, MinSize,
                         Alignment, TRUE, TRUE),
      "failed to initialise CBS");
  cbs = &cbsStruct;

  BTSetRange(allocTable, 0, ArraySize); /* Initially all allocated */

  /* We're not going to use this block, but I feel unhappy just */
  /* inventing addresses. */
  die((mps_res_t)ControlAlloc(&p, arena, ArraySize * Alignment,
                              /* withReservoirPermit */ FALSE),
      "failed to allocate block");
  dummyBlock = (Addr)p; /* avoid pun */

  printf("Allocated block [%p, %p)\n", (void*)dummyBlock,
         (char *)dummyBlock + ArraySize);

  checkCBS(cbs, allocTable, dummyBlock);
  for(i = 0; i < NOperations; i++) {
    switch(cbsRnd(3)) {
    case 0: {
      randomRange(&base, &limit, allocTable, dummyBlock);
      allocate(cbs, dummyBlock, allocTable, base, limit);
    } break;
    case 1: {
      randomRange(&base, &limit, allocTable, dummyBlock);
      deallocate(cbs, dummyBlock, allocTable, base, limit);
    } break;
    case 2: {
      size = cbsRnd(ArraySize / 10) + 1;
      high = cbsRnd(2) ? TRUE : FALSE;
      switch(cbsRnd(6)) {
      case 0:
      case 1:
      case 2: findDelete = CBSFindDeleteNONE; break;
      case 3: findDelete = CBSFindDeleteLOW; break;
      case 4: findDelete = CBSFindDeleteHIGH; break;
      case 5: findDelete = CBSFindDeleteENTIRE; break;
      }
      find(cbs, dummyBlock, allocTable, size, high, findDelete);
    } break;
    }
    if (i % 5000 == 0)
      checkCBS(cbs, allocTable, dummyBlock);
  }

  checkExpectations();

  /* CBSDescribe prints a very long line. */
  /* CBSDescribe(cbs, mps_lib_get_stdout()); */

  printf("\nNumber of allocations attempted: %ld\n", NAllocateTried);
  printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded);
  printf("Number of deallocations attempted: %ld\n", NDeallocateTried);
  printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded);
  printf("Number of new large blocks: %ld\n", NNewBlocks);
  printf("Number of deleted large blocks: %ld\n", NDeleteBlocks);
  printf("Number of grown large blocks: %ld\n", NGrowBlocks);
  printf("Number of shrunk large blocks: %ld\n", NShrinkBlocks);
  printf("\nNo problems detected.\n");
  return 0;
}