[pypy-commit] pypy default: merged upstream

alex_gaynor noreply at buildbot.pypy.org
Sat Jun 28 01:42:03 CEST 2014


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r72259:50a337a2e4f2
Date: 2014-06-27 16:41 -0700
http://bitbucket.org/pypy/pypy/changeset/50a337a2e4f2/

Log:	merged upstream

diff --git a/rpython/translator/c/src/thread_gil.c b/rpython/translator/c/src/thread_gil.c
--- a/rpython/translator/c/src/thread_gil.c
+++ b/rpython/translator/c/src/thread_gil.c
@@ -38,15 +38,14 @@
 
 long rpy_fastgil = 1;
 long rpy_waiting_threads = -42;    /* GIL not initialized */
-static mutex_t mutex_gil_stealer;
-static mutex_t mutex_gil;
+static mutex1_t mutex_gil_stealer;
+static mutex2_t mutex_gil;
 
 void RPyGilAllocate(void)
 {
     assert(RPY_FASTGIL_LOCKED(rpy_fastgil));
-    mutex_init(&mutex_gil_stealer);
-    mutex_init(&mutex_gil);
-    mutex_lock(&mutex_gil);
+    mutex1_init(&mutex_gil_stealer);
+    mutex2_init_locked(&mutex_gil);
     rpy_waiting_threads = 0;
 }
 
@@ -80,14 +79,15 @@
            first-in-first-out order, this will nicely give the threads
            a round-robin chance.
         */
