[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