177 lines
3.2 KiB
Plaintext
177 lines
3.2 KiB
Plaintext
$NetBSD: patch-ah,v 1.4 2008/10/28 11:32:07 markd Exp $
|
|
|
|
--- mcop_mt/threads_posix.cc.orig 2005-09-10 20:13:32.000000000 +1200
|
|
+++ mcop_mt/threads_posix.cc
|
|
@@ -27,13 +27,158 @@
|
|
/* only compile this if we have libpthread available */
|
|
#ifdef HAVE_LIBPTHREAD
|
|
|
|
+#include <signal.h>
|
|
#include <gsl/gslconfig.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <pthread.h>
|
|
+#include <unistd.h>
|
|
+#ifdef _POSIX_SEMAPHORES
|
|
#include <semaphore.h>
|
|
+#else
|
|
+
|
|
+#include <errno.h>
|
|
+#include <limits.h>
|
|
+
|
|
+struct sem_t {
|
|
+ pthread_mutex_t lock;
|
|
+ pthread_cond_t gtzero;
|
|
+ unsigned int count;
|
|
+ unsigned int nwaiters;
|
|
+};
|
|
+
|
|
+static int sem_init(sem_t *, int, unsigned int);
|
|
+static int sem_destroy(sem_t *);
|
|
+static int sem_wait(sem_t *);
|
|
+static int sem_trywait(sem_t *);
|
|
+static int sem_post(sem_t *);
|
|
+static int sem_getvalue(sem_t *, int *);
|
|
+
|
|
+static int
|
|
+sem_init(sem_t *sem, int pshared, unsigned int value)
|
|
+{
|
|
+
|
|
+ /*
|
|
+ * Range check the arguments.
|
|
+ */
|
|
+ if (pshared != 0) {
|
|
+ errno = EPERM;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (value > INT_MAX) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Initialize the semaphore.
|
|
+ */
|
|
+ if (pthread_mutex_init(&sem->lock, NULL) != 0) {
|
|
+ errno = ENOMEM;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (pthread_cond_init(&sem->gtzero, NULL) != 0) {
|
|
+ pthread_mutex_destroy(&sem->lock);
|
|
+ errno = ENOMEM;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ sem->count = value;
|
|
+ sem->nwaiters = 0;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+sem_destroy(sem_t *sem)
|
|
+{
|
|
+
|
|
+ /* Make sure there are no waiters. */
|
|
+ pthread_mutex_lock(&sem->lock);
|
|
+ if (sem->nwaiters > 0) {
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+ errno = EBUSY;
|
|
+ return -1;
|
|
+ }
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+
|
|
+ pthread_mutex_destroy(&sem->lock);
|
|
+ pthread_cond_destroy(&sem->gtzero);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+sem_wait(sem_t *sem)
|
|
+{
|
|
+ pthread_testcancel();
|
|
+
|
|
+ pthread_mutex_lock(&sem->lock);
|
|
+
|
|
+ while (sem->count == 0) {
|
|
+ sem->nwaiters++;
|
|
+ pthread_cond_wait(&sem->gtzero, &sem->lock);
|
|
+ }
|
|
+ sem->count--;
|
|
+
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+
|
|
+ pthread_testcancel();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+sem_trywait(sem_t *sem)
|
|
+{
|
|
+ int retval;
|
|
+
|
|
+ pthread_mutex_lock(&sem->lock);
|
|
+
|
|
+ if (sem->count > 0) {
|
|
+ sem->count--;
|
|
+ retval = 0;
|
|
+ } else {
|
|
+ errno = EAGAIN;
|
|
+ retval = -1;
|
|
+ }
|
|
+
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static int
|
|
+sem_post(sem_t *sem)
|
|
+{
|
|
+ pthread_mutex_lock(&sem->lock);
|
|
+
|
|
+ sem->count++;
|
|
+ if (sem->nwaiters > 0) {
|
|
+ pthread_cond_broadcast(&sem->gtzero);
|
|
+ }
|
|
+
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+sem_getvalue(sem_t *sem, int *sval)
|
|
+{
|
|
+
|
|
+ pthread_mutex_lock(&sem->lock);
|
|
+ *sval = sem->count;
|
|
+ pthread_mutex_unlock(&sem->lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
#include <debug.h>
|
|
#include <string.h>
|
|
|
|
@@ -186,10 +331,12 @@ public:
|
|
Thread_impl(Thread *thread) : thread(thread) {
|
|
}
|
|
void setPriority(int priority) {
|
|
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
|
|
struct sched_param sp;
|
|
sp.sched_priority = priority;
|
|
if (pthread_setschedparam(pthread, SCHED_FIFO, &sp))
|
|
arts_debug("Thread::setPriority: sched_setscheduler failed");
|
|
+#endif
|
|
}
|
|
static pthread_key_t privateDataKey;
|
|
static void *threadStartInternal(void *impl)
|