[pypy-commit] stmgc c5: Fixes. Invert the flag from FLAG_UNSORTED to FLAG_SORTED.
arigo
noreply at buildbot.pypy.org
Fri Dec 20 13:39:24 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: c5
Changeset: r572:7446839d5142
Date: 2013-12-20 13:11 +0100
http://bitbucket.org/pypy/stmgc/changeset/7446839d5142/
Log: Fixes. Invert the flag from FLAG_UNSORTED to FLAG_SORTED.
diff --git a/c5/demo2.c b/c5/demo2.c
--- a/c5/demo2.c
+++ b/c5/demo2.c
@@ -3,22 +3,23 @@
#include <assert.h>
+#define END_MARKER 0xDEADBEEF
+
char *stm_large_malloc(size_t request_size);
void stm_large_free(char *data);
-static void dump(char *start)
+static void dump(char *data)
{
- char *data = start;
- char *stop = start + 999999;
-
- while (data < stop) {
+ while (1) {
fprintf(stderr, "[ %p: %zu\n", data - 16, *(size_t*)(data - 16));
+ if (*(size_t*)(data - 8) == END_MARKER)
+ break;
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));
+ fprintf(stderr, " %p: end. ]\n\n", data - 8);
}
int main()
@@ -46,5 +47,14 @@
dump(start);
+ stm_large_malloc(600);
+ stm_large_free(d4);
+
+ dump(start);
+
+ stm_large_malloc(608);
+
+ dump(start);
+
return 0;
}
diff --git a/c5/largemalloc.c b/c5/largemalloc.c
--- a/c5/largemalloc.c
+++ b/c5/largemalloc.c
@@ -31,7 +31,7 @@
- otherwise, if this chunk is free: 1
- otherwise, 0. */
size_t size; /* size of the data in this chunk,
- plus optionally the FLAG_UNSORTED */
+ plus optionally the FLAG_SORTED */
dlist_t d; /* if free: a doubly-linked list */
/* if not free: the user data starts here */
@@ -43,14 +43,25 @@
considered "not free". */
} mchunk_t;
-#define FLAG_UNSORTED 1
+#define FLAG_SORTED 1
#define THIS_CHUNK_FREE 1
#define BOTH_CHUNKS_USED 0
#define CHUNK_HEADER_SIZE offsetof(struct malloc_chunk, d)
+#define END_MARKER 0xDEADBEEF
#define chunk_at_offset(p, ofs) ((mchunk_t *)(((char *)(p)) + (ofs)))
#define data2chunk(p) chunk_at_offset(p, -CHUNK_HEADER_SIZE)
-#define next_chunk(p) chunk_at_offset(p, CHUNK_HEADER_SIZE + (p)->size)
+
+static mchunk_t *next_chunk_s(mchunk_t *p)
+{
+ assert(p->size & FLAG_SORTED);
+ return chunk_at_offset(p, CHUNK_HEADER_SIZE + p->size - FLAG_SORTED);
+}
+static mchunk_t *next_chunk_u(mchunk_t *p)
+{
+ assert(!(p->size & FLAG_SORTED));
+ return chunk_at_offset(p, CHUNK_HEADER_SIZE + p->size);
+}
/* The free chunks are stored in "bins". Each bin is a doubly-linked
@@ -64,8 +75,8 @@
In each bin's doubly-linked list, chunks are sorted by their size in
decreasing order (if you start from 'd.next'). At the end of this
- list are some unsorted chunks (with FLAG_UNSORTED). All unsorted
- chunks are after all sorted chunks.
+ list are some unsorted chunks. All unsorted chunks are after all
+ sorted chunks. The flag 'FLAG_SORTED' distinguishes them.
*/
static dlist_t largebins[N_BINS] = {
@@ -101,7 +112,7 @@
new->d.prev = largebins[index].prev;
new->d.prev->next = &new->d;
largebins[index].prev = &new->d;
- new->size |= FLAG_UNSORTED;
+ assert(!(new->size & FLAG_SORTED));
}
static int compare_chunks(const void *vchunk1, const void *vchunk2)
@@ -123,7 +134,7 @@
dlist_t *end = &largebins[index];
dlist_t *scan = unsorted->prev;
size_t count = 1;
- while (scan != end && (data2chunk(scan)->size & FLAG_UNSORTED)) {
+ while (scan != end && !(data2chunk(scan)->size & FLAG_SORTED)) {
scan = scan->prev;
++count;
}
@@ -140,7 +151,7 @@
qsort(chunks, count, sizeof(mchunk_t *), compare_chunks);
--count;
- chunks[count]->size &= ~FLAG_UNSORTED;
+ chunks[count]->size |= FLAG_SORTED;
size_t search_size = chunks[count]->size;
dlist_t *head = largebins[index].next;
@@ -154,7 +165,7 @@
if (count == 0)
break; /* all done */
--count;
- chunks[count]->size &= ~FLAG_UNSORTED;
+ chunks[count]->size |= FLAG_SORTED;
search_size = chunks[count]->size;
}
else {
@@ -166,7 +177,7 @@
static void sort_bin(size_t index)
{
dlist_t *last = largebins[index].prev;
- if (last != &largebins[index] && (data2chunk(last)->size & FLAG_UNSORTED))
+ if (last != &largebins[index] && !(data2chunk(last)->size & FLAG_SORTED))
really_sort_bin(index);
}
@@ -186,9 +197,9 @@
while (scan != end) {
mscan = data2chunk(scan);
assert(mscan->prev_size == THIS_CHUNK_FREE);
- assert(next_chunk(mscan)->prev_size == mscan->size);
+ assert(next_chunk_s(mscan)->prev_size == mscan->size - FLAG_SORTED);
- if (mscan->size >= request_size)
+ if (mscan->size > request_size)
goto found;
scan = mscan->d.prev;
}
@@ -202,7 +213,6 @@
end = &largebins[index];
if (scan != end) {
mscan = data2chunk(scan);
- assert(mscan->size >= request_size);
goto found;
}
}
@@ -211,13 +221,16 @@
return allocate_more(request_size);
found:
+ assert(mscan->size & FLAG_SORTED);
+ assert(mscan->size > request_size);
+
/* unlink mscan from the doubly-linked list */
mscan->d.next->prev = mscan->d.prev;
mscan->d.prev->next = mscan->d.next;
- size_t remaining_size = mscan->size - request_size;
- if (remaining_size < sizeof(struct malloc_chunk)) {
- next_chunk(mscan)->prev_size = BOTH_CHUNKS_USED;
+ size_t remaining_size_plus_1 = mscan->size - request_size;
+ if (remaining_size_plus_1 <= sizeof(struct malloc_chunk)) {
+ next_chunk_s(mscan)->prev_size = BOTH_CHUNKS_USED;
}
else {
/* only part of the chunk is being used; reduce the size
@@ -226,9 +239,9 @@
mchunk_t *new = chunk_at_offset(mscan, CHUNK_HEADER_SIZE +
request_size);
new->prev_size = THIS_CHUNK_FREE;
- remaining_size -= CHUNK_HEADER_SIZE;
+ size_t remaining_size = remaining_size_plus_1 - 1 - CHUNK_HEADER_SIZE;
new->size = remaining_size;
- next_chunk(new)->prev_size = remaining_size;
+ next_chunk_u(new)->prev_size = remaining_size;
insert_unsorted(new);
mscan->size = request_size;
}
@@ -248,11 +261,12 @@
}
big_chunk->prev_size = THIS_CHUNK_FREE;
- big_chunk->size = big_size - CHUNK_HEADER_SIZE - sizeof(size_t);
+ big_chunk->size = big_size - CHUNK_HEADER_SIZE * 2;
- assert((char *)&next_chunk(big_chunk)->prev_size ==
- ((char *)big_chunk) + big_size - sizeof(size_t));
- next_chunk(big_chunk)->prev_size = big_chunk->size;
+ assert((char *)&next_chunk_u(big_chunk)->prev_size ==
+ ((char *)big_chunk) + big_size - CHUNK_HEADER_SIZE);
+ next_chunk_u(big_chunk)->prev_size = big_chunk->size;
+ next_chunk_u(big_chunk)->size = END_MARKER;
insert_unsorted(big_chunk);
@@ -274,7 +288,7 @@
mscan->prev_size = chunk->size;
}
else {
- mscan->size &= ~FLAG_UNSORTED;
+ mscan->size &= ~FLAG_SORTED;
size_t fsize = mscan->size;
mchunk_t *fscan = chunk_at_offset(mscan, fsize + CHUNK_HEADER_SIZE);
@@ -302,7 +316,7 @@
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);
+ assert((mscan->size & ~FLAG_SORTED) == chunk->prev_size);
/* unlink the previous chunk */
mscan->d.next->prev = mscan->d.prev;
@@ -310,7 +324,7 @@
/* merge the two chunks */
mscan->size = msize + chunk->size;
- next_chunk(mscan)->prev_size = mscan->size;
+ next_chunk_u(mscan)->prev_size = mscan->size;
assert(chunk->prev_size = (size_t)-1);
assert(chunk->size = (size_t)-1);
More information about the pypy-commit
mailing list