コード例 #1
0
ファイル: MemHeap.cpp プロジェクト: nimadini/EPL
/*
 * Check the chunk to see if it's bigger than it needs to be
 * split the chunk in two if it's larger than size
 * be sure that the "excess" (i.e., the new chunk) is at the
 * top of the current chunk.  i.e., the new signature
 * written at memory_pool['chunk'] must be at least 'size'
 */
void splitChunkIfNecessary(unsigned chunk, int size) {
    if (memory_pool[chunk] > size + min_chunk_size) {
        /* need to split... */
        int left_over_sig = memory_pool[chunk] - size - 2;
        // left_over_sig is the signature for the excess chunk
        unsigned left_over_chunk = chunk + size + 2;
        // left_over_chunk is the index of the new chunk we'll create

        setBothSignatures(chunk, size);
        setBothSignatures(left_over_chunk, left_over_sig);
    }

    /* that's it.  If the chunk's too small, there's nothing to do
     * so we don't need an else or nothin */
}
コード例 #2
0
ファイル: MemHeap.cpp プロジェクト: tabchas/ee312
void deallocateMemory(void *p)
{
    /* since the available memory is one position above the signature
     * the signature can be found at one position below the first
     * byte of available memory
     */
    int *chunk_address = ((int *)p) - 1;
    unsigned chunk;
    int top_signature;
    int bottom_signature;
    int size;

    if ((chunk_address < memory_pool)
        || (chunk_address >= &memory_pool[pool_size]))
    {
        /* due to silliness in the MetroWerks compiler, it is possible
         * for new to be called before the memory heap is on-line.  In that
         * case the system default heap is used, and not this one.
         * this generally only happens for global constructors, such as
         * the stuff associated with cout and cin.
         * When these objects are destroyed (after main ends) the
         * runtime system calls delete on all these things but
         * since our heap is now online, we get all the other heap's memory
         * back.  We're just going to ignore it.  The OS will clean up
         * that memory anyway when the application quits, so its
         * no big deal.
         */

        /* if you want to see this in action, de-comment the following line */
        // cout << "hey! that ain't mine, don't throw that junk at me\n";
        return;
    }
    chunk = chunk_address - memory_pool;

    bottom_signature = memory_pool[chunk];
    top_signature = memory_pool[topSignature(chunk)];

    /* another sanity check, not really insane at all. */
    assert(bottom_signature == top_signature
           && bottom_signature < 0);

    size = -bottom_signature;
    setBothSignatures(chunk, size);

    mergeChunkIfOK(chunk);

    if (chunk > 0)
    { // this is not quite silly, chunk could be equal to zero
        unsigned previous_chunk = predecessorChunk(chunk);
        mergeChunkIfOK(previous_chunk);
    }

    if (mem_leak_check && isEmptyHeap())
    {
        std::cout << "Yay, you do not have a memory leak!" << std::endl;
    }
}
コード例 #3
0
ファイル: MemHeap.cpp プロジェクト: nimadini/EPL
/*
 * check to see if the following chunk is available, if it is
 * then merge this chunk with the following chunk
 */
void mergeChunkIfOK(unsigned chunk) {
    unsigned next_chunk;
    int next_chunk_size;
    int size = memory_pool[chunk];

    if (size < 0) { return; } // not OK, this one is busy!
    next_chunk = successorChunk(chunk);
    if (next_chunk >= pool_size) { // No good, there is no successor!
        return; // give up now
    }

    next_chunk_size = memory_pool[next_chunk];

    if (next_chunk_size > 0) { // it's available!
        int new_size = size + next_chunk_size + 2;
        setBothSignatures(chunk, new_size);
    }
    /* that's it. we can leave the old signatures in the middle
     * after all, we'll never see them */
}
コード例 #4
0
ファイル: MemHeap.cpp プロジェクト: tabchas/ee312
void *allocateMemory(unsigned size_in_bytes)
{
    int size;
    unsigned chunk;
    int chunk_size;

    if (!initialized)
    {
        initializeHeap();
        initialized = true;
    }

    if (size_in_bytes == 0)
    {
        return nullptr;
    }

    size = (size_in_bytes + sizeof(int)-1) / sizeof(int);

    chunk = findFreeChunk(size);
    if (always_false)
    {
        displayChunks();
    }
    if (chunk == bogus_chunk)
    {
        printf("Ah NUTS, out of memory\n");
        exit(-1); // forces main to return -1 !immediately!
    }

    splitChunkIfNecessary(chunk, size);
    chunk_size = memory_pool[chunk];
    assert(chunk_size >= size); // just a sanity check, pretty insane really
    setBothSignatures(chunk, -chunk_size);

    /* OK, all done... all we need to do now is return... oh,
     * we're supposed to return a pointer, not an index.....
     */
    return &memory_pool[chunk + 1];
}