Author: Remi Meier
Branch: c7
Changeset: r705:d7f5d26b082d
Date: 2014-02-05 14:52 +0100
http://bitbucket.org/pypy/stmgc/changeset/d7f5d26b082d/
Log: implement requesting of safe-points and older-transaction-succeeds
in write-write conflicts
diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -21,6 +21,7 @@
static int num_threads_started;
uint8_t write_locks[READMARKER_END - READMARKER_START];
volatile uint8_t inevitable_lock __attribute__((aligned(64))); /* cache-line
alignment */
+long global_age = 0;
struct _thread_local1_s* _stm_dbg_get_tl(int thread)
{
@@ -134,18 +135,16 @@
if ((!prev_owner) || (prev_owner == lock_num))
break;
- if (_STM_TL->active == 2) {
+ struct _thread_local1_s* other_tl = _stm_dbg_get_tl(prev_owner - 1);
+ if ((_STM_TL->age < other_tl->age) || (_STM_TL->active == 2)) {
/* we must succeed! */
- _stm_dbg_get_tl(prev_owner - 1)->need_abort = 1;
+ other_tl->need_abort = 1;
_stm_start_safe_point(0);
/* XXX: not good, maybe should be signalled by other thread */
usleep(1);
_stm_stop_safe_point(0);
goto retry;
- }
-
-
- if (retries < 1) {
+ } else if (retries < 1) {
_stm_start_safe_point(0);
usleep(1);
_stm_stop_safe_point(0);
@@ -176,8 +175,8 @@
_stm_restore_local_state(thread_num);
_STM_TL->nursery_current = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
- memset((void*)real_address((object_t*)_STM_TL->nursery_current), 0x0,
- (FIRST_AFTER_NURSERY_PAGE - FIRST_NURSERY_PAGE) * 4096); /* clear
nursery */
+
memset((void*)real_address((object_t*)CLEAR_SYNC_REQUEST(_STM_TL->nursery_current)),
+ 0x0, (FIRST_AFTER_NURSERY_PAGE - FIRST_NURSERY_PAGE) * 4096); /*
clear nursery */
_STM_TL->shadow_stack = NULL;
_STM_TL->shadow_stack_base = NULL;
@@ -386,6 +385,8 @@
_STM_TL->jmpbufptr = jmpbufptr;
_STM_TL->active = 1;
_STM_TL->need_abort = 0;
+ /* global_age is approximate -> no synchronization required */
+ _STM_TL->age = global_age++;
fprintf(stderr, "%c", 'S'+_STM_TL->thread_num*32);
}
diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -94,6 +94,10 @@
jmpbufptr_t *jmpbufptr;
uint8_t transaction_read_version;
+ /* unsynchronized/inaccurate start age of transaction
+ XXX: may be replaced with size_of(read/write-set) */
+ long age;
+
/* static threads, not pthreads */
int thread_num;
char *thread_base;
@@ -105,7 +109,10 @@
object_t **shadow_stack;
object_t **shadow_stack_base;
- localchar_t *nursery_current;
+ union {
+ localchar_t *nursery_current;
+ uint32_t nursery_current_halfwords[2];
+ };
struct stm_list_s *modified_objects;
diff --git a/c7/nursery.c b/c7/nursery.c
--- a/c7/nursery.c
+++ b/c7/nursery.c
@@ -166,7 +166,7 @@
/* clear nursery */
localchar_t *nursery_base = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
memset((void*)real_address((object_t*)nursery_base), 0x0,
- _STM_TL->nursery_current - nursery_base);
+ CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) - nursery_base);
_STM_TL->nursery_current = nursery_base;
}
@@ -177,23 +177,33 @@
localchar_t *collect_and_reserve(size_t size)
{
+ localchar_t *new_current = _STM_TL->nursery_current;
+
+ while (((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096)
+ && _STM_TL->nursery_current_halfwords[1]) {
+
+ _STM_TL->nursery_current_halfwords[1] = 0;
+ _stm_start_safe_point(0);
+ /* no collect, it would mess with nursery_current */
+ _stm_stop_safe_point(0);
+
+ new_current = _STM_TL->nursery_current;
+ }
+
+ if (!((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096)) {
+ /* after safe-point, new_current is actually fine again */
+ return new_current - size;
+ }
+
/* reset nursery_current (left invalid by the caller) */
_STM_TL->nursery_current -= size;
- /* XXX: check for requested safe-point (by setting nursery_current
- too high or similar) */
-
-
- _stm_start_safe_point(0); /* don't release the COLLECT lock,
- that needs to be done afterwards if
- we want a major collection */
minor_collect();
- _stm_stop_safe_point(0);
/* XXX: if we_want_major_collect: acquire EXCLUSIVE & COLLECT lock
and do it */
- localchar_t *current = _STM_TL->nursery_current;
+ localchar_t *current = CLEAR_SYNC_REQUEST(_STM_TL->nursery_current);
_STM_TL->nursery_current = current + size;
return current;
}
@@ -231,7 +241,6 @@
localchar_t *current = _STM_TL->nursery_current;
localchar_t *new_current = current + size;
_STM_TL->nursery_current = new_current;
- assert((uintptr_t)new_current < (1L << 32));
if ((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096) {
current = collect_and_reserve(size);
@@ -312,7 +321,7 @@
/* clear the nursery */
localchar_t *nursery_base = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
memset((void*)real_address((object_t*)nursery_base), 0x0,
- _STM_TL->nursery_current - nursery_base);
+ CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) - nursery_base);
_STM_TL->nursery_current = nursery_base;
diff --git a/c7/stmsync.c b/c7/stmsync.c
--- a/c7/stmsync.c
+++ b/c7/stmsync.c
@@ -108,7 +108,7 @@
assert(!_STM_TL->active);
/* assert(!_STM_TL->need_abort); may happen, but will be cleared by
start_transaction() */
- assert(_STM_TL->nursery_current == (localchar_t*)(FIRST_NURSERY_PAGE *
4096));
+ assert(CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) ==
(localchar_t*)(FIRST_NURSERY_PAGE * 4096));
}
void _stm_acquire_tl_segment()
@@ -270,10 +270,12 @@
_stm_grab_thread_segment();
}
- if (flags & LOCK_EXCLUSIVE)
+ if (flags & LOCK_EXCLUSIVE) {
+ stm_request_safe_point(1 - _STM_TL->thread_num);
stm_start_exclusive_lock();
- else
+ } else {
stm_start_shared_lock();
+ }
if (flags & LOCK_COLLECT) { /* if we released the collection lock */
/* acquire read-collection. always succeeds because
@@ -296,3 +298,9 @@
+void stm_request_safe_point(int thread_num)
+{
+ struct _thread_local1_s* other_tl = _stm_dbg_get_tl(thread_num);
+ other_tl->nursery_current_halfwords[1] = 1;
+}
+
diff --git a/c7/stmsync.h b/c7/stmsync.h
--- a/c7/stmsync.h
+++ b/c7/stmsync.h
@@ -17,3 +17,8 @@
THREAD_YIELD = (1 << 2),
};
+
+void stm_request_safe_point(int thread_num);
+
+#define CLEAR_SYNC_REQUEST(nursery_current)
((localchar_t*)(((uintptr_t)(nursery_current)) & 0xffffffff))
+
diff --git a/duhton/demo/synth.duh b/duhton/demo/synth.duh
--- a/duhton/demo/synth.duh
+++ b/duhton/demo/synth.duh
@@ -62,8 +62,10 @@
-(setq N 800)
-(setq RAND_MAX 10)
+(setq N 1000)
+;; CONFL_IF_BELOW / RAND_MAX == ratio of conflicting transactions
+;; to non conflicting ones
+(setq RAND_MAX 8)
(setq CONFL_IF_BELOW 1)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit