Esempio n. 1
0
/* If the segment is out of sync, either sync it, or ensure
 * depth > 0, and the arena is suspended.
 */
static void cache(Arena arena, Seg seg)
{
    /* <design/trace/#fix.noaver> */
    AVERT_CRITICAL(Arena, arena);
    AVERT_CRITICAL(Seg, seg);

    if (SegSM(seg) == SegPM(seg)) return;
    if (SegDepth(seg) > 0) {
        ShieldSuspend(arena);
        return;
    }
    if (ShieldCacheSIZE == 0 || !arena->suspended)
        shieldSync(arena, seg);
    else {
        SegSetDepth(seg, SegDepth(seg) + 1);
        ++arena->shDepth;
        AVER(arena->shDepth > 0);
        AVER(SegDepth(seg) > 0);
        AVER(arena->shCacheLimit <= ShieldCacheSIZE);
        AVER(arena->shCacheI < arena->shCacheLimit);
        flush(arena, arena->shCacheI);
        arena->shCache[arena->shCacheI] = seg;
        ++arena->shCacheI;
        if (arena->shCacheI == ShieldCacheSIZE)
            arena->shCacheI = 0;
        if (arena->shCacheI == arena->shCacheLimit)
            ++arena->shCacheLimit;
    }
}
Esempio n. 2
0
static Tree SplayZig(Tree middle, Tree *rightFirstIO, Tree *rightNextReturn)
{
  AVERT_CRITICAL(Tree, middle);
  AVER_CRITICAL(rightFirstIO != NULL);
  AVERT_CRITICAL(Tree, *rightFirstIO);
  TreeSetLeft(*rightFirstIO, middle);
  *rightNextReturn = *rightFirstIO;
  *rightFirstIO = middle;
  return TreeLeft(middle);
}
Esempio n. 3
0
static Tree SplayZag(Tree middle, Tree *leftLastIO, Tree *leftPrevReturn)
{
  AVERT_CRITICAL(Tree, middle);
  AVER_CRITICAL(leftLastIO != NULL);
  AVERT_CRITICAL(Tree, *leftLastIO);
  TreeSetRight(*leftLastIO, middle);
  *leftPrevReturn = *leftLastIO;
  *leftLastIO = middle;
  return TreeRight(middle);
}
Esempio n. 4
0
static Tree SplayZigRev(Tree middle, Tree *rightFirstIO)
{
  Tree child;
  AVERT_CRITICAL(Tree, middle);
  AVER_CRITICAL(rightFirstIO != NULL);
  AVERT_CRITICAL(Tree, *rightFirstIO);
  child = TreeLeft(middle);
  TreeSetLeft(middle, *rightFirstIO);
  *rightFirstIO = middle;
  return child;
}
Esempio n. 5
0
static Tree SplayZagRev(Tree middle, Tree *leftLastIO)
{
  Tree child;
  AVERT_CRITICAL(Tree, middle);
  AVER_CRITICAL(leftLastIO != NULL);
  AVERT_CRITICAL(Tree, *leftLastIO);
  child = TreeRight(middle);
  TreeSetRight(middle, *leftLastIO);
  *leftLastIO = middle;
  return child;
}
Esempio n. 6
0
/* This ensures actual prot mode does not include mode */
static void protLower(Arena arena, Seg seg, AccessSet mode)
{
    /* <design/trace/#fix.noaver> */
    AVERT_CRITICAL(Arena, arena);
    UNUSED(arena);
    AVERT_CRITICAL(Seg, seg);

    if (SegPM(seg) & mode) {
        SegSetPM(seg, SegPM(seg) & ~mode);
        ProtSet(SegBase(seg), SegLimit(seg), SegPM(seg));
    }
}
Esempio n. 7
0
File: pool.c Progetto: bhanug/mps
Res PoolFix(Pool pool, ScanState ss, Seg seg, Addr *refIO)
{
  AVERT_CRITICAL(Pool, pool);
  AVERT_CRITICAL(ScanState, ss);
  AVERT_CRITICAL(Seg, seg);
  AVER_CRITICAL(pool == SegPool(seg));
  AVER_CRITICAL(refIO != NULL);

  /* Should only be fixing references to white segments. */
  AVER_CRITICAL(TraceSetInter(SegWhite(seg), ss->traces) != TraceSetEMPTY);

  return pool->fix(pool, ss, seg, refIO);
}
Esempio n. 8
0
static Tree SplayUpdateRightSpine(SplayTree splay, Tree node, Tree child)
{
  AVERT_CRITICAL(SplayTree, splay);
  AVERT_CRITICAL(Tree, node);
  AVERT_CRITICAL(Tree, child);
  while (node != TreeEMPTY) {
    Tree parent = TreeRight(node);
    TreeSetRight(node, child); /* un-reverse pointer */
    splay->updateNode(splay, node);
    child = node;
    node = parent;
  }
  return child;
}
Esempio n. 9
0
void (ShieldCover)(Arena arena, Seg seg)
{
    /* <design/trace/#fix.noaver> */
    AVERT_CRITICAL(Arena, arena);
    AVERT_CRITICAL(Seg, seg);
    AVER_CRITICAL(SegPM(seg) == AccessSetEMPTY);

    AVER_CRITICAL(arena->shDepth > 0);
    AVER_CRITICAL(SegDepth(seg) > 0);
    SegSetDepth(seg, SegDepth(seg) - 1);
    --arena->shDepth;

    /* ensure inv.unsynced.depth */
    cache(arena, seg);
}
Esempio n. 10
0
File: pool.c Progetto: bhanug/mps
void PoolReclaim(Pool pool, Trace trace, Seg seg)
{
  AVERT_CRITICAL(Pool, pool);
  AVERT_CRITICAL(Trace, trace);
  AVERT_CRITICAL(Seg, seg);
  AVER_CRITICAL(pool->arena == trace->arena);
  AVER_CRITICAL(SegPool(seg) == pool);

  /* There shouldn't be any grey things left for this trace. */
  AVER_CRITICAL(!TraceSetIsMember(SegGrey(seg), trace));
  /* Should only be reclaiming segments which are still white. */
  AVER_CRITICAL(TraceSetIsMember(SegWhite(seg), trace));

  Method(Pool, pool, reclaim)(pool, trace, seg);
}
Esempio n. 11
0
static Compare SplayFindLastCompare(Tree node, TreeKey key)
{
  SplayFindClosure my;
  SplayTestNodeFunction testNode;
  SplayTestTreeFunction testTree;
  void *testClosure;
  SplayTree splay;

  AVERT_CRITICAL(Tree, node);
  AVER_CRITICAL(key != NULL);

  /* Lift closure values into variables so that they aren't aliased by
     calls to the test functions. */
  my = (SplayFindClosure)key;
  testClosure = my->testClosure;
  testNode = my->testNode;
  testTree = my->testTree;
  splay = my->splay;

  if (TreeHasRight(node) &&
      (*testTree)(splay, TreeRight(node), testClosure)) {
    return CompareGREATER;
  } else if ((*testNode)(splay, node, testClosure)) {
    my->found = TRUE;
    return CompareEQUAL;
  } else {
    /* See SplayFindFirstCompare. */
    if (TreeHasLeft(node) &&
        !(*testTree)(splay, TreeLeft(node), testClosure)) {
      my->found = FALSE;
      return CompareEQUAL;
    }
    return CompareLESS;
  }
}
Esempio n. 12
0
Bool TractOfAddr(Tract *tractReturn, Arena arena, Addr addr)
{
  Bool b;
  Index i;
  Chunk chunk;
 
  /* <design/trace/#fix.noaver> */
  AVER_CRITICAL(tractReturn != NULL); /* .tract.critical */
  AVERT_CRITICAL(Arena, arena);

  b = ChunkOfAddr(&chunk, arena, addr);
  if (!b)
    return FALSE;
  /* <design/trace/#fix.tractofaddr> */
  i = INDEX_OF_ADDR(chunk, addr);
  /* .addr.free: If the page is recorded as being free then */
  /* either the page is free or it is */
  /* part of the arena tables (see .ullagepages). */
  if (BTGet(chunk->allocTable, i)) {
    *tractReturn = PageTract(ChunkPage(chunk, i));
    return TRUE;
  }

  return FALSE;
}
Esempio n. 13
0
Compare TreeFind(Tree *treeReturn, Tree root, TreeKey key, TreeCompare compare)
{
  Tree node, parent;
  Compare cmp = CompareEQUAL;
  
  AVERT_CRITICAL(Tree, root);
  AVER_CRITICAL(treeReturn != NULL);
  AVER_CRITICAL(FUNCHECK(compare));
  /* key is arbitrary */

  parent = NULL;
  node = root;
  while (node != TreeEMPTY) {
    parent = node;
    cmp = compare(node, key);
    switch (cmp) {
    case CompareLESS:
      node = node->left;
      break;
    case CompareEQUAL:
      *treeReturn = node;
      return cmp;
    case CompareGREATER:
      node = node->right;
      break;
    default:
      NOTREACHED;
      *treeReturn = NULL;
      return cmp;
    }
  }
  
  *treeReturn = parent;
  return cmp;
}
Esempio n. 14
0
Bool SplayFindFirst(Tree *nodeReturn, SplayTree splay,
                    SplayTestNodeFunction testNode,
                    SplayTestTreeFunction testTree,
                    void *testClosure)
{
  SplayFindClosureStruct closureStruct;
  Bool found;

  AVER_CRITICAL(nodeReturn != NULL);
  AVERT_CRITICAL(SplayTree, splay);
  AVER_CRITICAL(FUNCHECK(testNode));
  AVER_CRITICAL(FUNCHECK(testTree));

  if (SplayTreeIsEmpty(splay) ||
      !testTree(splay, SplayTreeRoot(splay), testClosure))
    return FALSE; /* no suitable nodes in tree */

  closureStruct.testClosure = testClosure;
  closureStruct.testNode = testNode;
  closureStruct.testTree = testTree;
  closureStruct.splay = splay;
  closureStruct.found = FALSE;

  found = SplaySplay(splay, &closureStruct,
                     SplayFindFirstCompare) == CompareEQUAL &&
          closureStruct.found;

  while (!found) {
    Tree oldRoot, newRoot;
    
    /* FIXME: Rename to "seen" and "not yet seen" or something. */
    oldRoot = SplayTreeRoot(splay);
    newRoot = TreeRight(oldRoot);

    if (newRoot == TreeEMPTY || !(*testTree)(splay, newRoot, testClosure))
      return FALSE; /* no suitable nodes in the rest of the tree */
  
    /* Temporarily chop off the left half-tree, inclusive of root,
       so that the search excludes any nodes we've seen already. */
    SplayTreeSetRoot(splay, newRoot);
    TreeSetRight(oldRoot, TreeEMPTY);

    found = SplaySplay(splay, &closureStruct,
                       SplayFindFirstCompare) == CompareEQUAL &&
            closureStruct.found;

    /* Restore the left tree, then rotate left so that the node we
       just splayed is at the root.  Update both. */
    newRoot = SplayTreeRoot(splay);
    TreeSetRight(oldRoot, newRoot);
    SplayTreeSetRoot(splay, oldRoot);
    TreeRotateLeft(&splay->root);
    splay->updateNode(splay, oldRoot);
    splay->updateNode(splay, newRoot);
  }

  *nodeReturn = SplayTreeRoot(splay);
  return TRUE;
}
Esempio n. 15
0
Addr (TractBase)(Tract tract)
{
  Addr base;
  AVERT_CRITICAL(Tract, tract); /* .tract.critical */

  base = tract->base;
  return base;
}
Esempio n. 16
0
File: pool.c Progetto: bhanug/mps
Res PoolFixEmergency(Pool pool, ScanState ss, Seg seg, Addr *refIO)
{
  Res res;

  AVERT_CRITICAL(Pool, pool);
  AVERT_CRITICAL(ScanState, ss);
  AVERT_CRITICAL(Seg, seg);
  AVER_CRITICAL(pool == SegPool(seg));
  AVER_CRITICAL(refIO != NULL);

  /* Should only be fixing references to white segments. */
  AVER_CRITICAL(TraceSetInter(SegWhite(seg), ss->traces) != TraceSetEMPTY);

  res = Method(Pool, pool, fixEmergency)(pool, ss, seg, refIO);
  AVER_CRITICAL(res == ResOK);
  return res;
}
Esempio n. 17
0
static Tree SplayUpdateLeftSpine(SplayTree splay, Tree node, Tree child)
{
  SplayUpdateNodeFunction updateNode;

  AVERT_CRITICAL(SplayTree, splay);
  AVERT_CRITICAL(Tree, node);
  AVERT_CRITICAL(Tree, child);

  updateNode = splay->updateNode;
  while(node != TreeEMPTY) {
    Tree parent = TreeLeft(node);
    TreeSetLeft(node, child); /* un-reverse pointer */
    updateNode(splay, node);
    child = node;
    node = parent;
  }
  return child;
}
Esempio n. 18
0
File: shield.c Progetto: bhanug/mps
void (ShieldCover)(Arena arena, Seg seg)
{
  Shield shield;
  
  /* <design/trace/#fix.noaver> */
  AVERT_CRITICAL(Arena, arena);
  shield = ArenaShield(arena);
  AVERT_CRITICAL(Seg, seg);
  AVER_CRITICAL(SegPM(seg) == AccessSetEMPTY);
 
  AVER_CRITICAL(SegDepth(seg) > 0);
  SegSetDepth(seg, SegDepth(seg) - 1);
  AVER_CRITICAL(shield->depth > 0);
  --shield->depth;

  /* Ensure design.mps.shield.inv.unsynced.depth. */
  shieldQueue(arena, seg);
}
Esempio n. 19
0
void PageAlloc(Chunk chunk, Index pi, Pool pool)
{
  Tract tract;
  Addr base;
  Page page;

  AVERT_CRITICAL(Chunk, chunk);
  AVER_CRITICAL(pi >= chunk->allocBase);
  AVER_CRITICAL(pi < chunk->pages);
  AVER_CRITICAL(!BTGet(chunk->allocTable, pi));
  AVERT_CRITICAL(Pool, pool);

  page = ChunkPage(chunk, pi);
  tract = PageTract(page);
  base = PageIndexBase(chunk, pi);
  BTSet(chunk->allocTable, pi);
  TractInit(tract, pool, base);
}
Esempio n. 20
0
File: shield.c Progetto: bhanug/mps
static void shieldProtLower(Shield shield, Seg seg, AccessSet mode)
{
  /* <design/trace/#fix.noaver> */
  SHIELD_AVERT_CRITICAL(Seg, seg);
  AVERT_CRITICAL(AccessSet, mode);

  if (BS_INTER(SegPM(seg), mode) != AccessSetEMPTY) {
    shieldSetPM(shield, seg, BS_DIFF(SegPM(seg), mode));
    ProtSet(SegBase(seg), SegLimit(seg), SegPM(seg));
  }
}
Esempio n. 21
0
Bool SplayTreeNeighbours(Tree *leftReturn, Tree *rightReturn,
                         SplayTree splay, TreeKey key)
{
  SplayStateStruct stateStruct;
  Bool found;
  Compare cmp;
#ifdef SPLAY_DEBUG
  Count count = SplayDebugCount(splay);
#endif

  AVERT_CRITICAL(SplayTree, splay);
  AVER_CRITICAL(leftReturn != NULL);
  AVER_CRITICAL(rightReturn != NULL);

  if (SplayTreeIsEmpty(splay)) {
    *leftReturn = *rightReturn = TreeEMPTY;
    return TRUE;
  }

  cmp = SplaySplit(&stateStruct, splay, key, splay->compare);

  switch (cmp) {
  default:
    NOTREACHED;
    /* fall through */
  case CompareEQUAL:
    found = FALSE;
    break;

  case CompareLESS:
    AVER_CRITICAL(!TreeHasLeft(stateStruct.middle));
    *rightReturn = stateStruct.middle;
    *leftReturn = stateStruct.leftLast;
    found = TRUE;
    break;

  case CompareGREATER:
    AVER_CRITICAL(!TreeHasRight(stateStruct.middle));
    *leftReturn = stateStruct.middle;
    *rightReturn = stateStruct.rightFirst;
    found = TRUE;
    break;
  }

  SplayAssemble(splay, &stateStruct);
  SplayTreeSetRoot(splay, stateStruct.middle);

#ifdef SPLAY_DEBUG
  AVER(count == SplayDebugCount(splay));
#endif

  return found;
}
Esempio n. 22
0
Compare ChunkCompare(Tree tree, TreeKey key)
{
  Addr base1, base2, limit2;
  Chunk chunk;

  AVERT_CRITICAL(Tree, tree);
  AVER_CRITICAL(tree != TreeEMPTY);

  /* See .chunk.at.base. */
  chunk = ChunkOfTree(tree);
  AVERT_CRITICAL(Chunk, chunk);

  base1 = AddrOfTreeKey(key);
  base2 = chunk->base;
  limit2 = chunk->limit;

  if (base1 < base2)
    return CompareLESS;
  else if (base1 >= limit2)
    return CompareGREATER;
  else
    return CompareEQUAL;
}
Esempio n. 23
0
void TractInit(Tract tract, Pool pool, Addr base)
{
  AVER_CRITICAL(tract != NULL);
  AVERT_CRITICAL(Pool, pool);

  tract->pool.pool = pool;
  tract->base = base;
  tract->p = NULL;
  tract->white = TraceSetEMPTY;
  tract->hasSeg = FALSE;

  AVERT(Tract, tract);

}
Esempio n. 24
0
void PageInit(Chunk chunk, Index pi)
{
  Page page;

  AVERT_CRITICAL(Chunk, chunk);
  AVER_CRITICAL(pi < chunk->pages);

  page = ChunkPage(chunk, pi);

  BTRes(chunk->allocTable, pi);
  PageSetPool(page, NULL);
  PageSetType(page, PageStateFREE);
  RingInit(PageSpareRing(page));
}
Esempio n. 25
0
Bool BTIsResRange(BT bt, Index base, Index limit)
{
  AVERT_CRITICAL(BT, bt);   /* See .aver.critical */
  AVER_CRITICAL(base < limit);
  /* Can't check range of base or limit */

#define SINGLE_IS_RES_RANGE(i) \
  if (BTGet(bt, (i))) return FALSE
#define BITS_IS_RES_RANGE(i,base,limit) \
  if ((bt[(i)] & BTMask((base),(limit))) != (Word)0) return FALSE
#define WORD_IS_RES_RANGE(i) \
  if (bt[(i)] != (Word)0) return FALSE

  ACT_ON_RANGE(base, limit, SINGLE_IS_RES_RANGE,
               BITS_IS_RES_RANGE, WORD_IS_RES_RANGE);
  return TRUE;
}
Esempio n. 26
0
static void SplayAssembleRev(SplayTree splay, SplayState state)
{
  Tree left, right;

  AVERT_CRITICAL(SplayTree, splay);
  AVER_CRITICAL(state->middle != TreeEMPTY);
  
  left = TreeLeft(state->middle);
  left = SplayUpdateRightSpine(splay, state->leftLast, left);
  TreeSetLeft(state->middle, left);

  right = TreeRight(state->middle);
  right = SplayUpdateLeftSpine(splay, state->rightFirst, right);
  TreeSetRight(state->middle, right);

  splay->updateNode(splay, state->middle);
}
Esempio n. 27
0
void (ShieldExpose)(Arena arena, Seg seg)
{
    AccessSet mode = AccessREAD | AccessWRITE;
    /* <design/trace/#fix.noaver> */
    AVERT_CRITICAL(Arena, arena);
    AVER_CRITICAL(arena->insideShield);

    SegSetDepth(seg, SegDepth(seg) + 1);
    ++arena->shDepth;
    /* <design/trace/#fix.noaver> */
    AVER_CRITICAL(arena->shDepth > 0);
    AVER_CRITICAL(SegDepth(seg) > 0);
    if (SegPM(seg) & mode)
        ShieldSuspend(arena);

    /* This ensures inv.expose.prot */
    protLower(arena, seg, mode);
}
Esempio n. 28
0
Tract TractOfBaseAddr(Arena arena, Addr addr)
{
  Tract tract = NULL;
  Bool found;

  AVERT_CRITICAL(Arena, arena);
  AVER_CRITICAL(AddrIsAligned(addr, ArenaGrainSize(arena)));

  /* Check first in the cache, see <design/arena/#tract.cache>. */
  if (arena->lastTractBase == addr) {
    tract = arena->lastTract;
  } else {
    found = TractOfAddr(&tract, arena, addr);
    AVER_CRITICAL(found);
  }

  AVER_CRITICAL(TractBase(tract) == addr);
  return tract;
}
Esempio n. 29
0
Bool ChunkOfAddr(Chunk *chunkReturn, Arena arena, Addr addr)
{
  Tree tree;

  AVER_CRITICAL(chunkReturn != NULL);
  AVERT_CRITICAL(Arena, arena);
  /* addr is arbitrary */

  if (TreeFind(&tree, ArenaChunkTree(arena), TreeKeyOfAddrVar(addr),
               ChunkCompare)
      == CompareEQUAL)
  {
    Chunk chunk = ChunkOfTree(tree);
    AVER_CRITICAL(chunk->base <= addr);
    AVER_CRITICAL(addr < chunk->limit);
    *chunkReturn = chunk;
    return TRUE;
  }
  return FALSE;
}
Esempio n. 30
0
static Compare SplayFindFirstCompare(Tree node, TreeKey key)
{
  SplayFindClosure my;
  SplayTestNodeFunction testNode;
  SplayTestTreeFunction testTree;
  void *testClosure;
  SplayTree splay;

  AVERT_CRITICAL(Tree, node);
  AVER_CRITICAL(key != NULL);

  /* Lift closure values into variables so that they aren't aliased by
     calls to the test functions. */
  my = (SplayFindClosure)key;
  testClosure = my->testClosure;
  testNode = my->testNode;
  testTree = my->testTree;
  splay = my->splay;
  
  if (TreeHasLeft(node) &&
      (*testTree)(splay, TreeLeft(node), testClosure)) {
    return CompareLESS;
  } else if ((*testNode)(splay, node, testClosure)) {
    my->found = TRUE;
    return CompareEQUAL;
  } else {
    /* If there's a right subtree but it doesn't satisfy the tree test
       then we want to terminate the splay right now.  SplaySplay will
       return TRUE, so the caller must check closure->found to find out
       whether the result node actually satisfies testNode. */
    if (TreeHasRight(node) &&
        !(*testTree)(splay, TreeRight(node), testClosure)) {
      my->found = FALSE;
      return CompareEQUAL;
    }
    return CompareGREATER;
  }
}