[pypy-commit] pypy stm-gc: Progress
arigo
noreply at buildbot.pypy.org
Sun Apr 22 19:28:15 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54623:c3cbaae90b9e
Date: 2012-04-22 17:29 +0200
http://bitbucket.org/pypy/pypy/changeset/c3cbaae90b9e/
Log: Progress
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -53,10 +53,17 @@
# is no possibility of having a GC collection inbetween.
keepalive_until_here(initial_transaction)
#
- # The following line causes the _run_transaction() function to be
+ # The following line causes the _stm_run_transaction() function to be
# generated in the C source with a specific signature, where it
# can be called by the C code.
- llhelper(StmOperations.RUN_TRANSACTION, _run_transaction)
+ llop.nop(lltype.Void, llhelper(StmOperations.RUN_TRANSACTION,
+ _stm_run_transaction))
+ #
+ # The same about the _stm_thread_starting() and _stm_thread_stopping()
+ llop.nop(lltype.Void, llhelper(StmOperations.INIT_DONE,
+ _stm_thread_starting))
+ llop.nop(lltype.Void, llhelper(StmOperations.INIT_DONE,
+ _stm_thread_stopping))
#
# Tell the C code to run all transactions.
ptr = _cast_transaction_to_voidp(initial_transaction)
@@ -128,7 +135,7 @@
_transactionalstate = _TransactionalState()
-def _run_transaction(transactionptr, retry_counter):
+def _stm_run_transaction(transactionptr, retry_counter):
#
# Tell the GC we are starting a transaction
llop.stm_start_transaction(lltype.Void)
@@ -185,3 +192,10 @@
next = new_transactions[n]
n -= 1
return next
+
+
+def _stm_thread_starting():
+ llop.stm_thread_starting(lltype.Void)
+
+def _stm_thread_stopping():
+ llop.stm_thread_stopping(lltype.Void)
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
--- a/pypy/rlib/test/test_rstm.py
+++ b/pypy/rlib/test/test_rstm.py
@@ -23,7 +23,7 @@
r, transactionptr = self._pending.popitem()
transaction = self.cast_voidp_to_transaction(transactionptr)
transaction._next_transaction = None
- nextptr = rstm._run_transaction(transactionptr, 0)
+ nextptr = rstm._stm_run_transaction(transactionptr, 0)
next = self.cast_voidp_to_transaction(nextptr)
while next is not None:
self._add(self.cast_transaction_to_voidp(next))
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -409,6 +409,8 @@
'stm_normalize_global': LLOp(),
'stm_start_transaction': LLOp(canrun=True, canmallocgc=True),
'stm_stop_transaction': LLOp(canrun=True, canmallocgc=True),
+ 'stm_thread_starting': LLOp(),
+ 'stm_thread_stopping': LLOp(),
# __________ address operations __________
@@ -540,6 +542,7 @@
'stack_current': LLOp(sideeffects=False),
'keepalive': LLOp(),
+ 'nop': LLOp(canrun=True),
'same_as': LLOp(canfold=True),
'hint': LLOp(),
'check_no_more_arg': LLOp(canraise=(Exception,)),
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -646,6 +646,9 @@
def op_stm_leave_transactional_mode():
pass
+def op_nop(x):
+ pass
+
# ____________________________________________________________
def get_op_impl(opname):
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
@@ -98,9 +98,9 @@
self.sharedarea = stmshared.StmGCSharedArea(self)
self.transactional_mode = False
#
- def _get_size(obj): # indirection to hide 'self'
+ def _stm_getsize(obj): # indirection to hide 'self'
return self.get_size(obj)
- self._getsize_fn = _get_size
+ self._stm_getsize = _stm_getsize
#
##for size, TYPE in PRIMITIVE_SIZES.items():
## self.declare_reader(size, TYPE)
@@ -113,8 +113,11 @@
# we implement differently anyway. So directly call GCBase.setup().
GCBase.setup(self)
#
- self.stm_operations.setup_size_getter(
- llhelper(self.stm_operations.GETSIZE, self._getsize_fn))
+ # The following line causes the _stm_getsize() function to be
+ # generated in the C source with a specific signature, where it
+ # can be called by the C code.
+ llop.nop(lltype.Void, llhelper(self.stm_operations.GETSIZE,
+ self._stm_getsize))
#
self.sharedarea.setup()
#
@@ -197,7 +200,7 @@
def start_transaction(self):
self.get_tls().start_transaction()
- def commit_transaction(self):
+ def stop_transaction(self):
self.get_tls().stop_transaction()
@@ -275,10 +278,9 @@
@dont_inline
def _stm_write_barrier_global(obj):
tls = self.get_tls()
- if not tls.in_transaction():
- return obj # not in transaction: only when running the code
- # in _run_thread(), i.e. in sub-threads outside
- # transactions. xxx statically detect this case?
+ if tls is self.main_thread_tls:
+ return obj # not in transaction
+ #
# we need to find or make a local copy
hdr = self.header(obj)
if hdr.tid & GCFLAG_WAS_COPIED == 0:
diff --git a/pypy/rpython/memory/gc/stmtls.py b/pypy/rpython/memory/gc/stmtls.py
--- a/pypy/rpython/memory/gc/stmtls.py
+++ b/pypy/rpython/memory/gc/stmtls.py
@@ -1,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi
+from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr, llhelper
from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, base_ptr_lltype
from pypy.rlib.objectmodel import we_are_translated, free_non_gc_object
@@ -104,7 +105,6 @@
"""Called on the main thread, just before spawning the other
threads."""
self.stop_transaction()
- self.stm_operations.enter_transactional_mode()
def leave_transactional_mode(self):
"""Restart using the main thread for mallocs."""
@@ -112,7 +112,6 @@
for key, value in StmGCTLS.nontranslated_dict.items():
if value is not self:
del StmGCTLS.nontranslated_dict[key]
- self.stm_operations.leave_transactional_mode()
self.start_transaction()
def start_transaction(self):
@@ -149,9 +148,6 @@
"local_nursery_is_empty: gc not running")
return self.nursery_free == self.nursery_start
- def in_transaction(self):
- return bool(self.nursery_free)
-
# ------------------------------------------------------------
def local_collection(self, end_of_transaction=0):
@@ -190,7 +186,8 @@
#
# Also find the roots that are the local copy of GCFLAG_WAS_COPIED
# objects.
- self.collect_roots_from_tldict()
+ if not self.in_main_thread:
+ self.collect_roots_from_tldict()
#
# Now repeatedly follow objects until 'pending' is empty.
self.collect_flush_pending()
@@ -427,11 +424,14 @@
if not hasattr(self.stm_operations, 'tldict_enum'):
return
CALLBACK = self.stm_operations.CALLBACK_ENUM
- callback = llhelper(CALLBACK, StmGCTLS._enum_entries)
- self.stm_operations.tldict_enum(callback)
+ llop.nop(lltype.Void, llhelper(CALLBACK, StmGCTLS._stm_enum_callback))
+ # The previous line causes the _stm_enum_callback() function to be
+ # generated in the C source with a specific signature, where it
+ # can be called by the C code.
+ self.stm_operations.tldict_enum()
@staticmethod
- def _enum_entries(tlsaddr, globalobj, localobj):
+ def _stm_enum_callback(tlsaddr, globalobj, localobj):
self = StmGCTLS.cast_address_to_tls_object(tlsaddr)
localhdr = self.gc.header(localobj)
ll_assert(localhdr.version == globalobj,
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -13,21 +13,21 @@
def _declare_functions(self, GCClass, getfn, s_gc, *args):
#
- def setup_thread(gc):
+ def thread_starting(gc):
self.root_walker.allocate_shadow_stack()
gc.setup_thread()
#
- def teardown_thread(gc):
+ def thread_stopping(gc):
gc.teardown_thread()
self.root_walker.free_shadow_stack()
#
super(StmFrameworkGCTransformer, self)._declare_functions(
GCClass, getfn, s_gc, *args)
- self.setup_secondary_thread_ptr = getfn(
- setup_thread,
+ self.thread_starting_ptr = getfn(
+ thread_starting,
[s_gc], annmodel.s_None)
- self.teardown_thread_ptr = getfn(
- teardown_thread,
+ self.thread_stopping_ptr = getfn(
+ thread_stopping,
[s_gc], annmodel.s_None)
self.stm_writebarrier_ptr = getfn(
self.gcdata.gc.stm_writebarrier,
@@ -44,8 +44,8 @@
self.stm_start_ptr = getfn(
self.gcdata.gc.start_transaction.im_func,
[s_gc], annmodel.s_None)
- self.stm_commit_ptr = getfn(
- self.gcdata.gc.commit_transaction.im_func,
+ self.stm_stop_ptr = getfn(
+ self.gcdata.gc.stop_transaction.im_func,
[s_gc], annmodel.s_None)
def build_root_walker(self):
@@ -62,12 +62,11 @@
resulttype=llmemory.Address)
hop.genop('adr_add', [v_gcdata_adr, c_ofs], resultvar=op.result)
- def gct_stm_descriptor_init(self, hop):
- hop.genop("direct_call", [self.setup_secondary_thread_ptr,
- self.c_const_gc])
+ def gct_stm_thread_starting(self, hop):
+ hop.genop("direct_call", [self.thread_starting_ptr, self.c_const_gc])
- def gct_stm_descriptor_done(self, hop):
- hop.genop("direct_call", [self.teardown_thread_ptr, self.c_const_gc])
+ def gct_stm_thread_stopping(self, hop):
+ hop.genop("direct_call", [self.thread_stopping_ptr, self.c_const_gc])
def gct_stm_enter_transactional_mode(self, hop):
livevars = self.push_roots(hop)
@@ -104,9 +103,9 @@
hop.genop("direct_call", [self.stm_start_ptr, self.c_const_gc])
self.pop_roots(hop, livevars)
- def gct_stm_commit_transaction(self, hop):
+ def gct_stm_stop_transaction(self, hop):
livevars = self.push_roots(hop)
- hop.genop("direct_call", [self.stm_commit_ptr, self.c_const_gc])
+ hop.genop("direct_call", [self.stm_stop_ptr, self.c_const_gc])
self.pop_roots(hop, livevars)
diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h
--- a/pypy/translator/c/src/mem.h
+++ b/pypy/translator/c/src/mem.h
@@ -91,6 +91,9 @@
#endif
+#define OP_NOP(r, x) /* nothing */
+
+
/* used by pypy.rlib.rstack, but also by asmgcc */
#define OP_STACK_CURRENT(r) r = (Signed)&r
diff --git a/pypy/translator/stm/src_stm/core.c b/pypy/translator/stm/src_stm/core.c
--- a/pypy/translator/stm/src_stm/core.c
+++ b/pypy/translator/stm/src_stm/core.c
@@ -6,7 +6,6 @@
#define SPINLOOP_REASONS 10
struct tx_descriptor {
- void *rpython_tls_object;
jmp_buf *setjmp_buf;
owner_version_t start_time;
owner_version_t end_time;
@@ -24,8 +23,6 @@
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*);
/************************************************************/
@@ -58,7 +55,7 @@
{
unsigned int c;
int i;
- struct tx_descriptor *d = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
d->num_spinloops[num]++;
//printf("tx_spinloop(%d)\n", num);
@@ -90,7 +87,7 @@
{
void *globalobj = item->addr;
void *localobj = item->val;
- long size = rpython_get_size(localobj);
+ long size = pypy_g__stm_getsize(localobj);
memcpy(((char *)globalobj) + sizeof(orec_t),
((char *)localobj) + sizeof(orec_t),
size - sizeof(orec_t));
@@ -198,7 +195,7 @@
/*** increase the abort count and restart the transaction */
static void tx_abort(int reason)
{
- struct tx_descriptor *d = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
assert(!is_inevitable(d));
d->num_aborts[reason]++;
#ifdef RPY_STM_DEBUG_PRINT
@@ -397,14 +394,13 @@
#define STM_READ_WORD(SIZE, SUFFIX, TYPE) \
TYPE stm_read_int##SIZE##SUFFIX(void* addr, long offset) \
{ \
- struct tx_descriptor *d = active_thread_descriptor; \
+ struct tx_descriptor *d = 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: */ \
- /* d is NULL only when in non-main threads but */ \
- /* outside a transaction. */ \
+ /* d is NULL when running in the main thread */ \
if (d == NULL) \
return *(TYPE *)(((char *)addr) + offset); \
\
@@ -434,7 +430,7 @@
void stm_copy_transactional_to_raw(void *src, void *dst, long size)
{
- struct tx_descriptor *d = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
volatile orec_t *o = get_orec(src);
owner_version_t ovt;
@@ -448,11 +444,14 @@
STM_DO_READ(memcpy(dst, src, size));
}
-static struct tx_descriptor *descriptor_init(long in_main_thread)
+static void descriptor_init(long in_main_thread)
{
assert(thread_descriptor == NULL);
- assert(active_thread_descriptor == NULL);
- if (1) /* for hg diff */
+ if (in_main_thread)
+ {
+ /* the main thread doesn't have a thread_descriptor at all */
+ }
+ else
{
struct tx_descriptor *d = malloc(sizeof(struct tx_descriptor));
memset(d, 0, sizeof(struct tx_descriptor));
@@ -461,40 +460,28 @@
PYPY_DEBUG_START("stm-init");
#endif
- if (in_main_thread)
- {
- d->my_lock_word = 0; /* special value for the main thread */
- }
- 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));
- }
- /*d->spinloop_counter = (unsigned int)(d->my_lock_word | 1);*/
+ /* 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));
thread_descriptor = d;
- if (in_main_thread)
- ; //stm_leave_transactional_mode();
- else
- ; /* active_thread_descriptor stays NULL */
#ifdef RPY_STM_DEBUG_PRINT
- if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE, "thread %lx starting\n",
- (long)pthread_self());
+ if (PYPY_HAVE_DEBUG_PRINTS)
+ fprintf(PYPY_DEBUG_FILE, "thread %lx starting with id %lx\n",
+ (long)pthread_self(), (long)d->my_lock_word);
PYPY_DEBUG_STOP("stm-init");
#endif
- return d;
}
}
static void descriptor_done(void)
{
struct tx_descriptor *d = thread_descriptor;
- assert(d != NULL);
- assert(active_thread_descriptor == NULL);
+ if (d == NULL)
+ return;
thread_descriptor = NULL;
@@ -535,17 +522,15 @@
static void begin_transaction(jmp_buf* buf)
{
struct tx_descriptor *d = thread_descriptor;
- /* you need to call descriptor_init() before calling
- stm_perform_transaction() */
+ /* you need to call descriptor_init() before calling this */
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)
+static void commit_transaction(void)
{
- struct tx_descriptor *d = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
assert(d != NULL);
// if I don't have writes, I'm committed
@@ -560,12 +545,10 @@
}
d->num_commits++;
common_cleanup(d);
- active_thread_descriptor = NULL;
- return d->start_time;
}
// bring that variable over to this CPU core (optimization, maybe)
- global_timestamp;
+ /* global_timestamp; */
// acquire locks
acquireLocks(d);
@@ -606,8 +589,6 @@
// reset all lists
common_cleanup(d);
- active_thread_descriptor = NULL;
- return d->end_time;
}
void stm_try_inevitable(STM_CCHARP1(why))
@@ -616,14 +597,11 @@
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 = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
if (d == NULL)
- return;
-
- if (is_inevitable(d)) /* also when the transaction is inactive */
- {
- return; /* I am already inevitable */
- }
+ return; /* I am running in the main thread */
+ if (is_inevitable(d))
+ return; /* I am already inevitable */
#ifdef RPY_STM_DEBUG_PRINT
PYPY_DEBUG_START("stm-inevitable");
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
@@ -1,6 +1,6 @@
/*** Extendable Timestamps
*
- * This is a C version of rstm_r5/stm/et.hpp.
+ * This is a (heavily modified) C version of rstm_r5/stm/et.hpp.
* See http://www.cs.rochester.edu/research/synchronization/rstm/api.shtml
*
*/
@@ -12,20 +12,22 @@
#include "src/commondefs.h"
+/* see comments in ../stmgcintf.py */
long stm_in_transaction(void);
-void stm_run_all_transactions(void*(*)(void*, long), void*, long);
-
-
-
-void stm_setup_size_getter(long(*)(void*));
+void stm_run_all_transactions(void*, long);
void stm_set_tls(void *, long);
void *stm_get_tls(void);
void stm_del_tls(void);
+long stm_thread_id(void);
void *stm_tldict_lookup(void *);
void stm_tldict_add(void *, void *);
-void stm_tldict_enum(void(*)(void*, void*, void*));
+void stm_tldict_enum(void);
+
+/* these functions are declared by generated C code from the GC */
+extern long pypy_g__stm_getsize(void *);
+extern void pypy_g__stm_enum_callback(void *, void *, void *);
char stm_read_int1(void *, long);
short stm_read_int2(void *, long);
@@ -51,8 +53,6 @@
0: not in a transaction
1: in a regular transaction
2: in an inevitable transaction */
-long stm_thread_id(void); /* returns a unique thread id,
- or 0 if descriptor_init() was not called */
void _stm_activate_transaction(long);
void stm_copy_transactional_to_raw(void *src, void *dst, long size);
diff --git a/pypy/translator/stm/src_stm/rpyintf.c b/pypy/translator/stm/src_stm/rpyintf.c
--- a/pypy/translator/stm/src_stm/rpyintf.c
+++ b/pypy/translator/stm/src_stm/rpyintf.c
@@ -4,19 +4,21 @@
{
struct tx_descriptor *d = thread_descriptor;
if (d == NULL)
- return 0; /* no thread_descriptor yet, assume it's the main thread */
+ return 0; /* no thread_descriptor: it's the main thread */
return d->my_lock_word;
}
+static __thread void *rpython_tls_object;
+
void stm_set_tls(void *newtls, long in_main_thread)
{
- struct tx_descriptor *d = descriptor_init(in_main_thread);
- d->rpython_tls_object = newtls;
+ descriptor_init(in_main_thread);
+ rpython_tls_object = newtls;
}
void *stm_get_tls(void)
{
- return thread_descriptor->rpython_tls_object;
+ return rpython_tls_object;
}
void stm_del_tls(void)
@@ -37,12 +39,12 @@
void stm_tldict_add(void *key, void *value)
{
- struct tx_descriptor *d = active_thread_descriptor;
+ struct tx_descriptor *d = thread_descriptor;
assert(d != NULL);
redolog_insert(&d->redolog, key, value);
}
-void stm_tldict_enum(void(*callback)(void*, void*, void*))
+void stm_tldict_enum(void)
{
struct tx_descriptor *d = thread_descriptor;
wlog_t *item;
@@ -50,40 +52,17 @@
REDOLOG_LOOP_FORWARD(d->redolog, item)
{
- callback(tls, item->addr, item->val);
+ pypy_g__stm_enum_callback(tls, item->addr, item->val);
} REDOLOG_LOOP_END;
}
-void stm_setup_size_getter(long(*getsize_fn)(void*))
-{
- rpython_get_size = getsize_fn;
-}
-
long stm_in_transaction(void)
{
struct tx_descriptor *d = thread_descriptor;
return d != NULL;
}
-void _stm_activate_transaction(long activate)
-{
- assert(thread_descriptor != NULL);
- if (activate)
- {
- active_thread_descriptor = thread_descriptor;
- }
- else
- {
- active_thread_descriptor = NULL;
- }
-}
-
-
-/* a helper to directly read the field '_next_transaction' on
- RPython instances of pypy.rlib.rstm.Transaction */
-static void *next_transaction(void *
-
-
+/************************************************************/
/* this lock is acquired when we start running transactions, and
released only when we are finished. */
@@ -94,11 +73,8 @@
static pthread_mutex_t mutex_global = PTHREAD_MUTEX_INITIALIZER;
/* some global data put there by run_all_transactions(). */
-typedef void *(*run_transaction_t)(void *, long);
-static run_transaction_t g_run_transaction;
static void *g_first_transaction, *g_last_transaction;
-static int g_num_threads;
-static int g_num_waiting_threads;
+static int g_num_threads, g_num_waiting_threads;
/* the main function running a thread */
static void *run_thread(void *ignored)
@@ -113,12 +89,10 @@
return NULL;
}
-void stm_run_all_transactions(run_transaction_t run_transaction,
- void *initial_transaction,
+void stm_run_all_transactions(void *initial_transaction,
long num_threads)
{
int i;
- g_run_transaction = run_transaction;
g_first_transaction = initial_transaction;
g_last_transaction = initial_transaction;
g_num_threads = (int)num_threads;
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
@@ -35,47 +35,58 @@
'8f': rffi.DOUBLE,
'4f': rffi.FLOAT}
+ INIT_DONE = lltype.Ptr(lltype.FuncType([], lltype.Void))
RUN_TRANSACTION = lltype.Ptr(lltype.FuncType([rffi.VOIDP, lltype.Signed],
rffi.VOIDP))
+ GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address],
+ lltype.Signed))
+ CALLBACK_ENUM = lltype.Ptr(lltype.FuncType([llmemory.Address]*3,
+ lltype.Void))
def _freeze_(self):
return True
+ # C part of the implementation of the pypy.rlib.rstm module
in_transaction = smexternal('stm_in_transaction', [], lltype.Signed)
run_all_transactions = smexternal('stm_run_all_transactions',
[rffi.VOIDP, lltype.Signed],
lltype.Void)
-
-
- # xxx review and delete xxx
- CALLBACK_ENUM = lltype.Ptr(lltype.FuncType([llmemory.Address] * 3,
- lltype.Void))
- _activate_transaction = smexternal('_stm_activate_transaction',
- [lltype.Signed], lltype.Void)
-
+ # for the GC: store and read a thread-local-storage field, as well
+ # as initialize and shut down the internal thread_descriptor
set_tls = smexternal('stm_set_tls', [llmemory.Address, lltype.Signed],
lltype.Void)
get_tls = smexternal('stm_get_tls', [], llmemory.Address)
del_tls = smexternal('stm_del_tls', [], lltype.Void)
+ # return the current thread id (a random non-null number, or 0 for
+ # the main thread)
+ thread_id = smexternal('stm_thread_id', [], lltype.Signed)
+
+ # lookup, add, and enumerate the content of the internal dictionary
+ # that maps GLOBAL objects to LOCAL objects
tldict_lookup = smexternal('stm_tldict_lookup', [llmemory.Address],
llmemory.Address)
tldict_add = smexternal('stm_tldict_add', [llmemory.Address] * 2,
lltype.Void)
- tldict_enum = smexternal('stm_tldict_enum', [CALLBACK_ENUM], lltype.Void)
+ tldict_enum = smexternal('stm_tldict_enum', [], lltype.Void)
+ # reader functions, to call if the object is GLOBAL
for _size, _TYPE in PRIMITIVE_SIZES.items():
_name = 'stm_read_int%s' % _size
locals()[_name] = smexternal(_name, [llmemory.Address, lltype.Signed],
_TYPE)
+ # a special reader function that copies all the content of the object
+ # somewhere else
stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
[llmemory.Address,
llmemory.Address,
lltype.Signed],
lltype.Void)
+ # if running in a transaction, make it inevitable
try_inevitable = smexternal('stm_try_inevitable', [], lltype.Void)
- thread_id = smexternal('stm_thread_id', [], lltype.Signed)
+
+ # for testing
abort_and_retry = smexternal('stm_abort_and_retry', [], lltype.Void)
More information about the pypy-commit
mailing list