Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r52096:92d4a43c2004
Date: 2012-02-04 18:37 +0100
http://bitbucket.org/pypy/pypy/changeset/92d4a43c2004/
Log: Implement and test stm_tldict_{lookup,add}.
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
@@ -147,6 +147,8 @@
/*** run the redo log to commit a transaction, and release the locks */
static void tx_redo(struct tx_descriptor *d)
{
+ abort();
+#if 0
owner_version_t newver = d->end_time;
wlog_t *item;
/* loop in "forward" order: in this order, if there are duplicate orecs
@@ -163,6 +165,7 @@
*o = newver;
}
} REDOLOG_LOOP_END;
+#endif
}
/*** on abort, release locks and restore the old version number. */
@@ -858,4 +861,21 @@
descriptor_done();
}
+void *stm_tldict_lookup(void *key)
+{
+ struct tx_descriptor *d = thread_descriptor;
+ wlog_t* found;
+ REDOLOG_FIND(d->redolog, key, found, goto not_found);
+ return found->val;
+
+ not_found:
+ return NULL;
+}
+
+void stm_tldict_add(void *key, void *value)
+{
+ struct tx_descriptor *d = thread_descriptor;
+ redolog_insert(&d->redolog, key, value);
+}
+
#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
@@ -16,6 +16,9 @@
void *stm_get_tls(void);
void stm_del_tls(void);
+void *stm_tldict_lookup(void *);
+void stm_tldict_add(void *, void *);
+
#ifdef RPY_STM_ASSERT
diff --git a/pypy/translator/stm/src_stm/lists.c
b/pypy/translator/stm/src_stm/lists.c
--- a/pypy/translator/stm/src_stm/lists.c
+++ b/pypy/translator/stm/src_stm/lists.c
@@ -21,8 +21,8 @@
#define TREE_MASK ((TREE_ARITY - 1) * sizeof(void*))
typedef struct {
- long* addr;
- long val;
+ void* addr;
+ void *val;
owner_version_t p; // the previous version number (if locked)
} wlog_t;
@@ -120,7 +120,7 @@
return (wlog_t *)entry; /* may be NULL */
}
-static void redolog_insert(struct RedoLog *redolog, long* addr, long val);
+static void redolog_insert(struct RedoLog *redolog, void* addr, void *val);
static void _redolog_grow(struct RedoLog *redolog, long extra)
{
@@ -156,7 +156,7 @@
return result;
}
-static void redolog_insert(struct RedoLog *redolog, long* addr, long val)
+static void redolog_insert(struct RedoLog *redolog, void* addr, void *val)
{
retry:;
wlog_t *wlog;
@@ -164,6 +164,7 @@
int shift = 0;
char *p = (char *)(redolog->toplevel.items);
char *entry;
+ assert((key & (sizeof(void*)-1)) == 0); /* only for aligned keys */
while (1)
{
p += (key >> shift) & TREE_MASK;
@@ -178,12 +179,8 @@
else
{
wlog_t *wlog1 = (wlog_t *)entry;
- if (wlog1->addr == addr)
- {
- /* overwrite and that's it */
- wlog1->val = val;
- return;
- }
+ /* the key must not already be present */
+ assert(wlog1->addr != addr);
/* collision: there is already a different wlog here */
wlog_node_t *node = (wlog_node_t *)
_redolog_grab(redolog, sizeof(wlog_node_t));
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
@@ -1,8 +1,11 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
+import random
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.translator.stm.stmgcintf import StmOperations
stm_operations = StmOperations()
+DEFAULT_TLS = lltype.Struct('DEFAULT_TLS')
+
def test_set_get_del():
# assume that they are really thread-local; not checked here
@@ -12,3 +15,50 @@
assert stm_operations.get_tls() == a
stm_operations.del_tls()
lltype.free(s, flavor='raw')
+
+
+class TestStmGcIntf:
+
+ 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)
+ stm_operations.set_tls(a)
+
+ def teardown_method(self, meth):
+ stm_operations.del_tls()
+
+ def test_set_get_del(self):
+ a = llmemory.cast_ptr_to_adr(self.tls)
+ assert stm_operations.get_tls() == a
+
+ def test_tldict(self):
+ a1 = rffi.cast(llmemory.Address, 0x4020)
+ a2 = rffi.cast(llmemory.Address, 10002)
+ a3 = rffi.cast(llmemory.Address, 0x4028)
+ a4 = rffi.cast(llmemory.Address, 10004)
+ #
+ assert stm_operations.tldict_lookup(a1) == llmemory.NULL
+ stm_operations.tldict_add(a1, a2)
+ assert stm_operations.tldict_lookup(a1) == a2
+ #
+ assert stm_operations.tldict_lookup(a3) == llmemory.NULL
+ stm_operations.tldict_add(a3, a4)
+ assert stm_operations.tldict_lookup(a3) == a4
+ assert stm_operations.tldict_lookup(a1) == a2
+
+ 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)
+ a2 = stm_operations.tldict_lookup(a1)
+ if key in content:
+ assert a2 == content[key]
+ else:
+ assert a2 == llmemory.NULL
+ a2 = rffi.cast(llmemory.Address, random.randrange(2000, 9999))
+ stm_operations.tldict_add(a1, a2)
+ content[key] = a2
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit