Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r52355:a8cf7f197ec1
Date: 2012-02-10 16:10 +0100
http://bitbucket.org/pypy/pypy/changeset/a8cf7f197ec1/
Log: Replace in_main_thread() with in_transaction().
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -297,7 +297,7 @@
#
@dont_inline
def _stm_write_barrier_global(obj):
- if stm_operations.in_main_thread():
+ if not stm_operations.in_transaction():
return obj
# we need to find of make a local copy
hdr = self.header(obj)
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py
b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -26,8 +26,8 @@
def setup_size_getter(self, getsize_fn):
self._getsize_fn = getsize_fn
- def in_main_thread(self):
- return self.threadnum == 0
+ def in_transaction(self):
+ return self.threadnum != 0
def set_tls(self, tls, in_main_thread):
assert lltype.typeOf(tls) == llmemory.Address
@@ -149,6 +149,7 @@
self.gc.stm_operations.threadnum = threadnum
if threadnum not in self.gc.stm_operations._tls_dict:
self.gc.setup_thread(False)
+ self.gc.start_transaction()
def gcsize(self, S):
return (llmemory.raw_malloc_usage(llmemory.sizeof(self.gc.HDR)) +
llmemory.raw_malloc_usage(llmemory.sizeof(S)))
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -81,6 +81,7 @@
if there is an inevitable transaction running */
static volatile unsigned long global_timestamp = 2;
static __thread struct tx_descriptor *thread_descriptor = NULL;
+static __thread struct tx_descriptor *active_thread_descriptor = NULL;
static long (*rpython_get_size)(void*);
/************************************************************/
@@ -114,7 +115,7 @@
{
unsigned int c;
int i;
- struct tx_descriptor *d = thread_descriptor;
+ struct tx_descriptor *d = active_thread_descriptor;
d->num_spinloops[num]++;
//printf("tx_spinloop(%d)\n", num);
@@ -132,11 +133,6 @@
#endif
}
-static _Bool is_main_thread(struct tx_descriptor *d)
-{
- return d->my_lock_word == 0;
-}
-
static _Bool is_inevitable(struct tx_descriptor *d)
{
return d->setjmp_buf == NULL;
@@ -268,7 +264,7 @@
/*** increase the abort count and restart the transaction */
static void tx_abort(int reason)
{
- struct tx_descriptor *d = thread_descriptor;
+ struct tx_descriptor *d = active_thread_descriptor;
assert(!is_inevitable(d));
d->num_aborts[reason]++;
#ifdef RPY_STM_DEBUG_PRINT
@@ -459,12 +455,16 @@
#define STM_READ_WORD(SIZE, TYPE) \
TYPE stm_read_int##SIZE(void* addr, long offset) \
{ \
- struct tx_descriptor *d = thread_descriptor; \
+ struct tx_descriptor *d = active_thread_descriptor; \
volatile orec_t *o = get_orec(addr); \
owner_version_t ovt; \
\
assert(sizeof(TYPE) == SIZE); \
\
+ /* XXX try to remove this check from the main path */ \
+ if (d == NULL) \
+ return *(TYPE *)(((char *)addr) + offset); \
+ \
if ((o->tid & GCFLAG_WAS_COPIED) != 0) \
{ \
/* Look up in the thread-local dictionary. */ \
@@ -477,10 +477,6 @@
not_found:; \
} \
\
- /* XXX try to remove this check from the main path */ \
- if (is_main_thread(d)) \
- return *(TYPE *)(((char *)addr) + offset); \
- \
STM_DO_READ(TYPE tmp = *(TYPE *)(((char *)addr) + offset)); \
return tmp; \
}
@@ -492,11 +488,11 @@
void stm_copy_transactional_to_raw(void *src, void *dst, long size)
{
- struct tx_descriptor *d = thread_descriptor;
+ struct tx_descriptor *d = active_thread_descriptor;
volatile orec_t *o = get_orec(src);
owner_version_t ovt;
- assert(!is_main_thread(d));
+ assert(d != NULL);
/* don't copy the header */
src = ((char *)src) + sizeof(orec_t);
@@ -507,9 +503,10 @@
}
-static struct tx_descriptor *descriptor_init(_Bool is_main_thread)
+static struct tx_descriptor *descriptor_init()
{
assert(thread_descriptor == NULL);
+ assert(active_thread_descriptor == NULL);
if (1) /* for hg diff */
{
struct tx_descriptor *d = malloc(sizeof(struct tx_descriptor));
@@ -519,21 +516,15 @@
PYPY_DEBUG_START("stm-init");
#endif
- if (is_main_thread)
- {
- d->my_lock_word = 0;
- }
- else
- {
- /* initialize 'my_lock_word' to be a unique negative number */
- d->my_lock_word = (owner_version_t)d;
- if (!IS_LOCKED(d->my_lock_word))
- d->my_lock_word = ~d->my_lock_word;
- assert(IS_LOCKED(d->my_lock_word));
- }
+ /* initialize 'my_lock_word' to be a unique negative number */
+ d->my_lock_word = (owner_version_t)d;
+ if (!IS_LOCKED(d->my_lock_word))
+ d->my_lock_word = ~d->my_lock_word;
+ assert(IS_LOCKED(d->my_lock_word));
/*d->spinloop_counter = (unsigned int)(d->my_lock_word | 1);*/
thread_descriptor = d;
+ /* active_thread_descriptor stays NULL */
#ifdef RPY_STM_DEBUG_PRINT
if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE, "thread %lx
starting\n",
@@ -548,6 +539,7 @@
{
struct tx_descriptor *d = thread_descriptor;
assert(d != NULL);
+ assert(active_thread_descriptor == NULL);
thread_descriptor = NULL;
@@ -593,12 +585,13 @@
assert(d != NULL);
d->setjmp_buf = buf;
d->start_time = (/*d->last_known_global_timestamp*/ global_timestamp) & ~1;
+ active_thread_descriptor = d;
}
static long commit_transaction(void)
{
- struct tx_descriptor *d = thread_descriptor;
- assert(!is_main_thread(d));
+ struct tx_descriptor *d = active_thread_descriptor;
+ assert(d != NULL);
// if I don't have writes, I'm committed
if (!redolog_any_entry(&d->redolog))
@@ -612,6 +605,7 @@
}
d->num_commits++;
common_cleanup(d);
+ active_thread_descriptor = NULL;
return d->start_time;
}
@@ -657,6 +651,7 @@
// reset all lists
common_cleanup(d);
+ active_thread_descriptor = NULL;
return d->end_time;
}
@@ -666,6 +661,7 @@
jmp_buf _jmpbuf;
volatile long v_counter = 0;
long counter;
+ assert(active_thread_descriptor == NULL);
setjmp(_jmpbuf);
begin_transaction(&_jmpbuf);
counter = v_counter;
@@ -681,8 +677,8 @@
global_timestamp and global_timestamp cannot be incremented
by another thread. We set the lowest bit in global_timestamp
to 1. */
- struct tx_descriptor *d = thread_descriptor;
- if (d == NULL || is_main_thread(d))
+ struct tx_descriptor *d = active_thread_descriptor;
+ if (d == NULL)
return;
#ifdef RPY_STM_DEBUG_PRINT
@@ -742,7 +738,10 @@
{
struct tx_descriptor *d = thread_descriptor;
if (d == NULL)
+ return -1;
+ if (active_thread_descriptor == NULL)
return 0;
+ assert(d == active_thread_descriptor);
if (!is_inevitable(d))
return 1;
else
@@ -756,9 +755,10 @@
}
-void stm_set_tls(void *newtls, long is_main_thread)
+void stm_set_tls(void *newtls, long in_main_thread)
{
- struct tx_descriptor *d = descriptor_init(is_main_thread);
+ /* 'in_main_thread' is ignored so far */
+ struct tx_descriptor *d = descriptor_init();
d->rpython_tls_object = newtls;
}
@@ -785,7 +785,8 @@
void stm_tldict_add(void *key, void *value)
{
- struct tx_descriptor *d = thread_descriptor;
+ struct tx_descriptor *d = active_thread_descriptor;
+ assert(d != NULL);
redolog_insert(&d->redolog, key, value);
}
@@ -806,10 +807,25 @@
rpython_get_size = getsize_fn;
}
-long stm_in_main_thread(void)
+long stm_in_transaction(void)
{
- struct tx_descriptor *d = thread_descriptor;
- return is_main_thread(d);
+ struct tx_descriptor *d = active_thread_descriptor;
+ return d != NULL;
+}
+
+void _stm_activate_transaction(long activate)
+{
+ assert(thread_descriptor != NULL);
+ if (activate)
+ {
+ assert(active_thread_descriptor == NULL);
+ active_thread_descriptor = thread_descriptor;
+ }
+ else
+ {
+ assert(active_thread_descriptor != NULL);
+ active_thread_descriptor = NULL;
+ }
}
#endif /* PYPY_NOT_MAIN_FILE */
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -46,6 +46,8 @@
2: in an inevitable transaction */
long stm_thread_id(void); /* returns a unique thread id,
or 0 if descriptor_init() was not called */
+long stm_in_transaction(void);
+void _stm_activate_transaction(long);
/************************************************************/
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
--- a/pypy/translator/stm/stmgcintf.py
+++ b/pypy/translator/stm/stmgcintf.py
@@ -15,7 +15,9 @@
setup_size_getter = smexternal('stm_setup_size_getter', [GETSIZE],
lltype.Void)
- in_main_thread = smexternal('stm_in_main_thread', [], lltype.Signed)
+ in_transaction = smexternal('stm_in_transaction', [], lltype.Signed)
+ _activate_transaction = smexternal('_stm_activate_transaction',
+ [lltype.Signed], lltype.Void)
set_tls = smexternal('stm_set_tls', [llmemory.Address, lltype.Signed],
lltype.Void)
diff --git a/pypy/translator/stm/test/targetdemo.py
b/pypy/translator/stm/test/targetdemo.py
--- a/pypy/translator/stm/test/targetdemo.py
+++ b/pypy/translator/stm/test/targetdemo.py
@@ -14,6 +14,7 @@
LENGTH = 5000
USE_MEMORY = False
anchor = Node(-1)
+ lock = ll_thread.allocate_ll_lock()
glob = Global()
class Arg:
diff --git a/pypy/translator/stm/test/test_stmgcintf.py
b/pypy/translator/stm/test/test_stmgcintf.py
--- a/pypy/translator/stm/test/test_stmgcintf.py
+++ b/pypy/translator/stm/test/test_stmgcintf.py
@@ -30,16 +30,23 @@
class TestStmGcIntf:
+ _in_transaction = False
def setup_method(self, meth):
TLS = getattr(meth, 'TLS', DEFAULT_TLS)
s = lltype.malloc(TLS, flavor='raw', immortal=True)
self.tls = s
a = llmemory.cast_ptr_to_adr(s)
- in_main_thread = getattr(meth, 'in_main_thread', True)
+ in_transaction = getattr(meth, 'in_transaction', False)
+ in_main_thread = getattr(meth, 'in_main_thread', not in_transaction)
stm_operations.set_tls(a, int(in_main_thread))
+ if in_transaction:
+ stm_operations._activate_transaction(1)
+ self._in_transaction = True
def teardown_method(self, meth):
+ if self._in_transaction:
+ stm_operations._activate_transaction(0)
stm_operations.del_tls()
def test_set_get_del(self):
@@ -60,6 +67,7 @@
stm_operations.tldict_add(a3, a4)
assert stm_operations.tldict_lookup(a3) == a4
assert stm_operations.tldict_lookup(a1) == a2
+ test_tldict.in_transaction = True
def test_tldict_large(self):
content = {}
@@ -74,7 +82,7 @@
a2 = rffi.cast(llmemory.Address, random.randrange(2000, 9999))
stm_operations.tldict_add(a1, a2)
content[key] = a2
- return content
+ test_tldict_large.in_transaction = True
def get_callback(self):
def callback(tls, key, value):
@@ -101,6 +109,7 @@
stm_operations.tldict_enum(p_callback)
assert (seen == [(a1, a2), (a3, a4)] or
seen == [(a3, a4), (a1, a2)])
+ test_enum_tldict_nonempty.in_transaction = True
def stm_read_case(self, flags, copied=False):
# doesn't test STM behavior, but just that it appears to work
@@ -136,7 +145,7 @@
assert res == 42042
res = self.stm_read_case(stmgc.GCFLAG_WAS_COPIED, copied=True)
assert res == 84084
- test_stm_read_word_transactional_thread.in_main_thread = False
+ test_stm_read_word_transactional_thread.in_transaction = True
def test_stm_read_int1(self):
S2 = lltype.Struct('S2', ('hdr', stmgc.StmGC.HDR),
@@ -186,11 +195,16 @@
#
lltype.free(s2, flavor='raw')
lltype.free(s1, flavor='raw')
- test_stm_copy_transactional_to_raw.in_main_thread = False
+ test_stm_copy_transactional_to_raw.in_transaction = True
- def test_in_main_thread(self):
- assert stm_operations.in_main_thread()
+ def test_in_transaction(self):
+ assert stm_operations.in_transaction()
+ test_in_transaction.in_transaction = True
- def test_not_in_main_thread(self):
- assert not stm_operations.in_main_thread()
- test_not_in_main_thread.in_main_thread = False
+ def test_not_in_transaction(self):
+ assert not stm_operations.in_transaction()
+ test_not_in_transaction.in_main_thread = False
+
+ def test_not_in_transaction_main(self):
+ assert not stm_operations.in_transaction()
+ test_not_in_transaction.in_main_thread = True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit