Esempio n. 1
0
void mmFree(void* mem)
{
    Block b = {{-1, -1, -1, -1}};
    size_t offset = (size_t) (mem - megMap); //total offset in memory area
    for(int i = 0; i < LEVELS; i++)
    {
        b.levels[i] = (offset - subblockStart[i]) / blockSize[i];
        if(b.levels[i] * blockSize[i] + subblockStart[i] == offset)
            break;
        offset -= (b.levels[i] * blockSize[i] + subblockStart[i]);
    }
    //b is the first block of group
    bool haveParent = false;
    Block parent;
    if(getBlockLevel(b) != 0)
    {
        haveParent = true;
        parent = getParentBlock(b);
    }
    while(getBlockStatus(b) != MID_END)
    {
        setBlockStatus(b, FREE);
        b = getNextBlock(b);
    }
    setBlockStatus(b, FREE);
    if(haveParent)
    {
        //check if parent can also be freed
        if(getMaxGroup(parent) == numSubblocks[getBlockLevel(parent)])
        {
            setBlockStatus(parent, FREE);
        }
    }
}
Esempio n. 2
0
//preconditions: b is a valid block, b can be subdivided (level < LEVELS - 1)
static Block getFirstSubblock(Block b)
{
    Block sub = b;
    int level = getBlockLevel(b);
    sub.levels[level + 1] = 0;
    return sub;
}
Esempio n. 3
0
static Block getNthSubblock(Block parent, int index)
{
    Block sub = getFirstSubblock(parent);
    int level = getBlockLevel(sub);
    sub.levels[level] = index;
    return sub;
}
Esempio n. 4
0
//Precondition: newParent is not LEVELS-1 (can be subdivided)
static void allocForSub(Block newParent)
{
    int parLevel = getBlockLevel(newParent);
    //Mark newParent in its bitmap
    setBlockStatus(newParent, SUBDIV);
    for(int i = 0; i < numSubblocks[parLevel + 1]; i++)
    {
        Block sub = getNthSubblock(newParent, i);
        setBlockStatus(sub, FREE);
    }
}
Esempio n. 5
0
//Get the memory location referenced by block
//Return NULL for invalid block descriptor
static void* getBlockPtr(Block b)
{
    void* ptr = (void*) megMap;
    if(!validBlock(b))
        return NULL;
    int level = getBlockLevel(b);
    for(int i = 0; i <= level; i++)
    {
        //For each level, add the offset for table as well as the memory for
        //blocks before this one
        ptr += subblockStart[i];
        ptr += b.levels[i] * blockSize[i];
    }
    return ptr;
}
Esempio n. 6
0
static void setBlockStatus(Block b, int code)
{
    int level = getBlockLevel(b);
    byte* table; //start of table for parent blocks, or top-level block.
    byte mask = 0b11;
    if(level == 0)
        table = (byte*) megMap;
    else
        table = (byte*) getBlockPtr(getParentBlock(b));
    int baseIndex = b.levels[level];
    byte* entry = table + (baseIndex / 4); //2 bits per entry
    int shift = 6 - (2 * (baseIndex % 4));  //trust me it works
    byte newVal = *entry & ~(mask << shift);
    newVal |= (code << shift);
    *entry = newVal;
}
Esempio n. 7
0
/* return命令の生成 */
int genCodeReturn(void)
{
  /* 直前の命令がreturnならば, 連続returnになるので
   * すぐに終わる
   * FIXME:最後が関数定義だとあかん */
  if (code[current_code_size].opcode == LVM_RETURN) 
    return current_code_size;

  /* コードサイズを確認してから命令生成 */
  /* オペランドのブロックレベルやパラメタ数は, table.hからの情報を使う */
  checkCodeSize();
  code[current_code_size].opcode = LVM_RETURN;
  code[current_code_size].u.address.block_level = getBlockLevel();
  code[current_code_size].u.address.address     = getCurrentNumParams();
  return current_code_size;
}
Esempio n. 8
0
static int getMaxGroup(Block b)
{
    int bestNum = 0;
    int num = 0;
    for(int i = 0; i < numSubblocks[getBlockLevel(b)]; i++)
    {
        if(getBlockStatus(b) == FREE)
            num++;
        else
        {
            if(num > bestNum)
                bestNum = num;
            num = 0;
        }
    }
    return bestNum;
}
Esempio n. 9
0
//Find best contiguous group of subblocks that can hold numBlocks
//Preconditions: parent is already allocated for 
static bool findGroupInBlock(Block parent, int numBlocks, Block* result, int* overshoot)
{
    //printf("Searching for group of free blocks in ");
    //printBlock(parent);
    //puts("");
    if(getBlockStatus(parent) != SUBDIV)
    {
        //puts("FATAL: parent is not subdivided!");
        return false;
    }
    int parentLevel = getBlockLevel(parent);
    if(parentLevel == LEVELS - 1)
    {
        //printf("FATAL ERROR: findGroupInBlock: parent level is level 3!");
        return false;
    }
    int numSub = numSubblocks[parentLevel];
    int bestStart = -1;
    int bestSize = numSub + 1;
    Block iter = getNthSubblock(parent, 0);
    int lvl = parentLevel + 1;
    while(iter.levels[lvl] < numSub)
    {
        //scan to next free block
        while(getBlockStatus(iter) != FREE && iter.levels[lvl] < numSub)
            iter.levels[lvl]++;
        //start counting the run
        int runStart = iter.levels[lvl];
        //scan to end of run
        while(getBlockStatus(iter) == FREE && iter.levels[lvl] < numSub)
            iter.levels[lvl]++;
        //save the run as best if it fits numBlocks and is smaller than last best
        int runSize = iter.levels[lvl] - runStart;
        if(runSize < bestSize && runSize >= numBlocks)
        {
            bestStart = runStart;
            bestSize = runSize;
        }
    }
    if(bestStart == -1)
        return false;
    *result = getNthSubblock(parent, bestStart);
    if(overshoot)
        *overshoot = bestSize - numBlocks;
    return true;
}
Esempio n. 10
0
static void allocGroup(Block first, int num)
{
    if(num == 1)
    {
        setBlockStatus(first, MID_END);
        return;
    }
    else
    {
        int* increment = &first.levels[getBlockLevel(first)];
        setBlockStatus(first, BEGIN);
        for(int i = 0; i < num - 1; i++)
        {
            (*increment)++;
            setBlockStatus(first, MID_END);
        }
    }
}
Esempio n. 11
0
//Return a BlockStatus value or -1 on error
static int getBlockStatus(Block b)
{
    if(!validBlock(b))
        return -1;
    int level = getBlockLevel(b);
    byte* table; //start of table for parent blocks, or top-level block.
    byte mask = 0b11;
    int shift;
    //set table to address of block status bitmap of parent
    if(level == 0)
        table = (byte*) megMap;
    else
        table = (byte*) getBlockPtr(getParentBlock(b));
    int baseIndex = b.levels[level];
    byte entry = *(table + (baseIndex / 4)); //2 bits per entry
    shift = 6 - (2 * (baseIndex % 4));  //trust me it works
    return (entry & (mask << shift)) >> shift;
}
Esempio n. 12
0
static bool groupSearch(int level, int numBlocks, Block parentBlock, Block* result)
{
    int parLevel = getBlockLevel(parentBlock);
    if(parLevel == level - 1)
    {
        if(findGroupInBlock(parentBlock, numBlocks, result, NULL))
            return true;
    }
    for(int i = 0; i < numSubblocks[parLevel]; i++)
    {
        Block sub = getNthSubblock(parentBlock, i);
        if(getBlockStatus(sub) == SUBDIV)
        {
            if(groupSearch(level, numBlocks, sub, result))
                return true;
        }
    }
    return false;
}
Esempio n. 13
0
//Return next block on the same level
static Block getNextBlock(Block b)
{
    int level = getBlockLevel(b);
    b.levels[level]++;
    return b;
}
Esempio n. 14
0
static Block getParentBlock(Block b)
{
    int level = getBlockLevel(b);
    b.levels[level] = -1;
    return b;
}