From 30ee9bbb11c434a8f2779bfac7a9b556121800ce Mon Sep 17 00:00:00 2001 From: Reinier Maas Date: Wed, 10 Oct 2018 15:02:35 +0200 Subject: [PATCH] Update memalloc.c The previous implementation releases only the last element. The new implementation releases all free elements that are trailing. Test 1 => * make allocations * remove them FiLo (inverted order of creation) * the entire heap is returned to system Test 2 => * make allocations * remove them FiFo (order of creation) * only the size of the last removed element is returned to system - with the changes the entire heap is returned to system --- memalloc.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/memalloc.c b/memalloc.c index e4354cf..aa27c08 100644 --- a/memalloc.c +++ b/memalloc.c @@ -44,24 +44,13 @@ void free(void *block) heap and release memory to OS. Else, we will keep the block but mark it as free. */ + header->is_free = 1; if ((char*)block + header->size == programbreak) { - if (head == tail) { - head = tail = NULL; - } else { - tmp = head; - while (tmp) { - if(tmp->next == tail) { - tmp->next = NULL; - tail = tmp; - } - tmp = tmp->next; - } - } /* sbrk() with a negative argument decrements the program break. So memory is released by the program to OS. */ - sbrk(0 - header->size - sizeof(struct header_t)); + sbrk(release_size()); /* Note: This lock does not really assure thread safety, because sbrk() itself is not really thread safe. Suppose there occurs a foregin sbrk(N) @@ -72,10 +61,38 @@ void free(void *block) pthread_mutex_unlock(&global_malloc_lock); return; } - header->is_free = 1; pthread_mutex_unlock(&global_malloc_lock); } +size_t release_size() +{ + /* This calculates the size of all trailing elements */ + struct header_t *new_tail, *tmp; + size_t release_size = 0; + new_tail = tmp = head; + while (tmp) { + if(tmp->next == NULL) { + new_tail->next = NULL; + tail = new_tail; + } + if(!tmp->is_free) { + new_tail = tmp; + release_size = 0; + } else { + release_size -= tmp->size - sizeof(struct header_t); + } + tmp = tmp->next; + } + /* Head equals tail can indicate two things: + * this is the last remaining element on the heap + * there are no remaining elements on the heap + */ + if (head == tail && head->is_free) { + head = tail = NULL; + } + return release_size; +} + void *malloc(size_t size) { size_t total_size;