Author: Remi Meier
Branch: c7
Changeset: r670:a867104d94d6
Date: 2014-01-22 16:02 +0100
http://bitbucket.org/pypy/stmgc/changeset/a867104d94d6/
Log: simple page-reuse for aborted transactions
diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -133,7 +133,8 @@
void stm_setup(void)
{
_stm_reset_shared_lock();
-
+ _stm_reset_pages();
+
/* Check that some values are acceptable */
assert(4096 <= ((uintptr_t)_STM_TL));
assert(((uintptr_t)_STM_TL) == ((uintptr_t)_STM_TL));
@@ -195,7 +196,6 @@
or should it be UNCOMMITTED???
*/
num_threads_started = 0;
- index_page_never_used = FIRST_AFTER_NURSERY_PAGE;
}
#define INVALID_GS_VALUE 0x6D6D6D6D
@@ -256,7 +256,7 @@
void _stm_teardown(void)
{
munmap(object_pages, TOTAL_MEMORY);
- _stm_reset_page_flags();
+ _stm_reset_pages();
memset(write_locks, 0, sizeof(write_locks));
object_pages = NULL;
}
diff --git a/c7/nursery.c b/c7/nursery.c
--- a/c7/nursery.c
+++ b/c7/nursery.c
@@ -322,24 +322,36 @@
_STM_TL->nursery_current = nursery_base;
- /* unreserve uncommitted_pages and mark them as SHARED again
- IFF they are not in alloc[] */
- /* STM_LIST_FOREACH(_STM_TL->uncommitted_pages, ({ */
- /* uintptr_t pagenum = (uintptr_t)item; */
- /* flag_page_private[pagenum] = SHARED_PAGE; */
- /* })); */
- stm_list_clear(_STM_TL->uncommitted_pages);
-
-
/* forget about GCFLAG_NOT_COMMITTED objects by
resetting alloc-pages */
long j;
for (j = 2; j < LARGE_OBJECT_WORDS; j++) {
alloc_for_size_t *alloc = &_STM_TL->alloc[j];
uint16_t num_allocated = ((uintptr_t)alloc->next) - alloc->start;
- /* forget about all non-committed objects */
- alloc->next -= num_allocated;
+ uintptr_t next = (uintptr_t)alloc->next;
+
+ if (num_allocated) {
+ /* forget about all non-committed objects */
+ alloc->next -= num_allocated;
+
+ uintptr_t pagenum = ((uintptr_t)(next - 1)) / 4096UL;
+ if (stm_get_page_flag(pagenum) == UNCOMMITTED_SHARED_PAGE) {
+ /* the page will be freed below, we need a new one for the
+ next allocation */
+ alloc->next = 0;
+ alloc->stop = 0;
+ alloc->start = 0;
+ }
+ }
}
+
+ /* unreserve uncommitted_pages and mark them as SHARED again
+ IFF they are not in alloc[] */
+ STM_LIST_FOREACH(_STM_TL->uncommitted_pages, ({
+ stm_pages_unreserve((uintptr_t)item);
+ }));
+ stm_list_clear(_STM_TL->uncommitted_pages);
+
}
diff --git a/c7/pages.c b/c7/pages.c
--- a/c7/pages.c
+++ b/c7/pages.c
@@ -22,12 +22,23 @@
#endif
+uintptr_t index_page_never_used;
+uint8_t flag_page_private[NB_PAGES];
-uint8_t flag_page_private[NB_PAGES];
-uintptr_t index_page_never_used;
+uint8_t list_lock = 0;
+struct stm_list_s *single_page_list;
-void _stm_reset_page_flags()
+
+void _stm_reset_pages()
{
+ assert(!list_lock);
+ if (!single_page_list)
+ single_page_list = stm_list_create();
+ else
+ stm_list_clear(single_page_list);
+
+ index_page_never_used = FIRST_AFTER_NURSERY_PAGE;
+
memset(flag_page_private, 0, sizeof(flag_page_private));
}
@@ -43,7 +54,6 @@
}
-
void stm_pages_privatize(uintptr_t pagenum)
{
if (flag_page_private[pagenum] == PRIVATE_PAGE)
@@ -98,11 +108,23 @@
}
+
uintptr_t stm_pages_reserve(int num)
{
/* grab free, possibly uninitialized pages */
-
- // XXX look in some free list first
+ if (!stm_list_is_empty(single_page_list)) {
+ uint8_t previous;
+ while ((previous = __sync_lock_test_and_set(&list_lock, 1)))
+ spin_loop();
+
+ if (!stm_list_is_empty(single_page_list)) {
+ uintptr_t res = (uintptr_t)stm_list_pop_item(single_page_list);
+ list_lock = 0;
+ return res;
+ }
+
+ list_lock = 0;
+ }
/* Return the index'th object page, which is so far never used. */
uintptr_t index = __sync_fetch_and_add(&index_page_never_used, num);
@@ -111,7 +133,7 @@
for (i = 0; i < num; i++) {
assert(flag_page_private[index+i] == SHARED_PAGE);
}
- assert(flag_page_private[index] == SHARED_PAGE);
+
if (index + num >= NB_PAGES) {
fprintf(stderr, "Out of mmap'ed memory!\n");
abort();
@@ -119,6 +141,17 @@
return index;
}
+void stm_pages_unreserve(uintptr_t pagenum)
+{
+ uint8_t previous;
+ while ((previous = __sync_lock_test_and_set(&list_lock, 1)))
+ spin_loop();
+
+ flag_page_private[pagenum] = SHARED_PAGE;
+ LIST_APPEND(single_page_list, (object_t*)pagenum);
+ list_lock = 0;
+}
+
diff --git a/c7/pages.h b/c7/pages.h
--- a/c7/pages.h
+++ b/c7/pages.h
@@ -19,8 +19,8 @@
uintptr_t stm_pages_reserve(int num);
uint8_t stm_get_page_flag(int pagenum);
void stm_set_page_flag(int pagenum, uint8_t flag);
-void _stm_reset_page_flags(void);
+void _stm_reset_pages(void);
+void stm_pages_unreserve(uintptr_t num);
-
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -439,8 +439,24 @@
newer = stm_pop_root()
assert stm_get_real_address(new) == stm_get_real_address(newer)
assert stm_get_char(newer) == '\0'
+
+ def test_reuse_page(self):
+ stm_start_transaction()
+ new = stm_allocate(16)
+ stm_push_root(new)
+ stm_minor_collect()
+ new = stm_pop_root()
+ assert stm_get_page_flag(stm_get_obj_pages(new)[0]) ==
lib.UNCOMMITTED_SHARED_PAGE
+ stm_abort_transaction()
+
+ stm_start_transaction()
+ newer = stm_allocate(16)
+ stm_push_root(newer)
+ stm_minor_collect()
+ newer = stm_pop_root()
+ assert new == newer
+
-
# def test_resolve_write_write_no_conflict(self):
# stm_start_transaction()
# p1 = stm_allocate(16)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit