[pypy-commit] stmgc c8-gil-like: in-progress
arigo
noreply at buildbot.pypy.org
Thu Jun 11 22:32:40 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: c8-gil-like
Changeset: r1805:ea72e4a504fd
Date: 2015-06-11 16:22 +0200
http://bitbucket.org/pypy/stmgc/changeset/ea72e4a504fd/
Log: in-progress
diff --git a/c8/demo/demo_random.c b/c8/demo/demo_random.c
--- a/c8/demo/demo_random.c
+++ b/c8/demo/demo_random.c
@@ -57,9 +57,16 @@
}
+long check_size(long size)
+{
+ assert(size >= sizeof(struct node_s));
+ assert(size <= sizeof(struct node_s) + 4096*70);
+ return size;
+}
+
ssize_t stmcb_size_rounded_up(struct object_s *ob)
{
- return ((struct node_s*)ob)->my_size;
+ return check_size(((struct node_s*)ob)->my_size);
}
void stmcb_trace(struct object_s *obj, void visit(object_t **))
@@ -69,7 +76,8 @@
/* and the same value at the end: */
/* note, ->next may be the same as last_next */
- nodeptr_t *last_next = (nodeptr_t*)((char*)n + n->my_size - sizeof(void*));
+ nodeptr_t *last_next = (nodeptr_t*)((char*)n + check_size(n->my_size)
+ - sizeof(void*));
assert(n->next == *last_next);
@@ -113,36 +121,36 @@
}
}
-void reload_roots()
-{
- int i;
- assert(td.num_roots == td.num_roots_at_transaction_start);
- for (i = td.num_roots_at_transaction_start - 1; i >= 0; i--) {
- if (td.roots[i])
- STM_POP_ROOT(stm_thread_local, td.roots[i]);
- }
-
- for (i = 0; i < td.num_roots_at_transaction_start; i++) {
- if (td.roots[i])
- STM_PUSH_ROOT(stm_thread_local, td.roots[i]);
- }
-}
-
void push_roots()
{
int i;
+ assert(td.num_roots_at_transaction_start <= td.num_roots);
for (i = td.num_roots_at_transaction_start; i < td.num_roots; i++) {
if (td.roots[i])
STM_PUSH_ROOT(stm_thread_local, td.roots[i]);
}
+ STM_SEGMENT->no_safe_point_here = 0;
}
void pop_roots()
{
int i;
- for (i = td.num_roots - 1; i >= td.num_roots_at_transaction_start; i--) {
- if (td.roots[i])
+ STM_SEGMENT->no_safe_point_here = 1;
+
+ assert(td.num_roots_at_transaction_start <= td.num_roots);
+ for (i = td.num_roots - 1; i >= 0; i--) {
+ if (td.roots[i]) {
STM_POP_ROOT(stm_thread_local, td.roots[i]);
+ assert(td.roots[i]);
+ }
+ }
+
+ fprintf(stderr, "stm_is_inevitable() = %d\n", (int)stm_is_inevitable());
+ for (i = 0; i < td.num_roots_at_transaction_start; i++) {
+ if (td.roots[i]) {
+ fprintf(stderr, "root %d: %p\n", i, td.roots[i]);
+ STM_PUSH_ROOT(stm_thread_local, td.roots[i]);
+ }
}
}
@@ -150,6 +158,7 @@
{
int i;
assert(idx >= td.num_roots_at_transaction_start);
+ assert(idx < td.num_roots);
for (i = idx; i < td.num_roots - 1; i++)
td.roots[i] = td.roots[i + 1];
@@ -158,6 +167,7 @@
void add_root(objptr_t r)
{
+ assert(td.num_roots_at_transaction_start <= td.num_roots);
if (r && td.num_roots < MAXROOTS) {
td.roots[td.num_roots++] = r;
}
@@ -184,7 +194,8 @@
nodeptr_t n = (nodeptr_t)p;
/* and the same value at the end: */
- nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + n->my_size - sizeof(void*));
+ nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n +
+ check_size(n->my_size) - sizeof(void*));
assert(n->next == *last_next);
n->next = (nodeptr_t)v;
*last_next = (nodeptr_t)v;
@@ -196,7 +207,8 @@
nodeptr_t n = (nodeptr_t)p;
/* and the same value at the end: */
- nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + n->my_size - sizeof(void*));
+ nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n +
+ check_size(n->my_size) - sizeof(void*));
OPT_ASSERT(n->next == *last_next);
return n->next;
@@ -229,7 +241,7 @@
sizeof(struct node_s) + (get_rand(100000) & ~15),
sizeof(struct node_s) + 4096,
sizeof(struct node_s) + 4096*70};
- size_t size = sizes[get_rand(4)];
+ size_t size = check_size(sizes[get_rand(4)]);
p = stm_allocate(size);
nodeptr_t n = (nodeptr_t)p;
n->sig = SIGNATURE;
@@ -240,7 +252,6 @@
n->next = NULL;
*last_next = NULL;
pop_roots();
- /* reload_roots not necessary, all are old after start_transaction */
break;
case 4: // read and validate 'p'
read_barrier(p);
@@ -306,7 +317,9 @@
stm_become_inevitable(&stm_thread_local, "please");
pop_roots();
return NULL;
- } else if (get_rand(240) == 1) {
+ } else if (0 && // XXXXXXXXXXXXXXXXXXXXX
+
+ get_rand(240) == 1) {
push_roots();
stm_become_globally_unique_transaction(&stm_thread_local, "really");
fprintf(stderr, "[GUT/%d]", (int)STM_SEGMENT->segment_num);
@@ -352,13 +365,16 @@
td.num_roots = td.num_roots_at_transaction_start;
p = NULL;
pop_roots(); /* does nothing.. */
- reload_roots();
while (td.steps_left-->0) {
if (td.steps_left % 8 == 0)
fprintf(stdout, "#");
- assert(p == NULL || ((nodeptr_t)p)->sig == SIGNATURE);
+ int local_seg = STM_SEGMENT->segment_num;
+ int p_sig = p == NULL ? 0 : ((nodeptr_t)p)->sig;
+
+ assert(p == NULL || p_sig == SIGNATURE);
+ (void)local_seg;
p = do_step(p);
@@ -366,7 +382,9 @@
push_roots();
long call_fork = (arg != NULL && *(long *)arg);
- if (call_fork == 0) { /* common case */
+ if (1 || // XXXXXXXXXXXXXXXX
+
+ call_fork == 0) { /* common case */
if (get_rand(100) < 50) {
stm_leave_transactional_zone(&stm_thread_local);
/* Nothing here; it's unlikely that a different thread
@@ -386,7 +404,6 @@
td.num_roots = td.num_roots_at_transaction_start;
p = NULL;
pop_roots();
- reload_roots();
}
else {
/* run a fork() inside the transaction */
diff --git a/c8/stm/detach.c b/c8/stm/detach.c
--- a/c8/stm/detach.c
+++ b/c8/stm/detach.c
@@ -32,6 +32,7 @@
void _stm_leave_noninevitable_transactional_zone(void)
{
+ dprintf(("leave_noninevitable_transactional_zone\n"));
_stm_become_inevitable(MSG_INEV_DONT_SLEEP);
/* did it work? */
@@ -61,11 +62,13 @@
disappear. XXX could be done even earlier, as soon as we have
read the shadowstack inside the minor collection. */
STM_SEGMENT->running_thread = NULL;
+
+ _core_commit_transaction();
+
+
write_fence();
assert(_stm_detached_inevitable_from_thread == -1);
_stm_detached_inevitable_from_thread = 0;
-
- _core_commit_transaction();
}
void _stm_reattach_transaction(intptr_t old, stm_thread_local_t *tl)
@@ -75,6 +78,7 @@
if (old == -1) {
/* busy-loop: wait until _stm_detached_inevitable_from_thread
is reset to a value different from -1 */
+ dprintf(("reattach_transaction: busy wait...\n"));
while (_stm_detached_inevitable_from_thread == -1)
spin_loop();
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -309,6 +309,7 @@
else
assert(finalbase <= ssbase && ssbase <= current);
+ dprintf(("collect_roots_in_nursery:\n"));
while (current > ssbase) {
--current;
uintptr_t x = (uintptr_t)current->ss;
@@ -320,6 +321,7 @@
else {
/* it is an odd-valued marker, ignore */
}
+ dprintf((" %p: %p -> %p\n", current, (void *)x, current->ss));
}
minor_trace_if_young(&tl->thread_local_obj);
@@ -519,6 +521,7 @@
static void _do_minor_collection(bool commit)
{
dprintf(("minor_collection commit=%d\n", (int)commit));
+ assert(!STM_SEGMENT->no_safe_point_here);
STM_PSEGMENT->minor_collect_will_commit_now = commit;
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -137,6 +137,9 @@
setup_detach();
set_gs_register(get_segment_base(0));
+
+ dprintf(("nursery: %p -> %p\n", (void *)NURSERY_START,
+ (void *)NURSERY_END));
}
void stm_teardown(void)
diff --git a/c8/stm/sync.c b/c8/stm/sync.c
--- a/c8/stm/sync.c
+++ b/c8/stm/sync.c
@@ -383,6 +383,7 @@
break; /* no safe point requested */
dprintf(("enter safe point\n"));
+ assert(!STM_SEGMENT->no_safe_point_here);
assert(STM_SEGMENT->nursery_end == NSE_SIGPAUSE);
assert(pause_signalled);
@@ -397,6 +398,7 @@
cond_wait(C_REQUEST_REMOVED);
STM_PSEGMENT->safe_point = SP_RUNNING;
timing_event(STM_SEGMENT->running_thread, STM_WAIT_DONE);
+ assert(!STM_SEGMENT->no_safe_point_here);
dprintf(("left safe point\n"));
}
}
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -40,6 +40,7 @@
struct stm_segment_info_s {
uint8_t transaction_read_version;
+ uint8_t no_safe_point_here; /* set from outside, triggers an assert */
int segment_num;
char *segment_base;
stm_char *nursery_current;
@@ -420,10 +421,12 @@
far more efficient than constantly starting and committing
transactions.
*/
+#include <stdio.h>
static inline void stm_enter_transactional_zone(stm_thread_local_t *tl) {
intptr_t old;
atomic_exchange(&_stm_detached_inevitable_from_thread, old, -1);
if (old == (intptr_t)tl) {
+ fprintf(stderr, "stm_enter_transactional_zone fast path\n");
_stm_detached_inevitable_from_thread = 0;
}
else {
@@ -434,10 +437,13 @@
}
static inline void stm_leave_transactional_zone(stm_thread_local_t *tl) {
assert(STM_SEGMENT->running_thread == tl);
- if (stm_is_inevitable())
+ if (stm_is_inevitable()) {
+ fprintf(stderr, "stm_leave_transactional_zone fast path\n");
_stm_detach_inevitable_transaction(tl);
- else
+ }
+ else {
_stm_leave_noninevitable_transactional_zone();
+ }
}
/* stm_force_transaction_break() is in theory equivalent to
@@ -461,8 +467,9 @@
assert(STM_SEGMENT->running_thread == tl);
if (!stm_is_inevitable())
_stm_become_inevitable(msg);
- /* now, we're running the inevitable transaction, so: */
- assert(_stm_detached_inevitable_from_thread == 0);
+ /* now, we're running the inevitable transaction, so this var should
+ be 0 (but can occasionally be -1 for a tiny amount of time) */
+ assert(((_stm_detached_inevitable_from_thread + 1) & ~1) == 0);
}
/* Forces a safe-point if needed. Normally not needed: this is
diff --git a/duhton-c8/duhton.c b/duhton-c8/duhton.c
--- a/duhton-c8/duhton.c
+++ b/duhton-c8/duhton.c
@@ -41,7 +41,8 @@
printf("))) ");
fflush(stdout);
}
- stm_start_inevitable_transaction(&stm_thread_local);
+ stm_enter_transactional_zone(&stm_thread_local);
+ stm_become_inevitable(&stm_thread_local, "starting point");
DuObject *code = Du_Compile(filename, interactive);
if (code == NULL) {
@@ -58,7 +59,7 @@
//stm_collect(0); /* hack... */
//_du_restore1(stm_thread_local_obj);
- stm_commit_transaction();
+ stm_leave_transactional_zone(&stm_thread_local);
Du_TransactionRun();
if (!interactive)
diff --git a/duhton-c8/glob.c b/duhton-c8/glob.c
--- a/duhton-c8/glob.c
+++ b/duhton-c8/glob.c
@@ -713,11 +713,12 @@
//stm_collect(0); /* hack... */
//_du_restore1(stm_thread_local_obj);
- stm_commit_transaction();
+ stm_leave_transactional_zone(&stm_thread_local);
Du_TransactionRun();
- stm_start_inevitable_transaction(&stm_thread_local);
+ stm_enter_transactional_zone(&stm_thread_local);
+ stm_become_inevitable(&stm_thread_local, "run-transactions finished");
return Du_None;
}
@@ -809,7 +810,8 @@
/* prebuilt objs stay on the shadowstack forever */
stm_register_thread_local(&stm_thread_local);
- stm_start_inevitable_transaction(&stm_thread_local);
+ stm_enter_transactional_zone(&stm_thread_local);
+ stm_become_inevitable(&stm_thread_local, "initialization");
all_threads_count = num_threads;
all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads);
@@ -857,7 +859,7 @@
DuFrame_SetBuiltinMacro(Du_Globals, "pair?", du_pair);
DuFrame_SetBuiltinMacro(Du_Globals, "assert", du_assert);
DuFrame_SetSymbolStr(Du_Globals, "None", Du_None);
- stm_commit_transaction();
+ stm_leave_transactional_zone(&stm_thread_local);
}
void Du_Finalize(void)
diff --git a/duhton-c8/transaction.c b/duhton-c8/transaction.c
--- a/duhton-c8/transaction.c
+++ b/duhton-c8/transaction.c
@@ -58,14 +58,14 @@
if (TLOBJ == NULL)
return;
- stm_start_inevitable_transaction(&stm_thread_local);
+ stm_enter_transactional_zone(&stm_thread_local);
DuConsObject *root = du_pending_transactions;
_du_write1(root);
root->cdr = TLOBJ;
TLOBJ = NULL;
- stm_commit_transaction();
+ stm_leave_transactional_zone(&stm_thread_local);
run_all_threads();
}
More information about the pypy-commit
mailing list