-        mutex_lock(&mutex_gil_stealer);
+        mutex1_lock(&mutex_gil_stealer);
+        mutex2_loop_start(&mutex_gil);
 
         /* We are now the stealer thread.  Steals! */
         while (1) {
             /* Sleep for one interval of time.  We may be woken up earlier
                if 'mutex_gil' is released.
             */
-            if (mutex_lock_timeout(&mutex_gil, 0.0001)) {   /* 0.1 ms... */
+            if (mutex2_lock_timeout(&mutex_gil, 0.0001)) {   /* 0.1 ms... */
                 /* We arrive here if 'mutex_gil' was recently released
                    and we just relocked it.
                  */
@@ -107,7 +107,8 @@
             /* Otherwise, loop back. */
         }
         atomic_decrement(&rpy_waiting_threads);
-        mutex_unlock(&mutex_gil_stealer);
+        mutex2_loop_stop(&mutex_gil);
+        mutex1_unlock(&mutex_gil_stealer);
 
         RESTORE_ERRNO();
     }
@@ -140,7 +141,7 @@
 
     /* Explicitly release the 'mutex_gil'.
      */
-    mutex_unlock(&mutex_gil);
+    mutex2_unlock(&mutex_gil);
 
     /* Now nobody has got the GIL, because 'mutex_gil' is released (but
        rpy_fastgil is still locked).  Call RPyGilAcquire().  It will
diff --git a/rpython/translator/c/src/thread_nt.c b/rpython/translator/c/src/thread_nt.c
--- a/rpython/translator/c/src/thread_nt.c
+++ b/rpython/translator/c/src/thread_nt.c
@@ -196,33 +196,46 @@
 /* GIL code                                                 */
 /************************************************************/
 
-typedef HANDLE mutex_t;   /* a semaphore, on Windows */
+typedef HANDLE mutex2_t;   /* a semaphore, on Windows */
 
 static void gil_fatal(const char *msg) {
     fprintf(stderr, "Fatal error in the GIL: %s\n", msg);
     abort();
 }
 
-static inline void mutex_init(mutex_t *mutex) {
+static inline void mutex2_init(mutex2_t *mutex) {
     *mutex = CreateSemaphore(NULL, 1, 1, NULL);
     if (*mutex == NULL)
         gil_fatal("CreateSemaphore failed");
 }
 
-static inline void mutex_lock(mutex_t *mutex) {
+static inline void mutex2_lock(mutex2_t *mutex) {
     WaitForSingleObject(*mutex, INFINITE);
 }
 
-static inline void mutex_unlock(mutex_t *mutex) {
+static inline void mutex2_unlock(mutex2_t *mutex) {
     ReleaseSemaphore(*mutex, 1, NULL);
 }
 
-static inline int mutex_lock_timeout(mutex_t *mutex, double delay)
+static inline void mutex2_init_locked(mutex2_t *mutex) {
+    mutex2_init(mutex);
+    mutex2_lock(mutex);
+}
+
+static inline void mutex2_loop_start(mutex2_t *mutex) { }
+static inline void mutex2_loop_stop(mutex2_t *mutex) { }
+
+static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay)
 {
     DWORD result = WaitForSingleObject(*mutex, (DWORD)(delay * 1000.0 + 0.999));
     return (result != WAIT_TIMEOUT);
 }
 
+#define mutex1_t      mutex2_t
+#define mutex1_init   mutex2_init
+#define mutex1_lock   mutex2_lock
+#define mutex1_unlock mutex2_unlock
+
 #ifdef _M_IA64
 /* On Itanium, use 'acquire' memory ordering semantics */
 #define lock_test_and_set(ptr, value)  InterlockedExchangeAcquire(ptr, value)
diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c
--- a/rpython/translator/c/src/thread_pthread.c
+++ b/rpython/translator/c/src/thread_pthread.c
@@ -479,7 +479,7 @@
 
 #define ASSERT_STATUS(call)                             \
     if (call != 0) {                                    \
-        fprintf(stderr, "Fatal error: " #call "\n");    \
+        perror("Fatal error: " #call);                  \
         abort();                                        \
     }
 
@@ -495,27 +495,42 @@
     t->tv_nsec = nsec;
 }
 
-typedef pthread_mutex_t mutex_t;
+typedef pthread_mutex_t mutex1_t;
 
-static inline void mutex_init(mutex_t *mutex) {
+static inline void mutex1_init(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_init(mutex, pthread_mutexattr_default));
 }
-static inline void mutex_lock(mutex_t *mutex) {
+static inline void mutex1_lock(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_lock(mutex));
 }
-static inline void mutex_unlock(mutex_t *mutex) {
+static inline void mutex1_unlock(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_unlock(mutex));
 }
-static inline int mutex_lock_timeout(mutex_t *mutex, double delay) {
+
+/************************************************************/
+#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
+/************************************************************/
+/* NB. the test above should cover two features: clock_gettime() and
+   pthread_mutex_timedlock().  It's unclear that there is a measurable
+   benefit in using pthread_mutex_timedlock(), but there is certainly
+   one in using clock_gettime(). */
+
+#define mutex2_t      mutex1_t
+#define mutex2_init   mutex1_init
+#define mutex2_lock   mutex1_lock
+#define mutex2_unlock mutex1_unlock
+
+static inline void mutex2_init_locked(mutex2_t *mutex) {
+    mutex2_init(mutex);
+    mutex2_lock(mutex);
+}
+
+static inline void mutex2_loop_start(mutex2_t *mutex) { }
+static inline void mutex2_loop_stop(mutex2_t *mutex) { }
+
+static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay) {
     struct timespec t;
-#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
     clock_gettime(CLOCK_REALTIME, &t);
-#else
-    struct timeval tv;
-    RPY_GETTIMEOFDAY(&tv);
-    t.tv_sec = tv.tv_sec;
-    t.tv_nsec = tv.tv_usec * 1000 + 999;
-#endif
     timespec_add(&t, delay);
     int error_from_timedlock = pthread_mutex_timedlock(mutex, &t);
     if (error_from_timedlock == ETIMEDOUT)
@@ -523,6 +538,58 @@
     ASSERT_STATUS(error_from_timedlock);
     return 1;
 }
+
+/************************************************************/
+#else
+/************************************************************/
+
+typedef struct {
+    char locked;
+    pthread_mutex_t mut;
+    pthread_cond_t cond;
+} mutex2_t;
+
+static inline void mutex2_init_locked(mutex2_t *mutex) {
+    mutex->locked = 1;
+    ASSERT_STATUS(pthread_mutex_init(&mutex->mut, pthread_mutexattr_default));
+    ASSERT_STATUS(pthread_cond_init(&mutex->cond, pthread_condattr_default));
+}
+static inline void mutex2_unlock(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_lock(&mutex->mut));
+    mutex->locked = 0;
+    ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut));
+    ASSERT_STATUS(pthread_cond_signal(&mutex->cond));
+}
+static inline void mutex2_loop_start(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_lock(&mutex->mut));
+}
+static inline void mutex2_loop_stop(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut));
+}
+static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay) {
+    if (mutex->locked) {
+        struct timespec t;
+        struct timeval tv;
+        RPY_GETTIMEOFDAY(&tv);
+        t.tv_sec = tv.tv_sec;
+        t.tv_nsec = tv.tv_usec * 1000 + 999;
+        timespec_add(&t, delay);
+        int error_from_timedwait = pthread_cond_timedwait(
+                                       &mutex->cond, &mutex->mut, &t);
+        if (error_from_timedwait != ETIMEDOUT) {
+            ASSERT_STATUS(error_from_timedwait);
+        }
+    }
+    int result = !mutex->locked;
+    mutex->locked = 1;
+    return result;
+}
+
+/************************************************************/
+#endif                                     /* _POSIX_TIMERS */
+/************************************************************/
+
+
 #define lock_test_and_set(ptr, value)  __sync_lock_test_and_set(ptr, value)
 #define atomic_increment(ptr)          __sync_fetch_and_add(ptr, 1)
 #define atomic_decrement(ptr)          __sync_fetch_and_sub(ptr, 1)


More information about the pypy-commit mailing list