Beispiel #1
0
/* Function used to create a new graph page for adjecent lists */
Gdb_ret_t createGraphPage(Graph_t *graph){
    // this will double memory usage while it does the copying!!!
    pthread_mutex_lock(&graph_mutex);
    pthread_mutex_lock(&node_mutex);
    List_p new_block = (List_p)resizeMemory(graph->arr_list, (graph->num_vertices + MAX_PAGE_SIZE)*sizeof(List_t));
    if(!new_block){
        pthread_mutex_unlock(&graph_mutex);
        pthread_mutex_unlock(&node_mutex);
        return MEM_FULL;
    }
    graph->arr_list = new_block;
    graph->num_vertices += MAX_PAGE_SIZE; // inclrease vertex count without needing to count - keep it O(1)
    pthread_mutex_unlock(&graph_mutex);
    pthread_mutex_unlock(&node_mutex);
    return OK;
}
Beispiel #2
0
/* heap_clear():
   Set the heap state to inactive, and free the block lists. This is
   called when the game starts or restarts.
*/
void heap_clear()
{
    while (heap_head) {
        heapblock_t *blo = heap_head;
        heap_head = blo->next;
        blo->next = NULL;
        blo->prev = NULL;
        glulx_free(blo);
    }
    heap_tail = NULL;

    if (heap_start) {
        glui32 res = resizeMemory(heap_start, 1);
        if (res)
            fatalError("Unable to revert memory size when deactivating heap.");
    }

    heap_start = 0;
    alloc_count = 0;
    /* heap_sanity_check(); */
}
Beispiel #3
0
git_sint32 restoreFromFile (git_sint32 * base, git_sint32 id,
    git_uint32 protectPos, git_uint32 protectSize)
{
    git_uint32 protectEnd = protectPos + protectSize;
    git_uint32 i;
    strid_t file;
    glui32 fileSize, fileStart;

    int gotIdent = 0;
    int gotMemory = 0;
    int gotStack = 0;
    int gotHeap = 0;

    // Find out what stream they want to use, and make sure it's valid.
    file = git_find_stream_by_id (id);
    if (file == 0)
        return 1;

    // Read IFF header.
    if (readWord (file) != read32("FORM"))
        return 1; // Not an IFF file.
    
    fileSize = readWord (file);
    fileStart = glk_stream_get_position (file);
    
    if (readWord (file) != read32("IFZS"))
        return 1; // Not a Quetzal file.
    
    // Discard the current heap.
    heap_clear();
    
    // Read all the chunks.
    
    while (glk_stream_get_position(file) < fileStart + fileSize)
    {
        git_uint32 chunkType, chunkSize, chunkStart;
        chunkType = readWord (file);
        chunkSize = readWord (file);
        chunkStart = glk_stream_get_position (file);

        if (chunkType == read32("IFhd"))
        {
            if (gotIdent)
                return 1;

            gotIdent = 1;

            if (chunkSize != 128)
                return 1;

            for (i = 0 ; i < 128 ; ++i)
            {
                glui32 c = glk_get_char_stream (file);
                if (gRom [i] != c)
                    return 1;
            }
        }
        else if (chunkType == read32("Stks"))
        {
            if (gotStack)
                return 1;

            gotStack = 1;

            if (chunkSize & 3)
                return 1;

            gStackPointer = base;
            for ( ; chunkSize > 0 ; chunkSize -= 4)
                *gStackPointer++ = readWord(file);
        }
        else if (chunkType == read32("CMem"))
        {
            git_uint32 bytesRead = 0;
            if (gotMemory)
                return 1;

            gotMemory = 1;

            if (resizeMemory (readWord(file), 1))
                fatalError ("Can't resize memory map");

            bytesRead = 4;
            i = gRamStart;
            while (i < gExtStart && bytesRead < chunkSize)
            {
                int mult = 0;
                char c = (char) glk_get_char_stream(file);
                ++bytesRead;
                
                if (c == 0)
                {
                    mult = (unsigned char) glk_get_char_stream(file);
                    ++bytesRead;
                }
                
                for (++mult ; mult > 0 ; --mult, ++i)
                    if (i >= protectEnd || i < protectPos)
                        gRam [i] = gRom [i] ^ c;
            }

            while (i < gEndMem && bytesRead < chunkSize)
            {
                int mult = 0;
                char c = (char) glk_get_char_stream(file);
                ++bytesRead;
                
                if (c == 0)
                {
                    mult = (unsigned char) glk_get_char_stream(file);
                    ++bytesRead;
                }
                
                for (++mult ; mult > 0 ; --mult, ++i)
                    if (i >= protectEnd || i < protectPos)
                        gRam [i] = c;
            }

            while (i < gExtStart)
                if (i >= protectEnd || i < protectPos)
                    gRam [i] = gRom [i], ++i;

            while (i < gEndMem)
                if (i >= protectEnd || i < protectPos)
                    gRam [i] = 0, ++i;

            if (bytesRead != chunkSize)
                return 1; // Too much data!

            if (chunkSize & 1)
                glk_get_char_stream (file);
        }
        else if (chunkType == read32("MAll"))
        {
            glui32 heapSize = 0;
            glui32 * heap = 0;

            if (gotHeap)
                return 1;

            gotHeap = 1;

            if (chunkSize & 3)
                return 1;

            if (chunkSize > 0)
            {
                heap = malloc (chunkSize);
                heapSize = chunkSize / 4;
                for (i = 0 ; i < heapSize ; ++i)
                    heap[i] = readWord(file);

                /* The summary might have come from any interpreter, so it could
                  be out of order. We'll sort it. */
                qsort(heap+2, (heapSize-2)/2, 8, &sort_heap_summary);

                if (heap_apply_summary (heapSize, heap))
                    fatalError ("Couldn't apply heap summary");
                free (heap);
            }
        }
        else
        {
            // Unknown chunk type -- just skip it.
            glk_stream_set_position (file, (chunkSize + 1) & ~1, seekmode_Current);
        }
    }

    // Make sure we have all the chunks we need.

    if (!gotIdent)
        fatalError ("No ident chunk in save file");

    if (!gotStack)
        fatalError ("No stack chunk in save file");

    if (!gotMemory)
        fatalError ("No memory chunk in save file");

    // If we reach this point, we restored successfully.

    return 0;
}
Beispiel #4
0
SquareMatrix::SquareMatrix(const int size) : matrix_(NULL), size_(size)
{
    resizeMemory(size_);
}
Beispiel #5
0
SquareMatrix::SquareMatrix(const SquareMatrix & rhs) : matrix_(NULL), size_(0)
{
    resizeMemory(rhs.size_);
    std::copy(rhs.matrix_, rhs.matrix_ + (rhs.size_ * rhs.size_), matrix_);
}
Beispiel #6
0
/* heap_alloc():
   Allocate a block. If necessary, activate the heap and/or extend memory.
   Returns the memory address of the block, or 0 if the operation failed.
*/
glui32 heap_alloc(glui32 len)
{
    heapblock_t *blo, *newblo;

    if (len <= 0)
        fatalError("Heap allocation length must be positive.");

    blo = heap_head;
    while (blo) {
        if (blo->isfree && blo->len >= len)
            break;

        if (!blo->isfree) {
            blo = blo->next;
            continue;
        }

        if (!blo->next || !blo->next->isfree) {
            blo = blo->next;
            continue;
        }

        /* This is a free block, but the next block in the list is also
           free, so we "advance" by merging rather than by going to
           blo->next. */
        newblo = blo->next;
        blo->len += newblo->len;
        if (newblo->next) {
            blo->next = newblo->next;
            newblo->next->prev = blo;
        }
        else {
            blo->next = NULL;
            heap_tail = blo;
        }
        newblo->next = NULL;
        newblo->prev = NULL;
        glulx_free(newblo);
        newblo = NULL;
        continue;
    }

    if (!blo) {
        /* No free area is visible on the list. Try extending memory. How
           much? Double the heap size, or by 256 bytes, or by the memory
           length requested -- whichever is greatest. */
        glui32 res;
        glui32 extension;
        glui32 oldendmem = gEndMem;

        extension = 0;
        if (heap_start)
            extension = gEndMem - heap_start;
        if (extension < len)
            extension = len;
        if (extension < 256)
            extension = 256;
        /* And it must be rounded up to a multiple of 256. */
        extension = (extension + 0xFF) & (~(glui32)0xFF);

        res = resizeMemory(gEndMem+extension, 1);
        if (res)
            return 0;

        /* If we just started the heap, note that. */
        if (heap_start == 0)
            heap_start = oldendmem;

        if (heap_tail && heap_tail->isfree) {
            /* Append the new space to the last block. */
            blo = heap_tail;
            blo->len += extension;
        }
        else {
            /* Append the new space to the block list, as a new block. */
            newblo = glulx_malloc(sizeof(heapblock_t));
            if (!newblo)
                fatalError("Unable to allocate record for heap block.");
            newblo->addr = oldendmem;
            newblo->len = extension;
            newblo->isfree = TRUE;
            newblo->next = NULL;
            newblo->prev = NULL;

            if (!heap_tail) {
                heap_head = newblo;
                heap_tail = newblo;
            }
            else {
                blo = heap_tail;
                heap_tail = newblo;
                blo->next = newblo;
                newblo->prev = blo;
            }

            blo = newblo;
            newblo = NULL;
        }

        /* and continue forwards, using this new block (blo). */
    }

    /* Something strange happened. */
    if (!blo || !blo->isfree || blo->len < len)
        return 0;

    /* We now have a free block of size len or longer. */

    if (blo->len == len) {
        blo->isfree = FALSE;
    }
    else {
        newblo = glulx_malloc(sizeof(heapblock_t));
        if (!newblo)
            fatalError("Unable to allocate record for heap block.");
        newblo->isfree = TRUE;
        newblo->addr = blo->addr + len;
        newblo->len = blo->len - len;
        blo->len = len;
        blo->isfree = FALSE;
        newblo->next = blo->next;
        if (newblo->next)
            newblo->next->prev = newblo;
        newblo->prev = blo;
        blo->next = newblo;
        if (heap_tail == blo)
            heap_tail = newblo;
    }

    alloc_count++;
    /* heap_sanity_check(); */
    return blo->addr;
}
Beispiel #7
0
int restoreUndo (git_sint32* base, git_uint32 protectPos, git_uint32 protectSize)
{
    if (gUndo == NULL)
    {
        // Nothing to undo!
        return 1;
    }
    else
    {
        UndoRecord * undo = gUndo;

        git_uint32 addr = gRamStart;     // Address in glulx memory.
        MemoryMap map = undo->memoryMap; // Glulx memory map.

        // Restore the size of the memory map
        heap_clear ();
        resizeMemory (undo->endMem, 1);

        // Restore the stack.
        memcpy (base, undo->stack, undo->stackSize);
        gStackPointer = base + (undo->stackSize / sizeof(git_sint32));

        // Restore the contents of RAM.

        if (protectSize > 0 && protectPos < gEndMem)
        {
            for ( ; addr < (protectPos & ~0xff) ; addr += 256, ++map)
                memcpy (gMem + addr, *map, 256);
            
            memcpy (gMem + addr, *map, protectPos & 0xff);
            protectSize += protectPos & 0xff;
            
            while (protectSize > 256)
                addr += 256, ++map, protectSize -= 256;

            if (addr < gEndMem)
            {
                memcpy (gMem + addr + protectSize,
                        *map + protectSize,
                        256 - protectSize);
            }
            addr += 256, ++map;
        }

        for ( ; addr < gEndMem ; addr += 256, ++map)
            memcpy (gMem + addr, *map, 256);

        // Restore the heap.
        if (heap_apply_summary (undo->heapSize, undo->heap))
            fatalError ("Couldn't apply heap summary");

        // Delete the undo record.

        gUndo = undo->prev;
        deleteRecord (undo);

        if (gUndo)
            gUndo->next = NULL;
        else
            assert (gUndoSize == 0);

        // And we're done.
        return 0;
    }
}