Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void *alloc(size_t chunk_size)
- {
- if (!isInitalized)
- {
- pthread_mutex_init(&lock, NULL);
- pthread_cond_init(&read_cond, NULL);
- pthread_cond_init(&write_cond, NULL);
- isInitalized = true;
- }
- void *old_address = sbrk(0); //Gets the current address of the edge
- void *return_address = nullptr; //Initializes an address to return
- int sizeDif = 0; //Variable that holds the size remainder in the chunk
- Chunk selectedChunk = {0, 0}; //Creates a placeholder chunk that is assigned to when a valid chunk is found
- //iterates though the list of freed chunks to see if it finds a valid chunk if the list has some elements
- while (selectedChunk.chunk_size == 0 && freedChunks.size() > 0)
- {
- read_lock();
- bool foundFittingChunk = false;
- int dif = -1; //the difference between the requested size and the size of the chunk
- std::list<Chunk>::iterator it;
- for (it = freedChunks.begin(); it != freedChunks.end(); it++)
- {
- //If first fit, take the first available chunk
- if (allocType == FIRST_FIT)
- {
- if (it->chunk_size >= (size_t)chunk_size)
- {
- foundFittingChunk = true;
- sizeDif = it->chunk_size - chunk_size;
- return_address = (void *)it->memory_address;
- selectedChunk = *it;
- break;
- }
- }
- //If worst fit. find the chunk with the most size difference
- else if (allocType == WORST_FIT)
- {
- int chunkDif = it->chunk_size - chunk_size;
- if (chunkDif >= 0 && (chunkDif >= dif || dif == -1))
- {
- foundFittingChunk = true;
- dif = chunkDif;
- return_address = (void *)it->memory_address;
- sizeDif = dif;
- selectedChunk = *it;
- }
- }
- //If best fit, find the chunk with the least chunk difference
- else if (allocType == BEST_FIT)
- {
- int chunkDif = it->chunk_size - chunk_size;
- if (chunkDif >= 0 && (chunkDif <= dif || dif == -1))
- {
- foundFittingChunk = true;
- dif = chunkDif;
- return_address = (void *)it->memory_address;
- sizeDif = dif;
- selectedChunk = *it;
- }
- }
- }
- read_unlock();
- //If found a chunk
- if (selectedChunk.chunk_size != 0)
- {
- if (pthread_mutex_trylock(&selectedChunk.instance_lock) == 0)
- {
- //Move the chunk from the freed list to the allocated list and store the memory address
- write_lock();
- allocate_chunk(selectedChunk);
- write_unlock();
- return_address = (void *)selectedChunk.memory_address;
- break;
- }
- else
- {
- selectedChunk = {0, 0};
- }
- }
- else
- {
- if (!foundFittingChunk)
- {
- break;
- }
- }
- }
- //If the remaining size of the chunk is usable. split it into its own chunk.
- if (sizeDif > 0)
- {
- write_lock();
- create_new_chunk(sizeDif, (intptr_t)((intptr_t)selectedChunk.memory_address + (intptr_t)sizeDif), true);
- write_unlock();
- }
- //If it didnt find a usable chunk, create a new one
- if (return_address == nullptr)
- {
- read_unlock();
- //increase the program edge by the requested amount
- sbrk(chunk_size + 1);
- write_lock();
- create_new_chunk((size_t)chunk_size, (intptr_t)old_address, false); //create and add a new chunk
- write_unlock();
- return_address = (void *)((intptr_t)old_address);
- }
- //Return the address
- return return_address;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement