summaryrefslogtreecommitdiff
path: root/lib/libc_r
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/arch/alpha/uthread_machdep.h10
-rw-r--r--lib/libc_r/arch/hppa/uthread_machdep.h6
-rw-r--r--lib/libc_r/arch/i386/uthread_machdep.h9
-rw-r--r--lib/libc_r/arch/m68k/uthread_machdep.h6
-rw-r--r--lib/libc_r/arch/m88k/uthread_machdep.h6
-rw-r--r--lib/libc_r/arch/mips/uthread_machdep.h6
-rw-r--r--lib/libc_r/arch/powerpc/uthread_machdep.h6
-rw-r--r--lib/libc_r/arch/sparc/uthread_machdep.h20
-rw-r--r--lib/libc_r/include/pthread.h31
-rw-r--r--lib/libc_r/include/pthread_np.h10
-rw-r--r--lib/libc_r/include/sched.h8
-rw-r--r--lib/libc_r/include/spinlock.h6
-rw-r--r--lib/libc_r/sys/Makefile.inc18
-rw-r--r--lib/libc_r/sys/uthread_error.c2
-rw-r--r--lib/libc_r/uthread/Makefile.inc12
-rw-r--r--lib/libc_r/uthread/pthread_private.h348
-rw-r--r--lib/libc_r/uthread/uthread_accept.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_destroy.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_getdetachstate.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_getinheritsched.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_getschedparam.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_getschedpolicy.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_getscope.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstackaddr.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstacksize.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_init.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_setdetachstate.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_setinheritsched.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_setprio.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_setschedparam.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_setschedpolicy.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_setscope.c3
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstackaddr.c5
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstacksize.c5
-rw-r--r--lib/libc_r/uthread/uthread_autoinit.c10
-rw-r--r--lib/libc_r/uthread/uthread_bind.c5
-rw-r--r--lib/libc_r/uthread/uthread_cancel.c33
-rw-r--r--lib/libc_r/uthread/uthread_clean.c5
-rw-r--r--lib/libc_r/uthread/uthread_close.c35
-rw-r--r--lib/libc_r/uthread/uthread_cond.c85
-rw-r--r--lib/libc_r/uthread/uthread_condattr_destroy.c5
-rw-r--r--lib/libc_r/uthread/uthread_condattr_init.c5
-rw-r--r--lib/libc_r/uthread/uthread_connect.c8
-rw-r--r--lib/libc_r/uthread/uthread_create.c85
-rw-r--r--lib/libc_r/uthread/uthread_detach.c24
-rw-r--r--lib/libc_r/uthread/uthread_dup.c5
-rw-r--r--lib/libc_r/uthread/uthread_dup2.c5
-rw-r--r--lib/libc_r/uthread/uthread_equal.c5
-rw-r--r--lib/libc_r/uthread/uthread_execve.c8
-rw-r--r--lib/libc_r/uthread/uthread_exit.c96
-rw-r--r--lib/libc_r/uthread/uthread_fchmod.c5
-rw-r--r--lib/libc_r/uthread/uthread_fchown.c5
-rw-r--r--lib/libc_r/uthread/uthread_fcntl.c5
-rw-r--r--lib/libc_r/uthread/uthread_fd.c86
-rw-r--r--lib/libc_r/uthread/uthread_file.c43
-rw-r--r--lib/libc_r/uthread/uthread_find_thread.c38
-rw-r--r--lib/libc_r/uthread/uthread_flock.c5
-rw-r--r--lib/libc_r/uthread/uthread_fork.c112
-rw-r--r--lib/libc_r/uthread/uthread_fstat.c5
-rw-r--r--lib/libc_r/uthread/uthread_fstatfs.c5
-rw-r--r--lib/libc_r/uthread/uthread_fsync.c5
-rw-r--r--lib/libc_r/uthread/uthread_gc.c162
-rw-r--r--lib/libc_r/uthread/uthread_getdirentries.c5
-rw-r--r--lib/libc_r/uthread/uthread_getpeername.c7
-rw-r--r--lib/libc_r/uthread/uthread_getprio.c3
-rw-r--r--lib/libc_r/uthread/uthread_getschedparam.c3
-rw-r--r--lib/libc_r/uthread/uthread_getsockname.c5
-rw-r--r--lib/libc_r/uthread/uthread_getsockopt.c5
-rw-r--r--lib/libc_r/uthread/uthread_init.c209
-rw-r--r--lib/libc_r/uthread/uthread_ioctl.c5
-rw-r--r--lib/libc_r/uthread/uthread_join.c29
-rw-r--r--lib/libc_r/uthread/uthread_kern.c1558
-rw-r--r--lib/libc_r/uthread/uthread_kill.c69
-rw-r--r--lib/libc_r/uthread/uthread_listen.c5
-rw-r--r--lib/libc_r/uthread/uthread_mattr_init.c3
-rw-r--r--lib/libc_r/uthread/uthread_mattr_kind_np.c8
-rw-r--r--lib/libc_r/uthread/uthread_msync.c9
-rw-r--r--lib/libc_r/uthread/uthread_multi_np.c5
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c208
-rw-r--r--lib/libc_r/uthread/uthread_mutex_prioceiling.c3
-rw-r--r--lib/libc_r/uthread/uthread_mutex_protocol.c3
-rw-r--r--lib/libc_r/uthread/uthread_mutexattr_destroy.c5
-rw-r--r--lib/libc_r/uthread/uthread_nanosleep.c46
-rw-r--r--lib/libc_r/uthread/uthread_once.c5
-rw-r--r--lib/libc_r/uthread/uthread_open.c7
-rw-r--r--lib/libc_r/uthread/uthread_pipe.c5
-rw-r--r--lib/libc_r/uthread/uthread_poll.c183
-rw-r--r--lib/libc_r/uthread/uthread_priority_queue.c194
-rw-r--r--lib/libc_r/uthread/uthread_queue.c125
-rw-r--r--lib/libc_r/uthread/uthread_read.c24
-rw-r--r--lib/libc_r/uthread/uthread_readv.c6
-rw-r--r--lib/libc_r/uthread/uthread_recvfrom.c8
-rw-r--r--lib/libc_r/uthread/uthread_recvmsg.c5
-rw-r--r--lib/libc_r/uthread/uthread_resume_np.c18
-rw-r--r--lib/libc_r/uthread/uthread_rwlock.c4
-rw-r--r--lib/libc_r/uthread/uthread_rwlockattr.c4
-rw-r--r--lib/libc_r/uthread/uthread_select.c196
-rw-r--r--lib/libc_r/uthread/uthread_self.c5
-rw-r--r--lib/libc_r/uthread/uthread_sendmsg.c5
-rw-r--r--lib/libc_r/uthread/uthread_sendto.c7
-rw-r--r--lib/libc_r/uthread/uthread_seterrno.c5
-rw-r--r--lib/libc_r/uthread/uthread_setprio.c3
-rw-r--r--lib/libc_r/uthread/uthread_setschedparam.c18
-rw-r--r--lib/libc_r/uthread/uthread_setsockopt.c5
-rw-r--r--lib/libc_r/uthread/uthread_shutdown.c5
-rw-r--r--lib/libc_r/uthread/uthread_sig.c223
-rw-r--r--lib/libc_r/uthread/uthread_sigaction.c8
-rw-r--r--lib/libc_r/uthread/uthread_sigaltstack.c4
-rw-r--r--lib/libc_r/uthread/uthread_sigblock.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigmask.c5
-rw-r--r--lib/libc_r/uthread/uthread_signal.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigpending.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigprocmask.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigsetmask.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigsuspend.c5
-rw-r--r--lib/libc_r/uthread/uthread_sigwait.c42
-rw-r--r--lib/libc_r/uthread/uthread_single_np.c5
-rw-r--r--lib/libc_r/uthread/uthread_socket.c5
-rw-r--r--lib/libc_r/uthread/uthread_socketpair.c7
-rw-r--r--lib/libc_r/uthread/uthread_spec.c7
-rw-r--r--lib/libc_r/uthread/uthread_spinlock.c10
-rw-r--r--lib/libc_r/uthread/uthread_stack.c97
-rw-r--r--lib/libc_r/uthread/uthread_suspend_np.c18
-rw-r--r--lib/libc_r/uthread/uthread_switch_np.c3
-rw-r--r--lib/libc_r/uthread/uthread_vfork.c6
-rw-r--r--lib/libc_r/uthread/uthread_wait4.c9
-rw-r--r--lib/libc_r/uthread/uthread_write.c27
-rw-r--r--lib/libc_r/uthread/uthread_writev.c6
-rw-r--r--lib/libc_r/uthread/uthread_yield.c5
130 files changed, 2646 insertions, 2379 deletions
diff --git a/lib/libc_r/arch/alpha/uthread_machdep.h b/lib/libc_r/arch/alpha/uthread_machdep.h
index 7ee0653367d..9a7c52da977 100644
--- a/lib/libc_r/arch/alpha/uthread_machdep.h
+++ b/lib/libc_r/arch/alpha/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/alpha machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.4 1999/02/04 23:37:39 niklas Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.5 1999/11/25 07:01:27 d Exp $
*/
/* save the floating point state of a thread */
@@ -50,11 +50,11 @@ do { \
{ \
/* entry */ \
(thr)->saved_jmp_buf[2] = (long) entry; \
- (thr)->saved_jmp_buf[4+R_RA] = 0; \
- (thr)->saved_jmp_buf[4+R_T12] = (long) entry; \
+ (thr)->saved_jmp_buf[4 + R_RA] = 0; \
+ (thr)->saved_jmp_buf[4 + R_T12] = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf[4 + R_SP] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
+ (thr)->saved_jmp_buf[4 + R_SP] = (long) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
diff --git a/lib/libc_r/arch/hppa/uthread_machdep.h b/lib/libc_r/arch/hppa/uthread_machdep.h
index 773bd90e22f..0d80d718ded 100644
--- a/lib/libc_r/arch/hppa/uthread_machdep.h
+++ b/lib/libc_r/arch/hppa/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/hppa machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.2 1999/01/17 23:49:48 d Exp $$
+ * $OpenBSD: uthread_machdep.h,v 1.3 1999/11/25 07:01:27 d Exp $$
*/
/* save the floating point state of a thread */
@@ -23,8 +23,8 @@
/* entry */ \
(thr)->saved_jmp_buf[5] = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf[2] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
+ (thr)->saved_jmp_buf[2] = (long) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
diff --git a/lib/libc_r/arch/i386/uthread_machdep.h b/lib/libc_r/arch/i386/uthread_machdep.h
index cac445509ca..dab5c413932 100644
--- a/lib/libc_r/arch/i386/uthread_machdep.h
+++ b/lib/libc_r/arch/i386/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/i386 machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.5 1999/03/10 09:50:33 d Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.6 1999/11/25 07:01:28 d Exp $
*/
#include <machine/reg.h>
@@ -59,9 +59,10 @@ struct _machdep_struct {
/* entry */ \
(thr)->saved_jmp_buf.mjb_eip = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf.mjb_esp = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
- - sizeof(double); \
+ (thr)->saved_jmp_buf.mjb_esp = \
+ (long) (thr)->stack->base + \
+ (thr)->stack->size \
+ - sizeof(double); \
}
static __inline int
diff --git a/lib/libc_r/arch/m68k/uthread_machdep.h b/lib/libc_r/arch/m68k/uthread_machdep.h
index 4ed702981b5..8bda374924d 100644
--- a/lib/libc_r/arch/m68k/uthread_machdep.h
+++ b/lib/libc_r/arch/m68k/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/m68k machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.2 1999/01/17 23:49:49 d Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.3 1999/11/25 07:01:28 d Exp $
*/
/* save the floating point state of a thread */
@@ -23,8 +23,8 @@
/* entry */ \
(thr)->saved_jmp_buf[5] = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf[2] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
+ (thr)->saved_jmp_buf[2] = (long) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
diff --git a/lib/libc_r/arch/m88k/uthread_machdep.h b/lib/libc_r/arch/m88k/uthread_machdep.h
index dcad59d851d..0fcad5cf0ae 100644
--- a/lib/libc_r/arch/m88k/uthread_machdep.h
+++ b/lib/libc_r/arch/m88k/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/m88k machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.1 1999/03/03 06:00:10 smurph Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.2 1999/11/25 07:01:28 d Exp $
*/
/* save the floating point state of a thread */
@@ -23,8 +23,8 @@
/* entry */ \
(thr)->saved_jmp_buf[5] = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf[2] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
+ (thr)->saved_jmp_buf[2] = (long) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
diff --git a/lib/libc_r/arch/mips/uthread_machdep.h b/lib/libc_r/arch/mips/uthread_machdep.h
index 6052b2003da..89fb399d629 100644
--- a/lib/libc_r/arch/mips/uthread_machdep.h
+++ b/lib/libc_r/arch/mips/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/mips machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.3 1999/01/17 23:49:49 d Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.4 1999/11/25 07:01:28 d Exp $
*/
#include <machine/regnum.h>
@@ -23,8 +23,8 @@
j->sc_regs[RA] = j->sc_pc; /* for gdb */ \
j->sc_pc = (int)entry; \
/* stack */ \
- j->sc_regs[SP] = (int) (thr)->stack \
- + (pattr)->stacksize_attr \
+ j->sc_regs[SP] = (int) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
diff --git a/lib/libc_r/arch/powerpc/uthread_machdep.h b/lib/libc_r/arch/powerpc/uthread_machdep.h
index bd713b5ff0e..6041279d95e 100644
--- a/lib/libc_r/arch/powerpc/uthread_machdep.h
+++ b/lib/libc_r/arch/powerpc/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/powerpc machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.3 1999/04/21 03:45:21 rahnds Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.4 1999/11/25 07:01:29 d Exp $
*/
/* save the floating point state of a thread */
@@ -24,8 +24,8 @@
(thr)->saved_jmp_buf[JMP_lr] = \
(unsigned int) entry; \
(thr)->saved_jmp_buf[JMP_r1] = \
- ((unsigned int) (thr)->stack \
- + (pattr)->stacksize_attr \
+ ((unsigned int) (thr)->stack->base \
+ + (thr)->stack->size \
- 0x4) & ~0xf; \
{ \
unsigned int *pbacklink = \
diff --git a/lib/libc_r/arch/sparc/uthread_machdep.h b/lib/libc_r/arch/sparc/uthread_machdep.h
index c922b49fd0c..46ffd6dc92c 100644
--- a/lib/libc_r/arch/sparc/uthread_machdep.h
+++ b/lib/libc_r/arch/sparc/uthread_machdep.h
@@ -1,7 +1,7 @@
/*
* OpenBSD/sparc machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.2 1999/01/17 23:49:49 d Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.3 1999/11/25 07:01:29 d Exp $
*/
#include <sys/signal.h>
@@ -9,13 +9,13 @@
/* save the floating point state of a thread */
#define _thread_machdep_save_float_state(thr) \
{ \
- /* XXX tdb */ \
+ /* XXX tdb */ \
}
/* restore the floating point state of a thread */
#define _thread_machdep_restore_float_state(thr) \
{ \
- /* XXX tdb */ \
+ /* XXX tdb */ \
}
/* initialise the jmpbuf stack frame so it continues from entry */
@@ -25,19 +25,13 @@
/* entry */ \
(thr)->saved_jmp_buf[1] = (long) entry; \
/* stack */ \
- (thr)->saved_jmp_buf[0] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
+ (thr)->saved_jmp_buf[0] = (long) (thr)->stack->base \
+ + (thr)->stack->size \
- sizeof(double); \
}
-/*
- * XXX high chance of longjmp botch (see libc/arch/sparc/gen/_setjmp.S)
- * because it uses the frame pointer to pop off frames.. we don't want
- * that.. what to do? fudge %fp? do our own setjmp?
- */
-#define _thread_machdep_longjmp(a,v) _longjmp(a,v)
-#define _thread_machdep_setjmp(a) _setjmp(a)
-
+#define _thread_machdep_longjmp(a,v) _longjmp(a,v)
+#define _thread_machdep_setjmp(a) _setjmp(a)
typedef jmp_buf _machdep_jmp_buf;
struct _machdep_struct {
diff --git a/lib/libc_r/include/pthread.h b/lib/libc_r/include/pthread.h
index 108f4d2de41..d94bbe8173f 100644
--- a/lib/libc_r/include/pthread.h
+++ b/lib/libc_r/include/pthread.h
@@ -30,13 +30,19 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: pthread.h,v 1.8 1999/06/15 00:10:37 d Exp $
+ * $OpenBSD: pthread.h,v 1.9 1999/11/25 07:01:29 d Exp $
*
+ * $FreeBSD: pthread.h,v 1.13 1999/07/31 08:36:07 rse Exp $
*/
#ifndef _PTHREAD_H_
#define _PTHREAD_H_
#ifdef _POSIX_THREADS
+#ifdef notyet
+#warning -pthread option no longer needed - upgrade gcc
+#endif
+#undef _POSIX_THREADS
+#endif
/*
* Header files.
@@ -62,7 +68,7 @@
* Note that those commented out are not currently supported by the
* implementation.
*/
-
+#define _POSIX_THREADS
#define _POSIX_THREAD_ATTR_STACKADDR
#define _POSIX_THREAD_ATTR_STACKSIZE
#define _POSIX_THREAD_PRIORITY_SCHEDULING
@@ -113,7 +119,6 @@ struct pthread_mutex_attr;
struct pthread_once;
struct pthread_rwlock;
struct pthread_rwlockattr;
-struct sched_param;
/*
* Primitive system data type definitions required by P1003.1c.
@@ -209,7 +214,6 @@ int pthread_attr_init __P((pthread_attr_t *));
int pthread_attr_setstacksize __P((pthread_attr_t *, size_t));
int pthread_attr_setstackaddr __P((pthread_attr_t *, void *));
int pthread_attr_setdetachstate __P((pthread_attr_t *, int));
-int pthread_cancel __P((pthread_t));
void pthread_cleanup_pop __P((int execute));
void pthread_cleanup_push __P((void (*routine) (void *),
void *routine_arg));
@@ -252,7 +256,7 @@ int pthread_mutex_lock __P((pthread_mutex_t *));
int pthread_mutex_trylock __P((pthread_mutex_t *));
int pthread_mutex_unlock __P((pthread_mutex_t *));
int pthread_once __P((pthread_once_t *,
- void (*init_routine) (void)));
+ void (*) (void)));
int pthread_rwlock_destroy __P((pthread_rwlock_t *));
int pthread_rwlock_init __P((pthread_rwlock_t *,
const pthread_rwlockattr_t *));
@@ -268,12 +272,13 @@ int pthread_rwlockattr_setpshared __P((pthread_rwlockattr_t *,
int *));
int pthread_rwlockattr_destroy __P((pthread_rwlockattr_t *));
pthread_t pthread_self __P((void));
-int pthread_setcancelstate __P((int, int *));
-int pthread_setcanceltype __P((int, int *));
int pthread_setspecific __P((pthread_key_t, const void *));
int pthread_sigmask __P((int, const sigset_t *, sigset_t *));
-void pthread_testcancel __P((void));
+int pthread_cancel __P((pthread_t));
+int pthread_setcancelstate __P((int, int *));
+int pthread_setcanceltype __P((int, int *));
+void pthread_testcancel __P((void));
int pthread_getprio __P((pthread_t));
int pthread_setprio __P((pthread_t, int));
@@ -326,15 +331,13 @@ int pthread_attr_setcleanup __P((pthread_attr_t *,
void (*routine) (void *), void *));
-#if 0
+#ifdef notyet
/*
- * Single Unix Specification v2 (UNIX98) also wants these:
+ * Single Unix Specification v2 (UNIX98) defines these:
*/
-
#define PTHREAD_PRIO_INHERIT
#define PTHREAD_PRIO_NONE
#define PTHREAD_PRIO_PROTECT
-
int pthread_attr_getguardsize __P((const pthread_attr_t *,
size_t *));
int pthread_attr_setguardsize __P((const pthread_attr_t *,
@@ -343,12 +346,8 @@ int pthread_getconcurrency __P((void));
int pthread_mutexattr_gettype __P((const pthread_mutexattr_t *,
int *));
int pthread_setconcurrency __P((int));
-
#endif /* susv2 */
__END_DECLS
-#else /* ! _POSIX_THREADS */
-#warning "included <pthread.h> without -pthread compiler option"
-#endif /* ! _POSIX_THREADS */
#endif /* _PTHREAD_H_ */
diff --git a/lib/libc_r/include/pthread_np.h b/lib/libc_r/include/pthread_np.h
index 6f8b7b7ef44..a6071d9e4d0 100644
--- a/lib/libc_r/include/pthread_np.h
+++ b/lib/libc_r/include/pthread_np.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_np.h,v 1.2 1999/05/26 00:17:41 d Exp $ */
+/* $OpenBSD: pthread_np.h,v 1.3 1999/11/25 07:01:29 d Exp $ */
/*
* Copyright (c) 1996-98 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -48,11 +48,11 @@ int pthread_multi_np __P((void));
int pthread_resume_np __P((pthread_t));
int pthread_single_np __P((void));
int pthread_suspend_np __P((pthread_t));
-int pthread_mutexattr_getkind_np __P((pthread_mutexattr_t attr));
-int pthread_mutexattr_setkind_np __P((pthread_mutexattr_t *attr, int kind));
+int pthread_mutexattr_getkind_np __P((pthread_mutexattr_t));
+int pthread_mutexattr_setkind_np __P((pthread_mutexattr_t *, int));
void pthread_set_name_np __P((pthread_t, char *));
-int pthread_switch_add_np (pthread_switch_routine_t routine);
-int pthread_switch_delete_np (pthread_switch_routine_t routine);
+int pthread_switch_add_np __P((pthread_switch_routine_t));
+int pthread_switch_delete_np __P((pthread_switch_routine_t));
__END_DECLS
#endif
diff --git a/lib/libc_r/include/sched.h b/lib/libc_r/include/sched.h
index 292edf7b2e3..46f8e9703d8 100644
--- a/lib/libc_r/include/sched.h
+++ b/lib/libc_r/include/sched.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched.h,v 1.2 1999/03/10 10:03:52 d Exp $ */
+/* $OpenBSD: sched.h,v 1.3 1999/11/25 07:01:29 d Exp $ */
#ifndef _SCHED_H_
#define _SCHED_H_
@@ -40,6 +40,10 @@
#include <sys/types.h> /* For pid_t */
+#ifndef KERNEL
+#include <time.h> /* Per P1003.4 */
+#endif
+
/* Scheduling policies
*/
#define SCHED_FIFO 1
@@ -53,8 +57,6 @@ struct sched_param
#ifndef KERNEL
#include <sys/cdefs.h>
-#include <time.h> /* Per P1003.4 */
-#include <sys/time.h>
__BEGIN_DECLS
int sched_setparam __P((pid_t, const struct sched_param *));
diff --git a/lib/libc_r/include/spinlock.h b/lib/libc_r/include/spinlock.h
index 4da4a9ec500..772331be377 100644
--- a/lib/libc_r/include/spinlock.h
+++ b/lib/libc_r/include/spinlock.h
@@ -29,8 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: spinlock.h,v 1.3 1999/01/18 00:03:34 d Exp $
- * $OpenBSD: spinlock.h,v 1.3 1999/01/18 00:03:34 d Exp $
+ * $Id: spinlock.h,v 1.4 1999/11/25 07:01:29 d Exp $
+ * $OpenBSD: spinlock.h,v 1.4 1999/11/25 07:01:29 d Exp $
*
* Lock definitions used in both libc and libpthread.
*
@@ -61,6 +61,8 @@ typedef struct {
#define _SPINLOCK(_lck) _spinlock(_lck)
#endif
+#define _SPINLOCK_INIT(_lck) _SPINUNLOCK(_lck)
+
/*
* Thread function prototype definitions:
*/
diff --git a/lib/libc_r/sys/Makefile.inc b/lib/libc_r/sys/Makefile.inc
index 2c4ee0df2fd..79b6afe2a4d 100644
--- a/lib/libc_r/sys/Makefile.inc
+++ b/lib/libc_r/sys/Makefile.inc
@@ -1,17 +1,23 @@
-# $Id: Makefile.inc,v 1.3 1999/01/06 05:36:18 d Exp $
-# $OpenBSD: Makefile.inc,v 1.3 1999/01/06 05:36:18 d Exp $
+# $Id: Makefile.inc,v 1.4 1999/11/25 07:01:29 d Exp $
+# $OpenBSD: Makefile.inc,v 1.4 1999/11/25 07:01:29 d Exp $
.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
-SRCS+= uthread_error.c _atomic_lock.c slow_atomic_lock.c
+SRCS+= uthread_error.c _atomic_lock.c slow_atomic_lock.c
SRCS+= _sys_aliases.c
CLEANFILES += _sys_aliases.c
_sys_aliases.c: ${.CURDIR}/Makefile ${LIBCSRCDIR}/sys/Makefile.inc
- (echo '#include <sys/cdefs.h>'; \
- for fn in ${ASM:R} ${PSEUDO:R} ""; do \
+ echo '#include <sys/cdefs.h>' > ${.TARGET}
+.if ${MACHINE} == "alpha"
+ # This kludge will disappear when we shift to -lpthread
+ echo '#define __indr_reference(old,new)' \
+ '__asm__(".globl "#new";"#new": jmp $$31,"#old)' > ${.TARGET}
+
+.endif
+ for fn in ${ASM:R} ${PSEUDO:R} ""; do \
case $$fn in ${HIDDEN_SYSCALLS:.o=|}"") : stays hidden ;; \
*) echo "__indr_reference(_thread_sys_$$fn,$$fn);";; \
esac; \
- done ) > ${.TARGET}
+ done >> ${.TARGET}
diff --git a/lib/libc_r/sys/uthread_error.c b/lib/libc_r/sys/uthread_error.c
index 545dfb06652..08740ed92ff 100644
--- a/lib/libc_r/sys/uthread_error.c
+++ b/lib/libc_r/sys/uthread_error.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_error.c,v 1.2 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
@@ -31,6 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_error.c,v 1.2 1999/08/05 12:14:13 deischen Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
diff --git a/lib/libc_r/uthread/Makefile.inc b/lib/libc_r/uthread/Makefile.inc
index 56a6b0046ba..00022b16eb6 100644
--- a/lib/libc_r/uthread/Makefile.inc
+++ b/lib/libc_r/uthread/Makefile.inc
@@ -1,5 +1,5 @@
-# $Id: Makefile.inc,v 1.8 1999/06/15 00:07:39 d Exp $
-# $OpenBSD: Makefile.inc,v 1.8 1999/06/15 00:07:39 d Exp $
+# $OpenBSD: Makefile.inc,v 1.9 1999/11/25 07:01:30 d Exp $
+# $FreeBSD: Makefile.inc,v 1.19 1999/08/28 00:03:19 peter Exp $
# uthread sources
.PATH: ${.CURDIR}/uthread
@@ -15,7 +15,6 @@ SRCS+= \
uthread_attr_getschedparam.c \
uthread_attr_getschedpolicy.c \
uthread_attr_getscope.c \
- uthread_attr_setstackaddr.c \
uthread_attr_getstackaddr.c \
uthread_attr_getstacksize.c \
uthread_attr_setcreatesuspend_np.c \
@@ -28,7 +27,6 @@ SRCS+= \
uthread_attr_setstacksize.c \
uthread_autoinit.c \
uthread_bind.c \
- uthread_fchflags.c \
uthread_cancel.c \
uthread_clean.c \
uthread_close.c \
@@ -63,7 +61,7 @@ SRCS+= \
uthread_getschedparam.c \
uthread_getsockname.c \
uthread_getsockopt.c \
- uthread_info.c \
+ uthread_info_openbsd.c \
uthread_init.c \
uthread_ioctl.c \
uthread_join.c \
@@ -82,9 +80,8 @@ SRCS+= \
uthread_once.c \
uthread_open.c \
uthread_pipe.c \
- uthread_priority_queue.c \
uthread_poll.c \
- uthread_queue.c \
+ uthread_priority_queue.c \
uthread_read.c \
uthread_readv.c \
uthread_recvfrom.c \
@@ -116,6 +113,7 @@ SRCS+= \
uthread_socketpair.c \
uthread_spec.c \
uthread_spinlock.c \
+ uthread_stack.c \
uthread_suspend_np.c \
uthread_switch_np.c \
uthread_vfork.c \
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index 69a36e13477..f49d0eb257e 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: pthread_private.h,v 1.18 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -31,15 +32,12 @@
*
* Private thread definitions for the uthread kernel.
*
- * $OpenBSD: pthread_private.h,v 1.17 1999/09/08 08:21:47 espie Exp $
- *
+ * $FreeBSD: pthread_private.h,v 1.27 1999/09/29 15:18:38 marcel Exp $
*/
#ifndef _PTHREAD_PRIVATE_H
#define _PTHREAD_PRIVATE_H
-#include <paths.h>
-
/*
* Include files.
*/
@@ -51,9 +49,7 @@
#include <sched.h>
#include <spinlock.h>
#include <pthread_np.h>
-#ifndef _NO_UTHREAD_MACHDEP
#include "uthread_machdep.h"
-#endif
/*
* Kernel fatal error handler macro.
@@ -66,33 +62,88 @@
/*
- * Priority queue manipulation macros:
+ * Priority queue manipulation macros (using pqe link):
*/
#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
-#define PTHREAD_PRIOQ_FIRST _pq_first(&_readyq)
+#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
/*
- * Waiting queue manipulation macros:
+ * Waiting queue manipulation macros (using pqe link):
*/
-#define PTHREAD_WAITQ_INSERT(thrd) TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe)
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
+#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
+#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
+#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
+#else
#define PTHREAD_WAITQ_REMOVE(thrd) TAILQ_REMOVE(&_waitingq,thrd,pqe)
+#define PTHREAD_WAITQ_INSERT(thrd) do { \
+ if ((thrd)->wakeup_time.tv_sec == -1) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else { \
+ pthread_t tid = TAILQ_FIRST(&_waitingq); \
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
+ ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \
+ ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \
+ (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
+ tid = TAILQ_NEXT(tid, pqe); \
+ if (tid == NULL) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else \
+ TAILQ_INSERT_BEFORE(tid,thrd,pqe); \
+ } \
+} while (0)
+#define PTHREAD_WAITQ_CLEARACTIVE()
+#define PTHREAD_WAITQ_SETACTIVE()
+#endif
+
+/*
+ * Work queue manipulation macros (using qe link):
+ */
+#define PTHREAD_WORKQ_INSERT(thrd) do { \
+ TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
+ (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+#define PTHREAD_WORKQ_REMOVE(thrd) do { \
+ TAILQ_REMOVE(&_workq,thrd,qe); \
+ (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+
/*
* State change macro without scheduling queue change:
*/
-#define PTHREAD_SET_STATE(thrd, newstate) { \
+#define PTHREAD_SET_STATE(thrd, newstate) do { \
(thrd)->state = newstate; \
(thrd)->fname = __FILE__; \
(thrd)->lineno = __LINE__; \
-}
+} while (0)
/*
* State change macro with scheduling queue change - This must be
* called with preemption deferred (see thread_kern_sched_[un]defer).
*/
-#define PTHREAD_NEW_STATE(thrd, newstate) { \
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if (_thread_kern_new_state != 0) \
+ PANIC("Recursive PTHREAD_NEW_STATE"); \
+ _thread_kern_new_state = 1; \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ _thread_kern_new_state = 0; \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#else
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if ((thrd)->state != newstate) { \
if ((thrd)->state == PS_RUNNING) { \
PTHREAD_PRIOQ_REMOVE(thrd); \
@@ -103,7 +154,8 @@
} \
} \
PTHREAD_SET_STATE(thrd, newstate); \
-}
+} while (0)
+#endif
/*
* Define the signals to be used for scheduling.
@@ -117,15 +169,6 @@
#endif
/*
- * Queue definitions.
- */
-struct pthread_queue {
- struct pthread *q_next;
- struct pthread *q_last;
- void *q_data;
-};
-
-/*
* Priority queues.
*
* XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
@@ -145,14 +188,9 @@ typedef struct pq_queue {
/*
- * Static queue initialization values.
- */
-#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
-
-/*
* TailQ initialization values.
*/
-#define TAILQ_INITIALIZER { NULL, NULL }
+#define TAILQ_INITIALIZER { NULL, NULL }
/*
* Mutex definitions.
@@ -223,7 +261,7 @@ struct pthread_mutex_attr {
*/
enum pthread_cond_type {
COND_TYPE_FAST,
- COND_TYPE_MAX
+#define COND_TYPE_MAX ((int)COND_TYPE_FAST + 1)
};
struct pthread_cond {
@@ -255,8 +293,8 @@ struct pthread_cond_attr {
* Static cond initialization values.
*/
#define PTHREAD_COND_STATIC_INITIALIZER \
- { COND_TYPE_FAST, PTHREAD_QUEUE_INITIALIZER, NULL, NULL, \
- 0, _SPINLOCK_INITIALIZER }
+ { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
+ 0, _SPINLOCK_INITIALIZER }
/*
* Cleanup definitions.
@@ -290,6 +328,13 @@ struct pthread_attr {
* Miscellaneous definitions.
*/
#define PTHREAD_STACK_DEFAULT 65536
+/*
+ * Maximum size of initial thread's stack. This perhaps deserves to be larger
+ * than the stacks of other threads, since many applications are likely to run
+ * almost entirely on this stack.
+ */
+#define PTHREAD_STACK_INITIAL 0x100000
+/* Address immediately beyond the beginning of the initial thread stack. */
#define PTHREAD_DEFAULT_PRIORITY 64
#define PTHREAD_MAX_PRIORITY 126
#define PTHREAD_MIN_PRIORITY 0
@@ -301,12 +346,6 @@ struct pthread_attr {
#define CLOCK_RES_NSEC 10000000
/*
- * Number of microseconds between incremental priority updates for
- * threads that are ready to run, but denied being run.
- */
-#define INC_PRIO_USEC 500000
-
-/*
* Time slice period in microseconds.
*/
#define TIMESLICE_USEC 100000
@@ -343,6 +382,7 @@ enum pthread_state {
PS_FDR_WAIT,
PS_FDW_WAIT,
PS_FILE_WAIT,
+ PS_POLL_WAIT,
PS_SELECT_WAIT,
PS_SLEEP_WAIT,
PS_WAIT_WAIT,
@@ -352,8 +392,8 @@ enum pthread_state {
PS_JOIN,
PS_SUSPENDED,
PS_DEAD,
- PS_DEADLOCK,
- PS_STATE_MAX
+ PS_DEADLOCK
+#define PS_STATE_MAX ((int)PS_DEADLOCK + 1)
};
@@ -375,8 +415,8 @@ struct fd_table_entry {
* state of the lock on the file descriptor.
*/
spinlock_t lock;
- struct pthread_queue r_queue; /* Read queue. */
- struct pthread_queue w_queue; /* Write queue. */
+ TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
+ TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
struct pthread *r_owner; /* Ptr to thread owning read lock. */
struct pthread *w_owner; /* Ptr to thread owning write lock. */
const char *r_fname; /* Ptr to read lock source file name */
@@ -388,11 +428,9 @@ struct fd_table_entry {
int flags; /* Flags used in open. */
};
-struct pthread_select_data {
+struct pthread_poll_data {
int nfds;
- fd_set readfds;
- fd_set writefds;
- fd_set exceptfds;
+ struct pollfd *fds;
};
union pthread_wait_data {
@@ -404,10 +442,21 @@ union pthread_wait_data {
short branch; /* Line number, for debugging. */
const char *fname; /* Source file name for debugging.*/
} fd;
- struct pthread_select_data * select_data;
+ struct pthread_poll_data * poll_data;
spinlock_t *spinlock;
};
+/* Spare thread stack. */
+struct stack {
+ SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
+ void *base; /* Bottom of useful stack */
+ size_t size; /* Size of useful stack */
+ void *redzone; /* Red zone location */
+ void *storage; /* allocated storage */
+};
+
+typedef TAILQ_ENTRY(pthread) pthread_entry_t;
+
/*
* Thread structure.
*/
@@ -425,15 +474,11 @@ struct pthread {
*/
spinlock_t lock;
- /*
- * Pointer to the next thread in the thread linked list.
- */
- struct pthread *nxt;
+ /* Queue entry for list of all threads: */
+ pthread_entry_t tle;
- /*
- * Pointer to the next thread in the dead thread linked list.
- */
- struct pthread *nxt_dead;
+ /* Queue entry for list of dead threads: */
+ pthread_entry_t dle;
/*
* Thread start routine, argument, stack pointer and thread
@@ -441,7 +486,7 @@ struct pthread {
*/
void *(*start_routine)(void *);
void *arg;
- void *stack;
+ struct stack *stack;
struct pthread_attr attr;
/*
@@ -450,6 +495,17 @@ struct pthread {
*/
struct sigcontext saved_sigcontext;
+ /*
+ * Saved jump buffer used in call to longjmp by _thread_kern_sched
+ * if sig_saved is FALSE.
+ */
+ _machdep_jmp_buf saved_jmp_buf;
+
+ /*
+ * Further machine-dependent context, valid if sig_saved is FALSE.
+ */
+ struct _machdep_struct _machdep;
+
/*
* TRUE if the last state saved was a signal context. FALSE if the
* last state saved was a jump buffer.
@@ -484,12 +540,6 @@ struct pthread {
long slice_usec;
/*
- * Cumulative times spent in thread
- */
- struct timeval ru_utime;
- struct timeval ru_stime;
-
- /*
* Incremental priority accumulated by thread while it is ready to
* run but is denied being run.
*/
@@ -510,36 +560,41 @@ struct pthread {
*/
int error;
- /* Join queue for waiting threads: */
- struct pthread_queue join_queue;
+ /* Join queue head and link for waiting threads: */
+ TAILQ_HEAD(join_head, pthread) join_queue;
/*
- * The current thread can belong to only one scheduling queue
- * at a time (ready or waiting queue). It can also belong to
- * a queue of threads waiting on mutexes or condition variables.
- * Use pqe for the scheduling queue link (both ready and waiting),
- * and qe for other links (mutexes and condition variables).
+ * The current thread can belong to only one scheduling queue at
+ * a time (ready or waiting queue). It can also belong to (only)
+ * one of:
*
- * Pointer to queue (if any) on which the current thread is waiting.
+ * o A queue of threads waiting for a mutex
+ * o A queue of threads waiting for a condition variable
+ * o A queue of threads waiting for another thread to terminate
+ * (the join queue above)
+ * o A queue of threads waiting for a file descriptor lock
+ * o A queue of threads needing work done by the kernel thread
+ * (waiting for a spinlock or file I/O)
*
- * XXX The queuing should be changed to use the TAILQ entry below.
- * XXX For the time being, it's hybrid.
+ * Use pqe for the scheduling queue link (both ready and waiting),
+ * and qe for other links.
*/
- struct pthread_queue *queue;
-
- /* Pointer to next element in queue. */
- struct pthread *qnxt;
/* Priority queue entry for this thread: */
- TAILQ_ENTRY(pthread) pqe;
+ pthread_entry_t pqe;
/* Queue entry for this thread: */
- TAILQ_ENTRY(pthread) qe;
+ pthread_entry_t qe;
/* Wait data. */
union pthread_wait_data data;
/*
+ * Allocated for converting select into poll.
+ */
+ struct pthread_poll_data poll_data;
+
+ /*
* Set to TRUE if a blocking operation was
* interrupted by a signal:
*/
@@ -549,25 +604,28 @@ struct pthread {
int signo;
/*
- * Set to non-zero when this thread has deferred thread
- * scheduling. We allow for recursive deferral.
+ * Set to non-zero when this thread has deferred signals.
+ * We allow for recursive deferral.
*/
- int sched_defer_count;
+ int sig_defer_count;
/*
* Set to TRUE if this thread should yield after undeferring
- * thread scheduling.
+ * signals.
*/
- int yield_on_sched_undefer;
+ int yield_on_sig_undefer;
/* Miscellaneous data. */
int flags;
#define PTHREAD_FLAGS_PRIVATE 0x0001
#define PTHREAD_EXITING 0x0002
-#define PTHREAD_FLAGS_QUEUED 0x0004 /* in queue (qe is used) */
-#define PTHREAD_FLAGS_TRACE 0x0008
-#define PTHREAD_CANCELLING 0x0010 /* thread has been cancelled */
-#define PTHREAD_AT_CANCEL_POINT 0x0020 /* thread at cancel point */
+#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/
+#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */
+#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link*/
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link*/
+#define PTHREAD_FLAGS_TRACE 0x0040 /* for debugging purposes */
+#define PTHREAD_FLAGS_CANCELED 0x1000 /* thread has been cancelled */
+#define PTHREAD_FLAGS_CANCELPT 0x2000 /* thread at cancel point */
/*
* Base priority is the user setable and retrievable priority
@@ -590,7 +648,7 @@ struct pthread {
/*
* Active priority is always the maximum of the threads base
* priority and inherited priority. When there is a change
- * in either the real or inherited priority, the active
+ * in either the base or inherited priority, the active
* priority must be recalculated.
*/
char active_priority;
@@ -611,17 +669,6 @@ struct pthread {
struct pthread_cleanup *cleanup;
const char *fname; /* Ptr to source file name */
int lineno; /* Source line number. */
-
- /*
- * Saved jump buffer used in call to longjmp by _thread_kern_sched
- * if sig_saved is FALSE.
- */
- _machdep_jmp_buf saved_jmp_buf;
-
-#ifndef _UTHREAD_MACHDEP
- /* Machine dependent information */
- struct _machdep_struct _machdep;
-#endif
};
/*
@@ -629,14 +676,13 @@ struct pthread {
*/
/* Kernel thread structure used when there are no running threads: */
-extern struct pthread volatile _thread_kern_thread;
-extern struct pthread * volatile _thread_kern_threadp;
+extern struct pthread _thread_kern_thread;
/* Ptr to the thread structure for the running thread: */
extern struct pthread * volatile _thread_run;
/* Ptr to the thread structure for the last user thread to run: */
-extern struct pthread * volatile _last_user_thread;
+extern struct pthread * volatile _last_user_thread;
/*
* Ptr to the thread running in single-threaded mode or NULL if
@@ -644,22 +690,23 @@ extern struct pthread * volatile _last_user_thread;
*/
extern struct pthread * volatile _thread_single;
-/* Ptr to the first thread in the thread linked list: */
-extern struct pthread * volatile _thread_link_list;
+/* List of all threads: */
+typedef TAILQ_HEAD(, pthread) _thread_list_t;
+extern _thread_list_t _thread_list;
/*
* Array of kernel pipe file descriptors that are used to ensure that
* no signals are missed in calls to _select.
*/
-extern int _thread_kern_pipe[2];
-extern int _thread_kern_in_select;
+extern int _thread_kern_pipe[2];
+extern int volatile _queue_signals;
extern int _thread_kern_in_sched;
/* Last time that an incremental priority update was performed: */
extern struct timeval kern_inc_prio_time;
/* Dead threads: */
-extern struct pthread * volatile _thread_dead;
+extern _thread_list_t _dead_list;
/* Initial thread: */
extern struct pthread *_thread_initial;
@@ -682,12 +729,18 @@ extern int _pthread_stdio_flags[3];
/* File table information: */
extern struct fd_table_entry **_thread_fd_table;
+
+/* Table for polling file descriptors: */
+extern struct pollfd *_thread_pfd_table;
+
extern const int dtablecount;
-extern int _thread_dtablesize;
+extern int _thread_dtablesize; /* Descriptor table size. */
+
+extern int _clock_res_nsec; /* Clock resolution in nsec. */
/* Garbage collector mutex and condition variable. */
-extern pthread_mutex_t _gc_mutex;
-extern pthread_cond_t _gc_cond;
+extern pthread_mutex_t _gc_mutex;
+extern pthread_cond_t _gc_cond;
/*
* Array of signal actions for this process.
@@ -698,19 +751,32 @@ extern struct sigaction _thread_sigact[NSIG];
* Scheduling queues:
*/
extern pq_queue_t _readyq;
-typedef TAILQ_HEAD(, pthread) _waitingq_t;
-extern _waitingq_t _waitingq;
+extern _thread_list_t _waitingq;
+
+/*
+ * Work queue:
+ */
+extern _thread_list_t _workq;
-/* Indicates that the waitingq now has threads ready to run. */
-extern volatile int _waitingq_check_reqd;
+/* Tracks the number of threads blocked while waiting for a spinlock. */
+extern volatile int _spinblock_count;
+
+/* Indicates that the signal queue needs to be checked. */
+extern volatile int _sigq_check_reqd;
/* Thread switch hook. */
extern pthread_switch_routine_t _sched_switch_hook;
/*
- * Where SIGINFO writes thread states when /dev/tty cannot be opened
+ * Spare stack queue. Stacks of default size are cached in order to reduce
+ * thread creation time. Spare stacks are used in LIFO order to increase cache
+ * locality.
*/
-#define INFO_DUMP_FILE "/tmp/uthread.dump"
+typedef SLIST_HEAD(, stack) _stack_list_t;
+extern _stack_list_t _stackq;
+
+/* Used for _PTHREADS_INVARIANTS checking. */
+extern int _thread_kern_new_state;
#ifdef _LOCK_DEBUG
#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
@@ -722,6 +788,8 @@ extern pthread_switch_routine_t _sched_switch_hook;
#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
#endif
+extern int __isthreaded;
+
/*
* Function prototype definitions.
*/
@@ -733,49 +801,52 @@ int _thread_fd_lock(int, int, struct timespec *);
int _thread_fd_lock_debug(int, int, struct timespec *,const char *fname,int lineno);
void _dispatch_signals(void);
void _thread_signal(pthread_t, int);
-void _lock_thread(void);
-void _lock_thread_list(void);
-void _unlock_thread(void);
-void _unlock_thread_list(void);
int _mutex_cv_lock(pthread_mutex_t *);
int _mutex_cv_unlock(pthread_mutex_t *);
+int _mutex_reinit(pthread_mutex_t *);
void _mutex_notify_priochange(struct pthread *);
-int _pq_init(struct pq_queue *pq, int, int);
+int _cond_reinit(pthread_cond_t *);
+int _pq_alloc(struct pq_queue *, int, int);
+int _pq_init(struct pq_queue *);
void _pq_remove(struct pq_queue *pq, struct pthread *);
void _pq_insert_head(struct pq_queue *pq, struct pthread *);
void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
struct pthread *_pq_first(struct pq_queue *pq);
-void _thread_exit(const char *, int, const char *)
- __attribute__((noreturn));
+#if defined(_PTHREADS_INVARIANTS)
+void _waitq_insert(pthread_t pthread);
+void _waitq_remove(pthread_t pthread);
+void _waitq_setactive(void);
+void _waitq_clearactive(void);
+#endif
+__dead void _thread_exit(const char *, int, const char *) __attribute__((noreturn));
void _thread_fd_unlock(int, int);
-void _thread_fd_unlock_debug(int, int, char *, int);
+void _thread_fd_unlock_debug(int, int, const char *, int);
void *_thread_cleanup(pthread_t);
void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void);
void _thread_kern_sched(struct sigcontext *);
-void _thread_kern_sched_state(enum pthread_state, const char *, int);
+void _thread_kern_sched_state(enum pthread_state,const char *fname,int lineno);
void _thread_kern_sched_state_unlock(enum pthread_state state,
spinlock_t *lock, char *fname, int lineno);
void _thread_kern_set_timeout(struct timespec *);
-void _thread_kern_sched_defer(void);
-void _thread_kern_sched_undefer(void);
+void _thread_kern_sig_defer(void);
+void _thread_kern_sig_undefer(void);
void _thread_sig_handler(int, int, struct sigcontext *);
+void _thread_sig_handle(int, struct sigcontext *);
+void _thread_sig_init(void);
void _thread_start(void);
void _thread_start_sig_handler(void);
void _thread_seterrno(pthread_t,int);
-void _thread_queue_init(struct pthread_queue *);
-void _thread_queue_enq(struct pthread_queue *, struct pthread *);
-int _thread_queue_remove(struct pthread_queue *, struct pthread *);
int _thread_fd_table_init(int fd);
-struct pthread *_thread_queue_get(struct pthread_queue *);
-struct pthread *_thread_queue_deq(struct pthread_queue *);
pthread_addr_t _thread_gc(pthread_addr_t);
void _thread_enter_cancellation_point(void);
void _thread_leave_cancellation_point(void);
void _thread_cancellation_point(void);
int _thread_slow_atomic_lock(volatile _spinlock_lock_t *);
int _thread_slow_atomic_is_locked(volatile _spinlock_lock_t *);
+struct stack * _thread_stack_alloc(void *, size_t);
+void _thread_stack_free(struct stack *);
/* #include <signal.h> */
#ifdef _USER_SIGNAL_H
@@ -900,7 +971,7 @@ int _thread_sys_fchdir(int);
int _thread_sys_fchown(int, uid_t, gid_t);
int _thread_sys_fsync(int);
int _thread_sys_ftruncate(int, off_t);
-long _thread_sys_fpathconf(int, int);
+long _thread_sys_fpathconf(int, int);
int _thread_sys_pause(void);
int _thread_sys_pipe(int *);
int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
@@ -909,8 +980,7 @@ pid_t _thread_sys_fork(void);
pid_t _thread_sys_tcgetpgrp(int);
ssize_t _thread_sys_read(int, void *, size_t);
ssize_t _thread_sys_write(int, const void *, size_t);
-void _thread_sys__exit(int)
- __attribute__((noreturn));
+__dead void _thread_sys__exit(int) __attribute__((noreturn));
#endif
/* #include <fcntl.h> */
@@ -948,16 +1018,16 @@ ssize_t _thread_sys_writev(int, const struct iovec *, int);
#endif
/* #include <sys/wait.h> */
-#ifdef _SYS_WAIT_H_
+#ifdef _SYS_WAIT_H_
pid_t _thread_sys_wait(int *);
pid_t _thread_sys_waitpid(pid_t, int *, int);
pid_t _thread_sys_wait3(int *, int, struct rusage *);
pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *);
#endif
-/* #include <sys/poll.h> */
+/* #include <poll.h> */
#ifdef _SYS_POLL_H_
-int _thread_sys_poll(struct pollfd[], int, int);
+int _thread_sys_poll(struct pollfd *, unsigned, int);
#endif
/* #include <sys/mman.h> */
diff --git a/lib/libc_r/uthread/uthread_accept.c b/lib/libc_r/uthread/uthread_accept.c
index 95f8c10b56c..db8d078c444 100644
--- a/lib/libc_r/uthread/uthread_accept.c
+++ b/lib/libc_r/uthread/uthread_accept.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_accept.c,v 1.4 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_accept.c,v 1.3 1999/02/16 16:39:59 deraadt Exp $
+ * $FreeBSD: uthread_accept.c,v 1.9 1999/08/28 00:03:20 peter Exp $
*/
#include <errno.h>
#include <unistd.h>
diff --git a/lib/libc_r/uthread/uthread_attr_destroy.c b/lib/libc_r/uthread/uthread_attr_destroy.c
index 51848d5d438..feb0c8309f0 100644
--- a/lib/libc_r/uthread/uthread_attr_destroy.c
+++ b/lib/libc_r/uthread/uthread_attr_destroy.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_destroy.c,v 1.3 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_destroy.c,v 1.2 1999/01/10 23:05:18 d Exp $
+ * $FreeBSD: uthread_attr_destroy.c,v 1.4 1999/08/28 00:03:20 peter Exp $
*/
#include <stdlib.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_attr_getdetachstate.c b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
index 52ebdfb89c1..f0326139902 100644
--- a/lib/libc_r/uthread/uthread_attr_getdetachstate.c
+++ b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_getdetachstate.c,v 1.3 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_getdetachstate.c,v 1.2 1999/01/06 05:29:21 d Exp $
+ * $FreeBSD: uthread_attr_getdetachstate.c,v 1.3 1999/08/28 00:03:20 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getinheritsched.c b/lib/libc_r/uthread/uthread_attr_getinheritsched.c
index 54294c2e74b..da160586615 100644
--- a/lib/libc_r/uthread/uthread_attr_getinheritsched.c
+++ b/lib/libc_r/uthread/uthread_attr_getinheritsched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_getinheritsched.c,v 1.1 1999/05/26 00:18:22 d Exp $ */
+/* $OpenBSD: uthread_attr_getinheritsched.c,v 1.2 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_getinheritsched.c,v 1.3 1999/08/28 00:03:21 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getschedparam.c b/lib/libc_r/uthread/uthread_attr_getschedparam.c
index 1a51d23b069..321d2b646b1 100644
--- a/lib/libc_r/uthread/uthread_attr_getschedparam.c
+++ b/lib/libc_r/uthread/uthread_attr_getschedparam.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_getschedparam.c,v 1.1 1999/05/26 00:18:22 d Exp $ */
+/* $OpenBSD: uthread_attr_getschedparam.c,v 1.2 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_getschedparam.c,v 1.3 1999/08/28 00:03:21 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getschedpolicy.c b/lib/libc_r/uthread/uthread_attr_getschedpolicy.c
index 54977df53a0..5be8dcba3bf 100644
--- a/lib/libc_r/uthread/uthread_attr_getschedpolicy.c
+++ b/lib/libc_r/uthread/uthread_attr_getschedpolicy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_getschedpolicy.c,v 1.1 1999/05/26 00:18:22 d Exp $ */
+/* $OpenBSD: uthread_attr_getschedpolicy.c,v 1.2 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_getschedpolicy.c,v 1.3 1999/08/28 00:03:21 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getscope.c b/lib/libc_r/uthread/uthread_attr_getscope.c
index 5dd4772ae46..68bfb0d6654 100644
--- a/lib/libc_r/uthread/uthread_attr_getscope.c
+++ b/lib/libc_r/uthread/uthread_attr_getscope.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_getscope.c,v 1.1 1999/05/26 00:18:22 d Exp $ */
+/* $OpenBSD: uthread_attr_getscope.c,v 1.2 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_getscope.c,v 1.3 1999/08/28 00:03:22 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getstackaddr.c b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
index 0e0cb724b33..1a99e1db8a8 100644
--- a/lib/libc_r/uthread/uthread_attr_getstackaddr.c
+++ b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_getstackaddr.c,v 1.3 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_getstackaddr.c,v 1.2 1999/01/06 05:29:21 d Exp $
+ * $FreeBSD: uthread_attr_getstackaddr.c,v 1.3 1999/08/28 00:03:22 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_getstacksize.c b/lib/libc_r/uthread/uthread_attr_getstacksize.c
index c62ca413e62..f8d2f0b054c 100644
--- a/lib/libc_r/uthread/uthread_attr_getstacksize.c
+++ b/lib/libc_r/uthread/uthread_attr_getstacksize.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_getstacksize.c,v 1.3 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_getstacksize.c,v 1.2 1999/01/06 05:29:21 d Exp $
+ * $FreeBSD: uthread_attr_getstacksize.c,v 1.3 1999/08/28 00:03:22 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_init.c b/lib/libc_r/uthread/uthread_attr_init.c
index 04cca9e6cb8..2842ef38a6d 100644
--- a/lib/libc_r/uthread/uthread_attr_init.c
+++ b/lib/libc_r/uthread/uthread_attr_init.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_init.c,v 1.3 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_init.c,v 1.2 1999/01/06 05:29:21 d Exp $
+ * $FreeBSD: uthread_attr_init.c,v 1.4 1999/08/28 00:03:23 peter Exp $
*/
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c b/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c
index 56c762c32f4..64c30da907e 100644
--- a/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c
+++ b/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_setcreatesuspend_np.c,v 1.3 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_setcreatesuspend_np.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_attr_setcreatesuspend_np.c,v 1.3 1999/08/28 00:03:24 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setdetachstate.c b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
index 5f86679e299..1c9e413d85a 100644
--- a/lib/libc_r/uthread/uthread_attr_setdetachstate.c
+++ b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_setdetachstate.c,v 1.3 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_setdetachstate.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_attr_setdetachstate.c,v 1.3 1999/08/28 00:03:24 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setinheritsched.c b/lib/libc_r/uthread/uthread_attr_setinheritsched.c
index 0e0e015558a..61e0f2f6144 100644
--- a/lib/libc_r/uthread/uthread_attr_setinheritsched.c
+++ b/lib/libc_r/uthread/uthread_attr_setinheritsched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_setinheritsched.c,v 1.1 1999/05/26 00:18:22 d Exp $ */
+/* $OpenBSD: uthread_attr_setinheritsched.c,v 1.2 1999/11/25 07:01:31 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_setinheritsched.c,v 1.3 1999/08/28 00:03:24 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setprio.c b/lib/libc_r/uthread/uthread_attr_setprio.c
index 4a548b3a201..f36e07208c6 100644
--- a/lib/libc_r/uthread/uthread_attr_setprio.c
+++ b/lib/libc_r/uthread/uthread_attr_setprio.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_setprio.c,v 1.3 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_setprio.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_attr_setprio.c,v 1.3 1999/08/28 00:03:24 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setschedparam.c b/lib/libc_r/uthread/uthread_attr_setschedparam.c
index 2ff67680fe8..216e1992c8b 100644
--- a/lib/libc_r/uthread/uthread_attr_setschedparam.c
+++ b/lib/libc_r/uthread/uthread_attr_setschedparam.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_setschedparam.c,v 1.1 1999/05/26 00:18:23 d Exp $ */
+/* $OpenBSD: uthread_attr_setschedparam.c,v 1.2 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_setschedparam.c,v 1.3 1999/08/28 00:03:25 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setschedpolicy.c b/lib/libc_r/uthread/uthread_attr_setschedpolicy.c
index 2b47a9d9339..f5090d987a9 100644
--- a/lib/libc_r/uthread/uthread_attr_setschedpolicy.c
+++ b/lib/libc_r/uthread/uthread_attr_setschedpolicy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_setschedpolicy.c,v 1.1 1999/05/26 00:18:23 d Exp $ */
+/* $OpenBSD: uthread_attr_setschedpolicy.c,v 1.2 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_setschedpolicy.c,v 1.3 1999/08/28 00:03:25 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setscope.c b/lib/libc_r/uthread/uthread_attr_setscope.c
index 26fdaf6f32c..e40b73afcb8 100644
--- a/lib/libc_r/uthread/uthread_attr_setscope.c
+++ b/lib/libc_r/uthread/uthread_attr_setscope.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_attr_setscope.c,v 1.1 1999/05/26 00:18:23 d Exp $ */
+/* $OpenBSD: uthread_attr_setscope.c,v 1.2 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_attr_setscope.c,v 1.3 1999/08/28 00:03:25 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setstackaddr.c b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
index ccef1189723..2dcdd79eee1 100644
--- a/lib/libc_r/uthread/uthread_attr_setstackaddr.c
+++ b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_setstackaddr.c,v 1.3 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_setstackaddr.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_attr_setstackaddr.c,v 1.3 1999/08/28 00:03:25 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_attr_setstacksize.c b/lib/libc_r/uthread/uthread_attr_setstacksize.c
index ee73ae39a9a..6b1792d02dc 100644
--- a/lib/libc_r/uthread/uthread_attr_setstacksize.c
+++ b/lib/libc_r/uthread/uthread_attr_setstacksize.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_attr_setstacksize.c,v 1.3 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_attr_setstacksize.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_attr_setstacksize.c,v 1.4 1999/08/28 00:03:26 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_autoinit.c b/lib/libc_r/uthread/uthread_autoinit.c
index 85aae18b063..850aec29f09 100644
--- a/lib/libc_r/uthread/uthread_autoinit.c
+++ b/lib/libc_r/uthread/uthread_autoinit.c
@@ -1,7 +1,7 @@
/*
* David Leonard, 1998. Public Domain. <david.leonard@csee.uq.edu.au>
*
- * $OpenBSD: uthread_autoinit.c,v 1.6 1999/03/10 10:05:39 d Exp $
+ * $OpenBSD: uthread_autoinit.c,v 1.7 1999/11/25 07:01:32 d Exp $
*/
#include <stdio.h>
@@ -49,7 +49,7 @@ _thread_dot_init()
* found in the .dynamic section into the _INIT field. This then gets
* automatically run by GNU ELF's ld.so.
*/
-#ifdef pmax
+#ifdef __mips__
extern int _init() __attribute__((constructor,section (".dynamic")));
int
_init()
@@ -58,7 +58,7 @@ _init()
_thread_init();
return 0;
}
-#endif /* mips */
+#endif /* __mips__ */
/*
* A GNU C installation may know how to automatically run
@@ -68,7 +68,7 @@ _init()
* the collect2 stage of linkage will inform __main (from libgcc.a)
* to call it.
*/
-#ifdef __GNUC__
+#if defined(__GNUC__) /* && defined(notyet) /* internal compiler error??? */
void _thread_init_constructor __P((void)) __attribute__((constructor));
void
_thread_init_constructor()
@@ -80,6 +80,6 @@ _thread_init_constructor()
/*
* Dummy symbol referenced by uthread_init.o so this compilation unit
- * is always loaded.
+ * is always loaded from archives.
*/
int _thread_autoinit_dummy_decl = 0;
diff --git a/lib/libc_r/uthread/uthread_bind.c b/lib/libc_r/uthread/uthread_bind.c
index 644b31a0197..fca26b55558 100644
--- a/lib/libc_r/uthread/uthread_bind.c
+++ b/lib/libc_r/uthread/uthread_bind.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_bind.c,v 1.4 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_bind.c,v 1.3 1999/02/16 16:39:59 deraadt Exp $
+ * $FreeBSD: uthread_bind.c,v 1.5 1999/08/28 00:03:26 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c
index f3a205d1e9e..e43e03bf00b 100644
--- a/lib/libc_r/uthread/uthread_cancel.c
+++ b/lib/libc_r/uthread/uthread_cancel.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_cancel.c,v 1.2 1999/11/25 07:01:32 d Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*/
@@ -12,35 +13,33 @@ pthread_cancel(pthread)
int ret;
if ((ret = _find_thread(pthread))) {
- } else if (pthread->state == PS_DEAD)
- ret = 0;
- else {
- /* Set the threads's I've-been-cancelled flag: */
- pthread->flags |= PTHREAD_CANCELLING;
+ } else if ((pthread->flags & PTHREAD_FLAGS_CANCELED) == 0) {
+ /* Set the thread's I've-been-cancelled flag: */
+ pthread->flags |= PTHREAD_FLAGS_CANCELED;
/* Check if we need to kick it back into the run queue: */
if ((pthread->cancelstate == PTHREAD_CANCEL_ENABLE) &&
((pthread->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) ||
- (pthread->flags & PTHREAD_AT_CANCEL_POINT)))
+ (pthread->flags & PTHREAD_FLAGS_CANCELPT)))
switch (pthread->state) {
- case PS_RUNNING:
- /* No need to resume: */
- break;
case PS_WAIT_WAIT:
case PS_FDR_WAIT:
case PS_FDW_WAIT:
case PS_SLEEP_WAIT:
case PS_SELECT_WAIT:
+ case PS_POLL_WAIT:
case PS_SIGSUSPEND:
/* Interrupt and resume: */
pthread->interrupted = 1;
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
break;
case PS_MUTEX_WAIT:
case PS_COND_WAIT:
+ case PS_SIGWAIT:
case PS_FDLR_WAIT:
case PS_FDLW_WAIT:
case PS_FILE_WAIT:
- case PS_SIGWAIT:
case PS_JOIN:
case PS_SUSPENDED:
case PS_SIGTHREAD:
@@ -48,8 +47,10 @@ pthread_cancel(pthread)
/* XXX may be incorrect */
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
break;
+ case PS_RUNNING:
+ case PS_DEADLOCK:
+ case PS_SPINBLOCK:
case PS_DEAD:
- case PS_STATE_MAX:
/* Ignore */
break;
}
@@ -134,14 +135,14 @@ _thread_enter_cancellation_point()
/* Look for a cancellation before we block: */
_thread_cancellation_point();
- _thread_run->flags |= PTHREAD_AT_CANCEL_POINT;
+ _thread_run->flags |= PTHREAD_FLAGS_CANCELPT;
}
void
_thread_leave_cancellation_point()
{
- _thread_run->flags &=~ PTHREAD_AT_CANCEL_POINT;
+ _thread_run->flags &=~ PTHREAD_FLAGS_CANCELPT;
/* Look for a cancellation after we unblock: */
_thread_cancellation_point();
}
@@ -155,9 +156,9 @@ _thread_cancellation_point()
{
if ((_thread_run->cancelstate == PTHREAD_CANCEL_ENABLE) &&
- ((_thread_run->flags & (PTHREAD_CANCELLING|PTHREAD_EXITING)) ==
- PTHREAD_CANCELLING)) {
- _thread_run->flags &=~ PTHREAD_CANCELLING;
+ ((_thread_run->flags & (PTHREAD_FLAGS_CANCELED|PTHREAD_EXITING)) ==
+ PTHREAD_FLAGS_CANCELED)) {
+ _thread_run->flags &=~ PTHREAD_FLAGS_CANCELED;
pthread_exit(PTHREAD_CANCELED);
PANIC("cancel");
}
diff --git a/lib/libc_r/uthread/uthread_clean.c b/lib/libc_r/uthread/uthread_clean.c
index c13519b0def..0fc9a272f7f 100644
--- a/lib/libc_r/uthread/uthread_clean.c
+++ b/lib/libc_r/uthread/uthread_clean.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_clean.c,v 1.3 1999/11/25 07:01:32 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_clean.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_clean.c,v 1.4 1999/08/28 00:03:26 peter Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_close.c b/lib/libc_r/uthread/uthread_close.c
index 6cfde5ca48e..a3dff060aec 100644
--- a/lib/libc_r/uthread/uthread_close.c
+++ b/lib/libc_r/uthread/uthread_close.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_close.c,v 1.6 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_close.c,v 1.5 1999/06/09 07:16:16 d Exp $
+ * $FreeBSD: uthread_close.c,v 1.7 1999/08/28 00:03:26 peter Exp $
*/
+#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
@@ -44,16 +46,26 @@ close(int fd)
{
int flags;
int ret;
+ int status;
struct stat sb;
+ struct fd_table_entry *entry;
/* This is a cancelation point: */
_thread_enter_cancellation_point();
- /* Lock the file descriptor while the file is closed: */
- if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
- /* Get file descriptor status. */
- _thread_sys_fstat(fd, &sb);
-
+ if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
+ /*
+ * Don't allow silly programs to close the kernel pipe.
+ */
+ errno = EBADF;
+ ret = -1;
+ }
+ /*
+ * Lock the file descriptor while the file is closed and get
+ * the file descriptor status:
+ */
+ else if (((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) &&
+ ((ret = _thread_sys_fstat(fd, &sb)) == 0)) {
/*
* Check if the file should be left as blocking.
*
@@ -81,11 +93,14 @@ close(int fd)
_thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}
+ /* XXX: Assumes well behaved threads. */
+ /* XXX: Defer real close to avoid race condition */
+ entry = _thread_fd_table[fd];
+ _thread_fd_table[fd] = NULL;
+ free(entry);
+
/* Close the file descriptor: */
ret = _thread_sys_close(fd);
-
- free(_thread_fd_table[fd]);
- _thread_fd_table[fd] = NULL;
}
/* No longer in a cancellation point: */
diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c
index aef5daac188..aed1adc7662 100644
--- a/lib/libc_r/uthread/uthread_cond.c
+++ b/lib/libc_r/uthread/uthread_cond.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_cond.c,v 1.7 1999/06/09 07:06:54 d Exp $ */
+/* $OpenBSD: uthread_cond.c,v 1.8 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_cond.c,v 1.18 1999/08/30 00:02:07 deischen Exp $
*/
#include <stdlib.h>
#include <errno.h>
@@ -45,6 +46,28 @@ static inline pthread_t cond_queue_deq(pthread_cond_t);
static inline void cond_queue_remove(pthread_cond_t, pthread_t);
static inline void cond_queue_enq(pthread_cond_t, pthread_t);
+/* Reinitialize a condition variable to defaults. */
+int
+_cond_reinit(pthread_cond_t * cond)
+{
+ int ret = 0;
+
+ if (cond == NULL)
+ ret = EINVAL;
+ else if (*cond == NULL)
+ ret = pthread_cond_init(cond, NULL);
+ else {
+ /*
+ * Initialize the condition variable structure:
+ */
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags = COND_FLAGS_INITED;
+ (*cond)->c_type = COND_TYPE_FAST;
+ (*cond)->c_mutex = NULL;
+ memset(&(*cond)->lock, 0, sizeof((*cond)->lock));
+ }
+ return (ret);
+}
int
pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
@@ -96,7 +119,7 @@ pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
pcond->c_flags |= COND_FLAGS_INITED;
pcond->c_type = type;
pcond->c_mutex = NULL;
- _SPINUNLOCK(&pcond->lock);
+ _SPINLOCK_INIT(&pcond->lock);
*cond = pcond;
}
}
@@ -136,6 +159,7 @@ int
pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
{
int rval = 0;
+ int status;
/* This is a cancellation point: */
_thread_enter_cancellation_point();
@@ -149,6 +173,9 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
*/
else if (*cond != NULL ||
(rval = pthread_cond_init(cond,NULL)) == 0) {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
/*
* If the condvar was statically allocated, properly
* initialize the tail queue.
@@ -158,9 +185,6 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
(*cond)->c_flags |= COND_FLAGS_INITED;
}
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
-
/* Process according to condition variable type: */
switch ((*cond)->c_type) {
/* Fast condition variable: */
@@ -242,11 +266,16 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
const struct timespec * abstime)
{
int rval = 0;
+ int status;
/* This is a cancellation point: */
_thread_enter_cancellation_point();
- if (cond == NULL)
+ if (cond == NULL || abstime == NULL)
+ rval = EINVAL;
+
+ else if (abstime->tv_sec < 0 ||
+ abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
rval = EINVAL;
/*
@@ -255,6 +284,9 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
*/
else if (*cond != NULL ||
(rval = pthread_cond_init(cond,NULL)) == 0) {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
/*
* If the condvar was statically allocated, properly
* initialize the tail queue.
@@ -264,10 +296,6 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
(*cond)->c_flags |= COND_FLAGS_INITED;
}
-
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
-
/* Process according to condition variable type: */
switch ((*cond)->c_type) {
/* Fast condition variable: */
@@ -367,6 +395,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
rval = EINVAL;
break;
}
+
}
/* No longer in a cancellation point: */
@@ -385,6 +414,12 @@ pthread_cond_signal(pthread_cond_t * cond)
if (cond == NULL || *cond == NULL)
rval = EINVAL;
else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
/* Lock the condition variable structure: */
_SPINLOCK(&(*cond)->lock);
@@ -419,6 +454,12 @@ pthread_cond_signal(pthread_cond_t * cond)
/* Unlock the condition variable structure: */
_SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
@@ -435,14 +476,10 @@ pthread_cond_broadcast(pthread_cond_t * cond)
rval = EINVAL;
else {
/*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues. In addition, we must assure
- * that all threads currently waiting on the condition
- * variable are signaled and are not timedout by a
- * scheduling signal that causes a preemption.
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Lock the condition variable structure: */
_SPINLOCK(&(*cond)->lock);
@@ -478,9 +515,11 @@ pthread_cond_broadcast(pthread_cond_t * cond)
/* Unlock the condition variable structure: */
_SPINUNLOCK(&(*cond)->lock);
- /* Reenable preemption and yield if necessary.
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
@@ -498,7 +537,7 @@ cond_queue_deq(pthread_cond_t cond)
if ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) {
TAILQ_REMOVE(&cond->c_queue, pthread, qe);
- pthread->flags &= ~PTHREAD_FLAGS_QUEUED;
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
}
return(pthread);
@@ -517,9 +556,9 @@ cond_queue_remove(pthread_cond_t cond, pthread_t pthread)
* guard against removing the thread from the queue if
* it isn't in the queue.
*/
- if (pthread->flags & PTHREAD_FLAGS_QUEUED) {
+ if (pthread->flags & PTHREAD_FLAGS_IN_CONDQ) {
TAILQ_REMOVE(&cond->c_queue, pthread, qe);
- pthread->flags &= ~PTHREAD_FLAGS_QUEUED;
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
}
}
@@ -545,6 +584,6 @@ cond_queue_enq(pthread_cond_t cond, pthread_t pthread)
tid = TAILQ_NEXT(tid, qe);
TAILQ_INSERT_BEFORE(tid, pthread, qe);
}
- pthread->flags |= PTHREAD_FLAGS_QUEUED;
+ pthread->flags |= PTHREAD_FLAGS_IN_CONDQ;
}
#endif
diff --git a/lib/libc_r/uthread/uthread_condattr_destroy.c b/lib/libc_r/uthread/uthread_condattr_destroy.c
index 7e6aa2dc124..62e5a4495a8 100644
--- a/lib/libc_r/uthread/uthread_condattr_destroy.c
+++ b/lib/libc_r/uthread/uthread_condattr_destroy.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_condattr_destroy.c,v 1.3 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_condattr_destroy.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_condattr_destroy.c,v 1.4 1999/08/28 00:03:27 peter Exp $
*/
#include <stdlib.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_condattr_init.c b/lib/libc_r/uthread/uthread_condattr_init.c
index 0231bc78f7b..298989ccef4 100644
--- a/lib/libc_r/uthread/uthread_condattr_init.c
+++ b/lib/libc_r/uthread/uthread_condattr_init.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_condattr_init.c,v 1.3 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_condattr_init.c,v 1.2 1999/01/06 05:29:22 d Exp $
+ * $FreeBSD: uthread_condattr_init.c,v 1.4 1999/08/28 00:03:27 peter Exp $
*/
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libc_r/uthread/uthread_connect.c b/lib/libc_r/uthread/uthread_connect.c
index 59fc0724f47..a6a2f367189 100644
--- a/lib/libc_r/uthread/uthread_connect.c
+++ b/lib/libc_r/uthread/uthread_connect.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_connect.c,v 1.3 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_connect.c,v 1.2 1999/02/16 16:40:00 deraadt Exp $
+ * $FreeBSD: uthread_connect.c,v 1.6 1999/08/28 00:03:28 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
@@ -43,8 +44,7 @@ int
connect(int fd, const struct sockaddr * name, socklen_t namelen)
{
struct sockaddr tmpname;
- int errnolen, ret;
- socklen_t tmpnamelen;
+ int errnolen, ret, tmpnamelen;
if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
if ((ret = _thread_sys_connect(fd, name, namelen)) < 0) {
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index 002f563d14a..67811b2d583 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_create.c,v 1.11 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_create.c,v 1.10 1999/05/26 00:18:23 d Exp $
+ * $FreeBSD: uthread_create.c,v 1.19 1999/08/28 00:03:28 peter Exp $
*/
#include <errno.h>
#include <stdlib.h>
@@ -37,22 +38,25 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
#ifdef _THREAD_SAFE
#include <machine/reg.h>
#include <pthread.h>
#include "pthread_private.h"
-#include "thread_private.h"
int
pthread_create(pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg)
{
int f_gc = 0;
+ int i;
int ret = 0;
+ int status;
pthread_t gc_thread;
pthread_t new_thread;
pthread_attr_t pattr;
- void *stack;
+ struct stack *stack;
/*
* Locking functions in libc are required when there are
@@ -72,31 +76,24 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
} else {
pattr = *attr;
}
- /* Check if a stack was specified in the thread attributes: */
- if ((stack = pattr->stackaddr_attr) != NULL) {
- }
- /* Allocate memory for the stack: */
- else if ((stack = (void *) malloc(pattr->stacksize_attr)) == NULL) {
- /* Insufficient memory to create a thread: */
+ /* Create a stack from the specified attributes: */
+ if ((stack = _thread_stack_alloc(pattr->stackaddr_attr,
+ pattr->stacksize_attr)) == NULL) {
ret = EAGAIN;
free(new_thread);
}
+
/* Check for errors: */
if (ret != 0) {
} else {
/* Initialise the thread structure: */
memset(new_thread, 0, sizeof(struct pthread));
+ _SPINLOCK_INIT(&new_thread->lock);
new_thread->slice_usec = -1;
new_thread->sig_saved = 0;
new_thread->stack = stack;
new_thread->start_routine = start_routine;
new_thread->arg = arg;
-#ifdef _THREAD_RUSAGE
- timerclear(&new_thread->ru_utime);
- timerclear(&new_thread->ru_stime);
-#endif
- _SPINUNLOCK(&new_thread->lock);
-
new_thread->cancelstate = PTHREAD_CANCEL_ENABLE;
new_thread->canceltype = PTHREAD_CANCEL_DEFERRED;
@@ -106,12 +103,6 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
*/
new_thread->magic = PTHREAD_MAGIC;
- if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
- PTHREAD_NEW_STATE(new_thread,PS_SUSPENDED);
- } else {
- PTHREAD_NEW_STATE(new_thread,PS_RUNNING);
- }
-
/* Initialise the thread for signals: */
new_thread->sigmask = _thread_run->sigmask;
@@ -123,8 +114,8 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* returned from a longjmp() to the beginning of
* _thread_start().
*/
-
- _thread_machdep_thread_create(new_thread, _thread_start, pattr);
+ _thread_machdep_thread_create(new_thread, _thread_start,
+ pattr);
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
@@ -135,22 +126,26 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
*/
if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
/* Copy the scheduling attributes: */
- new_thread->base_priority = _thread_run->base_priority;
- new_thread->attr.prio = _thread_run->base_priority;
- new_thread->attr.sched_policy = _thread_run->attr.sched_policy;
+ new_thread->base_priority
+ = _thread_run->base_priority;
+ new_thread->attr.prio
+ = _thread_run->base_priority;
+ new_thread->attr.sched_policy
+ = _thread_run->attr.sched_policy;
} else {
/*
* Use just the thread priority, leaving the
* other scheduling attributes as their
* default values:
*/
- new_thread->base_priority = new_thread->attr.prio;
+ new_thread->base_priority
+ = new_thread->attr.prio;
}
new_thread->active_priority = new_thread->base_priority;
new_thread->inherited_priority = 0;
/* Initialise the join queue for the new thread: */
- _thread_queue_init(&(new_thread->join_queue));
+ TAILQ_INIT(&(new_thread->join_queue));
/* Initialize the mutex queue: */
TAILQ_INIT(&new_thread->mutexq);
@@ -158,32 +153,24 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Initialise hooks in the thread structure: */
new_thread->specific_data = NULL;
new_thread->cleanup = NULL;
- new_thread->queue = NULL;
- new_thread->qnxt = NULL;
new_thread->flags = 0;
+ new_thread->poll_data.nfds = 0;
+ new_thread->poll_data.fds = NULL;
- /* Lock the thread list: */
- _lock_thread_list();
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
/*
* Check if the garbage collector thread
* needs to be started.
*/
- f_gc = (_thread_link_list == _thread_initial);
+ f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);
/* Add the thread to the linked list of all threads: */
- new_thread->nxt = _thread_link_list;
- _thread_link_list = new_thread;
-
- /* Unlock the thread list: */
- _unlock_thread_list();
-
- /*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
- */
- _thread_kern_sched_defer();
+ TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
new_thread->state = PS_SUSPENDED;
@@ -194,10 +181,10 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
}
/*
- * Reenable preemption and yield if a scheduling
- * signal occurred while in the critical region.
+ * Undefer and handle pending signals, yielding
+ * if necessary.
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
/* Return a pointer to the thread structure: */
if (thread != NULL)
diff --git a/lib/libc_r/uthread/uthread_detach.c b/lib/libc_r/uthread/uthread_detach.c
index cb51ff0e43d..181f73b942f 100644
--- a/lib/libc_r/uthread/uthread_detach.c
+++ b/lib/libc_r/uthread/uthread_detach.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_detach.c,v 1.5 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_detach.c,v 1.4 1999/05/26 00:18:23 d Exp $
+ * $FreeBSD: uthread_detach.c,v 1.10 1999/08/28 00:03:28 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -40,6 +41,7 @@ int
pthread_detach(pthread_t pthread)
{
int rval = 0;
+ int status;
pthread_t next_thread;
/* Check for invalid calling parameters: */
@@ -53,23 +55,25 @@ pthread_detach(pthread_t pthread)
pthread->attr.flags |= PTHREAD_DETACHED;
/*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Enter a loop to bring all threads off the join queue: */
- while ((next_thread = _thread_queue_deq(&pthread->join_queue)) != NULL) {
+ while ((next_thread = TAILQ_FIRST(&pthread->join_queue)) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&pthread->join_queue, next_thread, qe);
+
/* Make the thread run: */
PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
}
/*
- * Reenable preemption and yield if a scheduling signal
- * occurred while in the critical region.
+ * Undefer and handle pending signals, yielding if a
+ * scheduling signal occurred while in the critical region.
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
} else
/* Return an error: */
rval = EINVAL;
diff --git a/lib/libc_r/uthread/uthread_dup.c b/lib/libc_r/uthread/uthread_dup.c
index c24031b8968..8aba9a1dba6 100644
--- a/lib/libc_r/uthread/uthread_dup.c
+++ b/lib/libc_r/uthread/uthread_dup.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_dup.c,v 1.3 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_dup.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_dup.c,v 1.5 1999/08/28 00:03:29 peter Exp $
*/
#include <unistd.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_dup2.c b/lib/libc_r/uthread/uthread_dup2.c
index 2f34b8f7d32..2dfd9d8c361 100644
--- a/lib/libc_r/uthread/uthread_dup2.c
+++ b/lib/libc_r/uthread/uthread_dup2.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_dup2.c,v 1.4 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_dup2.c,v 1.3 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_dup2.c,v 1.6 1999/08/28 00:03:29 peter Exp $
*/
#include <errno.h>
#include <unistd.h>
diff --git a/lib/libc_r/uthread/uthread_equal.c b/lib/libc_r/uthread/uthread_equal.c
index 4ec9505d579..54da618366f 100644
--- a/lib/libc_r/uthread/uthread_equal.c
+++ b/lib/libc_r/uthread/uthread_equal.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_equal.c,v 1.3 1999/11/25 07:01:33 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_equal.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_equal.c,v 1.3 1999/08/28 00:03:29 peter Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
diff --git a/lib/libc_r/uthread/uthread_execve.c b/lib/libc_r/uthread/uthread_execve.c
index ba87ccf8d98..b401dd1a145 100644
--- a/lib/libc_r/uthread/uthread_execve.c
+++ b/lib/libc_r/uthread/uthread_execve.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_execve.c,v 1.5 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_execve.c,v 1.4 1999/05/26 00:18:23 d Exp $
+ * $FreeBSD: uthread_execve.c,v 1.8 1999/08/28 00:03:30 peter Exp $
*/
#include <errno.h>
#include <fcntl.h>
@@ -93,6 +94,9 @@ execve(const char *name, char *const * argv, char *const * envp)
act.sa_mask = _thread_sigact[i - 1].sa_mask;
act.sa_flags = _thread_sigact[i - 1].sa_flags;
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
/* Change the signal action for the process: */
_thread_sys_sigaction(i, &act, &oact);
}
diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c
index aba20d5cee2..976ccbbf46d 100644
--- a/lib/libc_r/uthread/uthread_exit.c
+++ b/lib/libc_r/uthread/uthread_exit.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_exit.c,v 1.10 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,14 +30,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_exit.c,v 1.9 1999/06/14 23:23:40 d Exp $
+ * $FreeBSD: uthread_exit.c,v 1.12 1999/08/30 15:45:42 dt Exp $
*/
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
@@ -77,31 +76,21 @@ void _exit(int status)
_thread_sys__exit(status);
}
-/*
- * Append a small number onto the end of a string.
- * This avoids the need to use sprintf, which is unsafe sometimes.
- */
static void
-numlcat(char *s, int num, size_t size)
+numlcat(char *s, int l, size_t sz)
{
- int i;
- char digit[7];
+ char digit[2];
- if (num<0) {
- num = -num;
- strlcat(s, "-", size);
+ /* Inefficient. */
+ if (l < 0) {
+ l = -l;
+ strlcat(s, "-", sz);
}
- digit[sizeof digit - 1] = '\0';
- for (i = sizeof digit - 2; i >= 0; i--) {
- digit[i] = '0' + (num % 10);
- num /= 10;
- if (num == 0)
- break;
- }
- if (i<0)
- strlcat(s, "inf", size);
- else
- strlcat(s, &digit[i], size);
+ if (l >= 10)
+ numlcat(s, l / 10, sz);
+ digit[0] = "0123456789"[l % 10];
+ digit[1] = '\0';
+ strlcat(s, digit, sz);
}
void
@@ -118,30 +107,36 @@ _thread_exit(const char *fname, int lineno, const char *string)
strlcat(s, fname, sizeof s);
strlcat(s, " (errno = ", sizeof s);
numlcat(s, errno, sizeof s);
- strlcat(s, ", pid = ", sizeof s);
- numlcat(s, _thread_sys_getpid(), sizeof s);
strlcat(s, ")\n", sizeof s);
/* Write the string to the standard error file descriptor: */
_thread_sys_write(2, s, strlen(s));
- /* Write a dump of the current thread status: */
- _thread_dump_info();
-
- /* Try to dump a core file: */
+ /* Force this process to exit: */
+ /* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */
+#if defined(_PTHREADS_INVARIANTS)
abort();
+#else
+ _exit(1);
+#endif
}
void
pthread_exit(void *status)
{
+ int sig;
+ long l;
pthread_t pthread;
/* Check if this thread is already in the process of exiting: */
if ((_thread_run->flags & PTHREAD_EXITING) != 0) {
- char msg[128];
- snprintf(msg,sizeof msg,"Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run);
- PANIC(msg);
+ PANIC("Thread has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!");
+ }
+
+ /* Free thread-specific poll_data structure, if allocated */
+ if (_thread_run->poll_data.fds != NULL) {
+ free(_thread_run->poll_data.fds);
+ _thread_run->poll_data.fds = NULL;
}
/* Flag this thread as exiting: */
@@ -164,22 +159,24 @@ pthread_exit(void *status)
}
/*
- * Guard against preemption by a scheduling signal. A change of
- * thread state modifies the waiting and priority queues.
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Check if there are any threads joined to this one: */
- while ((pthread = _thread_queue_deq(&(_thread_run->join_queue))) != NULL) {
+ while ((pthread = TAILQ_FIRST(&(_thread_run->join_queue))) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&_thread_run->join_queue, pthread, qe);
+
/* Wake the joined thread and let it detach this thread: */
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
}
/*
- * Reenable preemption and yield if a scheduling signal
- * occurred while in the critical region.
+ * Undefer and handle pending signals, yielding if necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
/*
* Lock the garbage collector mutex to ensure that the garbage
@@ -189,8 +186,21 @@ pthread_exit(void *status)
PANIC("Cannot lock gc mutex");
/* Add this thread to the list of dead threads. */
- _thread_run->nxt_dead = _thread_dead;
- _thread_dead = _thread_run;
+ TAILQ_INSERT_HEAD(&_dead_list, _thread_run, dle);
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Remove this thread from the thread list: */
+ TAILQ_REMOVE(&_thread_list, _thread_run, tle);
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
/*
* Signal the garbage collector thread that there is something
diff --git a/lib/libc_r/uthread/uthread_fchmod.c b/lib/libc_r/uthread/uthread_fchmod.c
index 454483e410e..652f45c0fd7 100644
--- a/lib/libc_r/uthread/uthread_fchmod.c
+++ b/lib/libc_r/uthread/uthread_fchmod.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fchmod.c,v 1.3 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fchmod.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_fchmod.c,v 1.5 1999/08/28 00:03:30 peter Exp $
*/
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/lib/libc_r/uthread/uthread_fchown.c b/lib/libc_r/uthread/uthread_fchown.c
index 6b1d4ff1999..ed136ad7ac5 100644
--- a/lib/libc_r/uthread/uthread_fchown.c
+++ b/lib/libc_r/uthread/uthread_fchown.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fchown.c,v 1.3 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fchown.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_fchown.c,v 1.5 1999/08/28 00:03:31 peter Exp $
*/
#include <sys/types.h>
#include <unistd.h>
diff --git a/lib/libc_r/uthread/uthread_fcntl.c b/lib/libc_r/uthread/uthread_fcntl.c
index c1348a7b27e..7070a564838 100644
--- a/lib/libc_r/uthread/uthread_fcntl.c
+++ b/lib/libc_r/uthread/uthread_fcntl.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fcntl.c,v 1.6 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fcntl.c,v 1.5 1999/06/09 07:16:16 d Exp $
+ * $FreeBSD: uthread_fcntl.c,v 1.8 1999/08/28 00:03:31 peter Exp $
*/
#include <stdarg.h>
#include <unistd.h>
diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c
index 0b51f75b737..39303fc0820 100644
--- a/lib/libc_r/uthread/uthread_fd.c
+++ b/lib/libc_r/uthread/uthread_fd.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fd.c,v 1.6 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_fd.c,v 1.10 1999/03/23 05:07:55 jb Exp $
- * $OpenBSD: uthread_fd.c,v 1.5 1999/05/26 00:18:23 d Exp $
+ * $FreeBSD: uthread_fd.c,v 1.13 1999/08/28 00:03:31 peter Exp $
*
*/
#include <errno.h>
@@ -80,28 +80,28 @@ _thread_fd_table_init(int fd)
ret = -1;
} else {
/* Initialise the file locks: */
- _SPINUNLOCK(&entry->lock);
+ _SPINLOCK_INIT(&entry->lock);
entry->r_owner = NULL;
entry->w_owner = NULL;
entry->r_fname = NULL;
entry->w_fname = NULL;
- entry->r_lineno = 0;;
- entry->w_lineno = 0;;
- entry->r_lockcount = 0;;
- entry->w_lockcount = 0;;
+ entry->r_lineno = 0;
+ entry->w_lineno = 0;
+ entry->r_lockcount = 0;
+ entry->w_lockcount = 0;
/* Initialise the read/write queues: */
- _thread_queue_init(&entry->r_queue);
- _thread_queue_init(&entry->w_queue);
+ TAILQ_INIT(&entry->r_queue);
+ TAILQ_INIT(&entry->w_queue);
/* Get the flags for the file: */
- if (fd >= 3 && (entry->flags =
- _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
+ if (((fd >= 3) || (_pthread_stdio_flags[fd] == -1)) &&
+ (entry->flags = _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
ret = -1;
- }
+ }
else {
/* Check if a stdio descriptor: */
- if (fd < 3)
+ if ((fd < 3) && (_pthread_stdio_flags[fd] != -1))
/*
* Use the stdio flags read by
* _pthread_init() to avoid
@@ -170,6 +170,12 @@ _thread_fd_unlock(int fd, int lock_type)
*/
if ((ret = _thread_fd_table_init(fd)) == 0) {
/*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
* Lock the file descriptor table entry to prevent
* other threads for clashing with the current
* thread's accesses:
@@ -196,8 +202,12 @@ _thread_fd_unlock(int fd, int lock_type)
* Get the next thread in the queue for a
* read lock on this file descriptor:
*/
- else if ((_thread_fd_table[fd]->r_owner = _thread_queue_deq(&_thread_fd_table[fd]->r_queue)) == NULL) {
+ else if ((_thread_fd_table[fd]->r_owner = TAILQ_FIRST(&_thread_fd_table[fd]->r_queue)) == NULL) {
} else {
+ /* Remove this thread from the queue: */
+ TAILQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_fd_table[fd]->r_owner, qe);
+
/*
* Set the state of the new owner of
* the thread to running:
@@ -234,8 +244,12 @@ _thread_fd_unlock(int fd, int lock_type)
* Get the next thread in the queue for a
* write lock on this file descriptor:
*/
- else if ((_thread_fd_table[fd]->w_owner = _thread_queue_deq(&_thread_fd_table[fd]->w_queue)) == NULL) {
+ else if ((_thread_fd_table[fd]->w_owner = TAILQ_FIRST(&_thread_fd_table[fd]->w_queue)) == NULL) {
} else {
+ /* Remove this thread from the queue: */
+ TAILQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_fd_table[fd]->w_owner, qe);
+
/*
* Set the state of the new owner of
* the thread to running:
@@ -255,6 +269,12 @@ _thread_fd_unlock(int fd, int lock_type)
/* Unlock the file descriptor table entry: */
_SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
}
/* Nothing to return. */
@@ -296,7 +316,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
* queue of threads waiting for a
* read lock on this file descriptor:
*/
- _thread_queue_enq(&_thread_fd_table[fd]->r_queue, _thread_run);
+ TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->r_queue, _thread_run, qe);
/*
* Save the file descriptor details
@@ -369,7 +389,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
* write lock on this file
* descriptor:
*/
- _thread_queue_enq(&_thread_fd_table[fd]->w_queue, _thread_run);
+ TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->w_queue, _thread_run, qe);
/*
* Save the file descriptor details
@@ -431,7 +451,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
}
void
-_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
+_thread_fd_unlock_debug(int fd, int lock_type, const char *fname, int lineno)
{
int ret;
@@ -441,6 +461,12 @@ _thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
*/
if ((ret = _thread_fd_table_init(fd)) == 0) {
/*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
* Lock the file descriptor table entry to prevent
* other threads for clashing with the current
* thread's accesses:
@@ -467,8 +493,12 @@ _thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
* Get the next thread in the queue for a
* read lock on this file descriptor:
*/
- else if ((_thread_fd_table[fd]->r_owner = _thread_queue_deq(&_thread_fd_table[fd]->r_queue)) == NULL) {
+ else if ((_thread_fd_table[fd]->r_owner = TAILQ_FIRST(&_thread_fd_table[fd]->r_queue)) == NULL) {
} else {
+ /* Remove this thread from the queue: */
+ TAILQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_fd_table[fd]->r_owner, qe);
+
/*
* Set the state of the new owner of
* the thread to running:
@@ -505,8 +535,12 @@ _thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
* Get the next thread in the queue for a
* write lock on this file descriptor:
*/
- else if ((_thread_fd_table[fd]->w_owner = _thread_queue_deq(&_thread_fd_table[fd]->w_queue)) == NULL) {
+ else if ((_thread_fd_table[fd]->w_owner = TAILQ_FIRST(&_thread_fd_table[fd]->w_queue)) == NULL) {
} else {
+ /* Remove this thread from the queue: */
+ TAILQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_fd_table[fd]->w_owner, qe);
+
/*
* Set the state of the new owner of
* the thread to running:
@@ -526,6 +560,12 @@ _thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
/* Unlock the file descriptor table entry: */
_SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary.
+ */
+ _thread_kern_sig_undefer();
}
/* Nothing to return. */
@@ -568,7 +608,7 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* queue of threads waiting for a
* read lock on this file descriptor:
*/
- _thread_queue_enq(&_thread_fd_table[fd]->r_queue, _thread_run);
+ TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->r_queue, _thread_run, qe);
/*
* Save the file descriptor details
@@ -650,7 +690,7 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* write lock on this file
* descriptor:
*/
- _thread_queue_enq(&_thread_fd_table[fd]->w_queue, _thread_run);
+ TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->w_queue, _thread_run, qe);
/*
* Save the file descriptor details
diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c
index a4b5f922fd7..e1c234fc3d4 100644
--- a/lib/libc_r/uthread/uthread_file.c
+++ b/lib/libc_r/uthread/uthread_file.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_file.c,v 1.4 1999/11/25 07:01:34 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_file.c,v 1.6 1998/09/09 16:50:33 dt Exp $
- * $OpenBSD: uthread_file.c,v 1.3 1998/12/23 22:44:39 d Exp $
+ * $FreeBSD: uthread_file.c,v 1.9 1999/08/28 00:03:32 peter Exp $
*
* POSIX stdio FILE locking functions. These assume that the locking
* is only required at FILE structure level, not at file descriptor
@@ -46,6 +46,13 @@
#include "pthread_private.h"
/*
+ * Weak symbols for externally visible functions in this file:
+ */
+#pragma weak flockfile=_flockfile
+#pragma weak ftrylockfile=_ftrylockfile
+#pragma weak funlockfile=_funlockfile
+
+/*
* The FILE lock structure. The FILE *fp is locked if the owner is
* not NULL. If not locked, the file lock structure can be
* reassigned to a different file by setting fp.
@@ -237,14 +244,14 @@ _flockfile_debug(FILE * fp, const char *fname, int lineno)
}
void
-flockfile(FILE * fp)
+_flockfile(FILE * fp)
{
_flockfile_debug(fp, "?", 1);
return;
}
int
-ftrylockfile(FILE * fp)
+_ftrylockfile(FILE * fp)
{
int ret = -1;
int idx = file_idx(fp);
@@ -255,15 +262,6 @@ ftrylockfile(FILE * fp)
/* Lock the hash table: */
_SPINLOCK(&hash_lock);
- /* Check if the static array has not been initialised: */
- if (!init_done) {
- /* Initialise the global array: */
- memset(flh,0,sizeof(flh));
-
- /* Flag the initialisation as complete: */
- init_done = 1;
- }
-
/* Get a pointer to any existing lock for the file: */
if ((p = find_lock(idx, fp)) == NULL) {
/*
@@ -305,13 +303,20 @@ ftrylockfile(FILE * fp)
}
void
-funlockfile(FILE * fp)
+_funlockfile(FILE * fp)
{
+ int status;
int idx = file_idx(fp);
struct file_lock *p;
/* Check if this is a real file: */
if (fp->_file >= 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
/* Lock the hash table: */
_SPINLOCK(&hash_lock);
@@ -319,7 +324,7 @@ funlockfile(FILE * fp)
* Get a pointer to the lock for the file and check that
* the running thread is the one with the lock:
*/
- if (init_done && (p = find_lock(idx, fp)) != NULL &&
+ if ((p = find_lock(idx, fp)) != NULL &&
p->owner == _thread_run) {
/*
* Check if this thread has locked the FILE
@@ -358,6 +363,12 @@ funlockfile(FILE * fp)
/* Unlock the hash table: */
_SPINUNLOCK(&hash_lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
}
return;
}
diff --git a/lib/libc_r/uthread/uthread_find_thread.c b/lib/libc_r/uthread/uthread_find_thread.c
index 21a37e679c7..42b561524b9 100644
--- a/lib/libc_r/uthread/uthread_find_thread.c
+++ b/lib/libc_r/uthread/uthread_find_thread.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_find_thread.c,v 1.4 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_find_thread.c,v 1.3 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_find_thread.c,v 1.5 1999/08/28 00:03:32 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -47,20 +48,20 @@ _find_thread(pthread_t pthread)
/* Invalid thread: */
return(EINVAL);
- /* Lock the thread list: */
- _lock_thread_list();
-
- /* Point to the first thread in the list: */
- pthread1 = _thread_link_list;
+ /*
+ * Defer signals to protect the thread list from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
- /* Search for the thread to join to: */
- while (pthread1 != NULL && pthread1 != pthread) {
- /* Point to the next thread: */
- pthread1 = pthread1->nxt;
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_thread_list, tle) {
+ if (pthread == pthread1)
+ break;
}
- /* Unlock the thread list: */
- _unlock_thread_list();
+ /* Undefer and handle pending signals, yielding if necessary: */
+ _thread_kern_sig_undefer();
/* Return zero if the thread exists: */
return ((pthread1 != NULL) ? 0:ESRCH);
@@ -84,13 +85,10 @@ _find_dead_thread(pthread_t pthread)
if (pthread_mutex_lock(&_gc_mutex) != 0)
PANIC("Cannot lock gc mutex");
- /* Point to the first thread in the list: */
- pthread1 = _thread_dead;
-
- /* Search for the thread to join to: */
- while (pthread1 != NULL && pthread1 != pthread) {
- /* Point to the next thread: */
- pthread1 = pthread1->nxt_dead;
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_dead_list, dle) {
+ if (pthread1 == pthread)
+ break;
}
/* Unlock the garbage collector mutex: */
diff --git a/lib/libc_r/uthread/uthread_flock.c b/lib/libc_r/uthread/uthread_flock.c
index e228762f43c..fed679bd80b 100644
--- a/lib/libc_r/uthread/uthread_flock.c
+++ b/lib/libc_r/uthread/uthread_flock.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_flock.c,v 1.3 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_flock.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_flock.c,v 1.5 1999/08/28 00:03:32 peter Exp $
*/
#include <sys/file.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_fork.c b/lib/libc_r/uthread/uthread_fork.c
index ed1566915bd..0e9aef59a20 100644
--- a/lib/libc_r/uthread/uthread_fork.c
+++ b/lib/libc_r/uthread/uthread_fork.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fork.c,v 1.7 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,13 +30,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fork.c,v 1.6 1999/06/15 00:07:39 d Exp $
+ * $FreeBSD: uthread_fork.c,v 1.14 1999/09/29 15:18:38 marcel Exp $
*/
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
-#include <stdlib.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
@@ -46,10 +46,13 @@ fork(void)
int i, flags;
pid_t ret;
pthread_t pthread;
- pthread_t pthread_next;
+ pthread_t pthread_save;
- /* Lock the thread list: */
- _lock_thread_list();
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
/* Fork a new process: */
if ((ret = _thread_sys_fork()) != 0) {
@@ -60,7 +63,7 @@ fork(void)
_thread_sys_close(_thread_kern_pipe[1]);
/* Reset signals pending for the running thread: */
- _thread_run->sigpend = 0;
+ sigemptyset(&_thread_run->sigpend);
/*
* Create a pipe that is written to by the signal handler to
@@ -90,45 +93,74 @@ fork(void)
else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
/* Abort this application: */
abort();
+ }
+ /* Reinitialize the GC mutex: */
+ else if (_mutex_reinit(&_gc_mutex) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC mutex for forked process");
+ }
+ /* Reinitialize the GC condition variable: */
+ else if (_cond_reinit(&_gc_cond) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC condvar for forked process");
+ }
/* Initialize the ready queue: */
- } else if (_pq_init(&_readyq, PTHREAD_MIN_PRIORITY,
- PTHREAD_MAX_PRIORITY) != 0) {
+ else if (_pq_init(&_readyq) != 0) {
/* Abort this application: */
- PANIC("Cannot allocate priority ready queue.");
+ PANIC("Cannot initialize priority ready queue.");
} else {
- /* Point to the first thread in the list: */
- pthread = _thread_link_list;
-
/*
* Enter a loop to remove all threads other than
* the running thread from the thread list:
*/
+ pthread = TAILQ_FIRST(&_thread_list);
while (pthread != NULL) {
- pthread_next = pthread->nxt;
- if (pthread == _thread_run) {
- _thread_link_list = pthread;
- pthread->nxt = NULL;
- } else {
- if (pthread->attr.stackaddr_attr ==
- NULL && pthread->stack != NULL)
- /*
- * Free the stack of the
- * dead thread:
- */
- free(pthread->stack);
-
- if (pthread->specific_data != NULL)
- free(pthread->specific_data);
-
- free(pthread);
- }
+ /* Save the thread to be freed: */
+ pthread_save = pthread;
+
+ /*
+ * Advance to the next thread before
+ * destroying the current thread:
+ */
+ pthread = TAILQ_NEXT(pthread, dle);
+
+ /* Make sure this isn't the running thread: */
+ if (pthread_save != _thread_run) {
+ /* Remove this thread from the list: */
+ TAILQ_REMOVE(&_thread_list,
+ pthread_save, tle);
- /* Point to the next thread: */
- pthread = pthread_next;
+ if(pthread_save->stack != NULL)
+ _thread_stack_free(pthread_save->stack);
+
+ if (pthread_save->specific_data != NULL)
+ free(pthread_save->specific_data);
+
+ if (pthread_save->poll_data.fds != NULL)
+ free(pthread_save->poll_data.fds);
+
+ free(pthread_save);
+ }
}
- /* Re-init the waiting queues. */
+ /* Re-init the dead thread list: */
+ TAILQ_INIT(&_dead_list);
+
+ /* Re-init the waiting and work queues. */
TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Re-init the threads mutex queue: */
+ TAILQ_INIT(&_thread_run->mutexq);
+
+ /* No spinlocks yet: */
+ _spinblock_count = 0;
+
+ /* Don't queue signals yet: */
+ _queue_signals = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
/* Initialize the scheduling switch hook routine: */
_sched_switch_hook = NULL;
@@ -137,7 +169,7 @@ fork(void)
for (i = 0; i < _thread_dtablesize; i++) {
if (_thread_fd_table[i] != NULL) {
/* Initialise the file locks: */
- _SPINUNLOCK(&_thread_fd_table[i]->lock);
+ _SPINLOCK_INIT(&_thread_fd_table[i]->lock);
_thread_fd_table[i]->r_owner = NULL;
_thread_fd_table[i]->w_owner = NULL;
_thread_fd_table[i]->r_fname = NULL;
@@ -148,15 +180,17 @@ fork(void)
_thread_fd_table[i]->w_lockcount = 0;;
/* Initialise the read/write queues: */
- _thread_queue_init(&_thread_fd_table[i]->r_queue);
- _thread_queue_init(&_thread_fd_table[i]->w_queue);
+ TAILQ_INIT(&_thread_fd_table[i]->r_queue);
+ TAILQ_INIT(&_thread_fd_table[i]->w_queue);
}
}
}
}
- /* Unock the thread list: */
- _unlock_thread_list();
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
/* Return the process ID: */
return (ret);
diff --git a/lib/libc_r/uthread/uthread_fstat.c b/lib/libc_r/uthread/uthread_fstat.c
index c1e195f0c69..29b65b5aac6 100644
--- a/lib/libc_r/uthread/uthread_fstat.c
+++ b/lib/libc_r/uthread/uthread_fstat.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fstat.c,v 1.3 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fstat.c,v 1.2 1999/01/06 05:29:23 d Exp $
+ * $FreeBSD: uthread_fstat.c,v 1.5 1999/08/28 00:03:33 peter Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_fstatfs.c b/lib/libc_r/uthread/uthread_fstatfs.c
index cbd590f008a..ba809a5bef4 100644
--- a/lib/libc_r/uthread/uthread_fstatfs.c
+++ b/lib/libc_r/uthread/uthread_fstatfs.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fstatfs.c,v 1.3 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fstatfs.c,v 1.2 1999/01/10 23:10:25 d Exp $
+ * $FreeBSD: uthread_fstatfs.c,v 1.5 1999/08/28 00:03:33 peter Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_fsync.c b/lib/libc_r/uthread/uthread_fsync.c
index 2136d62afe7..cc5cb5046e1 100644
--- a/lib/libc_r/uthread/uthread_fsync.c
+++ b/lib/libc_r/uthread/uthread_fsync.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_fsync.c,v 1.5 1999/11/25 07:01:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_fsync.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_fsync.c,v 1.5 1999/08/28 00:03:33 peter Exp $
*/
#include <unistd.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_gc.c b/lib/libc_r/uthread/uthread_gc.c
index 1a2790c74bd..d97b602687c 100644
--- a/lib/libc_r/uthread/uthread_gc.c
+++ b/lib/libc_r/uthread/uthread_gc.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_gc.c,v 1.6 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_gc.c,v 1.2 1998/09/30 19:17:51 dt Exp $
- * $OpenBSD: uthread_gc.c,v 1.5 1999/05/26 00:18:24 d Exp $
+ * $FreeBSD: uthread_gc.c,v 1.10 1999/08/28 00:03:34 peter Exp $
*
* Garbage collector thread. Frees memory allocated for dead threads.
*
@@ -38,12 +38,10 @@
#include <errno.h>
#include <time.h>
#include <unistd.h>
-#include <stdlib.h>
#include <sys/types.h>
-#include <sys/time.h>
-#ifdef _THREAD_SAFE
+#include <sys/types.h>
+#include <sys/mman.h>
#include <pthread.h>
-#include <pthread_np.h>
#include "pthread_private.h"
pthread_addr_t
@@ -71,7 +69,7 @@ _thread_gc(pthread_addr_t arg)
f_debug = (getenv("LIBC_R_DEBUG") != NULL);
/* Set the name of this thread. */
- pthread_set_name_np(_thread_run, "GC");
+ pthread_set_name_np(_thread_run,"GC");
while (!f_done) {
/* Check if debugging this application. */
@@ -79,20 +77,26 @@ _thread_gc(pthread_addr_t arg)
/* Dump thread info to file. */
_thread_dump_info();
- /* Lock the thread list: */
- _lock_thread_list();
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
/* Check if this is the last running thread: */
- if (_thread_link_list == _thread_run &&
- _thread_link_list->nxt == NULL)
+ if (TAILQ_FIRST(&_thread_list) == _thread_run &&
+ TAILQ_NEXT(_thread_run, tle) == NULL)
/*
* This is the last thread, so it can exit
* now.
*/
f_done = 1;
- /* Unlock the thread list: */
- _unlock_thread_list();
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
/*
* Lock the garbage collector mutex which ensures that
@@ -105,98 +109,50 @@ _thread_gc(pthread_addr_t arg)
p_stack = NULL;
pthread_cln = NULL;
- /* Point to the first dead thread (if there are any): */
- pthread = _thread_dead;
-
- /* There is no previous dead thread: */
- pthread_prv = NULL;
-
/*
* Enter a loop to search for the first dead thread that
* has memory to free.
*/
- while (p_stack == NULL && pthread_cln == NULL &&
- pthread != NULL) {
- /* Save a pointer to the next thread: */
- pthread_nxt = pthread->nxt_dead;
-
+ for (pthread = TAILQ_FIRST(&_dead_list);
+ p_stack == NULL && pthread_cln == NULL && pthread != NULL;
+ pthread = TAILQ_NEXT(pthread, dle)) {
/* Check if the initial thread: */
- if (pthread == _thread_initial)
+ if (pthread == _thread_initial) {
/* Don't destroy the initial thread. */
- pthread_prv = pthread;
-
+ }
/*
* Check if this thread has detached:
*/
else if ((pthread->attr.flags &
- PTHREAD_DETACHED) != 0) {
- /*
- * Check if there is no previous dead
- * thread:
- */
- if (pthread_prv == NULL)
- /*
- * The dead thread is at the head
- * of the list:
- */
- _thread_dead = pthread_nxt;
- else
- /*
- * The dead thread is not at the
- * head of the list:
- */
- pthread_prv->nxt_dead =
- pthread->nxt_dead;
+ PTHREAD_DETACHED) != 0) {
+ /* Remove this thread from the dead list: */
+ TAILQ_REMOVE(&_dead_list, pthread, dle);
/*
- * Check if the stack was not specified by
- * the caller to pthread_create and has not
- * been destroyed yet:
+ * Point to the stack structure that must
+ * be freed outside the locks:
*/
- if (pthread->attr.stackaddr_attr == NULL &&
- pthread->stack != NULL) {
- /*
- * Point to the stack that must
- * be freed outside the locks:
- */
+ if (pthread->stack != NULL)
p_stack = pthread->stack;
- }
/*
* Point to the thread structure that must
* be freed outside the locks:
*/
pthread_cln = pthread;
+
} else {
/*
* This thread has not detached, so do
- * not destroy it:
+ * not destroy it.
+ *
+ * But we can destroy its stack.
*/
- pthread_prv = pthread;
-
- /*
- * Check if the stack was not specified by
- * the caller to pthread_create and has not
- * been destroyed yet:
- */
- if (pthread->attr.stackaddr_attr == NULL &&
- pthread->stack != NULL) {
- /*
- * Point to the stack that must
- * be freed outside the locks:
- */
+ if (pthread->stack != NULL) {
p_stack = pthread->stack;
-
- /*
- * NULL the stack pointer now
- * that the memory has been freed:
- */
pthread->stack = NULL;
}
}
-
- /* Point to the next thread: */
- pthread = pthread_nxt;
}
/*
@@ -233,58 +189,18 @@ _thread_gc(pthread_addr_t arg)
* locks.
*/
if (p_stack != NULL)
- free(p_stack);
- if (pthread_cln != NULL) {
- /* Lock the thread list: */
- _lock_thread_list();
-
- /*
- * Check if the thread is at the head of the
- * linked list.
- */
- if (_thread_link_list == pthread_cln)
- /* There is no previous thread: */
- _thread_link_list = pthread_cln->nxt;
- else {
- /* Point to the first thread in the list: */
- pthread = _thread_link_list;
-
- /*
- * Enter a loop to find the thread in the
- * linked list before the thread that is
- * about to be freed.
- */
- while (pthread != NULL &&
- pthread->nxt != pthread_cln)
- /* Point to the next thread: */
- pthread = pthread->nxt;
-
- /* Check that a previous thread was found: */
- if (pthread != NULL) {
- /*
- * Point the previous thread to
- * the one after the thread being
- * freed:
- */
- pthread->nxt = pthread_cln->nxt;
- }
- }
-
- /* Unlock the thread list: */
- _unlock_thread_list();
-
- /* Free memory allocated for the thread's name: */
- if (pthread_cln->name != NULL)
- free(pthread_cln->name);
+ /* Free the stack storage. */
+ _thread_stack_free(p_stack);
+ if (pthread_cln != NULL) {
/*
* Free the memory allocated for the thread
* structure.
*/
+ if (pthread_cln->name != NULL)
+ free(pthread_cln->name);
free(pthread_cln);
}
-
}
return (NULL);
}
-#endif /* _THREAD_SAFE */
diff --git a/lib/libc_r/uthread/uthread_getdirentries.c b/lib/libc_r/uthread/uthread_getdirentries.c
index 60cd50ec6e2..1dd8d30e651 100644
--- a/lib/libc_r/uthread/uthread_getdirentries.c
+++ b/lib/libc_r/uthread/uthread_getdirentries.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_getdirentries.c,v 1.3 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_getdirentries.c,v 1.2 1999/01/06 05:29:24 d Exp $
+ * $FreeBSD: uthread_getdirentries.c,v 1.5 1999/08/28 00:03:34 peter Exp $
*/
#include <sys/types.h>
#include <dirent.h>
diff --git a/lib/libc_r/uthread/uthread_getpeername.c b/lib/libc_r/uthread/uthread_getpeername.c
index adb3ab3587b..378f23f7416 100644
--- a/lib/libc_r/uthread/uthread_getpeername.c
+++ b/lib/libc_r/uthread/uthread_getpeername.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_getpeername.c,v 1.4 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_getpeername.c,v 1.3 1999/02/16 16:40:00 deraadt Exp $
+ * $FreeBSD: uthread_getpeername.c,v 1.5 1999/08/28 00:03:34 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
@@ -38,7 +39,7 @@
#include "pthread_private.h"
int
-getpeername(int fd, struct sockaddr *peer, socklen_t *paddrlen)
+getpeername(int fd, struct sockaddr * peer, socklen_t *paddrlen)
{
int ret;
diff --git a/lib/libc_r/uthread/uthread_getprio.c b/lib/libc_r/uthread/uthread_getprio.c
index 074bff3e514..725fb0bde54 100644
--- a/lib/libc_r/uthread/uthread_getprio.c
+++ b/lib/libc_r/uthread/uthread_getprio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_getprio.c,v 1.3 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_getprio.c,v 1.4 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_getprio.c,v 1.6 1999/08/28 00:03:35 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_getschedparam.c b/lib/libc_r/uthread/uthread_getschedparam.c
index 7905c1960f4..3bfadd1709f 100644
--- a/lib/libc_r/uthread/uthread_getschedparam.c
+++ b/lib/libc_r/uthread/uthread_getschedparam.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_getschedparam.c,v 1.1 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_getschedparam.c,v 1.2 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_getschedparam.c,v 1.3 1999/08/28 00:03:35 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_getsockname.c b/lib/libc_r/uthread/uthread_getsockname.c
index 4ed580dc2cf..683cc910f15 100644
--- a/lib/libc_r/uthread/uthread_getsockname.c
+++ b/lib/libc_r/uthread/uthread_getsockname.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_getsockname.c,v 1.4 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_getsockname.c,v 1.3 1999/02/16 16:40:00 deraadt Exp $
+ * $FreeBSD: uthread_getsockname.c,v 1.5 1999/08/28 00:03:36 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_getsockopt.c b/lib/libc_r/uthread/uthread_getsockopt.c
index 7205ac345a3..f73b54780ea 100644
--- a/lib/libc_r/uthread/uthread_getsockopt.c
+++ b/lib/libc_r/uthread/uthread_getsockopt.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_getsockopt.c,v 1.4 1999/11/25 07:01:36 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_getsockopt.c,v 1.3 1999/02/16 16:40:00 deraadt Exp $
+ * $FreeBSD: uthread_getsockopt.c,v 1.5 1999/08/28 00:03:36 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index 281808e75f4..cbcb33083ac 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_init.c,v 1.9 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_init.c,v 1.10 1999/11/25 07:01:37 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_init.c,v 1.18 1999/08/28 00:03:36 peter Exp $
*/
#include <errno.h>
@@ -37,80 +38,68 @@
#include <string.h>
#include <fcntl.h>
#include <paths.h>
+#include <poll.h>
#include <unistd.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/ttycom.h>
#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <signal.h>
+#include <sys/user.h>
+#include <sys/mman.h>
#ifdef _THREAD_SAFE
#include <machine/reg.h>
#include <pthread.h>
-#include <pthread_np.h>
#include "pthread_private.h"
-/* Allocate space for global thread variables here: */
-
-static struct pthread kern_thread;
-struct pthread * volatile _thread_kern_threadp = &kern_thread;
-struct pthread * volatile _thread_run = &kern_thread;
-struct pthread * volatile _last_user_thread = &kern_thread;
-struct pthread * volatile _thread_single = NULL;
-struct pthread * volatile _thread_link_list = NULL;
-int _thread_kern_pipe[2] = { -1, -1 };
-int _thread_kern_in_select = 0;
-int _thread_kern_in_sched = 0;
-struct timeval kern_inc_prio_time = { 0, 0 };
-struct pthread * volatile _thread_dead = NULL;
-struct pthread * _thread_initial = NULL;
-struct pthread_attr pthread_attr_default = {
- SCHED_RR, /* sched_policy */
- 0, /* sched_inherit */
- TIMESLICE_USEC, /* sched_interval */
- PTHREAD_DEFAULT_PRIORITY, /* prio */
- PTHREAD_CREATE_RUNNING, /* suspend */
- PTHREAD_CREATE_JOINABLE, /* flags */
- NULL, /* arg_attr */
- NULL, /* cleanup_attr */
- NULL, /* stackaddr_attr */
- PTHREAD_STACK_DEFAULT /* stacksize_attr */
-};
-struct pthread_mutex_attr pthread_mutexattr_default = {
- PTHREAD_MUTEX_DEFAULT, /* m_type */
- PTHREAD_PRIO_NONE, /* m_protocol */
- 0, /* m_ceiling */
- 0 /* m_flags */
-};
-struct pthread_cond_attr pthread_condattr_default = {
- COND_TYPE_FAST, /* c_type */
- 0 /* c_flags */
-};
-int _pthread_stdio_flags[3];
-struct fd_table_entry ** _thread_fd_table = NULL;
-int _thread_dtablesize = NOFILE_MAX;
-pthread_mutex_t _gc_mutex = NULL;
-pthread_cond_t _gc_cond = NULL;
-struct sigaction _thread_sigact[NSIG];
-
-const int dtablecount = 4096/sizeof(struct fd_table_entry);
-pq_queue_t _readyq;
-_waitingq_t _waitingq;
-volatile int _waitingq_check_reqd = 0;
-pthread_switch_routine_t _sched_switch_hook = NULL;
-
-/* Automatic init module. */
+/* Global thread variables. */
+struct pthread _thread_kern_thread;
+struct pthread *volatile _thread_run = &_thread_kern_thread;
+struct pthread *volatile _last_user_thread = &_thread_kern_thread;
+struct pthread *volatile _thread_single = NULL;
+_thread_list_t _thread_list = TAILQ_HEAD_INITIALIZER(_thread_list);
+int _thread_kern_pipe[2] = { -1, -1 };
+int volatile _queue_signals = 0;
+int _thread_kern_in_sched = 0;
+struct timeval kern_inc_prio_time = { 0, 0 };
+_thread_list_t _dead_list = TAILQ_HEAD_INITIALIZER(_dead_list);
+struct pthread *_thread_initial = NULL;
+struct pthread_attr pthread_attr_default = {
+ SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
+ PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE,
+ NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
+struct pthread_mutex_attr pthread_mutexattr_default = {
+ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
+struct pthread_cond_attr pthread_condattr_default = { COND_TYPE_FAST, 0 };
+int _pthread_stdio_flags[3];
+struct fd_table_entry **_thread_fd_table = NULL;
+struct pollfd *_thread_pfd_table = NULL;
+const int dtablecount = 4096/sizeof(struct fd_table_entry);
+int _thread_dtablesize = 0;
+int _clock_res_nsec = CLOCK_RES_NSEC;
+pthread_mutex_t _gc_mutex = NULL;
+pthread_cond_t _gc_cond = NULL;
+struct sigaction _thread_sigact[NSIG];
+pq_queue_t _readyq;
+_thread_list_t _waitingq;
+_thread_list_t _workq;
+volatile int _spinblock_count = 0;
+volatile int _sigq_check_reqd = 0;
+pthread_switch_routine_t _sched_switch_hook = NULL;
+_stack_list_t _stackq;
+int _thread_kern_new_state = 0;
+
extern int _thread_autoinit_dummy_decl;
#ifdef GCC_2_8_MADE_THREAD_AWARE
-/* see src/gnu/usr.bin/gcc/libgcc2.c */
typedef void *** (*dynamic_handler_allocator)();
extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
static pthread_key_t except_head_key;
typedef struct {
- void **__dynamic_handler_chain;
- void *top_elt[2];
+ void **__dynamic_handler_chain;
+ void *top_elt[2];
} except_struct;
static void ***dynamic_allocator_handler_fn()
@@ -136,6 +125,9 @@ _thread_init(void)
int fd;
int flags;
int i;
+ size_t len;
+ int mib[2];
+ struct clockinfo clockinfo;
struct sigaction act;
/* Check if this function has already been called: */
@@ -152,26 +144,27 @@ _thread_init(void)
* Setup a new session for this process which is
* assumed to be running as root.
*/
- if (setsid() == -1)
+ if (setsid() == -1)
PANIC("Can't set session ID");
- if (revoke(_PATH_CONSOLE) != 0)
+ if (revoke(_PATH_CONSOLE) != 0)
PANIC("Can't revoke console");
- if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
PANIC("Can't open console");
- if (setlogin("root") == -1)
+ if (setlogin("root") == -1)
PANIC("Can't set login to root");
- if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
PANIC("Can't set controlling terminal");
- if (_thread_sys_dup2(fd,0) == -1 ||
- _thread_sys_dup2(fd,1) == -1 ||
- _thread_sys_dup2(fd,2) == -1)
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
PANIC("Can't dup2");
}
/* Get the standard I/O flags before messing with them : */
for (i = 0; i < 3; i++)
- if ((_pthread_stdio_flags[i] =
- _thread_sys_fcntl(i,F_GETFL, NULL)) == -1)
+ if (((_pthread_stdio_flags[i] =
+ _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) &&
+ (errno != EBADF))
PANIC("Cannot get stdio flags");
/*
@@ -202,9 +195,8 @@ _thread_init(void)
/* Abort this application: */
PANIC("Cannot get kernel write pipe flags");
}
- /* Initialize the ready queue: */
- else if (_pq_init(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY)
-!= 0) {
+ /* Allocate and initialize the ready queue: */
+ else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY) != 0) {
/* Abort this application: */
PANIC("Cannot allocate priority ready queue.");
}
@@ -217,23 +209,19 @@ _thread_init(void)
PANIC("Cannot allocate memory for initial thread");
} else {
/* Zero the global kernel thread structure: */
- memset(_thread_kern_threadp, 0, sizeof(struct pthread));
- _thread_kern_threadp->magic = PTHREAD_MAGIC;
-
- /* Set the kernel's name for the debugger: */
- pthread_set_name_np(_thread_kern_threadp, "kern");
-
- /* The kernel thread is a library thread: */
- _thread_kern_threadp->flags = PTHREAD_FLAGS_PRIVATE;
+ memset(&_thread_kern_thread, 0, sizeof(struct pthread));
+ _thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE;
+ memset(_thread_initial, 0, sizeof(struct pthread));
- /* Initialize the waiting queue: */
+ /* Initialize the waiting and work queues: */
TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
/* Initialize the scheduling switch hook routine: */
_sched_switch_hook = NULL;
- /* Zero the initial thread: */
- memset(_thread_initial, 0, sizeof(struct pthread));
+ /* Initialize the thread stack cache: */
+ SLIST_INIT(&_stackq);
/*
* Write a magic value to the thread structure
@@ -250,27 +238,29 @@ _thread_init(void)
_thread_initial->state = PS_RUNNING;
/* Initialise the queue: */
- _thread_queue_init(&(_thread_initial->join_queue));
+ TAILQ_INIT(&(_thread_initial->join_queue));
/* Initialize the owned mutex queue and count: */
TAILQ_INIT(&(_thread_initial->mutexq));
_thread_initial->priority_mutex_count = 0;
+ /* Give it a useful name */
+ pthread_set_name_np(_thread_initial, "main");
+
/* Initialise the rest of the fields: */
- _thread_initial->sched_defer_count = 0;
- _thread_initial->yield_on_sched_undefer = 0;
+ _thread_initial->poll_data.nfds = 0;
+ _thread_initial->poll_data.fds = NULL;
+ _thread_initial->sig_defer_count = 0;
+ _thread_initial->yield_on_sig_undefer = 0;
_thread_initial->specific_data = NULL;
_thread_initial->cleanup = NULL;
- _thread_initial->queue = NULL;
- _thread_initial->qnxt = NULL;
- _thread_initial->nxt = NULL;
_thread_initial->flags = 0;
_thread_initial->error = 0;
_thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE;
_thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED;
- pthread_set_name_np(_thread_initial, "init");
- _SPINUNLOCK(&_thread_initial->lock);
- _thread_link_list = _thread_initial;
+ _SPINLOCK_INIT(&_thread_initial->lock);
+ TAILQ_INIT(&_thread_list);
+ TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
_thread_run = _thread_initial;
/* Initialise the global signal action structure: */
@@ -278,6 +268,9 @@ _thread_init(void)
act.sa_handler = (void (*) ()) _thread_sig_handler;
act.sa_flags = 0;
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
/* Enter a loop to get the existing signal status: */
for (i = 1; i < NSIG; i++) {
/* Check for signals which cannot be trapped: */
@@ -286,7 +279,7 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_thread_sigact[i - 1]) != 0) {
/*
* Abort this process if signal
* initialisation fails:
@@ -309,6 +302,13 @@ _thread_init(void)
PANIC("Cannot initialise signal handler");
}
+ /* Get the kernel clockrate: */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+ len = sizeof (struct clockinfo);
+ if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
+ _clock_res_nsec = clockinfo.tick * 1000;
+
/* Get the table size: */
if ((_thread_dtablesize = getdtablesize()) < 0) {
/*
@@ -319,11 +319,22 @@ _thread_init(void)
}
/* Allocate memory for the file descriptor table: */
if ((_thread_fd_table = (struct fd_table_entry **) malloc(sizeof(struct fd_table_entry *) * _thread_dtablesize)) == NULL) {
+ /* Avoid accesses to file descriptor table on exit: */
+ _thread_dtablesize = 0;
+
/*
* Cannot allocate memory for the file descriptor
* table, so abort this process.
*/
PANIC("Cannot allocate memory for file descriptor table");
+ }
+ /* Allocate memory for the pollfd table: */
+ if ((_thread_pfd_table = (struct pollfd *) malloc(sizeof(struct pollfd) * _thread_dtablesize)) == NULL) {
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for pollfd table");
} else {
/*
* Enter a loop to initialise the file descriptor
@@ -333,13 +344,21 @@ _thread_init(void)
/* Initialise the file descriptor table: */
_thread_fd_table[i] = NULL;
}
+
+ /* Initialize stdio file descriptor table entries: */
+ for (i = 0; i < 3; i++) {
+ if ((_thread_fd_table_init(i) != 0) &&
+ (errno != EBADF))
+ PANIC("Cannot initialize stdio file "
+ "descriptor table entry");
+ }
}
}
#ifdef GCC_2_8_MADE_THREAD_AWARE
/* Create the thread-specific data for the exception linked list. */
if(pthread_key_create(&except_head_key, NULL) != 0)
- PANIC("Failed to create thread specific execption head");
+ PANIC("Failed to create thread specific execption head");
/* Setup the gcc exception handler per thread. */
__set_dynamic_handler_allocator( dynamic_allocator_handler_fn );
@@ -352,10 +371,8 @@ _thread_init(void)
gettimeofday(&kern_inc_prio_time, NULL);
- /* Pull in automatic thread unit. */
- _thread_autoinit_dummy_decl = 1;
+ _thread_autoinit_dummy_decl = 0;
return;
}
-
-#endif _THREAD_SAFE
+#endif
diff --git a/lib/libc_r/uthread/uthread_ioctl.c b/lib/libc_r/uthread/uthread_ioctl.c
index e26b7174797..d7daa17196b 100644
--- a/lib/libc_r/uthread/uthread_ioctl.c
+++ b/lib/libc_r/uthread/uthread_ioctl.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_ioctl.c,v 1.3 1999/11/25 07:01:37 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_ioctl.c,v 1.2 1999/01/06 05:29:24 d Exp $
+ * $FreeBSD: uthread_ioctl.c,v 1.6 1999/08/28 00:03:37 peter Exp $
*/
#include <stdarg.h>
#include <sys/ioctl.h>
diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c
index 42ef1f778bc..374a5d45b90 100644
--- a/lib/libc_r/uthread/uthread_join.c
+++ b/lib/libc_r/uthread/uthread_join.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_join.c,v 1.6 1999/11/25 07:01:37 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_join.c,v 1.5 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_join.c,v 1.9 1999/08/28 00:03:37 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -40,34 +41,26 @@ int
pthread_join(pthread_t pthread, void **thread_return)
{
int ret = 0;
- pthread_t pthread1 = NULL;
- /* This operation is a cancel point: */
+ /* This is a cancellation point: */
_thread_enter_cancellation_point();
/* Check if the caller has specified an invalid thread: */
- if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) {
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
/* Invalid thread: */
- _thread_leave_cancellation_point();
- return(EINVAL);
- }
+ ret = EINVAL;
/* Check if the caller has specified itself: */
- if (pthread == _thread_run) {
+ else if (pthread == _thread_run)
/* Avoid a deadlock condition: */
- _thread_leave_cancellation_point();
- return(EDEADLK);
- }
+ ret = EDEADLK;
/*
* Find the thread in the list of active threads or in the
* list of dead threads:
*/
- if (_find_thread(pthread) == 0 ||
- _find_dead_thread(pthread) == 0)
- pthread1 = pthread;
-
- if (pthread1 == NULL)
+ else if (_find_thread(pthread) != 0 &&
+ _find_dead_thread(pthread) != 0)
/* Return an error: */
ret = ESRCH;
@@ -79,7 +72,7 @@ pthread_join(pthread_t pthread, void **thread_return)
/* Check if the thread is not dead: */
else if (pthread->state != PS_DEAD) {
/* Add the running thread to the join queue: */
- _thread_queue_enq(&(pthread->join_queue), _thread_run);
+ TAILQ_INSERT_TAIL(&(pthread->join_queue), _thread_run, qe);
/* Schedule the next thread: */
_thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
index 78223f4ad10..56d6c7a3999 100644
--- a/lib/libc_r/uthread/uthread_kern.c
+++ b/lib/libc_r/uthread/uthread_kern.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_kern.c,v 1.8 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_kern.c,v 1.9 1999/11/25 07:01:37 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -30,22 +30,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_kern.c,v 1.18 1999/05/08 07:50:05 jasone Exp $
+ * $FreeBSD: uthread_kern.c,v 1.23 1999/09/29 15:18:39 marcel Exp $
*
*/
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <poll.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
-#ifdef _THREAD_RUSAGE
-#include <sys/resource.h>
-#endif
#include <sys/uio.h>
#include <sys/syscall.h>
#include <fcntl.h>
@@ -55,26 +53,34 @@
/* Static function prototype definitions: */
static void
-_thread_kern_select(int wait_reqd);
+_thread_kern_poll(int wait_reqd);
+
+static void
+dequeue_signals(void);
static inline void
thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in);
+static void
+_thread_check_cancel()
+{
+ if (!(_thread_run->flags & PTHREAD_FLAGS_CANCELPT) &&
+ (_thread_run->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS))
+ /*
+ * Check if an async-cancellable thread
+ * has been cancelled.
+ */
+ _thread_cancellation_point();
+}
+
void
_thread_kern_sched(struct sigcontext * scp)
{
- pthread_t pthread;
- pthread_t pthread_h = NULL;
- pthread_t last_thread = NULL;
+ pthread_t pthread, pthread_h = NULL;
struct itimerval itimer;
- struct timespec ts;
- struct timespec ts1;
- struct timeval tv;
- struct timeval tv1;
-#ifdef _THREAD_RUSAGE
- struct rusage ru;
- static struct rusage ru_prev;
-#endif
+ struct timespec ts, ts1;
+ struct timeval tv, tv1;
+ int set_timer = 0;
/*
* Flag the pthread kernel as executing scheduler code
@@ -91,7 +97,9 @@ _thread_kern_sched(struct sigcontext * scp)
*/
memcpy(&_thread_run->saved_sigcontext, scp, sizeof(_thread_run->saved_sigcontext));
- /* Save the floating point data: */
+ /*
+ * Save floating point state.
+ */
_thread_machdep_save_float_state(_thread_run);
/* Flag the signal context as the last state saved: */
@@ -112,25 +120,7 @@ _thread_kern_sched(struct sigcontext * scp)
thread_run_switch_hook(_last_user_thread, _thread_run);
}
- if (!(_thread_run->flags & PTHREAD_AT_CANCEL_POINT) &&
- (_thread_run->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)) {
- /*
- * Cancelations override signals.
- *
- * Stick a cancellation point at the start of
- * each async-cancellable thread's resumption.
- *
- * We allow threads woken at cancel points to do their
- * own checks.
- */
- _thread_cancellation_point();
- }
-
- /*
- * There might be pending signals for this thread, so
- * dispatch any that aren't blocked:
- */
- _dispatch_signals();
+ _thread_check_cancel();
return;
} else
@@ -144,18 +134,6 @@ _thread_kern_sched(struct sigcontext * scp)
/* Save errno. */
_thread_run->error = errno;
-#ifdef _THREAD_RUSAGE
- /* Accumulate time spent */
- if (getrusage(RUSAGE_SELF, &ru))
- PANIC("Cannot get resource usage");
- timersub(&ru.ru_utime, &ru_prev.ru_utime, &tv);
- timeradd(&tv, &_thread_run->ru_utime, &_thread_run->ru_utime);
- timersub(&ru.ru_stime, &ru_prev.ru_stime, &tv);
- timeradd(&tv, &_thread_run->ru_stime, &_thread_run->ru_stime);
- memcpy(&ru_prev.ru_utime, &ru.ru_utime, sizeof ru_prev.ru_utime);
- memcpy(&ru_prev.ru_stime, &ru.ru_stime, sizeof ru_prev.ru_stime);
-#endif /* _THREAD_RUSAGE */
-
/*
* Enter a scheduling loop that finds the next thread that is
* ready to run. This loop completes when there are no more threads
@@ -163,238 +141,208 @@ _thread_kern_sched(struct sigcontext * scp)
* either a sigreturn (if the state was saved as a sigcontext) or a
* longjmp (if the state was saved by a setjmp).
*/
- while (_thread_link_list != NULL) {
+ while (!(TAILQ_EMPTY(&_thread_list))) {
/* Get the current time of day: */
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, &ts);
/*
- * Poll file descriptors to update the state of threads
- * waiting on file I/O where data may be available:
+ * Protect the scheduling queues from access by the signal
+ * handler.
*/
- _thread_kern_select(0);
+ _queue_signals = 1;
- /*
- * Define the maximum time before a scheduling signal
- * is required:
- */
- itimer.it_value.tv_sec = 0;
- itimer.it_value.tv_usec = TIMESLICE_USEC;
-
- /*
- * The interval timer is not reloaded when it
- * times out. The interval time needs to be
- * calculated every time.
- */
- itimer.it_interval.tv_sec = 0;
- itimer.it_interval.tv_usec = 0;
-
- /*
- * Enter a loop to look for sleeping threads that are ready
- * or timedout. While we're at it, also find the smallest
- * timeout value for threads waiting for a time.
- */
- _waitingq_check_reqd = 0; /* reset flag before loop */
- TAILQ_FOREACH(pthread, &_waitingq, pqe) {
- /* Check if this thread is ready: */
- if (pthread->state == PS_RUNNING) {
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
- }
+ if (_thread_run != &_thread_kern_thread) {
/*
- * Check if this thread is blocked by an
- * atomic lock:
+ * This thread no longer needs to yield the CPU.
+ */
+ _thread_run->yield_on_sig_undefer = 0;
+
+ /*
+ * Save the current time as the time that the thread
+ * became inactive:
+ */
+ _thread_run->last_inactive.tv_sec = tv.tv_sec;
+ _thread_run->last_inactive.tv_usec = tv.tv_usec;
+
+ /*
+ * Place the currently running thread into the
+ * appropriate queue(s).
*/
- else if (pthread->state == PS_SPINBLOCK) {
+ switch (_thread_run->state) {
+ case PS_DEAD:
/*
- * If the lock is available, let
- * the thread run.
+ * Dead threads are not placed in any queue:
*/
- if (pthread->data.spinlock->access_lock == 0) {
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- }
+ break;
- /* Check if this thread is to timeout: */
- } else if (pthread->state == PS_COND_WAIT ||
- pthread->state == PS_SLEEP_WAIT ||
- pthread->state == PS_FDR_WAIT ||
- pthread->state == PS_FDW_WAIT ||
- pthread->state == PS_SELECT_WAIT) {
- /* Check if this thread is to wait forever: */
- if (pthread->wakeup_time.tv_sec == -1) {
- }
+ case PS_RUNNING:
/*
- * Check if this thread is to wakeup
- * immediately or if it is past its wakeup
- * time:
+ * Runnable threads can't be placed in the
+ * priority queue until after waiting threads
+ * are polled (to preserve round-robin
+ * scheduling).
*/
- else if ((pthread->wakeup_time.tv_sec == 0 &&
- pthread->wakeup_time.tv_nsec == 0) ||
- (ts.tv_sec > pthread->wakeup_time.tv_sec) ||
- ((ts.tv_sec == pthread->wakeup_time.tv_sec) &&
- (ts.tv_nsec >= pthread->wakeup_time.tv_nsec))) {
+ if ((_thread_run->slice_usec != -1) &&
+ (_thread_run->attr.sched_policy != SCHED_FIFO)) {
/*
- * Check if this thread is waiting on
- * select:
+ * Accumulate the number of microseconds that
+ * this thread has run for:
*/
- if (pthread->state == PS_SELECT_WAIT) {
- /*
- * The select has timed out, so
- * zero the file descriptor
- * sets:
- */
- FD_ZERO(&pthread->data.select_data->readfds);
- FD_ZERO(&pthread->data.select_data->writefds);
- FD_ZERO(&pthread->data.select_data->exceptfds);
- pthread->data.select_data->nfds = 0;
- }
- /*
- * Return an error as an interrupted
- * wait:
- */
- _thread_seterrno(pthread, EINTR);
+ _thread_run->slice_usec +=
+ (_thread_run->last_inactive.tv_sec -
+ _thread_run->last_active.tv_sec) * 1000000 +
+ _thread_run->last_inactive.tv_usec -
+ _thread_run->last_active.tv_usec;
+
+ /* Check for time quantum exceeded: */
+ if (_thread_run->slice_usec > TIMESLICE_USEC)
+ _thread_run->slice_usec = -1;
+ }
+ break;
- /*
- * Flag the timeout in the thread
- * structure:
- */
- pthread->timeout = 1;
+ /*
+ * States which do not depend on file descriptor I/O
+ * operations or timeouts:
+ */
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGTHREAD:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ case PS_WAIT_WAIT:
+ /* No timeouts for these states: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
- /*
- * Change the threads state to allow
- * it to be restarted:
- */
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- } else {
- /*
- * Calculate the time until this thread
- * is ready, allowing for the clock
- * resolution:
- */
- ts1.tv_sec = pthread->wakeup_time.tv_sec
- - ts.tv_sec;
- ts1.tv_nsec = pthread->wakeup_time.tv_nsec
- - ts.tv_nsec + CLOCK_RES_NSEC;
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
- /*
- * Check for underflow of the
- * nanosecond field:
- */
- if (ts1.tv_nsec < 0) {
- /*
- * Allow for the underflow
- * of the nanosecond field:
- */
- ts1.tv_sec--;
- ts1.tv_nsec += 1000000000;
- }
- /*
- * Check for overflow of the nanosecond
- * field:
- */
- if (ts1.tv_nsec >= 1000000000) {
- /*
- * Allow for the overflow of
- * the nanosecond field:
- */
- ts1.tv_sec++;
- ts1.tv_nsec -= 1000000000;
- }
- /*
- * Convert the timespec structure
- * to a timeval structure:
- */
- TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
- /*
- * Check if the thread will be ready
- * sooner than the earliest ones found
- * so far:
- */
- if (timercmp(&tv1, &itimer.it_value, <)) {
- /*
- * Update the time value:
- */
- itimer.it_value.tv_sec = tv1.tv_sec;
- itimer.it_value.tv_usec = tv1.tv_usec;
- }
- }
+ /* States which can timeout: */
+ case PS_COND_WAIT:
+ case PS_SLEEP_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States that require periodic work: */
+ case PS_SPINBLOCK:
+ /* No timeouts for this state: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Increment spinblock count: */
+ _spinblock_count++;
+
+ /* fall through */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+
+ /* Insert into the work queue: */
+ PTHREAD_WORKQ_INSERT(_thread_run);
}
}
- /* Check if there is a current thread: */
- if (_thread_run != _thread_kern_threadp) {
- /*
- * This thread no longer needs to yield the CPU.
- */
- _thread_run->yield_on_sched_undefer = 0;
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
- /*
- * Save the current time as the time that the thread
- * became inactive:
- */
- _thread_run->last_inactive.tv_sec = tv.tv_sec;
- _thread_run->last_inactive.tv_usec = tv.tv_usec;
+ /*
+ * Poll file descriptors to update the state of threads
+ * waiting on file I/O where data may be available:
+ */
+ _thread_kern_poll(0);
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Wake up threads that have timedout. This has to be
+ * done after polling in case a thread does a poll or
+ * select with zero time.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ while (((pthread = TAILQ_FIRST(&_waitingq)) != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1) &&
+ (((pthread->wakeup_time.tv_sec == 0) &&
+ (pthread->wakeup_time.tv_nsec == 0)) ||
+ (pthread->wakeup_time.tv_sec < ts.tv_sec) ||
+ ((pthread->wakeup_time.tv_sec == ts.tv_sec) &&
+ (pthread->wakeup_time.tv_nsec <= ts.tv_nsec)))) {
+ switch (pthread->state) {
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Return zero file descriptors ready: */
+ pthread->data.poll_data->nfds = 0;
+ /* fall through */
+ default:
+ /*
+ * Remove this thread from the waiting queue
+ * (and work queue if necessary) and place it
+ * in the ready queue.
+ */
+ PTHREAD_WAITQ_CLEARACTIVE();
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ break;
+ }
/*
- * Accumulate the number of microseconds that this
- * thread has run for:
+ * Flag the timeout in the thread structure:
*/
- if ((_thread_run->slice_usec != -1) &&
- (_thread_run->attr.sched_policy != SCHED_FIFO)) {
- _thread_run->slice_usec +=
- (_thread_run->last_inactive.tv_sec -
- _thread_run->last_active.tv_sec) * 1000000 +
- _thread_run->last_inactive.tv_usec -
- _thread_run->last_active.tv_usec;
-
- /* Check for time quantum exceeded: */
- if (_thread_run->slice_usec > TIMESLICE_USEC)
- _thread_run->slice_usec = -1;
- }
- if (_thread_run->state == PS_RUNNING) {
- if (_thread_run->slice_usec == -1) {
- /*
- * The thread exceeded its time
- * quantum or it yielded the CPU;
- * place it at the tail of the
- * queue for its priority.
- */
- PTHREAD_PRIOQ_INSERT_TAIL(_thread_run);
- } else {
- /*
- * The thread hasn't exceeded its
- * interval. Place it at the head
- * of the queue for its priority.
- */
- PTHREAD_PRIOQ_INSERT_HEAD(_thread_run);
- }
- }
- else if (_thread_run->state == PS_DEAD) {
+ pthread->timeout = 1;
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Check if there is a current runnable thread that isn't
+ * already in the ready queue:
+ */
+ if ((_thread_run != &_thread_kern_thread) &&
+ (_thread_run->state == PS_RUNNING) &&
+ ((_thread_run->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0)) {
+ if (_thread_run->slice_usec == -1) {
/*
- * Don't add dead threads to the waiting
- * queue, because when they're reaped, it
- * will corrupt the queue.
+ * The thread exceeded its time
+ * quantum or it yielded the CPU;
+ * place it at the tail of the
+ * queue for its priority.
*/
- }
- else {
+ PTHREAD_PRIOQ_INSERT_TAIL(_thread_run);
+ } else {
/*
- * This thread has changed state and needs
- * to be placed in the waiting queue.
+ * The thread hasn't exceeded its
+ * interval. Place it at the head
+ * of the queue for its priority.
*/
- PTHREAD_WAITQ_INSERT(_thread_run);
-
- /* Restart the time slice: */
- _thread_run->slice_usec = -1;
+ PTHREAD_PRIOQ_INSERT_HEAD(_thread_run);
}
}
/*
* Get the highest priority thread in the ready queue.
*/
- pthread_h = PTHREAD_PRIOQ_FIRST;
+ pthread_h = PTHREAD_PRIOQ_FIRST();
/* Check if there are no threads ready to run: */
if (pthread_h == NULL) {
@@ -403,20 +351,86 @@ _thread_kern_sched(struct sigcontext * scp)
* the running thread to point to the global kernel
* thread structure:
*/
- _thread_run = _thread_kern_threadp;
+ _thread_run = &_thread_kern_thread;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
/*
* There are no threads ready to run, so wait until
* something happens that changes this condition:
*/
- _thread_kern_select(1);
- } else {
+ _thread_kern_poll(1);
+ }
+ else {
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread_h);
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /* Check to see if there is more than one thread: */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Check for signals queued while the scheduling
+ * queues were protected:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Clear before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues again: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /*
+ * Check for a higher priority thread that
+ * became runnable due to signal handling.
+ */
+ if (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > pthread_h->active_priority)) {
+ /*
+ * Insert the lower priority thread
+ * at the head of its priority list:
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread_h);
+
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /* There's a new thread in town: */
+ pthread_h = pthread;
+ }
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /*
+ * Check to see if there is more than one
+ * thread:
+ */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
/* Make the selected thread the current thread: */
_thread_run = pthread_h;
- /* Remove the thread from the ready queue. */
- PTHREAD_PRIOQ_REMOVE(_thread_run);
-
/*
* Save the current time as the time that the thread
* became active:
@@ -425,6 +439,76 @@ _thread_kern_sched(struct sigcontext * scp)
_thread_run->last_active.tv_usec = tv.tv_usec;
/*
+ * Define the maximum time before a scheduling signal
+ * is required:
+ */
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = TIMESLICE_USEC;
+
+ /*
+ * The interval timer is not reloaded when it
+ * times out. The interval time needs to be
+ * calculated every time.
+ */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+
+ /* Get first thread on the waiting list: */
+ if ((pthread != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1)) {
+ /*
+ * Calculate the time until this thread
+ * is ready, allowing for the clock
+ * resolution:
+ */
+ ts1.tv_sec = pthread->wakeup_time.tv_sec
+ - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec
+ - ts.tv_nsec + _clock_res_nsec;
+
+ /*
+ * Check for underflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec < 0) {
+ /*
+ * Allow for the underflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+ }
+ /*
+ * Check for overflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec >= 1000000000) {
+ /*
+ * Allow for the overflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+ }
+ /*
+ * Convert the timespec structure to a
+ * timeval structure:
+ */
+ TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
+
+ /*
+ * Check if the thread will be ready
+ * sooner than the earliest ones found
+ * so far:
+ */
+ if (timercmp(&tv1, &itimer.it_value, <)) {
+ /*
+ * Update the time value:
+ */
+ itimer.it_value.tv_sec = tv1.tv_sec;
+ itimer.it_value.tv_usec = tv1.tv_usec;
+ }
+ }
+
+ /*
* Check if this thread is running for the first time
* or running again after using its full time slice
* allocation:
@@ -435,7 +519,7 @@ _thread_kern_sched(struct sigcontext * scp)
}
/* Check if there is more than one thread: */
- if (_thread_run != _thread_link_list || _thread_run->nxt != NULL) {
+ if (set_timer != 0) {
/*
* Start the interval timer for the
* calculated time interval:
@@ -454,8 +538,9 @@ _thread_kern_sched(struct sigcontext * scp)
/* Check if a signal context was saved: */
if (_thread_run->sig_saved == 1) {
-
- /* Restore the floating point state: */
+ /*
+ * Restore floating point state.
+ */
_thread_machdep_restore_float_state(_thread_run);
/*
@@ -474,13 +559,14 @@ _thread_kern_sched(struct sigcontext * scp)
_thread_run);
}
_thread_sys_sigreturn(&_thread_run->saved_sigcontext);
- } else
+ } else {
/*
* Do a longjmp to restart the thread that
* was context switched out (by a longjmp to
* a different thread):
*/
_thread_machdep_longjmp(_thread_run->saved_jmp_buf, 1);
+ }
/* This point should not be reached. */
PANIC("Thread has returned from sigreturn or longjmp");
@@ -494,6 +580,19 @@ _thread_kern_sched(struct sigcontext * scp)
void
_thread_kern_sched_state(enum pthread_state state, const char *fname, int lineno)
{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and is placed into the proper queue.
+ */
+ _queue_signals = 1;
+
/* Change the state of the current thread: */
_thread_run->state = state;
_thread_run->fname = fname;
@@ -508,6 +607,20 @@ void
_thread_kern_sched_state_unlock(enum pthread_state state,
spinlock_t *lock, char *fname, int lineno)
{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and it is placed into the proper
+ * queue(s).
+ */
+ _queue_signals = 1;
+
/* Change the state of the current thread: */
_thread_run->state = state;
_thread_run->fname = fname;
@@ -521,385 +634,193 @@ _thread_kern_sched_state_unlock(enum pthread_state state,
}
static void
-_thread_kern_select(int wait_reqd)
+_thread_kern_poll(int wait_reqd)
{
- char bufr[128];
- fd_set fd_set_except;
- fd_set fd_set_read;
- fd_set fd_set_write;
int count = 0;
- int count_dec;
- int found_one;
- int i;
- int nfds = -1;
- int settimeout;
- pthread_t pthread;
- ssize_t num;
+ int i, found;
+ int kern_pipe_added = 0;
+ int nfds = 0;
+ int timeout_ms = 0;
+ struct pthread *pthread;
struct timespec ts;
- struct timespec ts1;
- struct timeval *p_tv;
struct timeval tv;
- struct timeval tv1;
-
- /* Zero the file descriptor sets: */
- FD_ZERO(&fd_set_read);
- FD_ZERO(&fd_set_write);
- FD_ZERO(&fd_set_except);
/* Check if the caller wants to wait: */
- if (wait_reqd) {
- /*
- * Add the pthread kernel pipe file descriptor to the read
- * set:
- */
- FD_SET(_thread_kern_pipe[0], &fd_set_read);
- nfds = _thread_kern_pipe[0];
-
+ if (wait_reqd == 0) {
+ timeout_ms = 0;
+ }
+ else {
/* Get the current time of day: */
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ _queue_signals = 1;
+ pthread = TAILQ_FIRST(&_waitingq);
+ _queue_signals = 0;
+
+ if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
+ /*
+ * Either there are no threads in the waiting queue,
+ * or there are no threads that can timeout.
+ */
+ timeout_ms = -1;
+ }
+ else {
+ /*
+ * Calculate the time left for the next thread to
+ * timeout allowing for the clock resolution:
+ */
+ timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
+ 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ _clock_res_nsec) / 1000000);
+ /*
+ * Don't allow negative timeouts:
+ */
+ if (timeout_ms < 0)
+ timeout_ms = 0;
+ }
}
- /* Initialise the time value structure: */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
/*
- * Enter a loop to process threads waiting on either file descriptors
- * or times:
+ * Check to see if the signal queue needs to be walked to look
+ * for threads awoken by a signal while in the scheduler.
*/
- _waitingq_check_reqd = 0; /* reset flag before loop */
- TAILQ_FOREACH (pthread, &_waitingq, pqe) {
- /* Assume that this state does not time out: */
- settimeout = 0;
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling queued signals: */
+ _sigq_check_reqd = 0;
- /* Process according to thread state: */
- switch (pthread->state) {
+ dequeue_signals();
+ }
+
+ /*
+ * Check for a thread that became runnable due to a signal:
+ */
+ if (PTHREAD_PRIOQ_FIRST() != NULL) {
/*
- * States which do not depend on file descriptor I/O
- * operations or timeouts:
+ * Since there is at least one runnable thread,
+ * disable the wait.
*/
- case PS_DEAD:
- case PS_DEADLOCK:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
- case PS_JOIN:
- case PS_MUTEX_WAIT:
- case PS_SIGTHREAD:
- case PS_SIGWAIT:
- case PS_STATE_MAX:
- case PS_WAIT_WAIT:
- case PS_SUSPENDED:
- case PS_SIGSUSPEND:
- /* Nothing to do here. */
- break;
+ timeout_ms = 0;
+ }
+
+ /*
+ * Form the poll table:
+ */
+ nfds = 0;
+ if (timeout_ms != 0) {
+ /* Add the kernel pipe to the poll table: */
+ _thread_pfd_table[nfds].fd = _thread_kern_pipe[0];
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].revents = 0;
+ nfds++;
+ kern_pipe_added = 1;
+ }
- case PS_RUNNING:
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
/*
- * A signal occurred and made this thread ready
- * while in the scheduler or while the scheduling
- * queues were protected.
+ * If the lock is available, let the thread run.
*/
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ /* One less thread in a spinblock state: */
+ _spinblock_count--;
+ /*
+ * Since there is at least one runnable
+ * thread, disable the wait.
+ */
+ timeout_ms = 0;
+ }
break;
/* File descriptor read wait: */
case PS_FDR_WAIT:
- /* Add the file descriptor to the read set: */
- FD_SET(pthread->data.fd.fd, &fd_set_read);
-
- /*
- * Check if this file descriptor is greater than any
- * of those seen so far:
- */
- if (pthread->data.fd.fd > nfds) {
- /* Remember this file descriptor: */
- nfds = pthread->data.fd.fd;
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
}
- /* Increment the file descriptor count: */
- count++;
-
- /* This state can time out: */
- settimeout = 1;
break;
/* File descriptor write wait: */
case PS_FDW_WAIT:
- /* Add the file descriptor to the write set: */
- FD_SET(pthread->data.fd.fd, &fd_set_write);
-
- /*
- * Check if this file descriptor is greater than any
- * of those seen so far:
- */
- if (pthread->data.fd.fd > nfds) {
- /* Remember this file descriptor: */
- nfds = pthread->data.fd.fd;
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLWRNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
}
- /* Increment the file descriptor count: */
- count++;
-
- /* This state can time out: */
- settimeout = 1;
- break;
-
- /* States that time out: */
- case PS_SLEEP_WAIT:
- case PS_COND_WAIT:
- /* Flag a timeout as required: */
- settimeout = 1;
break;
- /* Select wait: */
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
case PS_SELECT_WAIT:
- /*
- * Enter a loop to process each file descriptor in
- * the thread-specific file descriptor sets:
- */
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- /*
- * Check if this file descriptor is set for
- * exceptions:
- */
- if (FD_ISSET(i, &pthread->data.select_data->exceptfds)) {
- /*
- * Add the file descriptor to the
- * exception set:
- */
- FD_SET(i, &fd_set_except);
-
- /*
- * Increment the file descriptor
- * count:
- */
- count++;
-
- /*
- * Check if this file descriptor is
- * greater than any of those seen so
- * far:
- */
- if (i > nfds) {
- /*
- * Remember this file
- * descriptor:
- */
- nfds = i;
- }
- }
- /*
- * Check if this file descriptor is set for
- * write:
- */
- if (FD_ISSET(i, &pthread->data.select_data->writefds)) {
- /*
- * Add the file descriptor to the
- * write set:
- */
- FD_SET(i, &fd_set_write);
-
- /*
- * Increment the file descriptor
- * count:
- */
- count++;
-
- /*
- * Check if this file descriptor is
- * greater than any of those seen so
- * far:
- */
- if (i > nfds) {
- /*
- * Remember this file
- * descriptor:
- */
- nfds = i;
- }
- }
- /*
- * Check if this file descriptor is set for
- * read:
- */
- if (FD_ISSET(i, &pthread->data.select_data->readfds)) {
- /*
- * Add the file descriptor to the
- * read set:
- */
- FD_SET(i, &fd_set_read);
-
- /*
- * Increment the file descriptor
- * count:
- */
- count++;
-
- /*
- * Check if this file descriptor is
- * greater than any of those seen so
- * far:
- */
- if (i > nfds) {
- /*
- * Remember this file
- * descriptor:
- */
- nfds = i;
- }
+ /* Limit number of polled files to table size: */
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ _thread_pfd_table[nfds + i].fd =
+ pthread->data.poll_data->fds[i].fd;
+ _thread_pfd_table[nfds + i].events =
+ pthread->data.poll_data->fds[i].events;
}
+ nfds += pthread->data.poll_data->nfds;
}
-
- /* This state can time out: */
- settimeout = 1;
break;
- }
-
- /*
- * Check if the caller wants to wait and if the thread state
- * is one that times out:
- */
- if (wait_reqd && settimeout) {
- /* Check if this thread wants to wait forever: */
- if (pthread->wakeup_time.tv_sec == -1) {
- }
- /* Check if this thread doesn't want to wait at all: */
- else if (pthread->wakeup_time.tv_sec == 0 &&
- pthread->wakeup_time.tv_nsec == 0) {
- /* Override the caller's request to wait: */
- wait_reqd = 0;
- } else {
- /*
- * Calculate the time until this thread is
- * ready, allowing for the clock resolution:
- */
- ts1.tv_sec = pthread->wakeup_time.tv_sec - ts.tv_sec;
- ts1.tv_nsec = pthread->wakeup_time.tv_nsec - ts.tv_nsec +
- CLOCK_RES_NSEC;
- /*
- * Check for underflow of the nanosecond
- * field:
- */
- if (ts1.tv_nsec < 0) {
- /*
- * Allow for the underflow of the
- * nanosecond field:
- */
- ts1.tv_sec--;
- ts1.tv_nsec += 1000000000;
- }
- /*
- * Check for overflow of the nanosecond
- * field:
- */
- if (ts1.tv_nsec >= 1000000000) {
- /*
- * Allow for the overflow of the
- * nanosecond field:
- */
- ts1.tv_sec++;
- ts1.tv_nsec -= 1000000000;
- }
- /*
- * Convert the timespec structure to a
- * timeval structure:
- */
- TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
-
- /*
- * Check if no time value has been found yet,
- * or if the thread will be ready sooner that
- * the earliest one found so far:
- */
- if ((tv.tv_sec == 0 && tv.tv_usec == 0) || timercmp(&tv1, &tv, <)) {
- /* Update the time value: */
- tv.tv_sec = tv1.tv_sec;
- tv.tv_usec = tv1.tv_usec;
- }
- }
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
}
}
+ PTHREAD_WAITQ_CLEARACTIVE();
- /* Check if the caller wants to wait: */
- if (wait_reqd) {
- /* Check if no threads were found with timeouts: */
- if (tv.tv_sec == 0 && tv.tv_usec == 0) {
- /* Wait forever: */
- p_tv = NULL;
- } else {
- /*
- * Point to the time value structure which contains
- * the earliest time that a thread will be ready:
- */
- p_tv = &tv;
- }
+ /*
+ * Wait for a file descriptor to be ready for read, write, or
+ * an exception, or a timeout to occur:
+ */
+ count = _thread_sys_poll(_thread_pfd_table, nfds, timeout_ms);
+ if (kern_pipe_added != 0)
/*
- * Flag the pthread kernel as in a select. This is to avoid
- * the window between the next statement that unblocks
- * signals and the select statement which follows.
+ * Remove the pthread kernel pipe file descriptor
+ * from the pollfd table:
*/
- _thread_kern_in_select = 1;
+ nfds = 1;
+ else
+ nfds = 0;
+ /*
+ * Check if it is possible that there are bytes in the kernel
+ * read pipe waiting to be read:
+ */
+ if (count < 0 || ((kern_pipe_added != 0) &&
+ (_thread_pfd_table[0].revents & POLLRDNORM))) {
/*
- * Wait for a file descriptor to be ready for read, write, or
- * an exception, or a timeout to occur:
+ * If the kernel read pipe was included in the
+ * count:
*/
- count = _thread_sys_select(nfds + 1, &fd_set_read, &fd_set_write, &fd_set_except, p_tv);
+ if (count > 0) {
+ /* Decrement the count of file descriptors: */
+ count--;
+ }
- /* Reset the kernel in select flag: */
- _thread_kern_in_select = 0;
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling signals: */
+ _sigq_check_reqd = 0;
- /*
- * Check if it is possible that there are bytes in the kernel
- * read pipe waiting to be read:
- */
- if (count < 0 || FD_ISSET(_thread_kern_pipe[0], &fd_set_read)) {
- /*
- * Check if the kernel read pipe was included in the
- * count:
- */
- if (count > 0) {
- /*
- * Remove the kernel read pipe from the
- * count:
- */
- FD_CLR(_thread_kern_pipe[0], &fd_set_read);
-
- /* Decrement the count of file descriptors: */
- count--;
- }
- /*
- * Enter a loop to read (and trash) bytes from the
- * pthread kernel pipe:
- */
- while ((num = _thread_sys_read(_thread_kern_pipe[0], bufr, sizeof(bufr))) > 0) {
- /*
- * The buffer read contains one byte per
- * signal and each byte is the signal number.
- * This data is not used, but the fact that
- * the signal handler wrote to the pipe *is*
- * used to cause the _select call
- * to complete if the signal occurred between
- * the time when signals were unblocked and
- * the _select select call being
- * made.
- */
- }
+ dequeue_signals();
}
}
- /* Check if there are file descriptors to poll: */
- else if (count > 0) {
- /*
- * Point to the time value structure which has been zeroed so
- * that the call to _select will not wait:
- */
- p_tv = &tv;
-
- /* Poll file descrptors without wait: */
- count = _thread_sys_select(nfds + 1, &fd_set_read, &fd_set_write, &fd_set_except, p_tv);
- }
/*
* Check if any file descriptors are ready:
@@ -908,302 +829,133 @@ _thread_kern_select(int wait_reqd)
/*
* Enter a loop to look for threads waiting on file
* descriptors that are flagged as available by the
- * _select syscall:
+ * _poll syscall:
*/
- TAILQ_FOREACH (pthread, &_waitingq, pqe) {
- /* Process according to thread state: */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
switch (pthread->state) {
- /*
- * States which do not depend on file
- * descriptor I/O operations:
- */
- case PS_COND_WAIT:
- case PS_DEAD:
- case PS_DEADLOCK:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
- case PS_JOIN:
- case PS_MUTEX_WAIT:
- case PS_SIGWAIT:
- case PS_SLEEP_WAIT:
- case PS_WAIT_WAIT:
- case PS_SIGTHREAD:
- case PS_STATE_MAX:
- case PS_SUSPENDED:
- case PS_SIGSUSPEND:
- /* Nothing to do here. */
- break;
-
- case PS_RUNNING:
+ case PS_SPINBLOCK:
/*
- * A signal occurred and made this thread
- * ready while in the scheduler.
+ * If the lock is available, let the thread run.
*/
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
- break;
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
- /* File descriptor read wait: */
- case PS_FDR_WAIT:
- /*
- * Check if the file descriptor is available
- * for read:
- */
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_read)) {
/*
- * Change the thread state to allow
- * it to read from the file when it
- * is scheduled next:
+ * One less thread in a spinblock state:
*/
- pthread->state = PS_RUNNING;
+ _spinblock_count--;
+ }
+ break;
- /*
- * Remove it from the waiting queue
- * and add it to the ready queue:
- */
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLRDNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
}
+ nfds++;
break;
/* File descriptor write wait: */
case PS_FDW_WAIT:
- /*
- * Check if the file descriptor is available
- * for write:
- */
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_write)) {
- /*
- * Change the thread state to allow
- * it to write to the file when it is
- * scheduled next:
- */
- pthread->state = PS_RUNNING;
-
- /*
- * Remove it from the waiting queue
- * and add it to the ready queue:
- */
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLWRNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
}
+ nfds++;
break;
- /* Select wait: */
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
case PS_SELECT_WAIT:
- /*
- * Reset the flag that indicates if a file
- * descriptor is ready for some type of
- * operation:
- */
- count_dec = 0;
-
- /*
- * Enter a loop to search though the
- * thread-specific select file descriptors
- * for the first descriptor that is ready:
- */
- for (i = 0; i < pthread->data.select_data->nfds && count_dec == 0; i++) {
- /*
- * Check if this file descriptor does
- * not have an exception:
- */
- if (FD_ISSET(i, &pthread->data.select_data->exceptfds) && FD_ISSET(i, &fd_set_except)) {
- /*
- * Flag this file descriptor
- * as ready:
- */
- count_dec = 1;
- }
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
/*
- * Check if this file descriptor is
- * not ready for write:
+ * Enter a loop looking for I/O
+ * readiness:
*/
- if (FD_ISSET(i, &pthread->data.select_data->writefds) && FD_ISSET(i, &fd_set_write)) {
- /*
- * Flag this file descriptor
- * as ready:
- */
- count_dec = 1;
+ found = 0;
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ if (_thread_pfd_table[nfds + i].revents != 0) {
+ pthread->data.poll_data->fds[i].revents =
+ _thread_pfd_table[nfds + i].revents;
+ found++;
+ }
}
- /*
- * Check if this file descriptor is
- * not ready for read:
- */
- if (FD_ISSET(i, &pthread->data.select_data->readfds) && FD_ISSET(i, &fd_set_read)) {
- /*
- * Flag this file descriptor
- * as ready:
- */
- count_dec = 1;
+
+ /* Increment before destroying: */
+ nfds += pthread->data.poll_data->nfds;
+
+ if (found != 0) {
+ pthread->data.poll_data->nfds = found;
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
}
}
+ else
+ nfds += pthread->data.poll_data->nfds;
+ break;
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+ else if (_spinblock_count != 0) {
+ /*
+ * Enter a loop to look for threads waiting on a spinlock
+ * that is now available.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ if (pthread->state == PS_SPINBLOCK) {
/*
- * Check if any file descriptors are ready
- * for the current thread:
+ * If the lock is available, let the thread run.
*/
- if (count_dec) {
- /*
- * Reset the count of file
- * descriptors that are ready for
- * this thread:
- */
- found_one = 0;
-
- /*
- * Enter a loop to search though the
- * thread-specific select file
- * descriptors:
- */
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- /*
- * Reset the count of
- * operations for which the
- * current file descriptor is
- * ready:
- */
- count_dec = 0;
-
- /*
- * Check if this file
- * descriptor is selected for
- * exceptions:
- */
- if (FD_ISSET(i, &pthread->data.select_data->exceptfds)) {
- /*
- * Check if this file
- * descriptor has an
- * exception:
- */
- if (FD_ISSET(i, &fd_set_except)) {
- /*
- * Increment
- * the count
- * for this
- * file:
- */
- count_dec++;
- } else {
- /*
- * Clear the
- * file
- * descriptor
- * in the
- * thread-spec
- * ific file
- * descriptor
- * set:
- */
- FD_CLR(i, &pthread->data.select_data->exceptfds);
- }
- }
- /*
- * Check if this file
- * descriptor is selected for
- * write:
- */
- if (FD_ISSET(i, &pthread->data.select_data->writefds)) {
- /*
- * Check if this file
- * descriptor is
- * ready for write:
- */
- if (FD_ISSET(i, &fd_set_write)) {
- /*
- * Increment
- * the count
- * for this
- * file:
- */
- count_dec++;
- } else {
- /*
- * Clear the
- * file
- * descriptor
- * in the
- * thread-spec
- * ific file
- * descriptor
- * set:
- */
- FD_CLR(i, &pthread->data.select_data->writefds);
- }
- }
- /*
- * Check if this file
- * descriptor is selected for
- * read:
- */
- if (FD_ISSET(i, &pthread->data.select_data->readfds)) {
- /*
- * Check if this file
- * descriptor is
- * ready for read:
- */
- if (FD_ISSET(i, &fd_set_read)) {
- /*
- * Increment
- * the count
- * for this
- * file:
- */
- count_dec++;
- } else {
- /*
- * Clear the
- * file
- * descriptor
- * in the
- * thread-spec
- * ific file
- * descriptor
- * set:
- */
- FD_CLR(i, &pthread->data.select_data->readfds);
- }
- }
- /*
- * Check if the current file
- * descriptor is ready for
- * any one of the operations:
- */
- if (count_dec > 0) {
- /*
- * Increment the
- * count of file
- * descriptors that
- * are ready for the
- * current thread:
- */
- found_one++;
- }
- }
-
- /*
- * Return the number of file
- * descriptors that are ready:
- */
- pthread->data.select_data->nfds = found_one;
-
- /*
- * Change the state of the current
- * thread to run:
- */
- pthread->state = PS_RUNNING;
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
/*
- * Remove it from the waiting queue
- * and add it to the ready queue:
+ * One less thread in a spinblock state:
*/
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ _spinblock_count--;
}
- break;
}
}
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ while (_sigq_check_reqd != 0) {
+ /* Handle queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
}
/* Nothing to return. */
@@ -1253,59 +1005,101 @@ _thread_kern_set_timeout(struct timespec * timeout)
}
void
-_thread_kern_sched_defer(void)
+_thread_kern_sig_defer(void)
{
- /* Allow scheduling deferral to be recursive. */
- _thread_run->sched_defer_count++;
+ /* Allow signal deferral to be recursive. */
+ _thread_run->sig_defer_count++;
}
void
-_thread_kern_sched_undefer(void)
+_thread_kern_sig_undefer(void)
{
pthread_t pthread;
int need_resched = 0;
/*
* Perform checks to yield only if we are about to undefer
- * scheduling.
+ * signals.
*/
- if (_thread_run->sched_defer_count == 1) {
+ if (_thread_run->sig_defer_count > 1) {
+ /* Decrement the signal deferral count. */
+ _thread_run->sig_defer_count--;
+ }
+ else if (_thread_run->sig_defer_count == 1) {
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+
/*
- * Check if the waiting queue needs to be examined for
- * threads that are now ready:
+ * Check if there are queued signals:
*/
- while (_waitingq_check_reqd != 0) {
- /* Clear the flag before checking the waiting queue: */
- _waitingq_check_reqd = 0;
-
- TAILQ_FOREACH(pthread, &_waitingq, pqe) {
- if (pthread->state == PS_RUNNING) {
- PTHREAD_WAITQ_REMOVE(pthread);
- PTHREAD_PRIOQ_INSERT_TAIL(pthread);
- }
+ while (_sigq_check_reqd != 0) {
+ /* Defer scheduling while we process queued signals: */
+ _thread_run->sig_defer_count = 1;
+
+ /* Clear the flag before checking the signal queue: */
+ _sigq_check_reqd = 0;
+
+ /* Dequeue and handle signals: */
+ dequeue_signals();
+
+ /*
+ * Avoiding an unnecessary check to reschedule, check
+ * to see if signal handling caused a higher priority
+ * thread to become ready.
+ */
+ if ((need_resched == 0) &&
+ (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > _thread_run->active_priority))) {
+ need_resched = 1;
}
+
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
}
- /*
- * We need to yield if a thread change of state caused a
- * higher priority thread to become ready, or if a
- * scheduling signal occurred while preemption was disabled.
- */
- if ((((pthread = PTHREAD_PRIOQ_FIRST) != NULL) &&
- (pthread->active_priority > _thread_run->active_priority)) ||
- (_thread_run->yield_on_sched_undefer != 0)) {
- _thread_run->yield_on_sched_undefer = 0;
- need_resched = 1;
+ /* Yield the CPU if necessary: */
+ if (need_resched || _thread_run->yield_on_sig_undefer != 0) {
+ _thread_run->yield_on_sig_undefer = 0;
+ _thread_kern_sched(NULL);
}
}
+}
- if (_thread_run->sched_defer_count > 0) {
- /* Decrement the scheduling deferral count. */
- _thread_run->sched_defer_count--;
+static void
+dequeue_signals(void)
+{
+ char bufr[128];
+ int i, num;
- /* Yield the CPU if necessary: */
- if (need_resched)
- _thread_kern_sched(NULL);
+ /*
+ * Enter a loop to read and handle queued signals from the
+ * pthread kernel pipe:
+ */
+ while (((num = _thread_sys_read(_thread_kern_pipe[0], bufr,
+ sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
+ /*
+ * The buffer read contains one byte per signal and
+ * each byte is the signal number.
+ */
+ for (i = 0; i < num; i++) {
+ if ((int) bufr[i] == _SCHED_SIGNAL) {
+ /*
+ * Scheduling signals shouldn't ever be
+ * queued; just ignore it for now.
+ */
+ }
+ else {
+ /* Handle this signal: */
+ _thread_sig_handle((int) bufr[i], NULL);
+ }
+ }
+ }
+ if ((num < 0) && (errno != EAGAIN)) {
+ /*
+ * The only error we should expect is if there is
+ * no data to read.
+ */
+ PANIC("Unable to read from thread kernel pipe");
}
}
@@ -1316,10 +1110,10 @@ thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in)
pthread_t tid_in = thread_in;
if ((tid_out != NULL) &&
- (tid_out->flags & PTHREAD_FLAGS_PRIVATE != 0))
+ ((tid_out->flags & PTHREAD_FLAGS_PRIVATE) != 0))
tid_out = NULL;
if ((tid_in != NULL) &&
- (tid_in->flags & PTHREAD_FLAGS_PRIVATE != 0))
+ ((tid_in->flags & PTHREAD_FLAGS_PRIVATE) != 0))
tid_in = NULL;
if ((_sched_switch_hook != NULL) && (tid_out != tid_in)) {
diff --git a/lib/libc_r/uthread/uthread_kill.c b/lib/libc_r/uthread/uthread_kill.c
index dc698ff1660..172d3817513 100644
--- a/lib/libc_r/uthread/uthread_kill.c
+++ b/lib/libc_r/uthread/uthread_kill.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_kill.c,v 1.6 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_kill.c,v 1.7 1999/11/25 07:01:37 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -21,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_kill.c,v 1.9 1999/08/28 00:03:38 peter Exp $
*/
#include <errno.h>
#include <signal.h>
@@ -47,18 +48,18 @@ pthread_kill(pthread_t pthread, int sig)
/* Invalid signal: */
ret = EINVAL;
- /* Ignored signals get dropped on the floor. */
- else if (_thread_sigact[sig - 1].sa_handler == SIG_IGN)
- ret = 0;
-
- /* Find the thread in the list of active threads: */
- else if ((ret = _find_thread(pthread)) == 0) {
+ /*
+ * Ensure the thread is in the list of active threads, and the
+ * signal is valid (signal 0 specifies error checking only) and
+ * not being ignored:
+ */
+ else if (((ret = _find_thread(pthread)) == 0) && (sig > 0) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
/*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
switch (pthread->state) {
case PS_SIGSUSPEND:
@@ -91,15 +92,19 @@ pthread_kill(pthread_t pthread, int sig)
sigaddset(&pthread->sigpend,sig);
break;
- case PS_SELECT_WAIT:
case PS_FDR_WAIT:
case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
case PS_SLEEP_WAIT:
+ case PS_SELECT_WAIT:
if (!sigismember(&pthread->sigmask, sig) &&
(_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
/* Flag the operation as interrupted: */
pthread->interrupted = 1;
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+
/* Change the state of the thread to run: */
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
@@ -117,11 +122,43 @@ pthread_kill(pthread_t pthread, int sig)
break;
}
+
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[sig - 1].sa_handler != SIG_IGN &&
+ sigismember(&pthread->sigpend, sig) &&
+ !sigismember(&pthread->sigmask, sig)) {
+ pthread_t pthread_saved = _thread_run;
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count++;
+
+ _thread_run = pthread;
+
+ /* Clear the pending signal: */
+ sigdelset(&pthread->sigpend, sig);
+
+ /*
+ * Dispatch the signal via the custom signal
+ * handler:
+ */
+ (*(_thread_sigact[sig - 1].sa_handler))(sig);
+
+ _thread_run = pthread_saved;
+
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count--;
+ }
+
/*
- * Reenable preemption and yield if a scheduling signal
- * occurred while in the critical region.
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
diff --git a/lib/libc_r/uthread/uthread_listen.c b/lib/libc_r/uthread/uthread_listen.c
index 880cb4c6b12..0f9b312b3bb 100644
--- a/lib/libc_r/uthread/uthread_listen.c
+++ b/lib/libc_r/uthread/uthread_listen.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_listen.c,v 1.3 1999/11/25 07:01:38 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_listen.c,v 1.2 1999/01/06 05:29:24 d Exp $
+ * $FreeBSD: uthread_listen.c,v 1.5 1999/08/28 00:03:38 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_mattr_init.c b/lib/libc_r/uthread/uthread_mattr_init.c
index 65b79e9539f..172ddb45b35 100644
--- a/lib/libc_r/uthread/uthread_mattr_init.c
+++ b/lib/libc_r/uthread/uthread_mattr_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_mattr_init.c,v 1.3 1999/05/26 00:18:24 d Exp $ */
+/* $OpenBSD: uthread_mattr_init.c,v 1.4 1999/11/25 07:01:38 d Exp $ */
/*
* Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_mattr_init.c,v 1.5 1999/08/28 00:03:39 peter Exp $
*/
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libc_r/uthread/uthread_mattr_kind_np.c b/lib/libc_r/uthread/uthread_mattr_kind_np.c
index 5f5d1b3a992..073c30da4e9 100644
--- a/lib/libc_r/uthread/uthread_mattr_kind_np.c
+++ b/lib/libc_r/uthread/uthread_mattr_kind_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_mattr_kind_np.c,v 1.5 1999/11/25 07:01:38 d Exp $ */
/*
* Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_mattr_kind_np.c,v 1.4 1999/05/26 00:18:25 d Exp $
+ * $FreeBSD: uthread_mattr_kind_np.c,v 1.4 1999/08/28 00:03:39 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -68,7 +69,8 @@ pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
int ret;
if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
- return EINVAL;
+ errno = EINVAL;
+ ret = -1;
} else {
(*attr)->m_type = type;
ret = 0;
diff --git a/lib/libc_r/uthread/uthread_msync.c b/lib/libc_r/uthread/uthread_msync.c
index fb7d5a7e86e..3edde1a31d4 100644
--- a/lib/libc_r/uthread/uthread_msync.c
+++ b/lib/libc_r/uthread/uthread_msync.c
@@ -1,7 +1,7 @@
/*
* David Leonard <d@openbsd.org>, 1999. Public Domain.
*
- * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $
+ * $OpenBSD: uthread_msync.c,v 1.3 1999/11/25 07:01:38 d Exp $
*/
#include <sys/types.h>
@@ -18,13 +18,6 @@ msync(addr, len, flags)
{
int ret;
- /*
- * XXX This is quite pointless unless we know how to get the
- * file descriptor associated with the memory, and lock it for
- * write. The only real use of this wrapper is to guarantee
- * a cancellation point, as per the standard. sigh.
- */
-
/* This is a cancellation point: */
_thread_enter_cancellation_point();
diff --git a/lib/libc_r/uthread/uthread_multi_np.c b/lib/libc_r/uthread/uthread_multi_np.c
index 4da9793804c..88c6cbbfddf 100644
--- a/lib/libc_r/uthread/uthread_multi_np.c
+++ b/lib/libc_r/uthread/uthread_multi_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_multi_np.c,v 1.3 1999/11/25 07:01:38 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_multi_np.c,v 1.2 1999/01/06 05:29:24 d Exp $
+ * $FreeBSD: uthread_multi_np.c,v 1.3 1999/08/28 00:03:40 peter Exp $
*/
#include <string.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
index 8cb8760046c..1ddce4f6131 100644
--- a/lib/libc_r/uthread/uthread_mutex.c
+++ b/lib/libc_r/uthread/uthread_mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_mutex.c,v 1.8 1999/06/09 07:06:54 d Exp $ */
+/* $OpenBSD: uthread_mutex.c,v 1.9 1999/11/25 07:01:38 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_mutex.c,v 1.16 1999/08/28 00:03:40 peter Exp $
*/
#include <stdlib.h>
#include <errno.h>
@@ -40,6 +41,25 @@
#include <pthread.h>
#include "pthread_private.h"
+#if defined(_PTHREADS_INVARIANTS)
+#define _MUTEX_INIT_LINK(m) do { \
+ (m)->m_qe.tqe_prev = NULL; \
+ (m)->m_qe.tqe_next = NULL; \
+} while (0)
+#define _MUTEX_ASSERT_IS_OWNED(m) do { \
+ if ((m)->m_qe.tqe_prev == NULL) \
+ PANIC("mutex is not on list"); \
+} while (0)
+#define _MUTEX_ASSERT_NOT_OWNED(m) do { \
+ if (((m)->m_qe.tqe_prev != NULL) || \
+ ((m)->m_qe.tqe_next != NULL)) \
+ PANIC("mutex is on list"); \
+} while (0)
+#else
+#define _MUTEX_INIT_LINK(m)
+#define _MUTEX_ASSERT_IS_OWNED(m)
+#define _MUTEX_ASSERT_NOT_OWNED(m)
+#endif
/*
* Prototypes
@@ -56,6 +76,34 @@ static inline void mutex_queue_enq(pthread_mutex_t, pthread_t);
static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+/* Reinitialize a mutex to defaults. */
+int
+_mutex_reinit(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+ else if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else {
+ /*
+ * Initialize the mutex structure:
+ */
+ (*mutex)->m_type = PTHREAD_MUTEX_DEFAULT;
+ (*mutex)->m_protocol = PTHREAD_PRIO_NONE;
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_owner = NULL;
+ (*mutex)->m_data.m_count = 0;
+ (*mutex)->m_flags = MUTEX_FLAGS_INITED;
+ (*mutex)->m_refcount = 0;
+ (*mutex)->m_prio = 0;
+ (*mutex)->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(*mutex);
+ _SPINLOCK_INIT(&(*mutex)->lock);
+ }
+ return (ret);
+}
int
pthread_mutex_init(pthread_mutex_t * mutex,
@@ -139,7 +187,8 @@ pthread_mutex_init(pthread_mutex_t * mutex,
else
pmutex->m_prio = 0;
pmutex->m_saved_prio = 0;
- _SPINUNLOCK(&pmutex->lock);
+ _MUTEX_INIT_LINK(pmutex);
+ memset(&pmutex->lock, 0, sizeof(pmutex->lock));
*mutex = pmutex;
} else {
free(pmutex);
@@ -148,7 +197,7 @@ pthread_mutex_init(pthread_mutex_t * mutex,
}
}
/* Return the completion status: */
- return (ret);
+ return(ret);
}
int
@@ -178,6 +227,7 @@ pthread_mutex_destroy(pthread_mutex_t * mutex)
* Free the memory allocated for the mutex
* structure:
*/
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
free(*mutex);
/*
@@ -223,28 +273,24 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
*/
else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
/*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
* If the mutex was statically allocated, properly
* initialize the tail queue.
*/
if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
TAILQ_INIT(&(*mutex)->m_queue);
+ _MUTEX_INIT_LINK(*mutex);
(*mutex)->m_flags |= MUTEX_FLAGS_INITED;
}
- /*
- * Guard against being preempted by a scheduling signal.
- * To support priority inheritence mutexes, we need to
- * maintain lists of mutex ownerships for each thread as
- * well as lists of waiting threads for each mutex. In
- * order to propagate priorities we need to atomically
- * walk these lists and cannot rely on a single mutex
- * lock to provide protection against modification.
- */
- _thread_kern_sched_defer();
-
- /* Lock the mutex structure: */
- _SPINLOCK(&(*mutex)->lock);
-
/* Process according to mutex type: */
switch ((*mutex)->m_protocol) {
/* Default POSIX mutex: */
@@ -255,6 +301,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
(*mutex)->m_owner = _thread_run;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == _thread_run)
@@ -283,6 +330,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
_thread_run->inherited_priority;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == _thread_run)
@@ -318,6 +366,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
(*mutex)->m_prio;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == _thread_run)
@@ -338,10 +387,10 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
_SPINUNLOCK(&(*mutex)->lock);
/*
- * Renable preemption and yield if a scheduling signal
- * arrived while in the critical region:
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
@@ -362,28 +411,24 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
/*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
* If the mutex was statically allocated, properly
* initialize the tail queue.
*/
if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
TAILQ_INIT(&(*mutex)->m_queue);
(*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ _MUTEX_INIT_LINK(*mutex);
}
- /*
- * Guard against being preempted by a scheduling signal.
- * To support priority inheritence mutexes, we need to
- * maintain lists of mutex ownerships for each thread as
- * well as lists of waiting threads for each mutex. In
- * order to propagate priorities we need to atomically
- * walk these lists and cannot rely on a single mutex
- * lock to provide protection against modification.
- */
- _thread_kern_sched_defer();
-
- /* Lock the mutex structure: */
- _SPINLOCK(&(*mutex)->lock);
-
/* Process according to mutex type: */
switch ((*mutex)->m_protocol) {
/* Default POSIX mutex: */
@@ -393,6 +438,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
(*mutex)->m_owner = _thread_run;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
@@ -420,12 +466,6 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
/* Lock the mutex structure again: */
_SPINLOCK(&(*mutex)->lock);
-
- /*
- * This thread is no longer waiting for
- * the mutex:
- */
- _thread_run->data.mutex = NULL;
}
break;
@@ -450,6 +490,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
(*mutex)->m_prio;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
@@ -482,12 +523,6 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
/* Lock the mutex structure again: */
_SPINLOCK(&(*mutex)->lock);
-
- /*
- * This thread is no longer waiting for
- * the mutex:
- */
- _thread_run->data.mutex = NULL;
}
break;
@@ -520,6 +555,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
(*mutex)->m_prio;
/* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
TAILQ_INSERT_TAIL(&_thread_run->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == _thread_run)
@@ -557,12 +593,6 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
ret = _thread_run->error;
_thread_run->error = 0;
-
- /*
- * This thread is no longer waiting for
- * the mutex:
- */
- _thread_run->data.mutex = NULL;
}
break;
@@ -577,10 +607,10 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
_SPINUNLOCK(&(*mutex)->lock);
/*
- * Renable preemption and yield if a scheduling signal
- * arrived while in the critical region:
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
@@ -684,15 +714,10 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
ret = EINVAL;
} else {
/*
- * Guard against being preempted by a scheduling signal.
- * To support priority inheritence mutexes, we need to
- * maintain lists of mutex ownerships for each thread as
- * well as lists of waiting threads for each mutex. In
- * order to propagate priorities we need to atomically
- * walk these lists and cannot rely on a single mutex
- * lock to provide protection against modification.
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Lock the mutex structure: */
_SPINLOCK(&(*mutex)->lock);
@@ -707,8 +732,8 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
*/
if ((*mutex)->m_owner != _thread_run) {
/*
- * Return a permission error when the thread
- * doesn't own the lock:
+ * Return a permission error when the
+ * thread doesn't own the lock.
*/
ret = EPERM;
}
@@ -724,8 +749,10 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
(*mutex)->m_data.m_count = 0;
/* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
(*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
/*
* Get the next thread from the queue of
@@ -739,6 +766,19 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
*/
PTHREAD_NEW_STATE((*mutex)->m_owner,
PS_RUNNING);
+
+ /*
+ * Add the mutex to the threads list of
+ * owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
}
}
break;
@@ -751,8 +791,8 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
*/
if ((*mutex)->m_owner != _thread_run) {
/*
- * Return a permission error when the thread
- * doesn't own the lock:
+ * Return a permission error when the
+ * thread doesn't own the lock.
*/
ret = EPERM;
}
@@ -785,8 +825,10 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
_thread_run->priority_mutex_count--;
/* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
(*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
/*
* Get the next thread from the queue of threads
@@ -858,8 +900,8 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
*/
if ((*mutex)->m_owner != _thread_run) {
/*
- * Return a permission error when the thread
- * doesn't own the lock:
+ * Return a permission error when the
+ * thread doesn't own the lock.
*/
ret = EPERM;
}
@@ -892,8 +934,10 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
_thread_run->priority_mutex_count--;
/* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
- (*mutex), m_qe);
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
/*
* Enter a loop to find a waiting thread whose
@@ -914,6 +958,11 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
(*mutex)->m_owner->error = EINVAL;
PTHREAD_NEW_STATE((*mutex)->m_owner,
PS_RUNNING);
+ /*
+ * The thread is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
}
/* Check for a new owner: */
@@ -979,10 +1028,10 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
_SPINUNLOCK(&(*mutex)->lock);
/*
- * Renable preemption and yield if a scheduling signal
- * arrived while in the critical region:
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
/* Return the completion status: */
@@ -991,11 +1040,11 @@ mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
/*
- * This function is called when a change in base priority occurs
- * for a thread that is thread holding, or waiting for, a priority
- * protection or inheritence mutex. A change in a threads base
- * priority can effect changes to active priorities of other threads
- * and to the ordering of mutex locking by waiting threads.
+ * This function is called when a change in base priority occurs for
+ * a thread that is holding or waiting for a priority protection or
+ * inheritence mutex. A change in a threads base priority can effect
+ * changes to active priorities of other threads and to the ordering
+ * of mutex locking by waiting threads.
*
* This must be called while thread scheduling is deferred.
*/
@@ -1232,8 +1281,7 @@ mutex_rescan_owned (pthread_t pthread, pthread_mutex_t mutex)
* If this thread is in the priority queue, it must be
* removed and reinserted for its new priority.
*/
- if ((pthread != _thread_run) &&
- (pthread->state == PS_RUNNING)) {
+ if (pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) {
/*
* Remove the thread from the priority queue
* before changing its priority:
diff --git a/lib/libc_r/uthread/uthread_mutex_prioceiling.c b/lib/libc_r/uthread/uthread_mutex_prioceiling.c
index 779c238cfe7..afcd9372d47 100644
--- a/lib/libc_r/uthread/uthread_mutex_prioceiling.c
+++ b/lib/libc_r/uthread/uthread_mutex_prioceiling.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_mutex_prioceiling.c,v 1.1 1999/05/26 00:18:25 d Exp $ */
+/* $OpenBSD: uthread_mutex_prioceiling.c,v 1.2 1999/11/25 07:01:40 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_mutex_prioceiling.c,v 1.3 1999/08/28 00:03:40 peter Exp $
*/
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libc_r/uthread/uthread_mutex_protocol.c b/lib/libc_r/uthread/uthread_mutex_protocol.c
index fa0b9804d57..6b075ee4f2b 100644
--- a/lib/libc_r/uthread/uthread_mutex_protocol.c
+++ b/lib/libc_r/uthread/uthread_mutex_protocol.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_mutex_protocol.c,v 1.1 1999/05/26 00:18:25 d Exp $ */
+/* $OpenBSD: uthread_mutex_protocol.c,v 1.2 1999/11/25 07:01:40 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_mutex_protocol.c,v 1.3 1999/08/28 00:03:41 peter Exp $
*/
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libc_r/uthread/uthread_mutexattr_destroy.c b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
index fcb3863bcab..5749e43d35f 100644
--- a/lib/libc_r/uthread/uthread_mutexattr_destroy.c
+++ b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_mutexattr_destroy.c,v 1.3 1999/11/25 07:01:40 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_mutexattr_destroy.c,v 1.2 1999/01/06 05:29:25 d Exp $
+ * $FreeBSD: uthread_mutexattr_destroy.c,v 1.4 1999/08/28 00:03:41 peter Exp $
*/
#include <stdlib.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_nanosleep.c b/lib/libc_r/uthread/uthread_nanosleep.c
index 4e182adfb6c..583e94e983f 100644
--- a/lib/libc_r/uthread/uthread_nanosleep.c
+++ b/lib/libc_r/uthread/uthread_nanosleep.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_nanosleep.c,v 1.5 1999/11/25 07:01:40 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_nanosleep.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_nanosleep.c,v 1.10 1999/08/28 00:03:41 peter Exp $
*/
#include <stdio.h>
#include <errno.h>
@@ -42,9 +43,8 @@ nanosleep(const struct timespec * time_to_sleep,
struct timespec * time_remaining)
{
int ret = 0;
- struct timespec start_time;
- struct timespec wakeup_time;
struct timespec current_time;
+ struct timespec current_time1;
struct timespec remaining_time;
struct timeval tv;
@@ -52,20 +52,26 @@ nanosleep(const struct timespec * time_to_sleep,
_thread_enter_cancellation_point();
/* Check if the time to sleep is legal: */
- if (time_to_sleep == NULL || time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec > 1000000000 || time_to_sleep->tv_sec < 0) {
+ if (time_to_sleep == NULL || time_to_sleep->tv_sec < 0 ||
+ time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec >= 1000000000) {
/* Return an EINVAL error : */
errno = EINVAL;
ret = -1;
} else {
/* Get the current time: */
gettimeofday(&tv, NULL);
- TIMEVAL_TO_TIMESPEC(&tv, &start_time);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
/* Calculate the time for the current thread to wake up: */
- timespecadd(time_to_sleep, &start_time, &wakeup_time);
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
- _thread_run->wakeup_time.tv_sec = wakeup_time.tv_sec;
- _thread_run->wakeup_time.tv_nsec = wakeup_time.tv_nsec;
+ /* Check if the nanosecond field has overflowed: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
_thread_run->interrupted = 0;
/* Reschedule the current thread to sleep: */
@@ -73,15 +79,31 @@ nanosleep(const struct timespec * time_to_sleep,
/* Get the current time: */
gettimeofday(&tv, NULL);
- TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time1);
/* Calculate the remaining time to sleep: */
- timespecsub(&wakeup_time, &current_time, &remaining_time);
+ remaining_time.tv_sec = time_to_sleep->tv_sec + current_time.tv_sec - current_time1.tv_sec;
+ remaining_time.tv_nsec = time_to_sleep->tv_nsec + current_time.tv_nsec - current_time1.tv_nsec;
+
+ /* Check if the nanosecond field has underflowed: */
+ if (remaining_time.tv_nsec < 0) {
+ /* Handle the underflow: */
+ remaining_time.tv_sec -= 1;
+ remaining_time.tv_nsec += 1000000000;
+ }
+
+ /* Check if the nanosecond field has overflowed: */
+ if (remaining_time.tv_nsec >= 1000000000) {
+ /* Handle the overflow: */
+ remaining_time.tv_sec += 1;
+ remaining_time.tv_nsec -= 1000000000;
+ }
/* Check if the sleep was longer than the required time: */
if (remaining_time.tv_sec < 0) {
/* Reset the time left: */
- timespecclear(&remaining_time);
+ remaining_time.tv_sec = 0;
+ remaining_time.tv_nsec = 0;
}
/* Check if the time remaining is to be returned: */
diff --git a/lib/libc_r/uthread/uthread_once.c b/lib/libc_r/uthread/uthread_once.c
index 43ce7c39266..27b3a4d594e 100644
--- a/lib/libc_r/uthread/uthread_once.c
+++ b/lib/libc_r/uthread/uthread_once.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_once.c,v 1.3 1999/11/25 07:01:40 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_once.c,v 1.2 1999/01/06 05:29:25 d Exp $
+ * $FreeBSD: uthread_once.c,v 1.3 1999/08/28 00:03:42 peter Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
diff --git a/lib/libc_r/uthread/uthread_open.c b/lib/libc_r/uthread/uthread_open.c
index bfdcea73091..944e46cd109 100644
--- a/lib/libc_r/uthread/uthread_open.c
+++ b/lib/libc_r/uthread/uthread_open.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_open.c,v 1.5 1999/11/25 07:01:41 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_open.c,v 1.4 1998/04/29 09:59:07 jb Exp $
- * $OpenBSD: uthread_open.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_open.c,v 1.6 1999/08/28 00:03:42 peter Exp $
*
*/
#include <stdarg.h>
@@ -47,6 +47,7 @@ open(const char *path, int flags,...)
{
int fd;
int mode = 0;
+ int status;
va_list ap;
/* This is a cancellation point: */
diff --git a/lib/libc_r/uthread/uthread_pipe.c b/lib/libc_r/uthread/uthread_pipe.c
index 65610f01302..6288ab82cbc 100644
--- a/lib/libc_r/uthread/uthread_pipe.c
+++ b/lib/libc_r/uthread/uthread_pipe.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_pipe.c,v 1.3 1999/11/25 07:01:41 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_pipe.c,v 1.2 1999/01/06 05:29:25 d Exp $
+ * $FreeBSD: uthread_pipe.c,v 1.5 1999/08/28 00:03:42 peter Exp $
*/
#include <unistd.h>
#include <fcntl.h>
diff --git a/lib/libc_r/uthread/uthread_poll.c b/lib/libc_r/uthread/uthread_poll.c
index da3e98d1547..6392cfcb169 100644
--- a/lib/libc_r/uthread/uthread_poll.c
+++ b/lib/libc_r/uthread/uthread_poll.c
@@ -1,138 +1,97 @@
+/* $OpenBSD: uthread_poll.c,v 1.3 1999/11/25 07:01:41 d Exp $ */
/*
- * David Leonard <d@openbsd.org>, 1999. Public Domain.
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>
+ * All rights reserved.
*
- * $OpenBSD: uthread_poll.c,v 1.2 1999/01/08 05:09:22 d Exp $
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: uthread_poll.c,v 1.4 1999/08/30 00:02:08 deischen Exp $
*/
#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <poll.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <poll.h>
-#include <stdlib.h>
+#include <sys/fcntl.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
-static void
-poll_helper(nfds, fds, data)
- int nfds;
- struct pollfd *fds;
- struct pthread_select_data *data;
-{
- int maxfd;
- int i;
- int event;
- int fd;
-
- FD_ZERO(&data->readfds);
- FD_ZERO(&data->writefds);
- FD_ZERO(&data->exceptfds);
-
- maxfd = -1;
- for (i = 0; i < nfds; i++) {
- event = fds[i].events;
- fd = fds[i].fd;
-
- if (event & POLLIN)
- FD_SET(fd, &data->readfds);
- if (event & POLLOUT)
- FD_SET(fd, &data->writefds);
- if (fd > maxfd)
- maxfd = fd;
- }
- data->nfds = maxfd + 1;
-}
-int
-poll(fds, nfds, timeout)
- struct pollfd fds[];
- int nfds;
- int timeout;
+int
+poll(struct pollfd fds[], int nfds, int timeout)
{
- fd_set rfds, wfds, rwfds;
- int i;
- struct timespec ts;
- int fd, event;
- struct pthread_select_data data;
- struct timeval zero_timeout = { 0, 0 };
- int ret;
+ struct timespec ts;
+ int numfds = nfds;
+ int i, ret = 0, found = 0;
+ struct pthread_poll_data data;
- if (timeout < 0) {
- /* Wait forever: */
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout == -1) {
+ /* Wait for ever: */
_thread_kern_set_timeout(NULL);
- } else {
+ } else if (timeout > 0) {
+ /* Convert the timeout in msec to a timespec: */
ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000000L;
+ ts.tv_nsec = (timeout % 1000) * 1000;
+
+ /* Set the wake up time: */
_thread_kern_set_timeout(&ts);
+ } else if (timeout < 0) {
+ /* a timeout less than zero but not == -1 is invalid */
+ errno = EINVAL;
+ return (-1);
}
- /* Obtain locks needed: */
- ret = 0;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&rwfds);
- for (i = 0; i < nfds; i++) {
- event = fds[i].events;
- fd = fds[i].fd;
-
- if (event & (POLLIN|POLLOUT))
- if (!FD_ISSET(fd, &rwfds) && !FD_ISSET(fd, &rfds) &&
- !FD_ISSET(fd, &wfds)) {
- if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) != 0)
- break;
- FD_SET(fd, &rwfds);
- continue;
- }
-
- if (event & POLLIN)
- if (!FD_ISSET(fd, &rwfds) && !FD_ISSET(fd, &rfds)) {
- if ((ret = _FD_LOCK(fd, FD_READ, NULL)) != 0)
- break;
- FD_SET(fd, &rfds);
- }
-
- if (event & POLLOUT)
- if (!FD_ISSET(fd, &rwfds) && !FD_ISSET(fd, &wfds)) {
- if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) != 0)
- break;
- FD_SET(fd, &wfds);
- }
- }
+ if (((ret = _thread_sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
+ data.nfds = numfds;
+ data.fds = fds;
- if (ret == 0) {
- poll_helper(nfds, fds, &data);
- ret = _thread_sys_select(data.nfds, &data.readfds,
- &data.writefds, NULL, &zero_timeout);
- if (ret == 0) {
- poll_helper(nfds, fds, &data);
- _thread_run->data.select_data = &data;
- _thread_run->interrupted = 0;
- _thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
- if (_thread_run->interrupted) {
- errno = EINTR;
- ret = -1;
- }
+ /*
+ * Clear revents in case of a timeout which leaves fds
+ * unchanged:
+ */
+ for (i = 0; i < numfds; i++) {
+ fds[i].revents = 0;
}
- if (ret >= 0)
- ret = _thread_sys_poll(fds, nfds, 0);
- }
-
- /* Clean up the locks: */
- for (i = 0; i < nfds; i++) {
- fd = fds[i].fd;
- if (FD_ISSET(fd, &rwfds)) {
- _FD_UNLOCK(fd, FD_RDWR);
- FD_CLR(fd, &rwfds);
- }
- if (FD_ISSET(fd, &rfds)) {
- _FD_UNLOCK(fd, FD_READ);
- FD_CLR(fd, &rfds);
- }
- if (FD_ISSET(fd, &wfds)) {
- _FD_UNLOCK(fd, FD_WRITE);
- FD_CLR(fd, &wfds);
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ } else {
+ ret = data.nfds;
}
}
diff --git a/lib/libc_r/uthread/uthread_priority_queue.c b/lib/libc_r/uthread/uthread_priority_queue.c
index a5f45ef7064..eef7ed65379 100644
--- a/lib/libc_r/uthread/uthread_priority_queue.c
+++ b/lib/libc_r/uthread/uthread_priority_queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_priority_queue.c,v 1.1 1999/05/26 00:18:25 d Exp $ */
+/* $OpenBSD: uthread_priority_queue.c,v 1.2 1999/11/25 07:01:41 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_priority_queue.c,v 1.3 1999/08/28 00:03:43 peter Exp $
*/
#include <stdlib.h>
#include <sys/queue.h>
@@ -41,9 +42,51 @@
/* Prototypes: */
static void pq_insert_prio_list(pq_queue_t *pq, int prio);
+#if defined(_PTHREADS_INVARIANTS)
+
+static int _pq_active = 0;
+
+#define _PQ_IN_SCHEDQ (PTHREAD_FLAGS_IN_PRIOQ | PTHREAD_FLAGS_IN_WAITQ | PTHREAD_FLAGS_IN_WORKQ)
+
+#define _PQ_SET_ACTIVE() _pq_active = 1
+#define _PQ_CLEAR_ACTIVE() _pq_active = 0
+#define _PQ_ASSERT_ACTIVE(msg) do { \
+ if (_pq_active == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_INACTIVE(msg) do { \
+ if (_pq_active != 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_WAITQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \
+ if ((thrd)->flags & _PQ_IN_SCHEDQ) \
+ PANIC(msg); \
+} while (0)
+
+#else
+
+#define _PQ_SET_ACTIVE()
+#define _PQ_CLEAR_ACTIVE()
+#define _PQ_ASSERT_ACTIVE(msg)
+#define _PQ_ASSERT_INACTIVE(msg)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg)
+#define _PQ_CHECK_PRIO()
+
+#endif
+
int
-_pq_init(pq_queue_t *pq, int minprio, int maxprio)
+_pq_alloc(pq_queue_t *pq, int minprio, int maxprio)
{
int i, ret = 0;
int prioslots = maxprio - minprio + 1;
@@ -57,8 +100,26 @@ _pq_init(pq_queue_t *pq, int minprio, int maxprio)
ret = -1;
else {
+ /* Remember the queue size: */
+ pq->pq_size = prioslots;
+
+ ret = _pq_init(pq);
+
+ }
+ return (ret);
+}
+
+int
+_pq_init(pq_queue_t *pq)
+{
+ int i, ret = 0;
+
+ if ((pq == NULL) || (pq->pq_lists == NULL))
+ ret = -1;
+
+ else {
/* Initialize the queue for each priority slot: */
- for (i = 0; i < prioslots; i++) {
+ for (i = 0; i < pq->pq_size; i++) {
TAILQ_INIT(&pq->pq_lists[i].pl_head);
pq->pq_lists[i].pl_prio = i;
pq->pq_lists[i].pl_queued = 0;
@@ -66,9 +127,7 @@ _pq_init(pq_queue_t *pq, int minprio, int maxprio)
/* Initialize the priority queue: */
TAILQ_INIT(&pq->pq_queue);
-
- /* Remember the queue size: */
- pq->pq_size = prioslots;
+ _PQ_CLEAR_ACTIVE();
}
return (ret);
}
@@ -78,7 +137,27 @@ _pq_remove(pq_queue_t *pq, pthread_t pthread)
{
int prio = pthread->active_priority;
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_PRIOQ(pthread, "_pq_remove: Not in priority queue");
+
+ /*
+ * Remove this thread from priority list. Note that if
+ * the priority list becomes empty, it is not removed
+ * from the priority queue because another thread may be
+ * added to the priority list (resulting in a needless
+ * removal/insertion). Priority lists are only removed
+ * from the priority queue when _pq_first is called.
+ */
TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe);
+
+ /* This thread is now longer in the priority queue. */
+ pthread->flags &= ~PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
}
@@ -87,10 +166,23 @@ _pq_insert_head(pq_queue_t *pq, pthread_t pthread)
{
int prio = pthread->active_priority;
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_head: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_head: Already in priority queue");
+
TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe);
if (pq->pq_lists[prio].pl_queued == 0)
/* Insert the list into the priority queue: */
pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
}
@@ -99,10 +191,23 @@ _pq_insert_tail(pq_queue_t *pq, pthread_t pthread)
{
int prio = pthread->active_priority;
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_tail: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_tail: Already in priority queue");
+
TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe);
if (pq->pq_lists[prio].pl_queued == 0)
/* Insert the list into the priority queue: */
pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
}
@@ -112,6 +217,12 @@ _pq_first(pq_queue_t *pq)
pq_list_t *pql;
pthread_t pthread = NULL;
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_first: pq_active");
+ _PQ_SET_ACTIVE();
+
while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) &&
(pthread == NULL)) {
if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) {
@@ -125,6 +236,8 @@ _pq_first(pq_queue_t *pq)
pql->pl_queued = 0;
}
}
+
+ _PQ_CLEAR_ACTIVE();
return (pthread);
}
@@ -135,9 +248,14 @@ pq_insert_prio_list(pq_queue_t *pq, int prio)
pq_list_t *pql;
/*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_ACTIVE("pq_insert_prio_list: pq_active");
+
+ /*
* The priority queue is in descending priority order. Start at
* the beginning of the queue and find the list before which the
- * new list should to be inserted.
+ * new list should be inserted.
*/
pql = TAILQ_FIRST(&pq->pq_queue);
while ((pql != NULL) && (pql->pl_prio > prio))
@@ -153,4 +271,66 @@ pq_insert_prio_list(pq_queue_t *pq, int prio)
pq->pq_lists[prio].pl_queued = 1;
}
+#if defined(_PTHREADS_INVARIANTS)
+void
+_waitq_insert(pthread_t pthread)
+{
+ pthread_t tid;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_insert: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread, "_waitq_insert: Already in queue");
+
+ if (pthread->wakeup_time.tv_sec == -1)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else {
+ tid = TAILQ_FIRST(&_waitingq);
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) &&
+ ((tid->wakeup_time.tv_sec < pthread->wakeup_time.tv_sec) ||
+ ((tid->wakeup_time.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (tid->wakeup_time.tv_nsec <= pthread->wakeup_time.tv_nsec))))
+ tid = TAILQ_NEXT(tid, pqe);
+ if (tid == NULL)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else
+ TAILQ_INSERT_BEFORE(tid, pthread, pqe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_remove(pthread_t pthread)
+{
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_WAITQ(pthread, "_waitq_remove: Not in queue");
+
+ TAILQ_REMOVE(&_waitingq, pthread, pqe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_setactive(void)
+{
+ _PQ_ASSERT_INACTIVE("_waitq_setactive: pq_active");
+ _PQ_SET_ACTIVE();
+}
+
+void
+_waitq_clearactive(void)
+{
+ _PQ_ASSERT_ACTIVE("_waitq_clearactive: ! pq_active");
+ _PQ_CLEAR_ACTIVE();
+}
+#endif
#endif
diff --git a/lib/libc_r/uthread/uthread_queue.c b/lib/libc_r/uthread/uthread_queue.c
deleted file mode 100644
index b30b5b9d425..00000000000
--- a/lib/libc_r/uthread/uthread_queue.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $OpenBSD: uthread_queue.c,v 1.2 1999/01/06 05:29:25 d Exp $
- */
-#include <stdio.h>
-#ifdef _THREAD_SAFE
-#include <pthread.h>
-#include "pthread_private.h"
-
-void
-_thread_queue_init(struct pthread_queue * queue)
-{
- /* Initialise the pointers in the queue structure: */
- queue->q_next = NULL;
- queue->q_last = NULL;
- queue->q_data = NULL;
- return;
-}
-
-void
-_thread_queue_enq(struct pthread_queue * queue, struct pthread * thread)
-{
- if (queue->q_last) {
- queue->q_last->qnxt = thread;
- } else {
- queue->q_next = thread;
- }
- queue->q_last = thread;
- thread->queue = queue;
- thread->qnxt = NULL;
- return;
-}
-
-struct pthread *
-_thread_queue_get(struct pthread_queue * queue)
-{
- /* Return the pointer to the next thread in the queue: */
- return (queue->q_next);
-}
-
-struct pthread *
-_thread_queue_deq(struct pthread_queue * queue)
-{
- struct pthread *thread = NULL;
-
- if (queue->q_next) {
- thread = queue->q_next;
- if (!(queue->q_next = queue->q_next->qnxt)) {
- queue->q_last = NULL;
- }
- thread->queue = NULL;
- thread->qnxt = NULL;
- }
- return (thread);
-}
-
-int
-_thread_queue_remove(struct pthread_queue * queue, struct pthread * thread)
-{
- struct pthread **current = &(queue->q_next);
- struct pthread *prev = NULL;
- int ret = -1;
-
- while (*current) {
- if (*current == thread) {
- if ((*current)->qnxt) {
- *current = (*current)->qnxt;
- } else {
- queue->q_last = prev;
- *current = NULL;
- }
- ret = 0;
- break;
- }
- prev = *current;
- current = &((*current)->qnxt);
- }
- thread->queue = NULL;
- thread->qnxt = NULL;
- return (ret);
-}
-
-int
-pthread_llist_remove(struct pthread ** llist, struct pthread * thread)
-{
- while (*llist) {
- if (*llist == thread) {
- *llist = thread->qnxt;
- return (0);
- }
- llist = &(*llist)->qnxt;
- }
- return (-1);
-}
-
-#endif
diff --git a/lib/libc_r/uthread/uthread_read.c b/lib/libc_r/uthread/uthread_read.c
index 6b9c96352d0..08c12241ed7 100644
--- a/lib/libc_r/uthread/uthread_read.c
+++ b/lib/libc_r/uthread/uthread_read.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_read.c,v 1.5 1999/11/25 07:01:41 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_read.c,v 1.6 1998/06/10 22:28:43 jb Exp $
- * $OpenBSD: uthread_read.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_read.c,v 1.8 1999/08/28 00:03:43 peter Exp $
*
*/
#include <sys/types.h>
@@ -52,14 +52,11 @@ read(int fd, void *buf, size_t nbytes)
_thread_enter_cancellation_point();
/* POSIX says to do just this: */
- if (nbytes == 0) {
- /* No longer in a cancellation point: */
- _thread_leave_cancellation_point();
- return (0);
- }
+ if (nbytes == 0)
+ ret = 0;
/* Lock the file descriptor for read: */
- if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ else if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
/* Get the read/write mode type: */
type = _thread_fd_table[fd]->flags & O_ACCMODE;
@@ -67,14 +64,11 @@ read(int fd, void *buf, size_t nbytes)
if (type != O_RDONLY && type != O_RDWR) {
/* File is not open for read: */
errno = EBADF;
- _FD_UNLOCK(fd, FD_READ);
- /* No longer in a cancellation point: */
- _thread_leave_cancellation_point();
- return (-1);
+ ret = -1;
}
/* Perform a non-blocking read syscall: */
- while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
+ else while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
(errno == EWOULDBLOCK || errno == EAGAIN)) {
_thread_run->data.fd.fd = fd;
@@ -101,8 +95,10 @@ read(int fd, void *buf, size_t nbytes)
}
_FD_UNLOCK(fd, FD_READ);
}
+
/* No longer in a cancellation point: */
_thread_leave_cancellation_point();
+
return (ret);
}
#endif
diff --git a/lib/libc_r/uthread/uthread_readv.c b/lib/libc_r/uthread/uthread_readv.c
index 293adfe0e53..1ef0ac51ba1 100644
--- a/lib/libc_r/uthread/uthread_readv.c
+++ b/lib/libc_r/uthread/uthread_readv.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_readv.c,v 1.3 1999/11/25 07:01:42 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_readv.c,v 1.6 1998/06/10 22:28:44 jb Exp $
- * $OpenBSD: uthread_readv.c,v 1.2 1998/12/23 22:49:46 d Exp $
+ * $FreeBSD: uthread_readv.c,v 1.8 1999/08/28 00:03:43 peter Exp $
*
*/
#include <sys/types.h>
diff --git a/lib/libc_r/uthread/uthread_recvfrom.c b/lib/libc_r/uthread/uthread_recvfrom.c
index e259eb62138..18c0c6ce8ed 100644
--- a/lib/libc_r/uthread/uthread_recvfrom.c
+++ b/lib/libc_r/uthread/uthread_recvfrom.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_recvfrom.c,v 1.4 1999/11/25 07:01:42 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_recvfrom.c,v 1.3 1999/02/16 16:40:00 deraadt Exp $
+ * $FreeBSD: uthread_recvfrom.c,v 1.5 1999/08/28 00:03:44 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
@@ -40,8 +41,7 @@
#include "pthread_private.h"
ssize_t
-recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr * from,
- socklen_t *from_len)
+recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr * from, socklen_t *from_len)
{
int ret;
diff --git a/lib/libc_r/uthread/uthread_recvmsg.c b/lib/libc_r/uthread/uthread_recvmsg.c
index 0b99b11c78d..c92b7a1c420 100644
--- a/lib/libc_r/uthread/uthread_recvmsg.c
+++ b/lib/libc_r/uthread/uthread_recvmsg.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_recvmsg.c,v 1.3 1999/11/25 07:01:42 d Exp $ */
/*
* Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_recvmsg.c,v 1.2 1999/01/06 05:29:25 d Exp $
+ * $FreeBSD: uthread_recvmsg.c,v 1.4 1999/08/28 00:03:44 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
diff --git a/lib/libc_r/uthread/uthread_resume_np.c b/lib/libc_r/uthread/uthread_resume_np.c
index e4be286bde6..8816f76e4c8 100644
--- a/lib/libc_r/uthread/uthread_resume_np.c
+++ b/lib/libc_r/uthread/uthread_resume_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_resume_np.c,v 1.4 1999/11/25 07:01:42 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_resume_np.c,v 1.3 1999/05/26 00:18:25 d Exp $
+ * $FreeBSD: uthread_resume_np.c,v 1.7 1999/08/28 00:03:44 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -47,20 +48,19 @@ pthread_resume_np(pthread_t thread)
/* The thread exists. Is it suspended? */
if (thread->state != PS_SUSPENDED) {
/*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Allow the thread to run. */
PTHREAD_NEW_STATE(thread,PS_RUNNING);
/*
- * Reenable preemption and yield if a scheduling
- * signal occurred while in the critical region.
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
}
return(ret);
diff --git a/lib/libc_r/uthread/uthread_rwlock.c b/lib/libc_r/uthread/uthread_rwlock.c
index e9ca20b00fa..259f1898402 100644
--- a/lib/libc_r/uthread/uthread_rwlock.c
+++ b/lib/libc_r/uthread/uthread_rwlock.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_rwlock.c,v 1.3 1999/11/25 07:01:42 d Exp $ */
/*-
* Copyright (c) 1998 Alex Nash
* All rights reserved.
@@ -23,8 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_rwlock.c,v 1.3 1998/09/07 21:07:59 alex Exp $
- * $OpenBSD: uthread_rwlock.c,v 1.2 1998/12/23 22:49:46 d Exp $
+ * $FreeBSD: uthread_rwlock.c,v 1.4 1999/08/28 00:03:45 peter Exp $
*/
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_rwlockattr.c b/lib/libc_r/uthread/uthread_rwlockattr.c
index 41a9d89333c..8e7f7a5e1d0 100644
--- a/lib/libc_r/uthread/uthread_rwlockattr.c
+++ b/lib/libc_r/uthread/uthread_rwlockattr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_rwlockattr.c,v 1.3 1999/11/25 07:01:42 d Exp $ */
/*-
* Copyright (c) 1998 Alex Nash
* All rights reserved.
@@ -23,8 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_rwlockattr.c,v 1.2 1998/09/07 19:23:55 alex Exp $
- * $OpenBSD: uthread_rwlockattr.c,v 1.2 1998/12/23 22:49:46 d Exp $
+ * $FreeBSD: uthread_rwlockattr.c,v 1.3 1999/08/28 00:03:45 peter Exp $
*/
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_select.c b/lib/libc_r/uthread/uthread_select.c
index dd9714e7b3e..a7cd5c3d260 100644
--- a/lib/libc_r/uthread/uthread_select.c
+++ b/lib/libc_r/uthread/uthread_select.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_select.c,v 1.4 1999/11/25 07:01:42 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,13 +30,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_select.c,v 1.3 1999/05/26 00:18:25 d Exp $
+ * $FreeBSD: uthread_select.c,v 1.13 1999/08/30 00:02:08 deischen Exp $
*/
#include <unistd.h>
#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
#include <string.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
+#include <sys/fcntl.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
@@ -44,18 +49,22 @@ int
select(int numfds, fd_set * readfds, fd_set * writefds,
fd_set * exceptfds, struct timeval * timeout)
{
- fd_set read_locks, write_locks, rdwr_locks;
struct timespec ts;
- struct timeval zero_timeout = {0, 0};
- int i, ret = 0, got_all_locks = 1;
- int f_wait = 1;
- struct pthread_select_data data;
+ int i, ret = 0, f_wait = 1;
+ int pfd_index, got_one = 0, fd_count = 0;
+ struct pthread_poll_data data;
if (numfds > _thread_dtablesize) {
numfds = _thread_dtablesize;
}
/* Check if a timeout was specified: */
if (timeout) {
+ if (timeout->tv_sec < 0 ||
+ timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
/* Convert the timeval to a timespec: */
TIMEVAL_TO_TIMESPEC(timeout, &ts);
@@ -68,112 +77,129 @@ select(int numfds, fd_set * readfds, fd_set * writefds,
_thread_kern_set_timeout(NULL);
}
- FD_ZERO(&read_locks);
- FD_ZERO(&write_locks);
- FD_ZERO(&rdwr_locks);
-
- /* lock readfds */
+ /* Count the number of file descriptors to be polled: */
if (readfds || writefds || exceptfds) {
for (i = 0; i < numfds; i++) {
- if ((readfds && (FD_ISSET(i, readfds))) || (exceptfds && FD_ISSET(i, exceptfds))) {
- if (writefds && FD_ISSET(i, writefds)) {
- if ((ret = _FD_LOCK(i, FD_RDWR, NULL)) != 0) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &rdwr_locks);
- } else {
- if ((ret = _FD_LOCK(i, FD_READ, NULL)) != 0) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &read_locks);
- }
- } else {
- if (writefds && FD_ISSET(i, writefds)) {
- if ((ret = _FD_LOCK(i, FD_WRITE, NULL)) != 0) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &write_locks);
- }
+ if ((readfds && FD_ISSET(i, readfds)) ||
+ (exceptfds && FD_ISSET(i, exceptfds)) ||
+ (writefds && FD_ISSET(i, writefds))) {
+ fd_count++;
}
}
}
- if (got_all_locks) {
- data.nfds = numfds;
- FD_ZERO(&data.readfds);
- FD_ZERO(&data.writefds);
- FD_ZERO(&data.exceptfds);
- if (readfds != NULL) {
- memcpy(&data.readfds, readfds, sizeof(data.readfds));
- }
- if (writefds != NULL) {
- memcpy(&data.writefds, writefds, sizeof(data.writefds));
+
+ /*
+ * Allocate memory for poll data if it hasn't already been
+ * allocated or if previously allocated memory is insufficient.
+ */
+ if ((_thread_run->poll_data.fds == NULL) ||
+ (_thread_run->poll_data.nfds < fd_count)) {
+ data.fds = (struct pollfd *) realloc(_thread_run->poll_data.fds,
+ sizeof(struct pollfd) * MAX(128, fd_count));
+ if (data.fds == NULL) {
+ errno = ENOMEM;
+ ret = -1;
}
- if (exceptfds != NULL) {
- memcpy(&data.exceptfds, exceptfds, sizeof(data.exceptfds));
+ else {
+ /*
+ * Note that the threads poll data always
+ * indicates what is allocated, not what is
+ * currently being polled.
+ */
+ _thread_run->poll_data.fds = data.fds;
+ _thread_run->poll_data.nfds = MAX(128, fd_count);
}
- if ((ret = _thread_sys_select(data.nfds, &data.readfds, &data.writefds, &data.exceptfds, &zero_timeout)) == 0 && f_wait) {
- data.nfds = numfds;
- FD_ZERO(&data.readfds);
- FD_ZERO(&data.writefds);
- FD_ZERO(&data.exceptfds);
- if (readfds != NULL) {
- memcpy(&data.readfds, readfds, sizeof(data.readfds));
+ }
+ if (ret == 0) {
+ /* Setup the wait data. */
+ data.fds = _thread_run->poll_data.fds;
+ data.nfds = fd_count;
+
+ /*
+ * Setup the array of pollfds. Optimize this by
+ * running the loop in reverse and stopping when
+ * the number of selected file descriptors is reached.
+ */
+ for (i = numfds - 1, pfd_index = fd_count - 1;
+ (i >= 0) && (pfd_index >= 0); i--) {
+ data.fds[pfd_index].events = 0;
+ if (readfds && FD_ISSET(i, readfds)) {
+ data.fds[pfd_index].events = POLLRDNORM;
}
- if (writefds != NULL) {
- memcpy(&data.writefds, writefds, sizeof(data.writefds));
+ if (exceptfds && FD_ISSET(i, exceptfds)) {
+ data.fds[pfd_index].events |= POLLRDBAND;
}
- if (exceptfds != NULL) {
- memcpy(&data.exceptfds, exceptfds, sizeof(data.exceptfds));
+ if (writefds && FD_ISSET(i, writefds)) {
+ data.fds[pfd_index].events |= POLLWRNORM;
+ }
+ if (data.fds[pfd_index].events != 0) {
+ /*
+ * Set the file descriptor to be polled and
+ * clear revents in case of a timeout which
+ * leaves fds unchanged:
+ */
+ data.fds[pfd_index].fd = i;
+ data.fds[pfd_index].revents = 0;
+ pfd_index--;
}
- _thread_run->data.select_data = &data;
+ }
+ if (((ret = _thread_sys_poll(data.fds, data.nfds, 0)) == 0) &&
+ (f_wait != 0)) {
+ _thread_run->data.poll_data = &data;
_thread_run->interrupted = 0;
_thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
if (_thread_run->interrupted) {
errno = EINTR;
+ data.nfds = 0;
ret = -1;
} else
ret = data.nfds;
}
}
- /* clean up the locks */
- for (i = 0; i < numfds; i++)
- if (FD_ISSET(i, &read_locks))
- _FD_UNLOCK(i, FD_READ);
- for (i = 0; i < numfds; i++)
- if (FD_ISSET(i, &rdwr_locks))
- _FD_UNLOCK(i, FD_RDWR);
- for (i = 0; i < numfds; i++)
- if (FD_ISSET(i, &write_locks))
- _FD_UNLOCK(i, FD_WRITE);
if (ret >= 0) {
- if (readfds != NULL) {
- for (i = 0; i < numfds; i++) {
- if (FD_ISSET(i, readfds) &&
- !FD_ISSET(i, &data.readfds)) {
- FD_CLR(i, readfds);
+ numfds = 0;
+ for (i = 0; i < fd_count; i++) {
+ /*
+ * Check the results of the poll and clear
+ * this file descriptor from the fdset if
+ * the requested event wasn't ready.
+ */
+ got_one = 0;
+ if (readfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, readfds)) {
+ if (data.fds[i].revents & (POLLIN |
+ POLLRDNORM))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd, readfds);
}
}
- }
- if (writefds != NULL) {
- for (i = 0; i < numfds; i++) {
- if (FD_ISSET(i, writefds) &&
- !FD_ISSET(i, &data.writefds)) {
- FD_CLR(i, writefds);
+ if (writefds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, writefds)) {
+ if (data.fds[i].revents & (POLLOUT |
+ POLLWRNORM | POLLWRBAND))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ writefds);
}
}
- }
- if (exceptfds != NULL) {
- for (i = 0; i < numfds; i++) {
- if (FD_ISSET(i, exceptfds) &&
- !FD_ISSET(i, &data.exceptfds)) {
- FD_CLR(i, exceptfds);
+ if (exceptfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, exceptfds)) {
+ if (data.fds[i].revents & (POLLRDBAND |
+ POLLPRI | POLLHUP | POLLERR |
+ POLLNVAL))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ exceptfds);
}
}
+ if (got_one)
+ numfds++;
}
+ ret = numfds;
}
return (ret);
diff --git a/lib/libc_r/uthread/uthread_self.c b/lib/libc_r/uthread/uthread_self.c
index d9a5b26092b..0ff4f7f3ba6 100644
--- a/lib/libc_r/uthread/uthread_self.c
+++ b/lib/libc_r/uthread/uthread_self.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_self.c,v 1.3 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_self.c,v 1.2 1999/01/10 23:10:26 d Exp $
+ * $FreeBSD: uthread_self.c,v 1.3 1999/08/28 00:03:46 peter Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
diff --git a/lib/libc_r/uthread/uthread_sendmsg.c b/lib/libc_r/uthread/uthread_sendmsg.c
index db1b49d2016..36bc6a62439 100644
--- a/lib/libc_r/uthread/uthread_sendmsg.c
+++ b/lib/libc_r/uthread/uthread_sendmsg.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sendmsg.c,v 1.3 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sendmsg.c,v 1.2 1999/01/06 05:29:26 d Exp $
+ * $FreeBSD: uthread_sendmsg.c,v 1.4 1999/08/28 00:03:46 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
diff --git a/lib/libc_r/uthread/uthread_sendto.c b/lib/libc_r/uthread/uthread_sendto.c
index 8eacbd509d9..b0a8c059a1e 100644
--- a/lib/libc_r/uthread/uthread_sendto.c
+++ b/lib/libc_r/uthread/uthread_sendto.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sendto.c,v 1.4 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sendto.c,v 1.3 1999/02/16 16:41:13 millert Exp $
+ * $FreeBSD: uthread_sendto.c,v 1.5 1999/08/28 00:03:46 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
@@ -40,7 +41,7 @@
#include "pthread_private.h"
ssize_t
-sendto(int fd, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t to_len)
+sendto(int fd, const void *msg, size_t len, int flags, const struct sockaddr * to, socklen_t to_len)
{
int ret;
diff --git a/lib/libc_r/uthread/uthread_seterrno.c b/lib/libc_r/uthread/uthread_seterrno.c
index e63e9ba8d4d..41425e5b134 100644
--- a/lib/libc_r/uthread/uthread_seterrno.c
+++ b/lib/libc_r/uthread/uthread_seterrno.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_seterrno.c,v 1.3 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_seterrno.c,v 1.2 1999/01/06 05:29:26 d Exp $
+ * $FreeBSD: uthread_seterrno.c,v 1.4 1999/08/28 00:03:46 peter Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
diff --git a/lib/libc_r/uthread/uthread_setprio.c b/lib/libc_r/uthread/uthread_setprio.c
index 575eb62da2c..b0be80a20ad 100644
--- a/lib/libc_r/uthread/uthread_setprio.c
+++ b/lib/libc_r/uthread/uthread_setprio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_setprio.c,v 1.4 1999/05/26 00:18:25 d Exp $ */
+/* $OpenBSD: uthread_setprio.c,v 1.5 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_setprio.c,v 1.6 1999/08/28 00:03:47 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_setschedparam.c b/lib/libc_r/uthread/uthread_setschedparam.c
index 0024460c003..26e1b61d017 100644
--- a/lib/libc_r/uthread/uthread_setschedparam.c
+++ b/lib/libc_r/uthread/uthread_setschedparam.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_setschedparam.c,v 1.1 1999/05/26 00:18:25 d Exp $ */
+/* $OpenBSD: uthread_setschedparam.c,v 1.2 1999/11/25 07:01:43 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_setschedparam.c,v 1.3 1999/08/28 00:03:47 peter Exp $
*/
#include <errno.h>
#include <sys/param.h>
@@ -51,10 +52,10 @@ pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *p
/* Find the thread in the list of active threads: */
else if ((ret = _find_thread(pthread)) == 0) {
/*
- * Guard against being preempted by a scheduling
- * signal:
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
if (param->sched_priority != pthread->base_priority) {
/*
@@ -62,8 +63,7 @@ pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *p
* queue before any adjustments are made to its
* active priority:
*/
- if ((pthread != _thread_run) &&
- (pthread->state == PS_RUNNING)) {
+ if ((pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) != 0) {
in_readyq = 1;
old_prio = pthread->active_priority;
PTHREAD_PRIOQ_REMOVE(pthread);
@@ -104,10 +104,10 @@ pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *p
pthread->attr.sched_policy = policy;
/*
- * Renable preemption and yield if a scheduling signal
- * arrived while in the critical region:
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
return(ret);
}
diff --git a/lib/libc_r/uthread/uthread_setsockopt.c b/lib/libc_r/uthread/uthread_setsockopt.c
index 67be1fe195d..77cda0a65c1 100644
--- a/lib/libc_r/uthread/uthread_setsockopt.c
+++ b/lib/libc_r/uthread/uthread_setsockopt.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_setsockopt.c,v 1.4 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_setsockopt.c,v 1.3 1999/02/16 16:40:01 deraadt Exp $
+ * $FreeBSD: uthread_setsockopt.c,v 1.5 1999/08/28 00:03:47 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_shutdown.c b/lib/libc_r/uthread/uthread_shutdown.c
index 4923d34cec4..991fb2c932d 100644
--- a/lib/libc_r/uthread/uthread_shutdown.c
+++ b/lib/libc_r/uthread/uthread_shutdown.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_shutdown.c,v 1.3 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_shutdown.c,v 1.2 1999/01/06 05:29:27 d Exp $
+ * $FreeBSD: uthread_shutdown.c,v 1.6 1999/08/28 00:03:48 peter Exp $
*/
#include <errno.h>
#include <sys/types.h>
diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c
index 1d32d376fe0..465d5d06e99 100644
--- a/lib/libc_r/uthread/uthread_sig.c
+++ b/lib/libc_r/uthread/uthread_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_sig.c,v 1.5 1999/05/26 00:18:26 d Exp $ */
+/* $OpenBSD: uthread_sig.c,v 1.6 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -21,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_sig.c,v 1.20 1999/09/29 15:18:39 marcel Exp $
*/
#include <signal.h>
#include <fcntl.h>
@@ -39,115 +40,51 @@
#include <pthread.h>
#include "pthread_private.h"
-/*
- * State change macro for signal handler:
- */
-#define PTHREAD_SIG_NEW_STATE(thrd, newstate) { \
- if ((_thread_run->sched_defer_count == 0) && \
- (_thread_kern_in_sched == 0)) { \
- PTHREAD_NEW_STATE(thrd, newstate); \
- } else { \
- _waitingq_check_reqd = 1; \
- PTHREAD_SET_STATE(thrd, newstate); \
- } \
-}
-
/* Static variables: */
-static int volatile yield_on_unlock_thread = 0;
-static spinlock_t thread_link_list_lock = _SPINLOCK_INITIALIZER;
-
-int _thread_sig_statistics[NSIG];
+static spinlock_t signal_lock = _SPINLOCK_INITIALIZER;
+unsigned int pending_sigs[NSIG];
+unsigned int handled_sigs[NSIG];
+int volatile check_pending = 0;
-/* Lock the thread list: */
+/* Initialize signal handling facility: */
void
-_lock_thread_list()
+_thread_sig_init(void)
{
- /* Lock the thread list: */
- _SPINLOCK(&thread_link_list_lock);
-}
-
-/* Lock the thread list: */
-void
-_unlock_thread_list()
-{
- /* Unlock the thread list: */
- _SPINUNLOCK(&thread_link_list_lock);
-
- /*
- * Check if a scheduler interrupt occurred while the thread
- * list was locked:
- */
- if (yield_on_unlock_thread) {
- /* Reset the interrupt flag: */
- yield_on_unlock_thread = 0;
+ int i;
- /* This thread has overstayed it's welcome: */
- sched_yield();
+ /* Clear pending and handled signal counts: */
+ for (i = 1; i < NSIG; i++) {
+ pending_sigs[i - 1] = 0;
+ handled_sigs[i - 1] = 0;
}
+
+ /* Clear the lock: */
+ signal_lock.access_lock = 0;
}
void
_thread_sig_handler(int sig, int code, struct sigcontext * scp)
{
- char c;
- int i;
- pthread_t pthread;
-
- /*
- * Record the number of times this signal has been received
- */
- _thread_sig_statistics[sig]++;
-
- /*
- * Check if the pthread kernel has unblocked signals (or is about to)
- * and was on its way into a _select when the current
- * signal interrupted it:
- */
- if (_thread_kern_in_select) {
- /* Cast the signal number to a character variable: */
- c = sig;
-
- /*
- * Write the signal number to the kernel pipe so that it will
- * be ready to read when this signal handler returns. This
- * means that the _select call will complete
- * immediately.
- */
- _thread_sys_write(_thread_kern_pipe[1], &c, 1);
- }
-
- /* Check if the signal requires a dump of thread information: */
- if (sig == SIGINFO)
- /* Dump thread information to file: */
- _thread_dump_info();
+ char c;
+ int i;
/* Check if an interval timer signal: */
- else if (sig == _SCHED_SIGNAL) {
- /* Check if the scheduler interrupt has come at an
- * unfortunate time which one of the threads is
- * modifying the thread list:
- */
- if (_atomic_is_locked(&thread_link_list_lock.access_lock))
+ if (sig == _SCHED_SIGNAL) {
+ if (_thread_kern_in_sched != 0) {
/*
- * Set a flag so that the thread that has
- * the lock yields when it unlocks the
- * thread list:
+ * The scheduler is already running; ignore this
+ * signal.
*/
- yield_on_unlock_thread = 1;
-
+ }
/*
* Check if the scheduler interrupt has come when
* the currently running thread has deferred thread
- * scheduling.
+ * signals.
*/
- else if (_thread_run->sched_defer_count)
- _thread_run->yield_on_sched_undefer = 1;
+ else if (_thread_run->sig_defer_count > 0)
+ _thread_run->yield_on_sig_undefer = 1;
- /*
- * Check if the kernel has not been interrupted while
- * executing scheduler code:
- */
- else if (!_thread_kern_in_sched) {
+ else {
/*
* Schedule the next thread. This function is not
* expected to return because it will do a longjmp
@@ -161,6 +98,72 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
*/
PANIC("Returned to signal function from scheduler");
}
+ }
+ /*
+ * Check if the kernel has been interrupted while the scheduler
+ * is accessing the scheduling queues or if there is a currently
+ * running thread that has deferred signals.
+ */
+ else if ((_queue_signals != 0) || ((_thread_kern_in_sched == 0) &&
+ (_thread_run->sig_defer_count > 0))) {
+ /* Cast the signal number to a character variable: */
+ c = sig;
+
+ /*
+ * Write the signal number to the kernel pipe so that it will
+ * be ready to read when this signal handler returns.
+ */
+ _thread_sys_write(_thread_kern_pipe[1], &c, 1);
+
+ /* Indicate that there are queued signals in the pipe. */
+ _sigq_check_reqd = 1;
+ }
+ else {
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ /* There is another signal handler running: */
+ pending_sigs[sig - 1]++;
+ check_pending = 1;
+ }
+ else {
+ /* It's safe to handle the signal now. */
+ _thread_sig_handle(sig, scp);
+
+ /* Reset the pending and handled count back to 0: */
+ pending_sigs[sig - 1] = 0;
+ handled_sigs[sig - 1] = 0;
+
+ signal_lock.access_lock = 0;
+ }
+
+ /* Enter a loop to process pending signals: */
+ while ((check_pending != 0) &&
+ (_atomic_lock(&signal_lock.access_lock) == 0)) {
+ check_pending = 0;
+ for (i = 1; i < NSIG; i++) {
+ if (pending_sigs[i - 1] > handled_sigs[i - 1])
+ _thread_sig_handle(i, scp);
+ }
+ signal_lock.access_lock = 0;
+ }
+ }
+}
+
+void
+_thread_sig_handle(int sig, struct sigcontext * scp)
+{
+ int i;
+ pthread_t pthread, pthread_next;
+
+ /* Check if the signal requires a dump of thread information: */
+ if (sig == SIGINFO)
+ /* Dump thread information to file: */
+ _thread_dump_info();
+
+ /* Check if an interval timer signal: */
+ else if (sig == _SCHED_SIGNAL) {
+ /*
+ * This shouldn't ever occur (should this panic?).
+ */
} else {
/* Check if a child has terminated: */
if (sig == SIGCHLD) {
@@ -192,10 +195,9 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
* Enter a loop to discard pending SIGCONT
* signals:
*/
- for (pthread = _thread_link_list;
- pthread != NULL;
- pthread = pthread->nxt)
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
sigdelset(&pthread->sigpend,SIGCONT);
+ }
}
/*
@@ -205,11 +207,18 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
* if there are multiple waiters, we'll give it to the
* first one we find.
*/
- TAILQ_FOREACH(pthread, &_waitingq, pqe) {
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly destroying
+ * the link entry.
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
if ((pthread->state == PS_SIGWAIT) &&
sigismember(pthread->data.sigwait, sig)) {
/* Change the state of the thread to run: */
- PTHREAD_SIG_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
/* Return the signal number: */
pthread->signo = sig;
@@ -228,18 +237,26 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
* Enter a loop to process each thread in the linked
* list:
*/
- for (pthread = _thread_link_list; pthread != NULL;
- pthread = pthread->nxt) {
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
pthread_t pthread_saved = _thread_run;
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count++;
+
_thread_run = pthread;
_thread_signal(pthread,sig);
+
/*
* Dispatch pending signals to the
* running thread:
*/
_dispatch_signals();
_thread_run = pthread_saved;
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count--;
}
}
@@ -292,7 +309,7 @@ _thread_signal(pthread_t pthread, int sig)
pthread->interrupted = 1;
/* Change the state of the thread to run: */
- PTHREAD_SIG_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
/* Return the signal number: */
pthread->signo = sig;
@@ -304,6 +321,7 @@ _thread_signal(pthread_t pthread, int sig)
*/
case PS_FDR_WAIT:
case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
case PS_SLEEP_WAIT:
case PS_SELECT_WAIT:
if (sig != SIGCHLD ||
@@ -311,8 +329,11 @@ _thread_signal(pthread_t pthread, int sig)
/* Flag the operation as interrupted: */
pthread->interrupted = 1;
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+
/* Change the state of the thread to run: */
- PTHREAD_SIG_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
/* Return the signal number: */
pthread->signo = sig;
@@ -327,7 +348,7 @@ _thread_signal(pthread_t pthread, int sig)
if (!sigismember(&pthread->sigmask, sig) &&
_thread_sigact[sig - 1].sa_handler != SIG_DFL) {
/* Change the state of the thread to run: */
- PTHREAD_SIG_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
/* Return the signal number: */
pthread->signo = sig;
diff --git a/lib/libc_r/uthread/uthread_sigaction.c b/lib/libc_r/uthread/uthread_sigaction.c
index 6d709a8803f..de0aaeb7bfe 100644
--- a/lib/libc_r/uthread/uthread_sigaction.c
+++ b/lib/libc_r/uthread/uthread_sigaction.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigaction.c,v 1.5 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigaction.c,v 1.4 1999/05/26 00:18:26 d Exp $
+ * $FreeBSD: uthread_sigaction.c,v 1.8 1999/08/28 00:03:48 peter Exp $
*/
#include <signal.h>
#include <errno.h>
@@ -78,6 +79,9 @@ sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
gact.sa_mask = act->sa_mask;
gact.sa_flags = 0;
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&gact.sa_mask, _SCHED_SIGNAL);
+
/*
* Check if the signal handler is being set to
* the default or ignore handlers:
diff --git a/lib/libc_r/uthread/uthread_sigaltstack.c b/lib/libc_r/uthread/uthread_sigaltstack.c
index 9a1f9614542..fff62da3be2 100644
--- a/lib/libc_r/uthread/uthread_sigaltstack.c
+++ b/lib/libc_r/uthread/uthread_sigaltstack.c
@@ -1,6 +1,4 @@
-/*
- * $OpenBSD: uthread_sigaltstack.c,v 1.1 1998/11/09 03:13:20 d Exp $
- */
+/* $OpenBSD: uthread_sigaltstack.c,v 1.2 1999/11/25 07:01:44 d Exp $ */
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_sigblock.c b/lib/libc_r/uthread/uthread_sigblock.c
index 5b317d01472..dd08126ce70 100644
--- a/lib/libc_r/uthread/uthread_sigblock.c
+++ b/lib/libc_r/uthread/uthread_sigblock.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigblock.c,v 1.3 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigblock.c,v 1.2 1999/01/06 05:29:27 d Exp $
+ * $FreeBSD: uthread_sigblock.c,v 1.4 1999/08/28 00:03:49 peter Exp $
*/
#include <signal.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_sigmask.c b/lib/libc_r/uthread/uthread_sigmask.c
index bdaf30e09f8..6de570535e4 100644
--- a/lib/libc_r/uthread/uthread_sigmask.c
+++ b/lib/libc_r/uthread/uthread_sigmask.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigmask.c,v 1.3 1999/11/25 07:01:44 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigmask.c,v 1.2 1999/01/06 05:29:27 d Exp $
+ * $FreeBSD: uthread_sigmask.c,v 1.5 1999/09/29 15:18:40 marcel Exp $
*/
#include <errno.h>
#include <signal.h>
diff --git a/lib/libc_r/uthread/uthread_signal.c b/lib/libc_r/uthread/uthread_signal.c
index 2e1f3d21f60..bd9b488b3d0 100644
--- a/lib/libc_r/uthread/uthread_signal.c
+++ b/lib/libc_r/uthread/uthread_signal.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_signal.c,v 1.4 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_signal.c,v 1.3 1999/01/06 05:29:28 d Exp $
+ * $FreeBSD: uthread_signal.c,v 1.4 1999/08/28 00:03:49 peter Exp $
*/
#include <signal.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_sigpending.c b/lib/libc_r/uthread/uthread_sigpending.c
index 2daf3159b59..9921ee5a237 100644
--- a/lib/libc_r/uthread/uthread_sigpending.c
+++ b/lib/libc_r/uthread/uthread_sigpending.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_sigpending.c,v 1.1 1999/05/26 00:18:26 d Exp $ */
+/* $OpenBSD: uthread_sigpending.c,v 1.2 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -21,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_sigpending.c,v 1.3 1999/08/28 00:03:50 peter Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_sigprocmask.c b/lib/libc_r/uthread/uthread_sigprocmask.c
index c3f0b1dda16..28d4c3b1efe 100644
--- a/lib/libc_r/uthread/uthread_sigprocmask.c
+++ b/lib/libc_r/uthread/uthread_sigprocmask.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigprocmask.c,v 1.3 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigprocmask.c,v 1.2 1999/01/06 05:29:28 d Exp $
+ * $FreeBSD: uthread_sigprocmask.c,v 1.6 1999/09/29 15:18:40 marcel Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_sigsetmask.c b/lib/libc_r/uthread/uthread_sigsetmask.c
index 1f416551142..878efe36add 100644
--- a/lib/libc_r/uthread/uthread_sigsetmask.c
+++ b/lib/libc_r/uthread/uthread_sigsetmask.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigsetmask.c,v 1.3 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigsetmask.c,v 1.2 1999/01/06 05:29:28 d Exp $
+ * $FreeBSD: uthread_sigsetmask.c,v 1.4 1999/08/28 00:03:50 peter Exp $
*/
#include <signal.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_sigsuspend.c b/lib/libc_r/uthread/uthread_sigsuspend.c
index e0035c0fa1a..bd7e2094bd9 100644
--- a/lib/libc_r/uthread/uthread_sigsuspend.c
+++ b/lib/libc_r/uthread/uthread_sigsuspend.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigsuspend.c,v 1.4 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigsuspend.c,v 1.3 1999/01/06 05:29:28 d Exp $
+ * $FreeBSD: uthread_sigsuspend.c,v 1.7 1999/08/28 00:03:50 peter Exp $
*/
#include <signal.h>
#include <errno.h>
diff --git a/lib/libc_r/uthread/uthread_sigwait.c b/lib/libc_r/uthread/uthread_sigwait.c
index 00cf99ef20b..84db32d0470 100644
--- a/lib/libc_r/uthread/uthread_sigwait.c
+++ b/lib/libc_r/uthread/uthread_sigwait.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_sigwait.c,v 1.7 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_sigwait.c,v 1.6 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_sigwait.c,v 1.10 1999/09/30 14:51:31 marcel Exp $
*/
#include <signal.h>
#include <errno.h>
@@ -42,7 +43,7 @@ sigwait(const sigset_t * set, int *sig)
{
int ret = 0;
int i;
- sigset_t tempset;
+ sigset_t tempset, waitset;
struct sigaction act;
/* This is a cancellation point: */
@@ -55,17 +56,23 @@ sigwait(const sigset_t * set, int *sig)
act.sa_flags = SA_RESTART;
act.sa_mask = *set;
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
/*
- * These signals can't be waited on.
+ * Initialize the set of signals that will be waited on:
*/
- sigdelset(&act.sa_mask, SIGKILL);
- sigdelset(&act.sa_mask, SIGSTOP);
- sigdelset(&act.sa_mask, _SCHED_SIGNAL);
- sigdelset(&act.sa_mask, SIGCHLD);
- sigdelset(&act.sa_mask, SIGINFO);
+ waitset = *set;
+
+ /* These signals can't be waited on. */
+ sigdelset(&waitset, SIGKILL);
+ sigdelset(&waitset, SIGSTOP);
+ sigdelset(&waitset, _SCHED_SIGNAL);
+ sigdelset(&waitset, SIGCHLD);
+ sigdelset(&waitset, SIGINFO);
/* Check to see if a pending signal is in the wait mask. */
- if ((tempset = (_thread_run->sigpend & act.sa_mask))) {
+ if (tempset = (_thread_run->sigpend & waitset)) {
/* Enter a loop to find a pending signal: */
for (i = 1; i < NSIG; i++) {
if (sigismember (&tempset, i))
@@ -80,6 +87,7 @@ sigwait(const sigset_t * set, int *sig)
/* No longer in a cancellation point: */
_thread_leave_cancellation_point();
+
return (0);
}
@@ -87,17 +95,17 @@ sigwait(const sigset_t * set, int *sig)
* Enter a loop to find the signals that are SIG_DFL. For
* these signals we must install a dummy signal handler in
* order for the kernel to pass them in to us. POSIX says
- * that the application must explicitly install a dummy
+ * that the _application_ must explicitly install a dummy
* handler for signals that are SIG_IGN in order to sigwait
* on them. Note that SIG_IGN signals are left in the
* mask because a subsequent sigaction could enable an
* ignored signal.
*/
for (i = 1; i < NSIG; i++) {
- if (sigismember(&act.sa_mask, i)) {
- if (_thread_sigact[i - 1].sa_handler == SIG_DFL)
- if (_thread_sys_sigaction(i,&act,NULL) != 0)
- ret = -1;
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
}
}
if (ret == 0) {
@@ -107,7 +115,7 @@ sigwait(const sigset_t * set, int *sig)
* mask is independent of the threads signal mask
* and requires separate storage.
*/
- _thread_run->data.sigwait = &act.sa_mask;
+ _thread_run->data.sigwait = &waitset;
/* Wait for a signal: */
_thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
@@ -125,7 +133,7 @@ sigwait(const sigset_t * set, int *sig)
/* Restore the sigactions: */
act.sa_handler = SIG_DFL;
for (i = 1; i < NSIG; i++) {
- if (sigismember(&act.sa_mask, i) &&
+ if (sigismember(&waitset, i) &&
(_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
if (_thread_sys_sigaction(i,&act,NULL) != 0)
ret = -1;
diff --git a/lib/libc_r/uthread/uthread_single_np.c b/lib/libc_r/uthread/uthread_single_np.c
index 39c90837653..84208893b16 100644
--- a/lib/libc_r/uthread/uthread_single_np.c
+++ b/lib/libc_r/uthread/uthread_single_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_single_np.c,v 1.3 1999/11/25 07:01:45 d Exp $ */
/*
* Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_single_np.c,v 1.2 1999/01/06 05:29:28 d Exp $
+ * $FreeBSD: uthread_single_np.c,v 1.3 1999/08/28 00:03:51 peter Exp $
*/
#include <string.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_socket.c b/lib/libc_r/uthread/uthread_socket.c
index ea848d3c144..b4a96b8185a 100644
--- a/lib/libc_r/uthread/uthread_socket.c
+++ b/lib/libc_r/uthread/uthread_socket.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_socket.c,v 1.3 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_socket.c,v 1.2 1999/01/06 05:29:29 d Exp $
+ * $FreeBSD: uthread_socket.c,v 1.5 1999/08/28 00:03:51 peter Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/lib/libc_r/uthread/uthread_socketpair.c b/lib/libc_r/uthread/uthread_socketpair.c
index d78eaad0197..482a3d71b6c 100644
--- a/lib/libc_r/uthread/uthread_socketpair.c
+++ b/lib/libc_r/uthread/uthread_socketpair.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_socketpair.c,v 1.3 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,14 +30,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_socketpair.c,v 1.4 1998/04/29 09:59:27 jb Exp $
- * $OpenBSD: uthread_socketpair.c,v 1.2 1998/12/23 22:49:46 d Exp $
+ * $FreeBSD: uthread_socketpair.c,v 1.6 1999/08/28 00:03:52 peter Exp $
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
-#include <unistd.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
diff --git a/lib/libc_r/uthread/uthread_spec.c b/lib/libc_r/uthread/uthread_spec.c
index 6a4b9c9c5e4..1ac1df46fe4 100644
--- a/lib/libc_r/uthread/uthread_spec.c
+++ b/lib/libc_r/uthread/uthread_spec.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_spec.c,v 1.6 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_spec.c,v 1.5 1999/05/14 22:29:52 alex Exp $
+ * $FreeBSD: uthread_spec.c,v 1.13 1999/08/28 00:03:52 peter Exp $
*/
#include <signal.h>
#include <stdlib.h>
@@ -113,7 +114,7 @@ _thread_cleanupspecific(void)
_SPINUNLOCK(&key_table[key].lock);
/*
- * If there is a destructor, call it
+ * If there is a destructore, call it
* with the key table entry unlocked:
*/
if (destructor)
diff --git a/lib/libc_r/uthread/uthread_spinlock.c b/lib/libc_r/uthread/uthread_spinlock.c
index 3ea96013bc6..6e7a60706c4 100644
--- a/lib/libc_r/uthread/uthread_spinlock.c
+++ b/lib/libc_r/uthread/uthread_spinlock.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_spinlock.c,v 1.6 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_spinlock.c,v 1.5 1999/03/23 05:07:56 jb Exp $
- * $OpenBSD: uthread_spinlock.c,v 1.5 1999/05/26 00:18:26 d Exp $
+ * $FreeBSD: uthread_spinlock.c,v 1.7 1999/08/28 00:03:52 peter Exp $
*
*/
@@ -63,7 +63,7 @@ _spinlock(spinlock_t *lck)
}
/* The running thread now owns the lock: */
- lck->lock_owner = _thread_run;
+ lck->lock_owner = (long) _thread_run;
}
/*
@@ -101,7 +101,7 @@ _spinlock_debug(spinlock_t *lck, const char *fname, int lineno)
}
/* The running thread now owns the lock: */
- lck->lock_owner = _thread_run;
+ lck->lock_owner = (long) _thread_run;
lck->fname = fname;
lck->lineno = lineno;
}
diff --git a/lib/libc_r/uthread/uthread_stack.c b/lib/libc_r/uthread/uthread_stack.c
new file mode 100644
index 00000000000..940f295efd3
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_stack.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: uthread_stack.c,v 1.1 1999/11/25 07:01:46 d Exp $ */
+
+/*
+ * Thread stack allocation.
+ *
+ * Stack pointers are assumed to work their way down (backwards) to the
+ * beginning of the stack storage. The first page of this storage is
+ * protected using mprotect() so as to generate a SIGSEGV if a thread
+ * overflows its stack.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include "pthread_private.h"
+
+struct stack *
+_thread_stack_alloc(base, size)
+ void *base;
+ size_t size;
+{
+ struct stack *stack;
+
+ /* Maintain a queue of default-sized stacks that we can re-use. */
+ if (size == PTHREAD_STACK_DEFAULT) {
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ if ((stack = SLIST_FIRST(&_stackq)) != NULL) {
+ SLIST_REMOVE_HEAD(&_stackq, qe);
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+ return stack;
+ }
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+ }
+
+ /* Allocate some storage to hold information about the stack: */
+ stack = (struct stack *)malloc(sizeof (struct stack));
+ if (stack == NULL)
+ return NULL;
+
+ if (base != NULL) {
+ /* Use the user's storage */
+ stack->base = base;
+ stack->size = size;
+ stack->redzone = NULL;
+ stack->storage = NULL;
+ return stack;
+ }
+
+ /* Allocate some storage for the stack, with some overhead: */
+ stack->storage = malloc(size + NBPG * 2);
+ if (stack->storage == NULL) {
+ free(stack);
+ return NULL;
+ }
+
+ /* The red zone is the first physical page of the storage: */
+ stack->redzone = (void*)(((int)stack->storage + NBPG - 1) &
+ ~(NBPG - 1));
+ if (mprotect(stack->redzone, NBPG, 0) == -1)
+ PANIC("Cannot protect stack red zone");
+
+ /* Find the useful range of the stack. */
+ stack->base = stack->redzone + NBPG;
+ stack->size = size;
+
+ return stack;
+}
+
+void
+_thread_stack_free(stack)
+ struct stack *stack;
+{
+ /* Cache allocated stacks of default size. */
+ if (stack->storage != NULL && stack->size == PTHREAD_STACK_DEFAULT)
+ SLIST_INSERT_HEAD(&_stackq, stack, qe);
+ else {
+ /* Restore storage protection to what malloc expects: */
+ if (stack->redzone)
+ mprotect(stack->redzone, NBPG, PROT_READ|PROT_WRITE);
+
+ /* Free storage */
+ if (stack->storage)
+ free(stack->storage);
+
+ /* Free stack information storage. */
+ free(stack);
+ }
+}
diff --git a/lib/libc_r/uthread/uthread_suspend_np.c b/lib/libc_r/uthread/uthread_suspend_np.c
index daeb60a661a..8c455e0a11d 100644
--- a/lib/libc_r/uthread/uthread_suspend_np.c
+++ b/lib/libc_r/uthread/uthread_suspend_np.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_suspend_np.c,v 1.4 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_suspend_np.c,v 1.3 1999/05/26 00:18:26 d Exp $
+ * $FreeBSD: uthread_suspend_np.c,v 1.7 1999/08/28 00:03:53 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
@@ -53,20 +54,19 @@ pthread_suspend_np(pthread_t thread)
}
/*
- * Guard against preemption by a scheduling signal.
- * A change of thread state modifies the waiting
- * and priority queues.
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
*/
- _thread_kern_sched_defer();
+ _thread_kern_sig_defer();
/* Suspend the thread. */
PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
/*
- * Reenable preemption and yield if a scheduling signal
- * occurred while in the critical region.
+ * Undefer and handle pending signals, yielding if
+ * necessary:
*/
- _thread_kern_sched_undefer();
+ _thread_kern_sig_undefer();
}
return(ret);
}
diff --git a/lib/libc_r/uthread/uthread_switch_np.c b/lib/libc_r/uthread/uthread_switch_np.c
index 598edacd2bb..2e7351b9697 100644
--- a/lib/libc_r/uthread/uthread_switch_np.c
+++ b/lib/libc_r/uthread/uthread_switch_np.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_switch_np.c,v 1.1 1999/05/26 00:18:26 d Exp $ */
+/* $OpenBSD: uthread_switch_np.c,v 1.2 1999/11/25 07:01:46 d Exp $ */
/*
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
* All rights reserved.
@@ -30,6 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $FreeBSD: uthread_switch_np.c,v 1.3 1999/08/28 00:03:53 peter Exp $
*/
#include <errno.h>
#ifdef _THREAD_SAFE
diff --git a/lib/libc_r/uthread/uthread_vfork.c b/lib/libc_r/uthread/uthread_vfork.c
index a3b0ee5bb06..32ac5cd33c1 100644
--- a/lib/libc_r/uthread/uthread_vfork.c
+++ b/lib/libc_r/uthread/uthread_vfork.c
@@ -1,6 +1,4 @@
-/*
- * $OpenBSD: uthread_vfork.c,v 1.1 1998/11/09 03:13:21 d Exp $
- */
+/* $OpenBSD: uthread_vfork.c,v 1.2 1999/11/25 07:01:47 d Exp $ */
#include <unistd.h>
#ifdef _THREAD_SAFE
@@ -9,4 +7,4 @@ vfork(void)
{
return (fork());
}
-#endif /* _THREAD_SAFE */
+#endif
diff --git a/lib/libc_r/uthread/uthread_wait4.c b/lib/libc_r/uthread/uthread_wait4.c
index aef609468d4..0c3efa803f2 100644
--- a/lib/libc_r/uthread/uthread_wait4.c
+++ b/lib/libc_r/uthread/uthread_wait4.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_wait4.c,v 1.5 1999/11/25 07:01:47 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_wait4.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_wait4.c,v 1.5 1999/08/28 00:03:53 peter Exp $
*/
#include <errno.h>
#include <sys/wait.h>
@@ -45,6 +46,8 @@ wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
/* This is a cancellation point: */
_thread_enter_cancellation_point();
+ _thread_kern_sig_defer();
+
/* Perform a non-blocking wait4 syscall: */
while ((ret = _thread_sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) {
/* Reset the interrupted operation flag: */
@@ -61,6 +64,8 @@ wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
}
}
+ _thread_kern_sig_undefer();
+
/* No longer in a cancellation point: */
_thread_leave_cancellation_point();
diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c
index 7d91092f9ae..cac06ef3bb5 100644
--- a/lib/libc_r/uthread/uthread_write.c
+++ b/lib/libc_r/uthread/uthread_write.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_write.c,v 1.5 1999/11/25 07:01:47 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_write.c,v 1.10 1998/09/07 21:55:01 alex Exp $
- * $OpenBSD: uthread_write.c,v 1.4 1999/06/09 07:16:17 d Exp $
+ * $FreeBSD: uthread_write.c,v 1.12 1999/08/28 00:03:54 peter Exp $
*
*/
#include <sys/types.h>
@@ -51,18 +51,12 @@ write(int fd, const void *buf, size_t nbytes)
ssize_t num = 0;
ssize_t ret;
- /* This is a cancellation point: */
- _thread_enter_cancellation_point();
-
/* POSIX says to do just this: */
- if (nbytes == 0) {
- /* No longer in a cancellation point: */
- _thread_leave_cancellation_point();
- return (0);
- }
+ if (nbytes == 0)
+ ret = 0;
/* Lock the file descriptor for write: */
- if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ else if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
/* Get the read/write mode type: */
type = _thread_fd_table[fd]->flags & O_ACCMODE;
@@ -70,12 +64,10 @@ write(int fd, const void *buf, size_t nbytes)
if (type != O_WRONLY && type != O_RDWR) {
/* File is not open for write: */
errno = EBADF;
- _FD_UNLOCK(fd, FD_WRITE);
- /* No longer in a cancellation point: */
- _thread_leave_cancellation_point();
- return (-1);
+ ret = -1;
}
+ else {
/* Check if file operations are to block */
blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
@@ -136,7 +128,8 @@ write(int fd, const void *buf, size_t nbytes)
/* Return the number of bytes written: */
ret = num;
}
- _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _FD_UNLOCK(fd, FD_WRITE);
}
/* No longer in a cancellation point: */
diff --git a/lib/libc_r/uthread/uthread_writev.c b/lib/libc_r/uthread/uthread_writev.c
index dc280c9145c..411b3bc0238 100644
--- a/lib/libc_r/uthread/uthread_writev.c
+++ b/lib/libc_r/uthread/uthread_writev.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_writev.c,v 1.3 1999/11/25 07:01:47 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: uthread_writev.c,v 1.10 1998/06/14 09:36:14 jb Exp $
- * $OpenBSD: uthread_writev.c,v 1.2 1998/12/23 22:49:47 d Exp $
+ * $FreeBSD: uthread_writev.c,v 1.12 1999/08/28 00:03:55 peter Exp $
*
*/
#include <sys/types.h>
diff --git a/lib/libc_r/uthread/uthread_yield.c b/lib/libc_r/uthread/uthread_yield.c
index 1844be51fcc..0dfaaf14438 100644
--- a/lib/libc_r/uthread/uthread_yield.c
+++ b/lib/libc_r/uthread/uthread_yield.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: uthread_yield.c,v 1.3 1999/11/25 07:01:47 d Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: uthread_yield.c,v 1.2 1999/01/06 05:29:29 d Exp $
+ * $FreeBSD: uthread_yield.c,v 1.4 1999/08/28 00:03:55 peter Exp $
*/
#ifdef _THREAD_SAFE
#include <pthread.h>