[pypy-commit] pypy stm: Improve targetdemo.

arigo noreply at buildbot.pypy.org
Thu Nov 3 10:38:54 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r48680:755507f9382b
Date: 2011-11-03 10:38 +0100
http://bitbucket.org/pypy/pypy/changeset/755507f9382b/

Log:	Improve targetdemo.

diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -306,6 +306,7 @@
 
 AroundFnPtr = lltype.Ptr(lltype.FuncType([], lltype.Void))
 class AroundState:
+    _alloc_flavor_ = "raw"
     def _freeze_(self):
         self.before = None    # or a regular RPython function
         self.after = None     # or a regular RPython function
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
@@ -140,9 +140,17 @@
   }
 }
 
+static _Bool is_inevitable_or_inactive(struct tx_descriptor *d)
+{
+  return d->setjmp_buf == NULL;
+}
+
 static _Bool is_inevitable(struct tx_descriptor *d)
 {
-  return d->setjmp_buf == NULL;
+#ifdef RPY_STM_ASSERT
+  assert(d->transaction_active);
+#endif
+  return is_inevitable_or_inactive(d);
 }
 
 /*** run the redo log to commit a transaction, and release the locks */
@@ -249,6 +257,7 @@
   assert(d->transaction_active);
   d->transaction_active = 0;
 #endif
+  d->setjmp_buf = NULL;
 }
 
 static void tx_cleanup(struct tx_descriptor *d)
@@ -261,9 +270,10 @@
 
 static void tx_restart(struct tx_descriptor *d)
 {
+  jmp_buf *env = d->setjmp_buf;
   tx_cleanup(d);
   tx_spinloop(0);
-  longjmp(*d->setjmp_buf, 1);
+  longjmp(*env, 1);
 }
 
 /*** increase the abort count and restart the transaction */
@@ -335,6 +345,30 @@
 #ifdef USE_PTHREAD_MUTEX
 /* mutex: only to avoid busy-looping too much in tx_spinloop() below */
 static pthread_mutex_t mutex_inevitable = PTHREAD_MUTEX_INITIALIZER;
+# ifdef RPY_STM_ASSERT
+void mutex_lock(void)
+{
+  unsigned long pself = (unsigned long)pthread_self();
+  if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE,
+                                      "%lx: mutex inev locking...\n", pself);
+  pthread_mutex_lock(&mutex_inevitable);
+  if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE,
+                                      "%lx: mutex inev locked\n", pself);
+}
+void mutex_unlock(void)
+{
+  unsigned long pself = (unsigned long)pthread_self();
+  pthread_mutex_unlock(&mutex_inevitable);
+  if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE,
+                                      "%lx: mutex inev unlocked\n", pself);
+}
+# else
+#  define mutex_lock()    pthread_mutex_lock(&mutex_inevitable)
+#  define mutex_unlock()  pthread_mutex_unlock(&mutex_inevitable)
+# endif
+#else
+# define mutex_lock()     /* nothing */
+# define mutex_unlock()   /* nothing */
 #endif
 
 #ifdef COMMIT_OTHER_INEV
@@ -436,10 +470,8 @@
           d->start_time = curts - 1;
         }
       tx_spinloop(4);
-#ifdef USE_PTHREAD_MUTEX
-      pthread_mutex_lock(&mutex_inevitable);
-      pthread_mutex_unlock(&mutex_inevitable);
-#endif
+      mutex_lock();
+      mutex_unlock();
     }
   acquireLocks(d);
 }
@@ -465,15 +497,16 @@
   // run the redo log, and release the locks
   tx_redo(d);
 
