Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r894:7bd32f8dc1e8 Date: 2014-02-27 17:34 +0100 http://bitbucket.org/pypy/stmgc/changeset/7bd32f8dc1e8/
Log: Keep track of how much memory we're using diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c --- a/c7/stm/gcpage.c +++ b/c7/stm/gcpage.c @@ -76,6 +76,7 @@ char *addr = _stm_large_malloc(size); if (addr == NULL) stm_fatalerror("not enough memory!\n"); + increment_total_allocated(size + LARGE_MALLOC_OVERHEAD); if (addr + size > uninitialized_page_start) { uintptr_t npages; diff --git a/c7/stm/largemalloc.h b/c7/stm/largemalloc.h --- a/c7/stm/largemalloc.h +++ b/c7/stm/largemalloc.h @@ -12,3 +12,6 @@ void _stm_large_free(char *data); void _stm_large_dump(void); + + +#define LARGE_MALLOC_OVERHEAD (2 * sizeof(size_t)) /* estimate */ diff --git a/c7/stm/misc.c b/c7/stm/misc.c --- a/c7/stm/misc.c +++ b/c7/stm/misc.c @@ -71,4 +71,12 @@ return (object_t *)list_item( STM_PSEGMENT->objects_pointing_to_nursery, index); } + +uint64_t _stm_total_allocated(void) +{ + mutex_pages_lock(); + uint64_t result = increment_total_allocated(0); + mutex_pages_unlock(); + return result; +} #endif diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c --- a/c7/stm/nursery.c +++ b/c7/stm/nursery.c @@ -213,10 +213,14 @@ bool locked = false; wlog_t *item; TREE_LOOP_FORWARD(*STM_PSEGMENT->young_outside_nursery, item) { + assert(!_is_in_nursery((object_t *)item->addr)); if (!locked) { mutex_pages_lock(); locked = true; } + char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base,item->addr); + ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj); + increment_total_allocated(-(size + LARGE_MALLOC_OVERHEAD)); _stm_large_free(stm_object_pages + item->addr); } TREE_LOOP_END; diff --git a/c7/stm/pages.c b/c7/stm/pages.c --- a/c7/stm/pages.c +++ b/c7/stm/pages.c @@ -6,10 +6,19 @@ /************************************************************/ static union { - uint8_t mutex_pages; + struct { + uint8_t mutex_pages; + uint64_t total_allocated; /* keep track of how much memory we're + using, ignoring nurseries */ + }; char reserved[64]; } pages_ctl __attribute__((aligned(64))); +static void teardown_pages(void) +{ + memset(&pages_ctl, 0, sizeof(pages_ctl)); +} + static void mutex_pages_lock(void) { while (__sync_lock_test_and_set(&pages_ctl.mutex_pages, 1) != 0) { @@ -28,6 +37,13 @@ return pages_ctl.mutex_pages != 0; } +static uint64_t increment_total_allocated(ssize_t add_or_remove) +{ + assert(_has_mutex_pages()); + pages_ctl.total_allocated += add_or_remove; + return pages_ctl.total_allocated; +} + /************************************************************/ @@ -108,6 +124,7 @@ } write_fence(); memset(flag_page_private + pagenum, PRIVATE_PAGE, count); + increment_total_allocated(4096 * count); } static void _pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) diff --git a/c7/stm/pages.h b/c7/stm/pages.h --- a/c7/stm/pages.h +++ b/c7/stm/pages.h @@ -23,6 +23,7 @@ static void mutex_pages_lock(void); static void mutex_pages_unlock(void); +static uint64_t increment_total_allocated(ssize_t add_or_remove); inline static void pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) { diff --git a/c7/stm/setup.c b/c7/stm/setup.c --- a/c7/stm/setup.c +++ b/c7/stm/setup.c @@ -101,6 +101,7 @@ teardown_sync(); teardown_gcpage(); teardown_nursery(); + teardown_pages(); } void _init_shadow_stack(stm_thread_local_t *tl) diff --git a/c7/stmgc.h b/c7/stmgc.h --- a/c7/stmgc.h +++ b/c7/stmgc.h @@ -92,6 +92,7 @@ long _stm_count_objects_pointing_to_nursery(void); object_t *_stm_enum_modified_old_objects(long index); object_t *_stm_enum_objects_pointing_to_nursery(long index); +uint64_t _stm_total_allocated(void); #endif #define _STM_GCFLAG_WRITE_BARRIER 0x01 diff --git a/c7/test/support.py b/c7/test/support.py --- a/c7/test/support.py +++ b/c7/test/support.py @@ -70,6 +70,7 @@ object_t *_stm_enum_objects_pointing_to_nursery(long index); void stm_collect(long level); +uint64_t _stm_total_allocated(void); """) @@ -215,7 +216,7 @@ } else { int nrefs = myobj->type_id - 421420; - assert(nrefs < 100); + assert(nrefs < 10000); /* artificial limit, to check for garbage */ if (nrefs == 0) /* weakrefs */ nrefs = 1; return sizeof(struct myobj_s) + nrefs * sizeof(void*); diff --git a/c7/test/test_nursery.py b/c7/test/test_nursery.py --- a/c7/test/test_nursery.py +++ b/c7/test/test_nursery.py @@ -85,13 +85,17 @@ obj_size = lib._STM_FAST_ALLOC + 16 self.start_transaction() + assert lib._stm_total_allocated() == 0 seen = set() for i in range(10): stm_minor_collect() new = stm_allocate(obj_size) assert not is_in_nursery(new) + assert lib._stm_total_allocated() == obj_size + 16 seen.add(new) assert len(seen) < 5 # addresses are reused + stm_minor_collect() + assert lib._stm_total_allocated() == 0 def test_larger_than_limit_for_nursery_dont_die(self): obj_nrefs = (lib._STM_FAST_ALLOC + 16) // 8 @@ -115,6 +119,19 @@ lp1 = stm_get_ref(lp1, i) assert not lp1 + def test_account_for_privatized_page(self): + self.start_transaction() + obj = stm_allocate(16) + self.push_root(obj) + self.commit_transaction() + obj = self.pop_root() + base = lib._stm_total_allocated() + assert base <= 4096 + + self.start_transaction() + stm_write(obj) + assert lib._stm_total_allocated() == base + 4096 + def test_reset_partial_alloc_pages(self): py.test.skip("a would-be-nice feature, but not actually needed: " "the next major GC will take care of it") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit