[pypy-commit] stmgc c7: getting closer

arigo noreply at buildbot.pypy.org
Sat Jan 18 16:48:11 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7
Changeset: r641:1de3c5245ed2
Date: 2014-01-18 16:29 +0100
http://bitbucket.org/pypy/stmgc/changeset/1de3c5245ed2/

Log:	getting closer

diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -124,7 +124,8 @@
 void _stm_stop_safe_point(void);
 
 void stm_abort_transaction(void);
+
+#define stm_become_inevitable(msg)   /* XXX implement me! */
+
+
 #endif
-
-
-
diff --git a/duhton/duhton.c b/duhton/duhton.c
--- a/duhton/duhton.c
+++ b/duhton/duhton.c
@@ -42,17 +42,22 @@
             printf("))) ");
             fflush(stdout);
         }
+        stm_start_transaction(NULL);
         DuObject *code = Du_Compile(filename, interactive);
+        stm_stop_transaction();
         if (code == NULL) {
             printf("\n");
             break;
         }
         /*Du_Print(code, 1);
           printf("\n");*/
+        stm_start_transaction(NULL);
         DuObject *res = Du_Eval(code, Du_Globals);
         if (interactive) {
             Du_Print(res, 1);
         }
+        stm_stop_transaction();
+
         Du_TransactionRun();
         if (!interactive)
             break;
diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -610,16 +610,30 @@
 }
 
 extern void init_prebuilt_frame_objects(void);
+extern void init_prebuilt_list_objects(void);
+extern void init_prebuilt_object_objects(void);
+extern void init_prebuilt_symbol_objects(void);
+extern void init_prebuilt_transaction_objects(void);
 
 void Du_Initialize(int num_threads)
 {
-    stm_initialize();
+    assert(num_threads == 2);
 
+    stm_setup();
+    stm_setup_thread();
+    stm_setup_thread();
+    _stm_restore_local_state(0);
+
+    init_prebuilt_object_objects();
+    init_prebuilt_symbol_objects();
+    init_prebuilt_list_objects();
     init_prebuilt_frame_objects();
+    init_prebuilt_transaction_objects();
 
     all_threads_count = num_threads;
     all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads);
 
+    stm_start_transaction(NULL);
     DuFrame_SetBuiltinMacro(Du_Globals, "progn", Du_Progn);
     DuFrame_SetBuiltinMacro(Du_Globals, "setq", du_setq);
     DuFrame_SetBuiltinMacro(Du_Globals, "print", du_print);
@@ -655,9 +669,16 @@
     DuFrame_SetBuiltinMacro(Du_Globals, "pair?", du_pair);
     DuFrame_SetBuiltinMacro(Du_Globals, "assert", du_assert);
     DuFrame_SetSymbolStr(Du_Globals, "None", Du_None);
+    stm_stop_transaction();
 }
 
 void Du_Finalize(void)
 {
-    stm_finalize();
+    _stm_restore_local_state(1);
+    _stm_teardown_thread();
+
+    _stm_restore_local_state(0);
+    _stm_teardown_thread();
+
+    _stm_teardown();
 }
diff --git a/duhton/intobject.c b/duhton/intobject.c
--- a/duhton/intobject.c
+++ b/duhton/intobject.c
@@ -1,7 +1,7 @@
 #include "duhton.h"
 
-typedef struct {
-    DuOBJECT_HEAD
+typedef TLPREFIX struct DuIntObject_s {
+    DuOBJECT_HEAD1
     int ob_intval;
 } DuIntObject;
 
diff --git a/duhton/listobject.c b/duhton/listobject.c
--- a/duhton/listobject.c
+++ b/duhton/listobject.c
@@ -5,34 +5,34 @@
 /* 'tuple' objects are only used internally as the current items
    of 'list' objects
 */
-typedef struct {
-    DuOBJECT_HEAD
+typedef TLPREFIX struct DuTupleObject_s {
+    DuOBJECT_HEAD1
     int ob_count;
     DuObject *ob_items[1];
 } DuTupleObject;
 
-typedef struct {
-    DuOBJECT_HEAD
+typedef TLPREFIX struct DuListObject_s {
+    DuOBJECT_HEAD1
     DuTupleObject *ob_tuple;
 } DuListObject;
 
 
-void tuple_trace(DuTupleObject *ob, void visit(gcptr *))
+void tuple_trace(struct DuTupleObject_s *ob, void visit(object_t **))
 {
     int i;
     for (i=ob->ob_count-1; i>=0; i--) {
-        visit(&ob->ob_items[i]);
+        visit((object_t **)&ob->ob_items[i]);
     }
 }
 
-size_t tuple_bytesize(DuTupleObject *ob)
+size_t tuple_bytesize(struct DuTupleObject_s *ob)
 {
     return sizeof(DuTupleObject) + (ob->ob_count - 1) * sizeof(DuObject *);
 }
 
-void list_trace(DuListObject *ob, void visit(gcptr *))
+void list_trace(struct DuListObject_s *ob, void visit(object_t **))
 {
-    visit((gcptr *)&ob->ob_tuple);
+    visit((object_t **)&ob->ob_tuple);
 }
 
 void list_print(DuListObject *ob)
@@ -68,7 +68,8 @@
 {
     DuTupleObject *ob;
     size_t size = sizeof(DuTupleObject) + (length-1)*sizeof(DuObject *);
-    ob = (DuTupleObject *)stm_allocate(size, DUTYPE_TUPLE);
+    ob = (DuTupleObject *)stm_allocate(size);
+    ob->ob_base.type_id = DUTYPE_TUPLE;
     ob->ob_count = length;
     return ob;
 }
@@ -187,10 +188,18 @@
 
 static DuTupleObject *du_empty_tuple;
 
+void init_prebuilt_list_objects(void)
+{
+    du_empty_tuple = (DuTupleObject *)
+        stm_allocate_prebuilt(sizeof(DuTupleObject));
+    du_empty_tuple->ob_base.type_id = DUTYPE_TUPLE;
+    du_empty_tuple->ob_count = 0;
+}
+
 DuObject *DuList_New()
 {
     DuListObject *ob = (DuListObject *)DuObject_New(&DuList_Type);
-    ob->ob_tuple = &du_empty_tuple;
+    ob->ob_tuple = du_empty_tuple;
     return (DuObject *)ob;
 }
 
diff --git a/duhton/object.c b/duhton/object.c
--- a/duhton/object.c
+++ b/duhton/object.c
@@ -39,8 +39,9 @@
 DuObject *DuObject_New(DuType *tp)
 {
     assert(tp->dt_size >= sizeof(DuObject));
-    DuObject *ob = stm_allocate(tp->dt_size, tp->dt_typeindex);
+    DuObject *ob = (DuObject *)stm_allocate(tp->dt_size);
     assert(ob);
+    ob->type_id = tp->dt_typeindex;
     return ob;
 }
 
@@ -64,8 +65,13 @@
     none_is_true,
 };
 
-DuObject _Du_NoneStruct =
-    DuOBJECT_HEAD_INIT(DUTYPE_NONE);
+DuObject *Du_None;
+
+void init_prebuilt_object_objects(void)
+{
+    Du_None = (DuObject *)stm_allocate_prebuilt(sizeof(DuObject));
+    Du_None->type_id = DUTYPE_NONE;
+}
 
 void Du_FatalError(char *msg, ...)
 {
diff --git a/duhton/symbol.c b/duhton/symbol.c
--- a/duhton/symbol.c
+++ b/duhton/symbol.c
@@ -2,22 +2,21 @@
 #include <stdlib.h>
 #include "duhton.h"
 
-typedef struct _Du_Symbol {
-    DuOBJECT_HEAD
+typedef TLPREFIX struct DuSymbolObject_s DuSymbolObject;
+
+struct DuSymbolObject_s {
+    DuOBJECT_HEAD1
     int myid;
     char *name;
-    struct _Du_Symbol *next;
-} DuSymbolObject;
+    DuSymbolObject *next;
+};
 
-static DuSymbolObject _Du_AllSymbols = {
-    DuOBJECT_HEAD_INIT(DUTYPE_SYMBOL),
-    "",
-    NULL};
+static DuSymbolObject *_Du_AllSymbols;
 
 
-void symbol_trace(DuSymbolObject *ob, void visit(gcptr *))
+void symbol_trace(struct DuSymbolObject_s *ob, void visit(object_t **))
 {
-    visit((gcptr *)&ob->next);
+    visit((object_t **)&ob->next);
 }
 
 void symbol_print(DuSymbolObject *ob)
@@ -54,9 +53,19 @@
 
 static int next_id = 1;
 
+void init_prebuilt_symbol_objects(void)
+{
+    _Du_AllSymbols = (DuSymbolObject *)
+        stm_allocate_prebuilt(sizeof(DuSymbolObject));
+    _Du_AllSymbols->ob_base.type_id = DUTYPE_SYMBOL;
+    _Du_AllSymbols->myid = 0;
+    _Du_AllSymbols->name = "";
+    _Du_AllSymbols->next = NULL;
+}
+
 DuObject *DuSymbol_FromString(const char *name)
 {
-    DuSymbolObject *p, *head = &_Du_AllSymbols;
+    DuSymbolObject *p, *head = _Du_AllSymbols;
     for (p=head; p != NULL; p=p->next) {
         _du_read1(p);
         if (strcmp(name, p->name) == 0) {
@@ -84,7 +93,7 @@
 int DuSymbol_Id(DuObject *ob)
 {
     DuSymbol_Ensure("DuSymbol_Id", ob);
-    return ((DuSymbolObject *)ob)->id;
+    return ((DuSymbolObject *)ob)->myid;
 }
 
 void DuSymbol_Ensure(char *where, DuObject *ob)
diff --git a/duhton/transaction.c b/duhton/transaction.c
--- a/duhton/transaction.c
+++ b/duhton/transaction.c
@@ -3,14 +3,21 @@
 #include <unistd.h>
 
 
-static DuConsObject du_pending_transactions = {
-    DuOBJECT_HEAD_INIT(DUTYPE_CONS),
-    NULL,
-    Du_None,
+static DuConsObject *du_pending_transactions;
+
+void init_prebuilt_transaction_objects(void)
+{
+    assert(Du_None);   /* already created */
+
+    du_pending_transactions = (DuConsObject *)
+        stm_allocate_prebuilt(sizeof(DuConsObject));
+    du_pending_transactions->ob_base.type_id = DUTYPE_CONS;
+    du_pending_transactions->car = NULL;
+    du_pending_transactions->cdr = Du_None;
 };
 
 static pthread_mutex_t mutex_sleep = PTHREAD_MUTEX_INITIALIZER;
-static int thread_sleeping = 0;
+static int volatile thread_sleeping = 0;
 
 static void *run_thread(void *);   /* forward */
 
@@ -18,9 +25,12 @@
 {
     int i;
     for (i = 0; i < all_threads_count; i++) {
-        int status = pthread_create(&all_threads[i], NULL, run_thread, NULL);
-        if (status != 0)
-            stm_fatalerror("status != 0\n");
+        int status = pthread_create(&all_threads[i], NULL, run_thread,
+                                    (void *)(uintptr_t)i);
+        if (status != 0) {
+            fprintf(stderr, "status != 0\n");
+            abort();
+        }
     }
     for (i = 0; i < all_threads_count; i++) {
         pthread_join(all_threads[i], NULL);
@@ -29,16 +39,19 @@
 
 /************************************************************/
 
+__thread DuObject *stm_thread_local_obj = NULL;  /* XXX temp */
+
+
 void Du_TransactionAdd(DuObject *code, DuObject *frame)
 {
     DuObject *cell = DuCons_New(code, frame);
-    DuObject *pending = (DuObject *)stm_thread_local_obj;
+    DuObject *pending = stm_thread_local_obj;
 
     if (pending == NULL) {
         pending = Du_None;
     }
     pending = DuCons_New(cell, pending);
-    stm_thread_local_obj = (gcptr)pending;
+    stm_thread_local_obj = pending;
 }
 
 void Du_TransactionRun(void)
@@ -46,27 +59,32 @@
     if (stm_thread_local_obj == NULL)
         return;
 
-    DuConsObject *root = &du_pending_transactions;
+    stm_start_transaction(NULL);
+    DuConsObject *root = du_pending_transactions;
     _du_write1(root);
     root->cdr = stm_thread_local_obj;
+    stm_stop_transaction();
+    stm_thread_local_obj = NULL;
 
-    stm_commit_transaction();
     run_all_threads();
-    stm_begin_inevitable_transaction();
 }
 
 /************************************************************/
 
 static DuObject *next_cell(void)
 {
-    DuObject *pending = (DuObject *)stm_thread_local_obj;
+    DuObject *pending = stm_thread_local_obj;
+    jmpbufptr_t here;
 
     if (pending == NULL) {
         /* fish from the global list of pending transactions */
         DuConsObject *root;
 
+        while (__builtin_setjmp(here) == 1) { }
       restart:
-        root = &du_pending_transactions;
+        stm_start_transaction(&here);
+
+        root = du_pending_transactions;
         _du_read1(root);
 
         if (root->cdr != Du_None) {
@@ -77,22 +95,30 @@
             DuObject *result = _DuCons_CAR(cell);
             root->cdr = _DuCons_NEXT(cell);
 
+            stm_stop_transaction();
+
             return result;
         }
         else {
+            stm_stop_transaction();
+
             /* nothing to do, wait */
-            thread_sleeping++;
-            if (thread_sleeping == all_threads_count) {
+            int ts = __sync_add_and_fetch(&thread_sleeping, 1);
+            if (ts == all_threads_count) {
                 pthread_mutex_unlock(&mutex_sleep);
             }
-            stm_commit_transaction();
             pthread_mutex_lock(&mutex_sleep);
-            stm_begin_inevitable_transaction();
-            if (thread_sleeping == all_threads_count) {
-                pthread_mutex_unlock(&mutex_sleep);
-                return NULL;
+
+            while (1) {
+                ts = thread_sleeping;
+                if (ts == all_threads_count) {
+                    pthread_mutex_unlock(&mutex_sleep);
+                    return NULL;
+                }
+                assert(ts > 0);
+                if (__sync_bool_compare_and_swap(&thread_sleeping, ts, ts - 1))
+                    break;
             }
-            thread_sleeping--;
             goto restart;
         }
     }
@@ -100,6 +126,9 @@
     /* we have at least one thread-local transaction pending */
     stm_thread_local_obj = NULL;
 
+    while (__builtin_setjmp(here) == 1) { }
+    stm_start_transaction(&here);
+
     _du_read1(pending);
     DuObject *result = _DuCons_CAR(pending);
     DuObject *next = _DuCons_NEXT(pending);
@@ -116,36 +145,43 @@
             tail = tailnext;
         }
 
-        DuConsObject * root = &du_pending_transactions;
+        DuConsObject * root = du_pending_transactions;
         _du_write1(tail);
         _du_write1(root);
         ((DuConsObject *)tail)->cdr = root->cdr;
         root->cdr = next;
     }
 
+    stm_stop_transaction();
+
     return result;
 }
 
-int run_transaction(gcptr cell, int retry_counter)
+void run_transaction(DuObject *cell)
 {
     DuObject *code  = DuCons_Car(cell);
     DuObject *frame = DuCons_Cdr(cell);
     Du_Progn(code, frame);
-    return 0;
 }
 
-void *run_thread(void *ignored)
+void *run_thread(void *thread_id)
 {
-    stm_initialize();
+    jmpbufptr_t here;
+    int thread_num = (uintptr_t)thread_id;
+    _stm_restore_local_state(thread_num);
+    stm_thread_local_obj = NULL;
 
     while (1) {
-        /* we are inevitable here */
         DuObject *cell = next_cell();
         if (cell == NULL)
             break;
-        stm_perform_transaction(cell, run_transaction);
+        assert(stm_thread_local_obj == NULL);
+
+        while (__builtin_setjmp(here) == 1) { }
+        stm_start_transaction(&here);
+        run_transaction(cell);
+        stm_stop_transaction();
     }
 
-    stm_finalize();
     return NULL;
 }


More information about the pypy-commit mailing list