Author: Armin Rigo <ar...@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; } _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit