$NetBSD: patch-ah,v 1.2 2003/07/09 15:13:03 markd Exp $

--- mcop_mt/threads_posix.cc.orig	2002-03-25 22:13:17.000000000 +0000
+++ mcop_mt/threads_posix.cc
@@ -34,7 +34,151 @@
 #endif
 
 #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>
 
@@ -187,10 +330,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)