-#ifdef USE_PTHREAD_MUTEX
-  pthread_mutex_unlock(&mutex_inevitable);
-#endif
+  mutex_unlock();
 }
 
 /* lazy/lazy read instrumentation */
 long stm_read_word(long* addr)
 {
   struct tx_descriptor *d = thread_descriptor;
+#ifdef RPY_STM_ASSERT
+  assert(d->transaction_active);
+#endif
 
   // check writeset first
   wlog_t* found;
@@ -535,6 +568,9 @@
 void stm_write_word(long* addr, long val)
 {
   struct tx_descriptor *d = thread_descriptor;
+#ifdef RPY_STM_ASSERT
+  assert(d->transaction_active);
+#endif
   redolog_insert(&d->redolog, addr, val);
 }
 
@@ -647,9 +683,7 @@
           unsigned long ts = get_global_timestamp(d);
           assert(ts & 1);
           set_global_timestamp(d, ts - 1);
-#ifdef USE_PTHREAD_MUTEX
-          pthread_mutex_unlock(&mutex_inevitable);
-#endif
+          mutex_unlock();
         }
       d->num_commits++;
       common_cleanup(d);
@@ -723,17 +757,17 @@
   if (PYPY_HAVE_DEBUG_PRINTS)
     {
       fprintf(PYPY_DEBUG_FILE, "%s%s\n", why,
+              (!d->transaction_active) ? " (inactive)" :
               is_inevitable(d) ? " (already inevitable)" : "");
     }
-  assert(d->transaction_active);
 #endif
 
-  if (is_inevitable(d))
+  if (is_inevitable_or_inactive(d))
     {
 #ifdef RPY_STM_ASSERT
       PYPY_DEBUG_STOP("stm-inevitable");
 #endif
-      return;  /* I am already inevitable */
+      return;  /* I am already inevitable, or not in a transaction at all */
     }
 
   while (1)
@@ -744,26 +778,20 @@
           validate_fast(d, 2);
           d->start_time = curtime & ~1;
         }
-#ifdef USE_PTHREAD_MUTEX
-      pthread_mutex_lock(&mutex_inevitable);
-#endif
+      mutex_lock();
       if (curtime & 1)   /* there is, or was, already an inevitable thread */
         {
           /* should we spinloop here, or abort (and likely come back
              in try_inevitable() very soon)?  unclear.  For now
              let's try to spinloop, after the waiting done by
              acquiring the mutex */
-#ifdef USE_PTHREAD_MUTEX
-          pthread_mutex_unlock(&mutex_inevitable);
-#endif
+          mutex_unlock();
           tx_spinloop(6);
           continue;
         }
       if (change_global_timestamp(d, curtime, curtime + 1))
         break;
-#ifdef USE_PTHREAD_MUTEX
-      pthread_mutex_unlock(&mutex_inevitable);
-#endif
+      mutex_unlock();
     }
   d->setjmp_buf = NULL;   /* inevitable from now on */
 #ifdef COMMIT_OTHER_INEV
@@ -789,18 +817,14 @@
   unsigned long curtime;
 
  retry:
-#ifdef USE_PTHREAD_MUTEX
-  pthread_mutex_lock(&mutex_inevitable);   /* possibly waiting here */
-#endif
+  mutex_lock();   /* possibly waiting here */
 
   while (1)
     {
       curtime = global_timestamp;
       if (curtime & 1)
         {
-#ifdef USE_PTHREAD_MUTEX
-          pthread_mutex_unlock(&mutex_inevitable);
-#endif
+          mutex_unlock();
           tx_spinloop(5);
           goto retry;
         }
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
@@ -32,13 +32,34 @@
     print "thread done."
 
 
+
+# __________  temp, move me somewhere else  __________
+
+from pypy.rlib.objectmodel import invoke_around_extcall
+
+def before_external_call():
+    # this function must not raise, in such a way that the exception
+    # transformer knows that it cannot raise!
+    rstm.commit_transaction()
+before_external_call._gctransformer_hint_cannot_collect_ = True
+before_external_call._dont_reach_me_in_del_ = True
+
+def after_external_call():
+    rstm.begin_inevitable_transaction()
+after_external_call._gctransformer_hint_cannot_collect_ = True
+after_external_call._dont_reach_me_in_del_ = True
+
+
 # __________  Entry point  __________
 
 def entry_point(argv):
+    invoke_around_extcall(before_external_call, after_external_call)
     print "hello world"
     for i in range(NUM_THREADS):
         ll_thread.start_new_thread(run_me, ())
+    print "sleeping..."
     time.sleep(10)
+    print "done sleeping."
     return 0
 
 # _____ Define and setup target ___


More information about the pypy-commit mailing list