[pypy-commit] stmgc c7-refactor: Adapt demo2.c.

arigo noreply at buildbot.pypy.org
Wed Feb 19 06:43:33 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r771:c07b26b32fb1
Date: 2014-02-19 06:43 +0100
http://bitbucket.org/pypy/stmgc/changeset/c07b26b32fb1/

Log:	Adapt demo2.c.

diff --git a/c7/Makefile b/c7/Makefile
--- a/c7/Makefile
+++ b/c7/Makefile
@@ -14,16 +14,14 @@
 	rm -f $(BUILD_EXE) $(DEBUG_EXE) $(RELEASE_EXE)
 
 
-H_FILES = core.h list.h pagecopy.h reader_writer_lock.h stmsync.h pages.h nursery.h largemalloc.h
+H_FILES = stmgc.h stm/*.h
+C_FILES = stmgc.c stm/*.c
 
-C_FILES = core.c list.c pagecopy.c reader_writer_lock.c stmsync.c pages.c nursery.c largemalloc.c
 
-DEBUG = -g 
-
-
-# note that we don't say -DNDEBUG, so that asserts should still be compiled in
-# also, all debug code with extra checks but not the debugprints
-build-%: %.c ${H_FILES} ${C_FILES} 
-	clang -pthread  -g -O1  $< -o build-$* -Wall ${C_FILES}
-release-%: %.c ${H_FILES} ${C_FILES} 
-	clang -pthread  -g -DNDEBUG -O2 $< -o release-$* -Wall ${C_FILES}
+# note that 'build' is optimized but still contains all asserts
+debug-%: %.c ${H_FILES} ${C_FILES}
+	clang -pthread  -g  $< -o debug-$* -Wall -Werror  stmgc.c
+build-%: %.c ${H_FILES} ${C_FILES}
+	clang -pthread  -g -O1  $< -o build-$* -Wall  stmgc.c
+release-%: %.c ${H_FILES} ${C_FILES}
+	clang -pthread  -g -DNDEBUG -O2 $< -o release-$* -Wall  stmgc.c
diff --git a/c7/demo2.c b/c7/demo2.c
--- a/c7/demo2.c
+++ b/c7/demo2.c
@@ -4,8 +4,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 
-#include "core.h"
-#include "stmsync.h"
+#include "stmgc.h"
 
 #define LIST_LENGTH 6000
 #define BUNCH       400
@@ -20,8 +19,13 @@
     nodeptr_t next;
 };
 
+__thread stm_thread_local_t stm_thread_local;
 
-size_t stmcb_size(struct object_s *ob)
+#define PUSH_ROOT(p)   (void)0 // XXX...
+#define POP_ROOT(p)    (void)0 // XXX...
+
+
+ssize_t stmcb_size_rounded_up(struct object_s *ob)
 {
     return sizeof(struct node_s);
 }
@@ -34,97 +38,88 @@
 }
 
 
-nodeptr_t global_chained_list = NULL;
+nodeptr_t global_chained_list;
 
 
-long check_sorted()
+long check_sorted(void)
 {
     nodeptr_t r_n;
     long prev, sum;
-    jmpbufptr_t here;
+    stm_jmpbuf_t here;
 
- back:
-    if (__builtin_setjmp(here) == 0) {
-        stm_start_transaction(&here);
-        
-        stm_read((objptr_t)global_chained_list);
-        r_n = global_chained_list;
-        assert(r_n->value == -1);
-    
-        prev = -1;
-        sum = 0;
-        while (r_n->next) {
-            r_n = r_n->next;
-            stm_read((objptr_t)r_n);
-            sum += r_n->value;
+    STM_START_TRANSACTION(&stm_thread_local, here);
 
-            _stm_start_safe_point(0);
-            _stm_stop_safe_point(0);
-            if (prev >= r_n->value) {
-                stm_stop_transaction();
-                return -1;
-            }
-        
-            prev = r_n->value;
+    stm_read((objptr_t)global_chained_list);
+    r_n = global_chained_list;
+    assert(r_n->value == -1);
+
+    prev = -1;
+    sum = 0;
+    while (r_n->next) {
+        r_n = r_n->next;
+        stm_read((objptr_t)r_n);
+        sum += r_n->value;
+
+        stm_safe_point();
+        if (prev >= r_n->value) {
+            stm_commit_transaction();
+            return -1;
         }
 
-        stm_stop_transaction();
-        return sum;
+        prev = r_n->value;
     }
-    goto back;
+
+    stm_commit_transaction();
+    return sum;
 }
 
 nodeptr_t swap_nodes(nodeptr_t initial)
 {
-    jmpbufptr_t here;
+    stm_jmpbuf_t here;
 
     assert(initial != NULL);
- back:
-    if (__builtin_setjmp(here) == 0) {
-        stm_start_transaction(&here);
-        nodeptr_t prev = initial;
-        stm_read((objptr_t)prev);
-        
-        int i;
-        for (i=0; i<BUNCH; i++) {
-            nodeptr_t current = prev->next;
-            if (current == NULL) {
-                stm_stop_transaction();
-                return NULL;
-            }
-            stm_read((objptr_t)current);
-            nodeptr_t next = current->next;
-            if (next == NULL) {
-                stm_stop_transaction();
-                return NULL;
-            }
-            stm_read((objptr_t)next);
-            
-            if (next->value < current->value) {
-                stm_write((objptr_t)prev);
-                stm_write((objptr_t)current);
-                stm_write((objptr_t)next);
-                
-                prev->next = next;
-                current->next = next->next;
-                next->next = current;
 
-                _stm_start_safe_point(0);
-                _stm_stop_safe_point(0);
-            }
-            prev = current;
+    STM_START_TRANSACTION(&stm_thread_local, here);
+
+    nodeptr_t prev = initial;
+    stm_read((objptr_t)prev);
+
+    int i;
+    for (i=0; i<BUNCH; i++) {
+        nodeptr_t current = prev->next;
+        if (current == NULL) {
+            stm_commit_transaction();
+            return NULL;
         }
+        stm_read((objptr_t)current);
+        nodeptr_t next = current->next;
+        if (next == NULL) {
+            stm_commit_transaction();
+            return NULL;
+        }
+        stm_read((objptr_t)next);
 
-        stm_stop_transaction();
-        return prev;
+        if (next->value < current->value) {
+            stm_write((objptr_t)prev);
+            stm_write((objptr_t)current);
+            stm_write((objptr_t)next);
+
+            prev->next = next;
+            current->next = next->next;
+            next->next = current;
+
+            stm_safe_point();
+        }
+        prev = current;
     }
-    goto back;
+
+    stm_commit_transaction();
+    return prev;
 }
 
 
 
-
-void bubble_run()
+void bubble_run(void)
 {
     nodeptr_t r_current;
 
@@ -136,25 +131,25 @@
 
 
 /* initialize list with values in decreasing order */
-void setup_list()
+void setup_list(void)
 {
     int i;
     nodeptr_t w_newnode, w_prev;
 
-    stm_start_transaction(NULL);
+    stm_start_inevitable_transaction(&stm_thread_local);
 
     global_chained_list = (nodeptr_t)stm_allocate(sizeof(struct node_s));
     global_chained_list->value = -1;
     global_chained_list->next = NULL;
-    
-    stm_push_root((objptr_t)global_chained_list);
-    
+
+    PUSH_ROOT(global_chained_list);
+
     w_prev = global_chained_list;
     for (i = 0; i < LIST_LENGTH; i++) {
-        stm_push_root((objptr_t)w_prev);
+        PUSH_ROOT(w_prev);
         w_newnode = (nodeptr_t)stm_allocate(sizeof(struct node_s));
-        
-        w_prev = (nodeptr_t)stm_pop_root();
+
+        POP_ROOT(w_prev);
         w_newnode->value = LIST_LENGTH - i;
         w_newnode->next = NULL;
 
@@ -163,44 +158,31 @@
         w_prev = w_newnode;
     }
 
-    _stm_minor_collect();       /* hack.. */
-    global_chained_list = (nodeptr_t)stm_pop_root();
-    
-    stm_stop_transaction();
+    //_stm_minor_collect();       /* hack.. */
+    //POP_ROOT(global_chained_list); --- remains in the shadowstack
 
-    
-    
+    stm_commit_transaction();
+
+
     printf("setup ok\n");
 }
 
 
 static sem_t done;
-static sem_t go;
-static sem_t initialized;
 
 
 void *demo2(void *arg)
 {
-    
     int status;
-    if (arg != NULL) {
-        /* we still need to initialize */
-        stm_setup_pthread();
-        sem_post(&initialized);
-        status = sem_wait(&go);
-        assert(status == 0);
-    }
-    
+    stm_register_thread_local(&stm_thread_local);
+
     while (check_sorted() == -1) {
         bubble_run();
     }
 
-    if (arg != NULL) {
-        status = sem_post(&done);
-        assert(status == 0);
-        stm_teardown_pthread();
-    }
-    
+    assert(stm_thread_local.shadowstack == stm_thread_local.shadowstack_base);
+    stm_unregister_thread_local(&stm_thread_local);
+    status = sem_post(&done); assert(status == 0);
     return NULL;
 }
 
