Author: Armin Rigo <[email protected]>
Branch: rewind_setjmp
Changeset: r1278:5aef14b3bb77
Date: 2014-08-09 17:06 +0200
http://bitbucket.org/pypy/stmgc/changeset/5aef14b3bb77/
Log: fixing tests, in-progress
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -324,14 +324,14 @@
STM_SEGMENT->transaction_read_version = 1;
}
-void _stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf)
+static void _stm_start_transaction(stm_thread_local_t *tl, bool inevitable)
{
assert(!_stm_in_transaction(tl));
s_mutex_lock();
retry:
- if (jmpbuf == NULL) {
+ if (inevitable) {
wait_for_end_of_inevitable_transaction(tl);
}
@@ -346,11 +346,9 @@
STM_PSEGMENT->signalled_to_commit_soon = false;
STM_PSEGMENT->safe_point = SP_RUNNING;
STM_PSEGMENT->marker_inev[1] = 0;
- if (jmpbuf == NULL)
+ if (inevitable)
marker_fetch_inev();
- STM_PSEGMENT->transaction_state = (jmpbuf != NULL ? TS_REGULAR
- : TS_INEVITABLE);
- STM_SEGMENT->jmpbuf_ptr = jmpbuf;
+ STM_PSEGMENT->transaction_state = (inevitable ? TS_INEVITABLE :
TS_REGULAR);
#ifndef NDEBUG
STM_PSEGMENT->running_pthread = pthread_self();
#endif
@@ -390,6 +388,22 @@
check_nursery_at_transaction_start();
}
+long stm_start_transaction(stm_thread_local_t *tl)
+{
+#ifdef STM_NO_AUTOMATIC_SETJMP
+ long repeat_count = 0; /* test/support.py */
+#else
+ long repeat_count = rewind_jmp_setjmp(&tl->rjthread);
+#endif
+ _stm_start_transaction(tl, false);
+ return repeat_count;
+}
+
+void stm_start_inevitable_transaction(stm_thread_local_t *tl)
+{
+ _stm_start_transaction(tl, true);
+}
+
/************************************************************/
@@ -814,7 +828,7 @@
dprintf(("commit_transaction\n"));
assert(STM_SEGMENT->nursery_end == NURSERY_END);
- STM_SEGMENT->jmpbuf_ptr = NULL;
+ rewind_jmp_forget(&STM_SEGMENT->running_thread->rjthread);
/* if a major collection is required, do it here */
if (is_major_collection_requested()) {
@@ -987,6 +1001,10 @@
#pragma pop_macro("STM_PSEGMENT")
}
+#ifdef STM_NO_AUTOMATIC_SETJMP
+void _test_run_abort(stm_thread_local_t *tl) __attribute__((noreturn));
+#endif
+
static void abort_with_mutex(void)
{
assert(_has_mutex());
@@ -996,10 +1014,9 @@
abort_data_structures_from_segment_num(STM_SEGMENT->segment_num);
- stm_jmpbuf_t *jmpbuf_ptr = STM_SEGMENT->jmpbuf_ptr;
+ stm_thread_local_t *tl = STM_SEGMENT->running_thread;
/* clear memory registered on the thread-local */
- stm_thread_local_t *tl = STM_SEGMENT->running_thread;
if (tl->mem_clear_on_abort)
memset(tl->mem_clear_on_abort, 0, tl->mem_bytes_to_clear_on_abort);
@@ -1035,9 +1052,11 @@
*/
usleep(1);
- assert(jmpbuf_ptr != NULL);
- assert(jmpbuf_ptr != (stm_jmpbuf_t *)-1); /* for tests only */
- __builtin_longjmp(*jmpbuf_ptr, 1);
+#ifdef STM_NO_AUTOMATIC_SETJMP
+ _test_run_abort(tl);
+#else
+ rewind_jmp_longjmp(&tl->rjthread);
+#endif
}
void _stm_become_inevitable(const char *msg)
@@ -1051,12 +1070,11 @@
marker_fetch_inev();
wait_for_end_of_inevitable_transaction(NULL);
STM_PSEGMENT->transaction_state = TS_INEVITABLE;
- STM_SEGMENT->jmpbuf_ptr = NULL;
+ rewind_jmp_forget(&STM_SEGMENT->running_thread->rjthread);
clear_callbacks_on_abort();
}
else {
assert(STM_PSEGMENT->transaction_state == TS_INEVITABLE);
- assert(STM_SEGMENT->jmpbuf_ptr == NULL);
}
s_mutex_unlock();
diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -3,6 +3,9 @@
#endif
+
+#if 0
+
/* XXX this is currently not doing copy-on-write, but simply forces a
copy of all pages as soon as fork() is called. */
@@ -299,3 +302,7 @@
fork_support_ready = true;
}
}
+#endif
+static void setup_forksupport(void) {
+ if (0) _page_do_reshare(0, 0);
+}
diff --git a/c7/stm/rewind_setjmp.c b/c7/stm/rewind_setjmp.c
--- a/c7/stm/rewind_setjmp.c
+++ b/c7/stm/rewind_setjmp.c
@@ -36,7 +36,7 @@
}
__attribute__((noinline))
-int rewind_jmp_setjmp(rewind_jmp_thread *rjthread)
+long rewind_jmp_setjmp(rewind_jmp_thread *rjthread)
{
if (rjthread->moved_off) {
_rewind_jmp_free_stack_slices(rjthread);
@@ -51,13 +51,14 @@
else {
rjthread = rjthread1;
rjthread->head = rjthread->initial_head;
- result = 1;
+ result = rjthread->repeat_count + 1;
}
+ rjthread->repeat_count = result;
copy_stack(rjthread, (char *)&rjthread1);
return result;
}
-__attribute__((noinline))
+__attribute__((noinline, noreturn))
static void do_longjmp(rewind_jmp_thread *rjthread, char *stack_free)
{
assert(rjthread->moved_off_base != NULL);
@@ -78,6 +79,7 @@
__builtin_longjmp(rjthread->jmpbuf, 1);
}
+__attribute__((noreturn))
void rewind_jmp_longjmp(rewind_jmp_thread *rjthread)
{
char _rewind_jmp_marker;
diff --git a/c7/stm/rewind_setjmp.h b/c7/stm/rewind_setjmp.h
--- a/c7/stm/rewind_setjmp.h
+++ b/c7/stm/rewind_setjmp.h
@@ -50,6 +50,7 @@
char *moved_off_base;
struct _rewind_jmp_moved_s *moved_off;
void *jmpbuf[5];
+ long repeat_count;
} rewind_jmp_thread;
@@ -65,8 +66,8 @@
_rewind_jmp_copy_stack_slice(rjthread); \
} while (0)
-int rewind_jmp_setjmp(rewind_jmp_thread *rjthread);
-void rewind_jmp_longjmp(rewind_jmp_thread *rjthread);
+long rewind_jmp_setjmp(rewind_jmp_thread *rjthread);
+void rewind_jmp_longjmp(rewind_jmp_thread *rjthread) __attribute__((noreturn));
#define rewind_jmp_forget(rjthread) do { \
if ((rjthread)->moved_off) _rewind_jmp_free_stack_slices(rjthread); \
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -36,3 +36,4 @@
#include "stm/weakref.c"
#include "stm/timing.c"
#include "stm/marker.c"
+#include "stm/rewind_setjmp.c"
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -77,9 +77,10 @@
#define _STM_MARKER_LEN 80
typedef struct stm_thread_local_s {
- rewind_jmp_thread rjthread;
/* every thread should handle the shadow stack itself */
struct stm_shadowentry_s *shadowstack, *shadowstack_base;
+ /* rewind_setjmp's interface */
+ rewind_jmp_thread rjthread;
/* a generic optional thread-local object */
object_t *thread_local_obj;
/* in case this thread runs a transaction that aborts,
@@ -340,6 +341,7 @@
returned, starting at 0. If it is > 0, then the transaction was
aborted and restarted this number of times. */
long stm_start_transaction(stm_thread_local_t *tl);
+void stm_start_inevitable_transaction(stm_thread_local_t *tl);
void stm_commit_transaction(void);
/* Abort the currently running transaction. This function never
@@ -350,7 +352,7 @@
The stm_become_inevitable() itself may still abort. */
static inline void stm_become_inevitable(stm_thread_local_t *tl,
const char* msg) {
- abort();/* XXX
+ assert(0);/* XXX
assert(STM_SEGMENT->running_thread == tl);
if (STM_SEGMENT->jmpbuf_ptr != NULL)
_stm_become_inevitable(msg);*/
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -7,7 +7,6 @@
ffi = cffi.FFI()
ffi.cdef("""
typedef ... object_t;
-typedef ... stm_jmpbuf_t;
#define SIZEOF_MYOBJ ...
#define STM_NB_SEGMENTS ...
#define _STM_FAST_ALLOC ...
@@ -64,7 +63,8 @@
uintptr_t _stm_get_private_page(uintptr_t pagenum);
int _stm_get_flags(object_t *obj);
-void _stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf);
+void clear_jmpbuf(stm_thread_local_t *tl);
+long stm_start_transaction(stm_thread_local_t *tl);
bool _check_commit_transaction(void);
bool _check_abort_transaction(void);
bool _check_become_inevitable(stm_thread_local_t *tl);
@@ -148,7 +148,7 @@
GC_N_SMALL_REQUESTS = 36 # from gcpage.c
LARGE_MALLOC_OVERHEAD = 16 # from largemalloc.h
-lib = ffi.verify('''
+lib = ffi.verify(r'''
#include <stdlib.h>
#include <string.h>
#include <assert.h>
@@ -167,23 +167,26 @@
return obj->stm_flags;
}
+void clear_jmpbuf(stm_thread_local_t *tl) {
+ memset(&tl->rjthread, 0, sizeof(rewind_jmp_thread));
+}
+
+__attribute__((noreturn))
+void _test_run_abort(stm_thread_local_t *tl) {
+ void **jmpbuf = tl->rjthread.jmpbuf;
+ fprintf(stderr, "~~~~~ ABORT ~~~~~\n");
+ __builtin_longjmp(jmpbuf, 1);
+}
+
#define CHECKED(CALL) \
- stm_jmpbuf_t here; \
- stm_segment_info_t *segment = STM_SEGMENT; \
- if (__builtin_setjmp(here) == 0) { /* returned directly */ \
- if (segment->jmpbuf_ptr != NULL) { \
- assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1); \
- segment->jmpbuf_ptr = &here; \
- } \
+ stm_thread_local_t *_tl = STM_SEGMENT->running_thread; \
+ void **jmpbuf = _tl->rjthread.jmpbuf; \
+ if (__builtin_setjmp(jmpbuf) == 0) { /* returned directly */\
CALL; \
- if (segment->jmpbuf_ptr != NULL) { \
- segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1; \
- } \
+ clear_jmpbuf(_tl); \
return 0; \
} \
- if (segment->jmpbuf_ptr != NULL) { \
- segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1; \
- } \
+ clear_jmpbuf(_tl); \
return 1
bool _checked_stm_write(object_t *object) {
@@ -350,6 +353,7 @@
}
''', sources=source_files,
define_macros=[('STM_TESTS', '1'),
+ ('STM_NO_AUTOMATIC_SETJMP', '1'),
('STM_LARGEMALLOC_TEST', '1'),
('STM_NO_COND_WAIT', '1'),
('STM_DEBUGPRINT', '1'),
@@ -559,7 +563,9 @@
def start_transaction(self):
tl = self.tls[self.current_thread]
assert not lib._stm_in_transaction(tl)
- lib._stm_start_transaction(tl, ffi.cast("stm_jmpbuf_t *", -1))
+ res = lib.stm_start_transaction(tl)
+ assert res == 0
+ lib.clear_jmpbuf(tl)
assert lib._stm_in_transaction(tl)
#
seen = set()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit