示例#1
0
alloc_status mem_del_alloc(pool_pt pool, alloc_pt alloc)
{
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt poolMgr = (pool_mgr_pt) pool;
    // temporary node pt to check if the node if found
    node_pt node = (node_pt) alloc;
    // node that will hold the next node from the node that will be deleted
    node_pt next = NULL;
    // prev node from deleteNode
    node_pt prev = NULL;
    // this node will be used as a temporary storage
    node_pt deleteNode = NULL;
    // find the node in the node heap
    for(int i = 0; i< poolMgr->total_nodes; ++i){
        if(node == &poolMgr->node_heap[i]){
            deleteNode = &poolMgr->node_heap[i];
            break;
        }
    }
    // make sure it's found
    if (deleteNode != NULL);
    else{
        return ALLOC_FAIL;
    }

    next = deleteNode->next;
    prev = deleteNode->prev;
    deleteNode->allocated = 0;

    // update metadata (num_allocs, alloc_size)
    poolMgr->pool.num_allocs--;
    poolMgr->pool.alloc_size -= deleteNode->alloc_record.size;

    // if the next node in the list is a gap, merge deleteNode to it
    if(deleteNode->next != NULL && deleteNode->next->allocated == 0) {
        if(_mem_remove_from_gap_ix(poolMgr, 0, next) == ALLOC_FAIL) {
            return ALLOC_FAIL;
        }
        deleteNode->alloc_record.size += next->alloc_record.size;
        //   update node as unused
        next->used = 0;
        //   update metadata (used nodes)
        --(poolMgr->used_nodes);
        //   update linked list:
        if (next->next) {
            next->next->prev = deleteNode;
            deleteNode->next = next->next;
        } else {
            deleteNode->next = NULL;
        }
        next->next = NULL;
        next->prev = NULL;
    }
    // check if the prev node in the list a gap and merges it if it is
    if(deleteNode->prev!= NULL && deleteNode->prev->allocated == 0) {
        if(_mem_remove_from_gap_ix(poolMgr, 0, prev) == ALLOC_FAIL) {
            return ALLOC_FAIL;
        }
        prev->alloc_record.size += deleteNode->alloc_record.size;
        //   update metadata (used_nodes)
        --(poolMgr->used_nodes);
        deleteNode->used = 0;
        //   update linked list
        if (deleteNode->next) {
            prev->next = deleteNode->next;
            deleteNode->next->prev = prev;
        } else {
            prev->next = NULL;
        }
        deleteNode = prev;
    }
    // check success
    if (_mem_add_to_gap_ix(poolMgr, deleteNode->alloc_record.size, deleteNode) == ALLOC_OK) {
        return ALLOC_OK;
    }
    else {
        return ALLOC_FAIL;
    }
}
示例#2
0
alloc_status mem_del_alloc(pool_pt pool, alloc_pt alloc) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt pool_mgr = (pool_mgr_pt) pool;

    // get node from alloc by casting the pointer to (node_pt)
    node_pt node = (node_pt) alloc;

    node_pt node_delete;

    // locate the node in the node heap
    for(int i=0;i < pool_mgr->total_nodes; i++){
        if(pool_mgr->node_heap[i].alloc_record.mem == node->alloc_record.mem){

            node_delete = &pool_mgr->node_heap[i];
            break;
        };
    };

    // verify that node is not null
    if(node_delete == NULL){
        return ALLOC_NOT_FREED;
    };

    // set node to gap
    node_delete->allocated = 0;

    // update pool manager variables
    pool_mgr->pool.num_allocs--;
    pool_mgr->pool.alloc_size = pool_mgr->pool.alloc_size - node_delete->alloc_record.size;

    //if the next node is also a gap, merge to one gap
    node_pt merge_node;
    if(node_delete->next != NULL && node_delete->next->allocated == 0 && node_delete->next->used == 1){

        merge_node = node_delete->next;

        //  remove the next node from the gap index
        _mem_remove_from_gap_ix(pool_mgr,merge_node->alloc_record.size,merge_node);

        //  add size to the gap node
        node_delete->alloc_record.size = node_delete->alloc_record.size + node_delete->next->alloc_record.size;

        //  set merged node used variable to zero
        merge_node->used = 0;

        //   deincriment used nodes
        pool_mgr->used_nodes--;

        //  set the merge node next prev pointer to
        //node delete and node delete next to the merge node next
        // or set it to null if the merged next is null
        if (merge_node->next) {
            merge_node->next->prev = node_delete;
            node_delete->next = merge_node->next;
        } else {
            node_delete->next = NULL;
        }
        merge_node->next = NULL;
        merge_node->prev = NULL;
        merge_node->alloc_record.size = 0;
        merge_node->alloc_record.mem = NULL;
    };

    // add the node delete to the gap index
    _mem_add_to_gap_ix(pool_mgr,node_delete->alloc_record.size,node_delete);

    //if the node previous to the node to delete is a gap, merge the node
    node_pt prev_node;
    if (node_delete->prev != NULL && node_delete->prev->used == 1 && node_delete->prev->allocated == 0) {
        prev_node = node_delete->prev;

        //   remove the previous node and node to delete from the gap index
        _mem_remove_from_gap_ix(pool_mgr, prev_node->alloc_record.size, prev_node);
        _mem_remove_from_gap_ix(pool_mgr, node_delete->alloc_record.size,node_delete);



        //   add the node to delete to the previous node
        prev_node->alloc_record.size = node_delete->alloc_record.size + node_delete->prev->alloc_record.size;

        //  clear the metadata from the node to delete
        node_delete->alloc_record.size = 0;
        node_delete->alloc_record.mem = NULL;
        node_delete->used = 0;
        node_delete->allocated = 0;

        //   deincrement used nodes
        pool_mgr->used_nodes--;

        //  set the prev node next pointer to node delete next
        // and the prev pointer from the node delete next to prev node
        if (node_delete->next) {
            prev_node->next = node_delete->next;
            node_delete->next->prev = prev_node;
        } else {
            prev_node->next = NULL;
        }
        node_delete->next = NULL;
        node_delete->prev = NULL;

        //   add the previous node to the gap index
        _mem_add_to_gap_ix(pool_mgr,prev_node->alloc_record.size,prev_node);


    };

    return ALLOC_OK;
}
示例#3
0
alloc_pt mem_new_alloc(pool_pt pool, size_t size) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    // variables that will be used:
    pool_mgr_pt poolMgr = (pool_mgr_pt) pool;
    node_pt newNode = NULL;
    node_pt newGap = NULL;
    int i = 0;
    int j = 0;
    int remainGap = 0;


    // check if any gaps, return null if none
    if(poolMgr->gap_ix[0].node == NULL){
        return NULL;
    }

    // expand heap node, if necessary, quit on error
    if ((poolMgr->used_nodes / poolMgr->total_nodes) > MEM_NODE_HEAP_FILL_FACTOR && _mem_resize_node_heap(poolMgr) != ALLOC_OK) {
        _mem_resize_node_heap(poolMgr);
    }

    if (poolMgr->used_nodes > poolMgr->total_nodes) {
        return NULL;
    }
    // if policy == FIRST_FIT, (node heap)
    if(poolMgr->pool.policy == FIRST_FIT){
        while((i < poolMgr->total_nodes) && (poolMgr->node_heap[i].allocated != 0 || poolMgr->node_heap[i].alloc_record.size < size)){
            ++i;
        }
        // check if node found
        if(i == poolMgr->total_nodes){
            return NULL;
        }
        newNode = &poolMgr->node_heap[i];

    }
        // if policy == BEST_FIT, (gap ix)
    else if(poolMgr->pool.policy == BEST_FIT){
        if(poolMgr->pool.num_gaps > 0) {
            while (i < poolMgr->pool.num_gaps && poolMgr->gap_ix[i + 1].size >= size) {
                if(poolMgr->gap_ix[i].size == size){
                    break;
                }
                ++i;
            }
        }
        else {
            return NULL;
        }
        newNode = poolMgr->gap_ix[i].node;
    }

    // check if node found
    if(newNode == NULL){
        return NULL;
    }

    // update metadata (num_allocs, alloc_size)
    ++(poolMgr->pool.num_allocs);
    poolMgr->pool.alloc_size += size;

    // calculate the size of the remaining gap, if any
    if(newNode->alloc_record.size - size > 0){
        remainGap = newNode->alloc_record.size - size;
    }
    _mem_remove_from_gap_ix(poolMgr, size, newNode);

    // convert gap_node to an allocation node of given size
    newNode->alloc_record.size = size;
    newNode->allocated = 1;
    newNode->used = 1;

    // adjust node heap:
    //   if remaining gap, need a new node
    if(remainGap != 0) {
        //   find an unused one in the node heap
        while (poolMgr->node_heap[j].used != 0) {
            ++j;
        }
        newGap = &poolMgr->node_heap[j];
        //   make sure one was found
        if(newGap == NULL){
            return NULL;
        }
        else {
            newGap->alloc_record.size = remainGap;
            newGap->used = 1;
            newGap->allocated = 0;
        }
        newGap->next = newNode->next;

        //   update linked list (new node right after the node for allocation)
        if(newNode->next != NULL){
            newNode->next->prev = newGap;
        }
        ++(poolMgr->used_nodes);
        newNode->next = newGap;
        newGap->prev = newNode;


        //   add to gap index
        _mem_add_to_gap_ix(poolMgr, remainGap, newGap);
    }

    // return allocation record by casting the node to (alloc_pt)
    return (alloc_pt) newNode;
}
示例#4
0
alloc_pt mem_new_alloc(pool_pt pool, size_t size) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt pool_mgr = (pool_mgr_pt) pool;

    // verify if there are any gaps in the pool
    if (pool_mgr->pool.num_gaps == 0) {
        return NULL;
    };

    // resize node heap if nessisary
    _mem_resize_node_heap(pool_mgr);

    // check if used nodes are greater than total nodes
    if (pool_mgr->used_nodes >= pool_mgr->total_nodes) {
        return NULL;
    };



    // if FIRST_FIT, then find the first unallocated node with appropriate size in the node heap
    node_pt alloc_node;
    if (pool_mgr->pool.policy == FIRST_FIT) {
        for (int i = 0; i < pool_mgr->total_nodes; i++) {
            if (pool_mgr->node_heap[i].alloc_record.size >= size && pool_mgr->node_heap[i].allocated == 0) {
                alloc_node = &pool_mgr->node_heap[i];
                break;
            }else{
                alloc_node = NULL;
            };
        }
    };

    // if BEST_FIT, then find the first gap node with appropriate size in the gap index
    if(pool_mgr->pool.policy == BEST_FIT){
        for (int i = 0; i < pool_mgr->pool.num_gaps; i++) {
            if (pool_mgr->gap_ix[i].node->alloc_record.size >= size && pool_mgr->gap_ix[i].node->allocated == 0) {
                alloc_node = pool_mgr->gap_ix[i].node;
                break;
            }else{
                alloc_node = NULL;
            };
        }
    };

    // check if node found
    if (alloc_node == NULL) {
        return NULL;
    };

    // incriment num_allocs and add the size of the new allocation to alloc_size
    pool->num_allocs++;
    pool->alloc_size += size;

    // calculate the size of the remaining gap
    size_t gap_remain;
    gap_remain = alloc_node->alloc_record.size - size;

    // remove node from gap index
    _mem_remove_from_gap_ix(pool_mgr, size, alloc_node);

    // update the variables of the new allocated node
    alloc_node->allocated = 1;
    alloc_node->alloc_record.size = size;


    //use new node to handle remaining gap
    node_pt gap_node;

    // locate an unused node in the node heap
    if(gap_remain != 0) {
        for (int i = 0; i < pool_mgr->total_nodes; i++) {
            if (pool_mgr->node_heap[i].used == 0) {
                gap_node = &pool_mgr->node_heap[i];
                break;
            }
        }

        //   verify that the node we found exists
        if (gap_node == NULL) {
            //gap not found!
        }

        //   initialize the gap node by adding the appropriate values
        gap_node->alloc_record.size = gap_remain;
        gap_node->alloc_record.mem = alloc_node->alloc_record.mem + size;
        gap_node->used = 1;
        gap_node->allocated = 0;

        //  incriment the used nodes of the pool manager
        pool_mgr->used_nodes++;

        //   set new allocated node to point next to the remaining gap node
        if (alloc_node->next == NULL) {
            alloc_node->next = gap_node;
            gap_node->next = NULL;
            gap_node->prev = alloc_node;
        }
        else {
            gap_node->next = alloc_node->next;
            alloc_node->next->prev = gap_node;
            alloc_node->next = gap_node;
            gap_node->prev = alloc_node;
        };

        //   add to gap index
        _mem_add_to_gap_ix(pool_mgr, gap_remain, gap_node);
    }

    //   verify that the new allocated node was created succesfully
    if(alloc_node == NULL){
        return NULL;
    };

    // return allocation record by casting the node to (alloc_pt)
    return (alloc_pt) alloc_node;
}
示例#5
0
alloc_status mem_del_alloc(pool_pt pool, alloc_pt alloc) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt pool_mgr = (pool_mgr_pt) pool;

    // get node from alloc by casting the pointer to (node_pt)
    node_pt node = (node_pt) alloc;

    // find the node in the node heap
    int found = 0;
    for (int i = 0; i < pool_mgr->total_nodes; i++) {
        if (&pool_mgr->node_heap[i] == node) {
            found = 1;
            break;
        }

    }

    // this is node-to-delete
    // make sure it's found
    if (!found)
        return ALLOC_FAIL;

    // convert to gap node
    node->allocated = 0;

    // update metadata (num_allocs, alloc_size)
    pool_mgr->pool.num_allocs--;
    pool_mgr->pool.alloc_size -= alloc->size;

    // if the next node in the list is also a gap, merge into node-to-delete
    if (node->next != NULL && node->next->allocated == 0) {
        //   remove the next node from gap index
        //   check success
        if (_mem_remove_from_gap_ix(pool_mgr, node->next->alloc_record.size, node->next) != ALLOC_OK)
            return ALLOC_FAIL;

        //   add the size to the node-to-delete
        node->alloc_record.size += node->next->alloc_record.size;

        //   update node as unused
        node->next->used = 0;

        //   update metadata (used nodes)
        pool_mgr->used_nodes--;

        //   update linked list:
        /*
                        if (next->next) {
                            next->next->prev = node_to_del;
                            node_to_del->next = next->next;
                        } else {
                            node_to_del->next = NULL;
                        }
                        next->next = NULL;
                        next->prev = NULL;
         */
        node_pt node_to_del = node->next;
        if (node->next->next) {
            node->next->next->prev = node;
            node->next = node->next->next;
        } else {
            node->next = NULL;
        }
        node_to_del->next = NULL;
        node_to_del->prev = NULL;
    }

    // this merged node-to-delete might need to be added to the gap index
    // but one more thing to check...
    // if the previous node in the list is also a gap, merge into previous!
    if (node->prev != NULL && node->prev->allocated == 0) {
        //   remove the previous node from gap index
        //   check success
        if (_mem_remove_from_gap_ix(pool_mgr, node->prev->alloc_record.size, node->prev) != ALLOC_OK)
            return ALLOC_FAIL;

        //   add the size of node-to-delete to the previous
        node->prev->alloc_record.size += node->alloc_record.size;

        //   update node-to-delete as unused
        node->used = 0;

        //   update metadata (used_nodes)
        pool_mgr->used_nodes--;

        //   update linked list
        /*
                        if (node_to_del->next) {
                            prev->next = node_to_del->next;
                            node_to_del->next->prev = prev;
                        } else {
                            prev->next = NULL;
                        }
                        node_to_del->next = NULL;
                        node_to_del->prev = NULL;
         */
        node_pt prev_node = node->prev;
        if (node->next) {
            node->prev->next = node->next;
            node->next->prev = node->prev;
        } else {
            node->prev->next = NULL;
        }
        node->next = NULL;
        node->prev = NULL;
        //   change the node to add to the previous node!
        node = prev_node;
    }

    // add the resulting node to the gap index
    // check success
    if (_mem_add_to_gap_ix(pool_mgr, node->alloc_record.size, node) != ALLOC_OK)
        return ALLOC_FAIL;

    return ALLOC_OK;
}
示例#6
0
alloc_pt mem_new_alloc(pool_pt pool, size_t size) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt pool_mgr = (pool_mgr_pt) pool;

    // check if any gaps, return null if none
    if (pool_mgr->pool.num_gaps == 0)
        return NULL;

    // expand heap node, if necessary, quit on error
    if (_mem_resize_node_heap(pool_mgr) != ALLOC_OK)
        return NULL;

    // check used nodes fewer than total nodes, quit on error
    if (pool_mgr->used_nodes > pool_mgr->total_nodes)
        return NULL;

    // get a node for allocation:
    node_pt node = NULL;

    // if FIRST_FIT, then find the first sufficient node in the node heap
    if (pool->policy == FIRST_FIT) {
        for (int i = 0; i < pool_mgr->total_nodes; i ++) {
            if (pool_mgr->node_heap[i].used == 1
                && pool_mgr->node_heap[i].allocated == 0
                && pool_mgr->node_heap[i].alloc_record.size >= size) {
                node = &pool_mgr->node_heap[i];
                break;
            }
        }
        // if BEST_FIT, then find the first sufficient node in the gap index
    } else if  (pool->policy == BEST_FIT) {
        for (int i = 0; i < pool_mgr->gap_ix_capacity && node == NULL; i++) {
            if (pool_mgr->gap_ix[i].size >= size)
                node = pool_mgr->gap_ix[i].node;
        }
    } else {
        return NULL;
    }

    // check if node found
    if (node == NULL) {
        return NULL;
    }

    // update metadata (num_allocs, alloc_size)
    pool->num_allocs++;
    pool->alloc_size += size;

    // calculate the size of the remaining gap, if any
    size_t remaining_gap_size = node->alloc_record.size - size;

    // remove node from gap index
    if (_mem_remove_from_gap_ix(pool_mgr, size, node) != ALLOC_OK)
        return NULL;

    // convert gap_node to an allocation node of given size
    node->allocated = 1;
    node->alloc_record.size = size;

    // adjust node heap:
    //   if remaining gap, need a new node
    if (remaining_gap_size != 0) {
        //   find an unused one in the node heap
/*        node_pt unused_node = pool_mgr->node_heap;
        while (unused_node != NULL && unused_node->used != 0) {
            unused_node = unused_node->next;
        }*/

        node_pt unused_node = NULL;
        for (int i = 0; i < pool_mgr->total_nodes; i ++) {
            if (pool_mgr->node_heap[i].used == 0) {
                unused_node = &pool_mgr->node_heap[i];
                break;
            }
        }

        //   make sure one was found
        if (unused_node == NULL)
            return NULL;

        //   initialize it to a gap node
        unused_node->allocated = 0;
        unused_node->used = 1;
        unused_node->alloc_record.size = remaining_gap_size;
        unused_node->alloc_record.mem = node->alloc_record.mem + size;

        //   update metadata (used_nodes)
        pool_mgr->used_nodes++;

        //   update linked list (new node right after the node for allocation)
        unused_node->next = node->next;
        if (node->next != NULL)  {
            node->next->prev = unused_node;
        } else {
            unused_node->next = NULL;
        }
        node->next = unused_node;
        unused_node->prev = node;

        //   add to gap index
        //   check if successful
        if (_mem_add_to_gap_ix(pool_mgr, remaining_gap_size, unused_node) != ALLOC_OK)
            return NULL;
    }

    // return allocation record by casting the node to (alloc_pt)
    return (alloc_pt) node;
}
示例#7
0
pool_pt mem_pool_open(size_t size, alloc_policy policy) {
    // make sure there the pool store is allocated
    if (pool_store == NULL)
        return NULL;

    // expand the pool store, if necessary
    _mem_resize_pool_store();

    // allocate a new mem pool mgr
    pool_mgr_pt pool_mgr = malloc(sizeof(pool_mgr_t));

    // check success, on error return null
    if (pool_mgr == NULL)
        return  NULL;

    // allocate a new memory pool
    pool_mgr->pool.mem = malloc(size);
    pool_mgr->pool.policy = policy;
    pool_mgr->pool.total_size = size;

    // check success, on error deallocate mgr and return null
    if (pool_mgr->pool.mem == NULL) {
        free(pool_mgr->pool.mem);
        free(pool_mgr);
        return NULL;
    }

    // allocate a new node heap
    pool_mgr->node_heap = calloc(MEM_NODE_HEAP_INIT_CAPACITY, sizeof(node_t));
    pool_mgr->total_nodes = MEM_NODE_HEAP_INIT_CAPACITY;

    // check success, on error deallocate mgr/pool and return null
    if (pool_mgr->node_heap == NULL) {
        free(pool_mgr->pool.mem);
        free(pool_mgr->node_heap);
        free(pool_mgr);
        return NULL;
    }

    // allocate a new gap index
    pool_mgr->gap_ix = calloc(MEM_GAP_IX_INIT_CAPACITY, sizeof(gap_t));
    pool_mgr->gap_ix_capacity = MEM_GAP_IX_INIT_CAPACITY;

    // check success, on error deallocate mgr/pool/heap and return null
    if (pool_mgr->gap_ix == NULL) {
        free(pool_mgr->pool.mem);
        free(pool_mgr->node_heap);
        free(pool_mgr->gap_ix);
        free(pool_mgr);
        return NULL;
    }

    // assign all the pointers and update meta data:

    //   initialize top node of node heap
    pool_mgr->node_heap[0].alloc_record.mem = pool_mgr->pool.mem;
    pool_mgr->node_heap[0].alloc_record.size = size;
    pool_mgr->node_heap[0].used = 1;
    pool_mgr->used_nodes = 1;
    pool_mgr->pool.num_gaps = 0;

    //   initialize top node of gap index
    _mem_add_to_gap_ix(pool_mgr, size, &pool_mgr->node_heap[0]);
    //pool_mgr->gap_ix[0].node = &pool_mgr->node_heap[0];
    //pool_mgr->gap_ix[0].node->alloc_record.size = size;

    //   link pool mgr to pool store
    pool_store[pool_store_size] = pool_mgr;
    pool_store_size++;

    // return the address of the mgr, cast to (pool_pt)
    return (pool_pt) pool_mgr;
}
示例#8
0
alloc_pt mem_new_alloc(pool_pt pool, size_t size) {
    // get mgr from pool by casting the pointer to (pool_mgr_pt)
    pool_mgr_pt mem_pool_mgr = (pool_mgr_pt) pool;
    // check if any gaps, return null if none
    if(pool->num_gaps == 0)
    {
        return NULL;
    }
    // expand heap node, if necessary, quit on error
    if(mem_pool_mgr->total_nodes < mem_pool_mgr->used_nodes)
    {
        mem_pool_mgr->total_nodes += MEM_NODE_HEAP_EXPAND_FACTOR;
    }
    // check used nodes fewer than total nodes, quit on error
    if(mem_pool_mgr->total_nodes < mem_pool_mgr->used_nodes)
    {
        return NULL;
    }
    // get a node for allocation:
    node_pt nodeA = NULL;
    node_pt gapA = NULL;
    int i = 0;
    // if FIRST_FIT, then find the first sufficient node in the node heap
    if(mem_pool_mgr->pool.policy == FIRST_FIT)
    {
    while(i < mem_pool_mgr->total_nodes)
            if((mem_pool_mgr->node_heap[i].allocated != 0 || mem_pool_mgr->node_heap[i].alloc_record.size < size))
            ++i;
            nodeA = &mem_pool_mgr->node_heap[i];
    }
    // if BEST_FIT, then find the first sufficient node in the gap index
    if(mem_pool_mgr->pool.policy == BEST_FIT)
    {
    while(i < mem_pool_mgr->gap_ix->size)
            if(i < mem_pool_mgr->pool.num_gaps && mem_pool_mgr->gap_ix[i + 1].size >= size)
            ++i;
            nodeA = mem_pool_mgr->gap_ix[i].node;
    }
    // check if node found
    if (nodeA = NULL)
    {
        return NULL;
    }
    // update metadata (num_allocs, alloc_size)
    (mem_pool_mgr->pool.num_allocs)++;
    mem_pool_mgr->pool.alloc_size += size;
    // calculate the size of the remaining gap, if any
    int remainGap = 0;
    if(nodeA->alloc_record.size - size > 0)
    {
        remainGap = nodeA->alloc_record.size - size;
    }
    // remove node from gap index
    _mem_remove_from_gap_ix(mem_pool_mgr, size, nodeA);
    // convert gap_node to an allocation node of given size
    nodeA->alloc_record.size = size;
    nodeA->allocated = 1;
    nodeA->used = 1;
    // adjust node heap:
    //   if remaining gap, need a new node
    //   find an unused one in the node heap
    //   make sure one was found
    //   initialize it to a gap node
    int j = 0;
    if(remainGap > 0)
    {
        while(mem_pool_mgr->node_heap[j].used > 0)
        {
            gapA = &mem_pool_mgr->node_heap[j];
            ++j;
        }
    }

    //   update metadata (used_nodes)
    (mem_pool_mgr->used_nodes)++;
    //   update linked list (new node right after the node for allocation)
    if(nodeA->next != NULL)
    {
        nodeA->next->prev = gapA;
        gapA->prev = nodeA;
    }

    //   add to gap index
    _mem_add_to_gap_ix(mem_pool_mgr, remainGap, gapA);
    //   check if successful
    // return allocation record by casting the node to (alloc_pt)
    return (alloc_pt) nodeA;

}