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

Reply via email to