[pypy-commit] stmgc c5: stm_large_free()
arigo
noreply at buildbot.pypy.org
Fri Dec 20 12:31:36 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: c5
Changeset: r571:9f1e3f703bf8
Date: 2013-12-20 12:31 +0100
http://bitbucket.org/pypy/stmgc/changeset/9f1e3f703bf8/
Log: stm_large_free()
diff --git a/c5/demo2.c b/c5/demo2.c
--- a/c5/demo2.c
+++ b/c5/demo2.c
@@ -1,28 +1,50 @@
#include <stdlib.h>
#include <stdio.h>
+#include <assert.h>
char *stm_large_malloc(size_t request_size);
+void stm_large_free(char *data);
-static void dump(char *data)
+static void dump(char *start)
{
- fprintf(stderr, "[ %p: %zu\n", data - 16, *(size_t*)(data - 16));
- fprintf(stderr, " %p: %zu\n", data - 8, *(size_t*)(data - 8));
- size_t n = (*(size_t*)(data - 8)) & ~1;
- fprintf(stderr, " %p: %zu ]\n", data + n, *(size_t*)(data + n));
+ char *data = start;
+ char *stop = start + 999999;
+
+ while (data < stop) {
+ fprintf(stderr, "[ %p: %zu\n", data - 16, *(size_t*)(data - 16));
+ fprintf(stderr, " %p: %zu ]\n", data - 8, *(size_t*)(data - 8));
+ data += (*(size_t*)(data - 8)) & ~1;
+ data += 16;
+ }
+ fprintf(stderr, ". %p: %zu\n\n", data - 16, *(size_t*)(data - 16));
}
int main()
{
- char *d1 = stm_large_malloc(10000);
- char *d2 = stm_large_malloc(10000);
- char *d3 = stm_large_malloc(10000);
+ char *d1 = stm_large_malloc(7000);
+ char *start = d1;
+ char *d2 = stm_large_malloc(8000);
+ char *d3 = stm_large_malloc(9000);
- dump(d1);
- dump(d2);
- dump(d3);
- dump(d3 + 10016);
+ dump(start);
+
+ stm_large_free(d1);
+ stm_large_free(d2);
+
+ dump(start);
+
+ char *d4 = stm_large_malloc(600);
+ assert(d4 == d1);
+ char *d5 = stm_large_malloc(600);
+ assert(d5 == d4 + 616);
+
+ dump(start);
+
+ stm_large_free(d5);
+
+ dump(start);
return 0;
}
diff --git a/c5/largemalloc.c b/c5/largemalloc.c
--- a/c5/largemalloc.c
+++ b/c5/largemalloc.c
@@ -261,18 +261,61 @@
void stm_large_free(char *data)
{
-#if 0
mchunk_t *chunk = data2chunk(data);
+ assert((chunk->size & (sizeof(char *) - 1)) == 0);
assert(chunk->prev_size != THIS_CHUNK_FREE);
+ /* try to merge with the following chunk in memory */
+ size_t msize = chunk->size + CHUNK_HEADER_SIZE;
+ mchunk_t *mscan = chunk_at_offset(chunk, msize);
+
+ if (mscan->prev_size == BOTH_CHUNKS_USED) {
+ assert((mscan->size & (sizeof(char *) - 1)) == 0);
+ mscan->prev_size = chunk->size;
+ }
+ else {
+ mscan->size &= ~FLAG_UNSORTED;
+ size_t fsize = mscan->size;
+ mchunk_t *fscan = chunk_at_offset(mscan, fsize + CHUNK_HEADER_SIZE);
+
+ /* unlink the following chunk */
+ mscan->d.next->prev = mscan->d.prev;
+ mscan->d.prev->next = mscan->d.next;
+ assert(mscan->prev_size = (size_t)-1);
+ assert(mscan->size = (size_t)-1);
+
+ /* merge the two chunks */
+ assert(fsize == fscan->prev_size);
+ fsize += msize;
+ fscan->prev_size = fsize;
+ chunk->size = fsize;
+ }
+
+ /* try to merge with the previous chunk in memory */
if (chunk->prev_size == BOTH_CHUNKS_USED) {
chunk->prev_size = THIS_CHUNK_FREE;
}
else {
assert((chunk->prev_size & (sizeof(char *) - 1)) == 0);
- /* merge with the previous chunk */
- ...
+ /* get at the previous chunk */
+ msize = chunk->prev_size + CHUNK_HEADER_SIZE;
+ mscan = chunk_at_offset(chunk, -msize);
+ assert(mscan->prev_size == THIS_CHUNK_FREE);
+ assert((mscan->size & ~FLAG_UNSORTED) == chunk->prev_size);
+
+ /* unlink the previous chunk */
+ mscan->d.next->prev = mscan->d.prev;
+ mscan->d.prev->next = mscan->d.next;
+
+ /* merge the two chunks */
+ mscan->size = msize + chunk->size;
+ next_chunk(mscan)->prev_size = mscan->size;
+
+ assert(chunk->prev_size = (size_t)-1);
+ assert(chunk->size = (size_t)-1);
+ chunk = mscan;
}
-#endif
+
+ insert_unsorted(chunk);
}
More information about the pypy-commit
mailing list