@@ -236,32 +218,22 @@
 {
     int status;
 
-    status = sem_init(&initialized, 0, 0);
-    assert(status == 0);
-    status = sem_init(&go, 0, 0);
-    assert(status == 0);
-    
+    status = sem_init(&done, 0, 0); assert(status == 0);
+
     stm_setup();
-    stm_setup_pthread();
-    
-    newthread(demo2, (void*)1);
-
-    status = sem_wait(&initialized);
-    assert(status == 0);
+    stm_register_thread_local(&stm_thread_local);
 
     setup_list();
 
-    status = sem_post(&go);
-    assert(status == 0);
-    
-    demo2(NULL);
-    
-    status = sem_wait(&done);
-    assert(status == 0);
-    
+    newthread(demo2, (void*)1);
+    newthread(demo2, (void*)2);
+
+    status = sem_wait(&done); assert(status == 0);
+    status = sem_wait(&done); assert(status == 0);
+
     final_check();
 
-    stm_teardown_pthread();
+    stm_unregister_thread_local(&stm_thread_local);
     stm_teardown();
 
     return 0;
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -199,7 +199,7 @@
     /* may collect! */
     STM_SEGMENT->nursery_current -= size_rounded_up;  /* restore correct val */
 
-    if (collectable_safe_point())
+    if (_stm_collectable_safe_point())
         return (stm_char *)stm_allocate(size_rounded_up);
 
     if (size_rounded_up < MEDIUM_OBJECT) {
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -3,6 +3,10 @@
 #define NSE_SIGNAL        1
 #define NSE_SIGNAL_DONE   2
 
+#if _STM_NSE_SIGNAL != NSE_SIGNAL
+# error "adapt _STM_NSE_SIGNAL"
+#endif
+
 /* Rules for 'v_nursery_section_end':
 
    - Its main purpose is to be read by the owning thread in stm_allocate().
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -266,7 +266,7 @@
     return true;
 }
 
-static bool collectable_safe_point(void)
+bool _stm_collectable_safe_point(void)
 {
     bool any_operation = false;
  restart:;
diff --git a/c7/stm/sync.h b/c7/stm/sync.h
--- a/c7/stm/sync.h
+++ b/c7/stm/sync.h
@@ -17,4 +17,3 @@
 
 /* see the source for an exact description */
 static bool try_wait_for_other_safe_points(int requested_safe_point_kind);
-static bool collectable_safe_point(void);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -82,6 +82,7 @@
 stm_char *_stm_allocate_slowpath(ssize_t);
 void _stm_become_inevitable(char*);
 void _stm_start_transaction(stm_thread_local_t *, stm_jmpbuf_t *);
+bool _stm_collectable_safe_point(void);
 
 #ifdef STM_TESTS
 bool _stm_was_read(object_t *obj);
@@ -100,6 +101,7 @@
 #endif
 
 #define _STM_GCFLAG_WRITE_BARRIER_CALLED  0x80
+#define _STM_NSE_SIGNAL                   1
 #define STM_FLAGS_PREBUILT                0
 
 
@@ -208,13 +210,13 @@
 void stm_register_thread_local(stm_thread_local_t *tl);
 void stm_unregister_thread_local(stm_thread_local_t *tl);
 
-/* Starting and ending transactions.  You should only call stm_read(),
-   stm_write() and stm_allocate() from within a transaction.  Use
-   the macro STM_START_TRANSACTION() to start a transaction that
+/* Starting and ending transactions.  stm_read(), stm_write() and
+   stm_allocate() should only be called from within a transaction.
+   Use the macro STM_START_TRANSACTION() to start a transaction that
    can be restarted using the 'jmpbuf' (a local variable of type
    stm_jmpbuf_t). */
 #define STM_START_TRANSACTION(tl, jmpbuf)  ({           \
-    int _restart = __builtin_setjmp(&jmpbuf);           \
+    int _restart = __builtin_setjmp(jmpbuf);            \
     _stm_start_transaction(tl, &jmpbuf);                \
    _restart;                                            \
 })
@@ -239,6 +241,13 @@
         _stm_become_inevitable(msg);
 }
 
+/* Forces a safe-point if needed.  Normally not needed: this is
+   automatic if you call stm_allocate(). */
+static inline void stm_safe_point(void) {
+    if (STM_SEGMENT->v_nursery_section_end == _STM_NSE_SIGNAL)
+        _stm_collectable_safe_point();
+}
+
 
 /* ==================== END ==================== */
 


More information about the pypy-commit mailing list