Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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)
    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;
}