[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