summaryrefslogtreecommitdiffstats
path: root/Python/thread_pthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'Python/thread_pthread.h')
-rw-r--r--Python/thread_pthread.h205
1 files changed, 42 insertions, 163 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index ffc791c..44e2552 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -18,6 +18,18 @@
#ifndef THREAD_STACK_SIZE
#define THREAD_STACK_SIZE 0 /* use default stack size */
#endif
+
+#if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+ /* The default stack size for new threads on OSX is small enough that
+ * we'll get hard crashes instead of 'maximum recursion depth exceeded'
+ * exceptions.
+ *
+ * The default stack size below is the minimal stack size where a
+ * simple recursive function doesn't cause a hard crash.
+ */
+#undef THREAD_STACK_SIZE
+#define THREAD_STACK_SIZE 0x400000
+#endif
/* for safety, ensure a viable minimum stacksize */
#define THREAD_STACK_MIN 0x8000 /* 32kB */
#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
@@ -64,8 +76,7 @@
/* Whether or not to use semaphores directly rather than emulating them with
* mutexes and condition variables:
*/
-#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
- defined(HAVE_SEM_TIMEDWAIT))
+#if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)
# define USE_SEMAPHORES
#else
# undef USE_SEMAPHORES
@@ -84,26 +95,6 @@
#endif
-/* We assume all modern POSIX systems have gettimeofday() */
-#ifdef GETTIMEOFDAY_NO_TZ
-#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
-#else
-#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
-#endif
-
-#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
-do { \
- struct timeval tv; \
- GETTIMEOFDAY(&tv); \
- tv.tv_usec += microseconds % 1000000; \
- tv.tv_sec += microseconds / 1000000; \
- tv.tv_sec += tv.tv_usec / 1000000; \
- tv.tv_usec %= 1000000; \
- ts.tv_sec = tv.tv_sec; \
- ts.tv_nsec = tv.tv_usec * 1000; \
-} while(0)
-
-
/* A pthread mutex isn't sufficient to model the Python lock type
* because, according to Draft 5 of the docs (P1003.4a/D5), both of the
* following are undefined:
@@ -316,56 +307,31 @@ fix_status(int status)
return (status == -1) ? errno : status;
}
-PyLockStatus
-PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
- int intr_flag)
+int
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
{
- PyLockStatus success;
+ int success;
sem_t *thelock = (sem_t *)lock;
int status, error = 0;
- struct timespec ts;
- dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
- lock, microseconds, intr_flag));
+ dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- if (microseconds > 0)
- MICROSECONDS_TO_TIMESPEC(microseconds, ts);
do {
- if (microseconds > 0)
- status = fix_status(sem_timedwait(thelock, &ts));
- else if (microseconds == 0)
- status = fix_status(sem_trywait(thelock));
- else
+ if (waitflag)
status = fix_status(sem_wait(thelock));
- /* Retry if interrupted by a signal, unless the caller wants to be
- notified. */
- } while (!intr_flag && status == EINTR);
-
- /* Don't check the status if we're stopping because of an interrupt. */
- if (!(intr_flag && status == EINTR)) {
- if (microseconds > 0) {
- if (status != ETIMEDOUT)
- CHECK_STATUS("sem_timedwait");
- }
- else if (microseconds == 0) {
- if (status != EAGAIN)
- CHECK_STATUS("sem_trywait");
- }
- else {
- CHECK_STATUS("sem_wait");
- }
- }
+ else
+ status = fix_status(sem_trywait(thelock));
+ } while (status == EINTR); /* Retry if interrupted by a signal */
- if (status == 0) {
- success = PY_LOCK_ACQUIRED;
- } else if (intr_flag && status == EINTR) {
- success = PY_LOCK_INTR;
- } else {
- success = PY_LOCK_FAILURE;
+ if (waitflag) {
+ CHECK_STATUS("sem_wait");
+ } else if (status != EAGAIN) {
+ CHECK_STATUS("sem_trywait");
}
- dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
- lock, microseconds, intr_flag, success));
+ success = (status == 0) ? 1 : 0;
+
+ dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
return success;
}
@@ -404,12 +370,6 @@ PyThread_allocate_lock(void)
status = pthread_mutex_init(&lock->mut,
pthread_mutexattr_default);
CHECK_STATUS("pthread_mutex_init");
- /* Mark the pthread mutex underlying a Python mutex as
- pure happens-before. We can't simply mark the
- Python-level mutex as a mutex because it can be
- acquired and released in different threads, which
- will cause errors. */
- _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
status = pthread_cond_init(&lock->lock_released,
pthread_condattr_default);
@@ -442,69 +402,37 @@ PyThread_free_lock(PyThread_type_lock lock)
free((void *)thelock);
}
-PyLockStatus
-PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
- int intr_flag)
+int
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
{
- PyLockStatus success;
+ int success;
pthread_lock *thelock = (pthread_lock *)lock;
int status, error = 0;
- dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
- lock, microseconds, intr_flag));
+ dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
status = pthread_mutex_lock( &thelock->mut );
CHECK_STATUS("pthread_mutex_lock[1]");
+ success = thelock->locked == 0;
- if (thelock->locked == 0) {
- success = PY_LOCK_ACQUIRED;
- } else if (microseconds == 0) {
- success = PY_LOCK_FAILURE;
- } else {
- struct timespec ts;
- if (microseconds > 0)
- MICROSECONDS_TO_TIMESPEC(microseconds, ts);
+ if ( !success && waitflag ) {
/* continue trying until we get the lock */
/* mut must be locked by me -- part of the condition
* protocol */
- success = PY_LOCK_FAILURE;
- while (success == PY_LOCK_FAILURE) {
- if (microseconds > 0) {
- status = pthread_cond_timedwait(
- &thelock->lock_released,
- &thelock->mut, &ts);
- if (status == ETIMEDOUT)
- break;
- CHECK_STATUS("pthread_cond_timed_wait");
- }
- else {
- status = pthread_cond_wait(
- &thelock->lock_released,
- &thelock->mut);
- CHECK_STATUS("pthread_cond_wait");
- }
-
- if (intr_flag && status == 0 && thelock->locked) {
- /* We were woken up, but didn't get the lock. We probably received
- * a signal. Return PY_LOCK_INTR to allow the caller to handle
- * it and retry. */
- success = PY_LOCK_INTR;
- break;
- } else if (status == 0 && !thelock->locked) {
- success = PY_LOCK_ACQUIRED;
- } else {
- success = PY_LOCK_FAILURE;
- }
+ while ( thelock->locked ) {
+ status = pthread_cond_wait(&thelock->lock_released,
+ &thelock->mut);
+ CHECK_STATUS("pthread_cond_wait");
}
+ success = 1;
}
- if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
+ if (success) thelock->locked = 1;
status = pthread_mutex_unlock( &thelock->mut );
CHECK_STATUS("pthread_mutex_unlock[1]");
- if (error) success = PY_LOCK_FAILURE;
- dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
- lock, microseconds, intr_flag, success));
+ if (error) success = 0;
+ dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
return success;
}
@@ -531,12 +459,6 @@ PyThread_release_lock(PyThread_type_lock lock)
#endif /* USE_SEMAPHORES */
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
-}
-
/* set the thread stack size.
* Return 0 if size is valid, -1 if size is invalid,
* -2 if setting stack size is not supported.
@@ -581,46 +503,3 @@ _pythread_pthread_set_stacksize(size_t size)
}
#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
-
-#define Py_HAVE_NATIVE_TLS
-
-int
-PyThread_create_key(void)
-{
- pthread_key_t key;
- int fail = pthread_key_create(&key, NULL);
- return fail ? -1 : key;
-}
-
-void
-PyThread_delete_key(int key)
-{
- pthread_key_delete(key);
-}
-
-void
-PyThread_delete_key_value(int key)
-{
- pthread_setspecific(key, NULL);
-}
-
-int
-PyThread_set_key_value(int key, void *value)
-{
- int fail;
- void *oldValue = pthread_getspecific(key);
- if (oldValue != NULL)
- return 0;
- fail = pthread_setspecific(key, value);
- return fail ? -1 : 0;
-}
-
-void *
-PyThread_get_key_value(int key)
-{
- return pthread_getspecific(key);
-}
-
-void
-PyThread_ReInitTLS(void)
-{}