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; }
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; }
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; }