Author: Armin Rigo <[email protected]>
Branch:
Changeset: r118:afd0da81c314
Date: 2013-06-13 22:25 +0200
http://bitbucket.org/pypy/stmgc/changeset/afd0da81c314/
Log: Clean-ups in preparation for nursery.c
diff --git a/c4/dbgmem.c b/c4/dbgmem.c
--- a/c4/dbgmem.c
+++ b/c4/dbgmem.c
@@ -6,58 +6,18 @@
#include <sys/mman.h>
#define PAGE_SIZE 4096
-#define MMAP_LENGTH 67108864 /* 64MB */
-
-struct zone_s {
- struct zone_s *next;
- char *start;
- uint8_t active[MMAP_LENGTH / WORD];
-};
+#define MMAP_TOTAL 671088640 /* 640MB */
static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
-static char *free_zone = NULL, *free_zone_end = NULL;
-static struct zone_s *zones = NULL;
+static char *zone_current = NULL, *zone_end = NULL;
-void *stm_malloc(size_t sz)
-{
- pthread_mutex_lock(&malloc_mutex);
-
- size_t nb_pages = (sz + PAGE_SIZE - 1) / PAGE_SIZE + 1;
- if (free_zone_end - free_zone < nb_pages * PAGE_SIZE) {
- free_zone = mmap(NULL, MMAP_LENGTH, PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (free_zone == NULL || free_zone == MAP_FAILED) {
- fprintf(stderr, "out of memory: mmap() failed\n");
- abort();
- }
- free_zone_end = free_zone + MMAP_LENGTH;
- assert((MMAP_LENGTH % PAGE_SIZE) == 0);
-
- struct zone_s *z = calloc(1, sizeof(struct zone_s));
- if (z == NULL) {
- fprintf(stderr, "out of memory: malloc(zone_s) failed\n");
- abort();
- }
- z->start = free_zone;
- z->next = zones;
- zones = z;
- }
-
- char *result = free_zone;
- free_zone += nb_pages * PAGE_SIZE;
- pthread_mutex_unlock(&malloc_mutex);
-
- result += (-sz) & (PAGE_SIZE-1);
- assert(((intptr_t)(result + sz) & (PAGE_SIZE-1)) == 0);
- stm_dbgmem_used_again(result, sz, 1);
- return result;
-}
static void _stm_dbgmem(void *p, size_t sz, int prot)
{
- fprintf(stderr, "_stm_dbgmem(%p, 0x%lx, %d)\n", p, (long)sz, prot);
if (sz == 0)
return;
+
+ assert((ssize_t)sz > 0);
intptr_t align = ((intptr_t)p) & (PAGE_SIZE-1);
p = ((char *)p) - align;
sz += align;
@@ -65,64 +25,42 @@
assert(err == 0);
}
+void *stm_malloc(size_t sz)
+{
+ pthread_mutex_lock(&malloc_mutex);
+
+ if (zone_current == NULL) {
+ zone_current = mmap(NULL, MMAP_TOTAL, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (zone_current == NULL || zone_current == MAP_FAILED) {
+ fprintf(stderr, "not enough memory: mmap() failed\n");
+ abort();
+ }
+ zone_end = zone_current + MMAP_TOTAL;
+ assert((MMAP_TOTAL % PAGE_SIZE) == 0);
+ _stm_dbgmem(zone_current, MMAP_TOTAL, PROT_NONE);
+ }
+
+ size_t nb_pages = (sz + PAGE_SIZE - 1) / PAGE_SIZE + 1;
+ char *result = zone_current;
+ zone_current += nb_pages * PAGE_SIZE;
+ if (zone_current > zone_end) {
+ fprintf(stderr, "dbgmem.c: %ld MB of memory have been exausted\n",
+ (long)(MMAP_TOTAL / (1024*1024)));
+ abort();
+ }
+ pthread_mutex_unlock(&malloc_mutex);
+
+ result += (-sz) & (PAGE_SIZE-1);
+ assert(((intptr_t)(result + sz) & (PAGE_SIZE-1)) == 0);
+ _stm_dbgmem(result, sz, PROT_READ | PROT_WRITE);
+ return result;
+}
+
void stm_free(void *p, size_t sz)
{
- _stm_dbgmem(p, sz, PROT_READ | PROT_WRITE);
memset(p, 0xDD, sz);
- stm_dbgmem_not_used(p, sz, 1);
-}
-
-static void _stm_dbg_mark(char *p, size_t sz, uint8_t marker)
-{
- long startofs, numofs, i;
- struct zone_s *z = zones;
- while (!(z->start <= p && p < (z->start + MMAP_LENGTH))) {
- z = z->next;
- assert(z);
- }
- startofs = p - z->start;
- numofs = sz;
- assert((startofs & (WORD-1)) == 0);
- assert((numofs & (WORD-1)) == 0);
- assert(startofs + numofs <= MMAP_LENGTH);
- startofs /= WORD;
- numofs /= WORD;
- for (i=0; i<numofs; i++)
- z->active[startofs + i] = marker;
-}
-
-void stm_dbgmem_not_used(void *p, size_t sz, int protect)
-{
- _stm_dbg_mark(p, sz, 0);
- if (protect)
- _stm_dbgmem(p, sz, PROT_NONE);
-}
-
-void stm_dbgmem_used_again(void *p, size_t sz, int protect)
-{
- _stm_dbg_mark(p, sz, 42);
- if (protect)
- _stm_dbgmem(p, sz, PROT_READ | PROT_WRITE);
-}
-
-int stm_dbgmem_is_active(void *p1, int allow_outside)
-{
- char *p = (char *)p1;
- long startofs;
- uint8_t result;
- struct zone_s *z = zones;
- while (z && !(z->start <= p && p < (z->start + MMAP_LENGTH))) {
- z = z->next;
- }
- if (!z) {
- assert(allow_outside);
- return -1;
- }
- startofs = p - z->start;
- startofs /= WORD;
- result = z->active[startofs];
- assert(result == 0 || result == 42);
- return (result != 0);
+ _stm_dbgmem(p, sz, PROT_NONE);
}
/************************************************************/
diff --git a/c4/dbgmem.h b/c4/dbgmem.h
--- a/c4/dbgmem.h
+++ b/c4/dbgmem.h
@@ -7,18 +7,10 @@
void *stm_malloc(size_t);
void stm_free(void *, size_t);
-/* Debugging: for tracking which memory regions should be read or not. */
-void stm_dbgmem_not_used(void *p, size_t size, int protect);
-void stm_dbgmem_used_again(void *p, size_t size, int protect);
-int stm_dbgmem_is_active(void *p, int allow_outside);
-
#else
-#define stm_malloc(sz) malloc(sz)
-#define stm_free(p,sz) free(p)
-#define stm_dbgmem_not_used(p,sz,i) /* nothing */
-#define stm_dbgmem_used_again(p,sz,i) /* nothing */
-#define stm_dbgmem_is_active(p,i) 1
+#define stm_malloc(sz) malloc(sz)
+#define stm_free(p,sz) free(p)
#endif
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -956,7 +956,7 @@
}
else
{
- //stm_free(B);
+ stm_free(B, stmcb_size(B));
}
};
gcptrlist_clear(&d->private_from_protected);
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -105,6 +105,7 @@
* thread shuts down. It is reused the next time a thread starts. */
struct tx_public_descriptor {
revision_t collection_lock;
+ NURSERY_FIELDS_DECL
struct tx_descriptor *descriptor;
struct stub_block_s *stub_blocks;
gcptr stub_free_list;
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -26,7 +26,6 @@
/* allocate an object out of the local nursery */
-gcptr stm_allocate_object_of_size(size_t size);
gcptr stm_allocate(size_t size, unsigned long tid);
/* to push/pop objects into the local shadowstack */
@@ -65,10 +64,6 @@
/* callback: trace the content of an object */
extern void stmcb_trace(gcptr, void visit(gcptr *));
-/* debugging: allocate but immediately old, not via the nursery */
-gcptr _stm_allocate_object_of_size_old(size_t size);
-gcptr _stm_allocate_old(size_t size, unsigned long tid);
-
/* You can put one GC-tracked thread-local object here.
(Obviously it can be a container type containing more GC objects.)
It is set to NULL by stm_initialize(). */
diff --git a/c4/stmimpl.h b/c4/stmimpl.h
--- a/c4/stmimpl.h
+++ b/c4/stmimpl.h
@@ -30,6 +30,7 @@
#include "fprintcolor.h"
#include "lists.h"
#include "dbgmem.h"
+#include "nursery.h"
#include "et.h"
#include "steal.h"
#include "stmsync.h"
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -59,7 +59,7 @@
{
int r = DescriptorInit();
assert(r == 1);
- //stmgc_init_tls();
+ stm_init_nursery();
init_shadowstack();
//stmgcpage_init_tls();
BeginInevitableTransaction();
@@ -93,20 +93,6 @@
return obj;
}
-gcptr stm_allocate(size_t size, unsigned long tid)
-{
- gcptr result = stm_malloc(size);
- assert(tid == (tid & STM_USER_TID_MASK));
- result->h_tid = tid;
- result->h_revision = stm_private_rev_num;
- return result;
-}
-
-gcptr _stm_allocate_old(size_t size, unsigned long tid)
-{
- abort();
-}
-
/************************************************************/
static revision_t sync_required = 0;
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -5,11 +5,11 @@
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
header_files = [os.path.join(parent_dir, _n) for _n in
- "et.h lists.h steal.h "
+ "et.h lists.h steal.h nursery.h "
"stmsync.h dbgmem.h fprintcolor.h "
"stmgc.h stmimpl.h atomic_ops.h".split()]
source_files = [os.path.join(parent_dir, _n) for _n in
- "et.c lists.c steal.c "
+ "et.c lists.c steal.c nursery.c "
"stmsync.c dbgmem.c fprintcolor.c".split()]
_pycache_ = os.path.join(parent_dir, 'test', '__pycache__')
@@ -40,8 +40,7 @@
#define PREBUILT_FLAGS ...
#define PREBUILT_REVISION ...
- //gcptr stm_allocate_object_of_size(size_t size);
- gcptr stm_allocate(size_t size, unsigned long tid);
+ gcptr stm_allocate(size_t size, unsigned int tid);
void stm_push_root(gcptr);
gcptr stm_pop_root(void);
void stm_set_max_aborts(int max_aborts);
@@ -65,7 +64,6 @@
//void stmgc_minor_collect(void);
gcptr _stm_nonrecord_barrier(gcptr);
int _stm_is_private(gcptr);
- int stm_dbgmem_is_active(void *p, int allow_outside);
void stm_start_sharedlock(void);
void stm_stop_sharedlock(void);
void AbortTransaction(int);
@@ -125,7 +123,6 @@
int gettid(gcptr obj)
{
- assert(stm_dbgmem_is_active(obj, 1));
int result = stm_get_tid(obj);
assert(0 <= result && result < 521);
return result;
@@ -133,13 +130,11 @@
void settid(gcptr obj, int newtid)
{
- assert(stm_dbgmem_is_active(obj, 1));
stm_set_tid(obj, newtid);
}
gcptr rawgetptr(gcptr obj, long index)
{
- assert(stm_dbgmem_is_active(obj, 1));
assert(gettid(obj) > 421 + index);
return ((gcptr *)(obj + 1))[index];
}
@@ -147,21 +142,18 @@
void rawsetptr(gcptr obj, long index, gcptr newvalue)
{
fprintf(stderr, "%p->[%ld] = %p\n", obj, index, newvalue);
- assert(stm_dbgmem_is_active(obj, 1));
assert(gettid(obj) > 421 + index);
((gcptr *)(obj + 1))[index] = newvalue;
}
gcptr getptr(gcptr obj, long index)
{
- assert(stm_dbgmem_is_active(obj, 1));
obj = stm_read_barrier(obj);
return rawgetptr(obj, index);
}
void setptr(gcptr obj, long index, gcptr newvalue)
{
- assert(stm_dbgmem_is_active(obj, 1));
obj = stm_write_barrier(obj);
fprintf(stderr, "setptr: write_barrier: %p, writing [%ld] = %p\n",
obj, index, newvalue);
@@ -170,28 +162,24 @@
long rawgetlong(gcptr obj, long index)
{
- assert(stm_dbgmem_is_active(obj, 1));
assert(stmcb_size(obj) >= sizeof(gcptr *) + (index+1)*sizeof(void *));
return (long)((void **)(obj + 1))[index];
}
void rawsetlong(gcptr obj, long index, long newvalue)
{
- assert(stm_dbgmem_is_active(obj, 1));
assert(stmcb_size(obj) >= sizeof(gcptr *) + (index+1)*sizeof(void *));
((void **)(obj + 1))[index] = (void *)newvalue;
}
long getlong(gcptr obj, long index)
{
- assert(stm_dbgmem_is_active(obj, 1));
obj = stm_read_barrier(obj);
return rawgetlong(obj, index);
}
void setlong(gcptr obj, long index, long newvalue)
{
- assert(stm_dbgmem_is_active(obj, 1));
obj = stm_write_barrier(obj);
rawsetlong(obj, index, newvalue);
}
@@ -214,18 +202,6 @@
return (void *)thread_descriptor->public_descriptor;
}
- /*gcptr *addr_of_thread_local(void)
- {
- return &stm_thread_local_obj;
- }*/
-
- /*int in_nursery(gcptr obj)
- {
- assert(stm_dbgmem_is_active(obj, 1));
- struct tx_descriptor *d = thread_descriptor;
- return (d->nursery <= (char*)obj && ((char*)obj) < d->nursery_end);
- }*/
-
void stm_initialize_tests(int max_aborts)
{
stm_initialize();
@@ -234,7 +210,6 @@
size_t stmcb_size(gcptr obj)
{
- assert(stm_dbgmem_is_active(obj, 1));
if (gettid(obj) < 421) {
/* basic case: tid equals 42 plus the size of the object */
assert(gettid(obj) >= 42 + sizeof(struct stm_object_s));
@@ -250,7 +225,6 @@
void stmcb_trace(gcptr obj, void visit(gcptr *))
{
int i;
- assert(stm_dbgmem_is_active(obj, 1));
if (gettid(obj) < 421) {
/* basic case: no references */
return;
@@ -467,24 +441,15 @@
lib.stmgc_minor_collect()
def is_stub(p):
- assert lib.stm_dbgmem_is_active(p, 1) != 0
return p.h_tid & GCFLAG_STUB
def check_not_free(p):
- assert lib.stm_dbgmem_is_active(p, 1) == 1
assert 42 < (p.h_tid & 0xFFFF) < 521
def check_prebuilt(p):
- assert lib.stm_dbgmem_is_active(p, 1) == -1
assert 42 < (p.h_tid & 0xFFFF) < 521
assert p.h_tid & GCFLAG_PREBUILT_ORIGINAL
-def check_free(p):
- assert not lib.stm_dbgmem_is_active(p, 0)
-
-def check_nursery_free(p):
- assert not lib.stm_dbgmem_is_active(p, 0) or p.h_tid == 0
-
def make_global(p1):
assert p1.h_revision == lib.get_local_revision()
p1.h_revision = (lib.stm_global_cur_time() | 1) - 2
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit