[pypy-commit] stmgc default: make modified_old_objs a tree

Raemi noreply at buildbot.pypy.org
Thu Sep 4 13:25:00 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: 
Changeset: r1350:8a58897dff57
Date: 2014-09-04 13:25 +0200
http://bitbucket.org/pypy/stmgc/changeset/8a58897dff57/

Log:	make modified_old_objs a tree

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -45,7 +45,8 @@
 
 void _dbg_print_commit_log()
 {
-    struct stm_commit_log_entry_s *cl = &commit_log_root;
+    volatile struct stm_commit_log_entry_s *cl = (volatile struct stm_commit_log_entry_s *)
+        &commit_log_root;
 
     fprintf(stderr, "root (%p, %d)\n", cl->next, cl->segment_num);
     while ((cl = cl->next)) {
@@ -70,7 +71,8 @@
 
 void stm_validate(void *free_if_abort)
 {
-    struct stm_commit_log_entry_s *cl = STM_PSEGMENT->last_commit_log_entry;
+    volatile struct stm_commit_log_entry_s *cl = (volatile struct stm_commit_log_entry_s *)
+        STM_PSEGMENT->last_commit_log_entry;
 
     /* Don't check 'cl'. This entry is already checked */
     while ((cl = cl->next)) {
@@ -79,10 +81,6 @@
 
         object_t *obj;
         while ((obj = cl->written[i])) {
-            /* in case this entry's transaction has not yet discarded
-               the backup copies, wait. */
-            while (cl->committing)
-                spin_loop();
 
             _update_obj_from(cl->segment_num, obj);
 
@@ -95,33 +93,37 @@
         };
 
         /* last fully validated entry */
-        STM_PSEGMENT->last_commit_log_entry = cl;
+        STM_PSEGMENT->last_commit_log_entry = (struct stm_commit_log_entry_s *)cl;
     }
 }
 
 static struct stm_commit_log_entry_s *_create_commit_log_entry()
 {
-    struct list_s *lst = STM_PSEGMENT->modified_old_objects;
-    size_t count = list_count(lst);
+    struct tree_s *tree = STM_PSEGMENT->modified_old_objects;
+    size_t count = tree_count(tree);
     size_t byte_len = sizeof(struct stm_commit_log_entry_s) + (count + 1) * sizeof(object_t*);
     struct stm_commit_log_entry_s *result = malloc(byte_len);
-    int i;
 
     result->next = NULL;
     result->segment_num = STM_SEGMENT->segment_num;
-    for (i = 0; i < count; i++) {
-        result->written[i] = (object_t*)list_item(lst, i);
-    }
+
+    int i = 0;
+    wlog_t *item;
+    TREE_LOOP_FORWARD(tree, item);
+    result->written[i] = (object_t*)item->addr;
+    i++;
+    TREE_LOOP_END;
+
+    OPT_ASSERT(count == i);
     result->written[count] = NULL;
-    result->committing = false;
-    spinlock_acquire(result->committing); /* =true */
 
     return result;
 }
 
 static struct stm_commit_log_entry_s *_validate_and_add_to_commit_log()
 {
-    struct stm_commit_log_entry_s *new, **to;
+    struct stm_commit_log_entry_s *new;
+    volatile struct stm_commit_log_entry_s **to;
 
     new = _create_commit_log_entry();
     fprintf(stderr,"%p\n", new);
@@ -169,7 +171,7 @@
         dprintf(("prot %lu, len=%lu in seg %lu\n", first_page, (end_page - first_page + 1), i));
     }
 
-    LIST_APPEND(STM_PSEGMENT->modified_old_objects, obj);
+    tree_insert(STM_PSEGMENT->modified_old_objects, (uintptr_t)obj, 0);
 
     LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
     obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
@@ -221,7 +223,7 @@
         reset_transaction_read_version();
     }
 
-    assert(list_is_empty(STM_PSEGMENT->modified_old_objects));
+    assert(tree_count(STM_PSEGMENT->modified_old_objects) == 0);
     assert(list_is_empty(STM_PSEGMENT->objects_pointing_to_nursery));
     check_nursery_at_transaction_start();
 }
@@ -260,7 +262,6 @@
 
     struct stm_commit_log_entry_s* entry = _validate_and_add_to_commit_log();
     /* XXX:discard backup copies */
-    spinlock_release(entry->committing);
 
     s_mutex_lock();
 
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -48,7 +48,7 @@
 struct stm_priv_segment_info_s {
     struct stm_segment_info_s pub;
 
-    struct list_s *modified_old_objects;
+    struct tree_s *modified_old_objects;
     struct list_s *objects_pointing_to_nursery;
     uint8_t privatization_lock;
 
@@ -64,8 +64,7 @@
 
 /* Commit Log things */
 struct stm_commit_log_entry_s {
-    struct stm_commit_log_entry_s *next;
-    bool committing;            /* true while not yet removed backup copies */
+    volatile struct stm_commit_log_entry_s *next;
     int segment_num;
     object_t *written[];        /* terminated with a NULL ptr */
 };
diff --git a/c8/stm/list.c b/c8/stm/list.c
--- a/c8/stm/list.c
+++ b/c8/stm/list.c
@@ -43,6 +43,7 @@
     if (tree->raw_current != tree->raw_start) {
         _tree_clear_node(&tree->toplevel);
         tree->raw_current = tree->raw_start;
+        tree->count = 0;
     }
 }
 
@@ -64,7 +65,7 @@
     struct tree_s tree_copy;
     memset(&tree_copy, 0, sizeof(struct tree_s));
 
-    TREE_LOOP_FORWARD(*tree, item) {
+    TREE_LOOP_FORWARD(tree, item) {
         tree_insert(&tree_copy, item->addr, item->val);
 
     } TREE_LOOP_END;
@@ -99,7 +100,7 @@
     newtree.raw_current = newitems;
     newtree.raw_end = newitems + newalloc;
     _tree_clear_node(&newtree.toplevel);
-    TREE_LOOP_FORWARD(*tree, item)
+    TREE_LOOP_FORWARD(tree, item)
     {
         tree_insert(&newtree, item->addr, item->val);
     } TREE_LOOP_END;
@@ -145,6 +146,7 @@
                 /* reuse the deleted entry and that's it */
                 wlog1->addr = addr;
                 wlog1->val = val;
+                tree->count++;
                 return;
             }
             /* the key must not already be present */
@@ -166,15 +168,29 @@
     wlog->addr = addr;
     wlog->val = val;
     *(char **)p = (char *)wlog;
+    tree->count++;
 }
 
 static bool tree_delete_item(struct tree_s *tree, uintptr_t addr)
 {
     wlog_t *entry;
-    TREE_FIND(*tree, addr, entry, goto missing);
+    TREE_FIND(tree, addr, entry, goto missing);
     entry->addr = 0;
+    tree->count--;
     return true;
 
  missing:
     return false;
 }
+
+static wlog_t *tree_item(struct tree_s *tree, int index)
+{
+    int i = 0;
+    wlog_t *item;
+    TREE_LOOP_FORWARD(tree, item);
+    if (i == index)
+        return item;
+    i++;
+    TREE_LOOP_END;
+    return NULL;
+}
diff --git a/c8/stm/list.h b/c8/stm/list.h
--- a/c8/stm/list.h
+++ b/c8/stm/list.h
@@ -125,6 +125,7 @@
 
 struct tree_s {
     char *raw_start, *raw_current, *raw_end;
+    uintptr_t count;
     wlog_node_t toplevel;
 };
 
@@ -137,12 +138,16 @@
     return tree->raw_current == tree->raw_start;
 }
 
+static inline uintptr_t tree_count(struct tree_s *tree) {
+    return tree->count;
+}
+
 #define _TREE_LOOP(tree, item, INITIAL, _PLUS_)                         \
 {                                                                       \
   struct { char **next; char **end; } _stack[TREE_DEPTH_MAX], *_stackp; \
   char **_next, **_end, *_entry;                                        \
   long _deleted_factor = 0;                                             \
-  struct tree_s *_tree = &(tree);                                       \
+  struct tree_s *_tree = (tree);                                       \
   /* initialization */                                                  \
   _stackp = _stack;      /* empty stack */                              \
   _next = _tree->toplevel.items + INITIAL;                              \
@@ -189,12 +194,12 @@
 #define TREE_LOOP_END     } }
 #define TREE_LOOP_END_AND_COMPRESS                                       \
                          } if (_deleted_factor > 9) _tree_compress(_tree); }
-#define TREE_LOOP_DELETE(item)  { (item)->addr = NULL; _deleted_factor += 6; }
+#define TREE_LOOP_DELETE(tree, item)  { (tree)->count--; (item)->addr = NULL; _deleted_factor += 6; }
 
 #define TREE_FIND(tree, addr1, result, goto_not_found)          \
 {                                                               \
   uintptr_t _key = TREE_HASH(addr1);                            \
-  char *_p = (char *)((tree).toplevel.items);                   \
+  char *_p = (char *)((tree)->toplevel.items);                   \
   char *_entry = *(char **)(_p + (_key & TREE_MASK));           \
   if (_entry == NULL)                                           \
     goto_not_found;    /* common case, hopefully */             \
@@ -208,10 +213,11 @@
 static void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val);
 static bool tree_delete_item(struct tree_s *tree, uintptr_t addr)
      __attribute__((unused));
+static wlog_t *tree_item(struct tree_s *tree, int index); /* SLOW */
 
 static inline bool tree_contains(struct tree_s *tree, uintptr_t addr)
 {
     wlog_t *result;
-    TREE_FIND(*tree, addr, result, return false);
+    TREE_FIND(tree, addr, result, return false);
     return true;
 }
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -48,7 +48,7 @@
 {
     if (STM_PSEGMENT->modified_old_objects == NULL)
         return -1;
-    return list_count(STM_PSEGMENT->modified_old_objects);
+    return tree_count(STM_PSEGMENT->modified_old_objects);
 }
 
 long _stm_count_objects_pointing_to_nursery(void)
@@ -60,8 +60,8 @@
 
 object_t *_stm_enum_modified_old_objects(long index)
 {
-    return (object_t *)list_item(
-        STM_PSEGMENT->modified_old_objects, index);
+    wlog_t* entry = tree_item(STM_PSEGMENT->modified_old_objects, index);
+    return (object_t*)entry->addr;
 }
 
 object_t *_stm_enum_objects_pointing_to_nursery(long index)
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -130,7 +130,7 @@
         assert(0 <= i && i < 255);   /* 255 is WL_VISITED in gcpage.c */
         pr->pub.segment_num = i;
         pr->pub.segment_base = segment_base;
-        pr->modified_old_objects = list_create();
+        pr->modified_old_objects = tree_create();
         pr->objects_pointing_to_nursery = list_create();
         pr->last_commit_log_entry = &commit_log_root;
         pr->pub.transaction_read_version = 0xff;
@@ -162,7 +162,7 @@
         struct stm_priv_segment_info_s *pr = get_priv_segment(i);
         assert(list_is_empty(pr->objects_pointing_to_nursery));
         list_free(pr->objects_pointing_to_nursery);
-        list_free(pr->modified_old_objects);
+        tree_free(pr->modified_old_objects);
     }
 
     munmap(stm_object_pages, TOTAL_MEMORY);


More information about the pypy-commit mailing list