Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r52188:b4d3a591ff38
Date: 2012-02-07 16:52 +0100
http://bitbucket.org/pypy/pypy/changeset/b4d3a591ff38/
Log: Reads of 1, 2, 4, 8 bytes here too.
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
@@ -11,7 +11,6 @@
#include <stdlib.h>
#include <stdio.h>
-#include <assert.h>
#include <string.h>
#define USE_PTHREAD_MUTEX /* optional */
@@ -29,6 +28,13 @@
# define RPY_STM_ASSERT 1
#endif
+#ifdef RPY_STM_ASSERT
+# include <assert.h>
+#else
+# undef assert
+# define assert /* nothing */
+#endif
+
/************************************************************/
/* This is the same as the object header structure HDR
@@ -40,7 +46,7 @@
} orec_t;
enum {
- first_gcflag = 1 << (PYPY_LONG_BIT / 2),
+ first_gcflag = 1L << (PYPY_LONG_BIT / 2),
GCFLAG_GLOBAL = first_gcflag << 0,
GCFLAG_WAS_COPIED = first_gcflag << 1
};
@@ -424,62 +430,68 @@
}
/* lazy/lazy read instrumentation */
-long stm_read_word(void* addr, long offset)
-{
- struct tx_descriptor *d = thread_descriptor;
- volatile orec_t *o = get_orec(addr);
- owner_version_t ovt;
+#define STM_READ_WORD(SIZE, TYPE) \
+TYPE stm_read_int##SIZE(void* addr, long offset) \
+{ \
+ struct tx_descriptor *d = thread_descriptor; \
+ volatile orec_t *o = get_orec(addr); \
+ owner_version_t ovt; \
+ \
+ assert(sizeof(TYPE) == SIZE); \
+ \
+ if ((o->tid & GCFLAG_WAS_COPIED) != 0) \
+ { \
+ /* Look up in the thread-local dictionary. */ \
+ wlog_t *found; \
+ REDOLOG_FIND(d->redolog, addr, found, goto not_found); \
+ orec_t *localobj = (orec_t *)found->val; \
+ assert((localobj->tid & GCFLAG_GLOBAL) == 0); \
+ return *(TYPE *)(((char *)localobj) + offset); \
+ \
+ not_found:; \
+ } \
+ \
+ /* XXX try to remove this check from the main path */ \
+ if (is_main_thread(d)) \
+ return *(TYPE *)(((char *)addr) + offset); \
+ \
+ retry: \
+ /* read the orec BEFORE we read anything else */ \
+ ovt = o->version; \
+ CFENCE; \
+ \
+ /* this tx doesn't hold any locks, so if the lock for this addr is \
+ held, there is contention. A lock is never hold for too long, \
+ so spinloop until it is released. */ \
+ if (IS_LOCKED_OR_NEWER(ovt, d->start_time)) \
+ { \
+ if (IS_LOCKED(ovt)) { \
+ tx_spinloop(7); \
+ goto retry; \
+ } \
+ /* else this location is too new, scale forward */ \
+ owner_version_t newts = get_global_timestamp(d) & ~1; \
+ validate_fast(d, 1); \
+ d->start_time = newts; \
+ } \
+ \
+ /* orec is unlocked, with ts <= start_time. read the location */ \
+ TYPE tmp = *(TYPE *)(((char *)addr) + offset); \
+ \
+ /* postvalidate AFTER reading addr: */ \
+ CFENCE; \
+ if (__builtin_expect(o->version != ovt, 0)) \
+ goto retry; /* oups, try again */ \
+ \
+ oreclist_insert(&d->reads, (orec_t*)o); \
+ \
+ return tmp; \
+}
- if ((o->tid & GCFLAG_WAS_COPIED) != 0)
- {
- /* Look up in the thread-local dictionary. */
- wlog_t *found;
- REDOLOG_FIND(d->redolog, addr, found, goto not_found);
- orec_t *localobj = (orec_t *)found->val;
-#ifdef RPY_STM_ASSERT
- assert((localobj->tid & GCFLAG_GLOBAL) == 0);
-#endif
- return *(long *)(((char *)localobj) + offset);
-
- not_found:;
- }
-
- // XXX try to remove this check from the main path
- if (is_main_thread(d))
- return *(long *)(((char *)addr) + offset);
-
- retry:
- // read the orec BEFORE we read anything else
- ovt = o->version;
- CFENCE;
-
- // this tx doesn't hold any locks, so if the lock for this addr is held,
- // there is contention. A lock is never hold for too long, so spinloop
- // until it is released.
- if (IS_LOCKED_OR_NEWER(ovt, d->start_time))
- {
- if (IS_LOCKED(ovt)) {
- tx_spinloop(7);
- goto retry;
- }
- // else this location is too new, scale forward
- owner_version_t newts = get_global_timestamp(d) & ~1;
- validate_fast(d, 1);
- d->start_time = newts;
- }
-
- // orec is unlocked, with ts <= start_time. read the location
- long tmp = *(long *)(((char *)addr) + offset);
-
- // postvalidate AFTER reading addr:
- CFENCE;
- if (__builtin_expect(o->version != ovt, 0))
- goto retry; /* oups, try again */
-
- oreclist_insert(&d->reads, (orec_t*)o);
-
- return tmp;
-}
+STM_READ_WORD(1, char)
+STM_READ_WORD(2, short)
+STM_READ_WORD(4, int)
+STM_READ_WORD(8, long long)
static struct tx_descriptor *descriptor_init(_Bool is_main_thread)
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
@@ -1,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.gc.stmgc import PRIMITIVE_SIZES
from pypy.translator.stm import _rffi_stm
@@ -28,9 +29,10 @@
lltype.Void)
tldict_enum = smexternal('stm_tldict_enum', [CALLBACK], lltype.Void)
- stm_read_word = smexternal('stm_read_word',
- [llmemory.Address, lltype.Signed],
- lltype.Signed)
+ for _size, _TYPE in PRIMITIVE_SIZES.items():
+ _name = 'stm_read_int%d' % _size
+ locals()[_name] = smexternal(_name, [llmemory.Address, lltype.Signed],
+ _TYPE)
stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
[llmemory.Address,
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
@@ -4,6 +4,8 @@
from pypy.translator.stm.stmgcintf import StmOperations, CALLBACK, GETSIZE
from pypy.rpython.memory.gc import stmgc
+WORD = stmgc.WORD
+
stm_operations = StmOperations()
DEFAULT_TLS = lltype.Struct('DEFAULT_TLS')
@@ -12,6 +14,10 @@
('x', lltype.Signed),
('y', lltype.Signed))
+# xxx a lot of casts to convince rffi to give us a regular integer :-(
+SIZEOFHDR = rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT,
+ rffi.sizeof(S1.hdr)))
+
def test_set_get_del():
# assume that they are really thread-local; not checked here
@@ -57,7 +63,6 @@
def test_tldict_large(self):
content = {}
- WORD = rffi.sizeof(lltype.Signed)
for i in range(12000):
key = random.randrange(1000, 2000) * WORD
a1 = rffi.cast(llmemory.Address, key)
@@ -97,8 +102,8 @@
a1 = llmemory.cast_ptr_to_adr(s1)
a2 = llmemory.cast_ptr_to_adr(s2)
stm_operations.tldict_add(a1, a2)
- res = stm_operations.stm_read_word(llmemory.cast_ptr_to_adr(s1),
- rffi.sizeof(S1.hdr)) # 'x'
+ reader = getattr(stm_operations, 'stm_read_int%d' % WORD)
+ res = reader(llmemory.cast_ptr_to_adr(s1), SIZEOFHDR) # 'x'
lltype.free(s1, flavor='raw')
if copied:
lltype.free(s2, flavor='raw')
@@ -119,6 +124,24 @@
assert res == 84084
test_stm_read_word_transactional_thread.in_main_thread = False
+ def test_stm_read_int1(self):
+ S2 = lltype.Struct('S2', ('hdr', stmgc.StmGC.HDR),
+ ('c1', lltype.Char),
+ ('c2', lltype.Char),
+ ('c3', lltype.Char))
+ s2 = lltype.malloc(S2, flavor='raw')
+ s2.hdr.tid = stmgc.GCFLAG_GLOBAL | stmgc.GCFLAG_WAS_COPIED
+ s2.hdr.version = llmemory.NULL
+ s2.c1 = 'A'
+ s2.c2 = 'B'
+ s2.c3 = 'C'
+ reader = stm_operations.stm_read_int1
+ r1 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 0) # c1
+ r2 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 1) # c2
+ r3 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 2) # c3
+ lltype.free(s2, flavor='raw')
+ assert r1 == 'A' and r2 == 'B' and r3 == 'C'
+
def test_stm_size_getter(self):
def getsize(addr):
xxx
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit