[pypy-commit] pypy stm-gc: Implement and test stm_tldict_{lookup, add}.

arigo noreply at buildbot.pypy.org
Sat Feb 4 18:38:13 CET 2012


Author: Armin Rigo <arigo at tunes.org>
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


More information about the pypy-commit mailing list