diff options
Diffstat (limited to 'mit-pthreads/pthreads')
43 files changed, 0 insertions, 10973 deletions
diff --git a/mit-pthreads/pthreads/GNUmakefile.inc b/mit-pthreads/pthreads/GNUmakefile.inc deleted file mode 100644 index b3019364a1d..00000000000 --- a/mit-pthreads/pthreads/GNUmakefile.inc +++ /dev/null @@ -1,46 +0,0 @@ -# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 - -# pthread sources -VPATH := $(VPATH):${srcdir}/pthreads - -SRCS:= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c fd_sysv.c file.c globals.c \ - malloc.c mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c \ - syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \ - specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \ - pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \ - dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \ - pthread_cancel.c panic.c semaphore.c $(SRCS) - -ifeq ($(HAVE_SYSCALL_TEMPLATE),yes) -SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \ - case " $(SYSCALL_EXCEPTIONS) " in \ - *" "$$s" "*) ;; \ - *) echo $$s ;; \ - esac ; \ - done -STD_SYSCALLS:=$(shell $(SYSCALL_FILTER_RULE)) -STD_SYSCALL_FILES:= $(addprefix S,$(addsuffix .o,$(STD_SYSCALLS))) -EXTRA_OBJS := $(EXTRA_OBJS) syscalls.o -# EXTRA_OBJS := $(EXTRA_OBJS) $(STD_SYSCALL_FILES) - -ifndef SYSCALL_PIC_COMPILE -SYSCALL_PIC_COMPILE=true -endif - -obj/syscalls.o: syscall-template.S - -rm -rf obj/syscalls - mkdir obj/syscalls - for syscall in $(STD_SYSCALLS) ; do \ - echo $$syscall ; \ - $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c syscall-template.S -o obj/syscalls/S$$syscall.o ; \ - $(SYSCALL_PIC_COMPILE) ; \ - done - x=`pwd` && cd obj/syscalls && ld -r -o ../syscalls.o S*.o && cd $$x - rm -r obj/syscalls -endif - -syscall.o: ${.CURDIR}/pthreads/syscall.S - cpp ${CPPFLAGS} ${.CURDIR}/pthreads/syscall.S > syscall.i - as syscall.i - rm syscall.i - mv a.out syscall.o diff --git a/mit-pthreads/pthreads/Makefile.inc b/mit-pthreads/pthreads/Makefile.inc deleted file mode 100644 index 68d970f17d8..00000000000 --- a/mit-pthreads/pthreads/Makefile.inc +++ /dev/null @@ -1,76 +0,0 @@ -# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 - -# pthread sources -.PATH: ${srcdir}/pthreads - -SRCS+= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c file.c globals.c malloc.c \ - mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c syscall.S \ - pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \ - process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \ - pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \ - dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c \ - semaphore.c - -.if $(HAVE_SYSCALL_TEMPLATE) == yes -OBJS+= syscalls.o -.if !defined(NOPIC) -SOBJS+= syscalls.so -SYSCALL_PIC_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -DPIC -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.so -.else -SYSCALL_PIC_COMPILE= true -.endif -.if !defined(NOPROFILE) -POBJS+= syscalls.po -SYSCALL_PROF_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -pg -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.po -.else -SYSCALL_PROF_COMPILE= true -.endif - -OPSYS!= uname -s - -syscalls.o syscalls.so syscalls.po : syscall-template.S - -rm -rf ${.OBJDIR}/syscalls - mkdir ${.OBJDIR}/syscalls - for syscall in $(AVAILABLE_SYSCALLS) ; do \ - case " $(SYSCALL_EXCEPTIONS) " in \ - *" "$$syscall" "*) ;; \ - *) echo $$syscall ; \ - $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.o ; \ - $(SYSCALL_PIC_COMPILE) ; \ - $(SYSCALL_PROF_COMPILE) ;; \ - esac ; \ - done - x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.o *.o && cd $$x -.if !defined(NOPIC) - x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.so *.so && cd $$x -.endif -.if !defined(NOPROFILE) - x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.po *.po && cd $$x -.endif - rm -r ${.OBJDIR}/syscalls -.endif - -syscall.o: syscall.S -.if (${OPSYS} == "FreeBSD") - $(CC) -c -x assembler-with-cpp -o syscall.o ${.CURDIR}/syscall.S -.else - cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i - as syscall.i - rm syscall.i - mv a.out syscall.o -.endif - -syscall.po: syscall.S -.if (${OPSYS} == "FreeBSD") - $(CC) -c -x assembler-with-cpp -o syscall.po ${.CURDIR}/syscall.S -.else - cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i - as syscall.i - rm syscall.i - mv a.out syscall.po -.endif - -MAN2+= - -MAN3+= - diff --git a/mit-pthreads/pthreads/_exit.c b/mit-pthreads/pthreads/_exit.c deleted file mode 100644 index fde795011ce..00000000000 --- a/mit-pthreads/pthreads/_exit.c +++ /dev/null @@ -1,80 +0,0 @@ -/* ==== _exit.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : The locking functions for stdio. - * - * 1.00 94/09/04 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <fcntl.h> - -/* ========================================================================== - * _exit() - * - * Change all file descriptors back to their original state, - * before exiting for good. - */ -void _exit(int status) -{ - int fd; - - pthread_sched_prevent(); - - for (fd = 0; fd < dtablesize; fd++) { - if (fd_table[fd] == NULL) { - continue; - } - /* Is it a kernel fd ? */ - if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) { - continue; - } - switch (fd_table[fd]->type) { - case FD_HALF_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags); - fd_table[fd]->type = FD_TEST_HALF_DUPLEX; - break; - case FD_FULL_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags); - fd_table[fd]->type = FD_TEST_FULL_DUPLEX; - break; - default: - break; - } - } - machdep_sys_exit(status); -} - diff --git a/mit-pthreads/pthreads/cleanup.c b/mit-pthreads/pthreads/cleanup.c deleted file mode 100644 index 3eb096b8337..00000000000 --- a/mit-pthreads/pthreads/cleanup.c +++ /dev/null @@ -1,84 +0,0 @@ -/* ==== cleanup.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread attribute functions. - * - * 1.20 94/02/13 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> -#include <stdlib.h> - -/* ========================================================================== - * pthread_cleanup_push() - */ -int pthread_cleanup_push(void (*routine)(void *), void *routine_arg) -{ - struct pthread_cleanup *new; - int ret; - - if ((new = (struct pthread_cleanup*)malloc(sizeof(struct pthread_cleanup)))) - { - new->routine = routine; - new->routine_arg = routine_arg; - new->next = pthread_run->cleanup; - - pthread_run->cleanup = new; - ret = OK; - } else { - ret = ENOMEM; - } - return(ret); -} - -/* ========================================================================== - * pthread_cleanup_pop() - */ -void pthread_cleanup_pop(int execute) -{ - struct pthread_cleanup *old; - - if ((old = pthread_run->cleanup)) - { - pthread_run->cleanup = old->next; - if (execute) { - old->routine(old->routine_arg); - } - free(old); - } -} - diff --git a/mit-pthreads/pthreads/cond.c b/mit-pthreads/pthreads/cond.c deleted file mode 100644 index 8dacd0397ce..00000000000 --- a/mit-pthreads/pthreads/cond.c +++ /dev/null @@ -1,437 +0,0 @@ -/* ==== cond.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Condition variable functions. - * - * 1.00 93/10/28 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <sys/time.h> -#include <stdlib.h> -#include <timers.h> -#include <errno.h> - -#ifndef ETIME -#define ETIME ETIMEDOUT -#endif - -/* ========================================================================== - * pthread_cond_is_debug() - * - * Check that cond is a debug cond and if so returns entry number into - * array of debug condes. - */ -static int pthread_cond_debug_count = 0; -static pthread_cond_t ** pthread_cond_debug_ptrs = NULL; -static pthread_mutex_t pthread_cond_debug_mutex = PTHREAD_MUTEX_INITIALIZER; - -static inline int pthread_cond_is_debug(pthread_cond_t * cond) -{ - int i; - - for (i = 0; i < pthread_cond_debug_count; i++) { - if (pthread_cond_debug_ptrs[i] == cond) { - return(i); - } - } - return(NOTOK); -} -/* ========================================================================== - * pthread_cond_init() - * - * In this implementation I don't need to allocate memory. - * ENOMEM, EAGAIN should never be returned. Arch that have - * weird constraints may need special coding. - */ -int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) -{ - enum pthread_condtype type; - - /* Only check if attr specifies some mutex type other than fast */ - if ((cond_attr) && (cond_attr->c_type != COND_TYPE_FAST)) { - if (cond_attr->c_type >= COND_TYPE_MAX) { - return(EINVAL); - } - type = cond_attr->c_type; - } else { - type = COND_TYPE_FAST; - } - - switch (type) { - case COND_TYPE_FAST: - case COND_TYPE_COUNTING_FAST: - break; - case COND_TYPE_DEBUG: - pthread_mutex_lock(&pthread_cond_debug_mutex); - if (pthread_cond_is_debug(cond) == NOTOK) { - pthread_cond_t ** new; - - if ((new = (pthread_cond_t **)realloc(pthread_cond_debug_ptrs, - (pthread_cond_debug_count + 1) * (sizeof(void *)))) == NULL) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - return(ENOMEM); - } - pthread_cond_debug_ptrs = new; - pthread_cond_debug_ptrs[pthread_cond_debug_count++] = cond; - } else { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - return(EBUSY); - } - pthread_mutex_unlock(&pthread_cond_debug_mutex); - break; - case COND_TYPE_STATIC_FAST: - defualt: - return(EINVAL); - break; - } - - /* Set all other paramaters */ - pthread_queue_init(&cond->c_queue); - cond->c_flags |= COND_FLAGS_INITED; - cond->c_type = type; - return(OK); -} - -/* ========================================================================== - * pthread_cond_destroy() - */ -int pthread_cond_destroy(pthread_cond_t *cond) -{ - int i; - - /* Only check if cond is of type other than fast */ - switch(cond->c_type) { - case COND_TYPE_FAST: - case COND_TYPE_COUNTING_FAST: - break; - case COND_TYPE_DEBUG: - if (pthread_queue_get(&(cond->c_queue))) { - return(EBUSY); - } - pthread_mutex_lock(&pthread_cond_debug_mutex); - if ((i = pthread_cond_is_debug(cond)) == NOTOK) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - return(EINVAL); - } - - /* Remove the cond from the list of debug condition variables */ - pthread_cond_debug_ptrs[i] = - pthread_cond_debug_ptrs[--pthread_cond_debug_count]; - pthread_cond_debug_ptrs[pthread_cond_debug_count] = NULL; - pthread_mutex_unlock(&pthread_cond_debug_mutex); - break; - case COND_TYPE_STATIC_FAST: - default: - return(EINVAL); - break; - } - - /* Cleanup cond, others might want to use it. */ - pthread_queue_init(&cond->c_queue); - cond->c_flags = 0; - return(OK); -} - -/* ========================================================================== - * pthread_cond_wait() - */ -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - int rval; - - pthread_sched_prevent(); - switch (cond->c_type) { - case COND_TYPE_DEBUG: - pthread_mutex_lock(&pthread_cond_debug_mutex); - if (pthread_cond_is_debug(cond) == NOTOK) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - pthread_sched_resume(); - return(EINVAL); - } - pthread_mutex_unlock(&pthread_cond_debug_mutex); - - /* - * Fast condition variables do not check for any error conditions. - */ - case COND_TYPE_FAST: - case COND_TYPE_STATIC_FAST: - pthread_queue_enq(&cond->c_queue, pthread_run); - pthread_mutex_unlock(mutex); - - pthread_run->data.mutex = mutex; - - SET_PF_WAIT_EVENT(pthread_run); - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - /* Reschedule will unlock pthread_run */ - pthread_resched_resume(PS_COND_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - CLEAR_PF_DONE_EVENT(pthread_run); - - pthread_run->data.mutex = NULL; - - rval = pthread_mutex_lock(mutex); - return(rval); - break; - case COND_TYPE_COUNTING_FAST: - { - int count = mutex->m_data.m_count; - - pthread_queue_enq(&cond->c_queue, pthread_run); - pthread_mutex_unlock(mutex); - mutex->m_data.m_count = 1; - - pthread_run->data.mutex = mutex; - - SET_PF_WAIT_EVENT(pthread_run); - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - /* Reschedule will unlock pthread_run */ - pthread_resched_resume(PS_COND_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - CLEAR_PF_DONE_EVENT(pthread_run); - - pthread_run->data.mutex = NULL; - - rval = pthread_mutex_lock(mutex); - mutex->m_data.m_count = count; - return(rval); - break; - } - default: - rval = EINVAL; - break; - } - pthread_sched_resume(); - return(rval); -} - -/* ========================================================================== - * pthread_cond_timedwait() - */ -int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec * abstime) -{ - struct timespec current_time, new_time; - int rval = OK; - - pthread_sched_prevent(); - machdep_gettimeofday(& current_time); - - switch (cond->c_type) { - case COND_TYPE_DEBUG: - pthread_mutex_lock(&pthread_cond_debug_mutex); - if (pthread_cond_is_debug(cond) == NOTOK) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - pthread_sched_resume(); - return(EINVAL); - } - pthread_mutex_unlock(&pthread_cond_debug_mutex); - - /* - * Fast condition variables do not check for any error conditions. - */ - case COND_TYPE_FAST: - case COND_TYPE_STATIC_FAST: - - /* Set pthread wakeup time*/ - pthread_run->wakeup_time = *abstime; - - /* Install us on the sleep queue */ - sleep_schedule (¤t_time, &(pthread_run->wakeup_time)); - - pthread_queue_enq(&cond->c_queue, pthread_run); - SET_PF_WAIT_EVENT(pthread_run); - pthread_mutex_unlock(mutex); - - pthread_run->data.mutex = mutex; - - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - /* Reschedule will unlock pthread_run */ - pthread_resched_resume(PS_COND_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - - pthread_run->data.mutex = NULL; - - /* Remove ourselves from sleep queue. If we fail then we timedout */ - if (sleep_cancel(pthread_run) == NOTOK) { - SET_ERRNO(ETIME); - rval = ETIME; - } - - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_mutex_lock(mutex); - return(rval); - break; - case COND_TYPE_COUNTING_FAST: - { - int count = mutex->m_data.m_count; - - /* Set pthread wakeup time*/ - pthread_run->wakeup_time = *abstime; - - /* Install us on the sleep queue */ - sleep_schedule (¤t_time, &(pthread_run->wakeup_time)); - - pthread_queue_enq(&cond->c_queue, pthread_run); - SET_PF_WAIT_EVENT(pthread_run); - pthread_mutex_unlock(mutex); - - pthread_run->data.mutex = mutex; - - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - /* Reschedule will unlock pthread_run */ - pthread_resched_resume(PS_COND_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - - pthread_run->data.mutex = NULL; - - /* Remove ourselves from sleep queue. If we fail then we timedout */ - if (sleep_cancel(pthread_run) == NOTOK) { - SET_ERRNO(ETIME); - rval = ETIME; - } - - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_mutex_lock(mutex); - mutex->m_data.m_count = count; - return(rval); - break; - } - default: - rval = EINVAL; - break; - } - pthread_sched_resume(); - return(rval); -} - -/* ========================================================================== - * pthread_cond_signal() - */ -int pthread_cond_signal(pthread_cond_t *cond) -{ - struct pthread *pthread; - int rval; - - pthread_sched_prevent(); - switch (cond->c_type) { - case COND_TYPE_DEBUG: - pthread_mutex_lock(&pthread_cond_debug_mutex); - if (pthread_cond_is_debug(cond) == NOTOK) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - pthread_sched_resume(); - return(EINVAL); - } - pthread_mutex_unlock(&pthread_cond_debug_mutex); - - case COND_TYPE_FAST: - case COND_TYPE_STATIC_FAST: - if (pthread = pthread_queue_deq(&cond->c_queue)) { - if ((SET_PF_DONE_EVENT(pthread)) == OK) { - pthread_sched_other_resume(pthread); - } else { - pthread_sched_resume(); - } - return(OK); - } - rval = OK; - break; - default: - rval = EINVAL; - break; - } - pthread_sched_resume(); - return(rval); -} - -/* ========================================================================== - * pthread_cond_broadcast() - * - * Not much different then the above routine. - */ -int pthread_cond_broadcast(pthread_cond_t *cond) -{ - struct pthread * pthread, * high_pthread, * low_pthread; - int rval; - - pthread_sched_prevent(); - switch (cond->c_type) { - case COND_TYPE_DEBUG: - pthread_mutex_lock(&pthread_cond_debug_mutex); - if (pthread_cond_is_debug(cond) == NOTOK) { - pthread_mutex_unlock(&pthread_cond_debug_mutex); - pthread_sched_resume(); - return(EINVAL); - } - pthread_mutex_unlock(&pthread_cond_debug_mutex); - - case COND_TYPE_FAST: - case COND_TYPE_STATIC_FAST: - if (pthread = pthread_queue_deq(&cond->c_queue)) { - pthread->state = PS_RUNNING; - high_pthread = pthread; - - while (pthread = pthread_queue_deq(&cond->c_queue)) { - if (pthread->pthread_priority > - high_pthread->pthread_priority) { - low_pthread = high_pthread; - high_pthread = pthread; - } else { - low_pthread = pthread; - } - if ((SET_PF_DONE_EVENT(low_pthread)) == OK) { - pthread_prio_queue_enq(pthread_current_prio_queue, - low_pthread); - low_pthread->state = PS_RUNNING; - } - } - if ((SET_PF_DONE_EVENT(high_pthread)) == OK) { - pthread_sched_other_resume(high_pthread); - } else { - pthread_sched_resume(); - } - return(OK); - } - rval = OK; - break; - default: - rval = EINVAL; - break; - } - pthread_sched_resume(); - return(rval); -} - diff --git a/mit-pthreads/pthreads/condattr.c b/mit-pthreads/pthreads/condattr.c deleted file mode 100644 index ac010bdf4b1..00000000000 --- a/mit-pthreads/pthreads/condattr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ==== condattr.c =========================================================== - * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Mutex functions. - * - * 1.00 95/08/22 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> - -/* ========================================================================== - * pthread_condattr_init() - */ -int pthread_condattr_init(pthread_condattr_t *attr) -{ - attr->c_type = COND_TYPE_FAST; - return(OK); -} - -/* ========================================================================== - * pthread_condattr_destroy() - */ -int pthread_condattr_destroy(pthread_condattr_t *attr) -{ - return(OK); -} - -/* ========================================================================== - * pthread_condattr_settype() - */ -int pthread_condattr_settype(pthread_condattr_t *attr, unsigned int type) -{ - switch(type) { - case PTHREAD_CONDTYPE_FAST: - attr->c_type = COND_TYPE_FAST; - break; - case PTHREAD_CONDTYPE_RECURSIVE: - attr->c_type = COND_TYPE_COUNTING_FAST; - break; - case PTHREAD_CONDTYPE_DEBUG: - attr->c_type = COND_TYPE_DEBUG; - break; - default: - return(EINVAL); - } - return(OK); -} - -/* ========================================================================== - * pthread_condattr_gettype() - */ -int pthread_condattr_gettype(pthread_condattr_t *attr, unsigned int * type) -{ - *type = (unsigned int)attr->c_type; - return(OK); -} diff --git a/mit-pthreads/pthreads/dump_state.c b/mit-pthreads/pthreads/dump_state.c deleted file mode 100644 index 3d9840bad64..00000000000 --- a/mit-pthreads/pthreads/dump_state.c +++ /dev/null @@ -1,88 +0,0 @@ -/* ==== dump_state.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * $Id$ - * - * Description : Bogus debugging output routines. - * - * 1.00 95/02/08 snl - * -Started coding this file. - */ - -#include <pthread.h> -#include <stdio.h> - -/* ========================================================================== - * pthread_dump_state() - * - * Totally, totally bogus routine to dump the state of pthreads. - */ - -void -pthread_dump_state() -{ - pthread_t thread; - - for (thread = pthread_link_list; thread; thread = thread->pll) { - printf("Thread %lx", thread); - if (thread == pthread_initial) - printf("*"); - if (thread == pthread_run) - printf("^"); - printf(" "); - switch (thread->state) { - case PS_RUNNING: printf("RUNNING "); break; - case PS_MUTEX_WAIT: printf("MUTEX_WAIT "); break; - case PS_COND_WAIT: printf("COND_WAIT "); break; - case PS_FDLR_WAIT: printf("FDLR_WAIT "); break; - case PS_FDLW_WAIT: printf("FDLW_WAIT "); break; - case PS_FDR_WAIT: printf("FDR_WAIT "); break; - case PS_FDW_WAIT: printf("FDW_WAIT "); break; - case PS_SELECT_WAIT: printf("SELECT "); break; - case PS_SLEEP_WAIT: printf("SLEEP_WAIT "); break; - case PS_WAIT_WAIT: printf("WAIT_WAIT "); break; - case PS_SIGWAIT: printf("SIGWAIT "); break; - case PS_JOIN: printf("JOIN "); break; - case PS_DEAD: printf("DEAD "); break; - default: printf("*UNKNOWN %d* ", thread->state); - break; - } - switch (thread->attr.schedparam_policy) { - case SCHED_RR: printf("RR "); break; - case SCHED_IO: printf("IO "); break; - case SCHED_FIFO: printf("FIFO "); break; - case SCHED_OTHER: printf("OTHER "); break; - default: printf("*UNKNOWN %d* ", - thread->attr.schedparam_policy); - break; - } - } -} diff --git a/mit-pthreads/pthreads/errno.c b/mit-pthreads/pthreads/errno.c deleted file mode 100644 index bc680235424..00000000000 --- a/mit-pthreads/pthreads/errno.c +++ /dev/null @@ -1,53 +0,0 @@ -/* ==== errno.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Return the pointer to the threads errno address. - * - * 1.32 94/05/25 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* ========================================================================== - * __error() - */ -int * __error() -{ - if (!pthread_run->error_p) { - pthread_run->error_p = &pthread_run->error; - } - return(pthread_run->error_p); -} diff --git a/mit-pthreads/pthreads/fd.c b/mit-pthreads/pthreads/fd.c deleted file mode 100644 index 3eb59c11bd1..00000000000 --- a/mit-pthreads/pthreads/fd.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* ==== fd.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : All the syscalls dealing with fds. - * - * 1.00 93/08/14 proven - * -Started coding this file. - * - * 1.01 93/11/13 proven - * -The functions readv() and writev() added. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include "config.h" -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <sys/ioctl.h> -#ifdef HAVE_SYS_FILIO_H -#include <sys/filio.h> /* For ioctl */ -#endif -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include <fcntl.h> -#include <errno.h> -#include <pthread/posix.h> - -/* - * These first functions really should not be called by the user. - * - * I really should dynamically figure out what the table size is. - */ -static pthread_mutex_t fd_table_mutex = PTHREAD_MUTEX_INITIALIZER; -static const int dtablecount = 4096/sizeof(struct fd_table_entry); -int dtablesize; - -static int fd_get_pthread_fd_from_kernel_fd( int ); - -/* ========================================================================== - * Allocate dtablecount entries at once and populate the fd_table. - * - * fd_init_entry() - */ -int fd_init_entry(int entry) -{ - struct fd_table_entry *fd_entry; - int i, round; - - if (fd_table[entry] == NULL) { - round = entry - entry % dtablecount; - - if ((fd_entry = (struct fd_table_entry *)malloc( - sizeof(struct fd_table_entry) * dtablecount)) == NULL) { - return(NOTOK); - } - - for (i = 0; i < dtablecount && round+i < dtablesize; i++) { - fd_table[round + i] = &fd_entry[i]; - - fd_table[round + i]->ops = NULL; - fd_table[round + i]->type = FD_NT; - fd_table[round + i]->fd.i = NOTOK; - fd_table[round + i]->flags = 0; - fd_table[round + i]->count = 0; - - pthread_mutex_init(&(fd_table[round + i]->mutex), NULL); - pthread_queue_init(&(fd_table[round + i]->r_queue)); - pthread_queue_init(&(fd_table[round + i]->w_queue)); - fd_table[round + i]->r_owner = NULL; - fd_table[round + i]->w_owner = NULL; - fd_table[round + i]->r_lockcount= 0; - fd_table[round + i]->w_lockcount= 0; - - fd_table[round + i]->next = NULL; - } - } - return(OK); -} - -/* ========================================================================== - * fd_check_entry() - */ -int fd_check_entry(unsigned int entry) -{ - int ret = OK; - - pthread_mutex_lock(&fd_table_mutex); - - if (entry < dtablesize) { - if (fd_table[entry] == NULL) { - if (fd_init_entry(entry)) { - SET_ERRNO(EBADF); - ret = -EBADF; - } - } - } else { - SET_ERRNO(EBADF); - ret = -EBADF; - } - - pthread_mutex_unlock(&fd_table_mutex); - return(ret); -} - -/* ========================================================================== - * fd_init() - */ -void fd_init(void) -{ - int i; - - if ((dtablesize = machdep_sys_getdtablesize()) < 0) { - /* Can't figure out the table size. */ - PANIC(); - } - - /* select() can only handle FD_SETSIZE descriptors, so our inner loop will - * break if dtablesize is higher than that. This should be removed if and - * when the inner loop is rewritten to use poll(). */ - if (dtablesize > FD_SETSIZE) { - dtablesize = FD_SETSIZE; - } - - if (fd_table = (struct fd_table_entry **)malloc( - sizeof(struct fd_table_entry) * dtablesize)) { - memset(fd_table, 0, sizeof(struct fd_table_entry) * dtablesize); - if (fd_check_entry(0) == OK) { - return; - } - } - - /* - * There isn't enough memory to allocate a fd table at init time. - * This is a problem. - */ - PANIC(); - -} - -/* ========================================================================== - * fd_allocate() - */ -int fd_allocate() -{ - pthread_mutex_t * mutex; - int i; - - for (i = 0; i < dtablesize; i++) { - if (fd_check_entry(i) == OK) { - mutex = &(fd_table[i]->mutex); - if (pthread_mutex_trylock(mutex)) { - continue; - } - if (fd_table[i]->count || fd_table[i]->r_owner - || fd_table[i]->w_owner) { - pthread_mutex_unlock(mutex); - continue; - } - if (fd_table[i]->type == FD_NT) { - /* Test to see if the kernel version is in use */ - if ((machdep_sys_fcntl(i, F_GETFL, NULL)) >= OK) { - /* If so continue; */ - pthread_mutex_unlock(mutex); - continue; - } - } - fd_table[i]->count++; - pthread_mutex_unlock(mutex); - return(i); - } - } - SET_ERRNO(ENFILE); - return(NOTOK); -} - -/*---------------------------------------------------------------------- - * Function: fd_get_pthread_fd_from_kernel_fd - * Purpose: get the fd_table index of a kernel fd - * Args: fd = kernel fd to convert - * Returns: fd_table index, -1 if not found - * Notes: - *----------------------------------------------------------------------*/ -static int -fd_get_pthread_fd_from_kernel_fd( int kfd ) -{ - int j; - - /* This is *SICK*, but unless there is a faster way to - * turn a kernel fd into an fd_table index, this has to do. - */ - for( j=0; j < dtablesize; j++ ) { - if( fd_table[j] && - fd_table[j]->type != FD_NT && - fd_table[j]->type != FD_NIU && - fd_table[j]->fd.i == kfd ) { - return j; - } - } - - /* Not listed byfd, Check for kernel fd == pthread fd */ - if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) { - /* Assume that the kernel fd is the same */ - return kfd; - } - - return NOTOK; /* Not found */ -} - -/* ========================================================================== - * fd_basic_basic_unlock() - * - * The real work of unlock without the locking of fd_table[fd].lock. - */ -void fd_basic_basic_unlock(struct fd_table_entry * entry, int lock_type) -{ - struct pthread *pthread; - - if (entry->r_owner == pthread_run) { - if ((entry->type == FD_HALF_DUPLEX) || - (entry->type == FD_TEST_HALF_DUPLEX) || - (lock_type == FD_READ) || (lock_type == FD_RDWR)) { - if (entry->r_lockcount == 0) { - if (pthread = pthread_queue_deq(&entry->r_queue)) { - pthread_sched_prevent(); - entry->r_owner = pthread; - if ((SET_PF_DONE_EVENT(pthread)) == OK) { - pthread_sched_other_resume(pthread); - } else { - pthread_sched_resume(); - } - } else { - entry->r_owner = NULL; - } - } else { - entry->r_lockcount--; - } - } - } - - if (entry->w_owner == pthread_run) { - if ((entry->type != FD_HALF_DUPLEX) && - (entry->type != FD_TEST_HALF_DUPLEX) && - ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) { - if (entry->w_lockcount == 0) { - if (pthread = pthread_queue_deq(&entry->w_queue)) { - pthread_sched_prevent(); - entry->w_owner = pthread; - if ((SET_PF_DONE_EVENT(pthread)) == OK) { - pthread_sched_other_resume(pthread); - } else { - pthread_sched_resume(); - } - } else { - entry->w_owner = NULL; - } - } else { - entry->w_lockcount--; - } - } - } -} - -/* ========================================================================== - * fd_basic_unlock() - */ -void fd_basic_unlock(int fd, int lock_type) -{ - fd_basic_basic_unlock(fd_table[fd], lock_type); -} - -/* ========================================================================== - * fd_unlock() - */ -void fd_unlock(int fd, int lock_type) -{ - pthread_mutex_t *mutex; - - mutex = &(fd_table[fd]->mutex); - pthread_mutex_lock(mutex); - fd_basic_basic_unlock(fd_table[fd], lock_type); - pthread_mutex_unlock(mutex); -} - -/* ========================================================================== - * fd_basic_lock() - * - * The real work of lock without the locking of fd_table[fd].lock. - * Be sure to leave the lock the same way you found it. i.e. locked. - */ -int fd_basic_lock(unsigned int fd, int lock_type, pthread_mutex_t * mutex, - struct timespec * timeout) -{ - semaphore *plock; - - switch (fd_table[fd]->type) { - case FD_NIU: - /* If not in use return EBADF error */ - SET_ERRNO(EBADF); - return(NOTOK); - break; - case FD_NT: - /* - * If not tested, test it and see if it is valid - * If not ok return EBADF error - */ - fd_kern_init(fd); - if (fd_table[fd]->type == FD_NIU) { - SET_ERRNO(EBADF); - return(NOTOK); - } - break; - case FD_TEST_HALF_DUPLEX: - case FD_TEST_FULL_DUPLEX: - /* If a parent process reset the fd to its proper state */ - if (!fork_lock) { - /* It had better be a kernel fd */ - fd_kern_reset(fd); - } - break; - default: - break; - } - - if ((fd_table[fd]->type == FD_HALF_DUPLEX) || - (fd_table[fd]->type == FD_TEST_HALF_DUPLEX) || - (lock_type == FD_READ) || (lock_type == FD_RDWR)) { - if (fd_table[fd]->r_owner) { - if (fd_table[fd]->r_owner != pthread_run) { - pthread_sched_prevent(); - pthread_queue_enq(&fd_table[fd]->r_queue, pthread_run); - SET_PF_WAIT_EVENT(pthread_run); - pthread_mutex_unlock(mutex); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - /* Reschedule will unlock pthread_run */ - pthread_run->data.fd.fd = fd; - pthread_run->data.fd.branch = __LINE__; - pthread_resched_resume(PS_FDLR_WAIT); - pthread_mutex_lock(mutex); - - /* If we're the owner then we have to cancel the sleep */ - if (fd_table[fd]->r_owner != pthread_run) { - CLEAR_PF_DONE_EVENT(pthread_run); - SET_ERRNO(ETIMEDOUT); - return(NOTOK); - } - sleep_cancel(pthread_run); - } else { - /* Reschedule will unlock pthread_run */ - pthread_run->data.fd.fd = fd; - pthread_run->data.fd.branch = __LINE__; - pthread_resched_resume(PS_FDLR_WAIT); - pthread_mutex_lock(mutex); - } - CLEAR_PF_DONE_EVENT(pthread_run); - } else { - fd_table[fd]->r_lockcount++; - } - } - fd_table[fd]->r_owner = pthread_run; - } - if ((fd_table[fd]->type != FD_HALF_DUPLEX) && - (fd_table[fd]->type != FD_TEST_HALF_DUPLEX) && - ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) { - if (fd_table[fd]->w_owner) { - if (fd_table[fd]->w_owner != pthread_run) { - pthread_sched_prevent(); - pthread_queue_enq(&fd_table[fd]->w_queue, pthread_run); - SET_PF_WAIT_EVENT(pthread_run); - pthread_mutex_unlock(mutex); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - /* Reschedule will unlock pthread_run */ - pthread_run->data.fd.fd = fd; - pthread_run->data.fd.branch = __LINE__; - pthread_resched_resume(PS_FDLR_WAIT); - pthread_mutex_lock(mutex); - - /* If we're the owner then we have to cancel the sleep */ - if (fd_table[fd]->w_owner != pthread_run) { - if (lock_type == FD_RDWR) { - /* Unlock current thread */ - fd_basic_unlock(fd, FD_READ); - } - CLEAR_PF_DONE_EVENT(pthread_run); - SET_ERRNO(ETIMEDOUT); - return(NOTOK); - } - sleep_cancel(pthread_run); - } else { - /* Reschedule will unlock pthread_run */ - pthread_run->data.fd.fd = fd; - pthread_run->data.fd.branch = __LINE__; - pthread_resched_resume(PS_FDLR_WAIT); - pthread_mutex_lock(mutex); - } - CLEAR_PF_DONE_EVENT(pthread_run); - } else { - fd_table[fd]->w_lockcount++; - } - } - fd_table[fd]->w_owner = pthread_run; - } - if (!fd_table[fd]->count) { - fd_basic_unlock(fd, lock_type); - return(NOTOK); - } - return(OK); -} - -/*---------------------------------------------------------------------- - * Function: fd_unlock_for_cancel - * Purpose: Unlock all fd locks held prior to being cancelled - * Args: void - * Returns: - * OK or NOTOK - * Notes: - * Assumes the kernel is locked on entry - *----------------------------------------------------------------------*/ -int -fd_unlock_for_cancel( void ) -{ - int i, fd; - struct pthread_select_data *data; - int rdlk, wrlk, lktype; - int found; - - /* What we do depends on the previous state of the thread */ - switch( pthread_run->old_state ) { - case PS_RUNNING: - case PS_JOIN: - case PS_SLEEP_WAIT: - case PS_WAIT_WAIT: - case PS_SIGWAIT: - case PS_FDLR_WAIT: - case PS_FDLW_WAIT: - case PS_DEAD: - case PS_UNALLOCED: - break; /* Nothing to do */ - - case PS_COND_WAIT: - CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP ); - /* Must reaquire the mutex according to the standard */ - if( pthread_run->data.mutex == NULL ) { - PANIC(); - } - pthread_mutex_lock( pthread_run->data.mutex ); - break; - - case PS_FDR_WAIT: - CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP); - /* Free the lock on the fd being used */ - fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd ); - if( fd == NOTOK ) { - PANIC(); /* Can't find fd */ - } - fd_unlock( fd, FD_READ ); - break; - - case PS_FDW_WAIT: /* Waiting on i/o */ - CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP); - /* Free the lock on the fd being used */ - fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd ); - if( fd == NOTOK ) { - PANIC(); /* Can't find fd */ - } - fd_unlock( fd, FD_WRITE ); - break; - - case PS_SELECT_WAIT: - data = pthread_run->data.select_data; - - CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP); - - for( i = 0; i < data->nfds; i++) { - rdlk =(FD_ISSET(i,&data->readfds) - || FD_ISSET(i,&data->exceptfds)); - wrlk = FD_ISSET(i, &data->writefds); - lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE; - - if( ! (rdlk || wrlk) ) - continue; /* No locks, no unlock */ - - if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) { - PANIC(); /* Can't find fd */ - } - - fd_unlock( fd, lktype ); - } - break; - - case PS_MUTEX_WAIT: - PANIC(); /* Should never cancel a mutex wait */ - - default: - PANIC(); /* Unknown thread status */ - } -} - -/* ========================================================================== - * fd_lock() - */ -#define pthread_mutex_lock_timedwait(a, b) pthread_mutex_lock(a) - -int fd_lock(unsigned int fd, int lock_type, struct timespec * timeout) -{ - struct timespec current_time; - pthread_mutex_t *mutex; - int error; - - if ((error = fd_check_entry(fd)) == OK) { - mutex = &(fd_table[fd]->mutex); - if (pthread_mutex_lock_timedwait(mutex, timeout)) { - SET_ERRNO(ETIMEDOUT); - return(-ETIMEDOUT); - } - error = fd_basic_lock(fd, lock_type, mutex, timeout); - pthread_mutex_unlock(mutex); - } - return(error); -} - -/* ========================================================================== - * fd_free() - * - * Assumes fd is locked and owner by pthread_run - * Don't clear the queues, fd_unlock will do that. - */ -struct fd_table_entry * fd_free(int fd) -{ - struct fd_table_entry *fd_valid; - - fd_valid = NULL; - fd_table[fd]->r_lockcount = 0; - fd_table[fd]->w_lockcount = 0; - if (--fd_table[fd]->count) { - fd_valid = fd_table[fd]; - fd_table[fd] = fd_table[fd]->next; - fd_valid->next = fd_table[fd]->next; - /* Don't touch queues of fd_valid */ - } - - fd_table[fd]->type = FD_NIU; - fd_table[fd]->fd.i = NOTOK; - fd_table[fd]->next = NULL; - fd_table[fd]->flags = 0; - fd_table[fd]->count = 0; - return(fd_valid); -} - - -/* ========================================================================== - * ======================================================================= */ - -/* ========================================================================== - * read_timedwait() - */ -ssize_t read_timedwait(int fd, void *buf, size_t nbytes, - struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - ret = fd_table[fd]->ops->read(fd_table[fd]->fd, - fd_table[fd]->flags, buf, nbytes, timeout); - fd_unlock(fd, FD_READ); - } - return(ret); -} - -/* ========================================================================== - * read() - */ -ssize_t read(int fd, void *buf, size_t nbytes) -{ - return(read_timedwait(fd, buf, nbytes, NULL)); -} - -/* ========================================================================== - * readv_timedwait() - */ -int readv_timedwait(int fd, const struct iovec *iov, int iovcnt, - struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - ret = fd_table[fd]->ops->readv(fd_table[fd]->fd, - fd_table[fd]->flags, iov, iovcnt, timeout); - fd_unlock(fd, FD_READ); - } - return(ret); -} - -/* ========================================================================== - * readv() - */ -ssize_t readv(int fd, const struct iovec *iov, int iovcnt) -{ - return(readv_timedwait(fd, iov, iovcnt, NULL)); -} - -/* ========================================================================== - * write() - */ -ssize_t write_timedwait(int fd, const void *buf, size_t nbytes, - struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) - { - ret = fd_table[fd]->ops->write(fd_table[fd]->fd, - fd_table[fd]->flags, buf, nbytes, - timeout); - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * write() - */ -ssize_t write(int fd, const void * buf, size_t nbytes) -{ - return(write_timedwait(fd, buf, nbytes, NULL)); -} - -/* ========================================================================== - * writev_timedwait() - */ -int writev_timedwait(int fd, const struct iovec *iov, int iovcnt, - struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) { - ret = fd_table[fd]->ops->writev(fd_table[fd]->fd, - fd_table[fd]->flags, iov, iovcnt, timeout); - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * writev() - */ -ssize_t writev(int fd, const struct iovec *iov, int iovcnt) -{ - return(writev_timedwait(fd, iov, iovcnt, NULL)); -} - -/* ========================================================================== - * lseek() - */ -off_t lseek(int fd, off_t offset, int whence) -{ - off_t ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - ret = fd_table[fd]->ops->seek(fd_table[fd]->fd, - fd_table[fd]->flags, offset, whence); - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -/* ========================================================================== - * close() - * - * The whole close procedure is a bit odd and needs a bit of a rethink. - * For now close() locks the fd, calls fd_free() which checks to see if - * there are any other fd values poinging to the same real fd. If so - * It breaks the wait queue into two sections those that are waiting on fd - * and those waiting on other fd's. Those that are waiting on fd are connected - * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT - * RELEASED). close() then calls fd_unlock which give the fd to the next queued - * element which determins that the fd is closed and then calls fd_unlock etc... - * - * XXX close() is even uglier now. You may assume that the kernel fd is the - * same as fd if fd_table[fd] == NULL or if fd_table[fd]->type == FD_NT. - * This is true because before any fd_table[fd] is allocated the corresponding - * kernel fd must be checks to see if it's valid. - */ -int close(int fd) -{ - struct fd_table_entry * entry; - pthread_mutex_t *mutex; - union fd_data realfd; - int ret, flags; - - if(fd < 0 || fd >= dtablesize) - { - SET_ERRNO(EBADF); - return -1; - } - /* Need to lock the newfd by hand */ - pthread_mutex_lock(&fd_table_mutex); - if (fd_table[fd]) { - pthread_mutex_unlock(&fd_table_mutex); - mutex = &(fd_table[fd]->mutex); - pthread_mutex_lock(mutex); - - /* - * XXX Gross hack ... because of fork(), any fd closed by the - * parent should not change the fd of the child, unless it owns it. - */ - switch(fd_table[fd]->type) { - case FD_NIU: - pthread_mutex_unlock(mutex); - ret = -EBADF; - break; - case FD_NT: - /* - * If it's not tested then the only valid possibility is it's - * kernel fd. - */ - ret = machdep_sys_close(fd); - fd_table[fd]->type = FD_NIU; - pthread_mutex_unlock(mutex); - break; - case FD_TEST_FULL_DUPLEX: - case FD_TEST_HALF_DUPLEX: - realfd = fd_table[fd]->fd; - flags = fd_table[fd]->flags; - if ((entry = fd_free(fd)) == NULL) { - ret = fd_table[fd]->ops->close(realfd, flags); - } else { - /* There can't be any others waiting for fd. */ - pthread_mutex_unlock(&entry->mutex); - /* Note: entry->mutex = mutex */ - mutex = &(fd_table[fd]->mutex); - } - pthread_mutex_unlock(mutex); - break; - default: - ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL); - if (ret == OK) { - realfd = fd_table[fd]->fd; - flags = fd_table[fd]->flags; - pthread_mutex_unlock(mutex); - if ((entry = fd_free(fd)) == NULL) { - ret = fd_table[fd]->ops->close(realfd, flags); - } else { - fd_basic_basic_unlock(entry, FD_RDWR); - pthread_mutex_unlock(&entry->mutex); - /* Note: entry->mutex = mutex */ - } - fd_unlock(fd, FD_RDWR); - } else { - pthread_mutex_unlock(mutex); - } - break; - } - } else { - /* Don't bother creating a table entry */ - pthread_mutex_unlock(&fd_table_mutex); - ret = machdep_sys_close(fd); - } - if( ret < 0) { - SET_ERRNO(-ret); - ret = -1; - } - return(ret); -} - -/* ========================================================================== - * fd_basic_dup() - * - * - * This is a MAJOR guess!! I don't know if the mutext unlock is valid - * in the BIG picture. But it seems to be needed to avoid deadlocking - * with ourselves when we try to close the duped file descriptor. - */ -static inline void fd_basic_dup(int fd, int newfd) -{ - fd_table[newfd]->next = fd_table[fd]->next; - fd_table[fd]->next = fd_table[newfd]; - fd_table[newfd] = fd_table[fd]; - fd_table[fd]->count++; - pthread_mutex_unlock(&fd_table[newfd]->next->mutex); - -} - -/* ========================================================================== - * dup2() - * - * Note: Always lock the lower number fd first to avoid deadlocks. - * Note: Leave the newfd locked. It will be unlocked at close() time. - * Note: newfd must be locked by hand so it can be closed if it is open, - * or it won't be opened while dup is in progress. - */ -int dup2(fd, newfd) -{ - struct fd_table_entry * entry; - pthread_mutex_t *mutex; - union fd_data realfd; - int ret, flags; - - if ((ret = fd_check_entry(newfd)) != OK) - return ret; - - if (newfd < dtablesize) { - if (fd < newfd) { - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - /* Need to lock the newfd by hand */ - mutex = &(fd_table[newfd]->mutex); - pthread_mutex_lock(mutex); - - /* Is it inuse */ - if (fd_basic_lock(newfd, FD_RDWR, mutex, NULL) == OK) { - realfd = fd_table[newfd]->fd; - flags = fd_table[newfd]->flags; - /* free it and check close status */ - if ((entry = fd_free(newfd)) == NULL) { - entry = fd_table[newfd]; - entry->ops->close(realfd, flags); - if (entry->r_queue.q_next) { - if (fd_table[fd]->next) { - fd_table[fd]->r_queue.q_last->next = - entry->r_queue.q_next; - } else { - fd_table[fd]->r_queue.q_next = - entry->r_queue.q_next; - } - fd_table[fd]->r_queue.q_last = - entry->r_queue.q_last; - } - if (entry->w_queue.q_next) { - if (fd_table[fd]->next) { - fd_table[fd]->w_queue.q_last->next = - entry->w_queue.q_next; - } else { - fd_table[fd]->w_queue.q_next = - entry->w_queue.q_next; - } - fd_table[fd]->w_queue.q_last = - entry->w_queue.q_last; - } - entry->r_queue.q_next = NULL; - entry->w_queue.q_next = NULL; - entry->r_queue.q_last = NULL; - entry->w_queue.q_last = NULL; - entry->r_owner = NULL; - entry->w_owner = NULL; - ret = OK; - } else { - fd_basic_basic_unlock(entry, FD_RDWR); - pthread_mutex_unlock(&entry->mutex); - /* Note: entry->mutex = mutex */ - } - } - fd_basic_dup(fd, newfd); - } - fd_unlock(fd, FD_RDWR); - } else { - /* Need to lock the newfd by hand */ - mutex = &(fd_table[newfd]->mutex); - pthread_mutex_lock(mutex); - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - /* Is newfd inuse */ - if ((ret = fd_basic_lock(newfd, FD_RDWR, mutex, NULL)) == OK) { - realfd = fd_table[newfd]->fd; - flags = fd_table[newfd]->flags; - /* free it and check close status */ - if ((entry = fd_free(newfd)) == NULL) { - entry = fd_table[newfd]; - entry->ops->close(realfd, flags); - if (entry->r_queue.q_next) { - if (fd_table[fd]->next) { - fd_table[fd]->r_queue.q_last->next = - entry->r_queue.q_next; - } else { - fd_table[fd]->r_queue.q_next = - entry->r_queue.q_next; - } - fd_table[fd]->r_queue.q_last = - entry->r_queue.q_last; - } - if (entry->w_queue.q_next) { - if (fd_table[fd]->next) { - fd_table[fd]->w_queue.q_last->next = - entry->w_queue.q_next; - } else { - fd_table[fd]->w_queue.q_next = - entry->w_queue.q_next; - } - fd_table[fd]->w_queue.q_last = - entry->w_queue.q_last; - } - entry->r_queue.q_next = NULL; - entry->w_queue.q_next = NULL; - entry->r_queue.q_last = NULL; - entry->w_queue.q_last = NULL; - entry->r_owner = NULL; - entry->w_owner = NULL; - ret = OK; - } else { - fd_basic_basic_unlock(entry, FD_RDWR); - pthread_mutex_unlock(&entry->mutex); - /* Note: entry->mutex = mutex */ - } - fd_basic_dup(fd, newfd); - } - fd_unlock(fd, FD_RDWR); - } - } - } else { - ret = NOTOK; - } - return(ret); - -} - -/* ========================================================================== - * dup() - */ -int dup(int fd) -{ - int ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - ret = fd_allocate(); - fd_basic_dup(fd, ret); - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -/* ========================================================================== - * fcntl() - */ -int fcntl(int fd, int cmd, ...) -{ - int ret, realfd, flags; - struct flock *flock; - semaphore *plock; - va_list ap; - - flags = 0; - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - va_start(ap, cmd); - switch(cmd) { - case F_DUPFD: - ret = fd_allocate(); - fd_basic_dup(va_arg(ap, int), ret); - break; - case F_SETFD: - break; - case F_GETFD: - break; - case F_GETFL: - ret = fd_table[fd]->flags; - break; - case F_SETFL: - flags = va_arg(ap, int); - if ((ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, - fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK)) == OK) { - fd_table[fd]->flags = flags; - } - break; -/* case F_SETLKW: */ - /* - * Do the same as SETLK but if it fails with EACCES or EAGAIN - * block the thread and try again later, not implemented yet - */ -/* case F_SETLK: */ -/* case F_GETLK: - flock = va_arg(ap, struct flock*); - ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, - fd_table[fd]->flags, cmd, flock); - break; */ - default: - /* Might want to make va_arg use a union */ - ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, - fd_table[fd]->flags, cmd, va_arg(ap, void*)); - break; - } - va_end(ap); - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -/* ========================================================================== - * getdtablesize() - */ -int getdtablesize() -{ - return dtablesize; -} - -/* ========================================================================== - * ioctl() - * - * Really want to do a real implementation of this that parses the args ala - * fcntl(), above, but it will have to be a totally platform-specific, - * nightmare-on-elm-st-style sort of thing. Might even deserve its own file - * ala select()... --SNL - */ -#ifndef ioctl_request_type -#define ioctl_request_type unsigned long /* Dummy patch by Monty */ -#endif - -int -ioctl(int fd, ioctl_request_type request, ...) -{ - int ret; - pthread_va_list ap; - caddr_t arg; - - va_start( ap, request ); /* Get the arg */ - arg = va_arg(ap,caddr_t); - va_end( ap ); - - if (fd < 0 || fd >= dtablesize) - ret = NOTOK; - else if (fd_table[fd]->fd.i == NOTOK) - ret = machdep_sys_ioctl(fd, request, arg); - else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg); - if( ret == 0 && request == FIONBIO ) { - /* Properly set NONBLOCK flag */ - int v = *(int *)arg; - if( v ) - fd_table[fd]->flags |= __FD_NONBLOCK; - else - fd_table[fd]->flags &= ~__FD_NONBLOCK; - } - fd_unlock(fd, FD_RDWR); - } - return ret; -} - diff --git a/mit-pthreads/pthreads/fd_kern.c b/mit-pthreads/pthreads/fd_kern.c deleted file mode 100644 index f4ada4e4fd4..00000000000 --- a/mit-pthreads/pthreads/fd_kern.c +++ /dev/null @@ -1,1950 +0,0 @@ -/* ==== fd_kern.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Deals with the valid kernel fds. - * - * 1.00 93/09/27 proven - * -Started coding this file. - * - * 1.01 93/11/13 proven - * -The functions readv() and writev() added. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include "config.h" -#include <pthread.h> -#include <unistd.h> -#include <sys/compat.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <stdarg.h> -#include <signal.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread/posix.h> -#include <string.h> - -#if defined (HAVE_SYSCALL_SENDTO) && !defined (HAVE_SYSCALL_SEND) - -pthread_ssize_t machdep_sys_send (int fd, const void *msg, size_t len, - int flags) -{ - return machdep_sys_sendto (fd, msg, len, flags, - (const struct sockaddr *) 0, 0); -} - -#endif - -#if defined (HAVE_SYSCALL_RECVFROM) && !defined (HAVE_SYSCALL_RECV) - -pthread_ssize_t machdep_sys_recv (int fd, void *buf, size_t len, int flags) -{ - return machdep_sys_recvfrom (fd, buf, len, flags, - (struct sockaddr *) 0, (int *) 0); -} - -#endif - -/* ========================================================================== - * Check if there is any signal with must be handled. Added by Monty - * This could be somewhat system dependent but it should work. - */ - -static int fd_check_if_pending_signal(struct pthread *pthread) -{ - int i; - unsigned long *pending,*mask; - if (!pthread->sigcount) - return 0; - pending= (unsigned long*) &pthread->sigpending; - mask= (unsigned long*) &pthread->sigmask; - - for (i=0 ; i < sizeof(pthread->sigpending)/sizeof(unsigned long); i++) - { - if (*pending && (*mask ^ (unsigned) ~0L)) - return 1; - pending++; - mask++; - } - return 0; -} - -/* ========================================================================== - * Variables used by both fd_kern_poll and fd_kern_wait - */ -struct pthread_queue fd_wait_read = PTHREAD_QUEUE_INITIALIZER; -struct pthread_queue fd_wait_write = PTHREAD_QUEUE_INITIALIZER; -struct pthread_queue fd_wait_select = PTHREAD_QUEUE_INITIALIZER; - -static struct timeval __fd_kern_poll_timeout = { 0, 0 }; /* Moved by monty */ -extern struct timeval __fd_kern_wait_timeout; -extern volatile sig_atomic_t sig_to_process; - -/* - * ========================================================================== - * Do a select if there is someting to wait for. - * This is to a combination of the old fd_kern_poll() and fd_kern_wait() - * Return 1 if nothing to do. - */ - -static int fd_kern_select(struct timeval *timeout) -{ - fd_set fd_set_read, fd_set_write, fd_set_except; - struct pthread *pthread, *deq; - int count, i; - - if (!fd_wait_read.q_next && !fd_wait_write.q_next && !fd_wait_select.q_next) - return 1; /* Nothing to do */ - - FD_ZERO(&fd_set_read); - FD_ZERO(&fd_set_write); - FD_ZERO(&fd_set_except); - for (pthread = fd_wait_read.q_next; pthread; pthread = pthread->next) - FD_SET(pthread->data.fd.fd, &fd_set_read); - for (pthread = fd_wait_write.q_next; pthread; pthread = pthread->next) - FD_SET(pthread->data.fd.fd, &fd_set_write); - for (pthread = fd_wait_select.q_next; pthread; pthread = pthread->next) - { - for (i = 0; i < pthread->data.select_data->nfds; i++) { - if (FD_ISSET(i, &pthread->data.select_data->exceptfds)) - FD_SET(i, &fd_set_except); - if (FD_ISSET(i, &pthread->data.select_data->writefds)) - FD_SET(i, &fd_set_write); - if (FD_ISSET(i, &pthread->data.select_data->readfds)) - FD_SET(i, &fd_set_read); - } - } - - /* Turn off interrupts for real while we set the timer. */ - - if (timeout == &__fd_kern_wait_timeout) - { /* from fd_kern_wait() */ - sigset_t sig_to_block, oset; - sigfillset(&sig_to_block); - machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset); - - machdep_unset_thread_timer(NULL); - __fd_kern_wait_timeout.tv_usec = 0; - __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600; - - machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); - } - /* - * There is a small but finite chance that an interrupt will - * occure between the unblock and the select. Because of this - * sig_handler_real() sets the value of __fd_kern_wait_timeout - * to zero causing the select to do a poll instead of a wait. - */ - - while ((count = machdep_sys_select(dtablesize, &fd_set_read, - &fd_set_write, &fd_set_except, - timeout)) < OK) - { - if (count == -EINTR) - return 0; - PANIC(); - } - - for (pthread = fd_wait_read.q_next; pthread; ) { - if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_read) || - fd_check_if_pending_signal(pthread)) - { - if (FD_ISSET(pthread->data.fd.fd, &fd_set_read)) - count--; - deq = pthread; - pthread = pthread->next; - pthread_queue_remove(&fd_wait_read, deq); - if (SET_PF_DONE_EVENT(deq) == OK) { - pthread_prio_queue_enq(pthread_current_prio_queue, deq); - deq->state = PS_RUNNING; - } - continue; - } - pthread = pthread->next; - } - - for (pthread = fd_wait_write.q_next; pthread; ) { - if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_write) || - fd_check_if_pending_signal(pthread)) - { - if (FD_ISSET(pthread->data.fd.fd, &fd_set_read)) - count--; - deq = pthread; - pthread = pthread->next; - pthread_queue_remove(&fd_wait_write, deq); - if (SET_PF_DONE_EVENT(deq) == OK) { - pthread_prio_queue_enq(pthread_current_prio_queue, deq); - deq->state = PS_RUNNING; - } - continue; - } - pthread = pthread->next; - } - - for (pthread = fd_wait_select.q_next; pthread; ) - { - int found_one=0; /* Loop fixed by monty */ - if (count) - { - fd_set tmp_readfds, tmp_writefds, tmp_exceptfds; - memcpy(&tmp_readfds, &pthread->data.select_data->readfds, - sizeof(fd_set)); - memcpy(&tmp_writefds, &pthread->data.select_data->writefds, - sizeof(fd_set)); - memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds, - sizeof(fd_set)); - - for (i = 0; i < pthread->data.select_data->nfds; i++) { - if (FD_ISSET(i, &tmp_exceptfds)) - { - if (! FD_ISSET(i, &fd_set_except)) - FD_CLR(i, &tmp_exceptfds); - else - found_one=1; - } - if (FD_ISSET(i, &tmp_writefds)) - { - if (! FD_ISSET(i, &fd_set_write)) - FD_CLR(i, &tmp_writefds); - else - found_one=1; - } - if (FD_ISSET(i, &tmp_readfds)) - { - if (! FD_ISSET(i, &fd_set_read)) - FD_CLR(i, &tmp_readfds); - else - found_one=1; - } - } - if (found_one) - { - memcpy(&pthread->data.select_data->readfds, &tmp_readfds, - sizeof(fd_set)); - memcpy(&pthread->data.select_data->writefds, &tmp_writefds, - sizeof(fd_set)); - memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds, - sizeof(fd_set)); - } - } - if (found_one || fd_check_if_pending_signal(pthread)) - { - deq = pthread; - pthread = pthread->next; - pthread_queue_remove(&fd_wait_select, deq); - if (SET_PF_DONE_EVENT(deq) == OK) { - pthread_prio_queue_enq(pthread_current_prio_queue, deq); - deq->state = PS_RUNNING; - } - } else { - pthread = pthread->next; - } - } - return 0; -} - - -/* ========================================================================== - * fd_kern_poll() - * - * Called only from context_switch(). The kernel must be locked. - * - * This function uses a linked list of waiting pthreads, NOT a queue. - */ - -void fd_kern_poll() -{ - fd_kern_select(&__fd_kern_poll_timeout); -} - - -/* ========================================================================== - * fd_kern_wait() - * - * Called when there is no active thread to run. - */ - -void fd_kern_wait() -{ - if (fd_kern_select(&__fd_kern_wait_timeout)) - /* No threads, waiting on I/O, do a sigsuspend */ - sig_handler_pause(); -} - - -/* ========================================================================== - * Special Note: All operations return the errno as a negative of the errno - * listed in errno.h - * ======================================================================= */ - -/* ========================================================================== - * read() - */ -pthread_ssize_t __fd_kern_read(union fd_data fd_data, int flags, void *buf, - size_t nbytes, struct timespec * timeout) -{ - int fd = fd_data.i; - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_read(fd, buf, nbytes)) < OK) { - if (!(flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd; - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_FDR_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret= NOTOK; - break; - } - pthread_sched_resume(); - } else { - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_FDR_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - } else { - SET_ERRNO(-ret); - ret = NOTOK; - break; - } - } - return(ret); -} - -/* ========================================================================== - * readv() - */ -int __fd_kern_readv(union fd_data fd_data, int flags, const struct iovec *iov, - int iovcnt, struct timespec * timeout) -{ - int fd = fd_data.i; - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_readv(fd, iov, iovcnt)) < OK) { - if (!(flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - pthread_run->data.fd.fd = fd; - SET_PF_WAIT_EVENT(pthread_run); - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_FDW_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = NOTOK; - break; - } - pthread_sched_resume(); - } else { - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_FDW_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - } else { - SET_ERRNO(-ret); - ret = NOTOK; - break; - } - } - return(ret); -} - -/* ========================================================================== - * write() - */ -pthread_ssize_t __fd_kern_write(union fd_data fd_data, int flags, - const void *buf, size_t nbytes, struct timespec * timeout) -{ - int fd = fd_data.i; - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_write(fd, buf, nbytes)) < OK) { - if (!(flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - pthread_run->data.fd.fd = fd; - SET_PF_WAIT_EVENT(pthread_run); - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = NOTOK; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - } else { - SET_ERRNO(-ret); - ret = NOTOK; - break; - } - } - return(ret); -} - -/* ========================================================================== - * writev() - */ -int __fd_kern_writev(union fd_data fd_data, int flags, const struct iovec *iov, - int iovcnt, struct timespec * timeout) -{ - int fd = fd_data.i; - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_writev(fd, iov, iovcnt)) < OK) { - if (!(flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - pthread_run->data.fd.fd = fd; - SET_PF_WAIT_EVENT(pthread_run); - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = NOTOK; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - } else { - break; - } - } - return(ret); -} - -/* ========================================================================== - * For blocking version we really should set an interrupt - * fcntl() - */ -int __fd_kern_fcntl(union fd_data fd_data, int flags, int cmd, int arg) -{ - int fd = fd_data.i; - - return(machdep_sys_fcntl(fd, cmd, arg)); -} - -/* ========================================================================== - * close() - */ -int __fd_kern_close(union fd_data fd_data, int flags) -{ - int fd = fd_data.i; - - return(machdep_sys_close(fd)); -} - -/* ========================================================================== - * lseek() - * Assume that error number is in the range 0- 255 to get bigger - * range of seek. ; Monty - */ -off_t __fd_kern_lseek(union fd_data fd_data, int f, off_t offset, int whence) -{ - int fd = fd_data.i; - extern off_t machdep_sys_lseek(int, off_t, int); - off_t ret=machdep_sys_lseek(fd, offset, whence); - if ((long) ret < 0L && (long) ret >= -255L) - { - SET_ERRNO(ret); - ret= NOTOK; - } - return ret; -} - -/* - * File descriptor operations - */ -extern machdep_sys_close(); - -/* Normal file operations */ -static struct fd_ops __fd_kern_ops = { - __fd_kern_write, __fd_kern_read, __fd_kern_close, __fd_kern_fcntl, - __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1 -}; - -/* NFS file opperations */ - -/* FIFO file opperations */ - -/* Device operations */ - -/* ========================================================================== - * open() - * - * Because open could potentially block opening a file from a remote - * system, we want to make sure the call will timeout. We then try and open - * the file, and stat the file to determine what operations we should - * associate with the fd. - * - * This is not done yet - * - * A regular file on the local system needs no special treatment. - */ -int open(const char *path, int flags, ...) -{ - int fd, mode, fd_kern; - struct stat stat_buf; - va_list ap; - - /* If pthread scheduling == FIFO set a virtual timer */ - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } else { - mode = 0; - } - - if (!((fd = fd_allocate()) < OK)) { - fd_table[fd]->flags = flags; - flags |= __FD_NONBLOCK; - - if (!((fd_kern = machdep_sys_open(path, flags, mode)) < OK)) { - - /* fstat the file to determine what type it is */ - if (machdep_sys_fstat(fd_kern, &stat_buf)) { - PANIC(); - } - if (S_ISREG(stat_buf.st_mode)) { - fd_table[fd]->ops = &(__fd_kern_ops); - fd_table[fd]->type = FD_HALF_DUPLEX; - } else { - fd_table[fd]->ops = &(__fd_kern_ops); - fd_table[fd]->type = FD_FULL_DUPLEX; - } - fd_table[fd]->fd.i = fd_kern; - return(fd); - } - - fd_table[fd]->count = 0; - SET_ERRNO(-fd_kern); - } - return(NOTOK); -} - -/* ========================================================================== - * create() - */ -int create(const char *path, mode_t mode) -{ - return creat (path, mode); -} - -/* ========================================================================== - * creat() - */ -#undef creat - -int creat(const char *path, mode_t mode) -{ - return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode); -} - -/* ========================================================================== - * fchown() - */ -int fchown(int fd, uid_t owner, gid_t group) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) { - if ((ret = machdep_sys_fchown(fd_table[fd]->fd.i, owner, group)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * fchmod() - */ -int fchmod(int fd, mode_t mode) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) { - if ((ret = machdep_sys_fchmod(fd_table[fd]->fd.i, mode)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * ftruncate() - */ -int ftruncate(int fd, off_t length) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) { - if ((ret = machdep_sys_ftruncate(fd_table[fd]->fd.i, length)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -#if defined (HAVE_SYSCALL_FLOCK) -/* ========================================================================== - * flock() - * - * Added (mevans) - */ -int flock(int fd, int operation) -{ - int ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_flock(fd_table[fd]->fd.i, - operation)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return(ret); -} -#endif - -/* ========================================================================== - * pipe() - */ -int pipe(int fds[2]) -{ - int kfds[2]; - int ret; - - if ((fds[0] = fd_allocate()) >= OK) { - if ((fds[1] = fd_allocate()) >= OK) { - if ((ret = machdep_sys_pipe(kfds)) >= OK) { - fd_table[fds[0]]->flags = machdep_sys_fcntl(kfds[0], F_GETFL, NULL); - machdep_sys_fcntl(kfds[0], F_SETFL, fd_table[fds[0]]->flags | __FD_NONBLOCK); - fd_table[fds[1]]->flags = machdep_sys_fcntl(kfds[1], F_GETFL, NULL); - machdep_sys_fcntl(kfds[1], F_SETFL, fd_table[fds[1]]->flags | __FD_NONBLOCK); - - fd_table[fds[0]]->ops = &(__fd_kern_ops); - fd_table[fds[1]]->ops = &(__fd_kern_ops); - - /* Not really full duplex but ... */ - fd_table[fds[0]]->type = FD_FULL_DUPLEX; - fd_table[fds[1]]->type = FD_FULL_DUPLEX; - - fd_table[fds[0]]->fd.i = kfds[0]; - fd_table[fds[1]]->fd.i = kfds[1]; - - return(OK); - } else { - SET_ERRNO(-ret); - } - fd_table[fds[1]]->count = 0; - } - fd_table[fds[0]]->count = 0; - } - return(NOTOK); -} - -/* ========================================================================== - * fd_kern_reset() - * Change the fcntl blocking flag back to NONBLOCKING. This should only - * be called after a fork. - */ -void fd_kern_reset(int fd) -{ - switch (fd_table[fd]->type) { - case FD_TEST_HALF_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, - fd_table[fd]->flags | __FD_NONBLOCK); - fd_table[fd]->type = FD_HALF_DUPLEX; - break; - case FD_TEST_FULL_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, - fd_table[fd]->flags | __FD_NONBLOCK); - fd_table[fd]->type = FD_FULL_DUPLEX; - break; - default: - break; - } -} - -/* ========================================================================== - * fd_kern_init() - * - * Assume the entry is locked before routine is invoked - * - * This may change. The problem is setting the fd to nonblocking changes - * the parents fd too, which may not be the desired result. - * - * New added feature: If the fd in question is a tty then we open it again - * and close the original, this way we don't have to worry about the - * fd being NONBLOCKING to the outside world. - */ -void fd_kern_init(int fd) -{ - if ((fd_table[fd]->flags = machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) { - if (isatty_basic(fd)) { - int new_fd; - - if ((new_fd = machdep_sys_open(__ttyname_basic(fd), O_RDWR)) >= OK){ - if (machdep_sys_dup2(new_fd, fd) == OK) { - /* Should print a warning */ - - /* Should also set the flags to that of opened outside of - process */ - } - machdep_sys_close(new_fd); - } - } - /* We do these things regaurdless of the above results */ - machdep_sys_fcntl(fd, F_SETFL, fd_table[fd]->flags | __FD_NONBLOCK); - fd_table[fd]->ops = &(__fd_kern_ops); - fd_table[fd]->type = FD_HALF_DUPLEX; - fd_table[fd]->fd.i = fd; - fd_table[fd]->count = 1; - - } -} - -/* ========================================================================== - * fd_kern_gettableentry() - * - * Remember only return a a file descriptor that I will modify later. - * Don't return file descriptors that aren't owned by the child, or don't - * have kernel operations. - */ -static int fd_kern_gettableentry(const int child, int fd) -{ - int i; - - for (i = 0; i < dtablesize; i++) { - if (fd_table[i]) { - if (fd_table[i]->fd.i == fd) { - if (child) { - if ((fd_table[i]->type != FD_TEST_HALF_DUPLEX) && - (fd_table[i]->type != FD_TEST_FULL_DUPLEX)) { - continue; - } - } else { - if ((fd_table[i]->type == FD_NT) || - (fd_table[i]->type == FD_NIU)) { - continue; - } - } - /* Is it a kernel fd ? */ - if ((!fd_table[i]->ops) || - (fd_table[i]->ops->use_kfds != 1)) { - continue; - } - return(i); - } - } - } - return(NOTOK); -} - -/* ========================================================================== - * fd_kern_exec() - * - * Fixup the fd_table such that (fd == fd_table[fd]->fd.i) this way - * the new immage will be OK. - * - * Only touch those that won't be used by the parent if we're in a child - * otherwise fixup all. - * - * Returns: - * 0 no fixup necessary - * 1 fixup without problems - * 2 failed fixup on some descriptors, and clobbered them. - */ -int fd_kern_exec(const int child) -{ - int ret = 0; - int fd, i; - - for (fd = 0; fd < dtablesize; fd++) { - if (fd_table[fd] == NULL) { - continue; - } - /* Is the fd already in use ? */ - if (child) { - if ((fd_table[fd]->type != FD_TEST_HALF_DUPLEX) && - (fd_table[fd]->type != FD_TEST_FULL_DUPLEX)) { - continue; - } - } else { - if ((fd_table[fd]->type == FD_NT) || - (fd_table[fd]->type == FD_NIU)) { - continue; - } - } - /* Is it a kernel fd ? */ - if ((!fd_table[fd]->ops) || - (fd_table[fd]->ops->use_kfds != 1)) { - continue; - } - /* Does it match ? */ - if (fd_table[fd]->fd.i == fd) { - continue; - } - /* OK, fixup entry: Read comments before changing. This isn't obvious */ - - /* i is the real file descriptor fd currently represents */ - if (((i = fd_table[fd]->fd.i) >= dtablesize) || (i < 0)) { - /* This should never happen */ - PANIC(); - } - - /* - * if the real file descriptor with the same number as the fake file - * descriptor number fd is actually in use by the program, we have - * to move it out of the way - */ - if ((machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) { - /* fd is busy */ - int j; - - /* - * j is the fake file descriptor that represents the real file - * descriptor that we want to move. This way the fake file - * descriptor fd can move its real file descriptor i such that - * fd == i. - */ - if ((j = fd_kern_gettableentry(child, fd)) >= OK) { - - /* - * Since j represents a fake file descriptor and fd represents - * a fake file descriptor. If j < fd then a previous pass - * should have set fd_table[j]->fd.i == j. - */ - if (fd < j) { - if ((fd_table[j]->fd.i = machdep_sys_dup(fd)) < OK) { - /* Close j, there is nothing else we can do */ - fd_table[j]->type = FD_NIU; - ret = 2; - } - } else { - /* This implies fd_table[j]->fd.i != j */ - PANIC(); - } - } - } - - /* - * Here the real file descriptor i is set to equel the fake file - * descriptor fd - */ - machdep_sys_dup2(i, fd); - - /* - * Now comes the really complicated part: UNDERSTAND before changing - * - * Here are the things this routine wants to do ... - * - * Case 1. The real file descriptor has only one fake file descriptor - * representing it. - * fd -> i, fd != i ===> fd -> fd, close(i) - * Example fd = 4, i = 2: then close(2), set fd -> i = 4 - * - * Case 2. The real file descriptor has more than one fake file - * descriptor representing it, and this is the first fake file - * descriptor representing the real file descriptor - * fd -> i, fd' -> i, fd != i ===> fd -> fd, fd' -> fd, close(i) - * - * The problem is achiving the above is very messy and difficult, - * but I should be able to take a short cut. If fd > i then there - * will be no need to ever move i, this is because the fake file - * descriptor foo that we would have wanted to represent the real - * file descriptor i has already been processed. If fd < i then by - * moving i to fd all subsequent fake file descriptors fd' should fall - * into the previous case and won't need aditional adjusting. - * - * Does this break the above fd < j check .... It shouldn't because j - * is a fake file descriptor and if j < fd then j has already moved - * its real file descriptor foo such that foo <= j therefore foo < fd - * and not foo == fd therefor j cannot represent the real - * filedescriptor that fd want to move to and be less than fd - */ - if (fd < i) { - fd_table[fd]->fd.i = fd; - machdep_sys_close(i); - } - if (ret < 1) { - ret = 1; - } - } -} - -/* ========================================================================== - * fd_kern_fork() - */ -void fd_kern_fork() -{ - pthread_mutex_t *mutex; - int fd; - - for (fd = 0; fd < dtablesize; fd++) { - if (fd_table[fd] == NULL) { - continue; - } - mutex = & (fd_table[fd]->mutex); - if (pthread_mutex_trylock(mutex)) { - continue; - } - if ((fd_table[fd]->r_owner) || (fd_table[fd]->w_owner)) { - pthread_mutex_unlock(mutex); - continue; - } - /* Is it a kernel fd ? */ - if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) { - pthread_mutex_unlock(mutex); - continue; - } - switch (fd_table[fd]->type) { - case FD_HALF_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags); - fd_table[fd]->type = FD_TEST_HALF_DUPLEX; - break; - case FD_FULL_DUPLEX: - machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags); - fd_table[fd]->type = FD_TEST_FULL_DUPLEX; - break; - default: - break; - } - pthread_mutex_unlock(mutex); - } -} - -/* ========================================================================== - * Here are the berkeley socket functions. These are not POSIX. - * ======================================================================= */ - -#if defined (HAVE_SYSCALL_SOCKET) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * socket() - */ -int socket(int af, int type, int protocol) -{ - int fd, fd_kern; - - if (!((fd = fd_allocate()) < OK)) { - - if (!((fd_kern = machdep_sys_socket(af, type, protocol)) < OK)) { - int tmp_flags; - - tmp_flags = machdep_sys_fcntl(fd_kern, F_GETFL, 0); - machdep_sys_fcntl(fd_kern, F_SETFL, tmp_flags | __FD_NONBLOCK); - - /* Should fstat the file to determine what type it is */ - fd_table[fd]->ops = & __fd_kern_ops; - fd_table[fd]->type = FD_FULL_DUPLEX; - fd_table[fd]->fd.i = fd_kern; - fd_table[fd]->flags = tmp_flags; - return(fd); - } - - fd_table[fd]->count = 0; - SET_ERRNO(-fd_kern); - } - return(NOTOK); -} - -#endif - -#if defined (HAVE_SYSCALL_BIND) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * bind() - */ -#ifdef _OS_HAS_SOCKLEN_T -int bind(int fd, const struct sockaddr *name, socklen_t namelen) -#else -int bind(int fd, const struct sockaddr *name, int namelen) -#endif -{ - /* Not much to do in bind */ - int ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -#endif - -#if defined (HAVE_SYSCALL_CONNECT) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * connect() - */ -#ifdef _OS_HAS_SOCKLEN_T -int connect(int fd, const struct sockaddr *name, socklen_t namelen) -#else -int connect(int fd, const struct sockaddr *name, int namelen) -#endif -{ - struct sockaddr tmpname; - int ret, tmpnamelen; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) || - (ret == -EALREADY) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_write, pthread_run); - - pthread_resched_resume(PS_FDW_WAIT); - CLEAR_PF_DONE_EVENT(pthread_run); - - tmpnamelen = sizeof(tmpname); - /* OK now lets see if it really worked */ - if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i, - &tmpname, &tmpnamelen)) < OK) && - (ret == -ENOTCONN)) - { - /* Get the error, this function should not fail */ - machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET, - SO_ERROR, &ret, &tmpnamelen); - SET_ERRNO(ret); /* ret is already positive (mevans) */ - ret = NOTOK; - } - } else { - if (ret < 0) - { - SET_ERRNO(-ret); - ret = NOTOK; - } - } - } - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -#endif - -#if defined (HAVE_SYSCALL_ACCEPT) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * accept() - */ -#ifdef _OS_HAS_SOCKLEN_T -int accept(int fd, struct sockaddr *name, socklen_t *namelen) -#else -int accept(int fd, struct sockaddr *name, int *namelen) -#endif -{ - int ret, fd_kern; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - while ((fd_kern = machdep_sys_accept(fd_table[fd]->fd.i, name, namelen)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((fd_kern == -EWOULDBLOCK) || (fd_kern == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_read, pthread_run); - - pthread_resched_resume(PS_FDR_WAIT); - CLEAR_PF_DONE_EVENT(pthread_run); - } else { - fd_unlock(fd, FD_RDWR); - SET_ERRNO(-fd_kern); - return(NOTOK); - } - } - fd_unlock(fd, FD_RDWR); - - if (!((ret = fd_allocate()) < OK)) { - - /* This may be unnecessary */ - machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK); - - /* Should fstat the file to determine what type it is */ - fd_table[ret]->ops = & __fd_kern_ops; - fd_table[ret]->type = FD_FULL_DUPLEX; - fd_table[ret]->fd.i = fd_kern; - - /* XXX Flags should be the same as those on the listening fd */ - fd_table[ret]->flags = fd_table[fd]->flags; - } - } - return(ret); -} - -#endif - -#if defined (HAVE_SYSCALL_LISTEN) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * listen() - */ -int listen(int fd, int backlog) -{ - int ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -#endif - -#if defined (HAVE_SYSCALL_SEND) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * send_timedwait() - */ -ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags, - struct timespec * timeout) -{ - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) { - while ((ret = machdep_sys_send(fd_table[fd]->fd.i, - msg, len, flags)) < OK) - { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) - { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - ret = -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - ret= -EINTR; - break; - } - } else { - break; - } - } - fd_unlock(fd, FD_WRITE); - } - if (ret < 0) - { - SET_ERRNO(-ret); - return(NOTOK); - } - return ret; -} - -/* ========================================================================== - * send() - */ -ssize_t send(int fd, const void * msg, size_t len, int flags) -{ - return(send_timedwait(fd, msg, len, flags, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_SENDTO) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * sendto_timedwait() - */ -ssize_t sendto_timedwait(int fd, const void * msg, size_t len, - int flags, const struct sockaddr *to, int to_len, - struct timespec * timeout) -{ - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) { - while ((ret = machdep_sys_sendto(fd_table[fd]->fd.i, - msg, len, flags, to, to_len)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - ret= -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - ret= -EINTR; - break; - } - } - else - break; /* ret contains the errorcode */ - } - fd_unlock(fd, FD_WRITE); - } - if (ret < 0) - { - SET_ERRNO(-ret); - return(NOTOK); - } - return(ret); -} - -/* ========================================================================== - * sendto() - */ -#ifdef _OS_HAS_SOCKLEN_T -ssize_t sendto(int fd, const void * msg, size_t len, int flags, - const struct sockaddr *to, socklen_t to_len) -#else -ssize_t sendto(int fd, const void * msg, size_t len, int flags, - const struct sockaddr *to, int to_len) -#endif -{ - return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_SENDMSG) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * sendmsg_timedwait() - */ -ssize_t sendmsg_timedwait(int fd, const struct msghdr *msg, int flags, - struct timespec * timeout) -{ - int passed_fd, ret, i; - - /* Handle getting the real file descriptor */ - for(i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen/sizeof(i)); i++) { - passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i); - if ((ret = fd_lock(passed_fd, FD_RDWR, NULL)) == OK) { - *(((int *)((struct omsghdr *)msg)->msg_accrights) + i) - = fd_table[passed_fd]->fd.i; - machdep_sys_fcntl(fd_table[passed_fd]->fd.i, F_SETFL, - fd_table[passed_fd]->flags); - switch(fd_table[passed_fd]->type) { - case FD_TEST_FULL_DUPLEX: - case FD_TEST_HALF_DUPLEX: - break; - case FD_FULL_DUPLEX: - fd_table[passed_fd]->type = FD_TEST_FULL_DUPLEX; - break; - case FD_HALF_DUPLEX: - fd_table[passed_fd]->type = FD_TEST_HALF_DUPLEX; - break; - default: - PANIC(); - } - } else { - fd_unlock(fd, FD_RDWR); - SET_ERRNO(EBADF); - return(NOTOK); - } - fd_unlock(fd, FD_RDWR); - } - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) { - while((ret = machdep_sys_sendmsg(fd_table[fd]->fd.i, msg, flags)) < OK){ - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = NOTOK; - break; - } - pthread_sched_resume(); - - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - - } else { - SET_ERRNO(-ret); - ret = NOTOK; - break; - } - } - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * sendmsg() - */ -ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) -{ - return(sendmsg_timedwait(fd, msg, flags, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_RECV) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * recv_timedwait() - */ -ssize_t recv_timedwait(int fd, void * buf, size_t len, int flags, - struct timespec * timeout) -{ - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) { - while ((ret = machdep_sys_recv(fd_table[fd]->fd.i, - buf, len, flags)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDR_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - ret = -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDR_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - ret= -EINTR; - break; - } - - } else { - break; - } - } - fd_unlock(fd, FD_READ); - } - if (ret < 0) - { - SET_ERRNO(-ret); - return(NOTOK); - } - return(ret); -} - -/* ========================================================================== - * recv() - */ -ssize_t recv(int fd, void * buf, size_t len, int flags) -{ - return(recv_timedwait(fd, buf, len, flags, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_RECVFROM) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * recvfrom_timedwait() - */ -ssize_t recvfrom_timedwait(int fd, void * buf, size_t len, int flags, - struct sockaddr * from, int * from_len, - struct timespec * timeout) -{ - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) { - while ((ret = machdep_sys_recvfrom(fd_table[fd]->fd.i, - buf, len, flags, from, from_len)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDR_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - ret= -ETIMEDOUT; - break; - } - pthread_sched_resume(); - - } else { - pthread_resched_resume(PS_FDR_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - ret= -EINTR; - break; - } - } else { - break; - } - } - fd_unlock(fd, FD_READ); - } - if (ret < 0) - { - SET_ERRNO(-ret); - return(NOTOK); - } - return(ret); -} - -/* ========================================================================== - * recvfrom() - */ -#ifdef _OS_HAS_SOCKLEN_T -ssize_t recvfrom(int fd, void * buf, size_t len, int flags, - struct sockaddr * from, socklen_t * from_len) -#else -ssize_t recvfrom(int fd, void * buf, size_t len, int flags, - struct sockaddr * from, int * from_len) -#endif -{ - return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_RECVMSG) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * recvmsg_timedwait() - */ -ssize_t recvmsg_timedwait(int fd, struct msghdr *msg, int flags, - struct timespec * timeout) -{ - struct stat stat_buf; - int passed_fd, ret, i; - - pthread_run->sighandled=0; /* Added by monty */ - if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) { - while ((ret = machdep_sys_recvmsg(fd_table[fd]->fd.i, msg, flags)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, timeout); - - pthread_resched_resume(PS_FDR_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = NOTOK; - break; - } - pthread_sched_resume(); - - } else { - pthread_resched_resume(PS_FDR_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= NOTOK; - break; - } - } else { - SET_ERRNO(-ret); - ret = NOTOK; - break; - } - } - fd_unlock(fd, FD_READ); - - /* Handle getting the real file descriptor */ - for (i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen / sizeof(i)); - i++) { - passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i); - if (!((fd = fd_allocate()) < OK)) { - fd_table[fd]->flags = machdep_sys_fcntl(passed_fd, F_GETFL); - - if (!( fd_table[fd]->flags & __FD_NONBLOCK)) { - machdep_sys_fcntl(passed_fd, F_SETFL, - fd_table[fd]->flags | __FD_NONBLOCK); - } - - /* fstat the file to determine what type it is */ - machdep_sys_fstat(passed_fd, &stat_buf); - if (S_ISREG(stat_buf.st_mode)) { - fd_table[fd]->type = FD_HALF_DUPLEX; - } else { - fd_table[fd]->type = FD_FULL_DUPLEX; - } - *(((int *)((struct omsghdr *)msg)->msg_accrights) + i) = fd; - fd_table[fd]->ops = &(__fd_kern_ops); - fd_table[fd]->fd.i = passed_fd; - } else { - SET_ERRNO(EBADF); - return(NOTOK); - break; - } - } - } - return(ret); -} - -/* ========================================================================== - * recvmsg() - */ -ssize_t recvmsg(int fd, struct msghdr *msg, int flags) -{ - return(recvmsg_timedwait(fd, msg, flags, NULL)); -} - -#endif - -#if defined (HAVE_SYSCALL_SHUTDOWN) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * shutdown() - */ -int shutdown(int fd, int how) -{ - int ret; - - switch(how) { - case 0: /* Read */ - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_READ); - } - case 1: /* Write */ - if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) { - if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_WRITE); - } - case 2: /* Read-Write */ - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - default: - SET_ERRNO(EBADF); - ret = NOTOK; - break; - } - return(ret); -} - -#endif - -#if defined (HAVE_SYSCALL_SETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * setsockopt() - */ -#ifdef _OS_HAS_SOCKLEN_T -int setsockopt(int fd, int level, int optname, const void * optval, socklen_t optlen) -#else -int setsockopt(int fd, int level, int optname, const void * optval, int optlen) -#endif -{ - int ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { - if ((ret = machdep_sys_setsockopt(fd_table[fd]->fd.i, level, - optname, optval, optlen)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return ret; -} - -#endif - -#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * getsockopt() - */ -#ifdef _OS_HAS_SOCKLEN_T -int getsockopt(int fd, int level, int optname, void * optval, socklen_t * optlen) -#else -int getsockopt(int fd, int level, int optname, void * optval, int * optlen) -#endif -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level, - optname, optval, optlen)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return ret; -} - -#endif - -#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * getsockname() - */ -#ifdef _OS_HAS_SOCKLEN_T -int getsockname(int fd, struct sockaddr * name, socklen_t * naddrlen) -#else -int getsockname(int fd, struct sockaddr * name, int * naddrlen) -#endif -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i, - name, naddrlen)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return ret; -} - -#endif - -#if defined (HAVE_SYSCALL_GETPEERNAME) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * getpeername() - */ -#ifdef _OS_HAS_SOCKLEN_T -int getpeername(int fd, struct sockaddr * peer, socklen_t * paddrlen) -#else -int getpeername(int fd, struct sockaddr * peer, int * paddrlen) -#endif -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i, - peer, paddrlen)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_READ); - } - return ret; -} - -#endif - -#if defined (HAVE_SYSCALL_SOCKETPAIR) || defined (HAVE_SYSCALL_SOCKETCALL) - -/* ========================================================================== - * socketpair() - */ -int socketpair(int af, int type, int protocol, int pair[2]) -{ - int ret, fd[2]; - - if (!((pair[0] = fd_allocate()) < OK)) { - if (!((pair[1] = fd_allocate()) < OK)) { - if (!((ret = machdep_sys_socketpair(af, type, protocol, fd)) < OK)){ - int tmp_flags; - - tmp_flags = machdep_sys_fcntl(fd[0], F_GETFL, 0); - machdep_sys_fcntl(fd[0], F_SETFL, tmp_flags | __FD_NONBLOCK); - fd_table[pair[0]]->ops = & __fd_kern_ops; - fd_table[pair[0]]->type = FD_FULL_DUPLEX; - fd_table[pair[0]]->flags = tmp_flags; - fd_table[pair[0]]->fd.i = fd[0]; - - tmp_flags = machdep_sys_fcntl(fd[1], F_GETFL, 0); - machdep_sys_fcntl(fd[1], F_SETFL, tmp_flags | __FD_NONBLOCK); - fd_table[pair[1]]->ops = & __fd_kern_ops; - fd_table[pair[1]]->type = FD_FULL_DUPLEX; - fd_table[pair[1]]->flags = tmp_flags; - fd_table[pair[1]]->fd.i = fd[1]; - - return(ret); - } - fd_table[pair[1]]->count = 0; - } - fd_table[pair[0]]->count = 0; - SET_ERRNO(-ret); - } - return(NOTOK); -} - -#endif diff --git a/mit-pthreads/pthreads/fd_pipe.c b/mit-pthreads/pthreads/fd_pipe.c deleted file mode 100644 index e8bc20857ed..00000000000 --- a/mit-pthreads/pthreads/fd_pipe.c +++ /dev/null @@ -1,257 +0,0 @@ -/* ==== fd_pipe.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : The new fast ITC pipe routines. - * - * 1.00 93/08/14 proven - * -Started coding this file. - * - * 1.01 93/11/13 proven - * -The functions readv() and writev() added. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <pthread/fd_pipe.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread/posix.h> -#include <string.h> -#include <stdlib.h> - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -/* ========================================================================== - * The pipe lock is never unlocked until all pthreads waiting are done with it - * read() - */ -pthread_ssize_t __pipe_read(union fd_data fd_data, int flags, void *buf, - size_t nbytes, struct timespec * timeout) -{ - struct __pipe *fd = (struct __pipe *)fd_data.ptr; - struct pthread * pthread; - int ret = 0; - - if (flags & O_ACCMODE) { return(NOTOK); } - - /* If there is nothing to read, go to sleep */ - if (fd->count == 0) { - if (flags == WR_CLOSED) { - return(0); - } - - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - pthread_run->next = NULL; - fd->wait = pthread_run; - - pthread_resched_resume(PS_FDR_WAIT); - ret = fd->size; - } else { - ret = MIN(nbytes, fd->count); - memcpy(buf, fd->buf + fd->offset, ret); - if (!(fd->count -= ret)) { - fd->offset = 0; - } - - if (pthread = fd->wait) { - fd->wait = NULL; - pthread_sched_prevent(); - pthread_sched_other_resume(pthread); - } - } - return(ret); -} - -/* ========================================================================== - * __pipe_write() - * - * First check to see if the read side is still open, then - * check to see if there is a thread in a read wait for this pipe, if so - * copy as much data as possible directly into the read waiting threads - * buffer. The write thread(whether or not there was a read thread) - * copies as much data as it can into the pipe buffer and it there - * is still data it goes to sleep. - */ -pthread_ssize_t __pipe_write(union fd_data fd_data, int flags, const void *buf, - size_t nbytes, struct timespec * timeout) { - struct __pipe *fd = (struct __pipe *)fd_data.ptr; - struct pthread * pthread; - int ret, count; - - if (!(flags & O_ACCMODE)) { return(NOTOK); } - - while (fd->flags != RD_CLOSED) { - if (pthread = fd->wait) { - - pthread_sched_prevent(); - - /* Copy data directly into waiting pthreads buf */ - fd->wait_size = MIN(nbytes, fd->wait_size); - memcpy(fd->wait_buf, buf, fd->wait_size); - buf = (const char *)buf + fd->wait_size; - nbytes -= fd->wait_size; - ret = fd->wait_size; - fd->wait = NULL; - - /* Wake up waiting pthread */ - pthread_sched_other_resume(pthread); - } - - if (count = MIN(nbytes, fd->size - (fd->offset + fd->count))) { - memcpy(fd->buf + (fd->offset + fd->count), buf, count); - buf = (const char *)buf + count; - nbytes -= count; - ret += count; - } - if (nbytes) { - pthread_sched_prevent(); - fd->wait = pthread_run; - pthread_resched_resume(PS_FDW_WAIT); - } else { - return(ret); - } - } - return(NOTOK); -} - -/* ========================================================================== - * __pipe_close() - * - * The whole close procedure is a bit odd and needs a bit of a rethink. - * For now close() locks the fd, calls fd_free() which checks to see if - * there are any other fd values poinging to the same real fd. If so - * It breaks the wait queue into two sections those that are waiting on fd - * and those waiting on other fd's. Those that are waiting on fd are connected - * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT - * RELEASED). close() then calls fd_unlock which give the fd to the next queued - * element which determins that the fd is closed and then calls fd_unlock etc... - */ -int __pipe_close(struct __pipe *fd, int flags) -{ - struct pthread * pthread; - - if (!(fd->flags)) { - if (pthread = fd->wait) { - if (flags & O_ACCMODE) { - fd->count = 0; - fd->wait = NULL; - fd->flags |= WR_CLOSED; - pthread_sched_prevent(); - pthread_resched_resume(pthread); - } else { - /* Should send a signal */ - fd->flags |= RD_CLOSED; - } - } - } else { - free(fd); - return(OK); - } -} - -/* ========================================================================== - * For fcntl() which isn't implemented yet - * __pipe_enosys() - */ -static int __pipe_enosys() -{ - SET_ERRNO(ENOSYS); - return(NOTOK); -} - -/* ========================================================================== - * For writev() and readv() which aren't implemented yet - * __pipe_enosys_v() - */ -static int __pipe_enosys_v(union fd_data fd, int flags, - const struct iovec *vec, int nvec, - struct timespec *timeout) -{ - SET_ERRNO(ENOSYS); - return(NOTOK); -} - -/* ========================================================================== - * For lseek() which isn't implemented yet - * __pipe_enosys_o() - */ -static off_t __pipe_enosys_o() -{ - SET_ERRNO(ENOSYS); - return(NOTOK); -} - -/* - * File descriptor operations - */ -struct fd_ops fd_ops[] = { -{ __pipe_write, __pipe_read, __pipe_close, __pipe_enosys, - __pipe_enosys_v, __pipe_enosys_v, __pipe_enosys_o, 0 }, -}; - -/* ========================================================================== - * open() - */ -/* int __pipe_open(const char *path, int flags, ...) */ -int newpipe(int fd[2]) -{ - struct __pipe *fd_data; - - if ((!((fd[0] = fd_allocate()) < OK)) && (!((fd[1] = fd_allocate()) < OK))) { - fd_data = malloc(sizeof(struct __pipe)); - fd_data->buf = malloc(4096); - fd_data->size = 4096; - fd_data->count = 0; - fd_data->offset = 0; - - fd_data->wait = NULL; - fd_data->flags = 0; - - fd_table[fd[0]]->fd.ptr = fd_data; - fd_table[fd[0]]->flags = O_RDONLY; - fd_table[fd[1]]->fd.ptr = fd_data; - fd_table[fd[1]]->flags = O_WRONLY; - - return(OK); - } - return(NOTOK); -} - diff --git a/mit-pthreads/pthreads/fd_sysv.c b/mit-pthreads/pthreads/fd_sysv.c deleted file mode 100644 index 6dc01a49aa4..00000000000 --- a/mit-pthreads/pthreads/fd_sysv.c +++ /dev/null @@ -1,897 +0,0 @@ -/* ==== fd_sysv.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Transforms BSD socket calls to SYSV streams. - * - * 1.00 94/11/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <config.h> -#include <pthread.h> -#include <fcntl.h> -#include <errno.h> - -#if defined (HAVE_SYSCALL_PUTMSG) && defined (HAVE_SYSCALL_GETMSG) && !defined(HAVE_SYSCALL_SOCKETCALL) && !defined(HAVE_SYSCALL_SOCKET) -#define HAVE_STREAMS 1 - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <tiuser.h> -#include <sys/tihdr.h> -#include <netinet/in.h> -#include <sys/timod.h> - -#define STREAM_BUF_SIZE sizeof(union T_primitives) + sizeof(struct sockaddr) - -extern struct pthread_queue fd_wait_read, fd_wait_write; - -/* ========================================================================== - * putmsg_timedwait_basic() - */ -static int putmsg_timedwait_basic(int fd, struct strbuf * ctlptr, - struct strbuf * dataptr, int flags, struct timespec * timeout) -{ - - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_putmsg(fd_table[fd]->fd.i, - ctlptr, dataptr, flags)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDW_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_write, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(& current_time, timeout); - - pthread_resched_resume(PS_FDW_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDW_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= -EINTR; - break; - } - } else { - SET_ERRNO(-ret); - break; - } - } - return(ret); -} - -/* ========================================================================== - * putmsg_timedwait() - */ -int putmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr, - int flags, struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) { - ret = putmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout); - fd_unlock(fd, FD_WRITE); - } - return(ret); -} - -/* ========================================================================== - * putmsg() - */ -int putmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr, - int flags) -{ - return(putmsg_timedwait(fd, ctlptr, dataptr, flags, NULL)); -} - -/* ========================================================================== - * getmsg_timedwait_basic() - */ -int getmsg_timedwait_basic(int fd, struct strbuf * ctlptr, - struct strbuf * dataptr, int * flags, struct timespec * timeout) -{ - int ret; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_getmsg(fd_table[fd]->fd.i, - ctlptr, dataptr, flags)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - SET_PF_WAIT_EVENT(pthread_run); - pthread_run->data.fd.fd = fd_table[fd]->fd.i; - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(& current_time, timeout); - - pthread_resched_resume(PS_FDR_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDR_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - ret= -EINTR; - break; - } - - } else { - SET_ERRNO(-ret); - break; - } - } - return(ret); -} - -/* ========================================================================== - * getmsg_timedwait() - */ -int getmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr, - int * flags, struct timespec * timeout) -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) { - ret = getmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout); - fd_unlock(fd, FD_READ); - } - return (ret); -} - -/* ========================================================================== - * getmsg() - */ -int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr, - int * flags) -{ - return(getmsg_timedwait(fd, ctlptr, dataptr, flags, NULL)); -} - -#endif - -/* ========================================================================== - * Here are the berkeley socket functions implemented with stream calls. - * These are not POSIX. - * ======================================================================= */ - -#if (!defined (HAVE_SYSCALL_BIND)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * bind() - */ -int bind(int fd, const struct sockaddr *name, int namelen) -{ - char buf[STREAM_BUF_SIZE]; - union T_primitives * res; - struct T_bind_req * req; - struct T_bind_ack * ack; - struct strbuf strbuf; - int flags, ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) - { - req = (struct T_bind_req *)buf; - req->PRIM_type = T_BIND_REQ; - req->ADDR_length = namelen; - req->ADDR_offset = sizeof(struct T_bind_req); - req->CONIND_number = 4; - memcpy(buf + sizeof(struct T_bind_req), name, namelen); - - strbuf.len = sizeof(struct T_bind_req) + namelen; - strbuf.maxlen = STREAM_BUF_SIZE; - strbuf.buf = buf; - - if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) == OK) - { - memset(buf, 0, STREAM_BUF_SIZE); - - strbuf.len = sizeof(struct T_bind_ack) + namelen; - strbuf.maxlen = STREAM_BUF_SIZE; - strbuf.buf = buf; - flags = 0; - - if ((ret = getmsg_timedwait_basic(fd, &strbuf, NULL, - &flags, NULL)) >= OK) - { - res = (union T_primitives *)buf; - - switch(res->type) { - case T_BIND_ACK: - ret = OK; - break; - default: - SET_ERRNO(EPROTO); /* What should this be? */ - ret = NOTOK; - break; - } - } - else - { - SET_ERRNO(-ret); - ret = NOTOK; - } - } - else - { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -#endif - -#if (!defined (HAVE_SYSCALL_CONNECT)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * connect() - */ -int connect(int fd, const struct sockaddr *name, int namelen) -{ - char buf[STREAM_BUF_SIZE]; - union T_primitives * res; - struct T_conn_req * req; - struct T_conn_con * con; - struct T_ok_ack * ok; - struct strbuf strbuf; - int flags, ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) - { - req = (struct T_conn_req *)buf; - req->PRIM_type = T_CONN_REQ; - req->DEST_length = namelen; - req->DEST_offset = sizeof(struct T_conn_req); - req->OPT_length = 0; - req->OPT_offset = 0; - memcpy(buf + sizeof(struct T_conn_req), name, namelen); - - strbuf.len = sizeof(struct T_conn_req) + namelen; - strbuf.maxlen = STREAM_BUF_SIZE; - strbuf.buf = buf; - - if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) != OK) - goto err; - - memset(buf, 0, STREAM_BUF_SIZE); - ok = (struct T_ok_ack *)buf; - - strbuf.maxlen = STREAM_BUF_SIZE; - strbuf.len = STREAM_BUF_SIZE; - strbuf.buf = buf; - flags = 0; - - if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK) - goto err; /* Fixed by monty */ - if (ok->PRIM_type != T_OK_ACK) - { - ret= -EPROTO; /* What should this be? */ - goto err; - } - - memset(buf, 0, STREAM_BUF_SIZE); - strbuf.maxlen = STREAM_BUF_SIZE; - strbuf.len = STREAM_BUF_SIZE; - strbuf.buf = buf; - flags = 0; - - if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL) < OK)) - goto err; - - res = (union T_primitives *) buf; - switch(res->type) { - case T_CONN_CON: - ret = OK; - break; - case T_DISCON_IND: - ret= -ECONNREFUSED; - goto err; - default: - ret= -EPROTO; /* What should this be? */ - goto err; - } - fd_unlock(fd, FD_RDWR); - } - return(ret); - - err: - fd_unlock(fd, FD_RDWR); - SET_ERRNO(-ret); /* Proably not needed... */ - return NOTOK; -} - -#endif - -#if (!defined (HAVE_SYSCALL_LISTEN)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * listen() - */ -int listen(int fd, int backlog) -{ - return(OK); -} - -#endif - -#if (!defined (HAVE_SYSCALL_SOCKET)) && defined(HAVE_STREAMS) - -extern ssize_t __fd_kern_write(); -static pthread_ssize_t __fd_sysv_read(); -extern int __fd_kern_close(); -extern int __fd_kern_fcntl(); -extern int __fd_kern_writev(); -extern int __fd_kern_readv(); -extern off_t __fd_kern_lseek(); - -/* Normal file operations */ -static struct fd_ops __fd_sysv_ops = { - __fd_kern_write, __fd_sysv_read, __fd_kern_close, __fd_kern_fcntl, - __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1 -}; - -/* ========================================================================== - * read() - */ -static pthread_ssize_t __fd_sysv_read(union fd_data fd_data, int flags, - void *buf, size_t nbytes, struct timespec * timeout) -{ - struct strbuf dataptr; - int fd = fd_data.i; - int getmsg_flags; - int ret; - - getmsg_flags = 0; - dataptr.len = 0; - dataptr.buf = buf; - dataptr.maxlen = nbytes; - - pthread_run->sighandled=0; /* Added by monty */ - while ((ret = machdep_sys_getmsg(fd, NULL, &dataptr, &getmsg_flags)) < OK) { - if (!(fd_table[fd]->flags & __FD_NONBLOCK) && - ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { - pthread_sched_prevent(); - - /* queue pthread for a FDR_WAIT */ - pthread_run->data.fd.fd = fd; - SET_PF_WAIT_EVENT(pthread_run); - pthread_queue_enq(&fd_wait_read, pthread_run); - - if (timeout) { - /* get current time */ - struct timespec current_time; - machdep_gettimeofday(¤t_time); - sleep_schedule(& current_time, timeout); - - pthread_resched_resume(PS_FDR_WAIT); - - /* We're awake */ - pthread_sched_prevent(); - if (sleep_cancel(pthread_run) == NOTOK) { - CLEAR_PF_DONE_EVENT(pthread_run); - pthread_sched_resume(); - SET_ERRNO(ETIMEDOUT); - ret = -ETIMEDOUT; - break; - } - pthread_sched_resume(); - } else { - pthread_resched_resume(PS_FDR_WAIT); - } - CLEAR_PF_DONE_EVENT(pthread_run); - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - SET_ERRNO(EINTR); - return(NOTOK); - } - } else { - SET_ERRNO(-ret); - return(NOTOK); - break; - } - } - return(dataptr.len); -} - -/* ========================================================================== - * socket_tcp() - */ -static int socket_tcp(int fd) -{ - int ret; - - if ((ret = machdep_sys_open("/dev/tcp", O_RDWR | O_NONBLOCK, 0)) >= OK) { - /* Should fstat the file to determine what type it is */ - fd_table[fd]->ops = & __fd_sysv_ops; - fd_table[fd]->type = FD_FULL_DUPLEX; - fd_table[fd]->fd.i = ret; - fd_table[fd]->flags = 0; - } - return(ret); -} - -/* ========================================================================== - * socket() - */ -int socket(int af, int type, int protocol) -{ - int fd, fd_kern; - - if ((fd = fd_allocate()) < OK) - return (fd); - - switch(af) { - case AF_INET: - switch(type) { - case SOCK_STREAM: - if ((fd_kern = socket_tcp(fd)) >= OK) - return(fd); - SET_ERRNO(-fd_kern); - break; - case SOCK_DGRAM: - if ((fd_kern = machdep_sys_open("/dev/udp", - O_RDWR | O_NONBLOCK, 0)) >= OK) { - /* Should fstat the file to determine what type it is */ - fd_table[fd]->ops = & __fd_sysv_ops; - fd_table[fd]->type = FD_FULL_DUPLEX; - fd_table[fd]->fd.i = fd_kern; - fd_table[fd]->flags = 0; - return(fd); - } - SET_ERRNO(-fd_kern); - break; - default: - SET_ERRNO(EPROTONOSUPPORT); - break; - } - break; - case AF_UNIX: - case AF_ISO: - case AF_NS: - default: - SET_ERRNO(EPROTONOSUPPORT); - break; - } - fd_table[fd]->count = 0; - return(NOTOK); /* Fixed by monty */ -} - -#endif - -#if (!defined (HAVE_SYSCALL_ACCEPT)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * accept_fd() - */ -static int accept_fd(int fd, struct sockaddr *name, int *namelen, char * buf, - int SEQ_number) -{ - struct T_conn_res * res; - struct strbuf strbuf; - int fd_new, fd_kern; - - /* Get a new table entry */ - if ((fd_new = fd_allocate()) < OK) - return(NOTOK); - - /* Get the new kernel entry */ - if (!((fd_kern = socket_tcp(fd_new)) < OK)) { - res = (struct T_conn_res *)buf; - res->PRIM_type = T_CONN_RES; - /* res->QUEUE_ptr = (queue_t *)&fd_kern; */ - res->OPT_length = 0; - res->OPT_offset = 0; - res->SEQ_number = SEQ_number; - - strbuf.maxlen = sizeof(union T_primitives) +sizeof(struct sockaddr); - strbuf.len = sizeof(struct T_conn_ind) + (*namelen); - strbuf.buf = buf; - - { - struct strfdinsert insert; - - insert.ctlbuf.maxlen = (sizeof(union T_primitives) + - sizeof(struct sockaddr)); - insert.ctlbuf.len = sizeof(struct T_conn_ind); - insert.ctlbuf.buf = buf; - insert.databuf.maxlen = 0; - insert.databuf.len = 0; - insert.databuf.buf = NULL; - insert.flags = 0; - insert.fildes = fd_kern; - insert.offset = 4; - /* Should the following be checked ? */ - machdep_sys_ioctl(fd_table[fd]->fd.i, I_FDINSERT, &insert); - } - - /* if (putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL) == OK) { - /* return(fd_new); */ - { - int flags = 0; - int ret; - - /* Should the following be checked ? */ - ret = getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL); - return(fd_new); - - } - machdep_sys_close(fd_kern); - } - fd_table[fd_new]->count = 0; - return(NOTOK); -} - - -/* ========================================================================== - * accept() - */ -int accept(int fd, struct sockaddr *name, int *namelen) -{ - char buf[sizeof(union T_primitives) + sizeof(struct sockaddr)]; - struct T_conn_ind * ind; - struct strbuf strbuf; - int flags, ret; - - if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) - { - ind = (struct T_conn_ind *)buf; - ind->PRIM_type = T_CONN_IND; - ind->SRC_length = (*namelen); - ind->SRC_offset = sizeof(struct T_conn_ind); - ind->OPT_length = 0; - ind->OPT_offset = 0; - ind->SEQ_number = 0; - - strbuf.maxlen = sizeof(union T_primitives) + sizeof(struct sockaddr); - strbuf.len = sizeof(struct T_conn_ind) + (*namelen); - strbuf.buf = buf; - flags = 0; - - if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK) - { - SET_ERRNO(-ret); - ret= NOTOK; - } - else - ret = accept_fd(fd, name, namelen, buf, ind->SEQ_number); - fd_unlock(fd, FD_RDWR); - } - return(ret); -} - -#endif /* HAVE_SYSCALL_ACCEPT */ - -#if (!defined (HAVE_SYSCALL_SENDTO)) && defined (HAVE_STREAMS) - -/* ========================================================================== - * sendto_timedwait() - */ -ssize_t sendto_timedwait(int fd, const void * msg, size_t len, int flags, - const struct sockaddr *name, int namelen, struct timespec * timeout) -{ - char buf[STREAM_BUF_SIZE]; - struct T_unitdata_req * req; - struct strbuf dataptr; - struct strbuf ctlptr; - ssize_t ret, prio; - - req = (struct T_unitdata_req *)buf; - req->PRIM_type = T_UNITDATA_REQ; - req->DEST_length = namelen; - req->DEST_offset = sizeof(struct T_unitdata_req); - req->OPT_length = 0; - req->OPT_offset = 0; - memcpy(buf + sizeof(struct T_unitdata_req), name, namelen); - - ctlptr.len = sizeof(struct T_unitdata_req) + namelen; - ctlptr.maxlen = STREAM_BUF_SIZE; - ctlptr.buf = buf; - - dataptr.len = len; - dataptr.maxlen = len; - dataptr.buf = (void *)msg; - - if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) { - ret = len; - } - return(ret); -} - -/* ========================================================================== - * sendto() - */ -ssize_t sendto(int fd, const void * msg, size_t len, int flags, - const struct sockaddr *to, int to_len) -{ - return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL)); -} - -#endif - -#if (!defined (HAVE_SYSCALL_SEND)) && defined (HAVE_STREAMS) - -/* ========================================================================== - * send_timedwait() - */ -ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags, - struct timespec * timeout) -{ - char buf[STREAM_BUF_SIZE]; - struct T_unitdata_req * req; - struct strbuf dataptr; - struct strbuf ctlptr; - ssize_t ret, prio; - - req = (struct T_unitdata_req *)buf; - req->PRIM_type = T_UNITDATA_REQ; - req->DEST_length = 0; - req->DEST_offset = 0; - req->OPT_length = 0; - req->OPT_offset = 0; - - ctlptr.len = sizeof(struct T_unitdata_req); - ctlptr.maxlen = STREAM_BUF_SIZE; - ctlptr.buf = buf; - - dataptr.len = len; - dataptr.maxlen = len; - dataptr.buf = (void *)msg; - - if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) { - ret = len; - } - return(ret); -} - -/* ========================================================================== - * send() - */ -ssize_t send(int fd, const void * msg, size_t len, int flags) -{ - return(send_timedwait(fd, msg, len, flags, NULL)); -} - -#endif - -#if (!defined (HAVE_SYSCALL_RECVFROM)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * recvfrom_timedwait() - */ -ssize_t recvfrom_timedwait(int fd, void * msg, size_t len, int flags, - struct sockaddr * name, int * namelen, struct timespec * timeout) -{ - char buf[STREAM_BUF_SIZE]; - struct T_unitdata_ind * ind; - struct strbuf dataptr; - struct strbuf ctlptr; - int ret, prio; - - ctlptr.len = 0; - ctlptr.maxlen = STREAM_BUF_SIZE; - ctlptr.buf = buf; - - dataptr.maxlen = len; - dataptr.len = 0; - dataptr.buf = msg; - - prio = 0; - - ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout); - if (ret >= OK) { - if (name != NULL) { - ind = (struct T_unitdata_ind *)buf; - - if (*namelen > ind->SRC_length) - *namelen = ind->SRC_length; - memcpy(name, buf + ind->SRC_offset, *namelen); - } - ret = dataptr.len; - } - - return(ret); -} - -/* ========================================================================== - * recvfrom() - */ -ssize_t recvfrom(int fd, void * buf, size_t len, int flags, - struct sockaddr * from, int * from_len) -{ - return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL)); -} - -#endif - -#if (!defined (HAVE_SYSCALL_RECV)) && defined(HAVE_STREAMS) - -/* ========================================================================== - * recv_timedwait() - */ -ssize_t recv_timedwait(int fd, void * msg, size_t len, int flags, - struct timespec * timeout) -{ - char buf[STREAM_BUF_SIZE]; - struct T_unitdata_ind * ind; - struct strbuf dataptr; - struct strbuf ctlptr; - int ret, prio; - - ctlptr.len = 0; - ctlptr.maxlen = STREAM_BUF_SIZE; - ctlptr.buf = buf; - - dataptr.maxlen = len; - dataptr.len = 0; - dataptr.buf = msg; - - prio = 0; - - ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout); - if (ret >= OK) - ret = dataptr.len; - - return(ret); -} - -/* ========================================================================== - * recv() - */ -ssize_t recv(int fd, void * buf, size_t len, int flags, - struct sockaddr * from, int * from_len) -{ - return(recv_timedwait(fd, buf, len, flags, NULL)); -} - -#endif - -#if (!defined (HAVE_SYSCALL_SETSOCKOPT)) && defined(HAVE_STREAMS) -/* ========================================================================== - * setsockopt() - */ -int setsockopt(int s, int level, int optname, const void *optval, int optlen) -{ - return(0); -} -#endif - -struct foo { /* Used by getsockname and getpeername */ - long a; - int b; - struct sockaddr *name; -}; - -#if (!defined (HAVE_SYSCALL_GETSOCKNAME)) && defined(HAVE_STREAMS) -/* ========================================================================== - * getsockname() - */ - - -int getsockname(int s, struct sockaddr *name, int *namelen) -{ - struct foo foo; - int i; - if (*namelen < sizeof(struct sockaddr)) { - SET_ERRNO(ENOMEM); - return(-1); - } - foo.a = 0x84; - foo.b = 0; - foo.name = name; - i = ioctl(s, TI_GETMYNAME, &foo); - *namelen = foo.b; - return(i); -} -#endif - -#if (!defined (HAVE_SYSCALL_GETPEERNAME)) && defined(HAVE_STREAMS) -/* ========================================================================== - * getpeername() ; Added by Monty - */ - -int getpeername(int s, struct sockaddr *name, int *namelen) -{ - struct foo foo; - int i; - if (*namelen < sizeof(struct sockaddr)) { - SET_ERRNO(ENOMEM); - return(-1); - } - foo.a = 0x84; /* Max length ? */ - foo.b = 0; /* Return length */ - foo.name = name; /* Return buffer */ - i = ioctl(s, TI_GETPEERNAME, &foo); - *namelen = foo.b; - return(i); -} -#endif - - -#if (!defined (HAVE_SYSCALL_SHUTDOWN)) && defined(HAVE_STREAMS) -/* ========================================================================== - * shutdown() - */ - -int shutdown(int s, int how) -{ - return(0); -} -#endif diff --git a/mit-pthreads/pthreads/file.c b/mit-pthreads/pthreads/file.c deleted file mode 100644 index 4b8a8aad6db..00000000000 --- a/mit-pthreads/pthreads/file.c +++ /dev/null @@ -1,129 +0,0 @@ -/* ==== file.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : The locking functions for stdio. - * - * 1.00 93/09/04 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <stdio.h> - -/* ========================================================================== - * flockfile() - */ -void flockfile(FILE *fp) -{ - pthread_mutex_t *mutex; - int fd, flags; - - if ((fd = fileno(fp)) >= 0) { - pthread_mutex_lock(mutex = &(fd_table[fd]->mutex)); - - if (fp->_flags & __SRW) { - flags = FD_READ | FD_WRITE; - } else { - if (fp->_flags & __SWR) { - flags = FD_WRITE; - } else { - flags = FD_READ; - } - } - - /* This might fail but POSIX doesn't give a damn. */ - fd_basic_lock(fd, flags, mutex, NULL); - pthread_mutex_unlock(mutex); - } -} - -/* ========================================================================== - * ftrylockfile() - */ -int ftrylockfile(FILE *fp) -{ - pthread_mutex_t *mutex; - int fd, flags; - - if ((fd = fileno(fp)) >= 0) { - pthread_mutex_lock(mutex = &(fd_table[fd]->mutex)); - - if (fp->_flags & __SRW) { - flags = FD_READ | FD_WRITE; - } else { - if (fp->_flags & __SWR) { - flags = FD_WRITE; - } else { - flags = FD_READ; - } - } - if (!(fd_table[fd]->r_owner && fd_table[fd]->w_owner)) { - fd_basic_lock(fd, flags, mutex, NULL); - fd = OK; - } else { - fd = NOTOK; - } - pthread_mutex_unlock(mutex); - } else { - fd = OK; - } - return(fd); -} - -/* ========================================================================== - * funlockfile() - */ -void funlockfile(FILE *fp) -{ - pthread_mutex_t *mutex; - int fd, flags; - - if ((fd = fileno(fp)) >= 0) { - pthread_mutex_lock(mutex = &(fd_table[fd]->mutex)); - - if (fp->_flags & __SRW) { - flags = FD_READ | FD_WRITE; - } else { - if (fp->_flags & __SWR) { - flags = FD_WRITE; - } else { - flags = FD_READ; - } - } - fd_basic_unlock(fd, flags); - pthread_mutex_unlock(mutex); - } -} - diff --git a/mit-pthreads/pthreads/globals.c b/mit-pthreads/pthreads/globals.c deleted file mode 100644 index 921588fb220..00000000000 --- a/mit-pthreads/pthreads/globals.c +++ /dev/null @@ -1,85 +0,0 @@ -/* ==== globals.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Global variables. - * - * 1.00 93/07/26 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* - * Initial thread, running thread, and top of link list of all threads. - */ -struct pthread *pthread_run=NULL; -struct pthread *pthread_initial=NULL; -struct pthread *pthread_link_list=NULL; - -sigset_t * uthread_sigmask; /* Current process signal mask */ - -/* - * Dead thread queue, and threads elligible to be alloced queue. - */ -struct pthread_queue pthread_dead_queue; -struct pthread_queue pthread_alloc_queue; - -/* - * Queue for all threads elidgeable to run this scheduling round. - */ -struct pthread_prio_queue * pthread_current_prio_queue=NULL; - -/* - * default thread attributes - */ -pthread_attr_t pthread_attr_default = { SCHED_RR, PTHREAD_DEFAULT_PRIORITY, - PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT }; - -/* - * File table information - */ -struct fd_table_entry **fd_table=NULL; - -/* - * A we a fork()ed process - */ -volatile int fork_lock = 0; -volatile int pthread_kernel_lock=0; - -/* - * The page size, as returned by getpagesize() - */ -size_t pthread_pagesize=0; - diff --git a/mit-pthreads/pthreads/info.c b/mit-pthreads/pthreads/info.c deleted file mode 100644 index 2b9722ba291..00000000000 --- a/mit-pthreads/pthreads/info.c +++ /dev/null @@ -1,77 +0,0 @@ -/* hello */ - -#include <stdio.h> -#include <pthread.h> -#include <signal.h> - -static const char *const state_names[] = { -#define __pthread_defstate(S,NAME) NAME, -#include "pthread/state.def" -#undef __pthread_defstate - 0 -}; - -void (*dump_thread_info_fn) (struct pthread *, FILE *); - -static void -dump_thread_info (thread, file) - struct pthread *thread; - FILE *file; -{ - /* machdep */ - /* attr */ - /* signals */ - /* wakeup_time */ - /* join */ - fprintf (file, " thread @%p prio %3d %s", thread, - thread->pthread_priority, state_names[(int) thread->state]); - switch (thread->state) { - case PS_FDLR_WAIT: - fprintf (file, " fd %d[%d]", thread->data.fd.fd, - thread->data.fd.branch); - fprintf (file, " owner %pr/%pw", - fd_table[thread->data.fd.fd]->r_owner, - fd_table[thread->data.fd.fd]->w_owner); - break; - } - /* show where the signal handler gets run */ - if (thread == pthread_run) - fprintf (file, "\t\t[ME!]"); - fprintf (file, "\n"); - if (dump_thread_info_fn) - (*dump_thread_info_fn) (thread, file); -} - -static void -pthread_dump_info_to_file (file) - FILE *file; -{ - pthread_t t; - for (t = pthread_link_list; t; t = t->pll) - dump_thread_info (t, file); -} - -void -pthread_dump_info () -{ - if (ftrylockfile (stderr) != 0) - return; - fprintf (stderr, "process id %ld:\n", (long) getpid ()); - pthread_dump_info_to_file (stderr); - funlockfile (stderr); -} - -#ifdef SIGINFO -static void -sig_handler (sig) - int sig; -{ - pthread_dump_info (); -} - -void -pthread_setup_siginfo () -{ - (void) signal (SIGINFO, sig_handler); -} -#endif diff --git a/mit-pthreads/pthreads/init.cc b/mit-pthreads/pthreads/init.cc deleted file mode 100644 index 24a131a60a5..00000000000 --- a/mit-pthreads/pthreads/init.cc +++ /dev/null @@ -1,9 +0,0 @@ - -/* - * DO not delete this file. The hack here ensures that pthread_init() gets - * called before main does. This doesn't fix everything. It is still - * possible for a c++ module to reley on constructors that need pthreads. - */ -#include <pthread.h> - -char __pthread_init_hack = 42; diff --git a/mit-pthreads/pthreads/malloc.c b/mit-pthreads/pthreads/malloc.c deleted file mode 100644 index 76fe03824ac..00000000000 --- a/mit-pthreads/pthreads/malloc.c +++ /dev/null @@ -1,383 +0,0 @@ -/* ==== malloc.c ============================================================ - * Copyright (c) 1983 Regents of the University of California. - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Description : Malloc functions. - * This is a very fast storage allocator. It allocates blocks of a small - * number of different sizes, and keeps free lists of each size. Blocks that - * don't exactly fit are passed up to the next larger size. In this - * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. - * This is designed for use in a virtual memory environment. - * - * 0.00 82/02/21 Chris Kingsley kingsley@cit-20 - * - * 1.00 93/11/06 proven - * -Modified BSD libc malloc to be threadsafe. - * - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <sys/types.h> -#include <string.h> -#include <pthread/posix.h> - -/* - * The overhead on a block is at least 4 bytes. When free, this space - * contains a pointer to the next free block, and the bottom two bits must - * be zero. When in use, the first byte is set to MAGIC, and the second - * byte is the size index. The remaining bytes are for alignment. - * If range checking is enabled then a second word holds the size of the - * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC). - * The order of elements is critical: ov_magic must overlay the low order - * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern. - */ -#ifdef __alpha -#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE char* -#else -#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE double -#endif /* __alpha */ -union overhead { - _MOST_RESTRICTIVE_ALIGNMENT_TYPE __alignment_pad0; - union overhead *ov_next; /* when free */ - struct { - u_char ovu_magic; /* magic number */ - u_char ovu_index; /* bucket # */ -#ifdef RCHECK - u_short ovu_rmagic; /* range magic number */ - size_t ovu_size; /* actual block size */ -#endif - } ovu; -#define ov_magic ovu.ovu_magic -#define ov_index ovu.ovu_index -#define ov_rmagic ovu.ovu_rmagic -#define ov_size ovu.ovu_size -}; - -#define MAGIC 0xef /* magic # on accounting info */ -#define RMAGIC 0x5555 /* magic # on range info */ - -#ifdef RCHECK -#define RSLOP sizeof (u_short) -#else -#define RSLOP 0 -#endif - -/* - * nextf[i] is the pointer to the next free block of size 2^(i+3). The - * smallest allocatable block is 8 bytes. The overhead information - * precedes the data area returned to the user. - */ -#define NBUCKETS 30 -static union overhead *nextf[NBUCKETS]; -#ifndef hpux -extern char *sbrk(); -#endif - -static size_t pagesz; /* page size */ -static int pagebucket; /* page size bucket */ -static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER; - -#if defined(DEBUG) || defined(RCHECK) -#define ASSERT(p) if (!(p)) botch("p") -#include <stdio.h> -static -botch(s) - char *s; -{ - fprintf(stderr, "\r\nassertion botched: %s\r\n", s); - (void) fflush(stderr); /* just in case user buffered it */ - abort(); -} -#else -#define ASSERT(p) -#endif - -/* ========================================================================== - * morecore() - * - * Allocate more memory to the indicated bucket - */ -static inline void morecore(int bucket) -{ - register union overhead *op; - register size_t sz; /* size of desired block */ - size_t amt; /* amount to allocate */ - size_t nblks; /* how many blocks we get */ - - /* - * sbrk_size <= 0 only for big, FLUFFY, requests (about - * 2^30 bytes on a VAX, I think) or for a negative arg. - */ - sz = 1L << (bucket + 3); -#ifdef DEBUG - ASSERT(sz > 0); -#else - if (sz <= 0) - return; -#endif - if (sz < pagesz) { - amt = pagesz; - nblks = amt / sz; - } else { - amt = sz + pagesz; - nblks = 1; - } - op = (union overhead *)sbrk(amt); - /* no more room! */ - if (op == (union overhead *) -1) - return; - /* - * Add new memory allocated to that on - * free list for this hash bucket. - */ - nextf[bucket] = op; - while (--nblks > 0) { - op->ov_next = (union overhead *)((caddr_t)op + sz); - op = (union overhead *)((caddr_t)op + sz); - } -} - -/* ========================================================================== - * malloc() - */ -void *malloc(size_t nbytes) -{ - pthread_mutex_t *mutex; - union overhead *op; - size_t amt; - size_t bucket, n; - - mutex = &malloc_mutex; - pthread_mutex_lock(mutex); - /* - * First time malloc is called, setup page size and - * align break pointer so all data will be page aligned. - */ - if (pagesz == 0) { - size_t x; - pagesz = n = getpagesize(); - op = (union overhead *)sbrk(0); - x = sizeof (*op) - ((long)op & (n - 1)); - if (n < x) - n = n + pagesz - x; - else - n = n - x; - if (n) { - if (sbrk(n) == (char *)-1) { - /* Unlock before returning (mevans) */ - pthread_mutex_unlock(mutex); - return (NULL); - } - } - bucket = 0; - amt = 8; - while (pagesz > amt) { - amt <<= 1; - bucket++; - } - pagebucket = bucket; - } - /* - * Convert amount of memory requested into closest block size - * stored in hash buckets which satisfies request. - * Account for space used per block for accounting. - */ - if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { -#ifndef RCHECK - amt = 8; /* size of first bucket */ - bucket = 0; -#else - amt = 16; /* size of first bucket */ - bucket = 1; -#endif - n = -(sizeof (*op) + RSLOP); - } else { - amt = pagesz; - bucket = pagebucket; - } - while (nbytes > amt + n) { - amt <<= 1; - if (amt == 0) { - pthread_mutex_unlock(mutex); - return (NULL); - } - bucket++; - } - ASSERT (bucket < NBUCKETS); - /* - * If nothing in hash bucket right now, - * request more memory from the system. - */ - if ((op = nextf[bucket]) == NULL) { - morecore(bucket); - if ((op = nextf[bucket]) == NULL) { - pthread_mutex_unlock(mutex); - return (NULL); - } - } - /* remove from linked list */ - nextf[bucket] = op->ov_next; - op->ov_magic = MAGIC; - op->ov_index = bucket; -#ifdef RCHECK - /* - * Record allocated size of block and - * bound space with magic numbers. - */ - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - op->ov_rmagic = RMAGIC; - *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; -#endif - pthread_mutex_unlock(mutex); - return ((char *)(op + 1)); -} - -/* ========================================================================== - * free() - */ -void free(void *cp) -{ - pthread_mutex_t *mutex; - union overhead *op; - int size; - - mutex = &malloc_mutex; - pthread_mutex_lock(mutex); - if (cp == NULL) { - pthread_mutex_unlock(mutex); - return; - } - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); -#ifdef DEBUG - ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ -#else - if (op->ov_magic != MAGIC) { - pthread_mutex_unlock(mutex); - return; /* sanity */ - } -#endif -#ifdef RCHECK - ASSERT(op->ov_rmagic == RMAGIC); - ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); -#endif - size = op->ov_index; - ASSERT(size < NBUCKETS); - op->ov_next = nextf[size]; /* also clobbers ov_magic */ - nextf[size] = op; - - pthread_mutex_unlock(mutex); -} - -/* ========================================================================== - * realloc() - * - * Storage compaction is no longer supported, fix program and try again. - */ -void *realloc(void *cp, size_t nbytes) -{ - pthread_mutex_t *mutex; - size_t onb; - size_t i; - union overhead *op; - char *res; - - if (cp == NULL) - return (malloc(nbytes)); - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); - - if (op->ov_magic == MAGIC) { - i = op->ov_index; - } else { - /* - * This will cause old programs using storage compaction feature of - * realloc to break in a pseudo resonable way that is easy to debug. - * Returning a malloced buffer without the copy may cause - * indeterministic behavior. - */ - return(NULL); - } - - mutex = &malloc_mutex; - pthread_mutex_lock(mutex); - onb = 1L << (i + 3); - if (onb < pagesz) - onb -= sizeof (*op) + RSLOP; - else - onb += pagesz - sizeof (*op) - RSLOP; - - /* avoid the copy if same size block */ - if (i) { - i = 1L << (i + 2); - if (i < pagesz) - i -= sizeof (*op) + RSLOP; - else - i += pagesz - sizeof (*op) - RSLOP; - } - - if (nbytes <= onb && nbytes > i) { -#ifdef RCHECK - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; -#endif - pthread_mutex_unlock(mutex); - return(cp); - } - pthread_mutex_unlock(mutex); - - if ((res = malloc(nbytes)) == NULL) { - free(cp); - return (NULL); - } - - memcpy(res, cp, (nbytes < onb) ? nbytes : onb); - free(cp); - - return (res); -} - -/* ========================================================================== - * calloc() - * - * Added to ensure pthread's allocation is used (mevans). - */ -void *calloc(size_t nmemb, size_t size) -{ - void *p; - size *= nmemb; - p = malloc(size); - if (p) memset(p, 0, size); - return (p); -} diff --git a/mit-pthreads/pthreads/mutex.c b/mit-pthreads/pthreads/mutex.c deleted file mode 100644 index 1a2ca6fa1c1..00000000000 --- a/mit-pthreads/pthreads/mutex.c +++ /dev/null @@ -1,371 +0,0 @@ -/* ==== mutex.c ============================================================== - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Mutex functions. - * - * 1.00 93/07/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <stdlib.h> -#include <errno.h> - -/* ========================================================================== - * pthread_mutex_is_debug() - * - * Check that mutex is a debug mutex and if so returns entry number into - * array of debug mutexes. - */ -static int pthread_mutex_debug_count = 0; -static pthread_mutex_t ** pthread_mutex_debug_ptrs = NULL; - -static inline int pthread_mutex_is_debug(pthread_mutex_t * mutex) -{ - int i; - - for (i = 0; i < pthread_mutex_debug_count; i++) { - if (pthread_mutex_debug_ptrs[i] == mutex) { - return(i); - } - } - return(NOTOK); -} - -/* ========================================================================== - * pthread_mutex_init() - * - * In this implementation I don't need to allocate memory. - * ENOMEM, EAGAIN should never be returned. Arch that have - * weird constraints may need special coding. - */ -int pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - enum pthread_mutextype type; - - /* Only check if attr specifies some mutex type other than fast */ - if ((mutex_attr) && (mutex_attr->m_type != MUTEX_TYPE_FAST)) { - if (mutex_attr->m_type >= MUTEX_TYPE_MAX) { - return(EINVAL); - } - type = mutex_attr->m_type; - } else { - type = MUTEX_TYPE_FAST; - } - mutex->m_flags = 0; - - pthread_sched_prevent(); - - switch(type) { - case MUTEX_TYPE_FAST: - break; - case MUTEX_TYPE_STATIC_FAST: - pthread_sched_resume(); - return(EINVAL); - break; - case MUTEX_TYPE_COUNTING_FAST: - mutex->m_data.m_count = 0; - break; - case MUTEX_TYPE_DEBUG: - if (pthread_mutex_is_debug(mutex) == NOTOK) { - pthread_mutex_t ** new; - - if ((new = (pthread_mutex_t **)realloc(pthread_mutex_debug_ptrs, - (pthread_mutex_debug_count + 1) * (sizeof(void *)))) == NULL) { - pthread_sched_resume(); - return(ENOMEM); - } - pthread_mutex_debug_ptrs = new; - pthread_mutex_debug_ptrs[pthread_mutex_debug_count++] = mutex; - } else { - pthread_sched_resume(); - return(EBUSY); - } - break; - default: - pthread_sched_resume(); - return(EINVAL); - break; - } - /* Set all other paramaters */ - pthread_queue_init(&mutex->m_queue); - mutex->m_flags |= MUTEX_FLAGS_INITED; - mutex->m_owner = NULL; - mutex->m_type = type; - - pthread_sched_resume(); - return(OK); -} - -/* ========================================================================== - * pthread_mutex_destroy() - */ -int pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - int i; - - pthread_sched_prevent(); - - /* Only check if mutex is of type other than fast */ - switch(mutex->m_type) { - case MUTEX_TYPE_FAST: - break; - case MUTEX_TYPE_STATIC_FAST: - pthread_sched_resume(); - return(EINVAL); - break; - case MUTEX_TYPE_COUNTING_FAST: - mutex->m_data.m_count = 0; - break; - case MUTEX_TYPE_DEBUG: - if ((i = pthread_mutex_is_debug(mutex)) == NOTOK) { - pthread_sched_resume(); - return(EINVAL); - } - if (mutex->m_owner) { - pthread_sched_resume(); - return(EBUSY); - } - - /* Remove the mutex from the list of debug mutexes */ - pthread_mutex_debug_ptrs[i] = - pthread_mutex_debug_ptrs[--pthread_mutex_debug_count]; - pthread_mutex_debug_ptrs[pthread_mutex_debug_count] = NULL; - break; - default: - pthread_sched_resume(); - return(EINVAL); - break; - } - - /* Cleanup mutex, others might want to use it. */ - pthread_queue_init(&mutex->m_queue); - mutex->m_owner = NULL; - mutex->m_flags = 0; - - pthread_sched_resume(); - return(OK); -} - -/* ========================================================================== - * pthread_mutex_trylock() - */ -int pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - int rval; - - pthread_sched_prevent(); - switch (mutex->m_type) { - /* - * Fast mutexes do not check for any error conditions. - */ - case MUTEX_TYPE_FAST: - case MUTEX_TYPE_STATIC_FAST: - if (!mutex->m_owner) { - mutex->m_owner = pthread_run; - rval = OK; - } else { - rval = EBUSY; - } - break; - case MUTEX_TYPE_COUNTING_FAST: - if (mutex->m_owner) { - if (mutex->m_owner == pthread_run) { - mutex->m_data.m_count++; - rval = OK; - } else { - rval = EBUSY; - } - } else { - mutex->m_owner = pthread_run; - rval = OK; - } - break; - case MUTEX_TYPE_DEBUG: - if (pthread_mutex_is_debug(mutex) != NOTOK) { - if (!mutex->m_owner) { - mutex->m_owner = pthread_run; - rval = OK; - } else { - rval = EBUSY; - } - } else { - rval = EINVAL; - } - break; - default: - rval = EINVAL; - break; - } - - pthread_sched_resume(); - return(rval); -} - -/* ========================================================================== - * pthread_mutex_lock() - */ -int pthread_mutex_lock(pthread_mutex_t *mutex) -{ - int rval; - - pthread_sched_prevent(); - switch (mutex->m_type) { - /* - * Fast mutexes do not check for any error conditions. - */ - case MUTEX_TYPE_FAST: - case MUTEX_TYPE_STATIC_FAST: - if (mutex->m_owner) { - pthread_queue_enq(&mutex->m_queue, pthread_run); - - /* Reschedule will unlock scheduler */ - pthread_resched_resume(PS_MUTEX_WAIT); - return(OK); - } - mutex->m_owner = pthread_run; - rval = OK; - break; - case MUTEX_TYPE_COUNTING_FAST: - if (mutex->m_owner) { - if (mutex->m_owner != pthread_run) { - pthread_queue_enq(&mutex->m_queue, pthread_run); - - /* Reschedule will unlock scheduler */ - pthread_resched_resume(PS_MUTEX_WAIT); - return(OK); - } else { - mutex->m_data.m_count++; - } - } else { - mutex->m_owner = pthread_run; - } - rval = OK; - break; - case MUTEX_TYPE_DEBUG: - if (pthread_mutex_is_debug(mutex) != NOTOK) { - if (mutex->m_owner) { - if (mutex->m_owner != pthread_run) { - pthread_queue_enq(&mutex->m_queue, pthread_run); - - /* Reschedule will unlock pthread_run */ - pthread_resched_resume(PS_MUTEX_WAIT); - - if (mutex->m_owner != pthread_run) { - PANIC(); - } - return(OK); - } - rval = EDEADLK; - break; - } - mutex->m_owner = pthread_run; - rval = OK; - break; - } - rval = EINVAL; - break; - default: - rval = EINVAL; - break; - } - - pthread_sched_resume(); - return(rval); -} - -/* ========================================================================== - * pthread_mutex_unlock() - */ -int pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - struct pthread *pthread; - int rval; - - pthread_sched_prevent(); - - switch (mutex->m_type) { - /* - * Fast mutexes do not check for any error conditions. - */ - case MUTEX_TYPE_FAST: - case MUTEX_TYPE_STATIC_FAST: - if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) { - - /* Reschedule will unlock scheduler */ - pthread_sched_other_resume(mutex->m_owner); - return(OK); - } - rval = OK; - break; - case MUTEX_TYPE_COUNTING_FAST: - if (mutex->m_data.m_count) { - mutex->m_data.m_count--; - rval = OK; - break; - } - if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) { - - /* Reschedule will unlock scheduler */ - pthread_sched_other_resume(mutex->m_owner); - return(OK); - } - rval = OK; - break; - case MUTEX_TYPE_DEBUG: - if (pthread_mutex_is_debug(mutex) != NOTOK) { - if (mutex->m_owner == pthread_run) { - if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) { - - /* Reschedule will unlock scheduler */ - pthread_sched_other_resume(mutex->m_owner); - return(OK); - } - rval = OK; - } else { - rval = EPERM; - } - } else { - rval = EINVAL; - } - break; - default: - rval = EINVAL; - break; - } - pthread_sched_resume(); - return(rval); -} diff --git a/mit-pthreads/pthreads/mutexattr.c b/mit-pthreads/pthreads/mutexattr.c deleted file mode 100644 index d045b5041a0..00000000000 --- a/mit-pthreads/pthreads/mutexattr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ==== mutexattr.c =========================================================== - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Mutex functions. - * - * 1.00 93/07/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> - -/* ========================================================================== - * pthread_mutexattr_init() - */ -int pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - attr->m_type = MUTEX_TYPE_FAST; - return(OK); -} - -/* ========================================================================== - * pthread_mutexattr_destroy() - */ -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - return(OK); -} - -/* ========================================================================== - * pthread_mutexattr_settype() - */ -int pthread_mutexattr_settype(pthread_mutexattr_t *attr, unsigned int type) -{ - switch(type) { - case PTHREAD_MUTEXTYPE_FAST: - attr->m_type = MUTEX_TYPE_FAST; - break; - case PTHREAD_MUTEXTYPE_RECURSIVE: - attr->m_type = MUTEX_TYPE_COUNTING_FAST; - break; - case PTHREAD_MUTEXTYPE_DEBUG: - attr->m_type = MUTEX_TYPE_DEBUG; - break; - default: - return(EINVAL); - } - return(OK); -} - -/* ========================================================================== - * pthread_mutexattr_gettype() - */ -int pthread_mutexattr_gettype(pthread_mutexattr_t *attr, unsigned int * type) -{ - *type = (unsigned int)attr->m_type; - return(OK); -} diff --git a/mit-pthreads/pthreads/panic.c b/mit-pthreads/pthreads/panic.c deleted file mode 100644 index 6b963acd651..00000000000 --- a/mit-pthreads/pthreads/panic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* ==== panic.c ======================================================= - * Copyright (c) 1996 by Larry V. Streepy, Jr. - * 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 Larry V. Streepy, Jr. - * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``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 Larry V. Streepy, Jr. 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. - * - * Description : pthread kernel panic - * - * 02 Oct 1996 - Larry V. Streepy, Jr. - * - Initial coding - */ - -#include <pthread.h> -#include <stdio.h> -/*---------------------------------------------------------------------- - * Function: panic_kernel - * Purpose: print a message and panic the pthreads kernel - * Args: file name, line number, and function - * Returns: doesn't - * Notes: - *----------------------------------------------------------------------*/ void -panic_kernel( const char *file, unsigned int line, const char *func ) -{ -#ifdef __GNUC__ - (void) fprintf( stderr, "%s:%u: %s%sPhtreads kernel panic.\n", - file, line, func ? func : "", func ? ": " : "" ); - (void) fflush (stderr); -#else - (void) fprintf( stderr, "%s:%u: Phtreads kernel panic.\n", file, line ); - (void) fflush (stderr); -#endif - abort(); -} diff --git a/mit-pthreads/pthreads/prio_queue.c b/mit-pthreads/pthreads/prio_queue.c deleted file mode 100644 index d976f9cd68f..00000000000 --- a/mit-pthreads/pthreads/prio_queue.c +++ /dev/null @@ -1,176 +0,0 @@ -/* ==== prio_queue.c ========================================================== - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Priority Queue functions. - * - * 1.00 94/09/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* A thread when it becomes eligeble to run is placed on the run queue. - This requires locking the kernel lock -*/ - -/* ========================================================================== - * pthread_prio_queue_init() - */ -void pthread_prio_queue_init(struct pthread_prio_queue * queue) -{ - int i; - - for (i = 0; i <= PTHREAD_MAX_PRIORITY; i++) { - queue->level[i].first = NULL; - queue->level[i].last = NULL; - } - queue->next = NULL; - queue->data = NULL; -} - -/* ========================================================================== - * pthread_priority_enq() - */ -void pthread_prio_queue_enq(struct pthread_prio_queue * queue, - struct pthread * pthread) -{ - int priority = pthread->pthread_priority; - - if (queue->next) { - if (queue->level[priority].first) { - pthread->next = (queue->level[priority].last)->next; - (queue->level[priority].last)->next = pthread; - queue->level[priority].last = pthread; - return; - } - if (priority != PTHREAD_MAX_PRIORITY) { - int prev_priority; - /* Find first higher priority thread queued on queue */ - for (prev_priority = priority + 1; prev_priority <= - PTHREAD_MAX_PRIORITY; prev_priority++) { - if (queue->level[prev_priority].first) { - pthread->next = (queue->level[prev_priority].last)->next; - (queue->level[prev_priority].last)->next = pthread; - queue->level[priority].first = pthread; - queue->level[priority].last = pthread; - return; - } - } - } - } - queue->level[priority].first = pthread; - queue->level[priority].last = pthread; - pthread->next = queue->next; - queue->next = pthread; -} - -/* ========================================================================== - * pthread_prio_queue_deq() - */ -struct pthread * pthread_prio_queue_deq(struct pthread_prio_queue * queue) -{ - struct pthread * pthread; - int priority; - - if (pthread = queue->next) { - priority = queue->next->pthread_priority; - if (queue->level[priority].first == queue->level[priority].last) { - queue->level[priority].first = NULL; - queue->level[priority].last = NULL; - } else { - queue->level[priority].first = pthread->next; - } - queue->next = pthread->next; - pthread->next = NULL; - } - return(pthread); -} - -/* ========================================================================== - * pthread_prio_queue_remove() - */ -int pthread_prio_queue_remove(struct pthread_prio_queue *queue, - struct pthread *thread) -{ - /* XXX This is slow, should start with thread priority */ - int priority = thread->pthread_priority; - struct pthread **current = &(queue->level[priority].first); - struct pthread *prev = NULL; - - if (thread==*current) { - int current_priority=priority+1; - - if (*current == queue->next){ - pthread_prio_queue_deq(queue); - thread->next = NULL; - return(OK); - } - for (current_priority; current_priority <= PTHREAD_MAX_PRIORITY; - current_priority++) { - if (queue->level[current_priority].last) { - queue->level[current_priority].last->next = (*current)->next; - if ((*current)->next && - (*current)->next->pthread_priority == priority) - queue->level[priority].first = (*current)->next; - else { - queue->level[priority].first = NULL; - queue->level[priority].last = NULL; - } - thread->next = NULL; - return(OK); - } - } - } - - if (*current == NULL) /* Mati Sauks */ - { - return (NOTOK); - } - for (prev=*current,current=&((*current)->next); - *current && ((*current)->pthread_priority == priority); - prev=*current,current=&((*current)->next)) { - if (*current == thread) { - if (*current == queue->level[priority].last) { - queue->level[priority].last = prev; - } - - *current = (*current)->next; - thread->next=NULL; - return(OK); - } - } - return(NOTOK); -} - diff --git a/mit-pthreads/pthreads/process.c b/mit-pthreads/pthreads/process.c deleted file mode 100644 index 9b3abb3384b..00000000000 --- a/mit-pthreads/pthreads/process.c +++ /dev/null @@ -1,208 +0,0 @@ -/* ==== process.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Process functions (fork, exec, ...). - * - * 1.23 94/04/18 proven - * -Started coding this file. - */ - -#include <pthread.h> -#include <sys/types.h> -#include <pthread.h> -#include <stdarg.h> -#include <unistd.h> -#ifdef HAVE_ALLOC_H -#include <alloc.h> -#endif - -extern void *alloca(); - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -/* ========================================================================== - * fork() - * - * This function requires a sig_prevent()/sig_check_and_resume() for the - * parent. The child never unlocks. - */ -pid_t fork() -{ - pid_t ret; - - pthread_sched_prevent(); - - fd_kern_fork(); - if (ret = machdep_sys_fork()) { /* Parent or error */ - pthread_sched_resume(); - } else { /* Child */ - machdep_unset_thread_timer(NULL); - machdep_stop_timer(NULL); - fork_lock++; - pthread_kernel_lock--; - } - return(ret); -} - -#ifdef HAVE_VFORK -/* The semantics of vfork probably won't mix well with the pthread - library code. Don't even try. */ -pid_t vfork () -{ - return fork (); -} -#endif - -/* ========================================================================== - * execve() - * - * This function requires a sig_prevent()/sig_check_and_resume() if one - * hasn't been done in the fork routine. Normally machdep_sys_execve() - * should never return. - */ -int execve(const char *name, char * const *argv, char * const *envp) -{ - int ret; - - if (!fork_lock) { - pthread_sched_prevent(); - fd_kern_exec(0); - ret = machdep_sys_execve(name, argv, envp); - pthread_sched_resume(); - } else { - fd_kern_exec(1); - ret = machdep_sys_execve(name, argv, envp); - } - return(ret); -} - -/* Variants of execve. Define them here so that the system versions - don't get used and drag in the system version of execve. */ -#include <sys/stat.h> -#include <string.h> -#include <sys/param.h> -extern char **environ; - -static const char *find (const char *name, char *buf) -{ - char *p1, *p2; - extern char *getenv (); - struct stat sb; - - if (strchr (name, '/')) - return name; - p1 = getenv ("PATH"); - if (p1 == 0) - p1 = "/bin:/usr/bin:"; - while (*p1) { - memset (buf, 0, MAXPATHLEN); - p2 = strchr (p1, ':'); - if (p2 == 0) - p2 = p1 + strlen (p1); - strncpy (buf, p1, p2 - p1); - buf[p2 - p1] = 0; - strcat (buf, "/"); - strcat (buf, name); - if (lstat (buf, &sb) == 0) - return buf; - - if (*p2 == ':') - p2++; - p1 = p2; - } - return name; -} - -int execl (const char *path, const char *arg, ...) -{ -#ifdef SCO_3_5 - return execve (path, (char *const *) &arg, environ); -#else - char ** argv; - va_list ap; - int i; - - va_start(ap, arg); - for (i = 1; va_arg(ap, char *) != NULL; i++); - va_end(ap); - - argv = alloca (i * sizeof (char *)); - - va_start(ap, arg); - argv[0] = (char *) arg; - for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++); - va_end(ap); - - return execve (path, argv, environ); -#endif -} - -int execlp (const char *name, const char *arg, ...) -{ -#ifdef SCO_3_5 - char buf[MAXPATHLEN]; - return execve (find (name, buf), (char *const *) &arg, environ); -#else - char buf[MAXPATHLEN]; - char ** argv; - va_list ap; - int i; - - va_start(ap, arg); - for (i = 1; va_arg(ap, char *) != NULL; i++); - va_end(ap); - - argv = alloca (i * sizeof (char *)); - - va_start(ap, arg); - argv[0] = (char *) arg; - for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++); - va_end(ap); - - return execve (find (name, buf), argv, environ); -#endif -} - -int execle (const char *name, const char *arg, ... /* , char *const envp[] */); - -/* This one turns on ptrace-style tracing? */ -int exect (const char *path, char *const argv[], char *const envp[]); - -int execv (const char *path, char *const argv[]) { - return execve (path, argv, environ); -} - -int execvp (const char *name, char *const argv[]) { - char buf[MAXPATHLEN]; - return execve (find (name, buf), argv, environ); -} diff --git a/mit-pthreads/pthreads/pthread.c b/mit-pthreads/pthreads/pthread.c deleted file mode 100644 index 6f7e2d53980..00000000000 --- a/mit-pthreads/pthreads/pthread.c +++ /dev/null @@ -1,293 +0,0 @@ -/* ==== pthread.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread functions. - * - * 1.00 93/07/26 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <stdlib.h> -#include <signal.h> -#include <errno.h> -#include <string.h> -#include <sched.h> - -/* ========================================================================== - * sched_yield() - */ -int sched_yield() -{ - sig_handler_fake(SIGVTALRM); - return(OK); -} - -/* ========================================================================== - * pthread_yield() - */ -void pthread_yield() -{ - sig_handler_fake(SIGVTALRM); -} - -/* ========================================================================== - * pthread_self() - */ -pthread_t pthread_self() -{ - return(pthread_run); -} - -/* ========================================================================== - * pthread_equal() - */ -int pthread_equal(pthread_t t1, pthread_t t2) -{ - return(t1 == t2); -} - -/* ========================================================================== - * pthread_exit() - */ -extern void pthread_cleanupspecific(void); - -void pthread_exit(void *status) -{ - pthread_t pthread; - - /* Save return value */ - pthread_run->ret = status; - - /* First execute all cleanup handlers */ - while (pthread_run->cleanup) { - pthread_cleanup_pop(1); - } - - /* Don't forget the cleanup attr */ - if (pthread_run->attr.cleanup_attr) { - pthread_run->attr.cleanup_attr(pthread_run->attr.arg_attr); - } - - /* Next run thread-specific data desctructors */ - if (pthread_run->specific_data) { - pthread_cleanupspecific(); - } - - pthread_sched_prevent(); - - if (!(pthread_run->attr.flags & PTHREAD_DETACHED)) { - /* - * Are there any threads joined to this one, - * if so wake them and let them detach this thread. - */ - while (pthread = pthread_queue_deq(&(pthread_run->join_queue))) { - pthread_prio_queue_enq(pthread_current_prio_queue, pthread); - pthread->state = PS_RUNNING; - } - pthread_queue_enq(&pthread_dead_queue, pthread_run); - pthread_resched_resume(PS_DEAD); - } else { - pthread_queue_enq(&pthread_alloc_queue, pthread_run); - pthread_resched_resume(PS_UNALLOCED); - } - - /* This thread will never run again */ - PANIC(); - -} - -/*---------------------------------------------------------------------- - * Function: __pthread_is_valid - * Purpose: Scan the list of threads to see if a specified thread exists - * Args: - * pthread = The thread to scan for - * Returns: - * int = 1 if found, 0 if not - * Notes: - * The kernel is assumed to be locked - *----------------------------------------------------------------------*/ -int -__pthread_is_valid( pthread_t pthread ) -{ - int rtn = 0; /* Assume not found */ - pthread_t t; - - for( t = pthread_link_list; t; t = t->pll ) { - if( t == pthread ) { - rtn = 1; /* Found it */ - break; - } - } - - return rtn; -} - -/* ========================================================================== - * __pthread_free() - */ -static inline void __pthread_free(pthread_t new_thread) -{ - pthread_sched_prevent(); - new_thread->state = PS_UNALLOCED; - new_thread->attr.stacksize_attr = 0; - new_thread->attr.stackaddr_attr = NULL; - pthread_queue_enq(&pthread_alloc_queue, new_thread); - pthread_sched_resume(); -} -/* ========================================================================== - * __pthread_alloc() - */ -/* static inline pthread_t __pthread_alloc(const pthread_attr_t *attr) */ -static pthread_t __pthread_alloc(const pthread_attr_t *attr) -{ - pthread_t thread; - void * stack; - void * old; - - pthread_sched_prevent(); - thread = pthread_queue_deq(&pthread_alloc_queue); - pthread_sched_resume(); - - if (thread) { - if (stack = attr->stackaddr_attr) { - __machdep_stack_repl(&(thread->machdep_data), stack); - } else { - if ((__machdep_stack_get(&(thread->machdep_data)) == NULL) - || (attr->stacksize_attr > thread->attr.stacksize_attr)) { - if (stack = __machdep_stack_alloc(attr->stacksize_attr)) { - __machdep_stack_repl(&(thread->machdep_data), stack); - } else { - __pthread_free(thread); - thread = NULL; - } - } - } - } else { - /* We should probable allocate several for efficiency */ - if (thread = (pthread_t)malloc(sizeof(struct pthread))) { - /* Link new thread into list of all threads */ - - pthread_sched_prevent(); - thread->state = PS_UNALLOCED; - thread->pll = pthread_link_list; - pthread_link_list = thread; - pthread_sched_resume(); - - if ((stack = attr->stackaddr_attr) || - (stack = __machdep_stack_alloc(attr->stacksize_attr))) { - __machdep_stack_set(&(thread->machdep_data), stack); - } else { - __machdep_stack_set(&(thread->machdep_data), NULL); - __pthread_free(thread); - thread = NULL; - } - } - } - return(thread); -} - -/* ========================================================================== - * pthread_create() - * - * After the new thread structure is allocated and set up, it is added to - * pthread_run_next_queue, which requires a sig_prevent(), - * sig_check_and_resume() - */ -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, - void * (*start_routine)(void *), void *arg) -{ - pthread_t new_thread; - int nsec = 100000000; - int retval = OK; - - if (! attr) - attr = &pthread_attr_default; - - if (new_thread = __pthread_alloc(attr)) { - - __machdep_pthread_create(&(new_thread->machdep_data), - start_routine, arg, attr->stacksize_attr, nsec, 0); - - memcpy(&new_thread->attr, attr, sizeof(pthread_attr_t)); - if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) { - new_thread->pthread_priority = pthread_run->pthread_priority; - new_thread->attr.sched_priority = pthread_run->pthread_priority; - new_thread->attr.schedparam_policy = - pthread_run->attr.schedparam_policy; - } else { - new_thread->pthread_priority = new_thread->attr.sched_priority; - } - - if (!(new_thread->attr.flags & PTHREAD_NOFLOAT)) { - machdep_save_float_state(new_thread); - } - - /* Initialize signalmask */ - new_thread->sigmask = pthread_run->sigmask; - sigemptyset(&(new_thread->sigpending)); - new_thread->sigcount = 0; - - pthread_queue_init(&(new_thread->join_queue)); - new_thread->specific_data = NULL; - new_thread->specific_data_count = 0; - new_thread->cleanup = NULL; - new_thread->queue = NULL; - new_thread->next = NULL; - new_thread->flags = 0; - - /* PTHREADS spec says we start with cancellability on and deferred */ - SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE); - SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED); - - new_thread->error_p = NULL; - new_thread->sll = NULL; - - pthread_sched_prevent(); - - - pthread_sched_other_resume(new_thread); - /* - * Assignment must be outside of the locked pthread kernel incase - * thread is a bogus address resulting in a seg-fault. We want the - * original thread to be capable of handling the resulting signal. - * --proven - */ - (*thread) = new_thread; - } else { - retval = EAGAIN; - } - return(retval); -} diff --git a/mit-pthreads/pthreads/pthread_attr.c b/mit-pthreads/pthreads/pthread_attr.c deleted file mode 100644 index 5e1c0302227..00000000000 --- a/mit-pthreads/pthreads/pthread_attr.c +++ /dev/null @@ -1,255 +0,0 @@ -/* ==== pthread_attr.c ======================================================= - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread attribute functions. - * - * 1.00 93/11/04 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> -#include <string.h> - -/* Currently we do no locking, should we just to be safe? CAP */ -/* ========================================================================== - * pthread_attr_init() - */ -int pthread_attr_init(pthread_attr_t *attr) -{ - memcpy(attr, &pthread_attr_default, sizeof(pthread_attr_t)); - return(OK); -} - -/* ========================================================================== - * pthread_attr_destroy() - */ -int pthread_attr_destroy(pthread_attr_t *attr) -{ - return(OK); -} - -/* ========================================================================== - * pthread_attr_getstacksize() - */ -int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize) -{ - *stacksize = attr->stacksize_attr; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setstacksize() - */ -int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) -{ - if (stacksize >= PTHREAD_STACK_MIN) { - attr->stacksize_attr = stacksize; - return(OK); - } - return(EINVAL); -} - -/* ========================================================================== - * pthread_attr_getstackaddr() - */ -int pthread_attr_getstackaddr(pthread_attr_t *attr, void ** stackaddr) -{ - *stackaddr = attr->stackaddr_attr; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setstackaddr() - */ -int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr) -{ - attr->stackaddr_attr = stackaddr; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setcleanup() - */ -int pthread_attr_setcleanup(pthread_attr_t *attr, void (*routine)(void *), - void * arg) -{ - attr->cleanup_attr = routine; - attr->arg_attr = arg; - return(OK); -} - -/* ========================================================================== - * pthread_attr_getdetachstate() - */ -int pthread_attr_getdetachstate(pthread_attr_t *attr, int * detachstate) -{ - *detachstate = attr->flags & PTHREAD_DETACHED; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setdetachstate() - */ -int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) -{ - attr->flags = (attr->flags & ~(PTHREAD_DETACHED)) | - (detachstate & PTHREAD_DETACHED); - return(OK); -} - -/* ========================================================================== - * pthread_attr_getfloatstate() - */ -int pthread_attr_getfloatstate(pthread_attr_t *attr, int * floatstate) -{ - *floatstate = attr->flags & PTHREAD_NOFLOAT; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setfloatstate() - */ -int pthread_attr_setfloatstate(pthread_attr_t *attr, int floatstate) -{ - attr->flags = (attr->flags & ~(PTHREAD_NOFLOAT)) | - (floatstate & PTHREAD_NOFLOAT); - return(OK); -} - -/* ========================================================================== - * pthread_attr_getscope() - */ -int pthread_attr_getscope(pthread_attr_t *attr, int * contentionscope) -{ - *contentionscope = attr->flags & PTHREAD_SCOPE_SYSTEM; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setscope() - */ -int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) -{ - int ret; - - switch (contentionscope) { - case PTHREAD_SCOPE_PROCESS: - attr->flags = (attr->flags & ~(PTHREAD_SCOPE_PROCESS)) - | PTHREAD_SCOPE_PROCESS; - ret = OK; - break; - case PTHREAD_SCOPE_SYSTEM: - ret = ENOSYS; - break; - default: - ret = EINVAL; - break; - } - - return(ret); -} - -/* ========================================================================== - * pthread_attr_getinheritsched() - */ -int pthread_attr_getinheritsched(pthread_attr_t *attr, int * inheritsched) -{ - *inheritsched = attr->flags & PTHREAD_INHERIT_SCHED; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setinheritsched() - */ -int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) -{ - attr->flags = (attr->flags & ~(PTHREAD_INHERIT_SCHED)) | - (inheritsched & PTHREAD_INHERIT_SCHED); - return(OK); -} - -/* ========================================================================== - * pthread_attr_getschedpolicy() - */ -int pthread_attr_getschedpolicy(pthread_attr_t *attr, int * schedpolicy) -{ - *schedpolicy = (int)attr->schedparam_policy; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setschedpolicy() - */ -int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy) -{ - int ret; - - switch(schedpolicy) { - case SCHED_FIFO: - case SCHED_IO: - case SCHED_RR: - attr->schedparam_policy = schedpolicy; - ret = OK; - break; - default: - ret = EINVAL; - break; - } - return(ret); -} - -/* ========================================================================== - * pthread_attr_getschedparam() - */ -int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param * param) -{ - param->sched_priority = attr->sched_priority; - return(OK); -} - -/* ========================================================================== - * pthread_attr_setschedparam() - */ -int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param * param) -{ - if ((param->sched_priority >= PTHREAD_MIN_PRIORITY) && - (param->sched_priority <= PTHREAD_MAX_PRIORITY)) { - attr->sched_priority = param->sched_priority; - return(OK); - } - return(EINVAL); -} - diff --git a/mit-pthreads/pthreads/pthread_cancel.c b/mit-pthreads/pthreads/pthread_cancel.c deleted file mode 100644 index 4191a269027..00000000000 --- a/mit-pthreads/pthreads/pthread_cancel.c +++ /dev/null @@ -1,258 +0,0 @@ -/* ==== pthread_cancel.c ==================================================== - * Copyright (c) 1996 by Larry V. Streepy, Jr. - * 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 Larry V. Streepy, Jr. - * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``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 Larry V. Streepy, Jr. 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. - * - * Description : pthread_cancel operations - * - * 27 Sep 1996 - Larry V. Streepy, Jr. - * - Initial coding - */ -#ifndef lint -static const char rcsid[] = "$Id:"; -#endif -#include <pthread.h> -#include <errno.h> -static void possiblyMakeRunnable( pthread_t pthread ); - -/*---------------------------------------------------------------------- - * Function: pthread_cancel - * Purpose: Allows a thread to request that it or another thread - * terminate execution - * Args: - * thread = thread to mark as cancelled - * Returns: - * int 0 = ok, -1 = some error (see errno) - * Notes: - * The thread is simply marked as CANCELLED, it is up to the cancelled - * thread to decide how to handle it. - *----------------------------------------------------------------------*/ int -pthread_cancel( pthread_t pthread ) -{ - int rtn = 0; /* Assume all ok */ - pthread_sched_prevent(); - /* Ensure they gave us a legal pthread pointer */ - if( ! __pthread_is_valid( pthread ) ) { - rtn = ESRCH; /* No such thread */ - } else if( pthread->state == PS_UNALLOCED || pthread->state == PS_DEAD ) { - /* The standard doesn't call these out as errors, so return 0 */ - rtn = 0; - } else { - SET_PF_CANCELLED(pthread); /* Set the flag */ - /* If the thread is in the right state, then stick it on the - * run queue so it will get a chance to process the cancel. - */ - if( pthread != pthread_run ) { - possiblyMakeRunnable( pthread ); - } - } - pthread_sched_resume(); - if( rtn == 0 ) - pthread_testcancel(); /* See if we cancelled ourself */ - return rtn; -} - -/*---------------------------------------------------------------------- - * Function: pthread_setcancelstate - * Purpose: Set the current thread's cancellability state - * Args: - * state = PTHREAD_CANCEL_DISABLE or PTHREAD_CANCEL_ENABLE - * oldstate= pointer to holder for old state or NULL (*MODIFIED*) - * Returns: - * int 0 = ok - * EINVAL = state is neither of the legal states - * Notes: - * This has to be async-cancel safe, so we prevent scheduling in - * here - *----------------------------------------------------------------------*/ - -int -pthread_setcancelstate( int newstate, int *oldstate ) -{ - int ostate = TEST_PF_CANCEL_STATE(pthread_run); - int rtn = 0; - pthread_sched_prevent(); - if( newstate == PTHREAD_CANCEL_ENABLE || - newstate == PTHREAD_CANCEL_DISABLE ) { - SET_PF_CANCEL_STATE(pthread_run, newstate); - if( oldstate != NULL ) - *oldstate = ostate; - } else { /* Invalid new state */ - rtn = EINVAL; - } - pthread_sched_resume(); - if( rtn == 0 ) { - /* Test to see if we have a pending cancel to handle */ - pthread_testcancel(); - } - return rtn; -} - -/*---------------------------------------------------------------------- - * Function: pthread_setcanceltype - * Purpose: Set the current thread's cancellability type - * Args: - * type = PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS - * oldtype = pointer to holder for old type or NULL (*MODIFIED*) - * Returns: - * int 0 = ok - * EINVAL = type is neither of the legal states - * Notes: - * This has to be async-cancel safe, so we prevent scheduling in - * here - *----------------------------------------------------------------------*/ - -int -pthread_setcanceltype( int newtype, int *oldtype ) -{ - int otype = TEST_PF_CANCEL_TYPE(pthread_run); - int rtn = 0; - pthread_sched_prevent(); - if( newtype == PTHREAD_CANCEL_DEFERRED || - newtype == PTHREAD_CANCEL_ASYNCHRONOUS) { - SET_PF_CANCEL_TYPE(pthread_run, newtype); - if( oldtype != NULL ) - *oldtype = otype; - } else { /* Invalid new type */ - rtn = EINVAL; - } - pthread_sched_resume(); - if( rtn == 0 ) { - /* Test to see if we have a pending cancel to handle */ - pthread_testcancel(); - } - return rtn; -} - -/*---------------------------------------------------------------------- - * Function: pthread_testcancel - * Purpose: Requests delivery of a pending cancel to the current thread - * Args: void - * Returns: void - * Notes: - * If the current thread has been cancelled, this function will not - * return and the threads exit processing will be initiated. - *----------------------------------------------------------------------*/ - -void -pthread_testcancel( void ) -{ - if( TEST_PF_CANCEL_STATE(pthread_run) == PTHREAD_CANCEL_DISABLE ) { - return; /* Can't be cancelled */ - } - /* Ensure that we aren't in the process of exiting already */ - if( TEST_PF_RUNNING_TO_CANCEL(pthread_run) ) - return; - - /* See if we have been cancelled */ - if( TEST_PF_CANCELLED(pthread_run) ) { - /* Set this flag to avoid recursively calling pthread_exit */ - SET_PF_RUNNING_TO_CANCEL(pthread_run); - pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */ - } - return; /* Not cancelled */ -} - -/*---------------------------------------------------------------------- - * Function: pthread_cancel_internal - * Purpose: An internal routine to begin the cancel processing - * Args: freelocks = do we need to free locks before exiting - * Returns: void - * Notes: - * This routine is called from pthread_resched_resume - * prior to a context switch, and after a thread has resumed. - * - * The kernel must *NOT* be locked on entry here - *----------------------------------------------------------------------*/ - -void -pthread_cancel_internal( int freelocks ) -{ - pthread_sched_prevent(); /* gotta stay focused */ - /* Since we can be called from pthread_resched_resume(), our - * state is currently not PS_RUNNING. Since we side stepped - * the actually blocking, we need to be removed from the queue - * and marked as running. - */ - if( pthread_run->state != PS_RUNNING ) { - if( pthread_run->queue == NULL ) { - PANIC(); /* Must be on a queue */ - } - /* We MUST NOT put the thread on the prio_queue here. It - * is already running (although it's state has changed) and if we - * put it on the run queue, it will get resumed after it is dead - * and we end up with a nice panic. - */ - pthread_queue_remove(pthread_run->queue, pthread_run); - pthread_run->state = PS_RUNNING; /* we are running */ - } - /* Set this flag to avoid recursively calling pthread_exit */ - SET_PF_RUNNING_TO_CANCEL(pthread_run); - /* Free up any locks we hold if told to. */ - if( freelocks ) { - fd_unlock_for_cancel(); - } - pthread_sched_resume(); - pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */ -} - -/*---------------------------------------------------------------------- - * Function: possiblyMakeRunnable - * Purpose: Make a thread runnable so it can be cancelled if state allows - * Args: - * pthread = thread to process - * Returns: - * Notes: - *----------------------------------------------------------------------*/ - -static void -possiblyMakeRunnable( pthread_t pthread ) -{ - if( ! TEST_PTHREAD_IS_CANCELLABLE(pthread) ) - return; /* Not currently cancellable */ - /* If the thread is currently runnable, then we just let things - * take their course when it is next resumed. - */ - if( pthread->state == PS_RUNNING ) - return; /* will happen at context switch */ - /* If the thread is sleeping, the it isn't on a queue. */ - if( pthread->state == PS_SLEEP_WAIT ) { - sleep_cancel( pthread ); /* Remove from sleep list */ - } else { - /* Otherwise, we need to take it off the queue and make it runnable */ - if( pthread->queue == NULL ) { - PANIC(); /* Must be on a queue */ - } - pthread_queue_remove(pthread->queue, pthread); - } - /* And make it runnable */ - pthread_prio_queue_enq(pthread_current_prio_queue, pthread); - pthread->old_state = pthread->state; - pthread->state = PS_RUNNING; -} diff --git a/mit-pthreads/pthreads/pthread_detach.c b/mit-pthreads/pthreads/pthread_detach.c deleted file mode 100644 index d3ae8c03bb3..00000000000 --- a/mit-pthreads/pthreads/pthread_detach.c +++ /dev/null @@ -1,92 +0,0 @@ -/* ==== pthread_detach.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : pthread_join function. - * - * 1.00 94/01/15 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <errno.h> -#include <pthread.h> - -/* ========================================================================== - * pthread_detach() - */ -int pthread_detach(pthread_t pthread) -{ - struct pthread * next_thread, * high_thread, * low_thread; - int ret; - - pthread_sched_prevent(); - - /* Check that thread isn't detached already */ - if (!(pthread->attr.flags & PTHREAD_DETACHED)) { - - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Wakeup all threads waiting on a join */ - if (next_thread = pthread_queue_deq(&(pthread->join_queue))) { - high_thread = next_thread; - - while (next_thread = pthread_queue_deq(&(pthread->join_queue))) { - if (high_thread->pthread_priority < next_thread->pthread_priority) { - low_thread = high_thread; - high_thread = next_thread; - } else { - low_thread = next_thread; - } - pthread_prio_queue_enq(pthread_current_prio_queue, low_thread); - low_thread->state = PS_RUNNING; - } - /* If the thread is dead then move it to the alloc queue */ - if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) { - pthread_queue_enq(&pthread_alloc_queue, pthread); - } - pthread_sched_other_resume(high_thread); - return(OK); - } - /* If the thread is dead then move it to the alloc queue */ - if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) { - pthread_queue_enq(&pthread_alloc_queue, pthread); - pthread->state = PS_UNALLOCED; - } - ret = OK; - } else { - ret = ESRCH; - } - pthread_sched_resume(); - return(ret); -} diff --git a/mit-pthreads/pthreads/pthread_init.c b/mit-pthreads/pthreads/pthread_init.c deleted file mode 100644 index 83e19fe0229..00000000000 --- a/mit-pthreads/pthreads/pthread_init.c +++ /dev/null @@ -1,135 +0,0 @@ -/* ==== pthread_init.c ======================================================== - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread_init routine. - * - * 1.00 94/09/20 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <stdlib.h> -#include <string.h> - -/* - * errno is declared here to prevent the linker from pulling in errno - * from the C library (and whatever else is in that file). I also use - * errno as the default location for error numbers for the initial thread - * giving some backwards compatibility. - */ -#ifdef errno -#undef errno -#endif - -#if !defined(M_UNIX) -int errno; -#else -extern int errno; -#endif - -/* ========================================================================== - * pthread_init() - * - * We use features of the C++ linker to make sure this function is called - * before anything else is done in the program. See init.cc. - */ -void pthread_init(void) -{ - struct machdep_pthread machdep_data = MACHDEP_PTHREAD_INIT; - - /* Only call this once */ - if (pthread_initial) { - return; - } - - pthread_pagesize = getpagesize(); - - /* Initialize the first thread */ - if ((pthread_initial = (pthread_t)malloc(sizeof(struct pthread))) && - (pthread_current_prio_queue = (struct pthread_prio_queue *) - malloc(sizeof(struct pthread_prio_queue)))) { - memcpy(&(pthread_initial->machdep_data), &machdep_data, - sizeof(machdep_data)); - memcpy(&pthread_initial->attr, &pthread_attr_default, - sizeof(pthread_attr_t)); - - pthread_initial->pthread_priority = PTHREAD_DEFAULT_PRIORITY; - pthread_initial->state = PS_RUNNING; - - pthread_queue_init(&(pthread_initial->join_queue)); - pthread_initial->specific_data = NULL; - pthread_initial->specific_data_count = 0; - pthread_initial->cleanup = NULL; - pthread_initial->queue = NULL; - pthread_initial->next = NULL; - pthread_initial->flags = 0; - pthread_initial->pll = NULL; - pthread_initial->sll = NULL; - - /* PTHREADS spec says we start with cancellability on and deferred */ - SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE); - SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED); - - - /* Ugly errno hack */ - pthread_initial->error_p = &errno; - pthread_initial->error = 0; - - pthread_prio_queue_init(pthread_current_prio_queue); - pthread_link_list = pthread_initial; - pthread_run = pthread_initial; - - uthread_sigmask = &(pthread_run->sigmask); - - /* XXX can I assume the mask and pending siganl sets are empty. */ - sigemptyset(&(pthread_initial->sigpending)); - sigemptyset(&(pthread_initial->sigmask)); - pthread_initial->sigcount = 0; - - /* Initialize the signal handler. */ - sig_init(); - - /* Initialize the fd table. */ - fd_init(); - - /* Start the scheduler */ - machdep_set_thread_timer(&(pthread_run->machdep_data)); -#ifdef M_UNIX - machdep_sys_init(); -#endif - return; - } - PANIC(); -} diff --git a/mit-pthreads/pthreads/pthread_join.c b/mit-pthreads/pthreads/pthread_join.c deleted file mode 100644 index 879250020a1..00000000000 --- a/mit-pthreads/pthreads/pthread_join.c +++ /dev/null @@ -1,139 +0,0 @@ -/* ==== pthread_join.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : pthread_join function. - * - * 1.00 94/01/15 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> - -static int testDeadlock( struct pthread_queue *queue, pthread_t target ); - -/* ========================================================================== - * pthread_join() - */ -int pthread_join(pthread_t pthread, void **thread_return) -{ - int ret; - - pthread_sched_prevent(); - - /* Ensure they gave us a legal pthread pointer */ - if( ! __pthread_is_valid( pthread ) ) { - pthread_sched_resume(); - return(EINVAL); - } - - /* Check that thread isn't detached already */ - if (pthread->attr.flags & PTHREAD_DETACHED) { - pthread_sched_resume(); - return(ESRCH); - } - - /* - * Now check if other thread has exited - * Note: This must happen after checking detached state. - */ - if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) { - - /* Before we pend on the join, ensure there is no dead lock */ - - if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) { - ret = EDEADLK; - } else { - pthread_queue_enq(&(pthread->join_queue), pthread_run); - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - pthread_resched_resume(PS_JOIN); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - pthread_sched_prevent(); - - if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) { - pthread_queue_enq(&pthread_alloc_queue, pthread); - pthread->attr.flags |= PTHREAD_DETACHED; - pthread->state = PS_UNALLOCED; - if (thread_return) { - *thread_return = pthread->ret; - } - ret = OK; - } else { - ret = ESRCH; - } - } - } else { - /* Just get the return value and detach the thread */ - pthread_queue_enq(&pthread_alloc_queue, pthread); - pthread->attr.flags |= PTHREAD_DETACHED; - pthread->state = PS_UNALLOCED; - if (thread_return) { - *thread_return = pthread->ret; - } - ret = OK; - } - pthread_sched_resume(); - return(ret); -} - -/*---------------------------------------------------------------------- - * Function: testDeadlock - * Purpose: recursive queue walk to check for deadlocks - * Args: - * queue = the queue to walk - * pthread = target to scan for - * Returns: - * OK = no deadlock, NOTOK = deadlock - * Notes: - *----------------------------------------------------------------------*/ -static int -testDeadlock( struct pthread_queue *queue, pthread_t target ) -{ - pthread_t t; - - if( queue == NULL ) - return OK; /* Empty queue, obviously ok */ - - for( t = queue->q_next; t; t = t->next ) { - if( t == target ) - return NOTOK; /* bang, your dead */ - - if( testDeadlock( &t->join_queue, target ) == NOTOK ) { - return NOTOK; - } - } - - return OK; /* No deadlock */ -} diff --git a/mit-pthreads/pthreads/pthread_kill.c b/mit-pthreads/pthreads/pthread_kill.c deleted file mode 100644 index 9e3e61488a3..00000000000 --- a/mit-pthreads/pthreads/pthread_kill.c +++ /dev/null @@ -1,93 +0,0 @@ -/* ==== pthread_kill.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : pthread_kill function. - * - * 1.32 94/06/12 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* Defined in sig.c, a linked list of threads currently - * blocked in sigwait(): */ -extern struct pthread * pthread_sigwait; - - -/* ========================================================================== - * pthread_kill() - */ -int pthread_kill(struct pthread * pthread, int sig) -{ - struct pthread ** pthread_ptr; - - pthread_sched_prevent(); - - /* Check who is the current owner of pthread */ -/* if (pthread->kthread != pthread_run->kthread) { */ - if (0) { - } else { - if (pthread->state == PS_SIGWAIT) { - if(sigismember(pthread->data.sigwait, sig)) { - for (pthread_ptr = &pthread_sigwait; - (*pthread_ptr); - pthread_ptr = &((*pthread_ptr)->next)) { - if ((*pthread_ptr) == pthread) { - - /* Take the thread out of the - * pthread_sigwait linked list: */ - *pthread_ptr=(*pthread_ptr)->next; - - *(int *)(pthread->ret) = sig; - pthread_sched_other_resume(pthread); - return(OK); - } - } - /* A thread should not be in the state PS_SIGWAIT - * without being in the pthread_sigwait linked - * list: */ - PANIC(); - } - } - if (!sigismember(&pthread->sigpending,sig)) /* Added by monty */ - { - sigaddset(&(pthread->sigpending), sig); - pthread->sigcount++; - } - } - - pthread_sched_resume(); - return(OK); -} diff --git a/mit-pthreads/pthreads/pthread_once.c b/mit-pthreads/pthreads/pthread_once.c deleted file mode 100644 index 0a3dcd23fae..00000000000 --- a/mit-pthreads/pthreads/pthread_once.c +++ /dev/null @@ -1,59 +0,0 @@ -/* ==== pthread_once.c ======================================================= - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : pthread_once function. - * - * 1.00 93/12/12 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* ========================================================================== - * pthread_once() - */ -int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) -{ - /* Check first for speed */ - if (once_control->state == PTHREAD_NEEDS_INIT) { - pthread_mutex_lock(&(once_control->mutex)); - if (once_control->state == PTHREAD_NEEDS_INIT) { - init_routine(); - once_control->state = PTHREAD_DONE_INIT; - } - pthread_mutex_unlock(&(once_control->mutex)); - } - return(OK); -} diff --git a/mit-pthreads/pthreads/queue.c b/mit-pthreads/pthreads/queue.c deleted file mode 100644 index c33774bf4dd..00000000000 --- a/mit-pthreads/pthreads/queue.c +++ /dev/null @@ -1,143 +0,0 @@ -/* ==== queue.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Queue functions. - * - * 1.00 93/07/15 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> - -/* - * All routines in this file assume that the queue has been appropriatly - * locked. - */ - -/* ========================================================================== - * pthread_queue_init() - */ -void pthread_queue_init(struct pthread_queue *queue) -{ - queue->q_next = NULL; - queue->q_last = NULL; - queue->q_data = NULL; -} - -/* ========================================================================== - * pthread_queue_enq() - */ -void pthread_queue_enq(struct pthread_queue *queue, struct pthread *thread) -{ - if (queue->q_last) { - queue->q_last->next = thread; - } else { - queue->q_next = thread; - } - queue->q_last = thread; - thread->queue = queue; - thread->next = NULL; - -} - -/* ========================================================================== - * pthread_queue_get() - */ -struct pthread *pthread_queue_get(struct pthread_queue *queue) -{ - return(queue->q_next); -} - -/* ========================================================================== - * pthread_queue_deq() - */ -struct pthread *pthread_queue_deq(struct pthread_queue *queue) -{ - struct pthread *thread = NULL; - - if (queue->q_next) { - thread = queue->q_next; - if (!(queue->q_next = queue->q_next->next)) { - queue->q_last = NULL; - } - thread->queue = NULL; - thread->next = NULL; - } - return(thread); -} - -/* ========================================================================== - * pthread_queue_remove() - */ -int pthread_queue_remove(struct pthread_queue *queue, struct pthread *thread) -{ - struct pthread **current = &(queue->q_next); - struct pthread *prev = NULL; - int ret = NOTOK; - - while (*current) { - if (*current == thread) { - if ((*current)->next) { - *current = (*current)->next; - } else { - queue->q_last = prev; - *current = NULL; - } - thread->queue = NULL; - thread->next = NULL; - ret = OK; - break; - } - prev = *current; - current = &((*current)->next); - } - return(ret); -} - -/* ========================================================================== - * pthread_llist_remove() - */ -int pthread_llist_remove(struct pthread **llist, struct pthread *thread) -{ - while (*llist) { - if (*llist == thread) { - *llist = thread->next; - return(OK); - } - llist = &(*llist)->next; - } - return(NOTOK); -} - diff --git a/mit-pthreads/pthreads/readv.c b/mit-pthreads/pthreads/readv.c deleted file mode 100644 index fd63d31cf94..00000000000 --- a/mit-pthreads/pthreads/readv.c +++ /dev/null @@ -1,85 +0,0 @@ -/* ==== readv.c ============================================================ - * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Implementation of readv(). - * - * 1.00 95/06/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include "config.h" - -#ifndef HAVE_SYSCALL_READV - -#include <errno.h> -#include <unistd.h> -#include <sys/uio.h> -#include <sys/types.h> - -/* ========================================================================== - * machdep_sys_readv() - */ -int machdep_sys_readv(int fd, struct iovec * vector, int count) -{ - size_t bytes, i; - char *buffer; - int ret = 0; - - /* Find the total number of bytes to be read. */ - for (bytes = 0, i = 0; i < count; ++i) - bytes += vector[i].iov_len; - - if (bytes) { - /* - * Allocate a temporary buffer to hold the data. - * Don't use alloca because threads tend to have smaller stacks. - */ - if ((buffer = (char *)malloc(bytes)) == NULL) { - return(-ENOMEM); - } - ret = (int)machdep_sys_read(fd, buffer, bytes); - - /* Copy the data from memory specified by VECTOR to BUFFER */ - for (i = 0, bytes = 0; ret > 0; ret -= vector[i].iov_len) { - memcpy(vector[i].iov_base, buffer + bytes, - ret > vector[i].iov_len ? vector[i].iov_len : ret); - bytes += vector[i].iov_len; - } - free(buffer); - } - return(ret); -} - -#endif diff --git a/mit-pthreads/pthreads/schedparam.c b/mit-pthreads/pthreads/schedparam.c deleted file mode 100644 index b4b28577022..00000000000 --- a/mit-pthreads/pthreads/schedparam.c +++ /dev/null @@ -1,170 +0,0 @@ -/* ==== schedparam.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread schedparam functions. - * - * 1.38 94/06/15 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <sched.h> -#include <errno.h> - -/* ========================================================================== - * sched_get_priority_max - */ -int sched_get_priority_max(int policy) -{ - return PTHREAD_MAX_PRIORITY; -} - -/* ========================================================================== - * sched_get_priority_min - */ -int sched_get_priority_min(int policy) -{ - return PTHREAD_MIN_PRIORITY; -} - -/* Currently only policy is supported */ -/* ========================================================================== - * pthread_setschedparam() - */ -int pthread_setschedparam(pthread_t pthread, int policy, - struct sched_param * param) -{ - enum schedparam_policy new_policy, old_policy; - int ret = OK; - int prio; - - new_policy = policy; - pthread_sched_prevent(); - old_policy = pthread->attr.schedparam_policy; - - if (param) { - if ((param->sched_priority < PTHREAD_MIN_PRIORITY) || - (param->sched_priority > PTHREAD_MAX_PRIORITY)) { - pthread_sched_resume(); - return(EINVAL); - } - prio = param->sched_priority; - } else { - prio = pthread->pthread_priority; - } - - if (pthread == pthread_run) { - switch(new_policy) { - case SCHED_RR: - pthread->attr.schedparam_policy = new_policy; - switch (old_policy) { - case SCHED_FIFO: - machdep_unset_thread_timer(NULL); - default: - pthread->pthread_priority = prio; - break; - } - break; - case SCHED_FIFO: - pthread->attr.schedparam_policy = new_policy; - switch (old_policy) { - case SCHED_IO: - case SCHED_RR: - if (pthread->pthread_priority < prio) { - pthread->pthread_priority = prio; - pthread_sched_resume(); - pthread_yield(); - return(OK); - } - default: - pthread->pthread_priority = prio; - break; - } - break; - case SCHED_IO: - pthread->attr.schedparam_policy = new_policy; - switch (old_policy) { - case SCHED_FIFO: - machdep_unset_thread_timer(NULL); - default: - pthread->pthread_priority = prio; - break; - } - break; - default: - SET_ERRNO(EINVAL); - ret = EINVAL; - break; - } - } else { - switch(new_policy) { - case SCHED_FIFO: - case SCHED_IO: - case SCHED_RR: - if(pthread_prio_queue_remove(pthread_current_prio_queue,pthread) == OK) { - pthread->attr.schedparam_policy = new_policy; - pthread->pthread_priority = prio; - pthread_sched_other_resume(pthread); - } else { - pthread->attr.schedparam_policy = new_policy; - pthread->pthread_priority = prio; - pthread_sched_resume(); - } - return(OK); - break; - default: - SET_ERRNO(EINVAL); - ret = EINVAL; - break; - } - } - - pthread_sched_resume(); - return(ret); -} - -/* ========================================================================== - * pthread_getschedparam() - */ -int pthread_getschedparam(pthread_t pthread, int * policy, - struct sched_param * param) -{ - *policy = pthread->attr.schedparam_policy; - if (param) { - param->sched_priority = pthread->pthread_priority; - } - return(OK); -} - diff --git a/mit-pthreads/pthreads/select.c b/mit-pthreads/pthreads/select.c deleted file mode 100644 index eaafce31f19..00000000000 --- a/mit-pthreads/pthreads/select.c +++ /dev/null @@ -1,255 +0,0 @@ -/* ==== select.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * This code based on code contributed by - * Peter Hofmann <peterh@prz.tu-berlin.d400.de> - * - * Description : Select. - * - * 1.23 94/04/26 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <string.h> -#include <errno.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/time.h> - -extern struct pthread_queue fd_wait_select; -static struct timeval zero_timeout = { 0, 0 }; /* Moved by monty */ - -/* ========================================================================== - * select() - */ -int select(int numfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout) -{ - fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */ - fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p; - fd_set read_locks, write_locks, rdwr_locks; - struct timespec timeout_time, current_time; - int i, j, ret = 0, got_all_locks = 1; - struct pthread_select_data data; - - if (numfds > dtablesize) { - numfds = dtablesize; - } - - data.nfds = 0; - FD_ZERO(&data.readfds); - FD_ZERO(&data.writefds); - FD_ZERO(&data.exceptfds); - - /* Do this first */ - if (timeout) { - machdep_gettimeofday(¤t_time); - timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec; - if ((timeout_time.tv_nsec = current_time.tv_nsec + - (timeout->tv_usec * 1000)) > 1000000000) { - timeout_time.tv_nsec -= 1000000000; - timeout_time.tv_sec++; - } - } - - FD_ZERO(&read_locks); - FD_ZERO(&write_locks); - FD_ZERO(&rdwr_locks); - FD_ZERO(&real_readfds); - FD_ZERO(&real_writefds); - FD_ZERO(&real_exceptfds); - - /* lock readfds */ - if (readfds || writefds || exceptfds) { - for (i = 0; i < numfds; i++) { - if ((readfds && (FD_ISSET(i, readfds))) || - (exceptfds && FD_ISSET(i, exceptfds))) { - if (writefds && FD_ISSET(i ,writefds)) { - if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) { - got_all_locks = 0; - break; - } - FD_SET(i, &rdwr_locks); - FD_SET(fd_table[i]->fd.i,&real_writefds); - } else { - if ((ret = fd_lock(i, FD_READ, NULL)) != OK) { - got_all_locks = 0; - break; - } - FD_SET(i, &read_locks); - } - if (readfds && FD_ISSET(i,readfds)) { - FD_SET(fd_table[i]->fd.i, &real_readfds); - } - if (exceptfds && FD_ISSET(i,exceptfds)) { - FD_SET(fd_table[i]->fd.i, &real_exceptfds); - } - if (fd_table[i]->fd.i >= data.nfds) { - data.nfds = fd_table[i]->fd.i + 1; - } - } else { - if (writefds && FD_ISSET(i, writefds)) { - if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) { - got_all_locks = 0; - break; - } - FD_SET(i, &write_locks); - FD_SET(fd_table[i]->fd.i,&real_writefds); - if (fd_table[i]->fd.i >= data.nfds) { - data.nfds = fd_table[i]->fd.i + 1; - } - } - } - } - } - - if (got_all_locks) - { - memcpy(&data.readfds,&real_readfds,sizeof(fd_set)); - memcpy(&data.writefds,&real_writefds,sizeof(fd_set)); - memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set)); - - real_readfds_p = (readfds == NULL) ? NULL : &real_readfds; - real_writefds_p = (writefds == NULL) ? NULL : &real_writefds; - real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds; - - pthread_run->sighandled=0; - if ((ret = machdep_sys_select(data.nfds, real_readfds_p, - real_writefds_p, real_exceptfds_p, - &zero_timeout)) == OK) { - pthread_sched_prevent(); - - real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds; - real_writefds_p = (writefds == NULL) ? NULL : &data.writefds; - real_readfds_p = (readfds == NULL) ? NULL : &data.readfds; - - pthread_queue_enq(&fd_wait_select, pthread_run); - pthread_run->data.select_data = &data; - SET_PF_WAIT_EVENT(pthread_run); - - if (timeout) { - machdep_gettimeofday(¤t_time); - sleep_schedule(¤t_time, &timeout_time); - - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_SELECT_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - - /* We're awake */ - if (sleep_cancel(pthread_run) == NOTOK) { - ret = OK; - } - else - { - int count = 0; - for (i = 0; i < numfds; i++) - { - if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) - count++; - if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) - count++; - if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) - count++; - } - ret = count; - } - /* Moving this after the sleep_cancel() seemed - * to fix intermittent crashes during heavy - * socket use. (mevans) - */ - CLEAR_PF_DONE_EVENT(pthread_run); - } else { - int count = 0; - SET_PF_AT_CANCEL_POINT(pthread_run); - pthread_resched_resume(PS_SELECT_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); - CLEAR_PF_DONE_EVENT(pthread_run); - for (i = 0; i < numfds; i++) - { - if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) - count++; - if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) - count++; - if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) - count++; - } - ret = count; - } - if (pthread_run->sighandled) /* Added by monty */ - { /* We where aborted */ - ret= NOTOK; - SET_ERRNO(EINTR); - } - } else if (ret < 0) { - SET_ERRNO(-ret); - ret = NOTOK; - } - } - - /* clean up the locks */ - for (i = 0; i < numfds; i++) - { /* Changed by monty */ - if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ); - if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR); - if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE); - } - if (ret > 0) { - if (readfds != NULL) { - for (i = 0; i < numfds; i++) { - if (! (FD_ISSET(i,readfds) && - FD_ISSET(fd_table[i]->fd.i,real_readfds_p))) - FD_CLR(i,readfds); - } - } - if (writefds != NULL) { - for (i = 0; i < numfds; i++) - if (! (FD_ISSET(i,writefds) && - FD_ISSET(fd_table[i]->fd.i,real_writefds_p))) - FD_CLR(i,writefds); - } - if (exceptfds != NULL) { - for (i = 0; i < numfds; i++) - if (! (FD_ISSET(i,exceptfds) && - FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p))) - FD_CLR(i,exceptfds); - } - } else { - if (exceptfds != NULL) FD_ZERO(exceptfds); - if (writefds != NULL) FD_ZERO(writefds); - if (readfds != NULL) FD_ZERO(readfds); - } - - return(ret); -} diff --git a/mit-pthreads/pthreads/semaphore.c b/mit-pthreads/pthreads/semaphore.c deleted file mode 100644 index 0af54beca8a..00000000000 --- a/mit-pthreads/pthreads/semaphore.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - This is written by Sergei Golubchik for MySQL AB and is in public domain. - - Simple implementation of semaphores, needed to compile MySQL with - MIT-pthreads. -*/ - -#include <pthread.h> -#include <errno.h> -#include <semaphore.h> - -int sem_init(sem_t * sem, int pshared, uint value) -{ - sem->count=value; - pthread_cond_init(&sem->cond, 0); - pthread_mutex_init(&sem->mutex, 0); - return 0; -} - -int sem_destroy(sem_t * sem) -{ - int err1,err2; - err1=pthread_cond_destroy(&sem->cond); - err2=pthread_mutex_destroy(&sem->mutex); - if (err1 || err2) - { - errno=err1 ? err1 : err2; - return -1; - } - return 0; -} - -int sem_wait(sem_t * sem) -{ - if ((errno=pthread_mutex_lock(&sem->mutex))) - return -1; - while (!sem->count) - pthread_cond_wait(&sem->cond, &sem->mutex); - if (errno) - return -1; - sem->count--; /* mutex is locked here */ - pthread_mutex_unlock(&sem->mutex); - return 0; -} - -int sem_trywait(sem_t * sem) -{ - if ((errno=pthread_mutex_lock(&sem->mutex))) - return -1; - if (sem->count) - sem->count--; - else - errno=EAGAIN; - pthread_mutex_unlock(&sem->mutex); - return errno ? -1 : 0; -} - - -int sem_post(sem_t * sem) -{ - if ((errno=pthread_mutex_lock(&sem->mutex))) - return -1; - sem->count++; - pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */ - pthread_cond_signal(&sem->cond); /* first: x_unlock or x_signal ? */ - return 0; -} - -int sem_post_multiple(sem_t * sem, uint count) -{ - if ((errno=pthread_mutex_lock(&sem->mutex))) - return -1; - sem->count+=count; - pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */ - pthread_cond_broadcast(&sem->cond); /* first: x_unlock or x_broadcast ? */ - return 0; -} - -int sem_getvalue(sem_t * sem, uint *sval) -{ - if ((errno=pthread_mutex_lock(&sem->mutex))) - return -1; - *sval=sem->count; - pthread_mutex_unlock(&sem->mutex); - return 0; -} diff --git a/mit-pthreads/pthreads/sig.c b/mit-pthreads/pthreads/sig.c deleted file mode 100644 index 85d4465bf1c..00000000000 --- a/mit-pthreads/pthreads/sig.c +++ /dev/null @@ -1,452 +0,0 @@ -/* ==== sig.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : All the thread signal functions. - * - * 1.32 94/06/12 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <string.h> - -#if defined(M_UNIX) -#define signal(A,B) machdep_sys_signal((A),(B)) -#endif - -extern void sig_handler_real(); - -struct pthread * pthread_sigwait; -static sigset_t pending_signals; - -struct pthread_sigvec { - void (*vector)(); - sigset_t mask; - int flags; -} pthread_sigvec[SIGMAX]; - -/* ========================================================================== - * pthread_sig_register() - * - * Assumes the kernel is locked. - */ -int pthread_sig_register(int sig) -{ - struct pthread ** pthread_ptr, * pthread; - int ret; - - /* - * If we have a siginfo structure and the signal is synchronous then - * only deliver the signal to the current thread. - */ - - /* Check waiting threads for delivery */ - for (pthread_ptr = &pthread_sigwait; (*pthread_ptr); - pthread_ptr = &((*pthread_ptr)->next)) { - if (sigismember((*pthread_ptr)->data.sigwait, sig)) { - pthread=*pthread_ptr; - *pthread_ptr=(*pthread_ptr)->next; - - pthread_prio_queue_enq(pthread_current_prio_queue, pthread); - ret = pthread->pthread_priority; - *(int *)(pthread->ret) = sig; - pthread->state = PS_RUNNING; - - return(ret); - } - } - - /* Check current running thread */ - if (pthread_run) { - if (!sigismember(&pthread_run->sigmask, sig)) { - sigaddset(&pthread_run->sigpending, sig); - pthread_run->sigcount++; - return(0); - } - } - - /* Check any running thread */ - for (pthread = pthread_current_prio_queue->next; - pthread; pthread = pthread->next) { - if (!sigismember(&pthread->sigmask, sig)) { - sigaddset(&pthread->sigpending, sig); - pthread->sigcount++; - return(0); - } - } - - /* Check any thread */ - for (pthread = pthread_link_list; pthread; pthread = pthread->pll) { - if (!sigismember(&pthread->sigmask, sig)) { - sigaddset(&pthread->sigpending, sig); - pthread->sigcount++; - return(0); - } - } - - sigaddset(&pending_signals, sig); - return(0); -} - -/* ========================================================================== - * pthread_sig_default() - */ -void pthread_sig_default(int sig) -{ - sigset_t mask, omask; - - if (pthread_sigvec[sig].vector == SIG_DFL) { - /* Set the signal handler to default before issueing the kill */ - signal(sig, SIG_DFL); - kill(getpid(), sig); - sigemptyset(&mask); - sigaddset(&mask, sig); - machdep_sys_sigprocmask(SIG_UNBLOCK, &mask, &omask); - signal(sig, sig_handler_real); - } -} - -/* ========================================================================== - * pthread_sig_process() - * - * Assumes the kernel is locked. - */ -void pthread_sig_process() -{ - void (*vector)(); - int i, j; - - for (i = 1; i < SIGMAX; i++) { - if (sigismember(&(pthread_run->sigpending), i)) { - if (! sigismember(&(pthread_run->sigmask), i)) { - sigdelset(&(pthread_run->sigpending), i); - pthread_run->sigcount--; - - if (pthread_sigvec[i].vector == SIG_IGN) { - continue; - } - if (pthread_sigvec[i].vector == SIG_DFL) { - pthread_sig_default(i); - continue; - } - - { - sigset_t omask; - - sigemptyset(&omask); - /* Save old mask */ - for (j = 1; j < SIGMAX; j++) { - if (sigismember(&(pthread_run->sigmask), j)) { - if (sigismember(&(pthread_sigvec[i].mask), j)) - sigaddset(&(pthread_run->sigmask), j); - sigaddset(&omask, j); - } - } - /* The signal is masked while handling the signal */ - sigaddset(&(pthread_run->sigmask), i); - - /* - * Allow interrupts during a signal, - * but not a change in the vector - */ - vector = pthread_sigvec[i].vector; - if (--pthread_kernel_lock) { - PANIC(); - } - vector(i); - pthread_run->sighandled=1; /* Mark for select; Monty */ - pthread_kernel_lock++; - - memcpy(&(pthread_run->sigmask), &omask, sizeof(omask)); - } - } - } - } -} - -/* ========================================================================== - * pthread_sigmask() - * - * It is unclear wheather this call should be implemented as an atomic - * operation. The resulting mask could be wrong if in the signal - * handler the thread calls sigprocmask for any signal other than the - * signal the handler is dealing with. - */ -int pthread_sigmask(int how, const sigset_t *set, sigset_t * oset) -{ - int i; - - if (oset) { - sigemptyset(oset); - for (i = 1; i < SIGMAX; i++) { - if (sigismember(&(pthread_run->sigmask), i)) { - sigaddset(oset, i); - } - } - } - - if (set) { - switch(how) { - case SIG_BLOCK: - for (i = 1; i < SIGMAX; i++) { - if (sigismember(set, i)) { - sigaddset(&(pthread_run->sigmask), i); - } - } - break; - case SIG_UNBLOCK: - pthread_sched_prevent(); - for (i = 1; i < SIGMAX; i++) { - if (sigismember(set, i)) { - sigdelset(&(pthread_run->sigmask), i); - if (sigismember(&pending_signals, i)) { - sigaddset(&(pthread_run->sigpending), i); - sigdelset(&pending_signals, i); - pthread_run->sigcount++; - } - } - } - pthread_sched_resume(); - break; - case SIG_SETMASK: - sigfillset(&(pthread_run->sigmask)); - pthread_sched_prevent(); - for (i = 1; i < SIGMAX; i++) { - if (! sigismember(set, i)) { - sigdelset(&(pthread_run->sigmask), i); - if (sigismember(&pending_signals, i)) { - sigaddset(&(pthread_run->sigpending), i); - sigdelset(&pending_signals, i); - pthread_run->sigcount++; - } - } - } - pthread_sched_resume(); - break; - default: - SET_ERRNO(EINVAL); - return(NOTOK); - } - } - return(OK); -} - -int sigprocmask(int how, const sigset_t *set, sigset_t * oset) -{ - return(pthread_sigmask(how, set, oset)); -} - -/* ========================================================================== - * sigwait() - */ -int sigwait(const sigset_t * set, int * sig) -{ - int i; - - /* Check that sig is valid */ - *sig = 0; - - pthread_sched_prevent(); - for (i = 1; i < SIGMAX; i++) { - if (sigismember(set, i)) { - /* Check personal signals */ - if (sigismember(&(pthread_run->sigpending), i)) { - sigdelset(&(pthread_run->sigpending), i); - pthread_sched_resume(); - *sig = i; - return(OK); - } - /* Check kernel signals */ - if (sigismember(&pending_signals, i)) { - sigdelset(&pending_signals, i); - pthread_sched_resume(); - *sig = i; - return(OK); - } - } - } - - /* No pending signals, wait for one */ - pthread_run->next = pthread_sigwait; - pthread_sigwait = pthread_run; - pthread_run->data.sigwait = set; - pthread_run->ret = sig; - - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - pthread_resched_resume(PS_SIGWAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - - return(OK); -} - -/* ========================================================================== - * raise() - */ -int raise(int sig) -{ - return(pthread_kill(pthread_self(), sig)); -} - -/* ========================================================================== - * sigsuspend() - */ -int sigsuspend(const sigset_t * mask) -{ - int ret_sig, ret; - sigset_t nm, om; - - sigfillset(&nm); - for(ret_sig = 1; ret_sig < SIGMAX; ret_sig++) { - if (sigismember(mask, ret_sig)) { - sigdelset(&nm, ret_sig); - } - } - pthread_sigmask(SIG_BLOCK, &nm, &om); - if ((ret = sigwait(&nm, &ret_sig)) == OK) { - sigemptyset(&nm); - sigaddset(&nm, ret_sig); - pthread_kill(pthread_self(), ret_sig); - pthread_sigmask(SIG_UNBLOCK, &nm, NULL); - /* There is a race condition here, it's not worth worring about */ - pthread_sigmask(SIG_BLOCK, &nm, NULL); - SET_ERRNO(EINTR); - ret = NOTOK; - } - pthread_sigmask(SIG_SETMASK, &om, NULL); - return(ret); -} - -/* ========================================================================== - * pthread_signal() - */ -void (*pthread_signal(int sig, void (*dispatch)(int)))() -{ - void (*odispatch)(int); - - odispatch = pthread_sigvec[sig].vector; - if ((sig > 0) && (sig < SIGMAX)) { - pthread_sigvec[sig].vector = dispatch; - sigemptyset(&(pthread_sigvec[sig].mask)); - pthread_sigvec[sig].flags = 0; - } - return(odispatch); -} - -/* ========================================================================== - * pthread_sigprocmask() - */ -int pthread_sigaction(int sig, const struct sigaction * act, - struct sigaction * oact) -{ - if ((sig > 0) && (sig < SIGMAX)) { - if (oact) { - memcpy(&(oact->sa_mask), &(pthread_sigvec[sig].mask), - sizeof(sigset_t)); - oact->sa_handler = pthread_sigvec[sig].vector; - oact->sa_flags = pthread_sigvec[sig].flags; - } - if (act) { - memcpy(&(pthread_sigvec[sig].mask), &(act->sa_mask), - sizeof(sigset_t)); - pthread_sigvec[sig].vector = act->sa_handler; - pthread_sigvec[sig].flags = act->sa_flags; - } - return(OK); - } - SET_ERRNO(EINVAL); - return(NOTOK); -} - -/* - * The following here are stolen from BSD because I get mutiply defined - * symbols between sig.o and posix_sig.o in Sun's libc.a under Sunos 4.1.3. - * The problem is that sigprocmask() is defined in posix_sig.o, in the same - * module that a lot of other sigset-primitives are defined, and we have - * our definition of sigprocmask() here, but use those other primitives. - */ - -#undef sigemptyset -#undef sigfillset -#undef sigaddset -#undef sigdelset -#undef sigismember - -static const sigset_t __sigemptyset = __SIGEMPTYSET; -int sigemptyset(sigset_t *set) -{ - *set = __sigemptyset; - return (0); -} - -static const sigset_t __sigfillset = __SIGFILLSET; -int sigfillset(sigset_t * set) -{ - *set = __sigfillset; - return (0); -} - -#define _MAXIMUM_SIG NSIG - -int sigaddset(sigset_t *set, int signo) -{ - if (signo <= 0 || signo >= _MAXIMUM_SIG) { - errno = EINVAL; - return -1; - } - __SIGADDSET(set, signo); - return (0); -} - -int sigdelset(sigset_t *set, int signo) -{ - if (signo <= 0 || signo >= _MAXIMUM_SIG) { - errno = EINVAL; - return -1; - } - __SIGDELSET(set, signo); - return (0); -} - -int sigismember(const sigset_t *set, int signo) -{ - if (signo <= 0 || signo >= _MAXIMUM_SIG) { - errno = EINVAL; - return -1; - } - return(__SIGISMEMBER(set, signo)); -} - diff --git a/mit-pthreads/pthreads/signal.c b/mit-pthreads/pthreads/signal.c deleted file mode 100644 index 7da4183c1cb..00000000000 --- a/mit-pthreads/pthreads/signal.c +++ /dev/null @@ -1,653 +0,0 @@ -/* ==== signal.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Queue functions. - * - * 1.00 93/07/21 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <config.h> -#include <pthread.h> -#include <signal.h> - -/* This will force init.o to get dragged in; if you've got support for - C++ initialization, that'll cause pthread_init to be called at - program startup automatically, so the application won't need to - call it explicitly. */ - -extern char __pthread_init_hack; -char *__pthread_init_hack_2 = &__pthread_init_hack; - -/* - * Time which select in fd_kern_wait() will sleep. - * If there are no threads to run we sleep for an hour or until - * we get an interrupt or an fd thats awakens. To make sure we - * don't miss an interrupt this variable gets reset too zero in - * sig_handler_real(). - */ -struct timeval __fd_kern_wait_timeout = { 0, 0 }; - -/* - * Global for user-kernel lock, and blocked signals - */ - -static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, }; -volatile sig_atomic_t sig_to_process = 0; - -/* static volatile sigset_t sig_to_process; */ -static volatile int sig_count = 0; - -static void sig_handler(int signal); -static void set_thread_timer(); -static void __cleanup_after_resume( void ); -void sig_prevent(void); -void sig_resume(void); - -/* ========================================================================== - * context_switch() - * - * This routine saves the current state of the running thread gets - * the next thread to run and restores it's state. To allow different - * processors to work with this routine, I allow the machdep_restore_state() - * to either return or have it return from machdep_save_state with a value - * other than 0, this is for implementations which use setjmp/longjmp. - */ -static void context_switch() -{ - struct pthread **current, *next, *last, **dead; - - if (pthread_run->state == PS_RUNNING) { - /* Put current thread back on the queue */ - pthread_prio_queue_enq(pthread_current_prio_queue, pthread_run); - } - - /* save floating point registers if necessary */ - if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) { - machdep_save_float_state(pthread_run); - } - /* save state of current thread */ - if (machdep_save_state()) { - return; - } - - last = pthread_run; - - /* Poll all fds */ - fd_kern_poll(); - -context_switch_reschedule:; - /* Are there any threads to run */ - if (pthread_run = pthread_prio_queue_deq(pthread_current_prio_queue)) { - /* restore floating point registers if necessary */ - if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) { - machdep_restore_float_state(); - } - uthread_sigmask = &(pthread_run->sigmask); - /* restore state of new current thread */ - machdep_restore_state(); - return; - } - - /* Are there any threads at all */ - for (next = pthread_link_list; next; next = next->pll) { - if ((next->state != PS_UNALLOCED) && (next->state != PS_DEAD)) { - sigset_t sig_to_block, oset; - - sigfillset(&sig_to_block); - - /* - * Check sig_to_process before calling fd_kern_wait, to handle - * things like zero timeouts to select() which would register - * a signal with the sig_handler_fake() call. - * - * This case should ignore SIGVTALRM - */ - machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset); - signum_to_process[SIGVTALRM] = 0; - if (sig_to_process) { - /* Process interrupts */ - /* - * XXX pthread_run should not be set! - * Places where it dumps core should be fixed to - * check for the existance of pthread_run --proven - */ - sig_handler(0); - } else { - machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); - /* - * Do a wait, timeout is set to a hour unless we get an - * intr. before the select in wich case it polls. - */ - fd_kern_wait(); - machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset); - /* Check for interrupts, but ignore SIGVTALR */ - signum_to_process[SIGVTALRM] = 0; - if (sig_to_process) { - /* Process interrupts */ - sig_handler(0); - } - } - machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); - goto context_switch_reschedule; - } - } - - /* There are no threads alive. */ - pthread_run = last; - exit(0); -} - -#if !defined(HAVE_SYSCALL_SIGSUSPEND) && defined(HAVE_SYSCALL_SIGPAUSE) - -/* ========================================================================== - * machdep_sys_sigsuspend() - */ -int machdep_sys_sigsuspend(sigset_t * set) -{ - return(machdep_sys_sigpause(* set)); -} - -#endif - -/* ========================================================================== - * sig_handler_pause() - * - * Wait until a signal is sent to the process. - */ -void sig_handler_pause() -{ - sigset_t sig_to_block, sig_to_pause, oset; - - sigfillset(&sig_to_block); - sigemptyset(&sig_to_pause); - machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset); -/* if (!(SIG_ANY(sig_to_process))) { */ - if (!sig_to_process) { - machdep_sys_sigsuspend(&sig_to_pause); - } - machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); -} - -/* ========================================================================== - * context_switch_done() - * - * This routine does all the things that are necessary after a context_switch() - * calls the machdep_restore_state(). DO NOT put this in the context_switch() - * routine because sometimes the machdep_restore_state() doesn't return - * to context_switch() but instead ends up in machdep_thread_start() or - * some such routine, which will need to call this routine and - * sig_check_and_resume(). - */ -void context_switch_done() -{ - /* sigdelset((sigset_t *)&sig_to_process, SIGVTALRM); */ - signum_to_process[SIGVTALRM] = 0; - set_thread_timer(); -} - -/* ========================================================================== - * set_thread_timer() - * - * Assums kernel is locked. - */ -static void set_thread_timer() -{ - static int last_sched_attr = SCHED_RR; - - switch (pthread_run->attr.schedparam_policy) { - case SCHED_RR: - machdep_set_thread_timer(&(pthread_run->machdep_data)); - break; - case SCHED_FIFO: - if (last_sched_attr != SCHED_FIFO) { - machdep_unset_thread_timer(NULL); - } - break; - case SCHED_IO: - if ((last_sched_attr != SCHED_IO) && (!sig_count)) { - machdep_set_thread_timer(&(pthread_run->machdep_data)); - } - break; - default: - machdep_set_thread_timer(&(pthread_run->machdep_data)); - break; - } - last_sched_attr = pthread_run->attr.schedparam_policy; -} - -/* ========================================================================== - * sigvtalrm() - */ -static inline void sigvtalrm() -{ - if (sig_count) { - sigset_t sigall, oset; - - sig_count = 0; - - /* Unblock all signals */ - sigemptyset(&sigall); - machdep_sys_sigprocmask(SIG_SETMASK, &sigall, &oset); - } - context_switch(); - context_switch_done(); -} - -/* ========================================================================== - * sigdefault() - */ -static inline void sigdefault(int sig) -{ - int ret; - - ret = pthread_sig_register(sig); - if (pthread_run && (ret > pthread_run->pthread_priority)) { - sigvtalrm(); - } -} - -/* ========================================================================== - * sig_handler_switch() - */ -static inline void sig_handler_switch(int sig) -{ - int ret; - - switch(sig) { - case 0: - break; - case SIGVTALRM: - sigvtalrm(); - break; - case SIGALRM: -/* sigdelset((sigset_t *)&sig_to_process, SIGALRM); */ - signum_to_process[SIGALRM] = 0; - switch (ret = sleep_wakeup()) { - default: - if (pthread_run && (ret > pthread_run->pthread_priority)) { - sigvtalrm(); - } - case 0: - break; - case NOTOK: - /* Do the registered action, no threads were sleeping */ - /* There is a timing window that gets - * here when no threads are on the - * sleep queue. This is a quick fix. - * The real problem is possibly related - * to heavy use of condition variables - * with time outs. - * (mevans) - *sigdefault(sig); - */ - break; - } - break; - case SIGCHLD: -/* sigdelset((sigset_t *)&sig_to_process, SIGCHLD); */ - signum_to_process[SIGCHLD] = 0; - switch (ret = wait_wakeup()) { - default: - if (pthread_run && (ret > pthread_run->pthread_priority)) { - sigvtalrm(); - } - case 0: - break; - case NOTOK: - /* Do the registered action, no threads were waiting */ - sigdefault(sig); - break; - } - break; - -#ifdef SIGINFO - case SIGINFO: - pthread_dump_info (); - /* Then fall through, invoking the application's - signal handler after printing our info out. - - I'm not convinced that this is right, but I'm not - 100% convinced that it is wrong, and this is how - Chris wants it done... */ -#endif - - default: - /* Do the registered action */ - if (!sigismember(uthread_sigmask, sig)) { - /* - * If the signal isn't masked by the last running thread and - * the signal behavior is default or ignore then we can - * execute it immediatly. --proven - */ - pthread_sig_default(sig); - } - signum_to_process[sig] = 0; - sigdefault(sig); - break; - } - -} - -/* ========================================================================== - * sig_handler() - * - * Process signal that just came in, plus any pending on the signal mask. - * All of these must be resolved. - * - * Assumes the kernel is locked. - */ -static void sig_handler(int sig) -{ - if (pthread_kernel_lock != 1) { - PANIC(); - } - - if (sig) { - sig_handler_switch(sig); - } - - while (sig_to_process) { - for (sig_to_process = 0, sig = 1; sig <= SIGMAX; sig++) { - if (signum_to_process[sig]) { - sig_handler_switch(sig); - } - } - } - - -/* - if (SIG_ANY(sig_to_process)) { - for (sig = 1; sig <= SIGMAX; sig++) { - if (sigismember((sigset_t *)&sig_to_process, sig)) { - goto sig_handler_top; - } - } - } -*/ -} - -/* ========================================================================== - * sig_handler_real() - * - * On a multi-processor this would need to use the test and set instruction - * otherwise the following will work. - */ -void sig_handler_real(int sig) -{ - /* - * Get around systems with BROKEN signal handlers. - * - * Some systems will reissue SIGCHLD if the handler explicitly - * clear the signal pending by either doing a wait() or - * ignoring the signal. - */ -#if defined BROKEN_SIGNALS - if (sig == SIGCHLD) { - sigignore(SIGCHLD); - signal(SIGCHLD, sig_handler_real); - } -#endif - - if (pthread_kernel_lock) { - /* sigaddset((sigset_t *)&sig_to_process, sig); */ - __fd_kern_wait_timeout.tv_sec = 0; - signum_to_process[sig] = 1; - sig_to_process = 1; - return; - } - pthread_kernel_lock++; - - sig_count++; - sig_handler(sig); - - /* Handle any signals the current thread might have just gotten */ - if (pthread_run && pthread_run->sigcount) { - pthread_sig_process(); - } - pthread_kernel_lock--; -} - -/* ========================================================================== - * sig_handler_fake() - */ -void sig_handler_fake(int sig) -{ - if (pthread_kernel_lock) { - /* sigaddset((sigset_t *)&sig_to_process, sig); */ - signum_to_process[sig] = 1; - sig_to_process = 1; - return; - } - pthread_kernel_lock++; - sig_handler(sig); - while (!(--pthread_kernel_lock)) { - if (sig_to_process) { - /* if (SIG_ANY(sig_to_process)) { */ - pthread_kernel_lock++; - sig_handler(0); - } else { - break; - } - } -} - -/* ========================================================================== - * __pthread_signal_delete(int sig) - * - * Assumes the kernel is locked. - */ -void __pthread_signal_delete(int sig) -{ - signum_to_process[sig] = 0; -} - -/* ========================================================================== - * pthread_sched_other_resume() - * - * Check if thread to be resumed is of higher priority and if so - * stop current thread and start new thread. - */ -pthread_sched_other_resume(struct pthread * pthread) -{ - pthread->state = PS_RUNNING; - pthread_prio_queue_enq(pthread_current_prio_queue, pthread); - - if (pthread->pthread_priority > pthread_run->pthread_priority) { - if (pthread_kernel_lock == 1) { - sig_handler(SIGVTALRM); - } - } - - __cleanup_after_resume(); -} - -/* ========================================================================== - * pthread_resched_resume() - * - * This routine assumes that the caller is the current pthread, pthread_run - * and that it has a lock the kernel thread and it wants to reschedule itself. - */ -void pthread_resched_resume(enum pthread_state state) -{ - pthread_run->state = state; - - /* Since we are about to block this thread, lets see if we are - * at a cancel point and if we've been cancelled. - * Avoid cancelling dead or unalloced threads. - */ - if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) && - TEST_PTHREAD_IS_CANCELLABLE(pthread_run) && - state != PS_DEAD && state != PS_UNALLOCED ) { - - /* Set this flag to avoid recursively calling pthread_exit */ - /* We have to set this flag here because we will unlock the - * kernel prior to calling pthread_cancel_internal. - */ - SET_PF_RUNNING_TO_CANCEL(pthread_run); - - pthread_run->old_state = state; /* unlock needs this data */ - pthread_sched_resume(); /* Unlock kernel before cancel */ - pthread_cancel_internal( 1 ); /* free locks and exit */ - } - - sig_handler(SIGVTALRM); - - __cleanup_after_resume(); -} - -/* ========================================================================== - * pthread_sched_resume() - */ -void pthread_sched_resume() -{ - __cleanup_after_resume(); -} - -/*---------------------------------------------------------------------- - * Function: __cleanup_after_resume - * Purpose: cleanup kernel locks after a resume - * Args: void - * Returns: void - * Notes: - *----------------------------------------------------------------------*/ -static void -__cleanup_after_resume( void ) -{ - /* Only bother if we are truely unlocking the kernel */ - while (!(--pthread_kernel_lock)) { - /* if (SIG_ANY(sig_to_process)) { */ - if (sig_to_process) { - pthread_kernel_lock++; - sig_handler(0); - continue; - } - if (pthread_run && pthread_run->sigcount) { - pthread_kernel_lock++; - pthread_sig_process(); - continue; - } - break; - } - - if( pthread_run == NULL ) - return; /* Must be during init processing */ - - /* Test for cancel that should be handled now */ - - if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) && - TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) { - /* Kernel is already unlocked */ - pthread_cancel_internal( 1 ); /* free locks and exit */ - } -} - -/* ========================================================================== - * pthread_sched_prevent() - */ -void pthread_sched_prevent(void) -{ - pthread_kernel_lock++; -} - -/* ========================================================================== - * sig_init() - * - * SIGVTALRM (NOT POSIX) needed for thread timeslice timeouts. - * Since it's not POSIX I will replace it with a - * virtual timer for threads. - * SIGALRM (IS POSIX) so some special handling will be - * necessary to fake SIGALRM signals - */ -#ifndef SIGINFO -#define SIGINFO 0 -#endif -void sig_init(void) -{ - static const int signum_to_initialize[] = - { SIGCHLD, SIGALRM, SIGVTALRM, SIGINFO, 0 }; - static const int signum_to_ignore[] = { SIGKILL, SIGSTOP, 0 }; - int i, j; - -#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION) - struct sigaction act; - - act.sa_handler = sig_handler_real; - sigemptyset(&(act.sa_mask)); - act.sa_flags = 0; -#endif - - /* Initialize the important signals */ - for (i = 0; signum_to_initialize[i]; i++) { - -#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION) - if (sigaction(signum_to_initialize[i], &act, NULL)) { -#else - if (signal(signum_to_initialize[i], sig_handler_real)) { -#endif - PANIC(); - } - } - - /* Initialize the rest of the signals */ - for (j = 1; j < SIGMAX; j++) { - for (i = 0; signum_to_initialize[i]; i++) { - if (signum_to_initialize[i] == j) { - goto sig_next; - } - } - /* Because Solaris 2.4 can't deal -- proven */ - for (i = 0; signum_to_ignore[i]; i++) { - if (signum_to_ignore[i] == j) { - goto sig_next; - } - } - pthread_signal(j, SIG_DFL); - -#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION) - sigaction(j, &act, NULL); -#else - signal(j, sig_handler_real); -#endif - - sig_next:; - } - -#if defined BROKEN_SIGNALS - signal(SIGCHLD, sig_handler_real); -#endif - -} - diff --git a/mit-pthreads/pthreads/sleep.c b/mit-pthreads/pthreads/sleep.c deleted file mode 100644 index 1c13dd2eb1d..00000000000 --- a/mit-pthreads/pthreads/sleep.c +++ /dev/null @@ -1,367 +0,0 @@ -/* ==== sleep.c ============================================================ - * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : All the appropriate sleep routines. - * - * 1.00 93/12/28 proven - * -Started coding this file. - * - * 1.36 94/06/04 proven - * -Use new timer structure pthread_timer, that uses seconds - * -nano seconds. Rewrite all routines completely. - * - * 1.38 94/06/13 proven - * -switch pthread_timer to timespec - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <stdio.h> -#include <errno.h> -#include <sys/time.h> -#include <signal.h> -#include <unistd.h> -#include <sys/compat.h> - -struct pthread * pthread_sleep = NULL; - -/* ========================================================================== - * sleep_compare_time() - */ -/* static inline int sleep_compare_time(struct timespec * time1, - struct timespec * time2) */ -static int sleep_compare_time(struct timespec * time1, struct timespec * time2) -{ - if ((time1->tv_sec < time2->tv_sec) || - ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec < time2->tv_nsec))) { - return(-1); - } - if ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec == time2->tv_nsec)){ - return(0); - } - return(1); -} - -/* ========================================================================== - * machdep_stop_timer() - * - * Returns the time left on the timer. - */ -static struct itimerval timestop = { { 0, 0 }, { 0, 0 } }; - -void machdep_stop_timer(struct timespec *current) -{ - struct itimerval timenow; - - setitimer(ITIMER_REAL, & timestop, & timenow); - __pthread_signal_delete(SIGALRM); - if (current) { - current->tv_nsec = timenow.it_value.tv_usec * 1000; - current->tv_sec = timenow.it_value.tv_sec; - } -} - -/* ========================================================================== - * machdep_start_timer() - */ -int machdep_start_timer(struct timespec *current, struct timespec *wakeup) -{ - struct itimerval timeout; - - timeout.it_value.tv_usec = (wakeup->tv_nsec - current->tv_nsec) / 1000; - timeout.it_value.tv_sec = wakeup->tv_sec - current->tv_sec; - timeout.it_interval.tv_usec = 0; - timeout.it_interval.tv_sec = 0; - if (timeout.it_value.tv_usec < 0) { - timeout.it_value.tv_usec += 1000000; - timeout.it_value.tv_sec--; - } - - if (((long) timeout.it_value.tv_sec >= 0) && - ((timeout.it_value.tv_usec) || (timeout.it_value.tv_sec))) { - if (setitimer(ITIMER_REAL, & timeout, NULL) < 0) - { - fprintf(stderr,"Got error %d from setitimer with:\n\ - wakeup: tv_sec: %ld tv_nsec: %ld\n\ - current: tv_sec: %ld tv_nsec: %ld\n\ - argument: tv_sec: %ld tv_usec: %ld\n", - errno, - wakeup->tv_sec, wakeup->tv_nsec, - current->tv_sec, current->tv_nsec, - timeout.it_value.tv_sec, timeout.it_value.tv_usec); - PANIC(); - } - } else { - /* - * There is no time on the timer. - * This shouldn't happen, - * but isn't fatal. - */ - sig_handler_fake(SIGALRM); - } - return(OK); -} - -/* ========================================================================== - * sleep_schedule() - * - * Assumes that the current thread is the thread to be scheduled - * and that the kthread is already locked. - */ -void sleep_schedule(struct timespec *current_time, struct timespec *new_time) -{ - struct pthread * pthread_sleep_current, * pthread_sleep_prev; - - /* Record the new time as the current thread's wakeup time. */ - pthread_run->wakeup_time = *new_time; - - /* any threads? */ - if (pthread_sleep_current = pthread_sleep) { - if (sleep_compare_time(&(pthread_sleep_current->wakeup_time), - new_time) <= 0) { - /* Don't need to restart timer */ - while (pthread_sleep_current->sll) { - - pthread_sleep_prev = pthread_sleep_current; - pthread_sleep_current = pthread_sleep_current->sll; - - if (sleep_compare_time(&(pthread_sleep_current->wakeup_time), - new_time) > 0) { - pthread_run->sll = pthread_sleep_current; - pthread_sleep_prev->sll = pthread_run; - return; - } - } - - /* No more threads in queue, attach pthread_run to end of list */ - pthread_sleep_current->sll = pthread_run; - pthread_run->sll = NULL; - - } else { - /* Start timer and enqueue thread */ - machdep_start_timer(current_time, new_time); - pthread_run->sll = pthread_sleep_current; - pthread_sleep = pthread_run; - } - } else { - /* Start timer and enqueue thread */ - machdep_start_timer(current_time, new_time); - pthread_sleep = pthread_run; - pthread_run->sll = NULL; - } -} - -/* ========================================================================== - * sleep_wakeup() - * - * This routine is called by the interrupt handler, which has already - * locked the current kthread. Since all threads on this list are owned - * by the current kthread, rescheduling won't be a problem. - */ -int sleep_spurious_wakeup = 0; -int sleep_wakeup() -{ - struct pthread *pthread_sleep_next; - struct timespec current_time; - int ret = 0; - - if (pthread_sleep == NULL) { - return(NOTOK); - } - - machdep_gettimeofday(¤t_time); - if (sleep_compare_time(&(pthread_sleep->wakeup_time), ¤t_time) > 0) { - machdep_start_timer(¤t_time, &(pthread_sleep->wakeup_time)); - sleep_spurious_wakeup++; - return(OK); - } - - do { - if (pthread_sleep->pthread_priority > ret) { - ret = pthread_sleep->pthread_priority; - } - - /* - * Clean up removed thread and start it running again. - * - * Note: It is VERY important to remove the thread form the - * current queue before putting it on the run queue. - * Both queues use pthread_sleep->next, and the thread that points - * to pthread_sleep should point to pthread_sleep->next then - * pthread_sleep should be put on the run queue. - */ - if ((SET_PF_DONE_EVENT(pthread_sleep)) == OK) { - if (pthread_sleep->queue) - pthread_queue_remove(pthread_sleep->queue, pthread_sleep); - pthread_prio_queue_enq(pthread_current_prio_queue, pthread_sleep); - pthread_sleep->state = PS_RUNNING; - } - - pthread_sleep_next = pthread_sleep->sll; - pthread_sleep->sll = NULL; - - if ((pthread_sleep = pthread_sleep_next) == NULL) { - /* No more threads on sleep queue */ - return(ret); - } - } while (sleep_compare_time(&(pthread_sleep->wakeup_time), &(current_time)) <= 0); - - /* Start timer for next time interval */ - machdep_start_timer(¤t_time, &(pthread_sleep->wakeup_time)); - return(ret); -} - - -/* ========================================================================== - * __sleep() - */ -void __sleep(struct timespec * time_to_sleep) -{ - struct pthread *pthread_sleep_prev; - struct timespec current_time, wakeup_time; - - pthread_sched_prevent(); - - /* Get real time */ - machdep_gettimeofday(¤t_time); - wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec; - wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec; - - sleep_schedule(¤t_time, &wakeup_time); - - /* Reschedule thread */ - SET_PF_WAIT_EVENT(pthread_run); - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - pthread_resched_resume(PS_SLEEP_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - CLEAR_PF_DONE_EVENT(pthread_run); - - /* Return actual time slept */ - time_to_sleep->tv_sec = pthread_run->wakeup_time.tv_sec; - time_to_sleep->tv_nsec = pthread_run->wakeup_time.tv_nsec; -} - -/* ========================================================================== - * pthread_nanosleep() - */ -unsigned int pthread_nanosleep(unsigned int nseconds) -{ - struct timespec time_to_sleep; - - if (nseconds) { - time_to_sleep.tv_nsec = nseconds; - time_to_sleep.tv_sec = 0; - __sleep(&time_to_sleep); - nseconds = time_to_sleep.tv_nsec; - } - return(nseconds); -} - -/* ========================================================================== - * usleep() - */ -void usleep(unsigned int useconds) -{ - struct timespec time_to_sleep; - - if (useconds) { - time_to_sleep.tv_nsec = (useconds % 1000000) * 1000; - time_to_sleep.tv_sec = useconds / 1000000; - __sleep(&time_to_sleep); - } -} - -/* ========================================================================== - * sleep() - */ -unsigned int sleep(unsigned int seconds) -{ - struct timespec time_to_sleep; - - if (seconds) { - time_to_sleep.tv_sec = seconds; - time_to_sleep.tv_nsec = 0; - __sleep(&time_to_sleep); - seconds = time_to_sleep.tv_sec; - } - return(seconds); -} - -/* ========================================================================== - * sleep_cancel() - * - * Cannot be called while kernel is locked. - * Does not wake sleeping thread up, just remove it from the sleep queue. - */ -int sleep_cancel(struct pthread * pthread) -{ - struct timespec current_time, delta_time; - struct pthread * pthread_last; - int rval = NOTOK; - - /* Lock sleep queue, Note this may be on a different kthread queue */ - pthread_sched_prevent(); - - if (pthread_sleep) { - if (pthread == pthread_sleep) { - rval = OK; - machdep_stop_timer(&delta_time); - if (pthread_sleep = pthread_sleep->sll) { - current_time.tv_sec = delta_time.tv_sec; - current_time.tv_nsec = delta_time.tv_nsec; - current_time.tv_sec += pthread_sleep->wakeup_time.tv_sec; - current_time.tv_nsec += pthread_sleep->wakeup_time.tv_nsec; - while (current_time.tv_nsec > 1000000000) { - current_time.tv_nsec -= 1000000000; - current_time.tv_sec++; - } - machdep_start_timer(&(current_time), - &(pthread_sleep->wakeup_time)); - } - } else { - for (pthread_last = pthread_sleep; pthread_last; - pthread_last = pthread_last->sll) { - if (pthread_last->sll == pthread) { - pthread_last->sll = pthread->sll; - rval = OK; - break; - } - } - } - } - - pthread_sched_resume(); - pthread->sll = NULL; - return(rval); -} diff --git a/mit-pthreads/pthreads/specific.c b/mit-pthreads/pthreads/specific.c deleted file mode 100644 index 898f9b0cd1b..00000000000 --- a/mit-pthreads/pthreads/specific.c +++ /dev/null @@ -1,198 +0,0 @@ -/* ==== specific.c ======================================================= - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Pthread thread specific data management. - * - * 1.20 94/03/30 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <errno.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> - -static struct pthread_key key_table[PTHREAD_DATAKEYS_MAX]; -static pthread_mutex_t key_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* ========================================================================== - * pthread_key_create() - */ -int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)) -{ - pthread_mutex_lock(&key_mutex); - for ((*key) = 0; (*key) < PTHREAD_DATAKEYS_MAX; (*key)++) { - if (key_table[(*key)].count == 0) { - key_table[(*key)].count++; - key_table[(*key)].destructor = destructor; - pthread_mutex_init(&(key_table[(*key)].mutex), NULL); - pthread_mutex_unlock(&key_mutex); - return(OK); - } - } - pthread_mutex_unlock(&key_mutex); - return(EAGAIN); -} - -/* ========================================================================== - * pthread_key_delete() - */ -int pthread_key_delete(pthread_key_t key) -{ - int ret; - - if (key < PTHREAD_DATAKEYS_MAX) { - pthread_mutex_lock(&(key_table[key].mutex)); - switch (key_table[key].count) { - case 1: - pthread_mutex_destroy(&(key_table[key].mutex)); - key_table[key].destructor = NULL; - key_table[key].count = 0; - case 0: - ret = OK; - break; - default: - ret = EBUSY; - } - pthread_mutex_unlock(&(key_table[key].mutex)); - } else { - ret = EINVAL; - } - return(ret); -} - -/* ========================================================================== - * pthread_cleanupspecific() - */ -void pthread_cleanupspecific(void) -{ - void * data; - int key; - int itr; - - pthread_mutex_lock(&key_mutex); - for (itr = 0; itr < _POSIX_THREAD_DESTRUTOR_ITERATIONS; itr++) { - for (key = 0; key < PTHREAD_DATAKEYS_MAX; key++) { - if (pthread_run->specific_data_count) { - if (pthread_run->specific_data[key]) { - data = (void *)pthread_run->specific_data[key]; - pthread_run->specific_data[key] = NULL; - pthread_run->specific_data_count--; - if (key_table[key].destructor) { - pthread_mutex_unlock(&key_mutex); - key_table[key].destructor(data); - pthread_mutex_lock(&key_mutex); - } - key_table[key].count--; - } - } else { - free(pthread_run->specific_data); - pthread_mutex_unlock(&key_mutex); - return; - } - } - } - free(pthread_run->specific_data); - pthread_mutex_unlock(&key_mutex); -} - -static inline const void ** pthread_key_allocate_data(void) -{ - const void ** new_data; - if(new_data = (const void**)malloc(sizeof(void *) * PTHREAD_DATAKEYS_MAX)) { - memset((void *)new_data, 0, sizeof(void *) * PTHREAD_DATAKEYS_MAX); - } - return(new_data); -} - -/* ========================================================================== - * pthread_setspecific() - */ -int pthread_setspecific(pthread_key_t key, const void * value) -{ - int ret; - - if ((pthread_run->specific_data) || - (pthread_run->specific_data = pthread_key_allocate_data())) { - if ((key < PTHREAD_DATAKEYS_MAX) && (key_table)) { - pthread_mutex_lock(&(key_table[key].mutex)); - if (key_table[key].count) { - if (pthread_run->specific_data[key] == NULL) { - if (value != NULL) { - pthread_run->specific_data_count++; - key_table[key].count++; - } - } else { - if (value == NULL) { - pthread_run->specific_data_count--; - key_table[key].count--; - } - } - pthread_run->specific_data[key] = value; - ret = OK; - } else { - ret = EINVAL; - } - pthread_mutex_unlock(&(key_table[key].mutex)); - } else { - ret = EINVAL; - } - } else { - ret = ENOMEM; - } - return(ret); -} - -/* ========================================================================== - * pthread_getspecific() - */ -void * pthread_getspecific(pthread_key_t key) -{ - void *ret; - - if ((pthread_run->specific_data) && (key < PTHREAD_DATAKEYS_MAX) - && (key_table)) { - pthread_mutex_lock(&(key_table[key].mutex)); - if (key_table[key].count) { - ret = (void *)pthread_run->specific_data[key]; - } else { - ret = NULL; - } - pthread_mutex_unlock(&(key_table[key].mutex)); - } else { - ret = NULL; - } - return(ret); -} diff --git a/mit-pthreads/pthreads/stat.c b/mit-pthreads/pthreads/stat.c deleted file mode 100644 index f18b7c6bd24..00000000000 --- a/mit-pthreads/pthreads/stat.c +++ /dev/null @@ -1,116 +0,0 @@ -/* ==== stat.c ============================================================ - * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : All the syscalls dealing with fds. - * - * 1.00 93/05/27 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <errno.h> - -struct stat; -struct statfs; - -/* ========================================================================== - * fstat() - * - * Might want to indirect this. - */ -int fstat(int fd, struct stat *buf) -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_READ); - } - return(ret); -} - -/* ========================================================================== - * stat() - */ -int stat(const char * path, struct stat * buf) -{ - int ret; - - if ((ret = machdep_sys_stat(path, buf)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - return(ret); - -} - -/* ========================================================================== - * lstat() - */ -int lstat(const char * path, struct stat * buf) -{ - int ret; - - if ((ret = machdep_sys_lstat(path, buf)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - return(ret); - -} - -#ifdef HAVE_SYSCALL_FSTATFS -/* ========================================================================== - * fstatfs() - * - * Might want to indirect this. - */ -int fstatfs(int fd, struct statfs *buf) -{ - int ret; - - if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { - if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) { - SET_ERRNO(-ret); - ret = NOTOK; - } - fd_unlock(fd, FD_READ); - } - return(ret); -} -#endif diff --git a/mit-pthreads/pthreads/wait.c b/mit-pthreads/pthreads/wait.c deleted file mode 100644 index 9f0418ca8a1..00000000000 --- a/mit-pthreads/pthreads/wait.c +++ /dev/null @@ -1,159 +0,0 @@ -/* ==== wait.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : All the appropriate wait routines. - * - * 1.38 94/06/13 proven - * -Started coding this file. - * - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <pthread.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <pthread/posix.h> -#include <sys/compat.h> -#include <sys/wait.h> - -/* This is an UGLY hack to get wait to compile, something better is needed. */ -/* #define _POSIX_SOURCE -#undef _POSIX_SOURCE -*/ - -struct pthread_queue wait_queue = { NULL, NULL, NULL }; -extern void sig_handler_real(); - -/* ========================================================================== - * wait_wakeup() - * - * This routine is called by the interrupt handler which has locked - * the current kthread semaphore. Since only threads owned by the - * current kthread can be queue here, no additional locks are necessary. - */ -int wait_wakeup() -{ - struct pthread *pthread; - int ret = 0; - - if (pthread = pthread_queue_deq(& wait_queue)) { - /* Wakeup all threads, and enqueue them on the run queue */ - do { - pthread->state = PS_RUNNING; - if (pthread->pthread_priority > ret) { - ret = pthread->pthread_priority; - } - pthread_prio_queue_enq(pthread_current_prio_queue, pthread); - } while (pthread = pthread_queue_deq(&wait_queue)); - return(ret); - } - return(NOTOK); -} - -/* ========================================================================== - * For the wait calls, it is important that the current kthread is locked - * before the apropriate wait syscall is preformed. This way we ensure - * that there is never a case where a thread is waiting for a child but - * missed the interrupt for that child. - * Patched by William S. Lear 1997-02-02 - */ - -/* ========================================================================== - * waitpid() - */ -pid_t waitpid(pid_t pid, int *status, int options) -{ - pid_t ret; - - pthread_sched_prevent(); - ret = machdep_sys_waitpid(pid, status, options | WNOHANG); - /* If we are not doing nohang, try again, else return immediately */ - if (!(options & WNOHANG)) { - while (ret == OK) { - /* Enqueue thread on wait queue */ - pthread_queue_enq(&wait_queue, pthread_run); - - /* reschedule unlocks scheduler */ - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - pthread_resched_resume(PS_WAIT_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - - pthread_sched_prevent(); - - ret = machdep_sys_waitpid(pid, status, options | WNOHANG); - } - } - pthread_sched_resume(); - return(ret); -} - -/* ========================================================================== - * wait3() - * Patched by Monty 1997-02-02 - */ -pid_t wait3(__WAIT_STATUS status, int options, void * rusage) -{ - semaphore * lock; - pid_t ret; - - pthread_sched_prevent(); - ret = machdep_sys_wait3(status, options | WNOHANG, rusage); - /* If we are not doing nohang, try again, else return immediately */ - if (!(options & WNOHANG)) { - while (ret == OK) { - /* Enqueue thread on wait queue */ - pthread_queue_enq(&wait_queue, pthread_run); - - /* reschedule unlocks scheduler */ - SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */ - pthread_resched_resume(PS_WAIT_WAIT); - CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */ - - pthread_sched_prevent(); - - machdep_sys_wait3(status, options | WNOHANG, rusage); - } - } - pthread_sched_resume(); - return(ret); -} - -/* ========================================================================== - * wait() - */ -pid_t wait(__WAIT_STATUS status) -{ - return(waitpid((pid_t)-1, (int *)status, 0)); -} diff --git a/mit-pthreads/pthreads/wrapper.c b/mit-pthreads/pthreads/wrapper.c deleted file mode 100644 index 6e3f4478fcf..00000000000 --- a/mit-pthreads/pthreads/wrapper.c +++ /dev/null @@ -1,149 +0,0 @@ -/* ==== wrapper.c ============================================================ - * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Wrapper functions for syscalls that only need errno redirected - * - * 1.4x 94/07/23 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include "config.h" -#include <pthread.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pthread/posix.h> - -/* ========================================================================== - * link() - */ -int link(const char * name1, const char * name2) -{ - int ret; - - if ((ret = machdep_sys_link(name1, name2)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - -/* ========================================================================== - * unlink() - */ -int unlink(const char * path) -{ - int ret; - - if ((ret = machdep_sys_unlink(path)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - -/* ========================================================================== - * chdir() - */ -int chdir(const char * path) -{ - int ret; - - if ((ret = machdep_sys_chdir(path)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - -/* ========================================================================== - * chmod() - */ -int chmod(const char * path, mode_t mode) -{ - int ret; - - if ((ret = machdep_sys_chmod(path, mode)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - -/* ========================================================================== - * chown() - */ -int chown(const char * path, uid_t owner, gid_t group) -{ - int ret; - - if ((ret = machdep_sys_chown(path, owner, group)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - -/* ========================================================================== - * rename() - */ -int rename(const char * name1, const char * name2) -{ - int ret; - - if ((ret = machdep_sys_rename(name1, name2)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} - - -/* ========================================================================== - * chroot() - */ - -#ifdef HAVE_SYSCALL_CHROOT -int chroot(const char * name) -{ - int ret; - - if ((ret = machdep_sys_chroot(name)) < OK) { - SET_ERRNO(-ret); - } - return(ret); - -} -#endif diff --git a/mit-pthreads/pthreads/writev.c b/mit-pthreads/pthreads/writev.c deleted file mode 100644 index 9823d5ad201..00000000000 --- a/mit-pthreads/pthreads/writev.c +++ /dev/null @@ -1,89 +0,0 @@ -/* ==== writev.c ============================================================ - * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu - * 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 Chris Provenzano. - * 4. The name of Chris Provenzano may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. - * - * Description : Implementation of writev(). - * - * 1.00 95/06/19 proven - * -Started coding this file. - */ - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include "config.h" - -#ifndef HAVE_SYSCALL_WRITEV - -#include <errno.h> -#include <unistd.h> -#include <sys/uio.h> -#include <sys/types.h> - -/* ========================================================================== - * machdep_sys_writev() - * - * modified from the GNU C Library posix/writev.c - */ -int machdep_sys_writev(int fd, struct iovec * vector, int count) -{ - size_t bytes, i; - char *buffer; - int ret; - - /* Find the total number of bytes to be written. */ - for (bytes = 0, i = 0; i < count; ++i) - bytes += vector[i].iov_len; - - if (bytes) { - /* - * Allocate a temporary buffer to hold the data. - * Don't use alloca because threads tend to have smaller stacks. - */ - if ((buffer = (char *)malloc(bytes)) == NULL) { - return(-ENOMEM); - } - /* Copy the data from memory specified by VECTOR to BUFFER */ - for (ret = 0, i = 0; i < count; ++i) { - memcpy(buffer + ret, vector[i].iov_base, vector[i].iov_len); - ret += vector[i].iov_len; - } - } else { - buffer = NULL; - } - - ret = (int)machdep_sys_write(fd, buffer, bytes); - if (buffer) - free(buffer); - return(ret); -} - -#endif |