[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