diff options
Diffstat (limited to 'lib/libkse/thread')
113 files changed, 0 insertions, 18469 deletions
diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc deleted file mode 100644 index 561be93..0000000 --- a/lib/libkse/thread/Makefile.inc +++ /dev/null @@ -1,117 +0,0 @@ -# $FreeBSD$ - -# thr sources -.PATH: ${.CURDIR}/thread - -SRCS+= \ - thr_accept.c \ - thr_aio_suspend.c \ - thr_atfork.c \ - thr_attr_destroy.c \ - thr_attr_init.c \ - thr_attr_get_np.c \ - thr_attr_getdetachstate.c \ - thr_attr_getguardsize.c \ - thr_attr_getinheritsched.c \ - thr_attr_getschedparam.c \ - thr_attr_getschedpolicy.c \ - thr_attr_getscope.c \ - thr_attr_getstack.c \ - thr_attr_getstackaddr.c \ - thr_attr_getstacksize.c \ - thr_attr_setcreatesuspend_np.c \ - thr_attr_setdetachstate.c \ - thr_attr_setguardsize.c \ - thr_attr_setinheritsched.c \ - thr_attr_setschedparam.c \ - thr_attr_setschedpolicy.c \ - thr_attr_setscope.c \ - thr_attr_setstack.c \ - thr_attr_setstackaddr.c \ - thr_attr_setstacksize.c \ - thr_autoinit.c \ - thr_barrier.c \ - thr_barrierattr.c \ - thr_cancel.c \ - thr_clean.c \ - thr_close.c \ - thr_concurrency.c \ - thr_cond.c \ - thr_condattr_destroy.c \ - thr_condattr_init.c \ - thr_condattr_pshared.c \ - thr_connect.c \ - thr_creat.c \ - thr_create.c \ - thr_detach.c \ - thr_equal.c \ - thr_execve.c \ - thr_exit.c \ - thr_fcntl.c \ - thr_find_thread.c \ - thr_fork.c \ - thr_fsync.c \ - thr_getprio.c \ - thr_getschedparam.c \ - thr_info.c \ - thr_init.c \ - thr_join.c \ - thr_kern.c \ - thr_kill.c \ - thr_main_np.c \ - thr_mattr_init.c \ - thr_mattr_kind_np.c \ - thr_mattr_pshared.c \ - thr_msync.c \ - thr_multi_np.c \ - thr_mutex.c \ - thr_mutex_prioceiling.c \ - thr_mutex_protocol.c \ - thr_mutexattr_destroy.c \ - thr_nanosleep.c \ - thr_once.c \ - thr_open.c \ - thr_pause.c \ - thr_poll.c \ - thr_printf.c \ - thr_priority_queue.c \ - thr_pselect.c \ - thr_pspinlock.c \ - thr_raise.c \ - thr_read.c \ - thr_readv.c \ - thr_resume_np.c \ - thr_rtld.c \ - thr_rwlock.c \ - thr_rwlockattr.c \ - thr_select.c \ - thr_self.c \ - thr_sem.c \ - thr_seterrno.c \ - thr_setprio.c \ - thr_setschedparam.c \ - thr_sig.c \ - thr_sigaction.c \ - thr_sigaltstack.c \ - thr_sigmask.c \ - thr_sigpending.c \ - thr_sigprocmask.c \ - thr_sigsuspend.c \ - thr_sigwait.c \ - thr_single_np.c \ - thr_sleep.c \ - thr_spec.c \ - thr_spinlock.c \ - thr_stack.c \ - thr_suspend_np.c \ - thr_switch_np.c \ - thr_system.c \ - thr_symbols.c \ - thr_tcdrain.c \ - thr_vfork.c \ - thr_wait.c \ - thr_wait4.c \ - thr_waitpid.c \ - thr_write.c \ - thr_writev.c \ - thr_yield.c diff --git a/lib/libkse/thread/thr_accept.c b/lib/libkse/thread/thr_accept.c deleted file mode 100644 index 76327ef..0000000 --- a/lib/libkse/thread/thr_accept.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. 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 THE AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/socket.h> -#include <pthread.h> -#include "thr_private.h" - -int __accept(int s, struct sockaddr *addr, socklen_t *addrlen); - -__weak_reference(__accept, accept); - -int -__accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - ret = __sys_accept(s, addr, addrlen); - _thr_cancel_leave(curthread, ret == -1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_aio_suspend.c b/lib/libkse/thread/thr_aio_suspend.c deleted file mode 100644 index 87797f2..0000000 --- a/lib/libkse/thread/thr_aio_suspend.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include <aio.h> -#include <pthread.h> -#include "thr_private.h" - - -int -_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct - timespec *timeout); - -__weak_reference(_aio_suspend, aio_suspend); - -int -_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct - timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_aio_suspend(iocbs, niocb, timeout); - _thr_cancel_leave(curthread, 1); - - return (ret); -} - diff --git a/lib/libkse/thread/thr_atfork.c b/lib/libkse/thread/thr_atfork.c deleted file mode 100644 index 638f27b..0000000 --- a/lib/libkse/thread/thr_atfork.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * 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. 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 THE AUTHOR 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$ - */ -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include <sys/queue.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_atfork, pthread_atfork); - -int -_pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)) -{ - struct pthread_atfork *af; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - if ((af = malloc(sizeof(struct pthread_atfork))) == NULL) - return (ENOMEM); - - af->prepare = prepare; - af->parent = parent; - af->child = child; - _pthread_mutex_lock(&_thr_atfork_mutex); - TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe); - _pthread_mutex_unlock(&_thr_atfork_mutex); - return (0); -} - diff --git a/lib/libkse/thread/thr_attr_destroy.c b/lib/libkse/thread/thr_attr_destroy.c deleted file mode 100644 index 3f48e1f..0000000 --- a/lib/libkse/thread/thr_attr_destroy.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996 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. 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 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$ - */ -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_destroy, pthread_attr_destroy); - -int -_pthread_attr_destroy(pthread_attr_t *attr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL) - /* Invalid argument: */ - ret = EINVAL; - else { - /* Free the memory allocated to the attribute object: */ - free(*attr); - - /* - * Leave the attribute pointer NULL now that the memory - * has been freed: - */ - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_get_np.c b/lib/libkse/thread/thr_attr_get_np.c deleted file mode 100644 index fea3565..0000000 --- a/lib/libkse/thread/thr_attr_get_np.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_get_np, pthread_attr_get_np); - -int -_pthread_attr_get_np(pthread_t pid, pthread_attr_t *dst) -{ - struct pthread *curthread; - struct pthread_attr attr; - int ret; - - if (pid == NULL || dst == NULL || *dst == NULL) - return (EINVAL); - - curthread = _get_curthread(); - if ((ret = _thr_ref_add(curthread, pid, /*include dead*/0)) != 0) - return (ret); - attr = pid->attr; - _thr_ref_delete(curthread, pid); - memcpy(*dst, &attr, sizeof(struct pthread_attr)); - - return (0); -} diff --git a/lib/libkse/thread/thr_attr_getdetachstate.c b/lib/libkse/thread/thr_attr_getdetachstate.c deleted file mode 100644 index d9e16b8..0000000 --- a/lib/libkse/thread/thr_attr_getdetachstate.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate); - -int -_pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || detachstate == NULL) - ret = EINVAL; - else { - /* Check if the detached flag is set: */ - if ((*attr)->flags & PTHREAD_DETACHED) - /* Return detached: */ - *detachstate = PTHREAD_CREATE_DETACHED; - else - /* Return joinable: */ - *detachstate = PTHREAD_CREATE_JOINABLE; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getguardsize.c b/lib/libkse/thread/thr_attr_getguardsize.c deleted file mode 100644 index 65a1641..0000000 --- a/lib/libkse/thread/thr_attr_getguardsize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize); - -int -_pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || guardsize == NULL) - ret = EINVAL; - else { - /* Return the guard size: */ - *guardsize = (*attr)->guardsize_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getinheritsched.c b/lib/libkse/thread/thr_attr_getinheritsched.c deleted file mode 100644 index fdbdbe9..0000000 --- a/lib/libkse/thread/thr_attr_getinheritsched.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched); - -int -_pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else - *sched_inherit = (*attr)->sched_inherit; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getschedparam.c b/lib/libkse/thread/thr_attr_getschedparam.c deleted file mode 100644 index 369fc38..0000000 --- a/lib/libkse/thread/thr_attr_getschedparam.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam); - -int -_pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (param == NULL)) - ret = EINVAL; - else - param->sched_priority = (*attr)->prio; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getschedpolicy.c b/lib/libkse/thread/thr_attr_getschedpolicy.c deleted file mode 100644 index 28d48bc..0000000 --- a/lib/libkse/thread/thr_attr_getschedpolicy.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); - -int -_pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (policy == NULL)) - ret = EINVAL; - else - *policy = (*attr)->sched_policy; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getscope.c b/lib/libkse/thread/thr_attr_getscope.c deleted file mode 100644 index 96963cb..0000000 --- a/lib/libkse/thread/thr_attr_getscope.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getscope, pthread_attr_getscope); - -int -_pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL)) - /* Return an invalid argument: */ - ret = EINVAL; - - else - *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? - PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getstack.c b/lib/libkse/thread/thr_attr_getstack.c deleted file mode 100644 index 3d279f9..0000000 --- a/lib/libkse/thread/thr_attr_getstack.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. - * 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 Craig Rodrigues. - * 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 CRAIG RODRIGUES 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstack, pthread_attr_getstack); - -int -_pthread_attr_getstack(const pthread_attr_t * __restrict attr, - void ** __restrict stackaddr, - size_t * __restrict stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL - || stacksize == NULL ) - ret = EINVAL; - else { - /* Return the stack address and size */ - *stackaddr = (*attr)->stackaddr_attr; - *stacksize = (*attr)->stacksize_attr; - ret = 0; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_attr_getstackaddr.c b/lib/libkse/thread/thr_attr_getstackaddr.c deleted file mode 100644 index 2c8e593..0000000 --- a/lib/libkse/thread/thr_attr_getstackaddr.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr); - -int -_pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL) - ret = EINVAL; - else { - /* Return the stack address: */ - *stackaddr = (*attr)->stackaddr_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_getstacksize.c b/lib/libkse/thread/thr_attr_getstacksize.c deleted file mode 100644 index 25bb372..0000000 --- a/lib/libkse/thread/thr_attr_getstacksize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize); - -int -_pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stacksize == NULL) - ret = EINVAL; - else { - /* Return the stack size: */ - *stacksize = (*attr)->stacksize_attr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_init.c b/lib/libkse/thread/thr_attr_init.c deleted file mode 100644 index f320e4b..0000000 --- a/lib/libkse/thread/thr_attr_init.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1996 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. 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 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$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_init, pthread_attr_init); - -int -_pthread_attr_init(pthread_attr_t *attr) -{ - int ret; - pthread_attr_t pattr; - - /* Allocate memory for the attribute object: */ - if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) - /* Insufficient memory: */ - ret = ENOMEM; - else { - /* Initialise the attribute object with the defaults: */ - memcpy(pattr, &_pthread_attr_default, - sizeof(struct pthread_attr)); - pattr->guardsize_attr = _thr_guard_default; - pattr->stacksize_attr = _thr_stack_default; - - /* Return a pointer to the attribute object: */ - *attr = pattr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setcreatesuspend_np.c b/lib/libkse/thread/thr_attr_setcreatesuspend_np.c deleted file mode 100644 index 4dbd181..0000000 --- a/lib/libkse/thread/thr_attr_setcreatesuspend_np.c +++ /dev/null @@ -1,54 +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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr); - -__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np); - -int -_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) -{ - int ret; - - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - (*attr)->suspend = THR_CREATE_SUSPENDED; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setdetachstate.c b/lib/libkse/thread/thr_attr_setdetachstate.c deleted file mode 100644 index 6f45a18..0000000 --- a/lib/libkse/thread/thr_attr_setdetachstate.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate); - -int -_pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || - (detachstate != PTHREAD_CREATE_DETACHED && - detachstate != PTHREAD_CREATE_JOINABLE)) - ret = EINVAL; - else { - /* Check if detached state: */ - if (detachstate == PTHREAD_CREATE_DETACHED) - /* Set the detached flag: */ - (*attr)->flags |= PTHREAD_DETACHED; - else - /* Reset the detached flag: */ - (*attr)->flags &= ~PTHREAD_DETACHED; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setguardsize.c b/lib/libkse/thread/thr_attr_setguardsize.c deleted file mode 100644 index aa6e508..0000000 --- a/lib/libkse/thread/thr_attr_setguardsize.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize); - -int -_pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) -{ - int ret; - - /* Check for invalid arguments. */ - if (attr == NULL || *attr == NULL) - ret = EINVAL; - else { - /* Save the stack size. */ - (*attr)->guardsize_attr = guardsize; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setinheritsched.c b/lib/libkse/thread/thr_attr_setinheritsched.c deleted file mode 100644 index 5c1766b..0000000 --- a/lib/libkse/thread/thr_attr_setinheritsched.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched); - -int -_pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if (sched_inherit != PTHREAD_INHERIT_SCHED && - sched_inherit != PTHREAD_EXPLICIT_SCHED) - ret = ENOTSUP; - else - (*attr)->sched_inherit = sched_inherit; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setschedparam.c b/lib/libkse/thread/thr_attr_setschedparam.c deleted file mode 100644 index d7a6721..0000000 --- a/lib/libkse/thread/thr_attr_setschedparam.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam); - -int -_pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if (param == NULL) { - ret = ENOTSUP; - } else if ((param->sched_priority < THR_MIN_PRIORITY) || - (param->sched_priority > THR_MAX_PRIORITY)) { - /* Return an unsupported value error. */ - ret = ENOTSUP; - } else - (*attr)->prio = param->sched_priority; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setschedpolicy.c b/lib/libkse/thread/thr_attr_setschedpolicy.c deleted file mode 100644 index ac5df02..0000000 --- a/lib/libkse/thread/thr_attr_setschedpolicy.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); - -int -_pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) - ret = EINVAL; - else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) { - ret = ENOTSUP; - } else - (*attr)->sched_policy = policy; - - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setscope.c b/lib/libkse/thread/thr_attr_setscope.c deleted file mode 100644 index 97930e7..0000000 --- a/lib/libkse/thread/thr_attr_setscope.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setscope, pthread_attr_setscope); - -int -_pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) -{ - int ret = 0; - - if ((attr == NULL) || (*attr == NULL)) { - /* Return an invalid argument: */ - ret = EINVAL; - } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) && - (contentionscope != PTHREAD_SCOPE_SYSTEM)) { - ret = EINVAL; - } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) { - (*attr)->flags |= contentionscope; - } else { - (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_attr_setstack.c b/lib/libkse/thread/thr_attr_setstack.c deleted file mode 100644 index 127e60f..0000000 --- a/lib/libkse/thread/thr_attr_setstack.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. - * 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 Craig Rodrigues. - * 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 CRAIG RODRIGUES 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstack, pthread_attr_setstack); - -int -_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, - size_t stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL - || stacksize < PTHREAD_STACK_MIN ) - ret = EINVAL; - else { - /* Save the stack address and stack size */ - (*attr)->stackaddr_attr = stackaddr; - (*attr)->stacksize_attr = stacksize; - ret = 0; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_attr_setstackaddr.c b/lib/libkse/thread/thr_attr_setstackaddr.c deleted file mode 100644 index 2d6cc1b..0000000 --- a/lib/libkse/thread/thr_attr_setstackaddr.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr); - -int -_pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stackaddr == NULL) - ret = EINVAL; - else { - /* Save the stack address: */ - (*attr)->stackaddr_attr = stackaddr; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_attr_setstacksize.c b/lib/libkse/thread/thr_attr_setstacksize.c deleted file mode 100644 index 7d72d71..0000000 --- a/lib/libkse/thread/thr_attr_setstacksize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1996 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize); - -int -_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) -{ - int ret; - - /* Check for invalid arguments: */ - if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) - ret = EINVAL; - else { - /* Save the stack size: */ - (*attr)->stacksize_attr = stacksize; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_autoinit.c b/lib/libkse/thread/thr_autoinit.c deleted file mode 100644 index 95b2a85..0000000 --- a/lib/libkse/thread/thr_autoinit.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2002 Alfred Perlstein <alfred@freebsd.org>. - * 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 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$ - */ - -/* - * This module uses GCC extentions to initialize the - * threads package at program start-up time. - */ - -#include <pthread.h> -#include "thr_private.h" - -void _thread_init_hack(void) __attribute__ ((constructor)); - -void -_thread_init_hack(void) -{ - - _libpthread_init(NULL); -} - -/* - * For the shared version of the threads library, the above is sufficient. - * But for the archive version of the library, we need a little bit more. - * Namely, we must arrange for this particular module to be pulled in from - * the archive library at link time. To accomplish that, we define and - * initialize a variable, "_thread_autoinit_dummy_decl". This variable is - * referenced (as an extern) from libc/stdlib/exit.c. This will always - * create a need for this module, ensuring that it is present in the - * executable. - */ -extern int _thread_autoinit_dummy_decl; -int _thread_autoinit_dummy_decl = 0; diff --git a/lib/libkse/thread/thr_barrier.c b/lib/libkse/thread/thr_barrier.c deleted file mode 100644 index 21113cb..0000000 --- a/lib/libkse/thread/thr_barrier.c +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_barrier_init, pthread_barrier_init); -__weak_reference(_pthread_barrier_wait, pthread_barrier_wait); -__weak_reference(_pthread_barrier_destroy, pthread_barrier_destroy); - -int -_pthread_barrier_destroy(pthread_barrier_t *barrier) -{ - pthread_barrier_t bar; - int ret, ret2; - - if (barrier == NULL || *barrier == NULL) - return (EINVAL); - - bar = *barrier; - if (bar->b_waiters > 0) - return (EBUSY); - *barrier = NULL; - ret = _pthread_mutex_destroy(&bar->b_lock); - ret2 = _pthread_cond_destroy(&bar->b_cond); - free(bar); - return (ret ? ret : ret2); -} - -int -_pthread_barrier_init(pthread_barrier_t *barrier, - const pthread_barrierattr_t *attr __unused, unsigned count) -{ - pthread_barrier_t bar; - int ret; - - if (barrier == NULL || count <= 0) - return (EINVAL); - - bar = malloc(sizeof(struct pthread_barrier)); - if (bar == NULL) - return (ENOMEM); - - if ((ret = _pthread_mutex_init(&bar->b_lock, NULL)) != 0) { - free(bar); - return (ret); - } - - if ((ret = _pthread_cond_init(&bar->b_cond, NULL)) != 0) { - _pthread_mutex_destroy(&bar->b_lock); - free(bar); - return (ret); - } - - bar->b_waiters = 0; - bar->b_count = count; - bar->b_generation = 0; - *barrier = bar; - - return (0); -} - -int -_pthread_barrier_wait(pthread_barrier_t *barrier) -{ - int ret, gen; - pthread_barrier_t bar; - - if (barrier == NULL || *barrier == NULL) - return (EINVAL); - - bar = *barrier; - if ((ret = _pthread_mutex_lock(&bar->b_lock)) != 0) - return (ret); - - if (++bar->b_waiters == bar->b_count) { - /* Current thread is lastest thread */ - bar->b_generation++; - bar->b_waiters = 0; - ret = _pthread_cond_broadcast(&bar->b_cond); - if (ret == 0) - ret = PTHREAD_BARRIER_SERIAL_THREAD; - } else { - gen = bar->b_generation; - do { - ret = _pthread_cond_wait( - &bar->b_cond, &bar->b_lock); - /* test generation to avoid bogus wakeup */ - } while (ret == 0 && gen == bar->b_generation); - } - _pthread_mutex_unlock(&bar->b_lock); - return (ret); -} diff --git a/lib/libkse/thread/thr_barrierattr.c b/lib/libkse/thread/thr_barrierattr.c deleted file mode 100644 index 66411dc..0000000 --- a/lib/libkse/thread/thr_barrierattr.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2003 David Xu <davidxu@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_barrierattr_destroy, pthread_barrierattr_destroy); -__weak_reference(_pthread_barrierattr_init, pthread_barrierattr_init); -__weak_reference(_pthread_barrierattr_setpshared, - pthread_barrierattr_setpshared); -__weak_reference(_pthread_barrierattr_getpshared, - pthread_barrierattr_getpshared); - -int -_pthread_barrierattr_destroy(pthread_barrierattr_t *attr) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - free(*attr); - return (0); -} - -int -_pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, - int *pshared) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - *pshared = (*attr)->pshared; - return (0); -} - -int -_pthread_barrierattr_init(pthread_barrierattr_t *attr) -{ - - if (attr == NULL) - return (EINVAL); - - if ((*attr = malloc(sizeof(struct pthread_barrierattr))) == NULL) - return (ENOMEM); - - (*attr)->pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) -{ - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - - (*attr)->pshared = pshared; - return (0); -} diff --git a/lib/libkse/thread/thr_cancel.c b/lib/libkse/thread/thr_cancel.c deleted file mode 100644 index 7cffec4..0000000 --- a/lib/libkse/thread/thr_cancel.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * $FreeBSD$ - */ -#include "namespace.h" -#include <sys/errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_cancel, pthread_cancel); -__weak_reference(_pthread_setcancelstate, pthread_setcancelstate); -__weak_reference(_pthread_setcanceltype, pthread_setcanceltype); -__weak_reference(_pthread_testcancel, pthread_testcancel); - -static inline int -checkcancel(struct pthread *curthread) -{ - if ((curthread->cancelflags & THR_CANCELLING) != 0) { - /* - * It is possible for this thread to be swapped out - * while performing cancellation; do not allow it - * to be cancelled again. - */ - if ((curthread->flags & THR_FLAGS_EXITING) != 0) { - /* - * This may happen once, but after this, it - * shouldn't happen again. - */ - curthread->cancelflags &= ~THR_CANCELLING; - return (0); - } - if ((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) { - curthread->cancelflags &= ~THR_CANCELLING; - return (1); - } - } - return (0); -} - -static inline void -testcancel(struct pthread *curthread) -{ - if (checkcancel(curthread) != 0) { - /* Unlock before exiting: */ - THR_THREAD_UNLOCK(curthread, curthread); - - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } -} - -int -_pthread_cancel(pthread_t pthread) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *joinee = NULL; - struct kse_mailbox *kmbx = NULL; - int ret; - - if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) { - /* - * Take the thread's lock while we change the cancel flags. - */ - THR_THREAD_LOCK(curthread, pthread); - THR_SCHED_LOCK(curthread, pthread); - if (pthread->flags & THR_FLAGS_EXITING) { - THR_SCHED_UNLOCK(curthread, pthread); - THR_THREAD_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - return (ESRCH); - } - if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) || - (((pthread->cancelflags & THR_AT_CANCEL_POINT) == 0) && - ((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0))) - /* Just mark it for cancellation: */ - pthread->cancelflags |= THR_CANCELLING; - else { - /* - * Check if we need to kick it back into the - * run queue: - */ - switch (pthread->state) { - case PS_RUNNING: - /* No need to resume: */ - pthread->cancelflags |= THR_CANCELLING; - break; - - case PS_LOCKWAIT: - /* - * These can't be removed from the queue. - * Just mark it as cancelling and tell it - * to yield once it leaves the critical - * region. - */ - pthread->cancelflags |= THR_CANCELLING; - pthread->critical_yield = 1; - break; - - case PS_SLEEP_WAIT: - case PS_SIGSUSPEND: - case PS_SIGWAIT: - /* Interrupt and resume: */ - pthread->interrupted = 1; - pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - break; - - case PS_JOIN: - /* Disconnect the thread from the joinee: */ - joinee = pthread->join_status.thread; - pthread->join_status.thread = NULL; - pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - if ((joinee != NULL) && - (pthread->kseg == joinee->kseg)) { - /* Remove the joiner from the joinee. */ - joinee->joiner = NULL; - joinee = NULL; - } - break; - - case PS_SUSPENDED: - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - /* - * Threads in these states may be in queues. - * In order to preserve queue integrity, the - * cancelled thread must remove itself from the - * queue. Mark the thread as interrupted and - * needing cancellation, and set the state to - * running. When the thread resumes, it will - * remove itself from the queue and call the - * cancellation completion routine. - */ - pthread->interrupted = 1; - pthread->cancelflags |= THR_CANCEL_NEEDED; - kmbx = _thr_setrunnable_unlocked(pthread); - pthread->continuation = - _thr_finish_cancellation; - break; - - case PS_DEAD: - case PS_DEADLOCK: - case PS_STATE_MAX: - /* Ignore - only here to silence -Wall: */ - break; - } - if ((pthread->cancelflags & THR_AT_CANCEL_POINT) && - (pthread->blocked != 0 || - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); - } - - /* - * Release the thread's lock and remove the - * reference: - */ - THR_SCHED_UNLOCK(curthread, pthread); - THR_THREAD_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - - if ((joinee != NULL) && - (_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) { - /* Remove the joiner from the joinee. */ - THR_SCHED_LOCK(curthread, joinee); - joinee->joiner = NULL; - THR_SCHED_UNLOCK(curthread, joinee); - _thr_ref_delete(curthread, joinee); - } - } - return (ret); -} - -int -_pthread_setcancelstate(int state, int *oldstate) -{ - struct pthread *curthread = _get_curthread(); - int ostate; - int ret; - int need_exit = 0; - - /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); - - ostate = curthread->cancelflags & PTHREAD_CANCEL_DISABLE; - - switch (state) { - case PTHREAD_CANCEL_ENABLE: - curthread->cancelflags &= ~PTHREAD_CANCEL_DISABLE; - if ((curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0) - need_exit = checkcancel(curthread); - ret = 0; - break; - case PTHREAD_CANCEL_DISABLE: - curthread->cancelflags |= PTHREAD_CANCEL_DISABLE; - ret = 0; - break; - default: - ret = EINVAL; - } - - THR_THREAD_UNLOCK(curthread, curthread); - if (need_exit != 0) { - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } - if (ret == 0 && oldstate != NULL) - *oldstate = ostate; - - return (ret); -} - -int -_pthread_setcanceltype(int type, int *oldtype) -{ - struct pthread *curthread = _get_curthread(); - int otype; - int ret; - int need_exit = 0; - - /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); - - otype = curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS; - switch (type) { - case PTHREAD_CANCEL_ASYNCHRONOUS: - curthread->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS; - need_exit = checkcancel(curthread); - ret = 0; - break; - case PTHREAD_CANCEL_DEFERRED: - curthread->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS; - ret = 0; - break; - default: - ret = EINVAL; - } - - THR_THREAD_UNLOCK(curthread, curthread); - if (need_exit != 0) { - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } - if (ret == 0 && oldtype != NULL) - *oldtype = otype; - - return (ret); -} - -void -_pthread_testcancel(void) -{ - struct pthread *curthread = _get_curthread(); - - THR_THREAD_LOCK(curthread, curthread); - testcancel(curthread); - THR_THREAD_UNLOCK(curthread, curthread); -} - -void -_thr_cancel_enter(struct pthread *thread) -{ - /* Look for a cancellation before we block: */ - THR_THREAD_LOCK(thread, thread); - testcancel(thread); - thread->cancelflags |= THR_AT_CANCEL_POINT; - THR_THREAD_UNLOCK(thread, thread); -} - -void -_thr_cancel_leave(struct pthread *thread, int check) -{ - THR_THREAD_LOCK(thread, thread); - thread->cancelflags &= ~THR_AT_CANCEL_POINT; - /* Look for a cancellation after we unblock: */ - if (check) - testcancel(thread); - THR_THREAD_UNLOCK(thread, thread); -} - -void -_thr_finish_cancellation(void *arg __unused) -{ - struct pthread *curthread = _get_curthread(); - - curthread->continuation = NULL; - curthread->interrupted = 0; - - THR_THREAD_LOCK(curthread, curthread); - if ((curthread->cancelflags & THR_CANCEL_NEEDED) != 0) { - curthread->cancelflags &= ~THR_CANCEL_NEEDED; - THR_THREAD_UNLOCK(curthread, curthread); - _thr_exit_cleanup(); - _pthread_exit(PTHREAD_CANCELED); - } - THR_THREAD_UNLOCK(curthread, curthread); -} diff --git a/lib/libkse/thread/thr_clean.c b/lib/libkse/thread/thr_clean.c deleted file mode 100644 index 37323fd..0000000 --- a/lib/libkse/thread/thr_clean.c +++ /dev/null @@ -1,74 +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. 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 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$ - */ - -#include "namespace.h" -#include <signal.h> -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_cleanup_push, pthread_cleanup_push); -__weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop); - -void -_pthread_cleanup_push(void (*routine) (void *), void *routine_arg) -{ - struct pthread *curthread = _get_curthread(); - struct pthread_cleanup *new; - - if ((new = (struct pthread_cleanup *) - malloc(sizeof(struct pthread_cleanup))) != NULL) { - new->routine = routine; - new->routine_arg = routine_arg; - new->onstack = 0; - new->next = curthread->cleanup; - - curthread->cleanup = new; - } -} - -void -_pthread_cleanup_pop(int execute) -{ - struct pthread *curthread = _get_curthread(); - struct pthread_cleanup *old; - - if ((old = curthread->cleanup) != NULL) { - curthread->cleanup = old->next; - if (execute) { - old->routine(old->routine_arg); - } - if (old->onstack == 0) - free(old); - } -} diff --git a/lib/libkse/thread/thr_close.c b/lib/libkse/thread/thr_close.c deleted file mode 100644 index a76dab1..0000000 --- a/lib/libkse/thread/thr_close.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __close(int fd); - -__weak_reference(__close, close); - -int -__close(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_close(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_concurrency.c b/lib/libkse/thread/thr_concurrency.c deleted file mode 100644 index 8b1cf56..0000000 --- a/lib/libkse/thread/thr_concurrency.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (c) 2003 Sergey Osokin <osa@freebsd.org.ru>. - * 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. 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 THE AUTHORS 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/sysctl.h> -#include "un-namespace.h" - -#include "thr_private.h" - -/*#define DEBUG_CONCURRENCY */ -#ifdef DEBUG_CONCURRENCY -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -static int level = 0; - -__weak_reference(_pthread_getconcurrency, pthread_getconcurrency); -__weak_reference(_pthread_setconcurrency, pthread_setconcurrency); - -int -_pthread_getconcurrency(void) -{ - return (level); -} - -int -_pthread_setconcurrency(int new_level) -{ - int ret; - - if (new_level < 0) - ret = EINVAL; - else if (new_level == level) - ret = 0; - else if (new_level == 0) { - level = 0; - ret = 0; - } else if ((_kse_isthreaded() == 0) && (_kse_setthreaded(1) != 0)) { - DBG_MSG("Can't enable threading.\n"); - ret = EAGAIN; - } else { - ret = _thr_setconcurrency(new_level); - if (ret == 0) - level = new_level; - } - return (ret); -} - -int -_thr_setconcurrency(int new_level) -{ - struct pthread *curthread; - struct kse *newkse, *kse; - kse_critical_t crit; - int kse_count; - int i; - int ret; - - /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. - */ - if (_kse_isthreaded() == 0 && _kse_setthreaded(1)) - return (EAGAIN); - - ret = 0; - curthread = _get_curthread(); - /* Race condition, but so what. */ - kse_count = _kse_initial->k_kseg->kg_ksecount; - if (new_level > kse_count) { - for (i = kse_count; i < new_level; i++) { - newkse = _kse_alloc(curthread, 0); - if (newkse == NULL) { - DBG_MSG("Can't alloc new KSE.\n"); - ret = EAGAIN; - break; - } - newkse->k_kseg = _kse_initial->k_kseg; - newkse->k_schedq = _kse_initial->k_schedq; - newkse->k_curthread = NULL; - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); - TAILQ_INSERT_TAIL(&newkse->k_kseg->kg_kseq, - newkse, k_kgqe); - newkse->k_kseg->kg_ksecount++; - newkse->k_flags |= KF_STARTED; - KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg); - if (kse_create(&newkse->k_kcb->kcb_kmbx, 0) != 0) { - KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); - TAILQ_REMOVE(&newkse->k_kseg->kg_kseq, - newkse, k_kgqe); - newkse->k_kseg->kg_ksecount--; - KSE_SCHED_UNLOCK(curthread->kse, - newkse->k_kseg); - _kse_critical_leave(crit); - _kse_free(curthread, newkse); - DBG_MSG("kse_create syscall failed.\n"); - ret = EAGAIN; - break; - } else { - _kse_critical_leave(crit); - } - } - } else if (new_level < kse_count) { - kse_count = 0; - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, _kse_initial->k_kseg); - /* Count the number of active KSEs */ - TAILQ_FOREACH(kse, &_kse_initial->k_kseg->kg_kseq, k_kgqe) { - if ((kse->k_flags & KF_TERMINATED) == 0) - kse_count++; - } - /* Reduce the number of active KSEs appropriately. */ - kse = TAILQ_FIRST(&_kse_initial->k_kseg->kg_kseq); - while ((kse != NULL) && (kse_count > new_level)) { - if ((kse != _kse_initial) && - ((kse->k_flags & KF_TERMINATED) == 0)) { - kse->k_flags |= KF_TERMINATED; - kse_count--; - /* Wakup the KSE in case it is idle. */ - kse_wakeup(&kse->k_kcb->kcb_kmbx); - } - kse = TAILQ_NEXT(kse, k_kgqe); - } - KSE_SCHED_UNLOCK(curthread->kse, _kse_initial->k_kseg); - _kse_critical_leave(crit); - } - return (ret); -} - -int -_thr_setmaxconcurrency(void) -{ - int vcpu; - size_t len; - int ret; - - len = sizeof(vcpu); - ret = sysctlbyname("kern.threads.virtual_cpu", &vcpu, &len, NULL, 0); - if (ret == 0 && vcpu > 0) - ret = _thr_setconcurrency(vcpu); - return (ret); -} - diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c deleted file mode 100644 index 3f0b8a9..0000000 --- a/lib/libkse/thread/thr_cond.c +++ /dev/null @@ -1,836 +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. 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 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -#define THR_IN_CONDQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0) -#define THR_CONDQ_SET(thr) (thr)->sflags |= THR_FLAGS_IN_SYNCQ -#define THR_CONDQ_CLEAR(thr) (thr)->sflags &= ~THR_FLAGS_IN_SYNCQ - -/* - * Prototypes - */ -static inline struct pthread *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); -static void cond_wait_backout(void *); -static inline void check_continuation(struct pthread *, - struct pthread_cond *, pthread_mutex_t *); - -int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); -int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime); - -/* - * Double underscore versions are cancellation points. Single underscore - * versions are not and are provided for libc internal usage (which - * shouldn't introduce cancellation points). - */ -__weak_reference(__pthread_cond_wait, pthread_cond_wait); -__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait); - -__weak_reference(_pthread_cond_init, pthread_cond_init); -__weak_reference(_pthread_cond_destroy, pthread_cond_destroy); -__weak_reference(_pthread_cond_signal, pthread_cond_signal); -__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast); - - -int -_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) -{ - enum pthread_cond_type type; - pthread_cond_t pcond; - int flags; - int rval = 0; - - if (cond == NULL) - rval = EINVAL; - else { - /* - * Check if a pointer to a condition variable attribute - * structure was passed by the caller: - */ - if (cond_attr != NULL && *cond_attr != NULL) { - /* Default to a fast condition variable: */ - type = (*cond_attr)->c_type; - flags = (*cond_attr)->c_flags; - } else { - /* Default to a fast condition variable: */ - type = COND_TYPE_FAST; - flags = 0; - } - - /* Process according to condition variable type: */ - switch (type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Nothing to do here. */ - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Check for no errors: */ - if (rval == 0) { - if ((pcond = (pthread_cond_t) - malloc(sizeof(struct pthread_cond))) == NULL) { - rval = ENOMEM; - } else if (_lock_init(&pcond->c_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) { - free(pcond); - rval = ENOMEM; - } else { - /* - * Initialise the condition variable - * structure: - */ - TAILQ_INIT(&pcond->c_queue); - pcond->c_flags = COND_FLAGS_INITED; - pcond->c_type = type; - pcond->c_mutex = NULL; - pcond->c_seqno = 0; - *cond = pcond; - } - } - } - /* Return the completion status: */ - return (rval); -} - -int -_pthread_cond_destroy(pthread_cond_t *cond) -{ - struct pthread_cond *cv; - struct pthread *curthread = _get_curthread(); - int rval = 0; - - if (cond == NULL || *cond == NULL) - rval = EINVAL; - else { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* - * NULL the caller's pointer now that the condition - * variable has been destroyed: - */ - cv = *cond; - *cond = NULL; - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cv->c_lock); - - /* Free the cond lock structure: */ - _lock_destroy(&cv->c_lock); - - /* - * Free the memory allocated for the condition - * variable structure: - */ - free(cv); - - } - /* Return the completion status: */ - return (rval); -} - -int -_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int rval = 0; - int done = 0; - int mutex_locked = 1; - int seqno; - - if (cond == NULL) - return (EINVAL); - - /* - * If the condition variable is statically initialized, - * perform the dynamic initialization: - */ - if (*cond == NULL && - (rval = _pthread_cond_init(cond, NULL)) != 0) - return (rval); - - if (!_kse_isthreaded()) - _kse_setthreaded(1); - - /* - * Enter a loop waiting for a condition signal or broadcast - * to wake up this thread. A loop is needed in case the waiting - * thread is interrupted by a signal to execute a signal handler. - * It is not (currently) possible to remain in the waiting queue - * while running a handler. Instead, the thread is interrupted - * and backed out of the waiting queue prior to executing the - * signal handler. - */ - - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - seqno = (*cond)->c_seqno; - do { - /* - * If the condvar was statically allocated, properly - * initialize the tail queue. - */ - if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*cond)->c_queue); - (*cond)->c_flags |= COND_FLAGS_INITED; - } - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - if ((mutex == NULL) || (((*cond)->c_mutex != NULL) && - ((*cond)->c_mutex != *mutex))) { - /* Return invalid argument error: */ - rval = EINVAL; - } else { - /* Reset the timeout and interrupted flags: */ - curthread->timeout = 0; - curthread->interrupted = 0; - - /* - * Queue the running thread for the condition - * variable: - */ - cond_queue_enq(*cond, curthread); - - /* Wait forever: */ - curthread->wakeup_time.tv_sec = -1; - - /* Unlock the mutex: */ - if (mutex_locked && - ((rval = _mutex_cv_unlock(mutex)) != 0)) { - /* - * Cannot unlock the mutex, so remove - * the running thread from the condition - * variable queue: - */ - cond_queue_remove(*cond, curthread); - } - else { - /* Remember the mutex: */ - (*cond)->c_mutex = *mutex; - - /* - * Don't unlock the mutex the next - * time through the loop (if the - * thread has to be requeued after - * handling a signal). - */ - mutex_locked = 0; - - /* - * This thread is active and is in a - * critical region (holding the cv - * lock); we should be able to safely - * set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - THR_SET_STATE(curthread, PS_COND_WAIT); - - /* Remember the CV: */ - curthread->data.cond = *cond; - curthread->sigbackout = cond_wait_backout; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the CV structure: */ - THR_LOCK_RELEASE(curthread, - &(*cond)->c_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - /* - * XXX - This really isn't a good check - * since there can be more than one - * thread waiting on the CV. Signals - * sent to threads waiting on mutexes - * or CVs should really be deferred - * until the threads are no longer - * waiting, but POSIX says that signals - * should be sent "as soon as possible". - */ - done = (seqno != (*cond)->c_seqno); - if (done && !THR_IN_CONDQ(curthread)) { - /* - * The thread is dequeued, so - * it is safe to clear these. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - check_continuation(curthread, - NULL, mutex); - return (_mutex_cv_lock(mutex)); - } - - /* Relock the CV structure: */ - THR_LOCK_ACQUIRE(curthread, - &(*cond)->c_lock); - - /* - * Clear these after taking the lock to - * prevent a race condition where a - * signal can arrive before dequeueing - * the thread. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - done = (seqno != (*cond)->c_seqno); - - if (THR_IN_CONDQ(curthread)) { - cond_queue_remove(*cond, - curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - } - } - } - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - check_continuation(curthread, *cond, - mutex_locked ? NULL : mutex); - } while ((done == 0) && (rval == 0)); - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - - if (mutex_locked == 0) - _mutex_cv_lock(mutex); - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_wait, _thr_cond_wait); - -int -__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _pthread_cond_wait(cond, mutex); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, - const struct timespec * abstime) -{ - struct pthread *curthread = _get_curthread(); - int rval = 0; - int done = 0; - int mutex_locked = 1; - int seqno; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - - if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || - abstime->tv_nsec >= 1000000000) - return (EINVAL); - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - if (*cond == NULL && (rval = _pthread_cond_init(cond, NULL)) != 0) - return (rval); - - if (!_kse_isthreaded()) - _kse_setthreaded(1); - - /* - * Enter a loop waiting for a condition signal or broadcast - * to wake up this thread. A loop is needed in case the waiting - * thread is interrupted by a signal to execute a signal handler. - * It is not (currently) possible to remain in the waiting queue - * while running a handler. Instead, the thread is interrupted - * and backed out of the waiting queue prior to executing the - * signal handler. - */ - - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - seqno = (*cond)->c_seqno; - do { - /* - * If the condvar was statically allocated, properly - * initialize the tail queue. - */ - if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*cond)->c_queue); - (*cond)->c_flags |= COND_FLAGS_INITED; - } - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - if ((mutex == NULL) || (((*cond)->c_mutex != NULL) && - ((*cond)->c_mutex != *mutex))) { - /* Return invalid argument error: */ - rval = EINVAL; - } else { - /* Reset the timeout and interrupted flags: */ - curthread->timeout = 0; - curthread->interrupted = 0; - - /* - * Queue the running thread for the condition - * variable: - */ - cond_queue_enq(*cond, curthread); - - /* Unlock the mutex: */ - if (mutex_locked && - ((rval = _mutex_cv_unlock(mutex)) != 0)) { - /* - * Cannot unlock the mutex; remove the - * running thread from the condition - * variable queue: - */ - cond_queue_remove(*cond, curthread); - } else { - /* Remember the mutex: */ - (*cond)->c_mutex = *mutex; - - /* - * Don't unlock the mutex the next - * time through the loop (if the - * thread has to be requeued after - * handling a signal). - */ - mutex_locked = 0; - - /* - * This thread is active and is in a - * critical region (holding the cv - * lock); we should be able to safely - * set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - THR_SET_STATE(curthread, PS_COND_WAIT); - - /* Remember the CV: */ - curthread->data.cond = *cond; - curthread->sigbackout = cond_wait_backout; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the CV structure: */ - THR_LOCK_RELEASE(curthread, - &(*cond)->c_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - /* - * XXX - This really isn't a good check - * since there can be more than one - * thread waiting on the CV. Signals - * sent to threads waiting on mutexes - * or CVs should really be deferred - * until the threads are no longer - * waiting, but POSIX says that signals - * should be sent "as soon as possible". - */ - done = (seqno != (*cond)->c_seqno); - if (done && !THR_IN_CONDQ(curthread)) { - /* - * The thread is dequeued, so - * it is safe to clear these. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - check_continuation(curthread, - NULL, mutex); - return (_mutex_cv_lock(mutex)); - } - - /* Relock the CV structure: */ - THR_LOCK_ACQUIRE(curthread, - &(*cond)->c_lock); - - /* - * Clear these after taking the lock to - * prevent a race condition where a - * signal can arrive before dequeueing - * the thread. - */ - curthread->data.cond = NULL; - curthread->sigbackout = NULL; - - done = (seqno != (*cond)->c_seqno); - - if (THR_IN_CONDQ(curthread)) { - cond_queue_remove(*cond, - curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - } - - if (curthread->timeout != 0) { - /* The wait timedout. */ - rval = ETIMEDOUT; - } - } - } - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - check_continuation(curthread, *cond, - mutex_locked ? NULL : mutex); - } while ((done == 0) && (rval == 0)); - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - - if (mutex_locked == 0) - _mutex_cv_lock(mutex); - - /* Return the completion status: */ - return (rval); -} - -int -__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _pthread_cond_timedwait(cond, mutex, abstime); - _thr_cancel_leave(curthread, 1); - return (ret); -} - - -int -_pthread_cond_signal(pthread_cond_t * cond) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *pthread; - struct kse_mailbox *kmbx; - int rval = 0; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - if (cond == NULL) - rval = EINVAL; - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Increment the sequence number: */ - (*cond)->c_seqno++; - - /* - * Wakeups have to be done with the CV lock held; - * otherwise there is a race condition where the - * thread can timeout, run on another KSE, and enter - * another blocking state (including blocking on a CV). - */ - if ((pthread = TAILQ_FIRST(&(*cond)->c_queue)) - != NULL) { - THR_SCHED_LOCK(curthread, pthread); - cond_queue_remove(*cond, pthread); - pthread->sigbackout = NULL; - if ((pthread->kseg == curthread->kseg) && - (pthread->active_priority > - curthread->active_priority)) - curthread->critical_yield = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&(*cond)->c_queue)) - (*cond)->c_mutex = NULL; - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - } - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_signal, _thr_cond_signal); - -int -_pthread_cond_broadcast(pthread_cond_t * cond) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *pthread; - struct kse_mailbox *kmbx; - int rval = 0; - - THR_ASSERT(curthread->locklevel == 0, - "cv_timedwait: locklevel is not zero!"); - if (cond == NULL) - rval = EINVAL; - /* - * If the condition variable is statically initialized, perform dynamic - * initialization. - */ - else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock); - - /* Process according to condition variable type: */ - switch ((*cond)->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Increment the sequence number: */ - (*cond)->c_seqno++; - - /* - * Enter a loop to bring all threads off the - * condition queue: - */ - while ((pthread = TAILQ_FIRST(&(*cond)->c_queue)) - != NULL) { - THR_SCHED_LOCK(curthread, pthread); - cond_queue_remove(*cond, pthread); - pthread->sigbackout = NULL; - if ((pthread->kseg == curthread->kseg) && - (pthread->active_priority > - curthread->active_priority)) - curthread->critical_yield = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* There are no more waiting threads: */ - (*cond)->c_mutex = NULL; - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - rval = EINVAL; - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &(*cond)->c_lock); - } - - /* Return the completion status: */ - return (rval); -} - -__strong_reference(_pthread_cond_broadcast, _thr_cond_broadcast); - -static inline void -check_continuation(struct pthread *curthread, struct pthread_cond *cond, - pthread_mutex_t *mutex) -{ - if ((curthread->interrupted != 0) && - (curthread->continuation != NULL)) { - if (cond != NULL) - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cond->c_lock); - /* - * Note that even though this thread may have been - * canceled, POSIX requires that the mutex be - * reaquired prior to cancellation. - */ - if (mutex != NULL) - _mutex_cv_lock(mutex); - curthread->continuation((void *) curthread); - PANIC("continuation returned in pthread_cond_wait.\n"); - } -} - -static void -cond_wait_backout(void *arg) -{ - struct pthread *curthread = (struct pthread *)arg; - pthread_cond_t cond; - - cond = curthread->data.cond; - if (cond != NULL) { - /* Lock the condition variable structure: */ - THR_LOCK_ACQUIRE(curthread, &cond->c_lock); - - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - cond_queue_remove(cond, curthread); - - /* Check for no more waiters: */ - if (TAILQ_EMPTY(&cond->c_queue)) - cond->c_mutex = NULL; - break; - - default: - break; - } - - /* Unlock the condition variable structure: */ - THR_LOCK_RELEASE(curthread, &cond->c_lock); - } - /* No need to call this again. */ - curthread->sigbackout = NULL; -} - -/* - * Dequeue a waiting thread from the head of a condition queue in - * descending priority order. - */ -static inline struct pthread * -cond_queue_deq(pthread_cond_t cond) -{ - struct pthread *pthread; - - while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) { - TAILQ_REMOVE(&cond->c_queue, pthread, sqe); - THR_CONDQ_CLEAR(pthread); - if ((pthread->timeout == 0) && (pthread->interrupted == 0)) - /* - * Only exit the loop when we find a thread - * that hasn't timed out or been canceled; - * those threads are already running and don't - * need their run state changed. - */ - break; - } - - return (pthread); -} - -/* - * Remove a waiting thread from a condition queue in descending priority - * order. - */ -static inline void -cond_queue_remove(pthread_cond_t cond, struct pthread *pthread) -{ - /* - * Because pthread_cond_timedwait() can timeout as well - * as be signaled by another thread, it is necessary to - * guard against removing the thread from the queue if - * it isn't in the queue. - */ - if (THR_IN_CONDQ(pthread)) { - TAILQ_REMOVE(&cond->c_queue, pthread, sqe); - THR_CONDQ_CLEAR(pthread); - } -} - -/* - * Enqueue a waiting thread to a condition queue in descending priority - * order. - */ -static inline void -cond_queue_enq(pthread_cond_t cond, struct pthread *pthread) -{ - struct pthread *tid = TAILQ_LAST(&cond->c_queue, cond_head); - - THR_ASSERT(!THR_IN_SYNCQ(pthread), - "cond_queue_enq: thread already queued!"); - - /* - * For the common case of all threads having equal priority, - * we perform a quick check against the priority of the thread - * at the tail of the queue. - */ - if ((tid == NULL) || (pthread->active_priority <= tid->active_priority)) - TAILQ_INSERT_TAIL(&cond->c_queue, pthread, sqe); - else { - tid = TAILQ_FIRST(&cond->c_queue); - while (pthread->active_priority <= tid->active_priority) - tid = TAILQ_NEXT(tid, sqe); - TAILQ_INSERT_BEFORE(tid, pthread, sqe); - } - THR_CONDQ_SET(pthread); - pthread->data.cond = cond; -} diff --git a/lib/libkse/thread/thr_condattr_destroy.c b/lib/libkse/thread/thr_condattr_destroy.c deleted file mode 100644 index 67af37f..0000000 --- a/lib/libkse/thread/thr_condattr_destroy.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_condattr_destroy, pthread_condattr_destroy); - -int -_pthread_condattr_destroy(pthread_condattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_condattr_init.c b/lib/libkse/thread/thr_condattr_init.c deleted file mode 100644 index e67364d..0000000 --- a/lib/libkse/thread/thr_condattr_init.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_condattr_init, pthread_condattr_init); - -int -_pthread_condattr_init(pthread_condattr_t *attr) -{ - int ret; - pthread_condattr_t pattr; - - if ((pattr = (pthread_condattr_t) - malloc(sizeof(struct pthread_cond_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_condattr_default, - sizeof(struct pthread_cond_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_condattr_pshared.c b/lib/libkse/thread/thr_condattr_pshared.c deleted file mode 100644 index 79e1d60..0000000 --- a/lib/libkse/thread/thr_condattr_pshared.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2005 David Xu <davidxu@freebsd.org> - * 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 unmodified, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$ - * - */ - -#include <errno.h> -#include "thr_private.h" - -int _pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared); -int _pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); - -__weak_reference(_pthread_condattr_getpshared, pthread_condattr_getpshared); -__weak_reference(_pthread_condattr_setpshared, pthread_condattr_setpshared); - -int -_pthread_condattr_getpshared(const pthread_condattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libkse/thread/thr_connect.c b/lib/libkse/thread/thr_connect.c deleted file mode 100644 index 523a1d3..0000000 --- a/lib/libkse/thread/thr_connect.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. - * 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. 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 THE AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/socket.h> -#include <pthread.h> -#include "thr_private.h" - -int __connect(int fd, const struct sockaddr *name, socklen_t namelen); - -__weak_reference(__connect, connect); - -int -__connect(int fd, const struct sockaddr *name, socklen_t namelen) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - ret = __sys_connect(fd, name, namelen); - _thr_cancel_leave(curthread, ret == -1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_creat.c b/lib/libkse/thread/thr_creat.c deleted file mode 100644 index 63c8067..0000000 --- a/lib/libkse/thread/thr_creat.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -extern int __creat(const char *, mode_t); - -int ___creat(const char *path, mode_t mode); - -__weak_reference(___creat, creat); - -int -___creat(const char *path, mode_t mode) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __creat(path, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c deleted file mode 100644 index de1719c..0000000 --- a/lib/libkse/thread/thr_create.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com> - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <stddef.h> -#include <sys/time.h> -#include <machine/reg.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" -#include "libc_private.h" - -static void free_thread(struct pthread *curthread, struct pthread *thread); -static int create_stack(struct pthread_attr *pattr); -static void free_stack(struct pthread_attr *pattr); -static void thread_start(struct pthread *curthread, - void *(*start_routine) (void *), void *arg); - -__weak_reference(_pthread_create, pthread_create); - -/* - * Some notes on new thread creation and first time initializion - * to enable multi-threading. - * - * There are basically two things that need to be done. - * - * 1) The internal library variables must be initialized. - * 2) Upcalls need to be enabled to allow multiple threads - * to be run. - * - * The first may be done as a result of other pthread functions - * being called. When _thr_initial is null, _libpthread_init is - * called to initialize the internal variables; this also creates - * or sets the initial thread. It'd be nice to automatically - * have _libpthread_init called on program execution so we don't - * have to have checks throughout the library. - * - * The second part is only triggered by the creation of the first - * thread (other than the initial/main thread). If the thread - * being created is a scope system thread, then a new KSE/KSEG - * pair needs to be allocated. Also, if upcalls haven't been - * enabled on the initial thread's KSE, they must be now that - * there is more than one thread; this could be delayed until - * the initial KSEG has more than one thread. - */ -int -_pthread_create(pthread_t * thread, const pthread_attr_t * attr, - void *(*start_routine) (void *), void *arg) -{ - struct pthread *curthread, *new_thread; - struct kse *kse = NULL; - struct kse_group *kseg = NULL; - kse_critical_t crit; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. - */ - if (_kse_isthreaded() == 0 && _kse_setthreaded(1)) { - return (EAGAIN); - } - curthread = _get_curthread(); - - /* - * Allocate memory for the thread structure. - * Some functions use malloc, so don't put it - * in a critical region. - */ - if ((new_thread = _thr_alloc(curthread)) == NULL) { - /* Insufficient memory to create a thread: */ - ret = EAGAIN; - } else { - /* Check if default thread attributes are required: */ - if (attr == NULL || *attr == NULL) - /* Use the default thread attributes: */ - new_thread->attr = _pthread_attr_default; - else { - new_thread->attr = *(*attr); - if ((*attr)->sched_inherit == PTHREAD_INHERIT_SCHED) { - /* inherit scheduling contention scop */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - /* - * scheduling policy and scheduling parameters will be - * inherited in following code. - */ - } - } - if (_thread_scope_system > 0) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else if ((_thread_scope_system < 0) - && (thread != &_thr_sig_daemon)) - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - if (create_stack(&new_thread->attr) != 0) { - /* Insufficient memory to create a stack: */ - ret = EAGAIN; - _thr_free(curthread, new_thread); - } - else if (((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - (((kse = _kse_alloc(curthread, 1)) == NULL) - || ((kseg = _kseg_alloc(curthread)) == NULL))) { - /* Insufficient memory to create a new KSE/KSEG: */ - ret = EAGAIN; - if (kse != NULL) { - kse->k_kcb->kcb_kmbx.km_flags |= KMF_DONE; - _kse_free(curthread, kse); - } - free_stack(&new_thread->attr); - _thr_free(curthread, new_thread); - } - else { - if (kseg != NULL) { - /* Add the KSE to the KSEG's list of KSEs. */ - TAILQ_INSERT_HEAD(&kseg->kg_kseq, kse, k_kgqe); - kseg->kg_ksecount = 1; - kse->k_kseg = kseg; - kse->k_schedq = &kseg->kg_schedq; - } - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - new_thread->magic = THR_MAGIC; - - new_thread->slice_usec = -1; - new_thread->start_routine = start_routine; - new_thread->arg = arg; - new_thread->cancelflags = PTHREAD_CANCEL_ENABLE | - PTHREAD_CANCEL_DEFERRED; - - /* No thread is wanting to join to this one: */ - new_thread->joiner = NULL; - - /* - * Initialize the machine context. - * Enter a critical region to get consistent context. - */ - crit = _kse_critical_enter(); - THR_GETCONTEXT(&new_thread->tcb->tcb_tmbx.tm_context); - /* Initialize the thread for signals: */ - new_thread->sigmask = curthread->sigmask; - _kse_critical_leave(crit); - - new_thread->tcb->tcb_tmbx.tm_udata = new_thread; - new_thread->tcb->tcb_tmbx.tm_context.uc_sigmask = - new_thread->sigmask; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - new_thread->attr.stacksize_attr; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - new_thread->attr.stackaddr_attr; - makecontext(&new_thread->tcb->tcb_tmbx.tm_context, - (void (*)(void))thread_start, 3, new_thread, - start_routine, arg); - /* - * Check if this thread is to inherit the scheduling - * attributes from its parent: - */ - if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { - /* - * Copy the scheduling attributes. - * Lock the scheduling lock to get consistent - * scheduling parameters. - */ - THR_SCHED_LOCK(curthread, curthread); - new_thread->base_priority = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.prio = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.sched_policy = - curthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - } 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->active_priority = new_thread->base_priority; - new_thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&new_thread->mutexq); - - /* Initialise hooks in the thread structure: */ - new_thread->specific = NULL; - new_thread->specific_data_count = 0; - new_thread->cleanup = NULL; - new_thread->flags = 0; - new_thread->tlflags = 0; - new_thread->sigbackout = NULL; - new_thread->continuation = NULL; - new_thread->wakeup_time.tv_sec = -1; - new_thread->lock_switch = 0; - sigemptyset(&new_thread->sigpend); - new_thread->check_pending = 0; - new_thread->locklevel = 0; - new_thread->rdlock_count = 0; - new_thread->sigstk.ss_sp = 0; - new_thread->sigstk.ss_size = 0; - new_thread->sigstk.ss_flags = SS_DISABLE; - new_thread->oldsigmask = NULL; - - if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { - new_thread->state = PS_SUSPENDED; - new_thread->flags = THR_FLAGS_SUSPENDED; - } - else - new_thread->state = PS_RUNNING; - - /* - * System scope threads have their own kse and - * kseg. Process scope threads are all hung - * off the main process kseg. - */ - if ((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) { - new_thread->kseg = _kse_initial->k_kseg; - new_thread->kse = _kse_initial; - } - else { - kse->k_curthread = NULL; - kse->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - new_thread->kse = kse; - new_thread->kseg = kse->k_kseg; - kse->k_kcb->kcb_kmbx.km_udata = kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - } - - /* - * Schedule the new thread starting a new KSEG/KSE - * pair if necessary. - */ - ret = _thr_schedule_add(curthread, new_thread); - if (ret != 0) - free_thread(curthread, new_thread); - else { - /* Return a pointer to the thread structure: */ - (*thread) = new_thread; - } - } - } - - /* Return the status: */ - return (ret); -} - -static void -free_thread(struct pthread *curthread, struct pthread *thread) -{ - free_stack(&thread->attr); - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* Free the KSE and KSEG. */ - _kseg_free(thread->kseg); - _kse_free(curthread, thread->kse); - } - _thr_free(curthread, thread); -} - -static int -create_stack(struct pthread_attr *pattr) -{ - int ret; - - /* Check if a stack was specified in the thread attributes: */ - if ((pattr->stackaddr_attr) != NULL) { - pattr->guardsize_attr = 0; - pattr->flags |= THR_STACK_USER; - ret = 0; - } - else - ret = _thr_stack_alloc(pattr); - return (ret); -} - -static void -free_stack(struct pthread_attr *pattr) -{ - struct kse *curkse; - kse_critical_t crit; - - if ((pattr->flags & THR_STACK_USER) == 0) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Stack routines don't use malloc/free. */ - _thr_stack_free(pattr); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} - -static void -thread_start(struct pthread *curthread __unused, void *(*start_routine) (void *), - void *arg) -{ - /* Run the current thread's start routine with argument: */ - _pthread_exit(start_routine(arg)); - - /* This point should never be reached. */ - PANIC("Thread has resumed after exit"); -} diff --git a/lib/libkse/thread/thr_detach.c b/lib/libkse/thread/thr_detach.c deleted file mode 100644 index adb6861..0000000 --- a/lib/libkse/thread/thr_detach.c +++ /dev/null @@ -1,116 +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. 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 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$ - */ -#include "namespace.h" -#include <sys/types.h> -#include <machine/atomic.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_detach, pthread_detach); - -int -_pthread_detach(pthread_t pthread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - struct pthread *joiner; - int rval = 0; - - /* Check for invalid calling parameters: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) - /* Return an invalid argument error: */ - rval = EINVAL; - - else if ((rval = _thr_ref_add(curthread, pthread, - /*include dead*/1)) != 0) { - /* Return an error: */ - } - - /* Check if the thread is already detached: */ - else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - /* Return an error: */ - _thr_ref_delete(curthread, pthread); - rval = EINVAL; - } else { - /* Lock the detached thread: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Flag the thread as detached: */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Retrieve any joining thread and remove it: */ - joiner = pthread->joiner; - if ((joiner != NULL) && (joiner->kseg == pthread->kseg)) { - /* - * We already own the scheduler lock for the joiner. - * Take advantage of that and make the joiner runnable. - */ - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - joiner = NULL; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* See if there is a thread waiting in pthread_join(): */ - if ((joiner != NULL) && - (_thr_ref_add(curthread, joiner, 0) == 0)) { - /* Lock the joiner before fiddling with it. */ - THR_SCHED_LOCK(curthread, joiner); - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - THR_SCHED_UNLOCK(curthread, joiner); - _thr_ref_delete(curthread, joiner); - } - _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (rval); -} diff --git a/lib/libkse/thread/thr_equal.c b/lib/libkse/thread/thr_equal.c deleted file mode 100644 index ab6f884..0000000 --- a/lib/libkse/thread/thr_equal.c +++ /dev/null @@ -1,44 +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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_equal, pthread_equal); - -int -_pthread_equal(pthread_t t1, pthread_t t2) -{ - /* Compare the two thread pointers: */ - return (t1 == t2); -} diff --git a/lib/libkse/thread/thr_execve.c b/lib/libkse/thread/thr_execve.c deleted file mode 100644 index 2e700fc..0000000 --- a/lib/libkse/thread/thr_execve.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2004 Daniel Eischen <deischen@freebsd.org> - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <unistd.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_execve, execve); - -int -_execve(const char *name, char *const *argv, char *const *envp) -{ - struct kse_execve_args args; - struct pthread *curthread = _get_curthread(); - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - ret = __sys_execve(name, argv, envp); - else { - /* - * When exec'ing, set the kernel signal mask to the thread's - * signal mask to satisfy POSIX requirements. - */ - args.sigmask = curthread->sigmask; - args.sigpend = curthread->sigpend; - args.path = (char *)name; - args.argv = (char **)argv; - args.envp = (char **)envp; - args.reserved = NULL; - ret = kse_thr_interrupt(NULL, KSE_INTR_EXECVE, (long)&args); - } - - return (ret); -} diff --git a/lib/libkse/thread/thr_exit.c b/lib/libkse/thread/thr_exit.c deleted file mode 100644 index 7c61821..0000000 --- a/lib/libkse/thread/thr_exit.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -void _pthread_exit(void *status); - -__weak_reference(_pthread_exit, pthread_exit); - -void -_thr_exit(const char *fname, int lineno, const char *msg) -{ - - /* Write an error message to the standard error file descriptor: */ - _thread_printf(2, - "Fatal error '%s' at line %d in file %s (errno = %d)\n", - msg, lineno, fname, errno); - - abort(); -} - -/* - * Only called when a thread is cancelled. It may be more useful - * to call it from pthread_exit() if other ways of asynchronous or - * abnormal thread termination can be found. - */ -void -_thr_exit_cleanup(void) -{ - struct pthread *curthread = _get_curthread(); - - /* - * POSIX states that cancellation/termination of a thread should - * not release any visible resources (such as mutexes) and that - * it is the applications responsibility. Resources that are - * internal to the threads library, including file and fd locks, - * are not visible to the application and need to be released. - */ - /* Unlock all private mutexes: */ - _mutex_unlock_private(curthread); - - /* - * This still isn't quite correct because we don't account - * for held spinlocks (see libc/stdlib/malloc.c). - */ -} - -void -_pthread_exit(void *status) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - struct kse *curkse; - - /* Check if this thread is already in the process of exiting: */ - if ((curthread->flags & THR_FLAGS_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!", curthread); - PANIC(msg); - } - - /* - * Flag this thread as exiting. Threads should now be prevented - * from joining to this thread. - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->flags |= THR_FLAGS_EXITING; - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * To avoid signal-lost problem, if signals had already been - * delivered to us, handle it. we have already set EXITING flag - * so no new signals should be delivered to us. - * XXX this is not enough if signal was delivered just before - * thread called sigprocmask and masked it! in this case, we - * might have to re-post the signal by kill() if the signal - * is targeting process (not for a specified thread). - * Kernel has same signal-lost problem, a signal may be delivered - * to a thread which is on the way to call sigprocmask or thr_exit()! - */ - if (curthread->check_pending) - _thr_sig_check_pending(curthread); - /* Save the return value: */ - curthread->ret = status; - while (curthread->cleanup != NULL) { - _pthread_cleanup_pop(1); - } - if (curthread->attr.cleanup_attr != NULL) { - curthread->attr.cleanup_attr(curthread->attr.arg_attr); - } - /* Check if there is thread specific data: */ - if (curthread->specific != NULL) { - /* Run the thread-specific data destructors: */ - _thread_cleanupspecific(); - } - if (!_kse_isthreaded()) - exit(0); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Use thread_list_lock */ - _thread_active_threads--; - if ((_thread_scope_system <= 0 && _thread_active_threads == 1) || - (_thread_scope_system > 0 && _thread_active_threads == 0)) { - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - exit(0); - /* Never reach! */ - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - /* This thread will never be re-scheduled. */ - KSE_LOCK(curkse); - THR_SET_STATE(curthread, PS_DEAD); - _thr_sched_switch_unlocked(curthread); - /* Never reach! */ - - /* This point should not be reached. */ - PANIC("Dead thread has resumed"); -} diff --git a/lib/libkse/thread/thr_fcntl.c b/lib/libkse/thread/thr_fcntl.c deleted file mode 100644 index e739633..0000000 --- a/lib/libkse/thread/thr_fcntl.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <stdarg.h> -#include <fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __fcntl(int fd, int cmd,...); -extern int __fcntl_compat(int fd, int cmd,...); - -__weak_reference(__fcntl, fcntl); - -int -__fcntl(int fd, int cmd,...) -{ - struct pthread *curthread = _get_curthread(); - int ret, check = 1; - va_list ap; - - _thr_cancel_enter(curthread); - - va_start(ap, cmd); - switch (cmd) { - case F_DUPFD: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - check = (ret == -1); - break; - case F_SETFD: - case F_SETFL: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - break; - case F_GETFD: - case F_GETFL: - ret = __sys_fcntl(fd, cmd); - break; - default: - ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); - } - va_end(ap); - - _thr_cancel_leave(curthread, check); - - return (ret); -} diff --git a/lib/libkse/thread/thr_find_thread.c b/lib/libkse/thread/thr_find_thread.c deleted file mode 100644 index e146e97..0000000 --- a/lib/libkse/thread/thr_find_thread.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* - * Find a thread in the linked list of active threads and add a reference - * to it. Threads with positive reference counts will not be deallocated - * until all references are released. - */ -int -_thr_ref_add(struct pthread *curthread, struct pthread *thread, - int include_dead) -{ - kse_critical_t crit; - struct pthread *pthread; - struct kse *curkse; - - if (thread == NULL) - /* Invalid thread: */ - return (EINVAL); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - pthread = _thr_hash_find(thread); - if (pthread) { - if ((include_dead == 0) && - ((pthread->state == PS_DEAD) || - ((pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)))) - pthread = NULL; - else { - pthread->refcount++; - if (curthread != NULL) - curthread->critical_count++; - } - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Return zero if the thread exists: */ - return ((pthread != NULL) ? 0 : ESRCH); -} - -void -_thr_ref_delete(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - if (thread != NULL) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->refcount--; - if (curthread != NULL) - curthread->critical_count--; - if ((thread->refcount == 0) && - (thread->tlflags & TLFLAGS_GC_SAFE) != 0) - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} diff --git a/lib/libkse/thread/thr_fork.c b/lib/libkse/thread/thr_fork.c deleted file mode 100644 index 659bcb3..0000000 --- a/lib/libkse/thread/thr_fork.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <pthread.h> -#include <spinlock.h> -#include <sys/signalvar.h> -#include "un-namespace.h" - -#include "libc_private.h" -#include "thr_private.h" - -pid_t _fork(void); - -__weak_reference(_fork, fork); - -pid_t -_fork(void) -{ - sigset_t sigset, oldset; - struct pthread *curthread; - struct pthread_atfork *af; - pid_t ret; - int errsave; - - curthread = _get_curthread(); - - if (!_kse_isthreaded()) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - ret = __sys_fork(); - if (ret == 0) - /* Child */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - else - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - return (ret); - } - - /* - * Masks all signals until we reach a safe point in - * _kse_single_thread, and the signal masks will be - * restored in that function, for M:N thread, all - * signals were already masked in kernel atomically, - * we only need to do this for bound thread. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - } - - _pthread_mutex_lock(&_thr_atfork_mutex); - - /* Run down atfork prepare handlers. */ - TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { - if (af->prepare != NULL) - af->prepare(); - } - - /* Fork a new process: */ - if (_kse_isthreaded() != 0) { - _malloc_prefork(); - } - if ((ret = __sys_fork()) == 0) { - /* Child process */ - errsave = errno; - - /* Kernel signal mask is restored in _kse_single_thread */ - _kse_single_thread(curthread); - - /* Run down atfork child handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->child != NULL) - af->child(); - } - _thr_mutex_reinit(&_thr_atfork_mutex); - } else { - if (_kse_isthreaded() != 0) { - _malloc_postfork(); - } - errsave = errno; - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - } - /* Run down atfork parent handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->parent != NULL) - af->parent(); - } - _pthread_mutex_unlock(&_thr_atfork_mutex); - } - errno = errsave; - - /* Return the process ID: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_fsync.c b/lib/libkse/thread/thr_fsync.c deleted file mode 100644 index 7cf52aa..0000000 --- a/lib/libkse/thread/thr_fsync.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __fsync(int fd); - -__weak_reference(__fsync, fsync); - -int -__fsync(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_fsync(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_getprio.c b/lib/libkse/thread/thr_getprio.c deleted file mode 100644 index 0672d90..0000000 --- a/lib/libkse/thread/thr_getprio.c +++ /dev/null @@ -1,57 +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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -__weak_reference(_pthread_getprio, pthread_getprio); - -int -_pthread_getprio(pthread_t pthread) -{ - int policy, ret; - struct sched_param param; - - if ((ret = _pthread_getschedparam(pthread, &policy, ¶m)) == 0) - ret = param.sched_priority; - else { - /* Invalid thread: */ - errno = ret; - ret = -1; - } - - /* Return the thread priority or an error status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_getschedparam.c b/lib/libkse/thread/thr_getschedparam.c deleted file mode 100644 index 0cb1cc5..0000000 --- a/lib/libkse/thread/thr_getschedparam.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_getschedparam, pthread_getschedparam); - -int -_pthread_getschedparam(pthread_t pthread, int *policy, - struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int ret, tmp; - - if ((param == NULL) || (policy == NULL)) - /* Return an invalid argument error: */ - ret = EINVAL; - else if (pthread == curthread) { - /* - * Avoid searching the thread list when it is the current - * thread. - */ - THR_SCHED_LOCK(curthread, curthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - *policy = tmp; - ret = 0; - } - /* Find the thread in the list of active threads. */ - else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - THR_SCHED_LOCK(curthread, pthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - *policy = tmp; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_info.c b/lib/libkse/thread/thr_info.c deleted file mode 100644 index ac0e750..0000000 --- a/lib/libkse/thread/thr_info.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <errno.h> -#include "un-namespace.h" -#include "thr_private.h" - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof(arr) / sizeof(arr[0])) -#endif - -static void dump_thread(int fd, pthread_t pthread, int long_version); -void _pthread_set_name_np(pthread_t thread, char *name); - -__weak_reference(_pthread_set_name_np, pthread_set_name_np); - -struct s_thread_info { - enum pthread_state state; - const char *name; -}; - -/* Static variables: */ -static const struct s_thread_info thread_info[] = { - {PS_RUNNING , "Running"}, - {PS_LOCKWAIT , "Waiting on an internal lock"}, - {PS_MUTEX_WAIT , "Waiting on a mutex"}, - {PS_COND_WAIT , "Waiting on a condition variable"}, - {PS_SLEEP_WAIT , "Sleeping"}, - {PS_SIGSUSPEND , "Suspended, waiting for a signal"}, - {PS_SIGWAIT , "Waiting for a signal"}, - {PS_JOIN , "Waiting to join"}, - {PS_SUSPENDED , "Suspended"}, - {PS_DEAD , "Dead"}, - {PS_DEADLOCK , "Deadlocked"}, - {PS_STATE_MAX , "Not a real state!"} -}; - -void -_thread_dump_info(void) -{ - char s[512], tempfile[128]; - pthread_t pthread; - int fd, i; - - for (i = 0; i < 100000; i++) { - snprintf(tempfile, sizeof(tempfile), "/tmp/pthread.dump.%u.%i", - getpid(), i); - /* Open the dump file for append and create it if necessary: */ - if ((fd = __sys_open(tempfile, O_RDWR | O_CREAT | O_EXCL, - 0666)) < 0) { - /* Can't open the dump file. */ - if (errno == EEXIST) - continue; - /* - * We only need to continue in case of - * EEXIT error. Most other error - * codes means that we will fail all - * the times. - */ - return; - } else { - break; - } - } - if (i==100000) { - /* all 100000 possibilities are in use :( */ - return; - } else { - /* Dump the active threads. */ - strcpy(s, "\n\n========\nACTIVE THREADS\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Enter a loop to report each thread in the global list: */ - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread->state != PS_DEAD) - dump_thread(fd, pthread, /*long_verson*/ 1); - } - - /* - * Dump the ready threads. - * XXX - We can't easily do this because the run queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nREADY THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - - /* - * Dump the waiting threads. - * XXX - We can't easily do this because the wait queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nWAITING THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Close the dump file. */ - __sys_close(fd); - } -} - -static void -dump_thread(int fd, pthread_t pthread, int long_version) -{ - struct pthread *curthread = _get_curthread(); - char s[512]; - int i; - - /* Find the state: */ - for (i = 0; i < (int)NELEMENTS(thread_info) - 1; i++) - if (thread_info[i].state == pthread->state) - break; - - /* Output a record for the thread: */ - snprintf(s, sizeof(s), - "--------------------\n" - "Thread %p (%s), scope %s, prio %3d, blocked %s, state %s [%s:%d]\n", - pthread, (pthread->name == NULL) ? "" : pthread->name, - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM ? "system" : "process", - pthread->active_priority, (pthread->blocked != 0) ? "yes" : "no", - thread_info[i].name, pthread->fname, pthread->lineno); - __sys_write(fd, s, strlen(s)); - - if (long_version != 0) { - /* Check if this is the running thread: */ - if (pthread == curthread) { - /* Output a record for the running thread: */ - strcpy(s, "This is the running thread\n"); - __sys_write(fd, s, strlen(s)); - } - /* Check if this is the initial thread: */ - if (pthread == _thr_initial) { - /* Output a record for the initial thread: */ - strcpy(s, "This is the initial thread\n"); - __sys_write(fd, s, strlen(s)); - } - - /* Process according to thread state: */ - switch (pthread->state) { - case PS_SIGWAIT: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - - snprintf(s, sizeof(s), "waitset (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->data.sigwait->waitset->__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - /* - * Trap other states that are not explicitly - * coded to dump information: - */ - default: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - } - } -} - -/* Set the thread name for debug: */ -void -_pthread_set_name_np(pthread_t thread, char *name) -{ - struct pthread *curthread = _get_curthread(); - char *new_name; - char *prev_name; - int ret; - - new_name = strdup(name); - /* Add a reference to the target thread. */ - if (_thr_ref_add(curthread, thread, 0) != 0) { - free(new_name); - ret = ESRCH; - } - else { - THR_THREAD_LOCK(curthread, thread); - prev_name = thread->name; - thread->name = new_name; - THR_THREAD_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (prev_name != NULL) { - /* Free space for previous name. */ - free(prev_name); - } - ret = 0; - } -#if 0 - /* XXX - Should return error code. */ - return (ret); -#endif -} diff --git a/lib/libkse/thread/thr_init.c b/lib/libkse/thread/thr_init.c deleted file mode 100644 index 6c41961..0000000 --- a/lib/libkse/thread/thr_init.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (c) 1995-1998 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. 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 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$ - */ - -/* Allocate space for global thread variables here: */ -#define GLOBAL_PTHREAD_PRIVATE - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <machine/reg.h> - -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/event.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <sys/time.h> -#include <sys/ttycom.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <paths.h> -#include <pthread.h> -#include <pthread_np.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#include "libc_private.h" -#include "thr_private.h" - -int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int __pthread_mutex_lock(pthread_mutex_t *); -int __pthread_mutex_trylock(pthread_mutex_t *); -void _thread_init_hack(void); -extern int _thread_state_running; - -static void init_private(void); -static void init_main_thread(struct pthread *thread); - -/* - * All weak references used within libc should be in this table. - * This is so that static libraries will work. - */ -static void *references[] = { - &_accept, - &_bind, - &_close, - &_connect, - &_dup, - &_dup2, - &_execve, - &_fcntl, - &_flock, - &_flockfile, - &_fstat, - &_fstatfs, - &_fsync, - &_funlockfile, - &_getdirentries, - &_getlogin, - &_getpeername, - &_getsockname, - &_getsockopt, - &_ioctl, - &_kevent, - &_listen, - &_nanosleep, - &_open, - &_pthread_getspecific, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_mutex_destroy, - &_pthread_mutex_init, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock, - &_pthread_mutexattr_init, - &_pthread_mutexattr_destroy, - &_pthread_mutexattr_settype, - &_pthread_once, - &_pthread_setspecific, - &_read, - &_readv, - &_recvfrom, - &_recvmsg, - &_select, - &_sendmsg, - &_sendto, - &_setsockopt, - &_sigaction, - &_sigprocmask, - &_sigsuspend, - &_socket, - &_socketpair, - &_thread_init_hack, - &_wait4, - &_write, - &_writev -}; - -/* - * These are needed when linking statically. All references within - * libgcc (and in the future libc) to these routines are weak, but - * if they are not (strongly) referenced by the application or other - * libraries, then the actual functions will not be loaded. - */ -static void *libgcc_references[] = { - &_pthread_once, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_getspecific, - &_pthread_setspecific, - &_pthread_mutex_init, - &_pthread_mutex_destroy, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock -}; - -#define DUAL_ENTRY(entry) \ - (pthread_func_t)entry, (pthread_func_t)entry - -static pthread_func_t jmp_table[][2] = { - {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ - {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ - {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_getinheritsched)}, /* PJT_ATTR_GETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_getschedparam)}, /* PJT_ATTR_GETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_getschedpolicy)}, /* PJT_ATTR_GETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_getscope)}, /* PJT_ATTR_GETSCOPE */ - {DUAL_ENTRY(_pthread_attr_getstackaddr)}, /* PJT_ATTR_GETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_getstacksize)}, /* PJT_ATTR_GETSTACKSIZE */ - {DUAL_ENTRY(_pthread_attr_init)}, /* PJT_ATTR_INIT */ - {DUAL_ENTRY(_pthread_attr_setdetachstate)}, /* PJT_ATTR_SETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_setguardsize)}, /* PJT_ATTR_SETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_setinheritsched)}, /* PJT_ATTR_SETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_setschedparam)}, /* PJT_ATTR_SETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_setschedpolicy)}, /* PJT_ATTR_SETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_setscope)}, /* PJT_ATTR_SETSCOPE */ - {DUAL_ENTRY(_pthread_attr_setstackaddr)}, /* PJT_ATTR_SETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_setstacksize)}, /* PJT_ATTR_SETSTACKSIZE */ - {DUAL_ENTRY(_pthread_cancel)}, /* PJT_CANCEL */ - {DUAL_ENTRY(_pthread_cleanup_pop)}, /* PJT_CLEANUP_POP */ - {DUAL_ENTRY(_pthread_cleanup_push)}, /* PJT_CLEANUP_PUSH */ - {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ - {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ - {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ - {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ - {DUAL_ENTRY(_pthread_cond_timedwait)}, /* PJT_COND_TIMEDWAIT */ - {(pthread_func_t)__pthread_cond_wait, - (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ - {DUAL_ENTRY(_pthread_detach)}, /* PJT_DETACH */ - {DUAL_ENTRY(_pthread_equal)}, /* PJT_EQUAL */ - {DUAL_ENTRY(_pthread_exit)}, /* PJT_EXIT */ - {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ - {DUAL_ENTRY(_pthread_join)}, /* PJT_JOIN */ - {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ - {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ - {DUAL_ENTRY(_pthread_kill)}, /* PJT_KILL */ - {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ - {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ - {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ - {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ - {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ - {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ - {(pthread_func_t)__pthread_mutex_lock, - (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ - {(pthread_func_t)__pthread_mutex_trylock, - (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ - {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ - {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ - {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ - {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ - {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ - {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ - {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ - {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ - {DUAL_ENTRY(_pthread_setcancelstate)}, /* PJT_SETCANCELSTATE */ - {DUAL_ENTRY(_pthread_setcanceltype)}, /* PJT_SETCANCELTYPE */ - {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ - {DUAL_ENTRY(_pthread_sigmask)}, /* PJT_SIGMASK */ - {DUAL_ENTRY(_pthread_testcancel)} /* PJT_TESTCANCEL */ -}; - -static int init_once = 0; - -/* - * Threaded process initialization. - * - * This is only called under two conditions: - * - * 1) Some thread routines have detected that the library hasn't yet - * been initialized (_thr_initial == NULL && curthread == NULL), or - * - * 2) An explicit call to reinitialize after a fork (indicated - * by curthread != NULL) - */ -void -_libpthread_init(struct pthread *curthread) -{ - int fd; - - /* Check if this function has already been called: */ - if ((_thr_initial != NULL) && (curthread == NULL)) - /* Only initialize the threaded application once. */ - return; - - /* - * Make gcc quiescent about {,libgcc_}references not being - * referenced: - */ - if ((references[0] == NULL) || (libgcc_references[0] == NULL)) - PANIC("Failed loading mandatory references in _thread_init"); - - /* Pull debug symbols in for static binary */ - _thread_state_running = PS_RUNNING; - - /* - * Check the size of the jump table to make sure it is preset - * with the correct number of entries. - */ - if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) - PANIC("Thread jump table not properly initialized"); - memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); - - /* - * Check for the special case of this process running as - * or in place of init as pid = 1: - */ - if ((_thr_pid = getpid()) == 1) { - /* - * Setup a new session for this process which is - * assumed to be running as root. - */ - if (setsid() == -1) - PANIC("Can't set session ID"); - if (revoke(_PATH_CONSOLE) != 0) - PANIC("Can't revoke console"); - if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) - PANIC("Can't open console"); - if (setlogin("root") == -1) - PANIC("Can't set login to root"); - if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) - PANIC("Can't set controlling terminal"); - } - - /* Initialize pthread private data. */ - init_private(); - _kse_init(); - - /* Initialize the initial kse and kseg. */ - _kse_initial = _kse_alloc(NULL, _thread_scope_system > 0); - if (_kse_initial == NULL) - PANIC("Can't allocate initial kse."); - _kse_initial->k_kseg = _kseg_alloc(NULL); - if (_kse_initial->k_kseg == NULL) - PANIC("Can't allocate initial kseg."); - _kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - _kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq; - - TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe); - _kse_initial->k_kseg->kg_ksecount = 1; - - /* Set the initial thread. */ - if (curthread == NULL) { - /* Create and initialize the initial thread. */ - curthread = _thr_alloc(NULL); - if (curthread == NULL) - PANIC("Can't allocate initial thread"); - _thr_initial = curthread; - init_main_thread(curthread); - } else { - /* - * The initial thread is the current thread. It is - * assumed that the current thread is already initialized - * because it is left over from a fork(). - */ - _thr_initial = curthread; - } - _kse_initial->k_kseg->kg_threadcount = 0; - _thr_initial->kse = _kse_initial; - _thr_initial->kseg = _kse_initial->k_kseg; - _thr_initial->active = 1; - - /* - * Add the thread to the thread list and to the KSEG's thread - * queue. - */ - THR_LIST_ADD(_thr_initial); - KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial); - - /* Setup the KSE/thread specific data for the current KSE/thread. */ - _thr_initial->kse->k_curthread = _thr_initial; - _kcb_set(_thr_initial->kse->k_kcb); - _tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb); - _thr_initial->kse->k_flags |= KF_INITIALIZED; - - _thr_signal_init(); - _kse_critical_leave(&_thr_initial->tcb->tcb_tmbx); - /* - * activate threaded mode as soon as possible if we are - * being debugged - */ - if (_libkse_debug) - _kse_setthreaded(1); -} - -/* - * This function and pthread_create() do a lot of the same things. - * It'd be nice to consolidate the common stuff in one place. - */ -static void -init_main_thread(struct pthread *thread) -{ - /* Setup the thread attributes. */ - thread->attr = _pthread_attr_default; - thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - /* - * Set up the thread stack. - * - * Create a red zone below the main stack. All other stacks - * are constrained to a maximum size by the parameters - * passed to mmap(), but this stack is only limited by - * resource limits, so this stack needs an explicitly mapped - * red zone to protect the thread stack that is just beyond. - */ - if (mmap((void *)((uintptr_t)_usrstack - _thr_stack_initial - - _thr_guard_default), _thr_guard_default, 0, MAP_ANON, - -1, 0) == MAP_FAILED) - PANIC("Cannot allocate red zone for initial thread"); - - /* - * Mark the stack as an application supplied stack so that it - * isn't deallocated. - * - * XXX - I'm not sure it would hurt anything to deallocate - * the main thread stack because deallocation doesn't - * actually free() it; it just puts it in the free - * stack queue for later reuse. - */ - thread->attr.stackaddr_attr = (void *)((uintptr_t)_usrstack - - _thr_stack_initial); - thread->attr.stacksize_attr = _thr_stack_initial; - thread->attr.guardsize_attr = _thr_guard_default; - thread->attr.flags |= THR_STACK_USER; - - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - thread->magic = THR_MAGIC; - - thread->slice_usec = -1; - thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; - thread->name = strdup("initial thread"); - - /* Initialize the thread for signals: */ - SIGEMPTYSET(thread->sigmask); - - /* - * Set up the thread mailbox. The threads saved context - * is also in the mailbox. - */ - thread->tcb->tcb_tmbx.tm_udata = thread; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - thread->attr.stacksize_attr; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - thread->attr.stackaddr_attr; - - /* Default the priority of the initial thread: */ - thread->base_priority = THR_DEFAULT_PRIORITY; - thread->active_priority = THR_DEFAULT_PRIORITY; - thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&thread->mutexq); - - /* Initialize hooks in the thread structure: */ - thread->specific = NULL; - thread->cleanup = NULL; - thread->flags = 0; - thread->sigbackout = NULL; - thread->continuation = NULL; - - thread->state = PS_RUNNING; - thread->uniqueid = 0; -} - -static void -init_private(void) -{ - struct clockinfo clockinfo; - size_t len; - int mib[2]; - - /* - * Avoid reinitializing some things if they don't need to be, - * e.g. after a fork(). - */ - if (init_once == 0) { - /* Find the stack top */ - mib[0] = CTL_KERN; - mib[1] = KERN_USRSTACK; - len = sizeof (_usrstack); - if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) - PANIC("Cannot get kern.usrstack from sysctl"); - /* 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_usec = 1000000 / clockinfo.stathz; - else - _clock_res_usec = CLOCK_RES_USEC; - - _thr_page_size = getpagesize(); - _thr_guard_default = _thr_page_size; - if (sizeof(void *) == 8) { - _thr_stack_default = THR_STACK64_DEFAULT; - _thr_stack_initial = THR_STACK64_INITIAL; - } - else { - _thr_stack_default = THR_STACK32_DEFAULT; - _thr_stack_initial = THR_STACK32_INITIAL; - } - _pthread_attr_default.guardsize_attr = _thr_guard_default; - _pthread_attr_default.stacksize_attr = _thr_stack_default; - TAILQ_INIT(&_thr_atfork_list); - init_once = 1; /* Don't do this again. */ - } else { - /* - * Destroy the locks before creating them. We don't - * know what state they are in so it is better to just - * recreate them. - */ - _lock_destroy(&_thread_signal_lock); - _lock_destroy(&_mutex_static_lock); - _lock_destroy(&_rwlock_static_lock); - _lock_destroy(&_keytable_lock); - } - - /* Initialize everything else. */ - TAILQ_INIT(&_thread_list); - TAILQ_INIT(&_thread_gc_list); - _pthread_mutex_init(&_thr_atfork_mutex, NULL); - - /* - * Initialize the lock for temporary installation of signal - * handlers (to support sigwait() semantics) and for the - * process signal mask and pending signal sets. - */ - if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize _thread_signal_lock"); - if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize mutex static init lock"); - if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize rwlock static init lock"); - if (_lock_init(&_keytable_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize thread specific keytable lock"); - _thr_spinlock_init(); - - /* Clear pending signals and get the process signal mask. */ - SIGEMPTYSET(_thr_proc_sigpending); - - /* Are we in M:N mode (default) or 1:1 mode? */ -#ifdef SYSTEM_SCOPE_ONLY - _thread_scope_system = 1; -#else - if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL) - _thread_scope_system = 1; - else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) - _thread_scope_system = -1; -#endif - if (getenv("LIBPTHREAD_DEBUG") != NULL) - _thr_debug_flags |= DBG_INFO_DUMP; - - /* - * _thread_list_lock and _kse_count are initialized - * by _kse_init() - */ -} diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c deleted file mode 100644 index 3a95ed2..0000000 --- a/lib/libkse/thread/thr_join.c +++ /dev/null @@ -1,162 +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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_join, pthread_join); - -int -_pthread_join(pthread_t pthread, void **thread_return) -{ - struct pthread *curthread = _get_curthread(); - void *tmp; - kse_critical_t crit; - int ret = 0; - - _thr_cancel_enter(curthread); - - /* Check if the caller has specified an invalid thread: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) { - /* Invalid thread: */ - _thr_cancel_leave(curthread, 1); - return (EINVAL); - } - - /* Check if the caller has specified itself: */ - if (pthread == curthread) { - /* Avoid a deadlock condition: */ - _thr_cancel_leave(curthread, 1); - return (EDEADLK); - } - - /* - * Find the thread in the list of active threads or in the - * list of dead threads: - */ - if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) { - /* Return an error: */ - _thr_cancel_leave(curthread, 1); - return (ESRCH); - } - - THR_SCHED_LOCK(curthread, pthread); - /* Check if this thread has been detached: */ - if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - THR_SCHED_UNLOCK(curthread, pthread); - /* Remove the reference and return an error: */ - _thr_ref_delete(curthread, pthread); - ret = EINVAL; - } else { - /* Lock the target thread while checking its state. */ - if (pthread->state == PS_DEAD) { - /* Return the thread's return value: */ - tmp = pthread->ret; - - /* Detach the thread. */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Unlock the thread. */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Remove the thread from the list of active - * threads and add it to the GC list. - */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - THR_LIST_REMOVE(pthread); - THR_GCLIST_ADD(pthread); - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Remove the reference. */ - _thr_ref_delete(curthread, pthread); - if (thread_return != NULL) - *thread_return = tmp; - } - else if (pthread->joiner != NULL) { - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - /* Multiple joiners are not supported. */ - ret = ENOTSUP; - } - else { - /* Set the running thread to be the joiner: */ - pthread->joiner = curthread; - - /* Keep track of which thread we're joining to: */ - curthread->join_status.thread = pthread; - - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - THR_SCHED_LOCK(curthread, curthread); - while (curthread->join_status.thread == pthread) { - THR_SET_STATE(curthread, PS_JOIN); - THR_SCHED_UNLOCK(curthread, curthread); - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - THR_SCHED_LOCK(curthread, curthread); - } - THR_SCHED_UNLOCK(curthread, curthread); - - if ((curthread->cancelflags & THR_CANCELLING) && - !(curthread->cancelflags & PTHREAD_CANCEL_DISABLE)) { - if (_thr_ref_add(curthread, pthread, 1) == 0) { - THR_SCHED_LOCK(curthread, pthread); - pthread->joiner = NULL; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - } - _pthread_exit(PTHREAD_CANCELED); - } - - /* - * The thread return value and error are set by the - * thread we're joining to when it exits or detaches: - */ - ret = curthread->join_status.error; - if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->join_status.ret; - } - } - _thr_cancel_leave(curthread, 1); - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c deleted file mode 100644 index 6563ca7..0000000 --- a/lib/libkse/thread/thr_kern.c +++ /dev/null @@ -1,2573 +0,0 @@ -/* - * Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (C) 2002 Jonathon Mini <mini@freebsd.org> - * Copyright (c) 1995-1998 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 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. - * - */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/kse.h> -#include <sys/ptrace.h> -#include <sys/signalvar.h> -#include <sys/queue.h> -#include <machine/atomic.h> -#include <machine/sigframe.h> - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <ucontext.h> -#include <unistd.h> - -#include "atomic_ops.h" -#include "thr_private.h" -#include "libc_private.h" -#ifdef NOTYET -#include "spinlock.h" -#endif - -/* #define DEBUG_THREAD_KERN */ -#ifdef DEBUG_THREAD_KERN -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Define a high water mark for the maximum number of threads that - * will be cached. Once this level is reached, any extra threads - * will be free()'d. - */ -#define MAX_CACHED_THREADS 100 -/* - * Define high water marks for the maximum number of KSEs and KSE groups - * that will be cached. Because we support 1:1 threading, there could have - * same number of KSEs and KSE groups as threads. Once these levels are - * reached, any extra KSE and KSE groups will be free()'d. - */ -#define MAX_CACHED_KSES ((_thread_scope_system <= 0) ? 50 : 100) -#define MAX_CACHED_KSEGS ((_thread_scope_system <= 0) ? 50 : 100) - -#define KSE_SET_MBOX(kse, thrd) \ - (kse)->k_kcb->kcb_kmbx.km_curthread = &(thrd)->tcb->tcb_tmbx - -#define KSE_SET_EXITED(kse) (kse)->k_flags |= KF_EXITED - -/* - * Macros for manipulating the run queues. The priority queue - * routines use the thread's pqe link and also handle the setting - * and clearing of the thread's THR_FLAGS_IN_RUNQ flag. - */ -#define KSE_RUNQ_INSERT_HEAD(kse, thrd) \ - _pq_insert_head(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_INSERT_TAIL(kse, thrd) \ - _pq_insert_tail(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_REMOVE(kse, thrd) \ - _pq_remove(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_FIRST(kse) \ - ((_libkse_debug == 0) ? \ - _pq_first(&(kse)->k_schedq->sq_runq) : \ - _pq_first_debug(&(kse)->k_schedq->sq_runq)) - -#define KSE_RUNQ_THREADS(kse) ((kse)->k_schedq->sq_runq.pq_threads) - -#define THR_NEED_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) != 0 || \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -#define THR_NEED_ASYNC_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) == 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -/* - * We've got to keep track of everything that is allocated, not only - * to have a speedy free list, but also so they can be deallocated - * after a fork(). - */ -static TAILQ_HEAD(, kse) active_kseq; -static TAILQ_HEAD(, kse) free_kseq; -static TAILQ_HEAD(, kse_group) free_kse_groupq; -static TAILQ_HEAD(, kse_group) active_kse_groupq; -static TAILQ_HEAD(, kse_group) gc_ksegq; -static struct lock kse_lock; /* also used for kseg queue */ -static int free_kse_count = 0; -static int free_kseg_count = 0; -static TAILQ_HEAD(, pthread) free_threadq; -static struct lock thread_lock; -static int free_thread_count = 0; -static int inited = 0; -static int active_kse_count = 0; -static int active_kseg_count = 0; -static u_int64_t next_uniqueid = 1; - -LIST_HEAD(thread_hash_head, pthread); -#define THREAD_HASH_QUEUES 127 -static struct thread_hash_head thr_hashtable[THREAD_HASH_QUEUES]; -#define THREAD_HASH(thrd) ((unsigned long)thrd % THREAD_HASH_QUEUES) - -/* Lock for thread tcb constructor/destructor */ -static pthread_mutex_t _tcb_mutex; - -#ifdef DEBUG_THREAD_KERN -static void dump_queues(struct kse *curkse); -#endif -static void kse_check_completed(struct kse *kse); -static void kse_check_waitq(struct kse *kse); -static void kse_fini(struct kse *curkse); -static void kse_reinit(struct kse *kse, int sys_scope); -static void kse_sched_multi(struct kse_mailbox *kmbx); -static void kse_sched_single(struct kse_mailbox *kmbx); -static void kse_switchout_thread(struct kse *kse, struct pthread *thread); -static void kse_wait(struct kse *kse, struct pthread *td_wait, int sigseq); -static void kse_free_unlocked(struct kse *kse); -static void kse_destroy(struct kse *kse); -static void kseg_free_unlocked(struct kse_group *kseg); -static void kseg_init(struct kse_group *kseg); -static void kseg_reinit(struct kse_group *kseg); -static void kseg_destroy(struct kse_group *kseg); -static void kse_waitq_insert(struct pthread *thread); -static void kse_wakeup_multi(struct kse *curkse); -static struct kse_mailbox *kse_wakeup_one(struct pthread *thread); -static void thr_cleanup(struct kse *kse, struct pthread *curthread); -static void thr_link(struct pthread *thread); -static void thr_resume_wrapper(int sig, siginfo_t *, ucontext_t *); -static void thr_resume_check(struct pthread *curthread, ucontext_t *ucp); -static int thr_timedout(struct pthread *thread, struct timespec *curtime); -static void thr_unlink(struct pthread *thread); -static void thr_destroy(struct pthread *curthread, struct pthread *thread); -static void thread_gc(struct pthread *thread); -static void kse_gc(struct pthread *thread); -static void kseg_gc(struct pthread *thread); - -static __inline void -thr_accounting(struct pthread *thread) -{ - if ((thread->slice_usec != -1) && - (thread->slice_usec <= TIMESLICE_USEC) && - (thread->attr.sched_policy != SCHED_FIFO)) { - thread->slice_usec += (thread->tcb->tcb_tmbx.tm_uticks - + thread->tcb->tcb_tmbx.tm_sticks) * _clock_res_usec; - /* Check for time quantum exceeded: */ - if (thread->slice_usec > TIMESLICE_USEC) - thread->slice_usec = -1; - } - thread->tcb->tcb_tmbx.tm_uticks = 0; - thread->tcb->tcb_tmbx.tm_sticks = 0; -} - -/* - * This is called after a fork(). - * No locks need to be taken here since we are guaranteed to be - * single threaded. - * - * XXX - * POSIX says for threaded process, fork() function is used - * only to run new programs, and the effects of calling functions - * that require certain resources between the call to fork() and - * the call to an exec function are undefined. - * - * It is not safe to free memory after fork(), because these data - * structures may be in inconsistent state. - */ -void -_kse_single_thread(struct pthread *curthread) -{ -#ifdef NOTYET - struct kse *kse; - struct kse_group *kseg; - struct pthread *thread; - - _thr_spinlock_init(); - *__malloc_lock = (spinlock_t)_SPINLOCK_INITIALIZER; - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; - - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags &= ~PTHREAD_SCOPE_PROCESS; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* - * Enter a loop to remove and free all threads other than - * the running thread from the active thread list: - */ - while ((thread = TAILQ_FIRST(&_thread_list)) != NULL) { - THR_GCLIST_REMOVE(thread); - /* - * Remove this thread from the list (the current - * thread will be removed but re-added by libpthread - * initialization. - */ - TAILQ_REMOVE(&_thread_list, thread, tle); - /* Make sure this isn't the running thread: */ - if (thread != curthread) { - _thr_stack_free(&thread->attr); - if (thread->specific != NULL) - free(thread->specific); - thr_destroy(curthread, thread); - } - } - - TAILQ_INIT(&curthread->mutexq); /* initialize mutex queue */ - curthread->joiner = NULL; /* no joining threads yet */ - curthread->refcount = 0; - SIGEMPTYSET(curthread->sigpend); /* clear pending signals */ - - /* Don't free thread-specific data as the caller may require it */ - - /* Free the free KSEs: */ - while ((kse = TAILQ_FIRST(&free_kseq)) != NULL) { - TAILQ_REMOVE(&free_kseq, kse, k_qe); - kse_destroy(kse); - } - free_kse_count = 0; - - /* Free the active KSEs: */ - while ((kse = TAILQ_FIRST(&active_kseq)) != NULL) { - TAILQ_REMOVE(&active_kseq, kse, k_qe); - kse_destroy(kse); - } - active_kse_count = 0; - - /* Free the free KSEGs: */ - while ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - free_kseg_count = 0; - - /* Free the active KSEGs: */ - while ((kseg = TAILQ_FIRST(&active_kse_groupq)) != NULL) { - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - active_kseg_count = 0; - - /* Free the free threads. */ - while ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - thr_destroy(curthread, thread); - } - free_thread_count = 0; - - /* Free the to-be-gc'd threads. */ - while ((thread = TAILQ_FIRST(&_thread_gc_list)) != NULL) { - TAILQ_REMOVE(&_thread_gc_list, thread, gcle); - thr_destroy(curthread, thread); - } - TAILQ_INIT(&gc_ksegq); - _gc_count = 0; - - if (inited != 0) { - /* - * Destroy these locks; they'll be recreated to assure they - * are in the unlocked state. - */ - _lock_destroy(&kse_lock); - _lock_destroy(&thread_lock); - _lock_destroy(&_thread_list_lock); - inited = 0; - } - - /* We're no longer part of any lists */ - curthread->tlflags = 0; - - /* - * After a fork, we are still operating on the thread's original - * stack. Don't clear the THR_FLAGS_USER from the thread's - * attribute flags. - */ - - /* Initialize the threads library. */ - curthread->kse = NULL; - curthread->kseg = NULL; - _kse_initial = NULL; - _libpthread_init(curthread); -#else - int i; - - /* Reset the current thread and KSE lock data. */ - for (i = 0; i < curthread->locklevel; i++) { - _lockuser_reinit(&curthread->lockusers[i], (void *)curthread); - } - curthread->locklevel = 0; - for (i = 0; i < curthread->kse->k_locklevel; i++) { - _lockuser_reinit(&curthread->kse->k_lockusers[i], - (void *)curthread->kse); - _LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL); - } - curthread->kse->k_locklevel = 0; - - /* - * Reinitialize the thread and signal locks so that - * sigaction() will work after a fork(). - */ - _lock_reinit(&curthread->lock, LCK_ADAPTIVE, _thr_lock_wait, - _thr_lock_wakeup); - _lock_reinit(&_thread_signal_lock, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup); - - _thr_spinlock_init(); - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* - * After a fork, it is possible that an upcall occurs in - * the parent KSE that fork()'d before the child process - * is fully created and before its vm space is copied. - * During the upcall, the tcb is set to null or to another - * thread, and this is what gets copied in the child process - * when the vm space is cloned sometime after the upcall - * occurs. Note that we shouldn't have to set the kcb, but - * we do it for completeness. - */ - _kcb_set(curthread->kse->k_kcb); - _tcb_set(curthread->kse->k_kcb, curthread->tcb); - - /* After a fork(), there child should have no pending signals. */ - sigemptyset(&curthread->sigpend); - - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; -#endif -} - -/* - * This is used to initialize housekeeping and to initialize the - * KSD for the KSE. - */ -void -_kse_init(void) -{ - if (inited == 0) { - TAILQ_INIT(&active_kseq); - TAILQ_INIT(&active_kse_groupq); - TAILQ_INIT(&free_kseq); - TAILQ_INIT(&free_kse_groupq); - TAILQ_INIT(&free_threadq); - TAILQ_INIT(&gc_ksegq); - if (_lock_init(&kse_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize free KSE queue lock"); - if (_lock_init(&thread_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize free thread queue lock"); - if (_lock_init(&_thread_list_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup, calloc) != 0) - PANIC("Unable to initialize thread list lock"); - _pthread_mutex_init(&_tcb_mutex, NULL); - active_kse_count = 0; - active_kseg_count = 0; - _gc_count = 0; - inited = 1; - } -} - -/* - * This is called when the first thread (other than the initial - * thread) is created. - */ -int -_kse_setthreaded(int threaded) -{ - sigset_t sigset; - - if ((threaded != 0) && (__isthreaded == 0)) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - - /* - * Tell the kernel to create a KSE for the initial thread - * and enable upcalls in it. - */ - _kse_initial->k_flags |= KF_STARTED; - - if (_thread_scope_system <= 0) { - _thr_initial->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - _kse_initial->k_kseg->kg_flags &= ~KGF_SINGLE_THREAD; - _kse_initial->k_kcb->kcb_kmbx.km_curthread = NULL; - } - else { - /* - * For bound thread, kernel reads mailbox pointer - * once, we'd set it here before calling kse_create. - */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _kse_initial->k_kcb->kcb_kmbx.km_flags |= KMF_BOUND; - } - - /* - * Locking functions in libc are required when there are - * threads other than the initial thread. - */ - _thr_rtld_init(); - - __isthreaded = 1; - if (kse_create(&_kse_initial->k_kcb->kcb_kmbx, 0) != 0) { - _kse_initial->k_flags &= ~KF_STARTED; - __isthreaded = 0; - PANIC("kse_create() failed\n"); - return (-1); - } - _thr_initial->tcb->tcb_tmbx.tm_lwp = - _kse_initial->k_kcb->kcb_kmbx.km_lwp; - _thread_activated = 1; - -#ifndef SYSTEM_SCOPE_ONLY - if (_thread_scope_system <= 0) { - /* Set current thread to initial thread */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _thr_start_sig_daemon(); - _thr_setmaxconcurrency(); - } - else -#endif - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - } - return (0); -} - -/* - * Lock wait and wakeup handlers for KSE locks. These are only used by - * KSEs, and should never be used by threads. KSE locks include the - * KSE group lock (used for locking the scheduling queue) and the - * kse_lock defined above. - * - * When a KSE lock attempt blocks, the entire KSE blocks allowing another - * KSE to run. For the most part, it doesn't make much sense to try and - * schedule another thread because you need to lock the scheduling queue - * in order to do that. And since the KSE lock is used to lock the scheduling - * queue, you would just end up blocking again. - */ -void -_kse_lock_wait(struct lock *lock __unused, struct lockuser *lu) -{ - struct kse *curkse = (struct kse *)_LCK_GET_PRIVATE(lu); - struct timespec ts; - int saved_flags; - - if (curkse->k_kcb->kcb_kmbx.km_curthread != NULL) - PANIC("kse_lock_wait does not disable upcall.\n"); - /* - * Enter a loop to wait until we get the lock. - */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000; /* 1 sec */ - while (!_LCK_GRANTED(lu)) { - /* - * Yield the kse and wait to be notified when the lock - * is granted. - */ - saved_flags = curkse->k_kcb->kcb_kmbx.km_flags; - curkse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL | - KMF_NOCOMPLETED; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } -} - -void -_kse_lock_wakeup(struct lock *lock, struct lockuser *lu) -{ - struct kse *curkse; - struct kse *kse; - struct kse_mailbox *mbx; - - curkse = _get_curkse(); - kse = (struct kse *)_LCK_GET_PRIVATE(lu); - - if (kse == curkse) - PANIC("KSE trying to wake itself up in lock"); - else { - mbx = &kse->k_kcb->kcb_kmbx; - _lock_grant(lock, lu); - /* - * Notify the owning kse that it has the lock. - * It is safe to pass invalid address to kse_wakeup - * even if the mailbox is not in kernel at all, - * and waking up a wrong kse is also harmless. - */ - kse_wakeup(mbx); - } -} - -/* - * Thread wait and wakeup handlers for thread locks. These are only used - * by threads, never by KSEs. Thread locks include the per-thread lock - * (defined in its structure), and condition variable and mutex locks. - */ -void -_thr_lock_wait(struct lock *lock __unused, struct lockuser *lu) -{ - struct pthread *curthread = (struct pthread *)lu->lu_private; - - do { - THR_LOCK_SWITCH(curthread); - THR_SET_STATE(curthread, PS_LOCKWAIT); - _thr_sched_switch_unlocked(curthread); - } while (!_LCK_GRANTED(lu)); -} - -void -_thr_lock_wakeup(struct lock *lock __unused, struct lockuser *lu) -{ - struct pthread *thread; - struct pthread *curthread; - struct kse_mailbox *kmbx; - - curthread = _get_curthread(); - thread = (struct pthread *)_LCK_GET_PRIVATE(lu); - - THR_SCHED_LOCK(curthread, thread); - _lock_grant(lock, lu); - kmbx = _thr_setrunnable_unlocked(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); -} - -kse_critical_t -_kse_critical_enter(void) -{ - kse_critical_t crit; - - crit = (kse_critical_t)_kcb_critical_enter(); - return (crit); -} - -void -_kse_critical_leave(kse_critical_t crit) -{ - struct pthread *curthread; - - _kcb_critical_leave((struct kse_thr_mailbox *)crit); - if ((crit != NULL) && ((curthread = _get_curthread()) != NULL)) - THR_YIELD_CHECK(curthread); -} - -int -_kse_in_critical(void) -{ - return (_kcb_in_critical()); -} - -void -_thr_critical_enter(struct pthread *thread) -{ - thread->critical_count++; -} - -void -_thr_critical_leave(struct pthread *thread) -{ - thread->critical_count--; - THR_YIELD_CHECK(thread); -} - -void -_thr_sched_switch(struct pthread *curthread) -{ - struct kse *curkse; - - (void)_kse_critical_enter(); - curkse = _get_curkse(); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - _thr_sched_switch_unlocked(curthread); -} - -/* - * XXX - We may need to take the scheduling lock before calling - * this, or perhaps take the lock within here before - * doing anything else. - */ -void -_thr_sched_switch_unlocked(struct pthread *curthread) -{ - struct kse *curkse; - volatile int resume_once = 0; - ucontext_t *uc; - - /* We're in the scheduler, 5 by 5: */ - curkse = curthread->kse; - - curthread->need_switchout = 1; /* The thread yielded on its own. */ - curthread->critical_yield = 0; /* No need to yield anymore. */ - - /* Thread can unlock the scheduler lock. */ - curthread->lock_switch = 1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - kse_sched_single(&curkse->k_kcb->kcb_kmbx); - else { - if (__predict_false(_libkse_debug != 0)) { - /* - * Because debugger saves single step status in thread - * mailbox's tm_dflags, we can safely clear single - * step status here. the single step status will be - * restored by kse_switchin when the thread is - * switched in again. This also lets uts run in full - * speed. - */ - ptrace(PT_CLEARSTEP, curkse->k_kcb->kcb_kmbx.km_lwp, - (caddr_t) 1, 0); - } - - KSE_SET_SWITCH(curkse); - _thread_enter_uts(curthread->tcb, curkse->k_kcb); - } - - /* - * Unlock the scheduling queue and leave the - * critical region. - */ - /* Don't trust this after a switch! */ - curkse = curthread->kse; - - curthread->lock_switch = 0; - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* - * This thread is being resumed; check for cancellations. - */ - if (THR_NEED_ASYNC_CANCEL(curthread) && !THR_IN_CRITICAL(curthread)) { - uc = alloca(sizeof(ucontext_t)); - resume_once = 0; - THR_GETCONTEXT(uc); - if (resume_once == 0) { - resume_once = 1; - curthread->check_pending = 0; - thr_resume_check(curthread, uc); - } - } - THR_ACTIVATE_LAST_LOCK(curthread); -} - -/* - * This is the scheduler for a KSE which runs a scope system thread. - * The multi-thread KSE scheduler should also work for a single threaded - * KSE, but we use a separate scheduler so that it can be fine-tuned - * to be more efficient (and perhaps not need a separate stack for - * the KSE, allowing it to use the thread's stack). - */ - -static void -kse_sched_single(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread; - struct timespec ts; - sigset_t sigmask; - int i, sigseqno, level, first = 0; - - curkse = (struct kse *)kmbx->km_udata; - curthread = curkse->k_curthread; - - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - _tcb_set(curkse->k_kcb, curthread->tcb); - curkse->k_flags |= KF_INITIALIZED; - first = 1; - curthread->active = 1; - - /* Setup kernel signal masks for new thread. */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - /* - * Enter critical region, this is meanless for bound thread, - * It is used to let other code work, those code want mailbox - * to be cleared. - */ - (void)_kse_critical_enter(); - } else { - /* - * Bound thread always has tcb set, this prevent some - * code from blindly setting bound thread tcb to NULL, - * buggy code ? - */ - _tcb_set(curkse->k_kcb, curthread->tcb); - } - - curthread->critical_yield = 0; - curthread->need_switchout = 0; - - /* - * Lock the scheduling queue. - * - * There is no scheduling queue for single threaded KSEs, - * but we need a lock for protection regardless. - */ - if (curthread->lock_switch == 0) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - - /* - * This has to do the job of kse_switchout_thread(), only - * for a single threaded KSE/KSEG. - */ - - switch (curthread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - curthread->continuation = _thr_finish_cancellation; - THR_SET_STATE(curthread, PS_RUNNING); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - level = curthread->locklevel - 1; - if (_LCK_GRANTED(&curthread->lockusers[level])) - THR_SET_STATE(curthread, PS_RUNNING); - break; - - case PS_DEAD: - /* Unlock the scheduling queue and exit the KSE and thread. */ - thr_cleanup(curkse, curthread); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - PANIC("bound thread shouldn't get here\n"); - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(curthread)) { - curthread->join_status.thread = NULL; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SUSPENDED: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_RUNNING: - if ((curthread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(curthread)) { - THR_SET_STATE(curthread, PS_SUSPENDED); - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SIGWAIT: - PANIC("bound thread does not have SIGWAIT state\n"); - - case PS_SLEEP_WAIT: - PANIC("bound thread does not have SLEEP_WAIT state\n"); - - case PS_SIGSUSPEND: - PANIC("bound thread does not have SIGSUSPEND state\n"); - - case PS_DEADLOCK: - /* - * These states don't timeout and don't need - * to be in the waiting queue. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - break; - - default: - PANIC("Unknown state\n"); - break; - } - - while (curthread->state != PS_RUNNING) { - sigseqno = curkse->k_sigseqno; - if (curthread->check_pending != 0) { - /* - * Install pending signals into the frame, possible - * cause mutex or condvar backout. - */ - curthread->check_pending = 0; - SIGFILLSET(sigmask); - - /* - * Lock out kernel signal code when we are processing - * signals, and get a fresh copy of signal mask. - */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) - (void)_thr_sig_add(curthread, i, - &curthread->siginfo[i-1]); - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - /* The above code might make thread runnable */ - if (curthread->state == PS_RUNNING) - break; - } - THR_DEACTIVATE_LAST_LOCK(curthread); - kse_wait(curkse, curthread, sigseqno); - THR_ACTIVATE_LAST_LOCK(curthread); - if (curthread->wakeup_time.tv_sec >= 0) { - KSE_GET_TOD(curkse, &ts); - if (thr_timedout(curthread, &ts)) { - /* Indicate the thread timedout: */ - curthread->timeout = 1; - /* Make the thread runnable. */ - THR_SET_STATE(curthread, PS_RUNNING); - } - } - } - - if (curthread->lock_switch == 0) { - /* Unlock the scheduling queue. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - } - - DBG_MSG("Continuing bound thread %p\n", curthread); - if (first) { - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - pthread_exit(curthread->start_routine(curthread->arg)); - } -} - -#ifdef DEBUG_THREAD_KERN -static void -dump_queues(struct kse *curkse) -{ - struct pthread *thread; - - DBG_MSG("Threads in waiting queue:\n"); - TAILQ_FOREACH(thread, &curkse->k_kseg->kg_schedq.sq_waitq, pqe) { - DBG_MSG(" thread %p, state %d, blocked %d\n", - thread, thread->state, thread->blocked); - } -} -#endif - -/* - * This is the scheduler for a KSE which runs multiple threads. - */ -static void -kse_sched_multi(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread, *td_wait; - int ret; - - curkse = (struct kse *)kmbx->km_udata; - THR_ASSERT(curkse->k_kcb->kcb_kmbx.km_curthread == NULL, - "Mailbox not null in kse_sched_multi"); - - /* Check for first time initialization: */ - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - - /* Set this before grabbing the context. */ - curkse->k_flags |= KF_INITIALIZED; - } - - /* - * No current thread anymore, calling _get_curthread in UTS - * should dump core - */ - _tcb_set(curkse->k_kcb, NULL); - - /* If this is an upcall; take the scheduler lock. */ - if (!KSE_IS_SWITCH(curkse)) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - else - KSE_CLEAR_SWITCH(curkse); - - if (KSE_IS_IDLE(curkse)) { - KSE_CLEAR_IDLE(curkse); - curkse->k_kseg->kg_idle_kses--; - } - - /* - * Now that the scheduler lock is held, get the current - * thread. The KSE's current thread cannot be safely - * examined without the lock because it could have returned - * as completed on another KSE. See kse_check_completed(). - */ - curthread = curkse->k_curthread; - - /* - * If the current thread was completed in another KSE, then - * it will be in the run queue. Don't mark it as being blocked. - */ - if ((curthread != NULL) && - ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) && - (curthread->need_switchout == 0)) { - /* - * Assume the current thread is blocked; when the - * completed threads are checked and if the current - * thread is among the completed, the blocked flag - * will be cleared. - */ - curthread->blocked = 1; - DBG_MSG("Running thread %p is now blocked in kernel.\n", - curthread); - } - - /* Check for any unblocked threads in the kernel. */ - kse_check_completed(curkse); - - /* - * Check for threads that have timed-out. - */ - kse_check_waitq(curkse); - - /* - * Switchout the current thread, if necessary, as the last step - * so that it is inserted into the run queue (if it's runnable) - * _after_ any other threads that were added to it above. - */ - if (curthread == NULL) - ; /* Nothing to do here. */ - else if ((curthread->need_switchout == 0) && DBG_CAN_RUN(curthread) && - (curthread->blocked == 0) && (THR_IN_CRITICAL(curthread))) { - /* - * Resume the thread and tell it to yield when - * it leaves the critical region. - */ - curthread->critical_yield = 1; - curthread->active = 1; - if ((curthread->flags & THR_FLAGS_IN_RUNQ) != 0) - KSE_RUNQ_REMOVE(curkse, curthread); - curkse->k_curthread = curthread; - curthread->kse = curkse; - DBG_MSG("Continuing thread %p in critical region\n", - curthread); - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("Can't resume thread in critical region\n"); - } - else if ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - curthread->tcb->tcb_tmbx.tm_lwp = 0; - kse_switchout_thread(curkse, curthread); - } - curkse->k_curthread = NULL; - -#ifdef DEBUG_THREAD_KERN - dump_queues(curkse); -#endif - - /* Check if there are no threads ready to run: */ - while (((curthread = KSE_RUNQ_FIRST(curkse)) == NULL) && - (curkse->k_kseg->kg_threadcount != 0) && - ((curkse->k_flags & KF_TERMINATED) == 0)) { - /* - * Wait for a thread to become active or until there are - * no more threads. - */ - td_wait = KSE_WAITQ_FIRST(curkse); - kse_wait(curkse, td_wait, 0); - kse_check_completed(curkse); - kse_check_waitq(curkse); - } - - /* Check for no more threads: */ - if ((curkse->k_kseg->kg_threadcount == 0) || - ((curkse->k_flags & KF_TERMINATED) != 0)) { - /* - * Normally this shouldn't return, but it will if there - * are other KSEs running that create new threads that - * are assigned to this KSE[G]. For instance, if a scope - * system thread were to create a scope process thread - * and this kse[g] is the initial kse[g], then that newly - * created thread would be assigned to us (the initial - * kse[g]). - */ - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - kse_fini(curkse); - /* never returns */ - } - - THR_ASSERT(curthread != NULL, - "Return from kse_wait/fini without thread."); - THR_ASSERT(curthread->state != PS_DEAD, - "Trying to resume dead thread!"); - KSE_RUNQ_REMOVE(curkse, curthread); - - /* - * Make the selected thread the current thread. - */ - curkse->k_curthread = curthread; - - /* - * Make sure the current thread's kse points to this kse. - */ - curthread->kse = curkse; - - /* - * Reset the time slice if this thread is running for the first - * time or running again after using its full time slice allocation. - */ - if (curthread->slice_usec == -1) - curthread->slice_usec = 0; - - /* Mark the thread active. */ - curthread->active = 1; - - /* - * The thread's current signal frame will only be NULL if it - * is being resumed after being blocked in the kernel. In - * this case, and if the thread needs to run down pending - * signals or needs a cancellation check, we need to add a - * signal frame to the thread's context. - */ - if (curthread->lock_switch == 0 && curthread->state == PS_RUNNING && - (curthread->check_pending != 0 || - THR_NEED_ASYNC_CANCEL(curthread)) && - !THR_IN_CRITICAL(curthread)) { - curthread->check_pending = 0; - signalcontext(&curthread->tcb->tcb_tmbx.tm_context, 0, - (__sighandler_t *)thr_resume_wrapper); - } - kse_wakeup_multi(curkse); - /* - * Continue the thread at its current frame: - */ - if (curthread->lock_switch != 0) { - /* - * This thread came from a scheduler switch; it will - * unlock the scheduler lock and set the mailbox. - */ - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 0); - } else { - /* This thread won't unlock the scheduler lock. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - } - if (ret != 0) - PANIC("Thread has returned from _thread_switch"); - - /* This point should not be reached. */ - PANIC("Thread has returned from _thread_switch"); -} - -static void -thr_resume_wrapper(int sig __unused, siginfo_t *siginfo __unused, - ucontext_t *ucp) -{ - struct pthread *curthread = _get_curthread(); - struct kse *curkse; - int ret, err_save = errno; - - DBG_MSG(">>> sig wrapper\n"); - if (curthread->lock_switch) - PANIC("thr_resume_wrapper, lock_switch != 0\n"); - thr_resume_check(curthread, ucp); - errno = err_save; - _kse_critical_enter(); - curkse = curthread->kse; - curthread->tcb->tcb_tmbx.tm_context = *ucp; - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("thr_resume_wrapper: thread has returned " - "from _thread_switch"); - /* THR_SETCONTEXT(ucp); */ /* not work, why ? */ -} - -static void -thr_resume_check(struct pthread *curthread, ucontext_t *ucp) -{ - _thr_sig_rundown(curthread, ucp); - - if (THR_NEED_ASYNC_CANCEL(curthread)) - pthread_testcancel(); -} - -/* - * Clean up a thread. This must be called with the thread's KSE - * scheduling lock held. The thread must be a thread from the - * KSE's group. - */ -static void -thr_cleanup(struct kse *curkse, struct pthread *thread) -{ - struct pthread *joiner; - struct kse_mailbox *kmbx = NULL; - int sys_scope; - - thread->active = 0; - thread->need_switchout = 0; - thread->lock_switch = 0; - thread->check_pending = 0; - - if ((joiner = thread->joiner) != NULL) { - /* Joinee scheduler lock held; joiner won't leave. */ - if (joiner->kseg == curkse->k_kseg) { - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - (void)_thr_setrunnable_unlocked(joiner); - } - } else { - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* The joiner may have removed itself and exited. */ - if (_thr_ref_add(thread, joiner, 0) == 0) { - KSE_SCHED_LOCK(curkse, joiner->kseg); - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - kmbx = _thr_setrunnable_unlocked(joiner); - } - KSE_SCHED_UNLOCK(curkse, joiner->kseg); - _thr_ref_delete(thread, joiner); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - } - thread->attr.flags |= PTHREAD_DETACHED; - } - - if (!(sys_scope = (thread->attr.flags & PTHREAD_SCOPE_SYSTEM))) { - /* - * Remove the thread from the KSEG's list of threads. - */ - KSEG_THRQ_REMOVE(thread->kseg, thread); - /* - * Migrate the thread to the main KSE so that this - * KSE and KSEG can be cleaned when their last thread - * exits. - */ - thread->kseg = _kse_initial->k_kseg; - thread->kse = _kse_initial; - } - - /* - * We can't hold the thread list lock while holding the - * scheduler lock. - */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - DBG_MSG("Adding thread %p to GC list\n", thread); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->tlflags |= TLFLAGS_GC_SAFE; - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (sys_scope) { - /* - * System scope thread is single thread group, - * when thread is exited, its kse and ksegrp should - * be recycled as well. - * kse upcall stack belongs to thread, clear it here. - */ - curkse->k_stack.ss_sp = 0; - curkse->k_stack.ss_size = 0; - kse_exit(); - PANIC("kse_exit() failed for system scope thread"); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); -} - -void -_thr_gc(struct pthread *curthread) -{ - thread_gc(curthread); - kse_gc(curthread); - kseg_gc(curthread); -} - -static void -thread_gc(struct pthread *curthread) -{ - struct pthread *td, *td_next; - kse_critical_t crit; - TAILQ_HEAD(, pthread) worklist; - - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - /* Check the threads waiting for GC. */ - for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) { - td_next = TAILQ_NEXT(td, gcle); - if ((td->tlflags & TLFLAGS_GC_SAFE) == 0) - continue; - else if (((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - ((td->kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - /* - * The thread and KSE are operating on the same - * stack. Wait for the KSE to exit before freeing - * the thread's stack as well as everything else. - */ - continue; - } - /* - * Remove the thread from the GC list. If the thread - * isn't yet detached, it will get added back to the - * GC list at a later time. - */ - THR_GCLIST_REMOVE(td); - DBG_MSG("Freeing thread %p stack\n", td); - /* - * We can free the thread stack since it's no longer - * in use. - */ - _thr_stack_free(&td->attr); - if (((td->attr.flags & PTHREAD_DETACHED) != 0) && - (td->refcount == 0)) { - /* - * The thread has detached and is no longer - * referenced. It is safe to remove all - * remnants of the thread. - */ - THR_LIST_REMOVE(td); - TAILQ_INSERT_HEAD(&worklist, td, gcle); - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - while ((td = TAILQ_FIRST(&worklist)) != NULL) { - TAILQ_REMOVE(&worklist, td, gcle); - /* - * XXX we don't free initial thread and its kse - * (if thread is a bound thread), because there might - * have some code referencing initial thread and kse. - */ - if (td == _thr_initial) { - DBG_MSG("Initial thread won't be freed\n"); - continue; - } - - if ((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(td->kse); - kseg_free_unlocked(td->kseg); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - DBG_MSG("Freeing thread %p\n", td); - _thr_free(curthread, td); - } -} - -static void -kse_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse) worklist; - struct kse *kse; - - if (free_kse_count <= MAX_CACHED_KSES) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kse_count > MAX_CACHED_KSES) { - kse = TAILQ_FIRST(&free_kseq); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - TAILQ_INSERT_HEAD(&worklist, kse, k_qe); - free_kse_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kse = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kse, k_qe); - kse_destroy(kse); - } -} - -static void -kseg_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse_group) worklist; - struct kse_group *kseg; - - if (free_kseg_count <= MAX_CACHED_KSEGS) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kseg_count > MAX_CACHED_KSEGS) { - kseg = TAILQ_FIRST(&free_kse_groupq); - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - TAILQ_INSERT_HEAD(&worklist, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kseg = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kseg, kg_qe); - kseg_destroy(kseg); - } -} - -/* - * Only new threads that are running or suspended may be scheduled. - */ -int -_thr_schedule_add(struct pthread *curthread, struct pthread *newthread) -{ - kse_critical_t crit; - int ret; - - /* Add the new thread. */ - thr_link(newthread); - - /* - * If this is the first time creating a thread, make sure - * the mailbox is set for the current thread. - */ - if ((newthread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* We use the thread's stack as the KSE's stack. */ - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_sp = - newthread->attr.stackaddr_attr; - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_size = - newthread->attr.stacksize_attr; - - /* - * No need to lock the scheduling queue since the - * KSE/KSEG pair have not yet been started. - */ - KSEG_THRQ_ADD(newthread->kseg, newthread); - /* this thread never gives up kse */ - newthread->active = 1; - newthread->kse->k_curthread = newthread; - newthread->kse->k_kcb->kcb_kmbx.km_flags = KMF_BOUND; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_single; - newthread->kse->k_kcb->kcb_kmbx.km_quantum = 0; - KSE_SET_MBOX(newthread->kse, newthread); - /* - * This thread needs a new KSE and KSEG. - */ - newthread->kse->k_flags &= ~KF_INITIALIZED; - newthread->kse->k_flags |= KF_STARTED; - /* Fire up! */ - ret = kse_create(&newthread->kse->k_kcb->kcb_kmbx, 1); - if (ret != 0) - ret = errno; - } - else { - /* - * Lock the KSE and add the new thread to its list of - * assigned threads. If the new thread is runnable, also - * add it to the KSE's run queue. - */ - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, newthread->kseg); - KSEG_THRQ_ADD(newthread->kseg, newthread); - if (newthread->state == PS_RUNNING) - THR_RUNQ_INSERT_TAIL(newthread); - if ((newthread->kse->k_flags & KF_STARTED) == 0) { - /* - * This KSE hasn't been started yet. Start it - * outside of holding the lock. - */ - newthread->kse->k_flags |= KF_STARTED; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_multi; - newthread->kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_create(&newthread->kse->k_kcb->kcb_kmbx, 0); - } else if ((newthread->state == PS_RUNNING) && - KSE_IS_IDLE(newthread->kse)) { - /* - * The thread is being scheduled on another KSEG. - */ - kse_wakeup_one(newthread); - } - KSE_SCHED_UNLOCK(curthread->kse, newthread->kseg); - _kse_critical_leave(crit); - ret = 0; - } - if (ret != 0) - thr_unlink(newthread); - - return (ret); -} - -void -kse_waitq_insert(struct pthread *thread) -{ - struct pthread *td; - - if (thread->wakeup_time.tv_sec == -1) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, thread, - pqe); - else { - td = TAILQ_FIRST(&thread->kse->k_schedq->sq_waitq); - while ((td != NULL) && (td->wakeup_time.tv_sec != -1) && - ((td->wakeup_time.tv_sec < thread->wakeup_time.tv_sec) || - ((td->wakeup_time.tv_sec == thread->wakeup_time.tv_sec) && - (td->wakeup_time.tv_nsec <= thread->wakeup_time.tv_nsec)))) - td = TAILQ_NEXT(td, pqe); - if (td == NULL) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, - thread, pqe); - else - TAILQ_INSERT_BEFORE(td, thread, pqe); - } - thread->flags |= THR_FLAGS_IN_WAITQ; -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_completed(struct kse *kse) -{ - struct pthread *thread; - struct kse_thr_mailbox *completed; - int sig; - - if ((completed = kse->k_kcb->kcb_kmbx.km_completed) != NULL) { - kse->k_kcb->kcb_kmbx.km_completed = NULL; - while (completed != NULL) { - thread = completed->tm_udata; - DBG_MSG("Found completed thread %p, name %s\n", - thread, - (thread->name == NULL) ? "none" : thread->name); - thread->blocked = 0; - if (thread != kse->k_curthread) { - thr_accounting(thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else - KSE_RUNQ_INSERT_TAIL(kse, thread); - if ((thread->kse != kse) && - (thread->kse->k_curthread == thread)) { - /* - * Remove this thread from its - * previous KSE so that it (the KSE) - * doesn't think it is still active. - */ - thread->kse->k_curthread = NULL; - thread->active = 0; - } - } - if ((sig = thread->tcb->tcb_tmbx.tm_syncsig.si_signo) - != 0) { - if (SIGISMEMBER(thread->sigmask, sig)) - SIGADDSET(thread->sigpend, sig); - else if (THR_IN_CRITICAL(thread)) - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - else - (void)_thr_sig_add(thread, sig, - &thread->tcb->tcb_tmbx.tm_syncsig); - thread->tcb->tcb_tmbx.tm_syncsig.si_signo = 0; - } - completed = completed->tm_next; - } - } -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_waitq(struct kse *kse) -{ - struct pthread *pthread; - struct timespec ts; - - KSE_GET_TOD(kse, &ts); - - /* - * Wake up threads that have timedout. This has to be - * done before adding the current thread to the run queue - * so that a CPU intensive thread doesn't get preference - * over waiting threads. - */ - while (((pthread = KSE_WAITQ_FIRST(kse)) != NULL) && - thr_timedout(pthread, &ts)) { - /* Remove the thread from the wait queue: */ - KSE_WAITQ_REMOVE(kse, pthread); - DBG_MSG("Found timedout thread %p in waitq\n", pthread); - - /* Indicate the thread timedout: */ - pthread->timeout = 1; - - /* Add the thread to the priority queue: */ - if ((pthread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(pthread, PS_SUSPENDED); - else { - THR_SET_STATE(pthread, PS_RUNNING); - KSE_RUNQ_INSERT_TAIL(kse, pthread); - } - } -} - -static int -thr_timedout(struct pthread *thread, struct timespec *curtime) -{ - if (thread->wakeup_time.tv_sec < 0) - return (0); - else if (thread->wakeup_time.tv_sec > curtime->tv_sec) - return (0); - else if ((thread->wakeup_time.tv_sec == curtime->tv_sec) && - (thread->wakeup_time.tv_nsec > curtime->tv_nsec)) - return (0); - else - return (1); -} - -/* - * This must be called with the scheduling lock held. - * - * Each thread has a time slice, a wakeup time (used when it wants - * to wait for a specified amount of time), a run state, and an - * active flag. - * - * When a thread gets run by the scheduler, the active flag is - * set to non-zero (1). When a thread performs an explicit yield - * or schedules a state change, it enters the scheduler and the - * active flag is cleared. When the active flag is still seen - * set in the scheduler, that means that the thread is blocked in - * the kernel (because it is cleared before entering the scheduler - * in all other instances). - * - * The wakeup time is only set for those states that can timeout. - * It is set to (-1, -1) for all other instances. - * - * The thread's run state, aside from being useful when debugging, - * is used to place the thread in an appropriate queue. There - * are 2 basic queues: - * - * o run queue - queue ordered by priority for all threads - * that are runnable - * o waiting queue - queue sorted by wakeup time for all threads - * that are not otherwise runnable (not blocked - * in kernel, not waiting for locks) - * - * The thread's time slice is used for round-robin scheduling - * (the default scheduling policy). While a SCHED_RR thread - * is runnable it's time slice accumulates. When it reaches - * the time slice interval, it gets reset and added to the end - * of the queue of threads at its priority. When a thread no - * longer becomes runnable (blocks in kernel, waits, etc), its - * time slice is reset. - * - * The job of kse_switchout_thread() is to handle all of the above. - */ -static void -kse_switchout_thread(struct kse *kse, struct pthread *thread) -{ - int level; - int i; - int restart; - siginfo_t siginfo; - - /* - * Place the currently running thread into the - * appropriate queue(s). - */ - DBG_MSG("Switching out thread %p, state %d\n", thread, thread->state); - - THR_DEACTIVATE_LAST_LOCK(thread); - if (thread->blocked != 0) { - thread->active = 0; - thread->need_switchout = 0; - /* This thread must have blocked in the kernel. */ - /* - * Check for pending signals and cancellation for - * this thread to see if we need to interrupt it - * in the kernel. - */ - if (THR_NEED_CANCEL(thread)) { - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); - } else if (thread->check_pending != 0) { - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(thread->sigpend, i) && - !SIGISMEMBER(thread->sigmask, i)) { - restart = _thread_sigact[i - 1].sa_flags & SA_RESTART; - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - break; - } - } - } - } - else { - switch (thread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - thread->continuation = _thr_finish_cancellation; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - level = thread->locklevel - 1; - if (!_LCK_GRANTED(&thread->lockusers[level])) - KSE_WAITQ_INSERT(kse, thread); - else - THR_SET_STATE(thread, PS_RUNNING); - break; - - case PS_SLEEP_WAIT: - case PS_SIGWAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(thread)) { - thread->join_status.thread = NULL; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_SIGSUSPEND: - case PS_SUSPENDED: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_DEAD: - /* - * The scheduler is operating on a different - * stack. It is safe to do garbage collecting - * here. - */ - thr_cleanup(kse, thread); - return; - break; - - case PS_RUNNING: - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(thread)) - THR_SET_STATE(thread, PS_SUSPENDED); - break; - - case PS_DEADLOCK: - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - break; - - default: - PANIC("Unknown state\n"); - break; - } - - thr_accounting(thread); - if (thread->state == PS_RUNNING) { - if (thread->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. - */ - KSE_RUNQ_INSERT_TAIL(kse, thread); - } else { - /* - * The thread hasn't exceeded its interval - * Place it at the head of the queue for its - * priority. - */ - KSE_RUNQ_INSERT_HEAD(kse, thread); - } - } - } - thread->active = 0; - thread->need_switchout = 0; - if (thread->check_pending != 0) { - /* Install pending signals into the frame. */ - thread->check_pending = 0; - KSE_LOCK_ACQUIRE(kse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(thread->sigmask, i)) - continue; - if (SIGISMEMBER(thread->sigpend, i)) - (void)_thr_sig_add(thread, i, - &thread->siginfo[i-1]); - else if (SIGISMEMBER(_thr_proc_sigpending, i) && - _thr_getprocsig_unlocked(i, &siginfo)) { - (void)_thr_sig_add(thread, i, &siginfo); - } - } - KSE_LOCK_RELEASE(kse, &_thread_signal_lock); - } -} - -/* - * This function waits for the smallest timeout value of any waiting - * thread, or until it receives a message from another KSE. - * - * This must be called with the scheduling lock held. - */ -static void -kse_wait(struct kse *kse, struct pthread *td_wait, int sigseqno) -{ - struct timespec ts, ts_sleep; - int saved_flags; - - if ((td_wait == NULL) || (td_wait->wakeup_time.tv_sec < 0)) { - /* Limit sleep to no more than 1 minute. */ - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } else { - KSE_GET_TOD(kse, &ts); - TIMESPEC_SUB(&ts_sleep, &td_wait->wakeup_time, &ts); - if (ts_sleep.tv_sec > 60) { - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } - } - /* Don't sleep for negative times. */ - if ((ts_sleep.tv_sec >= 0) && (ts_sleep.tv_nsec >= 0)) { - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - if ((kse->k_kseg->kg_flags & KGF_SINGLE_THREAD) && - (kse->k_sigseqno != sigseqno)) - ; /* don't sleep */ - else { - saved_flags = kse->k_kcb->kcb_kmbx.km_flags; - kse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL; - kse_release(&ts_sleep); - kse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - if (KSE_IS_IDLE(kse)) { - KSE_CLEAR_IDLE(kse); - kse->k_kseg->kg_idle_kses--; - } - } -} - -/* - * Avoid calling this kse_exit() so as not to confuse it with the - * system call of the same name. - */ -static void -kse_fini(struct kse *kse) -{ - /* struct kse_group *free_kseg = NULL; */ - struct timespec ts; - struct pthread *td; - - /* - * Check to see if this is one of the main kses. - */ - if (kse->k_kseg != _kse_initial->k_kseg) { - PANIC("shouldn't get here"); - /* This is for supporting thread groups. */ -#ifdef NOT_YET - /* Remove this KSE from the KSEG's list of KSEs. */ - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - if (TAILQ_EMPTY(&kse->k_kseg->kg_kseq)) - free_kseg = kse->k_kseg; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - - /* - * Add this KSE to the list of free KSEs along with - * the KSEG if is now orphaned. - */ - KSE_LOCK_ACQUIRE(kse, &kse_lock); - if (free_kseg != NULL) - kseg_free_unlocked(free_kseg); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit()"); -#endif - } else { - /* - * We allow program to kill kse in initial group (by - * lowering the concurrency). - */ - if ((kse != _kse_initial) && - ((kse->k_flags & KF_TERMINATED) != 0)) { - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - /* - * Migrate thread to _kse_initial if its lastest - * kse it ran on is the kse. - */ - td = TAILQ_FIRST(&kse->k_kseg->kg_threadq); - while (td != NULL) { - if (td->kse == kse) - td->kse = _kse_initial; - td = TAILQ_NEXT(td, kle); - } - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - KSE_LOCK_ACQUIRE(kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - /* Make sure there is always at least one is awake */ - KSE_WAKEUP(_kse_initial); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit() failed for initial kseg"); - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - ts.tv_sec = 120; - ts.tv_nsec = 0; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_release(&ts); - /* Never reach */ - } -} - -void -_thr_set_timeout(const struct timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - - /* Reset the timeout flag for the running thread: */ - curthread->timeout = 0; - - /* Check if the thread is to wait forever: */ - if (timeout == NULL) { - /* - * Set the wakeup time to something that can be recognised as - * different to an actual time of day: - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - /* Check if no waiting is required: */ - else if ((timeout->tv_sec == 0) && (timeout->tv_nsec == 0)) { - /* Set the wake up time to 'immediately': */ - curthread->wakeup_time.tv_sec = 0; - curthread->wakeup_time.tv_nsec = 0; - } else { - /* Calculate the time for the current thread to wakeup: */ - KSE_GET_TOD(curthread->kse, &ts); - TIMESPEC_ADD(&curthread->wakeup_time, &ts, timeout); - } -} - -void -_thr_panic_exit(char *file, int line, char *msg) -{ - char buf[256]; - - snprintf(buf, sizeof(buf), "(%s:%d) %s\n", file, line, msg); - __sys_write(2, buf, strlen(buf)); - abort(); -} - -void -_thr_setrunnable(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse_mailbox *kmbx; - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, thread->kseg); - kmbx = _thr_setrunnable_unlocked(thread); - KSE_SCHED_UNLOCK(curthread->kse, thread->kseg); - _kse_critical_leave(crit); - if ((kmbx != NULL) && (__isthreaded != 0)) - kse_wakeup(kmbx); -} - -struct kse_mailbox * -_thr_setrunnable_unlocked(struct pthread *thread) -{ - struct kse_mailbox *kmbx = NULL; - - if ((thread->kseg->kg_flags & KGF_SINGLE_THREAD) != 0) { - /* No silly queues for these threads. */ - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - kmbx = kse_wakeup_one(thread); - } - - } else if (thread->state != PS_RUNNING) { - if ((thread->flags & THR_FLAGS_IN_WAITQ) != 0) - KSE_WAITQ_REMOVE(thread->kse, thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - if ((thread->blocked == 0) && (thread->active == 0) && - (thread->flags & THR_FLAGS_IN_RUNQ) == 0) - THR_RUNQ_INSERT_TAIL(thread); - /* - * XXX - Threads are not yet assigned to specific - * KSEs; they are assigned to the KSEG. So - * the fact that a thread's KSE is waiting - * doesn't necessarily mean that it will be - * the KSE that runs the thread after the - * lock is granted. But we don't know if the - * other KSEs within the same KSEG are also - * in a waiting state or not so we err on the - * side of caution and wakeup the thread's - * last known KSE. We ensure that the - * threads KSE doesn't change while it's - * scheduling lock is held so it is safe to - * reference it (the KSE). If the KSE wakes - * up and doesn't find any more work it will - * again go back to waiting so no harm is - * done. - */ - kmbx = kse_wakeup_one(thread); - } - } - return (kmbx); -} - -static struct kse_mailbox * -kse_wakeup_one(struct pthread *thread) -{ - struct kse *ke; - - if (KSE_IS_IDLE(thread->kse)) { - KSE_CLEAR_IDLE(thread->kse); - thread->kseg->kg_idle_kses--; - return (&thread->kse->k_kcb->kcb_kmbx); - } else { - TAILQ_FOREACH(ke, &thread->kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - return (&ke->k_kcb->kcb_kmbx); - } - } - } - return (NULL); -} - -static void -kse_wakeup_multi(struct kse *curkse) -{ - struct kse *ke; - int tmp; - - if ((tmp = KSE_RUNQ_THREADS(curkse)) && curkse->k_kseg->kg_idle_kses) { - TAILQ_FOREACH(ke, &curkse->k_kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - KSE_WAKEUP(ke); - if (--tmp == 0) - break; - } - } - } -} - -/* - * Allocate a new KSEG. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSEG is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse_group * -_kseg_alloc(struct pthread *curthread) -{ - struct kse_group *kseg = NULL; - kse_critical_t crit; - - if ((curthread != NULL) && (free_kseg_count > 0)) { - /* Use the kse lock for the kseg queue. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - if ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kseg) - kseg_reinit(kseg); - } - - /* - * If requested, attempt to allocate a new KSE group only if the - * KSE allocation was successful and a KSE group wasn't found in - * the free list. - */ - if ((kseg == NULL) && - ((kseg = (struct kse_group *)malloc(sizeof(*kseg))) != NULL)) { - if (_pq_alloc(&kseg->kg_schedq.sq_runq, - THR_MIN_PRIORITY, THR_LAST_PRIORITY) != 0) { - free(kseg); - kseg = NULL; - } else { - kseg_init(kseg); - /* Add the KSEG to the list of active KSEGs. */ - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } else { - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - } - } - } - return (kseg); -} - -static void -kseg_init(struct kse_group *kseg) -{ - kseg_reinit(kseg); - _lock_init(&kseg->kg_lock, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup, calloc); -} - -static void -kseg_reinit(struct kse_group *kseg) -{ - TAILQ_INIT(&kseg->kg_kseq); - TAILQ_INIT(&kseg->kg_threadq); - TAILQ_INIT(&kseg->kg_schedq.sq_waitq); - kseg->kg_threadcount = 0; - kseg->kg_ksecount = 0; - kseg->kg_idle_kses = 0; - kseg->kg_flags = 0; -} - -/* - * This must be called with the kse lock held and when there are - * no more threads that reference it. - */ -static void -kseg_free_unlocked(struct kse_group *kseg) -{ - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - TAILQ_INSERT_HEAD(&free_kse_groupq, kseg, kg_qe); - free_kseg_count++; - active_kseg_count--; -} - -void -_kseg_free(struct kse_group *kseg) -{ - struct kse *curkse; - kse_critical_t crit; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &kse_lock); - kseg_free_unlocked(kseg); - KSE_LOCK_RELEASE(curkse, &kse_lock); - _kse_critical_leave(crit); -} - -static void -kseg_destroy(struct kse_group *kseg) -{ - _lock_destroy(&kseg->kg_lock); - _pq_free(&kseg->kg_schedq.sq_runq); - free(kseg); -} - -/* - * Allocate a new KSE. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSE is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse * -_kse_alloc(struct pthread *curthread, int sys_scope) -{ - struct kse *kse = NULL; - char *stack; - kse_critical_t crit; - int i; - - if ((curthread != NULL) && (free_kse_count > 0)) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - /* Search for a finished KSE. */ - kse = TAILQ_FIRST(&free_kseq); - while ((kse != NULL) && - ((kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - kse = TAILQ_NEXT(kse, k_qe); - } - if (kse != NULL) { - DBG_MSG("found an unused kse.\n"); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - free_kse_count--; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kse != NULL) - kse_reinit(kse, sys_scope); - } - if ((kse == NULL) && - ((kse = (struct kse *)malloc(sizeof(*kse))) != NULL)) { - if (sys_scope != 0) - stack = NULL; - else if ((stack = malloc(KSE_STACKSIZE)) == NULL) { - free(kse); - return (NULL); - } - bzero(kse, sizeof(*kse)); - - /* Initialize KCB without the lock. */ - if ((kse->k_kcb = _kcb_ctor(kse)) == NULL) { - if (stack != NULL) - free(stack); - free(kse); - return (NULL); - } - - /* Initialize the lockusers. */ - for (i = 0; i < MAX_KSE_LOCKLEVEL; i++) { - _lockuser_init(&kse->k_lockusers[i], (void *)kse); - _LCK_SET_PRIVATE2(&kse->k_lockusers[i], NULL); - } - /* _lock_init(kse->k_lock, ...) */ - - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - } - kse->k_flags = 0; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - if (curthread != NULL) { - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - /* - * Create the KSE context. - * Scope system threads (one thread per KSE) are not required - * to have a stack for an unneeded kse upcall. - */ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - kse->k_stack.ss_sp = stack; - kse->k_stack.ss_size = KSE_STACKSIZE; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - } - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - /* - * We need to keep a copy of the stack in case it - * doesn't get used; a KSE running a scope system - * thread will use that thread's stack. - */ - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - } - return (kse); -} - -static void -kse_reinit(struct kse *kse, int sys_scope) -{ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - if (kse->k_stack.ss_sp == NULL) { - /* XXX check allocation failure */ - kse->k_stack.ss_sp = (char *) malloc(KSE_STACKSIZE); - kse->k_stack.ss_size = KSE_STACKSIZE; - } - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - if (kse->k_stack.ss_sp) - free(kse->k_stack.ss_sp); - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - kse->k_kcb->kcb_kmbx.km_quantum = 0; - } - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse->k_curthread = NULL; - kse->k_kseg = 0; - kse->k_schedq = 0; - kse->k_locklevel = 0; - kse->k_flags = 0; - kse->k_error = 0; - kse->k_cpu = 0; - kse->k_sigseqno = 0; -} - -void -kse_free_unlocked(struct kse *kse) -{ - TAILQ_REMOVE(&active_kseq, kse, k_qe); - active_kse_count--; - kse->k_kseg = NULL; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - kse->k_flags = 0; - TAILQ_INSERT_HEAD(&free_kseq, kse, k_qe); - free_kse_count++; -} - -void -_kse_free(struct pthread *curthread, struct kse *kse) -{ - kse_critical_t crit; - - if (curthread == NULL) - kse_free_unlocked(kse); - else { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } -} - -static void -kse_destroy(struct kse *kse) -{ - int i; - - if (kse->k_stack.ss_sp != NULL) - free(kse->k_stack.ss_sp); - _kcb_dtor(kse->k_kcb); - for (i = 0; i < MAX_KSE_LOCKLEVEL; ++i) - _lockuser_destroy(&kse->k_lockusers[i]); - _lock_destroy(&kse->k_lock); - free(kse); -} - -struct pthread * -_thr_alloc(struct pthread *curthread) -{ - kse_critical_t crit; - struct pthread *thread = NULL; - int i; - - if (curthread != NULL) { - if (GC_NEEDED()) - _thr_gc(curthread); - if (free_thread_count > 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - if ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - free_thread_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } - } - if ((thread == NULL) && - ((thread = malloc(sizeof(struct pthread))) != NULL)) { - bzero(thread, sizeof(struct pthread)); - thread->siginfo = calloc(_SIG_MAXSIG, sizeof(siginfo_t)); - if (thread->siginfo == NULL) { - free(thread); - return (NULL); - } - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - thread->tcb = _tcb_ctor(thread, 0 /* not initial tls */); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - thread->tcb = _tcb_ctor(thread, 1 /* initial tls */); - } - if (thread->tcb == NULL) { - free(thread->siginfo); - free(thread); - return (NULL); - } - /* - * Initialize thread locking. - * Lock initializing needs malloc, so don't - * enter critical region before doing this! - */ - if (_lock_init(&thread->lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) - PANIC("Cannot initialize thread lock"); - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) { - _lockuser_init(&thread->lockusers[i], (void *)thread); - _LCK_SET_PRIVATE2(&thread->lockusers[i], - (void *)thread); - } - } - return (thread); -} - -void -_thr_free(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - - DBG_MSG("Freeing thread %p\n", thread); - if (thread->name) { - free(thread->name); - thread->name = NULL; - } - if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) { - thr_destroy(curthread, thread); - } else { - /* Add the thread to the free thread list. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - TAILQ_INSERT_TAIL(&free_threadq, thread, tle); - free_thread_count++; - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } -} - -static void -thr_destroy(struct pthread *curthread, struct pthread *thread) -{ - int i; - - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) - _lockuser_destroy(&thread->lockusers[i]); - _lock_destroy(&thread->lock); - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - _tcb_dtor(thread->tcb); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - _tcb_dtor(thread->tcb); - } - free(thread->siginfo); - free(thread); -} - -/* - * Add an active thread: - * - * o Assign the thread a unique id (which GDB uses to track - * threads. - * o Add the thread to the list of all threads and increment - * number of active threads. - */ -static void -thr_link(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * Initialize the unique id (which GDB uses to track - * threads), add the thread to the list of all threads, - * and - */ - thread->uniqueid = next_uniqueid++; - THR_LIST_ADD(thread); - _thread_active_threads++; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -/* - * Remove an active thread. - */ -static void -thr_unlink(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - THR_LIST_REMOVE(thread); - _thread_active_threads--; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -_thr_hash_add(struct pthread *thread) -{ - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_INSERT_HEAD(head, thread, hle); -} - -void -_thr_hash_remove(struct pthread *thread) -{ - LIST_REMOVE(thread, hle); -} - -struct pthread * -_thr_hash_find(struct pthread *thread) -{ - struct pthread *td; - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_FOREACH(td, head, hle) { - if (td == thread) - return (thread); - } - return (NULL); -} - -void -_thr_debug_check_yield(struct pthread *curthread) -{ - /* - * Note that TMDF_SUSPEND is set after process is suspended. - * When we are being debugged, every suspension in process - * will cause all KSEs to schedule an upcall in kernel, unless the - * KSE is in critical region. - * If the function is being called, it means the KSE is no longer - * in critical region, if the TMDF_SUSPEND is set by debugger - * before KSE leaves critical region, we will catch it here, else - * if the flag is changed during testing, it also not a problem, - * because the change only occurs after a process suspension event - * occurs. A suspension event will always cause KSE to schedule an - * upcall, in the case, because we are not in critical region, - * upcall will be scheduled sucessfully, the flag will be checked - * again in kse_sched_multi, we won't back until the flag - * is cleared by debugger, the flag will be cleared in next - * suspension event. - */ - if (!DBG_CAN_RUN(curthread)) { - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) - _thr_sched_switch(curthread); - else - kse_thr_interrupt(&curthread->tcb->tcb_tmbx, - KSE_INTR_DBSUSPEND, 0); - } -} diff --git a/lib/libkse/thread/thr_kill.c b/lib/libkse/thread/thr_kill.c deleted file mode 100644 index e543fea..0000000 --- a/lib/libkse/thread/thr_kill.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <signal.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_kill, pthread_kill); - -int -_pthread_kill(pthread_t pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Check for invalid signal numbers: */ - if (sig < 0 || sig > _SIG_MAXSIG) - /* Invalid signal: */ - ret = EINVAL; - /* - * 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 = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - if ((sig > 0) && - (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) - _thr_sig_send(pthread, sig); - _thr_ref_delete(curthread, pthread); - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_main_np.c b/lib/libkse/thread/thr_main_np.c deleted file mode 100644 index d3e7a43..0000000 --- a/lib/libkse/thread/thr_main_np.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2001 Alfred Perlstein - * Author: Alfred Perlstein <alfred@FreeBSD.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_main_np, pthread_main_np); - -/* - * Provide the equivelant to Solaris thr_main() function - */ -int -_pthread_main_np() -{ - - if (!_thr_initial) - return (-1); - else - return (_pthread_equal(_pthread_self(), _thr_initial) ? 1 : 0); -} diff --git a/lib/libkse/thread/thr_mattr_init.c b/lib/libkse/thread/thr_mattr_init.c deleted file mode 100644 index 50a968c..0000000 --- a/lib/libkse/thread/thr_mattr_init.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>. - * 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 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$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_init, pthread_mutexattr_init); - -int -_pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - int ret; - pthread_mutexattr_t pattr; - - if ((pattr = (pthread_mutexattr_t) - malloc(sizeof(struct pthread_mutex_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_mutexattr_default, - sizeof(struct pthread_mutex_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_mattr_kind_np.c b/lib/libkse/thread/thr_mattr_kind_np.c deleted file mode 100644 index 67d338e..0000000 --- a/lib/libkse/thread/thr_mattr_kind_np.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>. - * 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind); -int _pthread_mutexattr_getkind_np(pthread_mutexattr_t attr); - -__weak_reference(_pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np); -__weak_reference(_pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np); -__weak_reference(_pthread_mutexattr_gettype, pthread_mutexattr_gettype); -__weak_reference(_pthread_mutexattr_settype, pthread_mutexattr_settype); - -int -_pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind) -{ - int ret; - if (attr == NULL || *attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = kind; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_getkind_np(pthread_mutexattr_t attr) -{ - int ret; - if (attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - ret = attr->m_type; - } - return(ret); -} - -int -_pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) -{ - int ret; - if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = type; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type) -{ - int ret; - - if (attr == NULL || *attr == NULL || (*attr)->m_type >= - PTHREAD_MUTEX_TYPE_MAX) { - ret = EINVAL; - } else { - *type = (*attr)->m_type; - ret = 0; - } - return ret; -} diff --git a/lib/libkse/thread/thr_mattr_pshared.c b/lib/libkse/thread/thr_mattr_pshared.c deleted file mode 100644 index 12d731c..0000000 --- a/lib/libkse/thread/thr_mattr_pshared.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2005 David Xu <davidxu@freebsd.org> - * 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 unmodified, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$ - * - */ - -#include "namespace.h" -#include <errno.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared); -int _pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); - - -__weak_reference(_pthread_mutexattr_getpshared, pthread_mutexattr_getpshared); -__weak_reference(_pthread_mutexattr_setpshared, pthread_mutexattr_setpshared); - -int -_pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libkse/thread/thr_msync.c b/lib/libkse/thread/thr_msync.c deleted file mode 100644 index 8bb0017..0000000 --- a/lib/libkse/thread/thr_msync.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $ - * - * $FreeBSD$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/mman.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __msync(void *addr, size_t len, int flags); - -__weak_reference(__msync, msync); - -int -__msync(void *addr, size_t len, int flags) -{ - struct pthread *curthread = _get_curthread(); - 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. - */ - _thr_cancel_enter(curthread); - ret = __sys_msync(addr, len, flags); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_multi_np.c b/lib/libkse/thread/thr_multi_np.c deleted file mode 100644 index 0886540..0000000 --- a/lib/libkse/thread/thr_multi_np.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1996 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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_multi_np, pthread_multi_np); - -int -_pthread_multi_np() -{ - - /* Return to multi-threaded scheduling mode: */ - /* - * XXX - Do we want to do this? - * __is_threaded = 1; - */ - _pthread_resume_all_np(); - return (0); -} diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c deleted file mode 100644 index 228e650..0000000 --- a/lib/libkse/thread/thr_mutex.c +++ /dev/null @@ -1,1862 +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. 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 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <sys/param.h> -#include <sys/queue.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_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) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) do { \ - THR_ASSERT(((thr)->sflags & THR_FLAGS_IN_SYNCQ) == 0, \ - "thread in syncq when it shouldn't be."); \ -} while (0); -#else -#define MUTEX_INIT_LINK(m) -#define MUTEX_ASSERT_IS_OWNED(m) -#define MUTEX_ASSERT_NOT_OWNED(m) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) -#endif - -#define THR_IN_MUTEXQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0) -#define MUTEX_DESTROY(m) do { \ - _lock_destroy(&(m)->m_lock); \ - free(m); \ -} while (0) - - -/* - * Prototypes - */ -static struct kse_mailbox *mutex_handoff(struct pthread *, - struct pthread_mutex *); -static inline int mutex_self_trylock(pthread_mutex_t); -static inline int mutex_self_lock(struct pthread *, pthread_mutex_t); -static int mutex_unlock_common(pthread_mutex_t *, int); -static void mutex_priority_adjust(struct pthread *, pthread_mutex_t); -static void mutex_rescan_owned (struct pthread *, struct pthread *, - struct pthread_mutex *); -static inline pthread_t mutex_queue_deq(pthread_mutex_t); -static inline void mutex_queue_remove(pthread_mutex_t, pthread_t); -static inline void mutex_queue_enq(pthread_mutex_t, pthread_t); -static void mutex_lock_backout(void *arg); - -int __pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr); -int __pthread_mutex_trylock(pthread_mutex_t *mutex); -int __pthread_mutex_lock(pthread_mutex_t *m); -int __pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout); -int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, - void *(calloc_cb)(size_t, size_t)); - - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -/* Single underscore versions provided for libc internal usage: */ -__weak_reference(__pthread_mutex_init, pthread_mutex_init); -__weak_reference(__pthread_mutex_lock, pthread_mutex_lock); -__weak_reference(__pthread_mutex_timedlock, pthread_mutex_timedlock); -__weak_reference(__pthread_mutex_trylock, pthread_mutex_trylock); - -/* No difference between libc and application usage of these: */ -__weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy); -__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock); -__weak_reference(_pthread_mutex_isowned_np, pthread_mutex_isowned_np); - -static int -thr_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr, void *(calloc_cb)(size_t, size_t)) -{ - struct pthread_mutex *pmutex; - enum pthread_mutextype type; - int protocol; - int ceiling; - int flags; - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* Check if default mutex attributes: */ - else if (mutex_attr == NULL || *mutex_attr == NULL) { - /* Default to a (error checking) POSIX mutex: */ - type = PTHREAD_MUTEX_ERRORCHECK; - protocol = PTHREAD_PRIO_NONE; - ceiling = THR_MAX_PRIORITY; - flags = 0; - } - - /* Check mutex type: */ - else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) || - ((*mutex_attr)->m_type >= PTHREAD_MUTEX_TYPE_MAX)) - /* Return an invalid argument error: */ - ret = EINVAL; - - /* Check mutex protocol: */ - else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) || - ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE)) - /* Return an invalid argument error: */ - ret = EINVAL; - - else { - /* Use the requested mutex type and protocol: */ - type = (*mutex_attr)->m_type; - protocol = (*mutex_attr)->m_protocol; - ceiling = (*mutex_attr)->m_ceiling; - flags = (*mutex_attr)->m_flags; - } - - /* Check no errors so far: */ - if (ret == 0) { - if ((pmutex = (pthread_mutex_t) - calloc_cb(1, sizeof(struct pthread_mutex))) == NULL) - ret = ENOMEM; - else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup, calloc_cb) != 0) { - free(pmutex); - *mutex = NULL; - ret = ENOMEM; - } else { - /* Set the mutex flags: */ - pmutex->m_flags = flags; - - /* Process according to mutex type: */ - switch (type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - case PTHREAD_MUTEX_ADAPTIVE_NP: - /* Nothing to do here. */ - break; - - /* Single UNIX Spec 2 recursive mutex: */ - case PTHREAD_MUTEX_RECURSIVE: - /* Reset the mutex count: */ - pmutex->m_count = 0; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - if (ret == 0) { - /* Initialise the rest of the mutex: */ - TAILQ_INIT(&pmutex->m_queue); - pmutex->m_flags |= MUTEX_FLAGS_INITED; - pmutex->m_owner = NULL; - pmutex->m_type = type; - pmutex->m_protocol = protocol; - pmutex->m_refcount = 0; - if (protocol == PTHREAD_PRIO_PROTECT) - pmutex->m_prio = ceiling; - else - pmutex->m_prio = -1; - pmutex->m_saved_prio = 0; - MUTEX_INIT_LINK(pmutex); - *mutex = pmutex; - } else { - /* Free the mutex lock structure: */ - MUTEX_DESTROY(pmutex); - *mutex = NULL; - } - } - } - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - - return (thr_mutex_init(mutex, mutex_attr, calloc)); -} - -int -_pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - struct pthread_mutex_attr mattr, *mattrp; - - if ((mutex_attr == NULL) || (*mutex_attr == NULL)) - return (__pthread_mutex_init(mutex, &static_mattr)); - else { - mattr = **mutex_attr; - mattr.m_flags |= MUTEX_FLAGS_PRIVATE; - mattrp = &mattr; - return (__pthread_mutex_init(mutex, &mattrp)); - } -} - -/* This function is used internally by malloc. */ -int -_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, - void *(calloc_cb)(size_t, size_t)) -{ - static const struct pthread_mutex_attr attr = { - .m_type = PTHREAD_MUTEX_NORMAL, - .m_protocol = PTHREAD_PRIO_NONE, - .m_ceiling = 0, - .m_flags = 0 - }; - static const struct pthread_mutex_attr *pattr = &attr; - - return (thr_mutex_init(mutex, (pthread_mutexattr_t *)&pattr, - calloc_cb)); -} - -void -_thr_mutex_reinit(pthread_mutex_t *mutex) -{ - _lock_reinit(&(*mutex)->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup); - TAILQ_INIT(&(*mutex)->m_queue); - (*mutex)->m_owner = NULL; - (*mutex)->m_count = 0; - (*mutex)->m_refcount = 0; - (*mutex)->m_prio = 0; - (*mutex)->m_saved_prio = 0; -} - -int -_pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - pthread_mutex_t m; - int ret = 0; - - if (mutex == NULL || *mutex == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - - /* - * Check to see if this mutex is in use: - */ - if (((*mutex)->m_owner != NULL) || - (!TAILQ_EMPTY(&(*mutex)->m_queue)) || - ((*mutex)->m_refcount != 0)) { - ret = EBUSY; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - } else { - /* - * Save a pointer to the mutex so it can be free'd - * and set the caller's pointer to NULL: - */ - m = *mutex; - *mutex = NULL; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* - * Free the memory allocated for the mutex - * structure: - */ - MUTEX_ASSERT_NOT_OWNED(m); - MUTEX_DESTROY(m); - } - } - - /* Return the completion status: */ - return (ret); -} - -static int -init_static(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = _pthread_mutex_init(mutex, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -init_static_private(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = _pthread_mutex_init(mutex, &static_mattr); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -mutex_trylock_common(struct pthread *curthread, pthread_mutex_t *mutex) -{ - int private; - int ret = 0; - - THR_ASSERT((mutex != NULL) && (*mutex != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - private = (*mutex)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * 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; - } - - /* Process according to mutex type: */ - switch ((*mutex)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on the attributes of the - * running thread when there are no waiters. - */ - (*mutex)->m_prio = curthread->active_priority; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*mutex)->m_prio) - ret = EINVAL; - - /* Check if this mutex is not locked: */ - else if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. - */ - curthread->active_priority = (*mutex)->m_prio; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = - (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(*mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if (ret == 0 && private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*mutex != NULL) || - ((ret = init_static(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -int -_pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking the mutex private (delete safe): - */ - else if ((*mutex != NULL) || - ((ret = init_static_private(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -static int -mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, - const struct timespec * abstime) -{ - int private; - int ret = 0; - - THR_ASSERT((m != NULL) && (*m != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || - abstime->tv_nsec >= 1000000000)) - return (EINVAL); - - /* Reset the interrupted flag: */ - curthread->interrupted = 0; - curthread->timeout = 0; - curthread->wakeup_time.tv_sec = -1; - - private = (*m)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * Enter a loop waiting to become the mutex owner. We need a - * loop in case the waiting thread is interrupted by a signal - * to execute a signal handler. It is not (currently) possible - * to remain in the waiting queue while running a handler. - * Instead, the thread is interrupted and backed out of the - * waiting queue prior to executing the signal handler. - */ - do { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* - * If the mutex was statically allocated, properly - * initialize the tail queue. - */ - if (((*m)->m_flags & MUTEX_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*m)->m_queue); - (*m)->m_flags |= MUTEX_FLAGS_INITED; - MUTEX_INIT_LINK(*m); - } - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on attributes of the - * running thread when there are no waiters. - * Make sure the thread's scheduling lock is - * held while priorities are adjusted. - */ - (*m)->m_prio = curthread->active_priority; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - if (curthread->active_priority > (*m)->m_prio) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, *m); - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*m)->m_prio) { - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - ret = EINVAL; - } - /* Check if this mutex is not locked: */ - else if ((*m)->m_owner == NULL) { - /* - * Lock the mutex for the running - * thread: - */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. Make sure the thread's - * scheduling lock is held while priorities - * are adjusted. - */ - curthread->active_priority = (*m)->m_prio; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* Clear any previous error: */ - curthread->error = 0; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - - /* - * The threads priority may have changed while - * waiting for the mutex causing a ceiling - * violation. - */ - ret = curthread->error; - curthread->error = 0; - } - break; - - /* Trap invalid mutex types: */ - default: - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - } while (((*m)->m_owner != curthread) && (ret == 0) && - (curthread->interrupted == 0) && (curthread->timeout == 0)); - - if (ret == 0 && (*m)->m_owner != curthread && curthread->timeout) - ret = ETIMEDOUT; - - /* - * Check to see if this thread was interrupted and - * is still in the mutex queue of waiting threads: - */ - if (curthread->interrupted != 0) { - /* Remove this thread from the mutex queue. */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - if (THR_IN_SYNCQ(curthread)) - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Check for asynchronous cancellation. */ - if (curthread->continuation != NULL) - curthread->continuation((void *) curthread); - } - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -__strong_reference(__pthread_mutex_lock, _thr_mutex_lock); - -int -_pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -int -__pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 0)); -} - -__strong_reference(_pthread_mutex_unlock, _thr_mutex_unlock); - -int -_mutex_cv_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 1)); -} - -int -_mutex_cv_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - if ((ret = _pthread_mutex_lock(m)) == 0) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - (*m)->m_refcount--; - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - return (ret); -} - -static inline int -mutex_self_trylock(pthread_mutex_t m) -{ - int ret = 0; - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - case PTHREAD_MUTEX_ADAPTIVE_NP: - ret = EBUSY; - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static inline int -mutex_self_lock(struct pthread *curthread, pthread_mutex_t m) -{ - int ret = 0; - - /* - * Don't allow evil recursive mutexes for private use - * in libc and libpthread. - */ - if (m->m_flags & MUTEX_FLAGS_PRIVATE) - PANIC("Recurse on a private mutex."); - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_ADAPTIVE_NP: - /* - * POSIX specifies that mutexes should return EDEADLK if a - * recursive lock is detected. - */ - ret = EDEADLK; - break; - - case PTHREAD_MUTEX_NORMAL: - /* - * What SS2 define as a 'normal' mutex. Intentionally - * deadlock on attempts to get a lock you already own. - */ - - THR_SCHED_LOCK(curthread, curthread); - THR_SET_STATE(curthread, PS_DEADLOCK); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static int -mutex_unlock_common(pthread_mutex_t *m, int add_reference) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - int ret = 0; - - if (m == NULL || *m == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority ceiling mutex: */ - case PTHREAD_PRIO_PROTECT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if ((ret == 0) && (add_reference != 0)) - /* Increment the reference count: */ - (*m)->m_refcount++; - - /* Leave the critical region if this is a private mutex. */ - if ((ret == 0) && ((*m)->m_flags & MUTEX_FLAGS_PRIVATE)) - THR_CRITICAL_LEAVE(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (ret); -} - - -/* - * 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 without the target thread's scheduling lock held. - */ -void -_mutex_notify_priochange(struct pthread *curthread, struct pthread *pthread, - int propagate_prio) -{ - struct pthread_mutex *m; - - /* Adjust the priorites of any owned priority mutexes: */ - if (pthread->priority_mutex_count > 0) { - /* - * Rescan the mutexes owned by this thread and correct - * their priorities to account for this threads change - * in priority. This has the side effect of changing - * the threads active priority. - * - * Be sure to lock the first mutex in the list of owned - * mutexes. This acts as a barrier against another - * simultaneous call to change the threads priority - * and from the owning thread releasing the mutex. - */ - m = TAILQ_FIRST(&pthread->mutexq); - if (m != NULL) { - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - /* - * Make sure the thread still owns the lock. - */ - if (m == TAILQ_FIRST(&pthread->mutexq)) - mutex_rescan_owned(curthread, pthread, - /* rescan all owned */ NULL); - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - - /* - * If this thread is waiting on a priority inheritence mutex, - * check for priority adjustments. A change in priority can - * also cause a ceiling violation(*) for a thread waiting on - * a priority protection mutex; we don't perform the check here - * as it is done in pthread_mutex_unlock. - * - * (*) It should be noted that a priority change to a thread - * _after_ taking and owning a priority ceiling mutex - * does not affect ownership of that mutex; the ceiling - * priority is only checked before mutex ownership occurs. - */ - if (propagate_prio != 0) { - /* - * Lock the thread's scheduling queue. This is a bit - * convoluted; the "in synchronization queue flag" can - * only be cleared with both the thread's scheduling and - * mutex locks held. The thread's pointer to the wanted - * mutex is guaranteed to be valid during this time. - */ - THR_SCHED_LOCK(curthread, pthread); - - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) == 0) || - ((m = pthread->data.mutex) == NULL)) - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * This thread is currently waiting on a mutex; unlock - * the scheduling queue lock and lock the mutex. We - * can't hold both at the same time because the locking - * order could cause a deadlock. - */ - THR_SCHED_UNLOCK(curthread, pthread); - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Check to make sure this thread is still in the - * same state (the lock above can yield the CPU to - * another thread or the thread may be running on - * another CPU). - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (pthread->data.mutex == m)) { - /* - * Remove and reinsert this thread into - * the list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - if (m->m_protocol == PTHREAD_PRIO_INHERIT) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, m); - } - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } -} - -/* - * Called when a new thread is added to the mutex waiting queue or - * when a threads priority changes that is already in the mutex - * waiting queue. - * - * This must be called with the mutex locked by the current thread. - */ -static void -mutex_priority_adjust(struct pthread *curthread, pthread_mutex_t mutex) -{ - pthread_mutex_t m = mutex; - struct pthread *pthread_next, *pthread = mutex->m_owner; - int done, temp_prio; - - /* - * Calculate the mutex priority as the maximum of the highest - * active priority of any waiting threads and the owning threads - * active priority(*). - * - * (*) Because the owning threads current active priority may - * reflect priority inherited from this mutex (and the mutex - * priority may have changed) we must recalculate the active - * priority based on the threads saved inherited priority - * and its base priority. - */ - pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, pthread->base_priority)); - - /* See if this mutex really needs adjusting: */ - if (temp_prio == m->m_prio) - /* No need to propagate the priority: */ - return; - - /* Set new priority of the mutex: */ - m->m_prio = temp_prio; - - /* - * Don't unlock the mutex passed in as an argument. It is - * expected to be locked and unlocked by the caller. - */ - done = 1; - do { - /* - * Save the threads priority before rescanning the - * owned mutexes: - */ - temp_prio = pthread->active_priority; - - /* - * Fix the priorities for all mutexes held by the owning - * thread since taking this mutex. This also has a - * potential side-effect of changing the threads priority. - * - * At this point the mutex is locked by the current thread. - * The owning thread can't release the mutex until it is - * unlocked, so we should be able to safely walk its list - * of owned mutexes. - */ - mutex_rescan_owned(curthread, pthread, m); - - /* - * If this isn't the first time through the loop, - * the current mutex needs to be unlocked. - */ - if (done == 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Assume we're done unless told otherwise: */ - done = 1; - - /* - * If the thread is currently waiting on a mutex, check - * to see if the threads new priority has affected the - * priority of the mutex. - */ - if ((temp_prio != pthread->active_priority) && - ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - ((m = pthread->data.mutex) != NULL) && - (m->m_protocol == PTHREAD_PRIO_INHERIT)) { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Make sure the thread is still waiting on the - * mutex: - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (m == pthread->data.mutex)) { - /* - * The priority for this thread has changed. - * Remove and reinsert this thread into the - * list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - /* - * Grab the waiting thread with highest - * priority: - */ - pthread_next = TAILQ_FIRST(&m->m_queue); - - /* - * Calculate the mutex priority as the maximum - * of the highest active priority of any - * waiting threads and the owning threads - * active priority. - */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, - m->m_owner->base_priority)); - - if (temp_prio != m->m_prio) { - /* - * The priority needs to be propagated - * to the mutex this thread is waiting - * on and up to the owner of that mutex. - */ - m->m_prio = temp_prio; - pthread = m->m_owner; - - /* We're not done yet: */ - done = 0; - } - } - /* Only release the mutex if we're done: */ - if (done != 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } while (done == 0); -} - -static void -mutex_rescan_owned(struct pthread *curthread, struct pthread *pthread, - struct pthread_mutex *mutex) -{ - struct pthread_mutex *m; - struct pthread *pthread_next; - int active_prio, inherited_prio; - - /* - * Start walking the mutexes the thread has taken since - * taking this mutex. - */ - if (mutex == NULL) { - /* - * A null mutex means start at the beginning of the owned - * mutex list. - */ - m = TAILQ_FIRST(&pthread->mutexq); - - /* There is no inherited priority yet. */ - inherited_prio = 0; - } else { - /* - * The caller wants to start after a specific mutex. It - * is assumed that this mutex is a priority inheritence - * mutex and that its priority has been correctly - * calculated. - */ - m = TAILQ_NEXT(mutex, m_qe); - - /* Start inheriting priority from the specified mutex. */ - inherited_prio = mutex->m_prio; - } - active_prio = MAX(inherited_prio, pthread->base_priority); - - for (; m != NULL; m = TAILQ_NEXT(m, m_qe)) { - /* - * We only want to deal with priority inheritence - * mutexes. This might be optimized by only placing - * priority inheritence mutexes into the owned mutex - * list, but it may prove to be useful having all - * owned mutexes in this list. Consider a thread - * exiting while holding mutexes... - */ - if (m->m_protocol == PTHREAD_PRIO_INHERIT) { - /* - * Fix the owners saved (inherited) priority to - * reflect the priority of the previous mutex. - */ - m->m_saved_prio = inherited_prio; - - if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL) - /* Recalculate the priority of the mutex: */ - m->m_prio = MAX(active_prio, - pthread_next->active_priority); - else - m->m_prio = active_prio; - - /* Recalculate new inherited and active priorities: */ - inherited_prio = m->m_prio; - active_prio = MAX(m->m_prio, pthread->base_priority); - } - } - - /* - * Fix the threads inherited priority and recalculate its - * active priority. - */ - pthread->inherited_priority = inherited_prio; - active_prio = MAX(inherited_prio, pthread->base_priority); - - if (active_prio != pthread->active_priority) { - /* Lock the thread's scheduling queue: */ - THR_SCHED_LOCK(curthread, pthread); - - if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - /* - * This thread is not in a run queue. Just set - * its active priority. - */ - pthread->active_priority = active_prio; - } - else { - /* - * This thread is in a run queue. Remove it from - * the queue before changing its priority: - */ - THR_RUNQ_REMOVE(pthread); - - /* - * POSIX states that if the priority is being - * lowered, the thread must be inserted at the - * head of the queue for its priority if it owns - * any priority protection or inheritence mutexes. - */ - if ((active_prio < pthread->active_priority) && - (pthread->priority_mutex_count > 0)) { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_HEAD(pthread); - } else { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_TAIL(pthread); - } - } - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -void -_mutex_unlock_private(pthread_t pthread) -{ - struct pthread_mutex *m, *m_next; - - for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) { - m_next = TAILQ_NEXT(m, m_qe); - if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0) - _pthread_mutex_unlock(&m); - } -} - -/* - * This is called by the current thread when it wants to back out of a - * mutex_lock in order to run a signal handler. - */ -static void -mutex_lock_backout(void *arg) -{ - struct pthread *curthread = (struct pthread *)arg; - struct pthread_mutex *m; - - if ((curthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - /* - * Any other thread may clear the "in sync queue flag", - * but only the current thread can clear the pointer - * to the mutex. So if the flag is set, we can - * guarantee that the pointer to the mutex is valid. - * The only problem may be if the mutex is destroyed - * out from under us, but that should be considered - * an application bug. - */ - m = curthread->data.mutex; - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - - /* - * Check to make sure this thread doesn't already own - * the mutex. Since mutexes are unlocked with direct - * handoffs, it is possible the previous owner gave it - * to us after we checked the sync queue flag and before - * we locked the mutex structure. - */ - if (m->m_owner == curthread) { - THR_LOCK_RELEASE(curthread, &m->m_lock); - mutex_unlock_common(&m, /* add_reference */ 0); - } else { - /* - * Remove ourselves from the mutex queue and - * clear the pointer to the mutex. We may no - * longer be in the mutex queue, but the removal - * function will DTRT. - */ - mutex_queue_remove(m, curthread); - curthread->data.mutex = NULL; - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - /* No need to call this again. */ - curthread->sigbackout = NULL; -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - * - * In order to properly dequeue a thread from the mutex queue and - * make it runnable without the possibility of errant wakeups, it - * is necessary to lock the thread's scheduling queue while also - * holding the mutex lock. - */ -static struct kse_mailbox * -mutex_handoff(struct pthread *curthread, struct pthread_mutex *mutex) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - - /* Keep dequeueing until we find a valid thread: */ - mutex->m_owner = NULL; - pthread = TAILQ_FIRST(&mutex->m_queue); - while (pthread != NULL) { - /* Take the thread's scheduling lock: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Remove the thread from the mutex queue: */ - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - switch (mutex->m_protocol) { - case PTHREAD_PRIO_NONE: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - break; - - case PTHREAD_PRIO_INHERIT: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Set the priority of the mutex. Since our waiting - * threads are in descending priority order, the - * priority of the mutex becomes the active priority - * of the thread we just dequeued. - */ - mutex->m_prio = pthread->active_priority; - - /* Save the owning threads inherited priority: */ - mutex->m_saved_prio = pthread->inherited_priority; - - /* - * The owning threads inherited priority now becomes - * his active priority (the priority of the mutex). - */ - pthread->inherited_priority = mutex->m_prio; - break; - - case PTHREAD_PRIO_PROTECT: - if (pthread->active_priority > mutex->m_prio) { - /* - * Either the mutex ceiling priority has - * been lowered and/or this threads priority - * has been raised subsequent to the thread - * being queued on the waiting list. - */ - pthread->error = EINVAL; - } - else { - /* - * Assign the new owner and add the mutex - * to the thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, - mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Save the owning threads inherited - * priority: - */ - mutex->m_saved_prio = - pthread->inherited_priority; - - /* - * The owning thread inherits the ceiling - * priority of the mutex and executes at - * that priority: - */ - pthread->inherited_priority = mutex->m_prio; - pthread->active_priority = mutex->m_prio; - - } - break; - } - - /* Make the thread runnable and unlock the scheduling queue: */ - kmbx = _thr_setrunnable_unlocked(pthread); - - /* Add a preemption point. */ - if ((curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - - if (mutex->m_owner == pthread) { - /* We're done; a valid owner was found. */ - if (mutex->m_flags & MUTEX_FLAGS_PRIVATE) - THR_CRITICAL_ENTER(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - break; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* Get the next thread from the waiting queue: */ - pthread = TAILQ_NEXT(pthread, sqe); - } - - if ((pthread == NULL) && (mutex->m_protocol == PTHREAD_PRIO_INHERIT)) - /* This mutex has no priority: */ - mutex->m_prio = 0; - return (kmbx); -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - */ -static inline pthread_t -mutex_queue_deq(struct pthread_mutex *mutex) -{ - pthread_t pthread; - - while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - if (pthread->interrupted == 0) - break; - } - - return (pthread); -} - -/* - * Remove a waiting thread from a mutex queue in descending priority order. - */ -static inline void -mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread) -{ - if ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - } -} - -/* - * Enqueue a waiting thread to a queue in descending priority order. - */ -static inline void -mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread) -{ - pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head); - - THR_ASSERT_NOT_IN_SYNCQ(pthread); - /* - * For the common case of all threads having equal priority, - * we perform a quick check against the priority of the thread - * at the tail of the queue. - */ - if ((tid == NULL) || (pthread->active_priority <= tid->active_priority)) - TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, sqe); - else { - tid = TAILQ_FIRST(&mutex->m_queue); - while (pthread->active_priority <= tid->active_priority) - tid = TAILQ_NEXT(tid, sqe); - TAILQ_INSERT_BEFORE(tid, pthread, sqe); - } - pthread->sflags |= THR_FLAGS_IN_SYNCQ; -} - -int -_pthread_mutex_isowned_np(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - - return ((*mutex)->m_owner == curthread); -} - diff --git a/lib/libkse/thread/thr_mutex_prioceiling.c b/lib/libkse/thread/thr_mutex_prioceiling.c deleted file mode 100644 index 7f1caf3..0000000 --- a/lib/libkse/thread/thr_mutex_prioceiling.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling); -__weak_reference(_pthread_mutexattr_setprioceiling, pthread_mutexattr_setprioceiling); -__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling); -__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling); - -int -_pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - *prioceiling = (*mattr)->m_ceiling; - - return(ret); -} - -int -_pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - (*mattr)->m_ceiling = prioceiling; - - return(ret); -} - -int -_pthread_mutex_getprioceiling(pthread_mutex_t *mutex, - int *prioceiling) -{ - int ret; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else { - *prioceiling = (*mutex)->m_prio; - ret = 0; - } - return (ret); -} - -int -_pthread_mutex_setprioceiling(pthread_mutex_t *mutex, - int prioceiling, int *old_ceiling) -{ - int ret = 0; - int tmp; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - /* Lock the mutex: */ - else if ((ret = _pthread_mutex_lock(mutex)) == 0) { - tmp = (*mutex)->m_prio; - /* Set the new ceiling: */ - (*mutex)->m_prio = prioceiling; - - /* Unlock the mutex: */ - ret = _pthread_mutex_unlock(mutex); - - /* Return the old ceiling: */ - *old_ceiling = tmp; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_mutex_protocol.c b/lib/libkse/thread/thr_mutex_protocol.c deleted file mode 100644 index 6ec2239..0000000 --- a/lib/libkse/thread/thr_mutex_protocol.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_getprotocol, pthread_mutexattr_getprotocol); -__weak_reference(_pthread_mutexattr_setprotocol, pthread_mutexattr_setprotocol); - -int -_pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else - *protocol = (*mattr)->m_protocol; - - return(ret); -} - -int -_pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL) || - (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT)) - ret = EINVAL; - else { - (*mattr)->m_protocol = protocol; - (*mattr)->m_ceiling = THR_MAX_PRIORITY; - } - return(ret); -} - diff --git a/lib/libkse/thread/thr_mutexattr_destroy.c b/lib/libkse/thread/thr_mutexattr_destroy.c deleted file mode 100644 index 8e0537e..0000000 --- a/lib/libkse/thread/thr_mutexattr_destroy.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_destroy, pthread_mutexattr_destroy); - -int -_pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libkse/thread/thr_nanosleep.c b/lib/libkse/thread/thr_nanosleep.c deleted file mode 100644 index b8210af..0000000 --- a/lib/libkse/thread/thr_nanosleep.c +++ /dev/null @@ -1,134 +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. 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 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$ - */ - -#include "namespace.h" -#include <stdio.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining); - -__weak_reference(__nanosleep, nanosleep); - -int -_nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - struct timespec ts, ts1; - struct timespec remaining_time; - struct timespec wakeup_time; - - /* Check if the time to sleep is legal: */ - 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 { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_nanosleep(time_to_sleep, time_remaining)); - - KSE_GET_TOD(curthread->kse, &ts); - - /* Calculate the time for the current thread to wake up: */ - TIMESPEC_ADD(&wakeup_time, &ts, time_to_sleep); - - THR_LOCK_SWITCH(curthread); - curthread->interrupted = 0; - curthread->wakeup_time = wakeup_time; - THR_SET_STATE(curthread, PS_SLEEP_WAIT); - - /* Reschedule the current thread to sleep: */ - _thr_sched_switch_unlocked(curthread); - - /* Calculate the remaining time to sleep: */ - KSE_GET_TOD(curthread->kse, &ts1); - remaining_time.tv_sec = time_to_sleep->tv_sec - + ts.tv_sec - ts1.tv_sec; - remaining_time.tv_nsec = time_to_sleep->tv_nsec - + ts.tv_nsec - ts1.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: */ - else 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: */ - remaining_time.tv_sec = 0; - remaining_time.tv_nsec = 0; - } - - /* Check if the time remaining is to be returned: */ - if (time_remaining != NULL) { - /* Return the actual time slept: */ - time_remaining->tv_sec = remaining_time.tv_sec; - time_remaining->tv_nsec = remaining_time.tv_nsec; - } - - /* Check if the sleep was interrupted: */ - if (curthread->interrupted) { - /* Return an EINTR error : */ - errno = EINTR; - ret = -1; - } - } - return (ret); -} - -int -__nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _nanosleep(time_to_sleep, time_remaining); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_once.c b/lib/libkse/thread/thr_once.c deleted file mode 100644 index eae29ac..0000000 --- a/lib/libkse/thread/thr_once.c +++ /dev/null @@ -1,96 +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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_once, pthread_once); - -#define ONCE_NEVER_DONE PTHREAD_NEEDS_INIT -#define ONCE_DONE PTHREAD_DONE_INIT -#define ONCE_IN_PROGRESS 0x02 -#define ONCE_MASK 0x03 - -static pthread_mutex_t once_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER; - -/* - * POSIX: - * The pthread_once() function is not a cancellation point. However, - * if init_routine is a cancellation point and is canceled, the effect - * on once_control shall be as if pthread_once() was never called. - */ - -static void -once_cancel_handler(void *arg) -{ - pthread_once_t *once_control = arg; - - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_NEVER_DONE; - _pthread_mutex_unlock(&once_lock); - _pthread_cond_broadcast(&once_cv); -} - -int -_pthread_once(pthread_once_t *once_control, void (*init_routine) (void)) -{ - struct pthread *curthread; - int wakeup = 0; - - if (once_control->state == ONCE_DONE) - return (0); - _pthread_mutex_lock(&once_lock); - while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS) - _pthread_cond_wait(&once_cv, &once_lock); - /* - * If previous thread was canceled, then the state still - * could be ONCE_NEVER_DONE, we need to check it again. - */ - if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) { - once_control->state = ONCE_IN_PROGRESS; - _pthread_mutex_unlock(&once_lock); - curthread = _get_curthread(); - THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control); - init_routine(); - THR_CLEANUP_POP(curthread, 0); - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_DONE; - wakeup = 1; - } - _pthread_mutex_unlock(&once_lock); - if (wakeup) - _pthread_cond_broadcast(&once_cv); - return (0); -} - diff --git a/lib/libkse/thread/thr_open.c b/lib/libkse/thread/thr_open.c deleted file mode 100644 index d60763b..0000000 --- a/lib/libkse/thread/thr_open.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - * - */ - -#include "namespace.h" -#include <stdarg.h> -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __open(const char *path, int flags,...); - -__weak_reference(__open, open); - -int -__open(const char *path, int flags,...) -{ - struct pthread *curthread = _get_curthread(); - int ret; - int mode = 0; - va_list ap; - - _thr_cancel_enter(curthread); - - /* Check if the file is being created: */ - if (flags & O_CREAT) { - /* Get the creation mode: */ - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } - - ret = __sys_open(path, flags, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libkse/thread/thr_pause.c b/lib/libkse/thread/thr_pause.c deleted file mode 100644 index fda1e2e..0000000 --- a/lib/libkse/thread/thr_pause.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pause(void); - -extern int __pause(void); - -__weak_reference(_pause, pause); - -int -_pause(void) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pause(); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_poll.c b/lib/libkse/thread/thr_poll.c deleted file mode 100644 index 03f11ce..0000000 --- a/lib/libkse/thread/thr_poll.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com> - * 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 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$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <poll.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/fcntl.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __poll(struct pollfd *fds, unsigned int nfds, int timeout); - -__weak_reference(__poll, poll); - -int -__poll(struct pollfd *fds, unsigned int nfds, int timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_poll(fds, nfds, timeout); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_printf.c b/lib/libkse/thread/thr_printf.c deleted file mode 100644 index 2a4b12b..0000000 --- a/lib/libkse/thread/thr_printf.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdarg.h> -#include <string.h> -#include <unistd.h> - -#include "thr_private.h" - -static void pchar(int fd, char c); -static void pstr(int fd, const char *s); - -/* - * Write formatted output to stdout, in a thread-safe manner. - * - * Recognises the following conversions: - * %c -> char - * %d -> signed int (base 10) - * %s -> string - * %u -> unsigned int (base 10) - * %x -> unsigned int (base 16) - * %p -> unsigned int (base 16) - */ -void -_thread_printf(int fd, const char *fmt, ...) -{ - static const char digits[16] = "0123456789abcdef"; - va_list ap; - char buf[20]; - char *s; - unsigned long r, u; - int c; - long d; - int islong; - - va_start(ap, fmt); - while ((c = *fmt++)) { - islong = 0; - if (c == '%') { -next: c = *fmt++; - if (c == '\0') - goto out; - switch (c) { - case 'c': - pchar(fd, va_arg(ap, int)); - continue; - case 's': - pstr(fd, va_arg(ap, char *)); - continue; - case 'l': - islong = 1; - goto next; - case 'p': - islong = 1; - case 'd': - case 'u': - case 'x': - r = ((c == 'u') || (c == 'd')) ? 10 : 16; - if (c == 'd') { - if (islong) - d = va_arg(ap, unsigned long); - else - d = va_arg(ap, unsigned); - if (d < 0) { - pchar(fd, '-'); - u = (unsigned long)(d * -1); - } else - u = (unsigned long)d; - } else { - if (islong) - u = va_arg(ap, unsigned long); - else - u = va_arg(ap, unsigned); - } - s = buf; - do { - *s++ = digits[u % r]; - } while (u /= r); - while (--s >= buf) - pchar(fd, *s); - continue; - } - } - pchar(fd, c); - } -out: - va_end(ap); -} - -/* - * Write a single character to stdout, in a thread-safe manner. - */ -static void -pchar(int fd, char c) -{ - - __sys_write(fd, &c, 1); -} - -/* - * Write a string to stdout, in a thread-safe manner. - */ -static void -pstr(int fd, const char *s) -{ - - __sys_write(fd, s, strlen(s)); -} - diff --git a/lib/libkse/thread/thr_priority_queue.c b/lib/libkse/thread/thr_priority_queue.c deleted file mode 100644 index e7d6f57..0000000 --- a/lib/libkse/thread/thr_priority_queue.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <sys/queue.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Prototypes: */ -static void pq_insert_prio_list(pq_queue_t *pq, int prio); - -#if defined(_PTHREADS_INVARIANTS) - -#define PQ_IN_SCHEDQ (THR_FLAGS_IN_RUNQ | THR_FLAGS_IN_WAITQ) - -#define PQ_SET_ACTIVE(pq) (pq)->pq_flags |= PQF_ACTIVE -#define PQ_CLEAR_ACTIVE(pq) (pq)->pq_flags &= ~PQF_ACTIVE -#define PQ_ASSERT_ACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_INACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) != 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_RUNQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \ - if (((thrd)->flags & PQ_IN_SCHEDQ) != 0) \ - PANIC(msg); \ -} while (0) - -#else - -#define PQ_SET_ACTIVE(pq) -#define PQ_CLEAR_ACTIVE(pq) -#define PQ_ASSERT_ACTIVE(pq, msg) -#define PQ_ASSERT_INACTIVE(pq, msg) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) - -#endif - -int -_pq_alloc(pq_queue_t *pq, int minprio, int maxprio) -{ - int ret = 0; - int prioslots = maxprio - minprio + 1; - - if (pq == NULL) - ret = -1; - - /* Create the priority queue with (maxprio - minprio + 1) slots: */ - else if ((pq->pq_lists = - (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL) - ret = -1; - - else { - /* Remember the queue size: */ - pq->pq_size = prioslots; - ret = _pq_init(pq); - } - return (ret); -} - -void -_pq_free(pq_queue_t *pq) -{ - if ((pq != NULL) && (pq->pq_lists != NULL)) - free(pq->pq_lists); -} - -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 < 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; - } - /* Initialize the priority queue: */ - TAILQ_INIT(&pq->pq_queue); - pq->pq_flags = 0; - pq->pq_threads = 0; - } - return (ret); -} - -void -_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, "_pq_remove: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_IN_RUNQ(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); - pq->pq_threads--; - /* This thread is now longer in the priority queue. */ - pthread->flags &= ~THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_head(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_head: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_head: Already in priority queue"); - - prio = pthread->active_priority; - 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); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_tail(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_tail: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_tail: Already in priority queue"); - - prio = pthread->active_priority; - 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); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -pthread_t -_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, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) && - (pthread == NULL)) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -/* - * Select a thread which is allowed to run by debugger, we probably - * should merge the function into _pq_first if that function is only - * used by scheduler to select a thread. - */ -pthread_t -_pq_first_debug(pq_queue_t *pq) -{ - pq_list_t *pql, *pqlnext = NULL; - pthread_t pthread = NULL; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - for (pql = TAILQ_FIRST(&pq->pq_queue); - pql != NULL && pthread == NULL; pql = pqlnext) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - pqlnext = TAILQ_NEXT(pql, pl_link); - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } else { - /* - * note there may be a suspension event during this - * test, If TMDF_SUSPEND is set after we tested it, - * we will run the thread, this seems be a problem, - * fortunatly, when we are being debugged, all context - * switch will be done by kse_switchin, that is a - * syscall, kse_switchin will check the flag again, - * the thread will be returned via upcall, so next - * time, UTS won't run the thread. - */ - while (pthread != NULL && !DBG_CAN_RUN(pthread)) { - pthread = TAILQ_NEXT(pthread, pqe); - } - if (pthread == NULL) - pqlnext = TAILQ_NEXT(pql, pl_link); - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -static void -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, "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 be inserted. - */ - pql = TAILQ_FIRST(&pq->pq_queue); - while ((pql != NULL) && (pql->pl_prio > prio)) - pql = TAILQ_NEXT(pql, pl_link); - - /* Insert the list: */ - if (pql == NULL) - TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link); - else - TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link); - - /* Mark this list as being in the queue: */ - pq->pq_lists[prio].pl_queued = 1; -} diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h deleted file mode 100644 index 46f6e80..0000000 --- a/lib/libkse/thread/thr_private.h +++ /dev/null @@ -1,1294 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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. - * - * Private thread definitions for the uthread kernel. - * - * $FreeBSD$ - */ - -#ifndef _THR_PRIVATE_H -#define _THR_PRIVATE_H - -/* - * Include files. - */ -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <sys/queue.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/cdefs.h> -#include <sys/kse.h> -#include <sched.h> -#include <ucontext.h> -#include <unistd.h> -#include <pthread.h> -#include <pthread_np.h> - -#ifndef LIBTHREAD_DB -#include "lock.h" -#include "pthread_md.h" -#endif - - -/* - * Evaluate the storage class specifier. - */ -#ifdef GLOBAL_PTHREAD_PRIVATE -#define SCLASS -#define SCLASS_PRESET(x...) = x -#else -#define SCLASS extern -#define SCLASS_PRESET(x...) -#endif - -/* - * Kernel fatal error handler macro. - */ -#define PANIC(string) _thr_exit(__FILE__, __LINE__, string) - - -/* Output debug messages like this: */ -#ifdef STDOUT_FILENO -#define stdout_debug(...) _thread_printf(STDOUT_FILENO, __VA_ARGS__) -#endif -#ifdef STDERR_FILENO -#define stderr_debug(...) _thread_printf(STDERR_FILENO, __VA_ARGS__) -#endif - -#define DBG_MUTEX 0x0001 -#define DBG_SIG 0x0002 -#define DBG_INFO_DUMP 0x0004 - -#ifdef _PTHREADS_INVARIANTS -#define THR_ASSERT(cond, msg) do { \ - if (!(cond)) \ - PANIC(msg); \ -} while (0) -#else -#define THR_ASSERT(cond, msg) -#endif - -/* - * State change macro without scheduling queue change: - */ -#define THR_SET_STATE(thrd, newstate) do { \ - (thrd)->state = newstate; \ - (thrd)->fname = __FILE__; \ - (thrd)->lineno = __LINE__; \ -} while (0) - - -#define TIMESPEC_ADD(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec + (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \ - if ((dst)->tv_nsec >= 1000000000) { \ - (dst)->tv_sec++; \ - (dst)->tv_nsec -= 1000000000; \ - } \ - } while (0) - -#define TIMESPEC_SUB(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec - (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \ - if ((dst)->tv_nsec < 0) { \ - (dst)->tv_sec--; \ - (dst)->tv_nsec += 1000000000; \ - } \ - } while (0) - -/* - * Priority queues. - * - * XXX It'd be nice if these were contained in uthread_priority_queue.[ch]. - */ -typedef struct pq_list { - TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */ - TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */ - int pl_prio; /* the priority of this list */ - int pl_queued; /* is this in the priority queue */ -} pq_list_t; - -typedef struct pq_queue { - TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */ - pq_list_t *pq_lists; /* array of all priority lists */ - int pq_size; /* number of priority lists */ -#define PQF_ACTIVE 0x0001 - int pq_flags; - int pq_threads; -} pq_queue_t; - -/* - * Each KSEG has a scheduling queue. For now, threads that exist in their - * own KSEG (system scope) will get a full priority queue. In the future - * this can be optimized for the single thread per KSEG case. - */ -struct sched_queue { - pq_queue_t sq_runq; - TAILQ_HEAD(, pthread) sq_waitq; /* waiting in userland */ -}; - -typedef struct kse_thr_mailbox *kse_critical_t; - -struct kse_group; - -#define MAX_KSE_LOCKLEVEL 5 -struct kse { - /* -- location and order specific items for gdb -- */ - struct kcb *k_kcb; - struct pthread *k_curthread; /* current thread */ - struct kse_group *k_kseg; /* parent KSEG */ - struct sched_queue *k_schedq; /* scheduling queue */ - /* -- end of location and order specific items -- */ - TAILQ_ENTRY(kse) k_qe; /* KSE list link entry */ - TAILQ_ENTRY(kse) k_kgqe; /* KSEG's KSE list entry */ - /* - * Items that are only modified by the kse, or that otherwise - * don't need to be locked when accessed - */ - struct lock k_lock; - struct lockuser k_lockusers[MAX_KSE_LOCKLEVEL]; - int k_locklevel; - stack_t k_stack; - int k_flags; -#define KF_STARTED 0x0001 /* kernel kse created */ -#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */ -#define KF_TERMINATED 0x0004 /* kse is terminated */ -#define KF_IDLE 0x0008 /* kse is idle */ -#define KF_SWITCH 0x0010 /* thread switch in UTS */ - int k_error; /* syscall errno in critical */ - int k_cpu; /* CPU ID when bound */ - int k_sigseqno; /* signal buffered count */ -}; - -#define KSE_SET_IDLE(kse) ((kse)->k_flags |= KF_IDLE) -#define KSE_CLEAR_IDLE(kse) ((kse)->k_flags &= ~KF_IDLE) -#define KSE_IS_IDLE(kse) (((kse)->k_flags & KF_IDLE) != 0) -#define KSE_SET_SWITCH(kse) ((kse)->k_flags |= KF_SWITCH) -#define KSE_CLEAR_SWITCH(kse) ((kse)->k_flags &= ~KF_SWITCH) -#define KSE_IS_SWITCH(kse) (((kse)->k_flags & KF_SWITCH) != 0) - -/* - * Each KSE group contains one or more KSEs in which threads can run. - * At least for now, there is one scheduling queue per KSE group; KSEs - * within the same KSE group compete for threads from the same scheduling - * queue. A scope system thread has one KSE in one KSE group; the group - * does not use its scheduling queue. - */ -struct kse_group { - TAILQ_HEAD(, kse) kg_kseq; /* list of KSEs in group */ - TAILQ_HEAD(, pthread) kg_threadq; /* list of threads in group */ - TAILQ_ENTRY(kse_group) kg_qe; /* link entry */ - struct sched_queue kg_schedq; /* scheduling queue */ - struct lock kg_lock; - int kg_threadcount; /* # of assigned threads */ - int kg_ksecount; /* # of assigned KSEs */ - int kg_idle_kses; - int kg_flags; -#define KGF_SINGLE_THREAD 0x0001 /* scope system kse group */ -#define KGF_SCHEDQ_INITED 0x0002 /* has an initialized schedq */ -}; - -/* - * Add/remove threads from a KSE's scheduling queue. - * For now the scheduling queue is hung off the KSEG. - */ -#define KSEG_THRQ_ADD(kseg, thr) \ -do { \ - TAILQ_INSERT_TAIL(&(kseg)->kg_threadq, thr, kle);\ - (kseg)->kg_threadcount++; \ -} while (0) - -#define KSEG_THRQ_REMOVE(kseg, thr) \ -do { \ - TAILQ_REMOVE(&(kseg)->kg_threadq, thr, kle); \ - (kseg)->kg_threadcount--; \ -} while (0) - - -/* - * Lock acquire and release for KSEs. - */ -#define KSE_LOCK_ACQUIRE(kse, lck) \ -do { \ - if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) { \ - (kse)->k_locklevel++; \ - _lock_acquire((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0); \ - } \ - else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define KSE_LOCK_RELEASE(kse, lck) \ -do { \ - if ((kse)->k_locklevel > 0) { \ - _lock_release((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1]); \ - (kse)->k_locklevel--; \ - } \ -} while (0) - -/* - * Lock our own KSEG. - */ -#define KSE_LOCK(curkse) \ - KSE_LOCK_ACQUIRE(curkse, &(curkse)->k_kseg->kg_lock) -#define KSE_UNLOCK(curkse) \ - KSE_LOCK_RELEASE(curkse, &(curkse)->k_kseg->kg_lock) - -/* - * Lock a potentially different KSEG. - */ -#define KSE_SCHED_LOCK(curkse, kseg) \ - KSE_LOCK_ACQUIRE(curkse, &(kseg)->kg_lock) -#define KSE_SCHED_UNLOCK(curkse, kseg) \ - KSE_LOCK_RELEASE(curkse, &(kseg)->kg_lock) - -/* - * Waiting queue manipulation macros (using pqe link): - */ -#define KSE_WAITQ_REMOVE(kse, thrd) \ -do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) != 0) { \ - TAILQ_REMOVE(&(kse)->k_schedq->sq_waitq, thrd, pqe); \ - (thrd)->flags &= ~THR_FLAGS_IN_WAITQ; \ - } \ -} while (0) -#define KSE_WAITQ_INSERT(kse, thrd) kse_waitq_insert(thrd) -#define KSE_WAITQ_FIRST(kse) TAILQ_FIRST(&(kse)->k_schedq->sq_waitq) - -#define KSE_WAKEUP(kse) kse_wakeup(&(kse)->k_kcb->kcb_kmbx) - -/* - * TailQ initialization values. - */ -#define TAILQ_INITIALIZER { NULL, NULL } - -/* - * lock initialization values. - */ -#define LCK_INITIALIZER { NULL, NULL, LCK_DEFAULT } - -struct pthread_mutex { - /* - * Lock for accesses to this structure. - */ - struct lock m_lock; - enum pthread_mutextype m_type; - int m_protocol; - TAILQ_HEAD(mutex_head, pthread) m_queue; - struct pthread *m_owner; - long m_flags; - int m_count; - int m_refcount; - - /* - * Used for priority inheritence and protection. - * - * m_prio - For priority inheritence, the highest active - * priority (threads locking the mutex inherit - * this priority). For priority protection, the - * ceiling priority of this mutex. - * m_saved_prio - mutex owners inherited priority before - * taking the mutex, restored when the owner - * unlocks the mutex. - */ - int m_prio; - int m_saved_prio; - - /* - * Link for list of all mutexes a thread currently owns. - */ - TAILQ_ENTRY(pthread_mutex) m_qe; -}; - -/* - * Flags for mutexes. - */ -#define MUTEX_FLAGS_PRIVATE 0x01 -#define MUTEX_FLAGS_INITED 0x02 -#define MUTEX_FLAGS_BUSY 0x04 - -/* - * Static mutex initialization values. - */ -#define PTHREAD_MUTEX_STATIC_INITIALIZER \ - { LCK_INITIALIZER, PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, \ - TAILQ_INITIALIZER, NULL, MUTEX_FLAGS_PRIVATE, 0, 0, 0, 0, \ - TAILQ_INITIALIZER } - -struct pthread_mutex_attr { - enum pthread_mutextype m_type; - int m_protocol; - int m_ceiling; - long m_flags; -}; - -#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ - { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } - -/* - * Condition variable definitions. - */ -enum pthread_cond_type { - COND_TYPE_FAST, - COND_TYPE_MAX -}; - -struct pthread_cond { - /* - * Lock for accesses to this structure. - */ - struct lock c_lock; - enum pthread_cond_type c_type; - TAILQ_HEAD(cond_head, pthread) c_queue; - struct pthread_mutex *c_mutex; - long c_flags; - long c_seqno; -}; - -struct pthread_cond_attr { - enum pthread_cond_type c_type; - long c_flags; -}; - -struct pthread_barrier { - pthread_mutex_t b_lock; - pthread_cond_t b_cond; - int b_count; - int b_waiters; - int b_generation; -}; - -struct pthread_barrierattr { - int pshared; -}; - -struct pthread_spinlock { - volatile int s_lock; - pthread_t s_owner; -}; - -/* - * Flags for condition variables. - */ -#define COND_FLAGS_PRIVATE 0x01 -#define COND_FLAGS_INITED 0x02 -#define COND_FLAGS_BUSY 0x04 - -/* - * Static cond initialization values. - */ -#define PTHREAD_COND_STATIC_INITIALIZER \ - { LCK_INITIALIZER, COND_TYPE_FAST, TAILQ_INITIALIZER, \ - NULL, NULL, 0, 0 } - -/* - * Cleanup definitions. - */ -struct pthread_cleanup { - struct pthread_cleanup *next; - void (*routine) (void *); - void *routine_arg; - int onstack; -}; - -#define THR_CLEANUP_PUSH(td, func, arg) { \ - struct pthread_cleanup __cup; \ - \ - __cup.routine = func; \ - __cup.routine_arg = arg; \ - __cup.onstack = 1; \ - __cup.next = (td)->cleanup; \ - (td)->cleanup = &__cup; - -#define THR_CLEANUP_POP(td, exec) \ - (td)->cleanup = __cup.next; \ - if ((exec) != 0) \ - __cup.routine(__cup.routine_arg); \ -} - -struct pthread_atfork { - TAILQ_ENTRY(pthread_atfork) qe; - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); -}; - -struct pthread_attr { - int sched_policy; - int sched_inherit; - int sched_interval; - int prio; - int suspend; -#define THR_STACK_USER 0x100 /* 0xFF reserved for <pthread.h> */ -#define THR_SIGNAL_THREAD 0x200 /* This is a signal thread */ - int flags; - void *arg_attr; - void (*cleanup_attr) (void *); - void *stackaddr_attr; - size_t stacksize_attr; - size_t guardsize_attr; -}; - -/* - * Thread creation state attributes. - */ -#define THR_CREATE_RUNNING 0 -#define THR_CREATE_SUSPENDED 1 - -/* - * Miscellaneous definitions. - */ -#define THR_STACK32_DEFAULT (1 * 1024 * 1024) -#define THR_STACK64_DEFAULT (2 * 1024 * 1024) - -/* - * 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 THR_STACK32_INITIAL (2 * 1024 * 1024) -#define THR_STACK64_INITIAL (4 * 1024 * 1024) - -/* - * Define the different priority ranges. All applications have thread - * priorities constrained within 0-31. The threads library raises the - * priority when delivering signals in order to ensure that signal - * delivery happens (from the POSIX spec) "as soon as possible". - * In the future, the threads library will also be able to map specific - * threads into real-time (cooperating) processes or kernel threads. - * The RT and SIGNAL priorities will be used internally and added to - * thread base priorities so that the scheduling queue can handle both - * normal and RT priority threads with and without signal handling. - * - * The approach taken is that, within each class, signal delivery - * always has priority over thread execution. - */ -#define THR_DEFAULT_PRIORITY 15 -#define THR_MIN_PRIORITY 0 -#define THR_MAX_PRIORITY 31 /* 0x1F */ -#define THR_SIGNAL_PRIORITY 32 /* 0x20 */ -#define THR_RT_PRIORITY 64 /* 0x40 */ -#define THR_FIRST_PRIORITY THR_MIN_PRIORITY -#define THR_LAST_PRIORITY \ - (THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY) -#define THR_BASE_PRIORITY(prio) ((prio) & THR_MAX_PRIORITY) - -/* - * Clock resolution in microseconds. - */ -#define CLOCK_RES_USEC 10000 - -/* - * Time slice period in microseconds. - */ -#define TIMESLICE_USEC 20000 - -/* - * XXX - Define a thread-safe macro to get the current time of day - * which is updated at regular intervals by something. - * - * For now, we just make the system call to get the time. - */ -#define KSE_GET_TOD(curkse, tsp) \ -do { \ - *tsp = (curkse)->k_kcb->kcb_kmbx.km_timeofday; \ - if ((tsp)->tv_sec == 0) \ - clock_gettime(CLOCK_REALTIME, tsp); \ -} while (0) - -struct pthread_rwlockattr { - int pshared; -}; - -struct pthread_rwlock { - pthread_mutex_t lock; /* monitor lock */ - pthread_cond_t read_signal; - pthread_cond_t write_signal; - int state; /* 0 = idle >0 = # of readers -1 = writer */ - int blocked_writers; -}; - -/* - * Thread states. - */ -enum pthread_state { - PS_RUNNING, - PS_LOCKWAIT, - PS_MUTEX_WAIT, - PS_COND_WAIT, - PS_SLEEP_WAIT, - PS_SIGSUSPEND, - PS_SIGWAIT, - PS_JOIN, - PS_SUSPENDED, - PS_DEAD, - PS_DEADLOCK, - PS_STATE_MAX -}; - -struct sigwait_data { - sigset_t *waitset; - siginfo_t *siginfo; /* used to save siginfo for sigwaitinfo() */ -}; - -union pthread_wait_data { - pthread_mutex_t mutex; - pthread_cond_t cond; - struct lock *lock; - struct sigwait_data *sigwait; -}; - -/* - * Define a continuation routine that can be used to perform a - * transfer of control: - */ -typedef void (*thread_continuation_t) (void *); - -/* - * This stores a thread's state prior to running a signal handler. - * It is used when a signal is delivered to a thread blocked in - * userland. If the signal handler returns normally, the thread's - * state is restored from here. - */ -struct pthread_sigframe { - int psf_valid; - int psf_flags; - int psf_cancelflags; - int psf_interrupted; - int psf_timeout; - int psf_signo; - enum pthread_state psf_state; - union pthread_wait_data psf_wait_data; - struct timespec psf_wakeup_time; - sigset_t psf_sigset; - sigset_t psf_sigmask; - int psf_seqno; - thread_continuation_t psf_continuation; -}; - -struct join_status { - struct pthread *thread; - void *ret; - int error; -}; - -struct pthread_specific_elem { - void *data; - int seqno; -}; - -typedef void (*const_key_destructor_t)(const void *); -typedef void (*key_destructor_t)(void *); - -struct pthread_key { - volatile int allocated; - volatile int count; - int seqno; - key_destructor_t destructor; -}; - -#define MAX_THR_LOCKLEVEL 5 -/* - * Thread structure. - */ -struct pthread { - /* Thread control block */ - struct tcb *tcb; - - /* - * Magic value to help recognize a valid thread structure - * from an invalid one: - */ -#define THR_MAGIC ((u_int32_t) 0xd09ba115) - u_int32_t magic; - char *name; - u_int64_t uniqueid; /* for gdb */ - - /* Queue entry for list of all threads: */ - TAILQ_ENTRY(pthread) tle; /* link for all threads in process */ - TAILQ_ENTRY(pthread) kle; /* link for all threads in KSE/KSEG */ - - /* Queue entry for GC lists: */ - TAILQ_ENTRY(pthread) gcle; - - /* Hash queue entry */ - LIST_ENTRY(pthread) hle; - - /* - * Lock for accesses to this thread structure. - */ - struct lock lock; - struct lockuser lockusers[MAX_THR_LOCKLEVEL]; - int locklevel; - kse_critical_t critical[MAX_KSE_LOCKLEVEL]; - struct kse *kse; - struct kse_group *kseg; - - /* - * Thread start routine, argument, stack pointer and thread - * attributes. - */ - void *(*start_routine)(void *); - void *arg; - struct pthread_attr attr; - - int active; /* thread running */ - int blocked; /* thread blocked in kernel */ - int need_switchout; - - /* - * Used for tracking delivery of signal handlers. - */ - siginfo_t *siginfo; - thread_continuation_t sigbackout; - - /* - * Cancelability flags - the lower 2 bits are used by cancel - * definitions in pthread.h - */ -#define THR_AT_CANCEL_POINT 0x0004 -#define THR_CANCELLING 0x0008 -#define THR_CANCEL_NEEDED 0x0010 - int cancelflags; - - thread_continuation_t continuation; - - /* - * The thread's base and pending signal masks. The active - * signal mask is stored in the thread's context (in mailbox). - */ - sigset_t sigmask; - sigset_t sigpend; - sigset_t *oldsigmask; - volatile int check_pending; - int refcount; - - /* Thread state: */ - enum pthread_state state; - volatile int lock_switch; - - /* - * Number of microseconds accumulated by this thread when - * time slicing is active. - */ - long slice_usec; - - /* - * Time to wake up thread. This is used for sleeping threads and - * for any operation which may time out (such as select). - */ - struct timespec wakeup_time; - - /* TRUE if operation has timed out. */ - int timeout; - - /* - * Error variable used instead of errno. The function __error() - * returns a pointer to this. - */ - int error; - - /* - * The joiner is the thread that is joining to this thread. The - * join status keeps track of a join operation to another thread. - */ - struct pthread *joiner; - struct join_status join_status; - - /* - * The current thread can belong to only one scheduling queue at - * a time (ready or waiting queue). It can also belong to: - * - * o A queue of threads waiting for a mutex - * o A queue of threads waiting for a condition variable - * - * It is possible for a thread to belong to more than one of the - * above queues if it is handling a signal. A thread may only - * enter a mutex or condition variable queue when it is not - * being called from a signal handler. If a thread is a member - * of one of these queues when a signal handler is invoked, it - * must be removed from the queue before invoking the handler - * and then added back to the queue after return from the handler. - * - * Use pqe for the scheduling queue link (both ready and waiting), - * sqe for synchronization (mutex, condition variable, and join) - * queue links, and qe for all other links. - */ - TAILQ_ENTRY(pthread) pqe; /* priority, wait queues link */ - TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */ - - /* Wait data. */ - union pthread_wait_data data; - - /* - * Set to TRUE if a blocking operation was - * interrupted by a signal: - */ - int interrupted; - - /* - * Set to non-zero when this thread has entered a critical - * region. We allow for recursive entries into critical regions. - */ - int critical_count; - - /* - * Set to TRUE if this thread should yield after leaving a - * critical region to check for signals, messages, etc. - */ - int critical_yield; - - int sflags; -#define THR_FLAGS_IN_SYNCQ 0x0001 - - /* Miscellaneous flags; only set with scheduling lock held. */ - int flags; -#define THR_FLAGS_PRIVATE 0x0001 -#define THR_FLAGS_IN_WAITQ 0x0002 /* in waiting queue using pqe link */ -#define THR_FLAGS_IN_RUNQ 0x0004 /* in run queue using pqe link */ -#define THR_FLAGS_EXITING 0x0008 /* thread is exiting */ -#define THR_FLAGS_SUSPENDED 0x0010 /* thread is suspended */ - - /* Thread list flags; only set with thread list lock held. */ -#define TLFLAGS_GC_SAFE 0x0001 /* thread safe for cleaning */ -#define TLFLAGS_IN_TDLIST 0x0002 /* thread in all thread list */ -#define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */ - int tlflags; - - /* - * Base priority is the user setable and retrievable priority - * of the thread. It is only affected by explicit calls to - * set thread priority and upon thread creation via a thread - * attribute or default priority. - */ - char base_priority; - - /* - * Inherited priority is the priority a thread inherits by - * taking a priority inheritence or protection mutex. It - * is not affected by base priority changes. Inherited - * priority defaults to and remains 0 until a mutex is taken - * that is being waited on by any other thread whose priority - * is non-zero. - */ - char inherited_priority; - - /* - * Active priority is always the maximum of the threads base - * priority and inherited priority. When there is a change - * in either the base or inherited priority, the active - * priority must be recalculated. - */ - char active_priority; - - /* Number of priority ceiling or protection mutexes owned. */ - int priority_mutex_count; - - /* Number rwlocks rdlocks held. */ - int rdlock_count; - - /* - * Queue of currently owned mutexes. - */ - TAILQ_HEAD(, pthread_mutex) mutexq; - - void *ret; - struct pthread_specific_elem *specific; - int specific_data_count; - - /* Alternative stack for sigaltstack() */ - stack_t sigstk; - - /* - * Current locks bitmap for rtld. - */ - int rtld_bits; - - /* Cleanup handlers Link List */ - struct pthread_cleanup *cleanup; - const char *fname; /* Ptr to source file name */ - int lineno; /* Source line number. */ -}; - -/* - * Critical regions can also be detected by looking at the threads - * current lock level. Ensure these macros increment and decrement - * the lock levels such that locks can not be held with a lock level - * of 0. - */ -#define THR_IN_CRITICAL(thrd) \ - (((thrd)->locklevel > 0) || \ - ((thrd)->critical_count > 0)) - -#define THR_YIELD_CHECK(thrd) \ -do { \ - if (!THR_IN_CRITICAL(thrd)) { \ - if (__predict_false(_libkse_debug)) \ - _thr_debug_check_yield(thrd); \ - if ((thrd)->critical_yield != 0) \ - _thr_sched_switch(thrd); \ - if ((thrd)->check_pending != 0) \ - _thr_sig_check_pending(thrd); \ - } \ -} while (0) - -#define THR_LOCK_ACQUIRE(thrd, lck) \ -do { \ - if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) { \ - THR_DEACTIVATE_LAST_LOCK(thrd); \ - (thrd)->locklevel++; \ - _lock_acquire((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1], \ - (thrd)->active_priority); \ - } else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define THR_LOCK_RELEASE(thrd, lck) \ -do { \ - if ((thrd)->locklevel > 0) { \ - _lock_release((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1]); \ - (thrd)->locklevel--; \ - THR_ACTIVATE_LAST_LOCK(thrd); \ - if ((thrd)->locklevel == 0) \ - THR_YIELD_CHECK(thrd); \ - } \ -} while (0) - -#define THR_ACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 1); \ -} while (0) - -#define THR_DEACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 0); \ -} while (0) - -/* - * For now, threads will have their own lock separate from their - * KSE scheduling lock. - */ -#define THR_LOCK(thr) THR_LOCK_ACQUIRE(thr, &(thr)->lock) -#define THR_UNLOCK(thr) THR_LOCK_RELEASE(thr, &(thr)->lock) -#define THR_THREAD_LOCK(curthrd, thr) THR_LOCK_ACQUIRE(curthrd, &(thr)->lock) -#define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock) - -/* - * Priority queue manipulation macros (using pqe link). We use - * the thread's kseg link instead of the kse link because a thread - * does not (currently) have a statically assigned kse. - */ -#define THR_RUNQ_INSERT_HEAD(thrd) \ - _pq_insert_head(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_INSERT_TAIL(thrd) \ - _pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_REMOVE(thrd) \ - _pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd) - -/* - * Macros to insert/remove threads to the all thread list and - * the gc list. - */ -#define THR_LIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_list, thrd, tle); \ - _thr_hash_add(thrd); \ - (thrd)->tlflags |= TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_LIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) != 0) { \ - TAILQ_REMOVE(&_thread_list, thrd, tle); \ - _thr_hash_remove(thrd); \ - (thrd)->tlflags &= ~TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_GCLIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\ - (thrd)->tlflags |= TLFLAGS_IN_GCLIST; \ - _gc_count++; \ - } \ -} while (0) -#define THR_GCLIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) != 0) { \ - TAILQ_REMOVE(&_thread_gc_list, thrd, gcle); \ - (thrd)->tlflags &= ~TLFLAGS_IN_GCLIST; \ - _gc_count--; \ - } \ -} while (0) - -#define GC_NEEDED() (atomic_load_acq_int(&_gc_count) >= 5) - -/* - * Locking the scheduling queue for another thread uses that thread's - * KSEG lock. - */ -#define THR_SCHED_LOCK(curthr, thr) do { \ - (curthr)->critical[(curthr)->locklevel] = _kse_critical_enter(); \ - (curthr)->locklevel++; \ - KSE_SCHED_LOCK((curthr)->kse, (thr)->kseg); \ -} while (0) - -#define THR_SCHED_UNLOCK(curthr, thr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (thr)->kseg); \ - (curthr)->locklevel--; \ - _kse_critical_leave((curthr)->critical[(curthr)->locklevel]); \ -} while (0) - -/* Take the scheduling lock with the intent to call the scheduler. */ -#define THR_LOCK_SWITCH(curthr) do { \ - (void)_kse_critical_enter(); \ - KSE_SCHED_LOCK((curthr)->kse, (curthr)->kseg); \ -} while (0) -#define THR_UNLOCK_SWITCH(curthr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (curthr)->kseg);\ -} while (0) - -#define THR_CRITICAL_ENTER(thr) (thr)->critical_count++ -#define THR_CRITICAL_LEAVE(thr) do { \ - (thr)->critical_count--; \ - if (((thr)->critical_yield != 0) && \ - ((thr)->critical_count == 0)) { \ - (thr)->critical_yield = 0; \ - _thr_sched_switch(thr); \ - } \ -} while (0) - -#define THR_IS_ACTIVE(thrd) \ - ((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd)) - -#define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0) - -#define THR_IS_SUSPENDED(thrd) \ - (((thrd)->state == PS_SUSPENDED) || \ - (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) -#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) -#define DBG_CAN_RUN(thrd) (((thrd)->tcb->tcb_tmbx.tm_dflags & \ - TMDF_SUSPEND) == 0) - -extern int __isthreaded; - -static inline int -_kse_isthreaded(void) -{ - return (__isthreaded != 0); -} - -/* - * Global variables for the pthread kernel. - */ - -SCLASS void *_usrstack SCLASS_PRESET(NULL); -SCLASS struct kse *_kse_initial SCLASS_PRESET(NULL); -SCLASS struct pthread *_thr_initial SCLASS_PRESET(NULL); -/* For debugger */ -SCLASS int _libkse_debug SCLASS_PRESET(0); -SCLASS int _thread_activated SCLASS_PRESET(0); -SCLASS int _thread_scope_system SCLASS_PRESET(0); - -/* List of all threads: */ -SCLASS TAILQ_HEAD(, pthread) _thread_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_list)); - -/* List of threads needing GC: */ -SCLASS TAILQ_HEAD(, pthread) _thread_gc_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_gc_list)); - -SCLASS int _thread_active_threads SCLASS_PRESET(1); - -SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _thr_atfork_list; -SCLASS pthread_mutex_t _thr_atfork_mutex; - -/* Default thread attributes: */ -SCLASS struct pthread_attr _pthread_attr_default - SCLASS_PRESET({ - SCHED_RR, 0, TIMESLICE_USEC, THR_DEFAULT_PRIORITY, - THR_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, - NULL, NULL, /* stacksize */0, /* guardsize */0 - }); - -/* Default mutex attributes: */ -SCLASS struct pthread_mutex_attr _pthread_mutexattr_default - SCLASS_PRESET({PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }); - -/* Default condition variable attributes: */ -SCLASS struct pthread_cond_attr _pthread_condattr_default - SCLASS_PRESET({COND_TYPE_FAST, 0}); - -/* Clock resolution in usec. */ -SCLASS int _clock_res_usec SCLASS_PRESET(CLOCK_RES_USEC); - -/* Array of signal actions for this process: */ -SCLASS struct sigaction _thread_sigact[_SIG_MAXSIG]; - -/* - * Lock for above count of dummy handlers and for the process signal - * mask and pending signal sets. - */ -SCLASS struct lock _thread_signal_lock; - -/* Pending signals and mask for this process: */ -SCLASS sigset_t _thr_proc_sigpending; -SCLASS siginfo_t _thr_proc_siginfo[_SIG_MAXSIG]; - -SCLASS pid_t _thr_pid SCLASS_PRESET(0); - -/* Garbage collector lock. */ -SCLASS struct lock _gc_lock; -SCLASS int _gc_check SCLASS_PRESET(0); -SCLASS int _gc_count SCLASS_PRESET(0); - -SCLASS struct lock _mutex_static_lock; -SCLASS struct lock _rwlock_static_lock; -SCLASS struct lock _keytable_lock; -SCLASS struct lock _thread_list_lock; -SCLASS size_t _thr_guard_default; -SCLASS size_t _thr_stack_default; -SCLASS size_t _thr_stack_initial; -SCLASS int _thr_page_size; -SCLASS pthread_t _thr_sig_daemon; -SCLASS int _thr_debug_flags SCLASS_PRESET(0); - -/* Undefine the storage class and preset specifiers: */ -#undef SCLASS -#undef SCLASS_PRESET - - -/* - * Function prototype definitions. - */ -__BEGIN_DECLS -int _cond_reinit(pthread_cond_t *); -struct kse *_kse_alloc(struct pthread *, int sys_scope); -kse_critical_t _kse_critical_enter(void); -void _kse_critical_leave(kse_critical_t); -int _kse_in_critical(void); -void _kse_free(struct pthread *, struct kse *); -void _kse_init(void); -struct kse_group *_kseg_alloc(struct pthread *); -void _kse_lock_wait(struct lock *, struct lockuser *lu); -void _kse_lock_wakeup(struct lock *, struct lockuser *lu); -void _kse_single_thread(struct pthread *); -int _kse_setthreaded(int); -void _kseg_free(struct kse_group *); -int _mutex_cv_lock(pthread_mutex_t *); -int _mutex_cv_unlock(pthread_mutex_t *); -void _mutex_notify_priochange(struct pthread *, struct pthread *, int); -int _mutex_reinit(struct pthread_mutex *); -void _mutex_unlock_private(struct pthread *); -void _libpthread_init(struct pthread *); -int _pq_alloc(struct pq_queue *, int, int); -void _pq_free(struct pq_queue *); -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); -struct pthread *_pq_first_debug(struct pq_queue *pq); -void *_pthread_getspecific(pthread_key_t); -int _pthread_key_create(pthread_key_t *, void (*) (void *)); -int _pthread_key_delete(pthread_key_t); -int _pthread_mutex_destroy(pthread_mutex_t *); -int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); -int _pthread_mutex_lock(pthread_mutex_t *); -int _pthread_mutex_trylock(pthread_mutex_t *); -int _pthread_mutex_unlock(pthread_mutex_t *); -int _pthread_mutexattr_init(pthread_mutexattr_t *); -int _pthread_mutexattr_destroy(pthread_mutexattr_t *); -int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); -int _pthread_once(pthread_once_t *, void (*) (void)); -int _pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); -int _pthread_rwlock_destroy (pthread_rwlock_t *); -struct pthread *_pthread_self(void); -int _pthread_setspecific(pthread_key_t, const void *); -void _pthread_yield(void); -void _pthread_cleanup_push(void (*routine) (void *), void *routine_arg); -void _pthread_cleanup_pop(int execute); -struct pthread *_thr_alloc(struct pthread *); -void _thr_exit(const char *, int, const char *) __dead2; -void _thr_exit_cleanup(void); -void _thr_lock_wait(struct lock *lock, struct lockuser *lu); -void _thr_lock_wakeup(struct lock *lock, struct lockuser *lu); -void _thr_mutex_reinit(pthread_mutex_t *); -int _thr_ref_add(struct pthread *, struct pthread *, int); -void _thr_ref_delete(struct pthread *, struct pthread *); -void _thr_rtld_init(void); -void _thr_rtld_fini(void); -int _thr_schedule_add(struct pthread *, struct pthread *); -void _thr_schedule_remove(struct pthread *, struct pthread *); -void _thr_setrunnable(struct pthread *curthread, struct pthread *thread); -struct kse_mailbox *_thr_setrunnable_unlocked(struct pthread *thread); -struct kse_mailbox *_thr_sig_add(struct pthread *, int, siginfo_t *); -void _thr_sig_dispatch(struct kse *, int, siginfo_t *); -int _thr_stack_alloc(struct pthread_attr *); -void _thr_stack_free(struct pthread_attr *); -void _thr_exit_cleanup(void); -void _thr_free(struct pthread *, struct pthread *); -void _thr_gc(struct pthread *); -void _thr_panic_exit(char *, int, char *); -void _thread_cleanupspecific(void); -void _thread_dump_info(void); -void _thread_printf(int, const char *, ...); -void _thr_sched_switch(struct pthread *); -void _thr_sched_switch_unlocked(struct pthread *); -void _thr_set_timeout(const struct timespec *); -void _thr_seterrno(struct pthread *, int); -void _thr_sig_handler(int, siginfo_t *, void *); -void _thr_sig_check_pending(struct pthread *); -void _thr_sig_rundown(struct pthread *, ucontext_t *); -void _thr_sig_send(struct pthread *pthread, int sig); -void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf); -void _thr_spinlock_init(void); -void _thr_cancel_enter(struct pthread *); -void _thr_cancel_leave(struct pthread *, int); -int _thr_setconcurrency(int new_level); -int _thr_setmaxconcurrency(void); -void _thr_critical_enter(struct pthread *); -void _thr_critical_leave(struct pthread *); -int _thr_start_sig_daemon(void); -int _thr_getprocsig(int sig, siginfo_t *siginfo); -int _thr_getprocsig_unlocked(int sig, siginfo_t *siginfo); -void _thr_signal_init(void); -void _thr_signal_deinit(void); -void _thr_hash_add(struct pthread *); -void _thr_hash_remove(struct pthread *); -struct pthread *_thr_hash_find(struct pthread *); -void _thr_finish_cancellation(void *arg); -int _thr_sigonstack(void *sp); -void _thr_debug_check_yield(struct pthread *); - -/* - * Aliases for _pthread functions. Should be called instead of - * originals if PLT replocation is unwanted at runtme. - */ -int _thr_cond_broadcast(pthread_cond_t *); -int _thr_cond_signal(pthread_cond_t *); -int _thr_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int _thr_mutex_lock(pthread_mutex_t *); -int _thr_mutex_unlock(pthread_mutex_t *); -int _thr_rwlock_rdlock (pthread_rwlock_t *); -int _thr_rwlock_wrlock (pthread_rwlock_t *); -int _thr_rwlock_unlock (pthread_rwlock_t *); - -/* #include <sys/aio.h> */ -#ifdef _SYS_AIO_H_ -int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); -#endif - -/* #include <fcntl.h> */ -#ifdef _SYS_FCNTL_H_ -int __sys_fcntl(int, int, ...); -int __sys_open(const char *, int, ...); -#endif - -/* #include <sys/ioctl.h> */ -#ifdef _SYS_IOCTL_H_ -int __sys_ioctl(int, unsigned long, ...); -#endif - -/* #inclde <sched.h> */ -#ifdef _SCHED_H_ -int __sys_sched_yield(void); -#endif - -/* #include <signal.h> */ -#ifdef _SIGNAL_H_ -int __sys_kill(pid_t, int); -int __sys_sigaction(int, const struct sigaction *, struct sigaction *); -int __sys_sigpending(sigset_t *); -int __sys_sigprocmask(int, const sigset_t *, sigset_t *); -int __sys_sigsuspend(const sigset_t *); -int __sys_sigreturn(ucontext_t *); -int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); -#endif - -/* #include <sys/socket.h> */ -#ifdef _SYS_SOCKET_H_ -int __sys_accept(int, struct sockaddr *, socklen_t *); -int __sys_connect(int, const struct sockaddr *, socklen_t); -int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, - off_t *, int); -#endif - -/* #include <sys/uio.h> */ -#ifdef _SYS_UIO_H_ -ssize_t __sys_readv(int, const struct iovec *, int); -ssize_t __sys_writev(int, const struct iovec *, int); -#endif - -/* #include <time.h> */ -#ifdef _TIME_H_ -int __sys_nanosleep(const struct timespec *, struct timespec *); -#endif - -/* #include <unistd.h> */ -#ifdef _UNISTD_H_ -int __sys_close(int); -int __sys_execve(const char *, char * const *, char * const *); -int __sys_fork(void); -int __sys_fsync(int); -pid_t __sys_getpid(void); -int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -ssize_t __sys_read(int, void *, size_t); -ssize_t __sys_write(int, const void *, size_t); -void __sys_exit(int); -int __sys_sigwait(const sigset_t *, int *); -int __sys_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *); -#endif - -/* #include <poll.h> */ -#ifdef _SYS_POLL_H_ -int __sys_poll(struct pollfd *, unsigned, int); -#endif - -/* #include <sys/mman.h> */ -#ifdef _SYS_MMAN_H_ -int __sys_msync(void *, size_t, int); -#endif - -static __inline int -_thr_dump_enabled(void) -{ - - return ((_thr_debug_flags & DBG_INFO_DUMP) != 0); -} - -#endif /* !_THR_PRIVATE_H */ diff --git a/lib/libkse/thread/thr_pselect.c b/lib/libkse/thread/thr_pselect.c deleted file mode 100644 index a8cbf13..0000000 --- a/lib/libkse/thread/thr_pselect.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2002 Daniel M. Eischen <deischen@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <sys/select.h> -#include <sys/time.h> -#include <errno.h> -#include <signal.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask); - -int _pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask); - -__weak_reference(_pselect, pselect); - -int -_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pselect(count, rfds, wfds, efds, timo, mask); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_pspinlock.c b/lib/libkse/thread/thr_pspinlock.c deleted file mode 100644 index 76376be..0000000 --- a/lib/libkse/thread/thr_pspinlock.c +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <stdlib.h> -#include "un-namespace.h" - -#include "atomic_ops.h" -#include "thr_private.h" - -#define SPIN_COUNT 10000 - -__weak_reference(_pthread_spin_init, pthread_spin_init); -__weak_reference(_pthread_spin_destroy, pthread_spin_destroy); -__weak_reference(_pthread_spin_trylock, pthread_spin_trylock); -__weak_reference(_pthread_spin_lock, pthread_spin_lock); -__weak_reference(_pthread_spin_unlock, pthread_spin_unlock); - -int -_pthread_spin_init(pthread_spinlock_t *lock, int pshared) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || pshared != PTHREAD_PROCESS_PRIVATE) - ret = EINVAL; - else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL) - ret = ENOMEM; - else { - lck->s_lock = 0; - lck->s_owner= NULL; - *lock = lck; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_destroy(pthread_spinlock_t *lock) -{ - int ret; - - if (lock == NULL || *lock == NULL) - ret = EINVAL; - else if ((*lock)->s_owner != NULL) - ret = EBUSY; - else { - free(*lock); - *lock = NULL; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_trylock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else if (lck->s_lock != 0) - ret = EBUSY; - else { - atomic_swap_int(&(lck)->s_lock, 1, &oldval); - if (oldval) - ret = EBUSY; - else { - lck->s_owner = _pthread_self(); - ret = 0; - } - } - return (ret); -} - -int -_pthread_spin_lock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int count, oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else { - do { - count = SPIN_COUNT; - while (lck->s_lock) { -#ifdef __i386__ - /* tell cpu we are spinning */ - __asm __volatile("pause"); -#endif - if (--count <= 0) { - count = SPIN_COUNT; - _pthread_yield(); - } - } - atomic_swap_int(&(lck)->s_lock, 1, &oldval); - } while (oldval); - - lck->s_owner = self; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_unlock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else { - if (lck->s_owner != _pthread_self()) - ret = EPERM; - else { - lck->s_owner = NULL; - atomic_swap_int(&lck->s_lock, 0, &ret); - ret = 0; - } - } - - return (ret); -} - diff --git a/lib/libkse/thread/thr_raise.c b/lib/libkse/thread/thr_raise.c deleted file mode 100644 index 707852a..0000000 --- a/lib/libkse/thread/thr_raise.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2003 David Xu<davidxu@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _raise(int sig); - -__weak_reference(_raise, raise); - -int -_raise(int sig) -{ - int ret; - - if (!_kse_isthreaded()) - ret = kill(getpid(), sig); - else { - ret = _pthread_kill(_pthread_self(), sig); - if (ret != 0) { - errno = ret; - ret = -1; - } - } - return (ret); -} diff --git a/lib/libkse/thread/thr_read.c b/lib/libkse/thread/thr_read.c deleted file mode 100644 index 829d069..0000000 --- a/lib/libkse/thread/thr_read.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -ssize_t __read(int fd, void *buf, size_t nbytes); - -__weak_reference(__read, read); - -ssize_t -__read(int fd, void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_read(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_readv.c b/lib/libkse/thread/thr_readv.c deleted file mode 100644 index 660a65a..0000000 --- a/lib/libkse/thread/thr_readv.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -ssize_t __readv(int fd, const struct iovec *iov, int iovcnt); - -__weak_reference(__readv, readv); - -ssize_t -__readv(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_readv(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_resume_np.c b/lib/libkse/thread/thr_resume_np.c deleted file mode 100644 index 685dbf3..0000000 --- a/lib/libkse/thread/thr_resume_np.c +++ /dev/null @@ -1,110 +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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_resume_np(pthread_t thread); -void _pthread_resume_all_np(void); - -static struct kse_mailbox *resume_common(struct pthread *); - -__weak_reference(_pthread_resume_np, pthread_resume_np); -__weak_reference(_pthread_resume_all_np, pthread_resume_all_np); - - -/* Resume a thread: */ -int -_pthread_resume_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - int ret; - - /* Add a reference to the thread: */ - if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - return (ret); -} - -void -_pthread_resume_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - struct kse_mailbox *kmbx; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -static struct kse_mailbox * -resume_common(struct pthread *thread) -{ - /* Clear the suspend flag: */ - thread->flags &= ~THR_FLAGS_SUSPENDED; - - /* - * If the thread's state is suspended, that means it is - * now runnable but not in any scheduling queue. Set the - * state to running and insert it into the run queue. - */ - if (thread->state == PS_SUSPENDED) - return (_thr_setrunnable_unlocked(thread)); - else - return (NULL); -} diff --git a/lib/libkse/thread/thr_rtld.c b/lib/libkse/thread/thr_rtld.c deleted file mode 100644 index 9320c48..0000000 --- a/lib/libkse/thread/thr_rtld.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2001 Alexander Kabaev - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$ - */ -#include <sys/cdefs.h> -#include <stdlib.h> - -#include "rtld_lock.h" -#include "thr_private.h" - -static int _thr_rtld_clr_flag(int); -static void *_thr_rtld_lock_create(void); -static void _thr_rtld_lock_destroy(void *); -static void _thr_rtld_lock_release(void *); -static void _thr_rtld_rlock_acquire(void *); -static int _thr_rtld_set_flag(int); -static void _thr_rtld_wlock_acquire(void *); - -#ifdef NOTYET -static void * -_thr_rtld_lock_create(void) -{ - pthread_rwlock_t prwlock; - if (_pthread_rwlock_init(&prwlock, NULL)) - return (NULL); - return (prwlock); -} - -static void -_thr_rtld_lock_destroy(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - if (prwlock != NULL) - _pthread_rwlock_destroy(&prwlock); -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_rdlock(&prwlock); -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_wrlock(&prwlock); -} - -static void -_thr_rtld_lock_release(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_unlock(&prwlock); -} - - -static int -_thr_rtld_set_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits |= mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - - return (bits); -} - -static int -_thr_rtld_clr_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits &= ~mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - return (bits); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} -#endif - -struct rtld_kse_lock { - struct lock lck; - struct kse *owner; - kse_critical_t crit; - int count; - int write; -}; - -static void * -_thr_rtld_lock_create(void) -{ - struct rtld_kse_lock *l; - - if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) { - _lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup, calloc); - l->owner = NULL; - l->count = 0; - l->write = 0; - } - return (l); -} - -static void -_thr_rtld_lock_destroy(void *lock __unused) -{ - /* XXX We really can not free memory after a fork() */ -#if 0 - struct rtld_kse_lock *l; - - l = (struct rtld_kse_lock *)lock; - _lock_destroy(&l->lck); - free(l); -#endif - return; -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - l->count++; - _kse_critical_leave(crit); /* probably not necessary */ - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 0; - } -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - _kse_critical_leave(crit); - PANIC("Recursive write lock attempt on rtld lock"); - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 1; - } -} - -static void -_thr_rtld_lock_release(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner != curkse) { - /* - * We might want to forcibly unlock the rtld lock - * and/or disable threaded mode so there is better - * chance that the panic will work. Otherwise, - * we could end up trying to take the rtld lock - * again. - */ - _kse_critical_leave(crit); - PANIC("Attempt to unlock rtld lock when not owner."); - } else { - l->count--; - if (l->count == 0) { - /* - * If there ever is a count associated with - * _kse_critical_leave(), we'll need to add - * another call to it here with the crit - * value from above. - */ - crit = l->crit; - l->owner = NULL; - l->write = 0; - KSE_LOCK_RELEASE(curkse, &l->lck); - } - _kse_critical_leave(crit); - } -} - - -static int -_thr_rtld_set_flag(int mask __unused) -{ - return (0); -} - -static int -_thr_rtld_clr_flag(int mask __unused) -{ - return (0); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} diff --git a/lib/libkse/thread/thr_rwlock.c b/lib/libkse/thread/thr_rwlock.c deleted file mode 100644 index 1c96c3a..0000000 --- a/lib/libkse/thread/thr_rwlock.c +++ /dev/null @@ -1,419 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* maximum number of times a read lock may be obtained */ -#define MAX_READ_LOCKS (INT_MAX - 1) - -__weak_reference(_pthread_rwlock_destroy, pthread_rwlock_destroy); -__weak_reference(_pthread_rwlock_init, pthread_rwlock_init); -__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock); -__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); -__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); -__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); -__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); -__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); -__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); - -/* - * Prototypes - */ -static int init_static(pthread_rwlock_t *rwlock); - - -static int -init_static(pthread_rwlock_t *rwlock) -{ - struct pthread *thread = _get_curthread(); - int ret; - - THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock); - - if (*rwlock == NULL) - ret = _pthread_rwlock_init(rwlock, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_rwlock_static_lock); - return (ret); -} - -int -_pthread_rwlock_destroy (pthread_rwlock_t *rwlock) -{ - int ret; - - if (rwlock == NULL) - ret = EINVAL; - else { - pthread_rwlock_t prwlock; - - prwlock = *rwlock; - - _pthread_mutex_destroy(&prwlock->lock); - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_cond_destroy(&prwlock->write_signal); - free(prwlock); - - *rwlock = NULL; - - ret = 0; - } - return (ret); -} - -int -_pthread_rwlock_init (pthread_rwlock_t *rwlock, - const pthread_rwlockattr_t *attr __unused) -{ - pthread_rwlock_t prwlock; - int ret; - - /* allocate rwlock object */ - prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock)); - - if (prwlock == NULL) - return (ENOMEM); - - /* initialize the lock */ - if ((ret = _pthread_mutex_init(&prwlock->lock, NULL)) != 0) - free(prwlock); - else { - /* initialize the read condition signal */ - ret = _pthread_cond_init(&prwlock->read_signal, NULL); - - if (ret != 0) { - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* initialize the write condition signal */ - ret = _pthread_cond_init(&prwlock->write_signal, NULL); - - if (ret != 0) { - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* success */ - prwlock->state = 0; - prwlock->blocked_writers = 0; - - *rwlock = prwlock; - } - } - } - - return (ret); -} - -static int -rwlock_rdlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - struct pthread *curthread; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - /* check lock count */ - if (prwlock->state == MAX_READ_LOCKS) { - _thr_mutex_unlock(&prwlock->lock); - return (EAGAIN); - } - - curthread = _get_curthread(); - if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* - * To avoid having to track all the rdlocks held by - * a thread or all of the threads that hold a rdlock, - * we keep a simple count of all the rdlocks held by - * a thread. If a thread holds any rdlocks it is - * possible that it is attempting to take a recursive - * rdlock. If there are blocked writers and precedence - * is given to them, then that would result in the thread - * deadlocking. So allowing a thread to take the rdlock - * when it already has one or more rdlocks avoids the - * deadlock. I hope the reader can follow that logic ;-) - */ - ; /* nothing needed */ - } else { - /* give writers priority over readers */ - while (prwlock->blocked_writers || prwlock->state < 0) { - if (abstime) - ret = _pthread_cond_timedwait - (&prwlock->read_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->read_signal, - &prwlock->lock); - if (ret != 0) { - /* can't do a whole lot if this fails */ - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - } - } - - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - - /* - * Something is really wrong if this call fails. Returning - * error won't do because we've already obtained the read - * lock. Decrementing 'state' is no good because we probably - * don't have the monitor lock. - */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_rdlock_common(rwlock, NULL)); -} - -__strong_reference(_pthread_rwlock_rdlock, _thr_rwlock_rdlock); - -int -_pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_rdlock_common(rwlock, abstime)); -} - -int -_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state == MAX_READ_LOCKS) - ret = EAGAIN; - else if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* see comment for pthread_rwlock_rdlock() */ - curthread->rdlock_count++; - prwlock->state++; - } - /* give writers priority over readers */ - else if (prwlock->blocked_writers || prwlock->state < 0) - ret = EBUSY; - else { - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - } - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - if (prwlock->state != 0) - ret = EBUSY; - else - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_unlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - if (prwlock == NULL) - return (EINVAL); - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state > 0) { - curthread->rdlock_count--; - prwlock->state--; - if (prwlock->state == 0 && prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - } else if (prwlock->state < 0) { - prwlock->state = 0; - - if (prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - else - ret = _thr_cond_broadcast(&prwlock->read_signal); - } else - ret = EINVAL; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -__strong_reference(_pthread_rwlock_unlock, _thr_rwlock_unlock); - -static int -rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - while (prwlock->state != 0) { - prwlock->blocked_writers++; - - if (abstime != NULL) - ret = _pthread_cond_timedwait(&prwlock->write_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->write_signal, - &prwlock->lock); - if (ret != 0) { - prwlock->blocked_writers--; - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - - prwlock->blocked_writers--; - } - - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_wrlock_common (rwlock, NULL)); -} -__strong_reference(_pthread_rwlock_wrlock, _thr_rwlock_wrlock); - -int -_pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_wrlock_common (rwlock, abstime)); -} diff --git a/lib/libkse/thread/thr_rwlockattr.c b/lib/libkse/thread/thr_rwlockattr.c deleted file mode 100644 index e5b9c96..0000000 --- a/lib/libkse/thread/thr_rwlockattr.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy); -__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared); -__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init); -__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared); - -int -_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = *rwlockattr; - - if (prwlockattr == NULL) - return(EINVAL); - - free(prwlockattr); - - return(0); -} - -int -_pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *rwlockattr, - int *pshared) -{ - *pshared = (*rwlockattr)->pshared; - - return(0); -} - -int -_pthread_rwlockattr_init(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = (pthread_rwlockattr_t) - malloc(sizeof(struct pthread_rwlockattr)); - - if (prwlockattr == NULL) - return(ENOMEM); - - prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE; - *rwlockattr = prwlockattr; - - return(0); -} - -int -_pthread_rwlockattr_setpshared(pthread_rwlockattr_t *rwlockattr, int pshared) -{ - /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return(EINVAL); - - (*rwlockattr)->pshared = pshared; - - return(0); -} - diff --git a/lib/libkse/thread/thr_select.c b/lib/libkse/thread/thr_select.c deleted file mode 100644 index 6d0219c..0000000 --- a/lib/libkse/thread/thr_select.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#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> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __select(int numfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - -__weak_reference(__select, select); - -int -__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - int ret; - - if (numfds == 0 && timeout != NULL) { - TIMEVAL_TO_TIMESPEC(timeout, &ts); - ret = _nanosleep(&ts, NULL); - } else { - _thr_cancel_enter(curthread); - ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); - _thr_cancel_leave(curthread, 1); - } - return (ret); -} diff --git a/lib/libkse/thread/thr_self.c b/lib/libkse/thread/thr_self.c deleted file mode 100644 index bad0041..0000000 --- a/lib/libkse/thread/thr_self.c +++ /dev/null @@ -1,47 +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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_self, pthread_self); - -pthread_t -_pthread_self(void) -{ - if (_thr_initial == NULL) - _libpthread_init(NULL); - - /* Return the running thread pointer: */ - return (_get_curthread()); -} diff --git a/lib/libkse/thread/thr_sem.c b/lib/libkse/thread/thr_sem.c deleted file mode 100644 index 87d2057b..0000000 --- a/lib/libkse/thread/thr_sem.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/queue.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <stdlib.h> -#include <time.h> -#include <_semaphore.h> -#include "un-namespace.h" -#include "libc_private.h" -#include "thr_private.h" - -__weak_reference(_sem_init, sem_init); -__weak_reference(_sem_wait, sem_wait); -__weak_reference(_sem_timedwait, sem_timedwait); -__weak_reference(_sem_post, sem_post); - - -static inline int -sem_check_validity(sem_t *sem) -{ - - if ((sem != NULL) && ((*sem)->magic == SEM_MAGIC)) - return (0); - else { - errno = EINVAL; - return (-1); - } -} - -static void -decrease_nwaiters(void *arg) -{ - sem_t *sem = (sem_t *)arg; - - (*sem)->nwaiters--; - /* - * this function is called from cancellation point, - * the mutex should already be hold. - */ - _pthread_mutex_unlock(&(*sem)->lock); -} - -static sem_t -sem_alloc(unsigned int value, semid_t semid, int system_sem) -{ - sem_t sem; - - if (value > SEM_VALUE_MAX) { - errno = EINVAL; - return (NULL); - } - - sem = (sem_t)malloc(sizeof(struct sem)); - if (sem == NULL) { - errno = ENOSPC; - return (NULL); - } - - /* - * Initialize the semaphore. - */ - if (_pthread_mutex_init(&sem->lock, NULL) != 0) { - free(sem); - errno = ENOSPC; - return (NULL); - } - - if (_pthread_cond_init(&sem->gtzero, NULL) != 0) { - _pthread_mutex_destroy(&sem->lock); - free(sem); - errno = ENOSPC; - return (NULL); - } - - sem->count = (u_int32_t)value; - sem->nwaiters = 0; - sem->magic = SEM_MAGIC; - sem->semid = semid; - sem->syssem = system_sem; - return (sem); -} - -int -_sem_init(sem_t *sem, int pshared, unsigned int value) -{ - semid_t semid; - - semid = (semid_t)SEM_USER; - if ((pshared != 0) && (ksem_init(&semid, value) != 0)) - return (-1); - - (*sem) = sem_alloc(value, semid, pshared); - if ((*sem) == NULL) { - if (pshared != 0) - ksem_destroy(semid); - return (-1); - } - return (0); -} - -int -_sem_wait(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - curthread = _get_curthread(); - if ((*sem)->syssem != 0) { - _thr_cancel_enter(curthread); - retval = ksem_wait((*sem)->semid); - _thr_cancel_leave(curthread, retval != 0); - } - else { - _pthread_testcancel(); - _pthread_mutex_lock(&(*sem)->lock); - - while ((*sem)->count <= 0) { - (*sem)->nwaiters++; - THR_CLEANUP_PUSH(curthread, decrease_nwaiters, sem); - _pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); - THR_CLEANUP_POP(curthread, 0); - (*sem)->nwaiters--; - } - (*sem)->count--; - - _pthread_mutex_unlock(&(*sem)->lock); - - retval = 0; - } - return (retval); -} - -int -_sem_timedwait(sem_t * __restrict sem, - const struct timespec * __restrict abs_timeout) -{ - struct pthread *curthread; - int retval; - int timeout_invalid; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) { - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - retval = ksem_timedwait((*sem)->semid, abs_timeout); - _thr_cancel_leave(curthread, retval != 0); - } - else { - /* - * The timeout argument is only supposed to - * be checked if the thread would have blocked. - * This is checked outside of the lock so a - * segfault on an invalid address doesn't end - * up leaving the mutex locked. - */ - _pthread_testcancel(); - timeout_invalid = (abs_timeout->tv_nsec >= 1000000000) || - (abs_timeout->tv_nsec < 0); - _pthread_mutex_lock(&(*sem)->lock); - - if ((*sem)->count <= 0) { - if (timeout_invalid) { - _pthread_mutex_unlock(&(*sem)->lock); - errno = EINVAL; - return (-1); - } - (*sem)->nwaiters++; - _pthread_cleanup_push(decrease_nwaiters, sem); - _pthread_cond_timedwait(&(*sem)->gtzero, - &(*sem)->lock, abs_timeout); - _pthread_cleanup_pop(0); - (*sem)->nwaiters--; - } - if ((*sem)->count == 0) { - errno = ETIMEDOUT; - retval = -1; - } - else { - (*sem)->count--; - retval = 0; - } - - _pthread_mutex_unlock(&(*sem)->lock); - } - - return (retval); -} - -int -_sem_post(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) - retval = ksem_post((*sem)->semid); - else { - /* - * sem_post() is required to be safe to call from within - * signal handlers. Thus, we must enter a critical region. - */ - curthread = _get_curthread(); - _thr_critical_enter(curthread); - _pthread_mutex_lock(&(*sem)->lock); - - (*sem)->count++; - if ((*sem)->nwaiters > 0) - _pthread_cond_signal(&(*sem)->gtzero); - - _pthread_mutex_unlock(&(*sem)->lock); - _thr_critical_leave(curthread); - retval = 0; - } - - return (retval); -} diff --git a/lib/libkse/thread/thr_seterrno.c b/lib/libkse/thread/thr_seterrno.c deleted file mode 100644 index f0b5f97..0000000 --- a/lib/libkse/thread/thr_seterrno.c +++ /dev/null @@ -1,61 +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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* - * This function needs to reference the global error variable which is - * normally hidden from the user. - */ -#ifdef errno -#undef errno; -#endif -extern int errno; - -void _thread_seterrno(pthread_t thread, int error); - -void -_thread_seterrno(pthread_t thread, int error) -{ - /* Check for the initial thread: */ - if (thread == _thr_initial) - /* The initial thread always uses the global error variable: */ - errno = error; - else - /* - * Threads other than the initial thread always use the error - * field in the thread structureL - */ - thread->error = error; -} diff --git a/lib/libkse/thread/thr_setprio.c b/lib/libkse/thread/thr_setprio.c deleted file mode 100644 index 4ea9962..0000000 --- a/lib/libkse/thread/thr_setprio.c +++ /dev/null @@ -1,54 +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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_setprio(pthread_t pthread, int prio); - -__weak_reference(_pthread_setprio, pthread_setprio); - -int -_pthread_setprio(pthread_t pthread, int prio) -{ - int ret, policy; - struct sched_param param; - - if ((ret = _pthread_getschedparam(pthread, &policy, ¶m)) == 0) { - param.sched_priority = prio; - ret = _pthread_setschedparam(pthread, policy, ¶m); - } - - /* Return the error status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_setschedparam.c b/lib/libkse/thread/thr_setschedparam.c deleted file mode 100644 index 4a9354f..0000000 --- a/lib/libkse/thread/thr_setschedparam.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <sys/param.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_setschedparam, pthread_setschedparam); - -int -_pthread_setschedparam(pthread_t pthread, int policy, - const struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int in_syncq; - int in_readyq = 0; - int old_prio; - int ret = 0; - - if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) { - /* Return an invalid argument error: */ - ret = EINVAL; - } else if ((param->sched_priority < THR_MIN_PRIORITY) || - (param->sched_priority > THR_MAX_PRIORITY)) { - /* Return an unsupported value error. */ - ret = ENOTSUP; - - /* Find the thread in the list of active threads: */ - } else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - /* - * Lock the threads scheduling queue while we change - * its priority: - */ - THR_SCHED_LOCK(curthread, pthread); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)) { - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - return (ESRCH); - } - in_syncq = pthread->sflags & THR_FLAGS_IN_SYNCQ; - - /* Set the scheduling policy: */ - pthread->attr.sched_policy = policy; - - if (param->sched_priority == - THR_BASE_PRIORITY(pthread->base_priority)) - /* - * There is nothing to do; unlock the threads - * scheduling queue. - */ - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * Remove the thread from its current priority - * queue before any adjustments are made to its - * active priority: - */ - old_prio = pthread->active_priority; - if ((pthread->flags & THR_FLAGS_IN_RUNQ) != 0) { - in_readyq = 1; - THR_RUNQ_REMOVE(pthread); - } - - /* Set the thread base priority: */ - pthread->base_priority &= - (THR_SIGNAL_PRIORITY | THR_RT_PRIORITY); - pthread->base_priority = param->sched_priority; - - /* Recalculate the active priority: */ - pthread->active_priority = MAX(pthread->base_priority, - pthread->inherited_priority); - - if (in_readyq) { - if ((pthread->priority_mutex_count > 0) && - (old_prio > pthread->active_priority)) { - /* - * POSIX states that if the priority is - * being lowered, the thread must be - * inserted at the head of the queue for - * its priority if it owns any priority - * protection or inheritence mutexes. - */ - THR_RUNQ_INSERT_HEAD(pthread); - } - else - THR_RUNQ_INSERT_TAIL(pthread); - } - - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Check for any mutex priority adjustments. This - * includes checking for a priority mutex on which - * this thread is waiting. - */ - _mutex_notify_priochange(curthread, pthread, in_syncq); - } - _thr_ref_delete(curthread, pthread); - } - return (ret); -} diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c deleted file mode 100644 index e3cf5bb..0000000 --- a/lib/libkse/thread/thr_sig.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Prototypes: */ -static inline void build_siginfo(siginfo_t *info, int signo); -#ifndef SYSTEM_SCOPE_ONLY -static struct pthread *thr_sig_find(struct kse *curkse, int sig, - siginfo_t *info); -#endif -static inline void thr_sigframe_restore(struct pthread *thread, - struct pthread_sigframe *psf); -static inline void thr_sigframe_save(struct pthread *thread, - struct pthread_sigframe *psf); - -#define SA_KILL 0x01 /* terminates process by default */ -#define SA_STOP 0x02 -#define SA_CONT 0x04 - -static int sigproptbl[NSIG] = { - SA_KILL, /* SIGHUP */ - SA_KILL, /* SIGINT */ - SA_KILL, /* SIGQUIT */ - SA_KILL, /* SIGILL */ - SA_KILL, /* SIGTRAP */ - SA_KILL, /* SIGABRT */ - SA_KILL, /* SIGEMT */ - SA_KILL, /* SIGFPE */ - SA_KILL, /* SIGKILL */ - SA_KILL, /* SIGBUS */ - SA_KILL, /* SIGSEGV */ - SA_KILL, /* SIGSYS */ - SA_KILL, /* SIGPIPE */ - SA_KILL, /* SIGALRM */ - SA_KILL, /* SIGTERM */ - 0, /* SIGURG */ - SA_STOP, /* SIGSTOP */ - SA_STOP, /* SIGTSTP */ - SA_CONT, /* SIGCONT */ - 0, /* SIGCHLD */ - SA_STOP, /* SIGTTIN */ - SA_STOP, /* SIGTTOU */ - 0, /* SIGIO */ - SA_KILL, /* SIGXCPU */ - SA_KILL, /* SIGXFSZ */ - SA_KILL, /* SIGVTALRM */ - SA_KILL, /* SIGPROF */ - 0, /* SIGWINCH */ - 0, /* SIGINFO */ - SA_KILL, /* SIGUSR1 */ - SA_KILL /* SIGUSR2 */ -}; - -/* #define DEBUG_SIGNAL */ -#ifdef DEBUG_SIGNAL -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Signal setup and delivery. - * - * 1) Delivering signals to threads in the same KSE. - * These signals are sent by upcall events and are set in the - * km_sigscaught field of the KSE mailbox. Since these signals - * are received while operating on the KSE stack, they can be - * delivered either by using signalcontext() to add a stack frame - * to the target thread's stack, or by adding them in the thread's - * pending set and having the thread run them down after it - * 2) Delivering signals to threads in other KSEs/KSEGs. - * 3) Delivering signals to threads in critical regions. - * 4) Delivering signals to threads after they change their signal masks. - * - * Methods of delivering signals. - * - * 1) Add a signal frame to the thread's saved context. - * 2) Add the signal to the thread structure, mark the thread as - * having signals to handle, and let the thread run them down - * after it resumes from the KSE scheduler. - * - * Problem with 1). You can't do this to a running thread or a - * thread in a critical region. - * - * Problem with 2). You can't do this to a thread that doesn't - * yield in some way (explicitly enters the scheduler). A thread - * blocked in the kernel or a CPU hungry thread will not see the - * signal without entering the scheduler. - * - * The solution is to use both 1) and 2) to deliver signals: - * - * o Thread in critical region - use 2). When the thread - * leaves the critical region it will check to see if it - * has pending signals and run them down. - * - * o Thread enters scheduler explicitly - use 2). The thread - * can check for pending signals after it returns from the - * the scheduler. - * - * o Thread is running and not current thread - use 2). When the - * thread hits a condition specified by one of the other bullets, - * the signal will be delivered. - * - * o Thread is running and is current thread (e.g., the thread - * has just changed its signal mask and now sees that it has - * pending signals) - just run down the pending signals. - * - * o Thread is swapped out due to quantum expiration - use 1) - * - * o Thread is blocked in kernel - kse_thr_wakeup() and then - * use 1) - */ - -/* - * Rules for selecting threads for signals received: - * - * 1) If the signal is a sychronous signal, it is delivered to - * the generating (current thread). If the thread has the - * signal masked, it is added to the threads pending signal - * set until the thread unmasks it. - * - * 2) A thread in sigwait() where the signal is in the thread's - * waitset. - * - * 3) A thread in sigsuspend() where the signal is not in the - * thread's suspended signal mask. - * - * 4) Any thread (first found/easiest to deliver) that has the - * signal unmasked. - */ - -#ifndef SYSTEM_SCOPE_ONLY - -static void * -sig_daemon(void *arg __unused) -{ - int i; - kse_critical_t crit; - struct timespec ts; - sigset_t set; - struct kse *curkse; - struct pthread *curthread = _get_curthread(); - - DBG_MSG("signal daemon started(%p)\n", curthread); - - curthread->name = strdup("signal thread"); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - - /* - * Daemon thread is a bound thread and we must be created with - * all signals masked - */ -#if 0 - SIGFILLSET(set); - __sys_sigprocmask(SIG_SETMASK, &set, NULL); -#endif - __sys_sigpending(&set); - ts.tv_sec = 0; - ts.tv_nsec = 0; - while (1) { - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - _thr_proc_sigpending = set; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(set, i) != 0) - _thr_sig_dispatch(curkse, i, - NULL /* no siginfo */); - } - ts.tv_sec = 30; - ts.tv_nsec = 0; - curkse->k_kcb->kcb_kmbx.km_flags = - KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = 0; - set = curkse->k_kcb->kcb_kmbx.km_sigscaught; - } - return (0); -} - - -/* Utility function to create signal daemon thread */ -int -_thr_start_sig_daemon(void) -{ - pthread_attr_t attr; - sigset_t sigset, oldset; - - SIGFILLSET(sigset); - _pthread_sigmask(SIG_SETMASK, &sigset, &oldset); - _pthread_attr_init(&attr); - _pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - attr->flags |= THR_SIGNAL_THREAD; - /* sigmask will be inherited */ - if (_pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) - PANIC("can not create signal daemon thread!\n"); - _pthread_attr_destroy(&attr); - _pthread_sigmask(SIG_SETMASK, &oldset, NULL); - return (0); -} - -/* - * This signal handler only delivers asynchronous signals. - * This must be called with upcalls disabled and without - * holding any locks. - */ -void -_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) -{ - struct kse_mailbox *kmbx; - struct pthread *thread; - - DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { - /* - * Setup the target thread to receive the signal: - */ - DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); - KSE_SCHED_LOCK(curkse, thread->kseg); - if ((thread->state == PS_DEAD) || - (thread->state == PS_DEADLOCK) || - THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else if (SIGISMEMBER(thread->sigmask, sig)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else { - kmbx = _thr_sig_add(thread, sig, info); - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - break; - } - } - DBG_MSG("<<< _thr_sig_dispatch\n"); -} - -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static __inline int -sigprop(int sig) -{ - - if (sig > 0 && sig < NSIG) - return (sigproptbl[_SIG_IDX(sig)]); - return (0); -} - -typedef void (*ohandler)(int sig, int code, - struct sigcontext *scp, char *addr, __sighandler_t *catcher); - -void -_thr_sig_handler(int sig, siginfo_t *info, void *ucp_arg) -{ - struct pthread_sigframe psf; - __siginfohandler_t *sigfunc; - struct pthread *curthread; - struct kse *curkse; - ucontext_t *ucp; - struct sigaction act; - int sa_flags, err_save; - - err_save = errno; - ucp = (ucontext_t *)ucp_arg; - - DBG_MSG(">>> _thr_sig_handler(%d)\n", sig); - - curthread = _get_curthread(); - if (curthread == NULL) - PANIC("No current thread.\n"); - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - PANIC("Thread is not system scope.\n"); - if (curthread->flags & THR_FLAGS_EXITING) { - errno = err_save; - return; - } - - curkse = _get_curkse(); - /* - * If thread is in critical region or if thread is on - * the way of state transition, then latch signal into buffer. - */ - if (_kse_in_critical() || THR_IN_CRITICAL(curthread) || - curthread->state != PS_RUNNING) { - DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig); - curthread->siginfo[sig-1] = *info; - curthread->check_pending = 1; - curkse->k_sigseqno++; - SIGADDSET(curthread->sigpend, sig); - /* - * If the kse is on the way to idle itself, but - * we have signal ready, we should prevent it - * to sleep, kernel will latch the wakeup request, - * so kse_release will return from kernel immediately. - */ - if (KSE_IS_IDLE(curkse)) - kse_wakeup(&curkse->k_kcb->kcb_kmbx); - errno = err_save; - return; - } - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - thr_sigframe_save(curthread, &psf); - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - - _kse_critical_enter(); - /* Get a fresh copy of signal mask */ - __sys_sigprocmask(SIG_BLOCK, NULL, &curthread->sigmask); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - if (sa_flags & SA_RESETHAND) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Now invoke real handler */ - if (((__sighandler_t *)sigfunc != SIG_DFL) && - ((__sighandler_t *)sigfunc != SIG_IGN) && - (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { - if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) - (*(sigfunc))(sig, info, ucp); - else { - ((ohandler)(*sigfunc))( - sig, info->si_code, (struct sigcontext *)ucp, - info->si_addr, (__sighandler_t *)sigfunc); - } - } else { - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - else - kill(getpid(), sig); - } -#ifdef NOTYET - else if (sigprop(sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); -#endif - } - } - _kse_critical_enter(); - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - thr_sigframe_restore(curthread, &psf); - - DBG_MSG("<<< _thr_sig_handler(%d)\n", sig); - - errno = err_save; -} - -struct sighandle_info { - __siginfohandler_t *sigfunc; - int sa_flags; - int sig; - siginfo_t *info; - ucontext_t *ucp; -}; - -static void handle_signal(struct pthread *curthread, - struct sighandle_info *shi); -static void handle_signal_altstack(struct pthread *curthread, - struct sighandle_info *shi); - -/* Must be called with signal lock and schedule lock held in order */ -static void -thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, - ucontext_t *ucp) -{ - __siginfohandler_t *sigfunc; - sigset_t sigmask; - int sa_flags; - int onstack; - struct sigaction act; - struct kse *curkse; - struct sighandle_info shi; - - /* - * Invoke the signal handler without going through the scheduler: - */ - DBG_MSG("Got signal %d, calling handler for current thread %p\n", - sig, curthread); - - if (!_kse_in_critical()) - PANIC("thr_sig_invoke_handler without in critical\n"); - curkse = curthread->kse; - /* - * Check that a custom handler is installed and if - * the signal is not blocked: - */ - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - sigmask = curthread->sigmask; - SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); - if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) - SIGADDSET(curthread->sigmask, sig); - if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* - * We are processing buffered signals, synchronize working - * signal mask into kernel. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - onstack = _thr_sigonstack(&sigfunc); - ucp->uc_stack = curthread->sigstk; - ucp->uc_stack.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((onstack) ? SS_ONSTACK : 0); - if (curthread->oldsigmask) { - ucp->uc_sigmask = *(curthread->oldsigmask); - curthread->oldsigmask = NULL; - } else - ucp->uc_sigmask = sigmask; - shi.sigfunc = sigfunc; - shi.sig = sig; - shi.sa_flags = sa_flags; - shi.info = info; - shi.ucp = ucp; - if ((curthread->sigstk.ss_flags & SS_DISABLE) == 0) { - /* Deliver signal on alternative stack */ - if (sa_flags & SA_ONSTACK && !onstack) - handle_signal_altstack(curthread, &shi); - else - handle_signal(curthread, &shi); - } else { - handle_signal(curthread, &shi); - } - - _kse_critical_enter(); - /* Don't trust after critical leave/enter */ - curkse = curthread->kse; - - /* - * Restore the thread's signal mask. - */ - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - - DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); -} - -static void -handle_signal(struct pthread *curthread, struct sighandle_info *shi) -{ - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (shi->sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - if (((__sighandler_t *)shi->sigfunc != SIG_DFL) && - ((__sighandler_t *)shi->sigfunc != SIG_IGN)) { - if ((shi->sa_flags & SA_SIGINFO) != 0 || shi->info == NULL) - (*(shi->sigfunc))(shi->sig, shi->info, shi->ucp); - else { - ((ohandler)(*shi->sigfunc))( - shi->sig, shi->info->si_code, - (struct sigcontext *)shi->ucp, - shi->info->si_addr, - (__sighandler_t *)shi->sigfunc); - } - } else { - if ((__sighandler_t *)shi->sigfunc == SIG_DFL) { - if (sigprop(shi->sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, shi->sig); - else - kill(getpid(), shi->sig); - } -#ifdef NOTYET - else if (sigprop(shi->sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, - shi->sig); -#endif - } - } -} - -static void -handle_signal_wrapper(struct pthread *curthread, ucontext_t *ret_uc, - struct sighandle_info *shi) -{ - shi->ucp->uc_stack.ss_flags = SS_ONSTACK; - handle_signal(curthread, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(ret_uc); - else { - /* Work around for ia64, THR_SETCONTEXT does not work */ - _kse_critical_enter(); - curthread->tcb->tcb_tmbx.tm_context = *ret_uc; - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT */ - } -} - -/* - * Jump to stack set by sigaltstack before invoking signal handler - */ -static void -handle_signal_altstack(struct pthread *curthread, struct sighandle_info *shi) -{ - volatile int once; - ucontext_t uc1, *uc2; - - THR_ASSERT(_kse_in_critical(), "Not in critical"); - - once = 0; - THR_GETCONTEXT(&uc1); - if (once == 0) { - once = 1; - /* XXX - * We are still in critical region, it is safe to operate thread - * context - */ - uc2 = &curthread->tcb->tcb_tmbx.tm_context; - uc2->uc_stack = curthread->sigstk; - makecontext(uc2, (void (*)(void))handle_signal_wrapper, - 3, curthread, &uc1, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(uc2); - else { - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT(uc2); */ - } - } -} - -int -_thr_getprocsig(int sig, siginfo_t *siginfo) -{ - kse_critical_t crit; - struct kse *curkse; - int ret; - - DBG_MSG(">>> _thr_getprocsig\n"); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - ret = _thr_getprocsig_unlocked(sig, siginfo); - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(crit); - - DBG_MSG("<<< _thr_getprocsig\n"); - return (ret); -} - -int -_thr_getprocsig_unlocked(int sig, siginfo_t *siginfo) -{ - sigset_t sigset; - struct timespec ts; - - /* try to retrieve signal from kernel */ - SIGEMPTYSET(sigset); - SIGADDSET(sigset, sig); - ts.tv_sec = 0; - ts.tv_nsec = 0; - SIGDELSET(_thr_proc_sigpending, sig); - if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) - return (sig); - return (0); -} - -#ifndef SYSTEM_SCOPE_ONLY -/* - * Find a thread that can handle the signal. This must be called - * with upcalls disabled. - */ -struct pthread * -thr_sig_find(struct kse *curkse, int sig, siginfo_t *info __unused) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - struct pthread *suspended_thread, *signaled_thread; - __siginfohandler_t *sigfunc; - siginfo_t si; - - DBG_MSG("Looking for thread to handle signal %d\n", sig); - - /* - * Enter a loop to look for threads that have the signal - * unmasked. POSIX specifies that a thread in a sigwait - * will get the signal over any other threads. Second - * preference will be threads in a sigsuspend. Third - * preference will be the current thread. If none of the - * above, then the signal is delivered to the first thread - * that is found. Note that if a custom handler is not - * installed, the signal only affects threads in sigwait. - */ - suspended_thread = NULL; - signaled_thread = NULL; - - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread == _thr_sig_daemon) - continue; - /* Signal delivering to bound thread is done by kernel */ - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - continue; - /* Take the scheduling lock. */ - KSE_SCHED_LOCK(curkse, pthread->kseg); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - THR_IS_EXITING(pthread) || - THR_IS_SUSPENDED(pthread)) { - ; /* Skip this thread. */ - } else if (pthread->state == PS_SIGWAIT && - SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* - * retrieve signal from kernel, if it is job control - * signal, and sigaction is SIG_DFL, then we will - * be stopped in kernel, we hold lock here, but that - * does not matter, because that's job control, and - * whole process should be stopped. - */ - if (_thr_getprocsig(sig, &si)) { - DBG_MSG("Waking thread %p in sigwait" - " with signal %d\n", pthread, sig); - /* where to put siginfo ? */ - *(pthread->data.sigwait->siginfo) = si; - kmbx = _thr_setrunnable_unlocked(pthread); - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - /* - * POSIX doesn't doesn't specify which thread - * will get the signal if there are multiple - * waiters, so we give it to the first thread - * we find. - * - * Do not attempt to deliver this signal - * to other threads and do not add the signal - * to the process pending set. - */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (kmbx != NULL) - kse_wakeup(kmbx); - if (suspended_thread != NULL) - _thr_ref_delete(NULL, suspended_thread); - if (signaled_thread != NULL) - _thr_ref_delete(NULL, signaled_thread); - return (NULL); - } else if (!SIGISMEMBER(pthread->sigmask, sig)) { - /* - * If debugger is running, we don't quick exit, - * and give it a chance to check the signal. - */ - if (_libkse_debug == 0) { - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - } - } - if (pthread->state == PS_SIGSUSPEND) { - if (suspended_thread == NULL) { - suspended_thread = pthread; - suspended_thread->refcount++; - } - } else if (signaled_thread == NULL) { - signaled_thread = pthread; - signaled_thread->refcount++; - } - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - if (suspended_thread != NULL) { - pthread = suspended_thread; - if (signaled_thread) - _thr_ref_delete(NULL, signaled_thread); - } else if (signaled_thread) { - pthread = signaled_thread; - } else { - pthread = NULL; - } - return (pthread); -} -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static inline void -build_siginfo(siginfo_t *info, int signo) -{ - bzero(info, sizeof(*info)); - info->si_signo = signo; - info->si_pid = _thr_pid; -} - -/* - * This is called by a thread when it has pending signals to deliver. - * It should only be called from the context of the thread. - */ -void -_thr_sig_rundown(struct pthread *curthread, ucontext_t *ucp) -{ - struct pthread_sigframe psf; - siginfo_t siginfo; - int i, err_save; - kse_critical_t crit; - struct kse *curkse; - sigset_t sigmask; - - err_save = errno; - - DBG_MSG(">>> thr_sig_rundown (%p)\n", curthread); - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - THR_ASSERT((curthread->state == PS_RUNNING), "state is not PS_RUNNING"); - - thr_sigframe_save(curthread, &psf); - /* - * Lower the priority before calling the handler in case - * it never returns (longjmps back): - */ - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - curthread->active_priority &= ~THR_SIGNAL_PRIORITY; - SIGFILLSET(sigmask); - while (1) { - /* - * For bound thread, we mask all signals and get a fresh - * copy of signal mask from kernel - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - } - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i-1]; - break; - } - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - && SIGISMEMBER(_thr_proc_sigpending, i)) { - if (_thr_getprocsig_unlocked(i, &siginfo)) - break; - } - } - if (i <= _SIG_MAXSIG) - thr_sig_invoke_handler(curthread, i, &siginfo, ucp); - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, - &curthread->sigmask, NULL); - } - break; - } - } - - /* Don't trust after signal handling */ - curkse = curthread->kse; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - /* repost masked signal to kernel, it hardly happens in real world */ - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - !SIGISEMPTY(curthread->sigpend)) { /* dirty read */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - if (!_kse_isthreaded()) - kill(getpid(), i); - else - kse_thr_interrupt( - &curthread->tcb->tcb_tmbx, - KSE_INTR_SENDSIG, - i); - } - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - } - DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread); - - thr_sigframe_restore(curthread, &psf); - errno = err_save; -} - -/* - * This checks pending signals for the current thread. It should be - * called whenever a thread changes its signal mask. Note that this - * is called from a thread (using its stack). - * - * XXX - We might want to just check to see if there are pending - * signals for the thread here, but enter the UTS scheduler - * to actually install the signal handler(s). - */ -void -_thr_sig_check_pending(struct pthread *curthread) -{ - ucontext_t uc; - volatile int once; - int errsave; - - /* - * If the thread is in critical region, delay processing signals. - * If the thread state is not PS_RUNNING, it might be switching - * into UTS and but a THR_LOCK_RELEASE saw check_pending, and it - * goes here, in the case we delay processing signals, lets UTS - * process complicated things, normally UTS will call _thr_sig_add - * to resume the thread, so we needn't repeat doing it here. - */ - if (THR_IN_CRITICAL(curthread) || curthread->state != PS_RUNNING) - return; - - errsave = errno; - once = 0; - THR_GETCONTEXT(&uc); - if (once == 0) { - once = 1; - curthread->check_pending = 0; - _thr_sig_rundown(curthread, &uc); - } - errno = errsave; -} - -/* - * Perform thread specific actions in response to a signal. - * This function is only called if there is a handler installed - * for the signal, and if the target thread has the signal - * unmasked. - * - * This must be called with the thread's scheduling lock held. - */ -struct kse_mailbox * -_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) -{ - siginfo_t siginfo; - struct kse *curkse; - struct kse_mailbox *kmbx = NULL; - struct pthread *curthread = _get_curthread(); - int restart; - int suppress_handler = 0; - int fromproc = 0; - __sighandler_t *sigfunc; - - DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig); - - curkse = _get_curkse(); - restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; - sigfunc = _thread_sigact[sig - 1].sa_handler; - fromproc = (curthread == _thr_sig_daemon); - - if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || - pthread->state == PS_STATE_MAX) - return (NULL); /* return false */ - - if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (curthread != pthread)) { - PANIC("Please use _thr_send_sig for bound thread"); - return (NULL); - } - - if (pthread->state != PS_SIGWAIT && - SIGISMEMBER(pthread->sigmask, sig)) { - /* signal is masked, just add signal to thread. */ - if (!fromproc) { - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - } else { - if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) - return (NULL); - SIGADDSET(pthread->sigpend, sig); - } - } - else { - /* if process signal not exists, just return */ - if (fromproc) { - if (!_thr_getprocsig(sig, &siginfo)) - return (NULL); - info = &siginfo; - } - - if (pthread->state != PS_SIGWAIT && sigfunc == SIG_DFL && - (sigprop(sig) & SA_KILL)) { - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - - /* - * Process according to thread state: - */ - switch (pthread->state) { - case PS_DEAD: - case PS_DEADLOCK: - case PS_STATE_MAX: - return (NULL); /* XXX return false */ - case PS_LOCKWAIT: - case PS_SUSPENDED: - /* - * You can't call a signal handler for threads in these - * states. - */ - suppress_handler = 1; - break; - case PS_RUNNING: - if ((pthread->flags & THR_FLAGS_IN_RUNQ)) { - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - THR_RUNQ_INSERT_TAIL(pthread); - } else { - /* Possible not in RUNQ and has curframe ? */ - pthread->active_priority |= THR_SIGNAL_PRIORITY; - } - break; - /* - * States which cannot be interrupted but still require the - * signal handler to run: - */ - case PS_COND_WAIT: - case PS_MUTEX_WAIT: - break; - - case PS_SLEEP_WAIT: - /* - * Unmasked signals always cause sleep to terminate - * early regardless of SA_RESTART: - */ - pthread->interrupted = 1; - break; - - case PS_JOIN: - break; - - case PS_SIGSUSPEND: - pthread->interrupted = 1; - break; - - case PS_SIGWAIT: - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - /* - * The signal handler is not called for threads in - * SIGWAIT. - */ - suppress_handler = 1; - /* Wake up the thread if the signal is not blocked. */ - if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* Return the signal number: */ - *(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1]; - /* Make the thread runnable: */ - kmbx = _thr_setrunnable_unlocked(pthread); - } else { - /* Increment the pending signal count. */ - SIGADDSET(pthread->sigpend, sig); - if (!SIGISMEMBER(pthread->sigmask, sig)) { - if (sigfunc == SIG_DFL && - sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, - sig); - /* Never reach */ - } - pthread->check_pending = 1; - pthread->interrupted = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - return (kmbx); - } - - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, sizeof(*info)); - pthread->check_pending = 1; - if (!(pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (pthread->blocked != 0) && !THR_IN_CRITICAL(pthread)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - if (suppress_handler == 0) { - /* - * Setup a signal frame and save the current threads - * state: - */ - if (pthread->state != PS_RUNNING) { - if (pthread->flags & THR_FLAGS_IN_RUNQ) - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - } - return (kmbx); -} - -/* - * Send a signal to a specific thread (ala pthread_kill): - */ -void -_thr_sig_send(struct pthread *pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, KSE_INTR_SENDSIG, sig); - return; - } - - /* Lock the scheduling queue of the target thread. */ - THR_SCHED_LOCK(curthread, pthread); - if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { - kmbx = _thr_sig_add(pthread, sig, NULL); - /* Add a preemption point. */ - if (kmbx == NULL && (curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - /* XXX - * If thread sent signal to itself, check signals now. - * It is not really needed, _kse_critical_leave should - * have already checked signals. - */ - if (pthread == curthread && curthread->check_pending) - _thr_sig_check_pending(curthread); - - } else { - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -static inline void -thr_sigframe_restore(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - curthread->cancelflags = psf->psf_cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - curthread->flags = psf->psf_flags; - curthread->interrupted = psf->psf_interrupted; - curthread->timeout = psf->psf_timeout; - curthread->data = psf->psf_wait_data; - curthread->wakeup_time = psf->psf_wakeup_time; - curthread->continuation = psf->psf_continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -static inline void -thr_sigframe_save(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - psf->psf_cancelflags = curthread->cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - /* This has to initialize all members of the sigframe. */ - psf->psf_flags = (curthread->flags & (THR_FLAGS_PRIVATE | THR_FLAGS_EXITING)); - psf->psf_interrupted = curthread->interrupted; - psf->psf_timeout = curthread->timeout; - psf->psf_wait_data = curthread->data; - psf->psf_wakeup_time = curthread->wakeup_time; - psf->psf_continuation = curthread->continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -void -_thr_signal_init(void) -{ - struct sigaction act; - __siginfohandler_t *sigfunc; - int i; - sigset_t sigset; - - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Get the signal handler details: */ - if (__sys_sigaction(i, NULL, &_thread_sigact[i - 1]) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot read signal handler info"); - } - /* Intall wrapper if handler was set */ - sigfunc = _thread_sigact[i - 1].sa_sigaction; - if (((__sighandler_t *)sigfunc) != SIG_DFL && - ((__sighandler_t *)sigfunc) != SIG_IGN) { - act = _thread_sigact[i - 1]; - act.sa_flags |= SA_SIGINFO; - act.sa_sigaction = - (__siginfohandler_t *)_thr_sig_handler; - __sys_sigaction(i, &act, NULL); - } - } - if (_thr_dump_enabled()) { - /* - * Install the signal handler for SIGINFO. It isn't - * really needed, but it is nice to have for debugging - * purposes. - */ - _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; - SIGEMPTYSET(act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_RESTART; - act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; - if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - /* - * Abort this process if signal initialisation fails: - */ - PANIC("Cannot initialize signal handler"); - } - } - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); - __sys_sigaltstack(NULL, &_thr_initial->sigstk); -} - -void -_thr_signal_deinit(void) -{ - int i; - struct pthread *curthread = _get_curthread(); - - /* Clear process pending signals. */ - sigemptyset(&_thr_proc_sigpending); - - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Check for signals which cannot be trapped: */ - if (i == SIGKILL || i == SIGSTOP) { - } - - /* Set the signal handler details: */ - else if (__sys_sigaction(i, &_thread_sigact[i - 1], - NULL) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot set signal handler info"); - } - } - __sys_sigaltstack(&curthread->sigstk, NULL); -} - diff --git a/lib/libkse/thread/thr_sigaction.c b/lib/libkse/thread/thr_sigaction.c deleted file mode 100644 index dda1c35..0000000 --- a/lib/libkse/thread/thr_sigaction.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_sigaction, sigaction); - -int -_sigaction(int sig, const struct sigaction * act, struct sigaction * oact) -{ - int ret = 0; - int err = 0; - struct sigaction newact, oldact; - struct pthread *curthread; - kse_critical_t crit; - - /* Check if the signal number is out of range: */ - if (sig < 1 || sig > _SIG_MAXSIG) { - /* Return an invalid argument: */ - errno = EINVAL; - ret = -1; - } else { - if (act) - newact = *act; - - crit = _kse_critical_enter(); - curthread = _get_curthread(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - - oldact = _thread_sigact[sig - 1]; - - /* Check if a signal action was supplied: */ - if (act != NULL) { - /* Set the new signal handler: */ - _thread_sigact[sig - 1] = newact; - } - - /* - * Check if the kernel needs to be advised of a change - * in signal action: - */ - if (act != NULL) { - - newact.sa_flags |= SA_SIGINFO; - - /* - * Check if the signal handler is being set to - * the default or ignore handlers: - */ - if (newact.sa_handler != SIG_DFL && - newact.sa_handler != SIG_IGN) { - /* - * Specify the thread kernel signal - * handler: - */ - newact.sa_sigaction = _thr_sig_handler; - } - /* - * Install libpthread signal handler wrapper - * for SIGINFO signal if threads dump enabled - * even if a user set the signal handler to - * SIG_DFL or SIG_IGN. - */ - if (sig == SIGINFO && _thr_dump_enabled()) { - newact.sa_sigaction = _thr_sig_handler; - } - /* Change the signal action in the kernel: */ - if (__sys_sigaction(sig, &newact, NULL) != 0) { - _thread_sigact[sig - 1] = oldact; - /* errno is in kse, will copy it to thread */ - err = errno; - ret = -1; - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - /* - * Check if the existing signal action structure contents are - * to be returned: - */ - if (oact != NULL) { - /* Return the existing signal action contents: */ - *oact = oldact; - } - if (ret != 0) { - /* Return errno to thread */ - errno = err; - } - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_sigaltstack.c b/lib/libkse/thread/thr_sigaltstack.c deleted file mode 100644 index 629f5b0..0000000 --- a/lib/libkse/thread/thr_sigaltstack.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2003 David Xu <davidxu@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <errno.h> -#include <signal.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _sigaltstack(stack_t *_ss, stack_t *_oss); - -__weak_reference(_sigaltstack, sigaltstack); - -int -_sigaltstack(stack_t *_ss, stack_t *_oss) -{ - struct pthread *curthread = _get_curthread(); - stack_t ss, oss; - int oonstack, errsave, ret; - kse_critical_t crit; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - crit = _kse_critical_enter(); - ret = __sys_sigaltstack(_ss, _oss); - errsave = errno; - /* Get a copy */ - if (ret == 0 && _ss != NULL) - curthread->sigstk = *_ss; - _kse_critical_leave(crit); - errno = errsave; - return (ret); - } - - if (_ss) - ss = *_ss; - if (_oss) - oss = *_oss; - - /* Should get and set stack in atomic way */ - crit = _kse_critical_enter(); - oonstack = _thr_sigonstack(&ss); - if (_oss != NULL) { - oss = curthread->sigstk; - oss.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((oonstack) ? SS_ONSTACK : 0); - } - - if (_ss != NULL) { - if (oonstack) { - _kse_critical_leave(crit); - errno = EPERM; - return (-1); - } - if ((ss.ss_flags & ~SS_DISABLE) != 0) { - _kse_critical_leave(crit); - errno = EINVAL; - return (-1); - } - if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < MINSIGSTKSZ) { - _kse_critical_leave(crit); - errno = ENOMEM; - return (-1); - } - curthread->sigstk = ss; - } else { - curthread->sigstk.ss_flags |= SS_DISABLE; - } - } - _kse_critical_leave(crit); - if (_oss != NULL) - *_oss = oss; - return (0); -} - -int -_thr_sigonstack(void *sp) -{ - struct pthread *curthread = _get_curthread(); - - return ((curthread->sigstk.ss_flags & SS_DISABLE) == 0 ? - (((size_t)sp - (size_t)curthread->sigstk.ss_sp) < curthread->sigstk.ss_size) - : 0); -} - diff --git a/lib/libkse/thread/thr_sigmask.c b/lib/libkse/thread/thr_sigmask.c deleted file mode 100644 index 4a9fdea..0000000 --- a/lib/libkse/thread/thr_sigmask.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_sigmask, pthread_sigmask); - -int -_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldset, newset; - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - ret = __sys_sigprocmask(how, set, oset); - if (ret != 0) - ret = errno; - /* Get a fresh copy */ - __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); - return (ret); - } - - if (set) - newset = *set; - - THR_SCHED_LOCK(curthread, curthread); - - ret = 0; - if (oset != NULL) - /* Return the current mask: */ - oldset = curthread->sigmask; - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - /* Process according to what to do: */ - switch (how) { - /* Block signals: */ - case SIG_BLOCK: - /* Add signals to the existing mask: */ - SIGSETOR(curthread->sigmask, newset); - break; - - /* Unblock signals: */ - case SIG_UNBLOCK: - /* Clear signals from the existing mask: */ - SIGSETNAND(curthread->sigmask, newset); - break; - - /* Set the signal process mask: */ - case SIG_SETMASK: - /* Set the new mask: */ - curthread->sigmask = newset; - break; - - /* Trap invalid actions: */ - default: - /* Return an invalid argument: */ - ret = EINVAL; - break; - } - SIG_CANTMASK(curthread->sigmask); - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * Run down any pending signals: - */ - if (ret == 0) - _thr_sig_check_pending(curthread); - } else - THR_SCHED_UNLOCK(curthread, curthread); - - if (ret == 0 && oset != NULL) - *oset = oldset; - return (ret); -} diff --git a/lib/libkse/thread/thr_sigpending.c b/lib/libkse/thread/thr_sigpending.c deleted file mode 100644 index f0183e7..0000000 --- a/lib/libkse/thread/thr_sigpending.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _sigpending(sigset_t *set); - -__weak_reference(_sigpending, sigpending); - -int -_sigpending(sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - sigset_t sigset; - int ret = 0; - - /* Check for a null signal set pointer: */ - if (set == NULL) { - /* Return an invalid argument: */ - ret = EINVAL; - } - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigpending(set)); - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - sigset = curthread->sigpend; - KSE_SCHED_UNLOCK(curthread->kse, curthread->kseg); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - SIGSETOR(sigset, _thr_proc_sigpending); - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - *set = sigset; - } - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libkse/thread/thr_sigprocmask.c b/lib/libkse/thread/thr_sigprocmask.c deleted file mode 100644 index 45fa5e2..0000000 --- a/lib/libkse/thread/thr_sigprocmask.c +++ /dev/null @@ -1,55 +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. 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 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$ - */ - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_sigprocmask, sigprocmask); - -int -_sigprocmask(int how, const sigset_t *set, sigset_t *oset) -{ - int ret; - - ret = _pthread_sigmask(how, set, oset); - if (ret) { - errno = ret; - ret = -1; - } - return (ret); -} diff --git a/lib/libkse/thread/thr_sigsuspend.c b/lib/libkse/thread/thr_sigsuspend.c deleted file mode 100644 index a6ef350..0000000 --- a/lib/libkse/thread/thr_sigsuspend.c +++ /dev/null @@ -1,109 +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. 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 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <string.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __sigsuspend(const sigset_t * set); - -__weak_reference(__sigsuspend, sigsuspend); - -int -_sigsuspend(const sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldmask, newmask, tempset; - int ret = -1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigsuspend(set)); - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - newmask = *set; - SIG_CANTMASK(newmask); - THR_LOCK_SWITCH(curthread); - - /* Save current sigmask: */ - oldmask = curthread->sigmask; - curthread->oldsigmask = &oldmask; - - /* Change the caller's mask: */ - curthread->sigmask = newmask; - tempset = curthread->sigpend; - SIGSETNAND(tempset, newmask); - if (SIGISEMPTY(tempset)) { - THR_SET_STATE(curthread, PS_SIGSUSPEND); - /* Wait for a signal: */ - _thr_sched_switch_unlocked(curthread); - } else { - curthread->check_pending = 1; - THR_UNLOCK_SWITCH(curthread); - /* check pending signal I can handle: */ - _thr_sig_check_pending(curthread); - } - if ((curthread->cancelflags & THR_CANCELLING) != 0) - curthread->oldsigmask = NULL; - else { - THR_ASSERT(curthread->oldsigmask == NULL, - "oldsigmask is not cleared"); - } - - /* Always return an interrupted error: */ - errno = EINTR; - } else { - /* Return an invalid argument error: */ - errno = EINVAL; - } - - /* Return the completion status: */ - return (ret); -} - -int -__sigsuspend(const sigset_t * set) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _sigsuspend(set); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_sigwait.c b/lib/libkse/thread/thr_sigwait.c deleted file mode 100644 index a9cdafa..0000000 --- a/lib/libkse/thread/thr_sigwait.c +++ /dev/null @@ -1,210 +0,0 @@ -//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) -/* - * Copyright (c) 1997 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. 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 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$ - */ - -#include "namespace.h" -#include <signal.h> -#include <sys/param.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int __sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout); -int __sigwaitinfo(const sigset_t *set, siginfo_t *info); -int __sigwait(const sigset_t *set, int *sig); -int _sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout); -int _sigwaitinfo(const sigset_t *set, siginfo_t *info); -int _sigwait(const sigset_t *set, int *sig); - -__weak_reference(__sigwait, sigwait); -__weak_reference(__sigtimedwait, sigtimedwait); -__weak_reference(__sigwaitinfo, sigwaitinfo); - -static int -lib_sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - int i; - struct sigwait_data waitdata; - sigset_t waitset; - kse_critical_t crit; - siginfo_t siginfo; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - if (info == NULL) - info = &siginfo; - return (__sys_sigtimedwait(set, info, timeout)); - } - - /* - * Initialize the set of signals that will be waited on: - */ - waitset = *set; - - /* These signals can't be waited on. */ - SIGDELSET(waitset, SIGKILL); - SIGDELSET(waitset, SIGSTOP); - - /* - * POSIX says 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. - */ - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(waitset, i) && - SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i - 1]; - KSE_SCHED_UNLOCK(curthread->kse, - curthread->kseg); - _kse_critical_leave(crit); - ret = i; - goto OUT; - } - } - curthread->timeout = 0; - curthread->interrupted = 0; - _thr_set_timeout(timeout); - /* Wait for a signal: */ - siginfo.si_signo = 0; - waitdata.waitset = &waitset; - waitdata.siginfo = &siginfo; - curthread->data.sigwait = &waitdata; - THR_SET_STATE(curthread, PS_SIGWAIT); - _thr_sched_switch_unlocked(curthread); - /* - * Return the signal number to the caller: - */ - if (siginfo.si_signo > 0) { - ret = siginfo.si_signo; - } else { - if (curthread->interrupted) - errno = EINTR; - else if (curthread->timeout) - errno = EAGAIN; - ret = -1; - } - curthread->timeout = 0; - curthread->interrupted = 0; - /* - * Probably unnecessary, but since it's in a union struct - * we don't know how it could be used in the future. - */ - curthread->data.sigwait = NULL; - -OUT: - if (ret > 0 && info != NULL) - *info = siginfo; - - return (ret); -} - -int -__sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, timeout); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int _sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - return lib_sigtimedwait(set, info, timeout); -} - -int -__sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, NULL); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - return lib_sigtimedwait(set, info, NULL); -} - -int -__sigwait(const sigset_t *set, int *sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwait(const sigset_t *set, int *sig) -{ - int ret; - - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - return (ret); -} - diff --git a/lib/libkse/thread/thr_single_np.c b/lib/libkse/thread/thr_single_np.c deleted file mode 100644 index 8f004e9..0000000 --- a/lib/libkse/thread/thr_single_np.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1996 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. 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 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$ - */ - -#include "namespace.h" -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_single_np(void); - -__weak_reference(_pthread_single_np, pthread_single_np); - -int _pthread_single_np(void) -{ - - /* Enter single-threaded (non-POSIX) scheduling mode: */ - _pthread_suspend_all_np(); - /* - * XXX - Do we want to do this? - * __is_threaded = 0; - */ - return (0); -} diff --git a/lib/libkse/thread/thr_sleep.c b/lib/libkse/thread/thr_sleep.c deleted file mode 100644 index ffa76b2..0000000 --- a/lib/libkse/thread/thr_sleep.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <unistd.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -extern unsigned int __sleep(unsigned int); -extern int __usleep(useconds_t); - -unsigned int _sleep(unsigned int seconds); - -__weak_reference(_sleep, sleep); -__weak_reference(_usleep, usleep); - -unsigned int -_sleep(unsigned int seconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __sleep(seconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} - -int -_usleep(useconds_t useconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __usleep(useconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_spec.c b/lib/libkse/thread/thr_spec.c deleted file mode 100644 index 1d4be45..0000000 --- a/lib/libkse/thread/thr_spec.c +++ /dev/null @@ -1,231 +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. 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 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$ - */ - -#include "namespace.h" -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - - -struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX]; - -__weak_reference(_pthread_key_create, pthread_key_create); -__weak_reference(_pthread_key_delete, pthread_key_delete); -__weak_reference(_pthread_getspecific, pthread_getspecific); -__weak_reference(_pthread_setspecific, pthread_setspecific); - - -int -_pthread_key_create(pthread_key_t *key, void (*destructor) (void *)) -{ - struct pthread *curthread; - int i; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; i < PTHREAD_KEYS_MAX; i++) { - - if (_thread_keytable[i].allocated == 0) { - _thread_keytable[i].allocated = 1; - _thread_keytable[i].destructor = destructor; - _thread_keytable[i].seqno++; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - *key = i; - return (0); - } - - } - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - return (EAGAIN); -} - -int -_pthread_key_delete(pthread_key_t key) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - - if (_thread_keytable[key].allocated) - _thread_keytable[key].allocated = 0; - else - ret = EINVAL; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - } else - ret = EINVAL; - return (ret); -} - -void -_thread_cleanupspecific(void) -{ - struct pthread *curthread = _get_curthread(); - const_key_destructor_t destructor; - const void *data = NULL; - int key; - int i; - - if (curthread->specific == NULL) - return; - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) && - (curthread->specific_data_count > 0); i++) { - for (key = 0; (key < PTHREAD_KEYS_MAX) && - (curthread->specific_data_count > 0); key++) { - destructor = NULL; - - if (_thread_keytable[key].allocated && - (curthread->specific[key].data != NULL)) { - if (curthread->specific[key].seqno == - _thread_keytable[key].seqno) { - data = curthread->specific[key].data; - destructor = (const_key_destructor_t) - _thread_keytable[key].destructor; - } - curthread->specific[key].data = NULL; - curthread->specific_data_count--; - } - - /* - * If there is a destructore, call it - * with the key table entry unlocked: - */ - if (destructor != NULL) { - /* - * Don't hold the lock while calling the - * destructor: - */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - destructor(data); - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - } - } - } - THR_LOCK_RELEASE(curthread, &_keytable_lock); - free(curthread->specific); - curthread->specific = NULL; - if (curthread->specific_data_count > 0) - stderr_debug("Thread %p has exited with leftover " - "thread-specific data after %d destructor iterations\n", - curthread, PTHREAD_DESTRUCTOR_ITERATIONS); -} - -static inline struct pthread_specific_elem * -pthread_key_allocate_data(void) -{ - struct pthread_specific_elem *new_data; - - new_data = (struct pthread_specific_elem *) - malloc(sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - if (new_data != NULL) { - memset((void *) new_data, 0, - sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - } - return (new_data); -} - -int -_pthread_setspecific(pthread_key_t key, const void *value) -{ - struct pthread *pthread; - int ret = 0; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - if ((pthread->specific) || - (pthread->specific = pthread_key_allocate_data())) { - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - if (_thread_keytable[key].allocated) { - if (pthread->specific[key].data == NULL) { - if (value != NULL) - pthread->specific_data_count++; - } else if (value == NULL) - pthread->specific_data_count--; - *(const void **)&pthread->specific[key].data = value; - pthread->specific[key].seqno = - _thread_keytable[key].seqno; - ret = 0; - } else - ret = EINVAL; - } else - ret = EINVAL; - } else - ret = ENOMEM; - return (ret); -} - -void * -_pthread_getspecific(pthread_key_t key) -{ - struct pthread *pthread; - void *data; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - /* Check if there is specific data: */ - if (pthread->specific != NULL && (unsigned int)key < PTHREAD_KEYS_MAX) { - /* Check if this key has been used before: */ - if (_thread_keytable[key].allocated && - (pthread->specific[key].seqno == _thread_keytable[key].seqno)) { - /* Return the value: */ - data = pthread->specific[key].data; - } else { - /* - * This key has not been used before, so return NULL - * instead: - */ - data = NULL; - } - } else - /* No specific data has been created, so just return NULL: */ - data = NULL; - return (data); -} diff --git a/lib/libkse/thread/thr_spinlock.c b/lib/libkse/thread/thr_spinlock.c deleted file mode 100644 index 685301f..0000000 --- a/lib/libkse/thread/thr_spinlock.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 1997 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. 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 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$ - * - */ - -#include "namespace.h" -#include <sys/types.h> -#include <machine/atomic.h> -#include <pthread.h> -#include <libc_private.h> -#include "un-namespace.h" -#include "spinlock.h" -#include "thr_private.h" - -#define MAX_SPINLOCKS 72 - -struct spinlock_extra { - spinlock_t *owner; - pthread_mutex_t lock; -}; - -struct nv_spinlock { - long access_lock; - long lock_owner; - struct spinlock_extra *extra; /* overlays fname in spinlock_t */ - int lineno; -}; -typedef struct nv_spinlock nv_spinlock_t; - -static void init_spinlock(spinlock_t *lck); - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -static pthread_mutex_t spinlock_static_lock; -static struct spinlock_extra extra[MAX_SPINLOCKS]; -static int spinlock_count = 0; -static int initialized = 0; - -/* - * These are for compatability only. Spinlocks of this type - * are deprecated. - */ - -void -_spinunlock(spinlock_t *lck) -{ - struct spinlock_extra *sl_extra; - - sl_extra = ((nv_spinlock_t *)lck)->extra; - _pthread_mutex_unlock(&sl_extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - */ -void -_spinlock(spinlock_t *lck) -{ - struct spinlock_extra *sl_extra; - - if (!__isthreaded) - PANIC("Spinlock called when not threaded."); - if (!initialized) - PANIC("Spinlocks not initialized."); - /* - * Try to grab the lock and loop if another thread grabs - * it before we do. - */ - if (lck->fname == NULL) - init_spinlock(lck); - sl_extra = ((nv_spinlock_t *)lck)->extra; - _pthread_mutex_lock(&sl_extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - * - * This function checks if the running thread has already locked the - * location, warns if this occurs and creates a thread dump before - * returning. - */ -void -_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused) -{ - _spinlock(lck); -} - -static void -init_spinlock(spinlock_t *lck) -{ - _pthread_mutex_lock(&spinlock_static_lock); - if ((lck->fname == NULL) && (spinlock_count < MAX_SPINLOCKS)) { - lck->fname = (char *)&extra[spinlock_count]; - extra[spinlock_count].owner = lck; - spinlock_count++; - } - _pthread_mutex_unlock(&spinlock_static_lock); - if (lck->fname == NULL) - PANIC("Exceeded max spinlocks"); -} - -void -_thr_spinlock_init(void) -{ - int i; - - if (initialized != 0) { - _thr_mutex_reinit(&spinlock_static_lock); - for (i = 0; i < spinlock_count; i++) - _thr_mutex_reinit(&extra[i].lock); - } else { - if (_pthread_mutex_init(&spinlock_static_lock, &static_mattr)) - PANIC("Cannot initialize spinlock_static_lock"); - for (i = 0; i < MAX_SPINLOCKS; i++) { - if (_pthread_mutex_init(&extra[i].lock, &static_mattr)) - PANIC("Cannot initialize spinlock extra"); - } - initialized = 1; - } -} diff --git a/lib/libkse/thread/thr_stack.c b/lib/libkse/thread/thr_stack.c deleted file mode 100644 index 6309e29..0000000 --- a/lib/libkse/thread/thr_stack.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 2000-2001 Jason Evans <jasone@freebsd.org> - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/queue.h> -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* Spare thread stack. */ -struct stack { - LIST_ENTRY(stack) qe; /* Stack queue linkage. */ - size_t stacksize; /* Stack size (rounded up). */ - size_t guardsize; /* Guard size. */ - void *stackaddr; /* Stack address. */ -}; - -/* - * Default sized (stack and guard) spare stack queue. Stacks are cached - * to avoid additional complexity managing mmap()ed stack regions. Spare - * stacks are used in LIFO order to increase cache locality. - */ -static LIST_HEAD(, stack) dstackq = LIST_HEAD_INITIALIZER(dstackq); - -/* - * Miscellaneous sized (non-default stack and/or guard) spare stack queue. - * Stacks are cached to avoid additional complexity managing mmap()ed - * stack regions. This list is unordered, since ordering on both stack - * size and guard size would be more trouble than it's worth. Stacks are - * allocated from this cache on a first size match basis. - */ -static LIST_HEAD(, stack) mstackq = LIST_HEAD_INITIALIZER(mstackq); - -/** - * Base address of the last stack allocated (including its red zone, if - * there is one). Stacks are allocated contiguously, starting beyond the - * top of the main stack. When a new stack is created, a red zone is - * typically created (actually, the red zone is mapped with PROT_NONE) above - * the top of the stack, such that the stack will not be able to grow all - * the way to the bottom of the next stack. This isn't fool-proof. It is - * possible for a stack to grow by a large amount, such that it grows into - * the next stack, and as long as the memory within the red zone is never - * accessed, nothing will prevent one thread stack from trouncing all over - * the next. - * - * low memory - * . . . . . . . . . . . . . . . . . . - * | | - * | stack 3 | start of 3rd thread stack - * +-----------------------------------+ - * | | - * | Red Zone (guard page) | red zone for 2nd thread - * | | - * +-----------------------------------+ - * | stack 2 - PTHREAD_STACK_DEFAULT | top of 2nd thread stack - * | | - * | | - * | | - * | | - * | stack 2 | - * +-----------------------------------+ <-- start of 2nd thread stack - * | | - * | Red Zone | red zone for 1st thread - * | | - * +-----------------------------------+ - * | stack 1 - PTHREAD_STACK_DEFAULT | top of 1st thread stack - * | | - * | | - * | | - * | | - * | stack 1 | - * +-----------------------------------+ <-- start of 1st thread stack - * | | (initial value of last_stack) - * | Red Zone | - * | | red zone for main thread - * +-----------------------------------+ - * | USRSTACK - PTHREAD_STACK_INITIAL | top of main thread stack - * | | ^ - * | | | - * | | | - * | | | stack growth - * | | - * +-----------------------------------+ <-- start of main thread stack - * (USRSTACK) - * high memory - * - */ -static void *last_stack = NULL; - -/* - * Round size up to the nearest multiple of - * _thr_page_size. - */ -static inline size_t -round_up(size_t size) -{ - if (size % _thr_page_size != 0) - size = ((size / _thr_page_size) + 1) * - _thr_page_size; - return (size); -} - -int -_thr_stack_alloc(struct pthread_attr *attr) -{ - struct stack *spare_stack; - struct kse *curkse; - kse_critical_t crit; - size_t stacksize; - size_t guardsize; - char *stackaddr; - - /* - * Round up stack size to nearest multiple of _thr_page_size so - * that mmap() * will work. If the stack size is not an even - * multiple, we end up initializing things such that there is - * unused space above the beginning of the stack, so the stack - * sits snugly against its guard. - */ - stacksize = round_up(attr->stacksize_attr); - guardsize = round_up(attr->guardsize_attr); - - attr->stackaddr_attr = NULL; - attr->flags &= ~THR_STACK_USER; - - /* - * Use the garbage collector lock for synchronization of the - * spare stack lists and allocations from usrstack. - */ - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * If the stack and guard sizes are default, try to allocate a stack - * from the default-size stack cache: - */ - if ((stacksize == _thr_stack_default) && - (guardsize == _thr_guard_default)) { - if ((spare_stack = LIST_FIRST(&dstackq)) != NULL) { - /* Use the spare stack. */ - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - } - } - /* - * The user specified a non-default stack and/or guard size, so try to - * allocate a stack from the non-default size stack cache, using the - * rounded up stack size (stack_size) in the search: - */ - else { - LIST_FOREACH(spare_stack, &mstackq, qe) { - if (spare_stack->stacksize == stacksize && - spare_stack->guardsize == guardsize) { - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - break; - } - } - } - if (attr->stackaddr_attr != NULL) { - /* A cached stack was found. Release the lock. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } - else { - /* Allocate a stack from usrstack. */ - if (last_stack == NULL) - last_stack = (void *)((uintptr_t)_usrstack - - (uintptr_t)_thr_stack_initial - - (uintptr_t)_thr_guard_default); - - /* Allocate a new stack. */ - stackaddr = (void *)((uintptr_t)last_stack - - (uintptr_t)stacksize - (uintptr_t)guardsize); - - /* - * Even if stack allocation fails, we don't want to try to - * use this location again, so unconditionally decrement - * last_stack. Under normal operating conditions, the most - * likely reason for an mmap() error is a stack overflow of - * the adjacent thread stack. - */ - last_stack = (void *)((uintptr_t)last_stack - - (uintptr_t)(stacksize + guardsize)); - - /* Release the lock before mmap'ing it. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Map the stack and guard page together, and split guard - page from allocated space: */ - if ((stackaddr = mmap(stackaddr, stacksize+guardsize, - PROT_READ | PROT_WRITE, MAP_STACK, - -1, 0)) != MAP_FAILED && - (guardsize == 0 || - mprotect(stackaddr, guardsize, PROT_NONE) == 0)) { - stackaddr += guardsize; - } else { - if (stackaddr != MAP_FAILED) - munmap(stackaddr, stacksize + guardsize); - stackaddr = NULL; - } - attr->stackaddr_attr = stackaddr; - } - if (attr->stackaddr_attr != NULL) - return (0); - else - return (-1); -} - -/* This function must be called with _thread_list_lock held. */ -void -_thr_stack_free(struct pthread_attr *attr) -{ - struct stack *spare_stack; - - if ((attr != NULL) && ((attr->flags & THR_STACK_USER) == 0) - && (attr->stackaddr_attr != NULL)) { - spare_stack = (struct stack *)((uintptr_t)attr->stackaddr_attr - + (uintptr_t)attr->stacksize_attr - sizeof(struct stack)); - spare_stack->stacksize = round_up(attr->stacksize_attr); - spare_stack->guardsize = round_up(attr->guardsize_attr); - spare_stack->stackaddr = attr->stackaddr_attr; - - if (spare_stack->stacksize == _thr_stack_default && - spare_stack->guardsize == _thr_guard_default) { - /* Default stack/guard size. */ - LIST_INSERT_HEAD(&dstackq, spare_stack, qe); - } else { - /* Non-default stack/guard size. */ - LIST_INSERT_HEAD(&mstackq, spare_stack, qe); - } - attr->stackaddr_attr = NULL; - } -} diff --git a/lib/libkse/thread/thr_suspend_np.c b/lib/libkse/thread/thr_suspend_np.c deleted file mode 100644 index 99af59c..0000000 --- a/lib/libkse/thread/thr_suspend_np.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _pthread_suspend_np(pthread_t thread); -void _pthread_suspend_all_np(void); - -static void suspend_common(struct pthread *thread); - -__weak_reference(_pthread_suspend_np, pthread_suspend_np); -__weak_reference(_pthread_suspend_all_np, pthread_suspend_all_np); - -/* Suspend a thread: */ -int -_pthread_suspend_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Suspending the current thread doesn't make sense. */ - if (thread == _get_curthread()) - ret = EDEADLK; - - /* Add a reference to the thread: */ - else if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) - == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, thread); - - /* Don't forget to remove the reference: */ - _thr_ref_delete(curthread, thread); - } - return (ret); -} - -void -_pthread_suspend_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -suspend_common(struct pthread *thread) -{ - if ((thread->state != PS_DEAD) && - (thread->state != PS_DEADLOCK) && - ((thread->flags & THR_FLAGS_EXITING) == 0)) { - thread->flags |= THR_FLAGS_SUSPENDED; - if ((thread->flags & THR_FLAGS_IN_RUNQ) != 0) { - THR_RUNQ_REMOVE(thread); - THR_SET_STATE(thread, PS_SUSPENDED); - } -#ifdef NOT_YET - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) - /* ??? */ -#endif - } -} diff --git a/lib/libkse/thread/thr_switch_np.c b/lib/libkse/thread/thr_switch_np.c deleted file mode 100644 index 058a3bb..0000000 --- a/lib/libkse/thread/thr_switch_np.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. - * 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 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$ - */ - -#include "namespace.h" -#include <errno.h> -#include <pthread.h> -#include <pthread_np.h> -#include "un-namespace.h" -#include "thr_private.h" - -__weak_reference(_pthread_switch_add_np, pthread_switch_add_np); -__weak_reference(_pthread_switch_delete_np, pthread_switch_delete_np); - -int -_pthread_switch_add_np(pthread_switch_routine_t routine __unused) -{ - return (ENOTSUP); -} - -int -_pthread_switch_delete_np(pthread_switch_routine_t routine __unused) -{ - return (ENOTSUP); -} diff --git a/lib/libkse/thread/thr_symbols.c b/lib/libkse/thread/thr_symbols.c deleted file mode 100644 index f48cc0f..0000000 --- a/lib/libkse/thread/thr_symbols.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004 David Xu <davidxu@freebsd.org> - * 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. 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 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <stddef.h> -#include <pthread.h> -#include <rtld.h> -#include "un-namespace.h" - -#include "thr_private.h" - -/* A collection of symbols needed by debugger */ - -/* int _libkse_debug */ -int _thread_off_tcb = offsetof(struct pthread, tcb); -int _thread_off_tmbx = offsetof(struct tcb, tcb_tmbx); -int _thread_off_next = offsetof(struct pthread, tle.tqe_next); -int _thread_off_attr_flags = offsetof(struct pthread, attr.flags); -int _thread_off_kse = offsetof(struct pthread, kse); -int _thread_off_kse_locklevel = offsetof(struct kse, k_locklevel); -int _thread_off_thr_locklevel = offsetof(struct pthread, locklevel); -int _thread_off_linkmap = offsetof(Obj_Entry, linkmap); -int _thread_off_tlsindex = offsetof(Obj_Entry, tlsindex); -int _thread_size_key = sizeof(struct pthread_key); -int _thread_off_key_allocated = offsetof(struct pthread_key, allocated); -int _thread_off_key_destructor = offsetof(struct pthread_key, destructor); -int _thread_max_keys = PTHREAD_KEYS_MAX; -int _thread_off_dtv = DTV_OFFSET; -int _thread_off_state = offsetof(struct pthread, state); -int _thread_state_running = PS_RUNNING; -int _thread_state_zoombie = PS_DEAD; -int _thread_off_sigmask = offsetof(struct pthread, sigmask); -int _thread_off_sigpend = offsetof(struct pthread, sigpend); diff --git a/lib/libkse/thread/thr_system.c b/lib/libkse/thread/thr_system.c deleted file mode 100644 index 5dbe426..0000000 --- a/lib/libkse/thread/thr_system.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <stdlib.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _system(const char *string); - -extern int __system(const char *); - -__weak_reference(_system, system); - -int -_system(const char *string) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __system(string); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_tcdrain.c b/lib/libkse/thread/thr_tcdrain.c deleted file mode 100644 index 55a403d..0000000 --- a/lib/libkse/thread/thr_tcdrain.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include "namespace.h" -#include <termios.h> -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -int _tcdrain(int fd); -extern int __tcdrain(int); - -__weak_reference(_tcdrain, tcdrain); - -int -_tcdrain(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __tcdrain(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_vfork.c b/lib/libkse/thread/thr_vfork.c deleted file mode 100644 index 4b22b1e..0000000 --- a/lib/libkse/thread/thr_vfork.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * $FreeBSD$ - */ - -#include <unistd.h> -#include "thr_private.h" - -int _vfork(void); - -__weak_reference(_vfork, vfork); - -int -_vfork(void) -{ - return (fork()); -} diff --git a/lib/libkse/thread/thr_wait.c b/lib/libkse/thread/thr_wait.c deleted file mode 100644 index e3f40bc..0000000 --- a/lib/libkse/thread/thr_wait.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include <pthread.h> -#include "thr_private.h" - -extern int __wait(int *); - -pid_t _wait(int *istat); - -__weak_reference(_wait, wait); - -pid_t -_wait(int *istat) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __wait(istat); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_wait4.c b/lib/libkse/thread/thr_wait4.c deleted file mode 100644 index d92366a..0000000 --- a/lib/libkse/thread/thr_wait4.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - */ - -#include "namespace.h" -#include <sys/types.h> -#include <errno.h> -#include <sys/wait.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -pid_t __wait4(pid_t pid, int *istat, int options, struct rusage *rusage); - -__weak_reference(__wait4, wait4); - -pid_t -__wait4(pid_t pid, int *istat, int options, struct rusage *rusage) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = _wait4(pid, istat, options, rusage); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_waitpid.c b/lib/libkse/thread/thr_waitpid.c deleted file mode 100644 index 1f2d4a7..0000000 --- a/lib/libkse/thread/thr_waitpid.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. - * 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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$ - */ - -#include <sys/types.h> -#include <sys/wait.h> -#include <pthread.h> -#include "thr_private.h" - -extern int __waitpid(pid_t, int *, int); - -pid_t _waitpid(pid_t wpid, int *status, int options); - -__weak_reference(_waitpid, waitpid); - -pid_t -_waitpid(pid_t wpid, int *status, int options) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __waitpid(wpid, status, options); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libkse/thread/thr_write.c b/lib/libkse/thread/thr_write.c deleted file mode 100644 index 1bb3bc0..0000000 --- a/lib/libkse/thread/thr_write.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - * - */ -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -__ssize_t __write(int fd, const void *buf, size_t nbytes); - -__weak_reference(__write, write); - -ssize_t -__write(int fd, const void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_write(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_writev.c b/lib/libkse/thread/thr_writev.c deleted file mode 100644 index f3f2aaf..0000000 --- a/lib/libkse/thread/thr_writev.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1995-1998 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. 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 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$ - * - */ -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -ssize_t __writev(int fd, const struct iovec *iov, int iovcnt); - -__weak_reference(__writev, writev); - -ssize_t -__writev(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_writev(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libkse/thread/thr_yield.c b/lib/libkse/thread/thr_yield.c deleted file mode 100644 index 7094609..0000000 --- a/lib/libkse/thread/thr_yield.c +++ /dev/null @@ -1,72 +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. 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 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$ - */ -#include <pthread.h> -#include "thr_private.h" - -int _sched_yield(void); - -__weak_reference(_sched_yield, sched_yield); -__weak_reference(_pthread_yield, pthread_yield); - -int -_sched_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sched_yield()); - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - /* Always return no error. */ - return(0); -} - -/* Draft 4 yield */ -void -_pthread_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sched_yield(); - return; - } - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); -} |