mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-27 13:32:45 +00:00
Submitted by: John Birrell
uthreads update from the author.
This commit is contained in:
parent
3b576b3e5e
commit
c840cec7c5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=22315
@ -66,6 +66,19 @@
|
||||
/* #define _POSIX_THREAD_PROCESS_SHARED */
|
||||
#define _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
|
||||
/*
|
||||
* Flags for threads and thread attributes.
|
||||
*/
|
||||
#define PTHREAD_DETACHED 0x1
|
||||
#define PTHREAD_SCOPE_SYSTEM 0x2
|
||||
#define PTHREAD_INHERIT_SCHED 0x4
|
||||
#define PTHREAD_NOFLOAT 0x8
|
||||
|
||||
#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED
|
||||
#define PTHREAD_CREATE_JOINABLE 0
|
||||
#define PTHREAD_SCOPE_PROCESS 0
|
||||
#define PTHREAD_EXPLICIT_SCHED 0
|
||||
|
||||
/*
|
||||
* Forward structure definitions.
|
||||
*
|
||||
@ -127,8 +140,8 @@ struct pthread_once {
|
||||
/*
|
||||
* Default attribute arguments.
|
||||
*/
|
||||
#define pthread_condattr_default NULL
|
||||
#ifndef PTHREAD_KERNEL
|
||||
#define pthread_condattr_default NULL
|
||||
#define pthread_mutexattr_default NULL
|
||||
#define pthread_attr_default NULL
|
||||
#endif
|
||||
@ -162,7 +175,7 @@ int pthread_attr_setstacksize __P((pthread_attr_t *, size_t));
|
||||
int pthread_attr_setstackaddr __P((pthread_attr_t *, void *));
|
||||
int pthread_attr_setdetachstate __P((pthread_attr_t *, int));
|
||||
void pthread_cleanup_pop __P((int execute));
|
||||
int pthread_cleanup_push __P((void (*routine) (void *),
|
||||
void pthread_cleanup_push __P((void (*routine) (void *),
|
||||
void *routine_arg));
|
||||
int pthread_condattr_destroy __P((pthread_condattr_t *attr));
|
||||
int pthread_condattr_init __P((pthread_condattr_t *attr));
|
||||
|
@ -117,7 +117,7 @@ __ttyname_basic(int fd)
|
||||
|
||||
pthread_mutex_lock(&ttyname_lock);
|
||||
if (ttyname_init == 0) {
|
||||
if (pthread_keycreate(&ttyname_key, free)) {
|
||||
if (pthread_key_create(&ttyname_key, free)) {
|
||||
pthread_mutex_unlock(&ttyname_lock);
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -1109,12 +1109,10 @@ const time_t * const timep;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&localtime_mutex);
|
||||
if ((p_tm = pthread_getspecific(localtime_key)) != 0) {
|
||||
return(NULL);
|
||||
} else if (p_tm == NULL) {
|
||||
if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
|
||||
p_tm = pthread_getspecific(localtime_key);
|
||||
if (p_tm == NULL) {
|
||||
if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL)
|
||||
return(NULL);
|
||||
}
|
||||
pthread_setspecific(localtime_key, p_tm);
|
||||
}
|
||||
pthread_mutex_lock(&lcl_mutex);
|
||||
|
@ -11,7 +11,6 @@ SHLIB_MINOR= 0
|
||||
CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS
|
||||
CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
|
||||
AINC= -I${.CURDIR}/../libc/${MACHINE} -I${.CURDIR}/uthread
|
||||
CLEANFILES+=tags
|
||||
PRECIOUSLIB= yes
|
||||
|
||||
.include "${.CURDIR}/db/Makefile.inc"
|
||||
@ -38,13 +37,4 @@ CFLAGS+= -DYP
|
||||
.endif
|
||||
.include "${.CURDIR}/${MACHINE}/sys/Makefile.inc"
|
||||
|
||||
beforeinstall: tags
|
||||
${INSTALL} ${COPY} -o bin -g bin -m 444 tags /var/db/libc_r.tags
|
||||
|
||||
tags: ${SRCS}
|
||||
ctags ${.ALLSRC:M*.c}
|
||||
egrep -o "^ENTRY(.*)|^FUNC(.*)|^SYSCALL(.*)" ${.ALLSRC:M*.s} | \
|
||||
sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
|
||||
>> tags; sort -o tags tags
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -3,18 +3,18 @@
|
||||
# machine-independent net sources
|
||||
.PATH: ${.CURDIR}/../libc/${MACHINE}/net ${.CURDIR}/../libc/net
|
||||
|
||||
SRCS+= addr2ascii.c ascii2addr.c \
|
||||
SRCS+= addr2ascii.c ascii2addr.c base64.c \
|
||||
gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
|
||||
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
|
||||
getproto.c getprotoent.c getprotoname.c getservbyname.c \
|
||||
getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
|
||||
inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
|
||||
inet_net_ntop.c inet_net_pton.c inet_neta.c \
|
||||
inet_pton.c linkaddr.c map_v4v6.c nsap_addr.c \
|
||||
rcmd.c recv.c res_comp.c res_data.c res_debug.c \
|
||||
res_init.c res_mkquery.c res_query.c res_send.c send.c ether_addr.c \
|
||||
|
||||
# iso_addr.c
|
||||
# ns_addr.c ns_ntoa.c
|
||||
res_init.c res_mkquery.c res_query.c res_send.c res_stubs.c \
|
||||
send.c ether_addr.c \
|
||||
ns_addr.c ns_ntoa.c
|
||||
|
||||
# machine-dependent net sources
|
||||
.include "${.CURDIR}/../libc/${MACHINE}/net/Makefile.inc"
|
||||
|
@ -9,13 +9,20 @@ SRCS+= \
|
||||
uthread_accept.c \
|
||||
uthread_attr_destroy.c \
|
||||
uthread_attr_init.c \
|
||||
uthread_attr_getdetachstate.c \
|
||||
uthread_attr_getstackaddr.c \
|
||||
uthread_attr_getstacksize.c \
|
||||
uthread_attr_setcreatesuspend_np.c \
|
||||
uthread_attr_setdetachstate.c \
|
||||
uthread_attr_setstackaddr.c \
|
||||
uthread_attr_setstacksize.c \
|
||||
uthread_autoinit.cc \
|
||||
uthread_bind.c \
|
||||
uthread_clean.c \
|
||||
uthread_close.c \
|
||||
uthread_cond.c \
|
||||
uthread_condattr_destroy.c \
|
||||
uthread_condattr_init.c \
|
||||
uthread_connect.c \
|
||||
uthread_create.c \
|
||||
uthread_detach.c \
|
||||
@ -44,12 +51,14 @@ SRCS+= \
|
||||
uthread_ioctl.c \
|
||||
uthread_join.c \
|
||||
uthread_kern.c \
|
||||
uthread_kill.c \
|
||||
uthread_listen.c \
|
||||
uthread_longjmp.c \
|
||||
uthread_mattr_init.c \
|
||||
uthread_mattr_kind_np.c \
|
||||
uthread_multi_np.c \
|
||||
uthread_mutex.c \
|
||||
uthread_mutexattr_destroy.c \
|
||||
uthread_nanosleep.c \
|
||||
uthread_once.c \
|
||||
uthread_open.c \
|
||||
@ -71,6 +80,7 @@ SRCS+= \
|
||||
uthread_sigaction.c \
|
||||
uthread_sigblock.c \
|
||||
uthread_single_np.c \
|
||||
uthread_sigmask.c \
|
||||
uthread_signal.c \
|
||||
uthread_sigprocmask.c \
|
||||
uthread_sigsetmask.c \
|
||||
|
@ -58,6 +58,15 @@
|
||||
*/
|
||||
#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
|
||||
|
||||
/*
|
||||
* State change macro:
|
||||
*/
|
||||
#define PTHREAD_NEW_STATE(thrd, newstate) { \
|
||||
(thrd)->state = newstate; \
|
||||
(thrd)->fname = __FILE__; \
|
||||
(thrd)->lineno = __LINE__; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue definitions.
|
||||
*/
|
||||
@ -206,19 +215,6 @@ struct sched_param {
|
||||
*/
|
||||
#define TIMESLICE_USEC 100000
|
||||
|
||||
/*
|
||||
* Flags.
|
||||
*/
|
||||
#define PTHREAD_DETACHED 0x1
|
||||
#define PTHREAD_SCOPE_SYSTEM 0x2
|
||||
#define PTHREAD_INHERIT_SCHED 0x4
|
||||
#define PTHREAD_NOFLOAT 0x8
|
||||
|
||||
#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED
|
||||
#define PTHREAD_CREATE_JOINABLE 0
|
||||
#define PTHREAD_SCOPE_PROCESS 0
|
||||
#define PTHREAD_EXPLICIT_SCHED 0
|
||||
|
||||
struct pthread_key {
|
||||
pthread_mutex_t mutex;
|
||||
long count;
|
||||
@ -407,6 +403,15 @@ struct pthread {
|
||||
/* Wait data. */
|
||||
union pthread_wait_data data;
|
||||
|
||||
/*
|
||||
* Set to TRUE if a blocking operation was
|
||||
* interrupted by a signal:
|
||||
*/
|
||||
int interrupted;
|
||||
|
||||
/* Signal number when in state PS_SIGWAIT: */
|
||||
int signo;
|
||||
|
||||
/* Miscellaneous data. */
|
||||
char flags;
|
||||
char pthread_priority;
|
||||
@ -416,6 +421,8 @@ struct pthread {
|
||||
|
||||
/* Cleanup handlers Link List */
|
||||
struct pthread_cleanup *cleanup;
|
||||
char *fname; /* Ptr to source file name */
|
||||
int lineno; /* Source line number. */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -426,7 +433,7 @@ struct pthread {
|
||||
SCLASS struct pthread _thread_kern_thread;
|
||||
|
||||
/* Ptr to the thread structure for the running thread: */
|
||||
SCLASS struct pthread *_thread_run
|
||||
SCLASS struct pthread * volatile _thread_run
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= &_thread_kern_thread;
|
||||
#else
|
||||
@ -437,7 +444,7 @@ SCLASS struct pthread *_thread_run
|
||||
* Ptr to the thread running in single-threaded mode or NULL if
|
||||
* running multi-threaded (default POSIX behaviour).
|
||||
*/
|
||||
SCLASS struct pthread *_thread_single
|
||||
SCLASS struct pthread * volatile _thread_single
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -445,7 +452,7 @@ SCLASS struct pthread *_thread_single
|
||||
#endif
|
||||
|
||||
/* Ptr to the first thread in the thread linked list: */
|
||||
SCLASS struct pthread *_thread_link_list
|
||||
SCLASS struct pthread * volatile _thread_link_list
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -481,7 +488,7 @@ SCLASS struct timeval kern_inc_prio_time
|
||||
#endif
|
||||
|
||||
/* Dead threads: */
|
||||
SCLASS struct pthread *_thread_dead
|
||||
SCLASS struct pthread * volatile _thread_dead
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -505,7 +512,7 @@ SCLASS struct pthread_attr pthread_attr_default
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Default thread attributes: */
|
||||
/* Default mutex attributes: */
|
||||
SCLASS struct pthread_mutex_attr pthread_mutexattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { MUTEX_TYPE_FAST, 0 };
|
||||
@ -513,6 +520,21 @@ SCLASS struct pthread_mutex_attr pthread_mutexattr_default
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Default condition variable attributes: */
|
||||
SCLASS struct pthread_cond_attr pthread_condattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { COND_TYPE_FAST, 0 };
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard I/O file descriptors need special flag treatment since
|
||||
* setting one to non-blocking does all on *BSD. Sigh. This array
|
||||
* is used to store the initial flag settings.
|
||||
*/
|
||||
SCLASS int _pthread_stdio_flags[3];
|
||||
|
||||
/* File table information: */
|
||||
SCLASS struct fd_table_entry **_thread_fd_table
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
@ -558,7 +580,6 @@ void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
|
||||
void _thread_kern_set_timeout(struct timespec *);
|
||||
void _thread_kern_sig_block(int *);
|
||||
void _thread_kern_sig_unblock(int);
|
||||
void _thread_cleanup_pop(int);
|
||||
void _thread_sig_handler(int, int, struct sigcontext *);
|
||||
void _thread_start(void);
|
||||
void _thread_start_sig_handler(void);
|
||||
|
@ -44,7 +44,7 @@ accept(int fd, struct sockaddr * name, int *namelen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Lock teh file descriptor: */
|
||||
/* Lock the file descriptor: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) == 0) {
|
||||
/* Enter a loop to wait for a connection request: */
|
||||
while ((ret = _thread_sys_accept(fd, name, namelen)) < 0) {
|
||||
@ -52,6 +52,8 @@ accept(int fd, struct sockaddr * name, int *namelen)
|
||||
if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
/* Save the socket file descriptor: */
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_run->data.fd.fname = __FILE__;
|
||||
_thread_run->data.fd.branch = __LINE__;
|
||||
|
||||
/* Set the timeout: */
|
||||
_thread_kern_set_timeout(NULL);
|
||||
|
@ -39,11 +39,19 @@
|
||||
int pthread_attr_destroy(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL)
|
||||
/* Invalid argument: */
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Free the memory allocated to the attribute object: */
|
||||
free(*attr);
|
||||
|
||||
/*
|
||||
* Leave the attribute pointer NULL now that the memory
|
||||
* has been freed:
|
||||
*/
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
|
57
lib/libc_r/uthread/uthread_attr_getdetachstate.c
Normal file
57
lib/libc_r/uthread/uthread_attr_getdetachstate.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || detachstate == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if the detached flag is set: */
|
||||
if ((*attr)->flags & PTHREAD_DETACHED)
|
||||
/* Return detached: */
|
||||
*detachstate = PTHREAD_CREATE_DETACHED;
|
||||
else
|
||||
/* Return joinable: */
|
||||
*detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libc_r/uthread/uthread_attr_getstackaddr.c
Normal file
52
lib/libc_r/uthread/uthread_attr_getstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack address: */
|
||||
*stackaddr = (*attr)->stackaddr_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libc_r/uthread/uthread_attr_getstacksize.c
Normal file
52
lib/libc_r/uthread/uthread_attr_getstacksize.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack size: */
|
||||
*stacksize = (*attr)->stacksize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -41,11 +41,16 @@ int pthread_attr_init(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_attr_t pattr;
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Allocate memory for the attribute object: */
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
|
||||
/* Insufficient memory: */
|
||||
ret = ENOMEM;
|
||||
else {
|
||||
/* Initialise the attribute object with the defaults: */
|
||||
memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
|
||||
|
||||
/* Return a pointer to the attribute object: */
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
|
59
lib/libc_r/uthread/uthread_attr_setdetachstate.c
Normal file
59
lib/libc_r/uthread/uthread_attr_setdetachstate.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL ||
|
||||
(detachstate != PTHREAD_CREATE_DETACHED &&
|
||||
detachstate != PTHREAD_CREATE_JOINABLE))
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if detached state: */
|
||||
if (detachstate == PTHREAD_CREATE_DETACHED)
|
||||
/* Set the detached flag: */
|
||||
(*attr)->flags |= PTHREAD_DETACHED;
|
||||
else
|
||||
/* Reset the detached flag: */
|
||||
(*attr)->flags &= ~PTHREAD_DETACHED;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libc_r/uthread/uthread_attr_setstackaddr.c
Normal file
52
lib/libc_r/uthread/uthread_attr_setstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack address: */
|
||||
(*attr)->stackaddr_attr = stackaddr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -38,10 +38,12 @@
|
||||
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack size: */
|
||||
(*attr)->stacksize_attr = stacksize;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -37,11 +37,10 @@
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
_thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
void
|
||||
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))) != NULL) {
|
||||
new->routine = routine;
|
||||
@ -49,15 +48,11 @@ _thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
new->next = _thread_run->cleanup;
|
||||
|
||||
_thread_run->cleanup = new;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = ENOMEM;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
_thread_cleanup_pop(int execute)
|
||||
pthread_cleanup_pop(int execute)
|
||||
{
|
||||
struct pthread_cleanup *old;
|
||||
|
||||
|
@ -272,7 +272,7 @@ pthread_cond_signal(pthread_cond_t * cond)
|
||||
/* Bring the next thread off the condition queue: */
|
||||
if ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -309,7 +309,7 @@ pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
/* Enter a loop to bring all threads off the condition queue: */
|
||||
while ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
|
52
lib/libc_r/uthread/uthread_condattr_destroy.c
Normal file
52
lib/libc_r/uthread/uthread_condattr_destroy.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_condattr_destroy(pthread_condattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
free(*attr);
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
58
lib/libc_r/uthread/uthread_condattr_init.c
Normal file
58
lib/libc_r/uthread/uthread_condattr_init.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_condattr_init(pthread_condattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_condattr_t pattr;
|
||||
|
||||
if ((pattr = (pthread_condattr_t)
|
||||
malloc(sizeof(struct pthread_cond_attr))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
ret = -1;
|
||||
} else {
|
||||
memcpy(pattr, &pthread_condattr_default,
|
||||
sizeof(struct pthread_cond_attr));
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -87,9 +87,9 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr,
|
||||
new_thread->start_routine = start_routine;
|
||||
new_thread->arg = arg;
|
||||
if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
|
||||
new_thread->state = PS_SUSPENDED;
|
||||
PTHREAD_NEW_STATE(new_thread,PS_SUSPENDED);
|
||||
} else {
|
||||
new_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(new_thread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/* Initialise the thread for signals: */
|
||||
@ -208,7 +208,7 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr,
|
||||
* a signal handler thread which must now
|
||||
* wait for the signal handler to complete:
|
||||
*/
|
||||
parent->state = PS_SIGTHREAD;
|
||||
PTHREAD_NEW_STATE(parent,PS_SIGTHREAD);
|
||||
} else {
|
||||
/* Schedule the new user thread: */
|
||||
_thread_kern_sched(NULL);
|
||||
|
@ -49,7 +49,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
/* Check for invalid calling parameters: */
|
||||
if (p_pthread == NULL || (pthread = *p_pthread) == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
}
|
||||
/* Check if the thread has not been detached: */
|
||||
@ -60,7 +60,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
/* Enter a loop to bring all threads off the join queue: */
|
||||
while ((next_thread = _thread_queue_deq(&pthread->join_queue)) != NULL) {
|
||||
/* Make the thread run: */
|
||||
next_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -70,7 +70,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
*p_pthread = NULL;
|
||||
} else {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ pthread_exit(void *status)
|
||||
_thread_run->ret = status;
|
||||
|
||||
while (_thread_run->cleanup != NULL) {
|
||||
_thread_cleanup_pop(1);
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
|
||||
if (_thread_run->attr.cleanup_attr != NULL) {
|
||||
@ -123,7 +123,7 @@ pthread_exit(void *status)
|
||||
/* Check if there are any threads joined to this one: */
|
||||
while ((pthread = _thread_queue_deq(&(_thread_run->join_queue))) != NULL) {
|
||||
/* Wake the joined thread and let it detach this thread: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/* Check if the running thread is at the head of the linked list: */
|
||||
@ -173,11 +173,11 @@ pthread_exit(void *status)
|
||||
|
||||
/*
|
||||
* Check if the parent is not waiting on any other signal
|
||||
* handler threads:
|
||||
* handler threads and if it hasn't died in the meantime:
|
||||
*/
|
||||
if (pthread == NULL) {
|
||||
if (pthread == NULL && _thread_run->parent_thread->state != PS_DEAD) {
|
||||
/* Allow the parent thread to run again: */
|
||||
_thread_run->parent_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(_thread_run->parent_thread,PS_RUNNING);
|
||||
}
|
||||
/* Get the signal number: */
|
||||
l = (long) _thread_run->arg;
|
||||
|
@ -47,23 +47,26 @@ _thread_fd_table_init(int fd)
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Check if the file descriptor is out of range: */
|
||||
if (fd < 0 || fd >= _thread_dtablesize) {
|
||||
if (fd < 0 || fd >= _thread_dtablesize)
|
||||
/* Return a bad file descriptor error: */
|
||||
errno = EBADF;
|
||||
ret = -1;
|
||||
}
|
||||
ret = EBADF;
|
||||
|
||||
/*
|
||||
* Check if memory has already been allocated for this file
|
||||
* descriptor:
|
||||
*/
|
||||
else if (_thread_fd_table[fd] != NULL) {
|
||||
/* Memory has already been allocated. */
|
||||
}
|
||||
/* Allocate memory for the file descriptor table entry: */
|
||||
else if ((_thread_fd_table[fd] = (struct fd_table_entry *) malloc(sizeof(struct fd_table_entry))) == NULL) {
|
||||
else if ((_thread_fd_table[fd] = (struct fd_table_entry *)
|
||||
malloc(sizeof(struct fd_table_entry))) == NULL)
|
||||
/* Return a bad file descriptor error: */
|
||||
errno = EBADF;
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = EBADF;
|
||||
else {
|
||||
/* Assume that the operation will succeed: */
|
||||
ret = 0;
|
||||
|
||||
/* Initialise the file locks: */
|
||||
_thread_fd_table[fd]->r_owner = NULL;
|
||||
_thread_fd_table[fd]->w_owner = NULL;
|
||||
@ -79,16 +82,32 @@ _thread_fd_table_init(int fd)
|
||||
_thread_queue_init(&_thread_fd_table[fd]->w_queue);
|
||||
|
||||
/* Get the flags for the file: */
|
||||
if ((_thread_fd_table[fd]->flags = _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
|
||||
ret = -1;
|
||||
if (fd >= 3 && (_thread_fd_table[fd]->flags =
|
||||
_thread_sys_fcntl(fd, F_GETFL, 0)) == -1)
|
||||
ret = errno;
|
||||
|
||||
/* Make the file descriptor non-blocking: */
|
||||
} else {
|
||||
_thread_sys_fcntl(fd, F_SETFL, _thread_fd_table[fd]->flags | O_NONBLOCK);
|
||||
else {
|
||||
/* Check if a stdio descriptor: */
|
||||
if (fd < 3)
|
||||
/*
|
||||
* Use the stdio flags read by
|
||||
* _pthread_init() to avoid
|
||||
* mistaking the non-blocking
|
||||
* flag that, when set on one
|
||||
* stdio fd, is set on all stdio
|
||||
* fds.
|
||||
*/
|
||||
_thread_fd_table[fd]->flags =
|
||||
_pthread_stdio_flags[fd];
|
||||
|
||||
/* Make the file descriptor non-blocking: */
|
||||
if (_thread_sys_fcntl(fd, F_SETFL,
|
||||
_thread_fd_table[fd]->flags | O_NONBLOCK) == -1)
|
||||
ret = errno;
|
||||
}
|
||||
|
||||
/* Check if one of the fcntl calls failed: */
|
||||
if (ret == -1) {
|
||||
if (ret != 0) {
|
||||
/* Free the file descriptor table entry: */
|
||||
free(_thread_fd_table[fd]);
|
||||
_thread_fd_table[fd] = NULL;
|
||||
@ -143,7 +162,7 @@ _thread_fd_unlock(int fd, int lock_type)
|
||||
* Set the state of the new owner of
|
||||
* the thread to running:
|
||||
*/
|
||||
_thread_fd_table[fd]->r_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
|
||||
|
||||
/*
|
||||
* Reset the number of read locks.
|
||||
@ -181,7 +200,7 @@ _thread_fd_unlock(int fd, int lock_type)
|
||||
* Set the state of the new owner of
|
||||
* the thread to running:
|
||||
*/
|
||||
_thread_fd_table[fd]->w_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
|
||||
|
||||
/*
|
||||
* Reset the number of write locks.
|
||||
|
@ -57,7 +57,7 @@ pthread_getprio(pthread_t pthread)
|
||||
/* Check if the thread pointer is NULL: */
|
||||
if (pthread == NULL || pthread_p == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Get the thread priority: */
|
||||
|
@ -87,8 +87,8 @@ _thread_dump_info(void)
|
||||
if (thread_info[j].state == pthread->state)
|
||||
break;
|
||||
/* Output a record for the current thread: */
|
||||
sprintf(s, "--------------------\nThread %p prio %3d state %s\n",
|
||||
pthread, pthread->pthread_priority, thread_info[j].name);
|
||||
sprintf(s, "--------------------\nThread %p prio %3d state %s [%s:%d]\n",
|
||||
pthread, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
|
||||
/* Check if this is the running thread: */
|
||||
@ -107,6 +107,9 @@ _thread_dump_info(void)
|
||||
switch (pthread->state) {
|
||||
/* File descriptor read lock wait: */
|
||||
case PS_FDLR_WAIT:
|
||||
case PS_FDLW_WAIT:
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
/* Write the lock details: */
|
||||
sprintf(s, "fd %d[%s:%d]", pthread->data.fd.fd, pthread->data.fd.fname, pthread->data.fd.branch);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
@ -140,11 +143,15 @@ _thread_dump_info(void)
|
||||
*/
|
||||
for (pthread = _thread_dead; pthread != NULL; pthread = pthread->nxt) {
|
||||
/* Output a record for the current thread: */
|
||||
sprintf(s, "Thread %p prio %3d\n", pthread, pthread->pthread_priority);
|
||||
sprintf(s, "Thread %p prio %3d [%s:%d]\n", pthread, pthread->pthread_priority,pthread->fname,pthread->lineno);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a header for file descriptors: */
|
||||
strcpy(s, "\n\n=============\nFILE DESCRIPTOR TABLE\n\n");
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
|
||||
/* Enter a loop to report file descriptor lock usage: */
|
||||
for (i = 0; i < _thread_dtablesize; i++) {
|
||||
/*
|
||||
|
@ -44,7 +44,11 @@
|
||||
#include <machine/reg.h>
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
extern int _thread_autoinit_dummy_decl;
|
||||
|
||||
/*
|
||||
* Threaded process initialization
|
||||
*/
|
||||
void
|
||||
_thread_init(void)
|
||||
{
|
||||
@ -52,15 +56,25 @@ _thread_init(void)
|
||||
int i;
|
||||
struct sigaction act;
|
||||
|
||||
/* Ensure that the auto-initialization routine is linked in: */
|
||||
_thread_autoinit_dummy_decl = 1;
|
||||
|
||||
/* Check if this function has already been called: */
|
||||
if (_thread_initial) {
|
||||
if (_thread_initial)
|
||||
/* Only initialise the threaded application once. */
|
||||
}
|
||||
return;
|
||||
|
||||
/* Get the standard I/O flags before messing with them : */
|
||||
for (i = 0; i < 3; i++)
|
||||
if ((_pthread_stdio_flags[i] =
|
||||
_thread_sys_fcntl(i,F_GETFL, NULL)) == -1)
|
||||
PANIC("Cannot get stdio flags");
|
||||
|
||||
/*
|
||||
* Create a pipe that is written to by the signal handler to prevent
|
||||
* signals being missed in calls to _thread_sys_select:
|
||||
*/
|
||||
else if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
|
||||
if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
|
||||
/* Cannot create pipe, so abort: */
|
||||
PANIC("Cannot create kernel pipe");
|
||||
}
|
||||
|
@ -40,14 +40,40 @@ pthread_join(pthread_t pthread, void **thread_return)
|
||||
{
|
||||
int rval = 0;
|
||||
int status;
|
||||
pthread_t pthread1;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Check if this thread has been detached: */
|
||||
if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
|
||||
/* Point to the first thread in the list: */
|
||||
pthread1 = _thread_link_list;
|
||||
|
||||
/* Search for the thread to join to: */
|
||||
while (pthread1 != NULL && pthread1 != pthread) {
|
||||
/* Point to the next thread: */
|
||||
pthread1 = pthread1->nxt;
|
||||
}
|
||||
|
||||
if (pthread1 == NULL) {
|
||||
/* Point to the first thread in the dead thread list: */
|
||||
pthread1 = _thread_dead;
|
||||
|
||||
/* Search for the thread to join to: */
|
||||
while (pthread1 != NULL && pthread1 != pthread) {
|
||||
/* Point to the next thread: */
|
||||
pthread1 = pthread1->nxt;
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread1 == NULL) {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
|
||||
/* Check if this thread has been detached: */
|
||||
} else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
|
||||
/* Return an error: */
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
/* Check if the thread is not dead: */
|
||||
@ -70,7 +96,7 @@ pthread_join(pthread_t pthread, void **thread_return)
|
||||
}
|
||||
} else {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
} else {
|
||||
|
@ -293,7 +293,7 @@ __asm__("fnsave %0": :"m"(*fdata));
|
||||
* Change the threads state to allow
|
||||
* it to be restarted:
|
||||
*/
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -823,14 +823,21 @@ __asm__("fnsave %0": :"m"(*fdata));
|
||||
static void
|
||||
_thread_signal(pthread_t pthread, int sig)
|
||||
{
|
||||
int done;
|
||||
long l;
|
||||
pthread_t new_pthread;
|
||||
struct sigaction act;
|
||||
void *arg;
|
||||
|
||||
/*
|
||||
* Assume that the signal will not be dealt with according
|
||||
* to the thread state:
|
||||
*/
|
||||
done = 0;
|
||||
|
||||
/* Process according to thread state: */
|
||||
switch (pthread->state) {
|
||||
/* States which do not change when a signal is trapped: */
|
||||
/* States which do not change when a signal is trapped: */
|
||||
case PS_COND_WAIT:
|
||||
case PS_DEAD:
|
||||
case PS_FDLR_WAIT:
|
||||
@ -844,7 +851,7 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Wait for child: */
|
||||
/* Wait for child: */
|
||||
case PS_WAIT_WAIT:
|
||||
/* Check if the signal is from a child exiting: */
|
||||
if (sig == SIGCHLD) {
|
||||
@ -852,42 +859,72 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
_thread_seterrno(pthread, 0);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
} else {
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
pthread->interrupted = 1;
|
||||
break;
|
||||
|
||||
/*
|
||||
* States that are interrupted by the occurrence of a signal
|
||||
* other than the scheduling alarm:
|
||||
*/
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
/* Waiting on I/O for zero or more file descriptors: */
|
||||
case PS_SELECT_WAIT:
|
||||
case PS_SLEEP_WAIT:
|
||||
case PS_SIGWAIT:
|
||||
pthread->data.select_data->nfds = -1;
|
||||
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
pthread->interrupted = 1;
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
break;
|
||||
|
||||
/*
|
||||
* States that are interrupted by the occurrence of a signal
|
||||
* other than the scheduling alarm:
|
||||
*/
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
case PS_SLEEP_WAIT:
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
pthread->interrupted = 1;
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
|
||||
/* Return the signal number: */
|
||||
pthread->signo = sig;
|
||||
break;
|
||||
|
||||
/* Waiting on a signal: */
|
||||
case PS_SIGWAIT:
|
||||
/* Change the state of the thread to run: */
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
|
||||
/* Return the signal number: */
|
||||
pthread->signo = sig;
|
||||
|
||||
/* Flag the signal as dealt with: */
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this signal is being ignored: */
|
||||
if (pthread->act[sig - 1].sa_handler == SIG_IGN) {
|
||||
/*
|
||||
* Check if this signal has been dealt with, or is being
|
||||
* ignored:
|
||||
*/
|
||||
if (done || pthread->act[sig - 1].sa_handler == SIG_IGN) {
|
||||
/* Ignore the signal for this thread. */
|
||||
}
|
||||
/* Check if this signal is to use the default handler: */
|
||||
else if (pthread->act[sig - 1].sa_handler == SIG_DFL) {
|
||||
/* Process according to signal type: */
|
||||
switch (sig) {
|
||||
/* Signals which cause core dumps: */
|
||||
/* Signals which cause core dumps: */
|
||||
case SIGQUIT:
|
||||
case SIGILL:
|
||||
case SIGTRAP:
|
||||
@ -910,7 +947,7 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
_thread_sys_sigreturn(&pthread->saved_sigcontext);
|
||||
break;
|
||||
|
||||
/* Default processing for other signals: */
|
||||
/* Default processing for other signals: */
|
||||
default:
|
||||
/*
|
||||
* ### Default processing is a problem to resolve!
|
||||
@ -983,6 +1020,8 @@ _thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
|
||||
{
|
||||
/* Change the state of the current thread: */
|
||||
_thread_run->state = state;
|
||||
_thread_run->fname = fname;
|
||||
_thread_run->lineno = lineno;
|
||||
|
||||
/* Schedule the next thread that is ready: */
|
||||
_thread_kern_sched(NULL);
|
||||
|
78
lib/libc_r/uthread/uthread_kill.c
Normal file
78
lib/libc_r/uthread/uthread_kill.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_kill(pthread_t pthread, int sig)
|
||||
{
|
||||
int rval = 0;
|
||||
int status;
|
||||
pthread_t p_pthread;
|
||||
|
||||
/* Check for invalid signal numbers: */
|
||||
if (sig < 0 || sig >= NSIG)
|
||||
/* Invalid signal: */
|
||||
rval = EINVAL;
|
||||
else {
|
||||
/* Assume that the search will succeed: */
|
||||
rval = 0;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Search for the thread: */
|
||||
p_pthread = _thread_link_list;
|
||||
while (p_pthread != NULL && p_pthread != pthread) {
|
||||
p_pthread = p_pthread->nxt;
|
||||
}
|
||||
|
||||
/* Check if the thread was not found: */
|
||||
if (p_pthread == NULL)
|
||||
/* Can't find the thread: */
|
||||
rval = ESRCH;
|
||||
else
|
||||
/* Increment the pending signal count: */
|
||||
p_pthread->sigpend[sig] += 1;
|
||||
|
||||
/* Unblock signals: */
|
||||
_thread_kern_sig_unblock(status);
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
#endif
|
@ -76,18 +76,18 @@ pthread_mutex_init(pthread_mutex_t * mutex,
|
||||
|
||||
/* Process according to mutex type: */
|
||||
switch (type) {
|
||||
/* Fast mutex: */
|
||||
/* Fast mutex: */
|
||||
case MUTEX_TYPE_FAST:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Counting mutex: */
|
||||
/* Counting mutex: */
|
||||
case MUTEX_TYPE_COUNTING_FAST:
|
||||
/* Reset the mutex count: */
|
||||
pmutex->m_data.m_count = 0;
|
||||
break;
|
||||
|
||||
/* Trap invalid mutex types: */
|
||||
/* Trap invalid mutex types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
errno = EINVAL;
|
||||
@ -130,18 +130,18 @@ pthread_mutex_destroy(pthread_mutex_t * mutex)
|
||||
|
||||
/* Process according to mutex type: */
|
||||
switch ((*mutex)->m_type) {
|
||||
/* Fast mutex: */
|
||||
/* Fast mutex: */
|
||||
case MUTEX_TYPE_FAST:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Counting mutex: */
|
||||
/* Counting mutex: */
|
||||
case MUTEX_TYPE_COUNTING_FAST:
|
||||
/* Reset the mutex count: */
|
||||
(*mutex)->m_data.m_count = 0;
|
||||
break;
|
||||
|
||||
/* Trap undefined mutex types: */
|
||||
/* Trap undefined mutex types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
errno = EINVAL;
|
||||
@ -348,7 +348,7 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
|
||||
*/
|
||||
else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
|
||||
/* Allow the new owner of the mutex to run: */
|
||||
(*mutex)->m_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -371,7 +371,7 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
|
||||
*/
|
||||
else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
|
||||
/* Allow the new owner of the mutex to run: */
|
||||
(*mutex)->m_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
|
52
lib/libc_r/uthread/uthread_mutexattr_destroy.c
Normal file
52
lib/libc_r/uthread/uthread_mutexattr_destroy.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
free(*attr);
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
read(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_READ, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking read syscall: */
|
||||
while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDR_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ read(int fd, void *buf, size_t nbytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
readv(int fd, const struct iovec * iov, int iovcnt)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_READ, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking readv syscall: */
|
||||
while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDR_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ readv(int fd, const struct iovec * iov, int iovcnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -49,21 +49,21 @@ pthread_resume_np(pthread_t thread)
|
||||
/* Found the thread. Is it suspended? */
|
||||
if (pthread->state == PS_SUSPENDED) {
|
||||
/* Allow the thread to run. */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
ret = 0;
|
||||
} else if (pthread->state == PS_RUNNING) {
|
||||
/* Thread is already running. */
|
||||
ret = 0;
|
||||
} else {
|
||||
/* Thread is in some other state. */
|
||||
_thread_seterrno(_thread_run,EINVAL);
|
||||
errno = EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if thread was not found. */
|
||||
if (ret == -1) {
|
||||
/* No such thread */
|
||||
_thread_seterrno(_thread_run,ESRCH);
|
||||
errno = ESRCH;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ pthread_setprio(pthread_t pthread, int prio)
|
||||
/* Check if the priority is invalid: */
|
||||
if (prio < PTHREAD_MIN_PRIORITY || prio > PTHREAD_MAX_PRIORITY) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Block signals: */
|
||||
@ -63,7 +63,7 @@ pthread_setprio(pthread_t pthread, int prio)
|
||||
/* Check if the thread pointer is NULL: */
|
||||
if (pthread == NULL || pthread_p == NULL) {
|
||||
/* Return a 'search' error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Set the thread priority: */
|
||||
|
@ -62,7 +62,7 @@ shutdown(int fd, int how)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
errno = EBADF;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
|
||||
_thread_seterrno(pthread, 0);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
|
||||
/* Check if the signal number is out of range: */
|
||||
if (sig < 1 || sig > NSIG) {
|
||||
/* Return an invalid argument: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
/*
|
||||
|
92
lib/libc_r/uthread/uthread_sigmask.c
Normal file
92
lib/libc_r/uthread/uthread_sigmask.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
/* Check if the existing signal process mask is to be returned: */
|
||||
if (oset != NULL) {
|
||||
/* Return the current mask: */
|
||||
*oset = _thread_run->sigmask;
|
||||
}
|
||||
/* Check if a new signal set was provided by the caller: */
|
||||
if (set != NULL) {
|
||||
/* Block signals while the signal mask is changed: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Process according to what to do: */
|
||||
switch (how) {
|
||||
/* Block signals: */
|
||||
case SIG_BLOCK:
|
||||
/* Add signals to the existing mask: */
|
||||
_thread_run->sigmask |= *set;
|
||||
break;
|
||||
|
||||
/* Unblock signals: */
|
||||
case SIG_UNBLOCK:
|
||||
/* Clear signals from the existing mask: */
|
||||
_thread_run->sigmask &= ~(*set);
|
||||
break;
|
||||
|
||||
/* Set the signal process mask: */
|
||||
case SIG_SETMASK:
|
||||
/* Set the new mask: */
|
||||
_thread_run->sigmask = *set;
|
||||
break;
|
||||
|
||||
/* Trap invalid actions: */
|
||||
default:
|
||||
/* Return an invalid argument: */
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule the next thread in case there are signals that
|
||||
* now need to be acted on:
|
||||
*/
|
||||
_thread_kern_sched(NULL);
|
||||
}
|
||||
/* Return the completion status: */
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
@ -54,28 +54,28 @@ sigprocmask(int how, const sigset_t * set, sigset_t * oset)
|
||||
|
||||
/* Process according to what to do: */
|
||||
switch (how) {
|
||||
/* Block signals: */
|
||||
/* Block signals: */
|
||||
case SIG_BLOCK:
|
||||
/* Add signals to the existing mask: */
|
||||
_thread_run->sigmask |= *set;
|
||||
break;
|
||||
|
||||
/* Unblock signals: */
|
||||
/* Unblock signals: */
|
||||
case SIG_UNBLOCK:
|
||||
/* Clear signals from the existing mask: */
|
||||
_thread_run->sigmask &= ~(*set);
|
||||
break;
|
||||
|
||||
/* Set the signal process mask: */
|
||||
/* Set the signal process mask: */
|
||||
case SIG_SETMASK:
|
||||
/* Set the new mask: */
|
||||
_thread_run->sigmask = *set;
|
||||
break;
|
||||
|
||||
/* Trap invalid actions: */
|
||||
/* Trap invalid actions: */
|
||||
default:
|
||||
/* Return an invalid argument: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ sigsuspend(const sigset_t * set)
|
||||
_thread_run->sigmask = oset;
|
||||
} else {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
|
73
lib/libc_r/uthread/uthread_sigwait.c
Normal file
73
lib/libc_r/uthread/uthread_sigwait.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
sigwait(const sigset_t * set, int *sig)
|
||||
{
|
||||
int ret;
|
||||
int status;
|
||||
sigset_t oset;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Save the current sigmal mask: */
|
||||
oset = _thread_run->sigmask;
|
||||
|
||||
/* Combine the caller's mask with the current one: */
|
||||
_thread_run->sigmask |= *set;
|
||||
|
||||
/* Wait for a signal: */
|
||||
_thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
|
||||
|
||||
/* Block signals again: */
|
||||
_thread_kern_sig_block(NULL);
|
||||
|
||||
/* Return the signal number to the caller: */
|
||||
*sig = _thread_run->signo;
|
||||
|
||||
/* Restore the signal mask: */
|
||||
_thread_run->sigmask = oset;
|
||||
|
||||
/* Unblock signals: */
|
||||
_thread_kern_sig_unblock(status);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
@ -41,19 +41,13 @@ int
|
||||
socketpair(int af, int type, int protocol, int pair[2])
|
||||
{
|
||||
int ret;
|
||||
if (!((ret = _thread_sys_socketpair(af, type, protocol, pair)) < 0)) {
|
||||
int tmp_flags;
|
||||
|
||||
tmp_flags = _thread_sys_fcntl(pair[0], F_GETFL, 0);
|
||||
_thread_sys_fcntl(pair[0], F_SETFL, tmp_flags | O_NONBLOCK);
|
||||
_thread_fd_table[pair[0]]->flags = tmp_flags;
|
||||
|
||||
tmp_flags = _thread_sys_fcntl(pair[1], F_GETFL, 0);
|
||||
_thread_sys_fcntl(pair[1], F_SETFL, tmp_flags | O_NONBLOCK);
|
||||
_thread_fd_table[pair[1]]->flags = tmp_flags;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
if (!((ret = _thread_sys_socketpair(af, type, protocol, pair)) < 0))
|
||||
if (_thread_fd_table_init(pair[0]) != 0 ||
|
||||
_thread_fd_table_init(pair[1]) != 0) {
|
||||
_thread_sys_close(pair[0]);
|
||||
_thread_sys_close(pair[1]);
|
||||
ret = -1;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
@ -209,7 +209,7 @@ pthread_getspecific(pthread_key_t key)
|
||||
/* Check for errors: */
|
||||
if (pthread == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
data = NULL;
|
||||
}
|
||||
/* Check if there is specific data: */
|
||||
|
@ -53,14 +53,14 @@ pthread_suspend_np(pthread_t thread)
|
||||
_thread_seterrno(pthread,EINTR);
|
||||
}
|
||||
/* Suspend the thread. */
|
||||
pthread->state = PS_SUSPENDED;
|
||||
PTHREAD_NEW_STATE(pthread,PS_SUSPENDED);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
/* Check if thread was not found. */
|
||||
if (ret == -1) {
|
||||
/* No such thread */
|
||||
_thread_seterrno(_thread_run,ESRCH);
|
||||
errno = ESRCH;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
write(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read and write: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking write syscall: */
|
||||
while ((ret = _thread_sys_write(fd, buf, nbytes)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDW_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ write(int fd, const void *buf, size_t nbytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
writev(int fd, const struct iovec * iov, int iovcnt)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read and write: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking writev syscall: */
|
||||
while ((ret = _thread_sys_writev(fd, iov, iovcnt)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDW_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ writev(int fd, const struct iovec * iov, int iovcnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ SHLIB_MINOR= 0
|
||||
CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS
|
||||
CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
|
||||
AINC= -I${.CURDIR}/../libc/${MACHINE} -I${.CURDIR}/uthread
|
||||
CLEANFILES+=tags
|
||||
PRECIOUSLIB= yes
|
||||
|
||||
.include "${.CURDIR}/db/Makefile.inc"
|
||||
@ -38,13 +37,4 @@ CFLAGS+= -DYP
|
||||
.endif
|
||||
.include "${.CURDIR}/${MACHINE}/sys/Makefile.inc"
|
||||
|
||||
beforeinstall: tags
|
||||
${INSTALL} ${COPY} -o bin -g bin -m 444 tags /var/db/libc_r.tags
|
||||
|
||||
tags: ${SRCS}
|
||||
ctags ${.ALLSRC:M*.c}
|
||||
egrep -o "^ENTRY(.*)|^FUNC(.*)|^SYSCALL(.*)" ${.ALLSRC:M*.s} | \
|
||||
sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
|
||||
>> tags; sort -o tags tags
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -9,13 +9,20 @@ SRCS+= \
|
||||
uthread_accept.c \
|
||||
uthread_attr_destroy.c \
|
||||
uthread_attr_init.c \
|
||||
uthread_attr_getdetachstate.c \
|
||||
uthread_attr_getstackaddr.c \
|
||||
uthread_attr_getstacksize.c \
|
||||
uthread_attr_setcreatesuspend_np.c \
|
||||
uthread_attr_setdetachstate.c \
|
||||
uthread_attr_setstackaddr.c \
|
||||
uthread_attr_setstacksize.c \
|
||||
uthread_autoinit.cc \
|
||||
uthread_bind.c \
|
||||
uthread_clean.c \
|
||||
uthread_close.c \
|
||||
uthread_cond.c \
|
||||
uthread_condattr_destroy.c \
|
||||
uthread_condattr_init.c \
|
||||
uthread_connect.c \
|
||||
uthread_create.c \
|
||||
uthread_detach.c \
|
||||
@ -44,12 +51,14 @@ SRCS+= \
|
||||
uthread_ioctl.c \
|
||||
uthread_join.c \
|
||||
uthread_kern.c \
|
||||
uthread_kill.c \
|
||||
uthread_listen.c \
|
||||
uthread_longjmp.c \
|
||||
uthread_mattr_init.c \
|
||||
uthread_mattr_kind_np.c \
|
||||
uthread_multi_np.c \
|
||||
uthread_mutex.c \
|
||||
uthread_mutexattr_destroy.c \
|
||||
uthread_nanosleep.c \
|
||||
uthread_once.c \
|
||||
uthread_open.c \
|
||||
@ -71,6 +80,7 @@ SRCS+= \
|
||||
uthread_sigaction.c \
|
||||
uthread_sigblock.c \
|
||||
uthread_single_np.c \
|
||||
uthread_sigmask.c \
|
||||
uthread_signal.c \
|
||||
uthread_sigprocmask.c \
|
||||
uthread_sigsetmask.c \
|
||||
|
@ -39,11 +39,19 @@
|
||||
int pthread_attr_destroy(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL)
|
||||
/* Invalid argument: */
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Free the memory allocated to the attribute object: */
|
||||
free(*attr);
|
||||
|
||||
/*
|
||||
* Leave the attribute pointer NULL now that the memory
|
||||
* has been freed:
|
||||
*/
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
|
57
lib/libkse/thread/thr_attr_getdetachstate.c
Normal file
57
lib/libkse/thread/thr_attr_getdetachstate.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || detachstate == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if the detached flag is set: */
|
||||
if ((*attr)->flags & PTHREAD_DETACHED)
|
||||
/* Return detached: */
|
||||
*detachstate = PTHREAD_CREATE_DETACHED;
|
||||
else
|
||||
/* Return joinable: */
|
||||
*detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libkse/thread/thr_attr_getstackaddr.c
Normal file
52
lib/libkse/thread/thr_attr_getstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack address: */
|
||||
*stackaddr = (*attr)->stackaddr_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libkse/thread/thr_attr_getstacksize.c
Normal file
52
lib/libkse/thread/thr_attr_getstacksize.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack size: */
|
||||
*stacksize = (*attr)->stacksize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -41,11 +41,16 @@ int pthread_attr_init(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_attr_t pattr;
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Allocate memory for the attribute object: */
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
|
||||
/* Insufficient memory: */
|
||||
ret = ENOMEM;
|
||||
else {
|
||||
/* Initialise the attribute object with the defaults: */
|
||||
memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
|
||||
|
||||
/* Return a pointer to the attribute object: */
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
|
59
lib/libkse/thread/thr_attr_setdetachstate.c
Normal file
59
lib/libkse/thread/thr_attr_setdetachstate.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL ||
|
||||
(detachstate != PTHREAD_CREATE_DETACHED &&
|
||||
detachstate != PTHREAD_CREATE_JOINABLE))
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if detached state: */
|
||||
if (detachstate == PTHREAD_CREATE_DETACHED)
|
||||
/* Set the detached flag: */
|
||||
(*attr)->flags |= PTHREAD_DETACHED;
|
||||
else
|
||||
/* Reset the detached flag: */
|
||||
(*attr)->flags &= ~PTHREAD_DETACHED;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libkse/thread/thr_attr_setstackaddr.c
Normal file
52
lib/libkse/thread/thr_attr_setstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack address: */
|
||||
(*attr)->stackaddr_attr = stackaddr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -38,10 +38,12 @@
|
||||
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack size: */
|
||||
(*attr)->stacksize_attr = stacksize;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -37,11 +37,10 @@
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
_thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
void
|
||||
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))) != NULL) {
|
||||
new->routine = routine;
|
||||
@ -49,15 +48,11 @@ _thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
new->next = _thread_run->cleanup;
|
||||
|
||||
_thread_run->cleanup = new;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = ENOMEM;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
_thread_cleanup_pop(int execute)
|
||||
pthread_cleanup_pop(int execute)
|
||||
{
|
||||
struct pthread_cleanup *old;
|
||||
|
||||
|
@ -272,7 +272,7 @@ pthread_cond_signal(pthread_cond_t * cond)
|
||||
/* Bring the next thread off the condition queue: */
|
||||
if ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -309,7 +309,7 @@ pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
/* Enter a loop to bring all threads off the condition queue: */
|
||||
while ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
|
52
lib/libkse/thread/thr_condattr_destroy.c
Normal file
52
lib/libkse/thread/thr_condattr_destroy.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_condattr_destroy(pthread_condattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
free(*attr);
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
58
lib/libkse/thread/thr_condattr_init.c
Normal file
58
lib/libkse/thread/thr_condattr_init.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_condattr_init(pthread_condattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_condattr_t pattr;
|
||||
|
||||
if ((pattr = (pthread_condattr_t)
|
||||
malloc(sizeof(struct pthread_cond_attr))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
ret = -1;
|
||||
} else {
|
||||
memcpy(pattr, &pthread_condattr_default,
|
||||
sizeof(struct pthread_cond_attr));
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -87,9 +87,9 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr,
|
||||
new_thread->start_routine = start_routine;
|
||||
new_thread->arg = arg;
|
||||
if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
|
||||
new_thread->state = PS_SUSPENDED;
|
||||
PTHREAD_NEW_STATE(new_thread,PS_SUSPENDED);
|
||||
} else {
|
||||
new_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(new_thread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/* Initialise the thread for signals: */
|
||||
@ -208,7 +208,7 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr,
|
||||
* a signal handler thread which must now
|
||||
* wait for the signal handler to complete:
|
||||
*/
|
||||
parent->state = PS_SIGTHREAD;
|
||||
PTHREAD_NEW_STATE(parent,PS_SIGTHREAD);
|
||||
} else {
|
||||
/* Schedule the new user thread: */
|
||||
_thread_kern_sched(NULL);
|
||||
|
@ -49,7 +49,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
/* Check for invalid calling parameters: */
|
||||
if (p_pthread == NULL || (pthread = *p_pthread) == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
}
|
||||
/* Check if the thread has not been detached: */
|
||||
@ -60,7 +60,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
/* Enter a loop to bring all threads off the join queue: */
|
||||
while ((next_thread = _thread_queue_deq(&pthread->join_queue)) != NULL) {
|
||||
/* Make the thread run: */
|
||||
next_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -70,7 +70,7 @@ pthread_detach(pthread_t * p_pthread)
|
||||
*p_pthread = NULL;
|
||||
} else {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ pthread_exit(void *status)
|
||||
_thread_run->ret = status;
|
||||
|
||||
while (_thread_run->cleanup != NULL) {
|
||||
_thread_cleanup_pop(1);
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
|
||||
if (_thread_run->attr.cleanup_attr != NULL) {
|
||||
@ -123,7 +123,7 @@ pthread_exit(void *status)
|
||||
/* Check if there are any threads joined to this one: */
|
||||
while ((pthread = _thread_queue_deq(&(_thread_run->join_queue))) != NULL) {
|
||||
/* Wake the joined thread and let it detach this thread: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
|
||||
/* Check if the running thread is at the head of the linked list: */
|
||||
@ -173,11 +173,11 @@ pthread_exit(void *status)
|
||||
|
||||
/*
|
||||
* Check if the parent is not waiting on any other signal
|
||||
* handler threads:
|
||||
* handler threads and if it hasn't died in the meantime:
|
||||
*/
|
||||
if (pthread == NULL) {
|
||||
if (pthread == NULL && _thread_run->parent_thread->state != PS_DEAD) {
|
||||
/* Allow the parent thread to run again: */
|
||||
_thread_run->parent_thread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(_thread_run->parent_thread,PS_RUNNING);
|
||||
}
|
||||
/* Get the signal number: */
|
||||
l = (long) _thread_run->arg;
|
||||
|
@ -57,7 +57,7 @@ pthread_getprio(pthread_t pthread)
|
||||
/* Check if the thread pointer is NULL: */
|
||||
if (pthread == NULL || pthread_p == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Get the thread priority: */
|
||||
|
@ -87,8 +87,8 @@ _thread_dump_info(void)
|
||||
if (thread_info[j].state == pthread->state)
|
||||
break;
|
||||
/* Output a record for the current thread: */
|
||||
sprintf(s, "--------------------\nThread %p prio %3d state %s\n",
|
||||
pthread, pthread->pthread_priority, thread_info[j].name);
|
||||
sprintf(s, "--------------------\nThread %p prio %3d state %s [%s:%d]\n",
|
||||
pthread, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
|
||||
/* Check if this is the running thread: */
|
||||
@ -107,6 +107,9 @@ _thread_dump_info(void)
|
||||
switch (pthread->state) {
|
||||
/* File descriptor read lock wait: */
|
||||
case PS_FDLR_WAIT:
|
||||
case PS_FDLW_WAIT:
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
/* Write the lock details: */
|
||||
sprintf(s, "fd %d[%s:%d]", pthread->data.fd.fd, pthread->data.fd.fname, pthread->data.fd.branch);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
@ -140,11 +143,15 @@ _thread_dump_info(void)
|
||||
*/
|
||||
for (pthread = _thread_dead; pthread != NULL; pthread = pthread->nxt) {
|
||||
/* Output a record for the current thread: */
|
||||
sprintf(s, "Thread %p prio %3d\n", pthread, pthread->pthread_priority);
|
||||
sprintf(s, "Thread %p prio %3d [%s:%d]\n", pthread, pthread->pthread_priority,pthread->fname,pthread->lineno);
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a header for file descriptors: */
|
||||
strcpy(s, "\n\n=============\nFILE DESCRIPTOR TABLE\n\n");
|
||||
_thread_sys_write(fd, s, strlen(s));
|
||||
|
||||
/* Enter a loop to report file descriptor lock usage: */
|
||||
for (i = 0; i < _thread_dtablesize; i++) {
|
||||
/*
|
||||
|
@ -44,7 +44,11 @@
|
||||
#include <machine/reg.h>
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
extern int _thread_autoinit_dummy_decl;
|
||||
|
||||
/*
|
||||
* Threaded process initialization
|
||||
*/
|
||||
void
|
||||
_thread_init(void)
|
||||
{
|
||||
@ -52,15 +56,25 @@ _thread_init(void)
|
||||
int i;
|
||||
struct sigaction act;
|
||||
|
||||
/* Ensure that the auto-initialization routine is linked in: */
|
||||
_thread_autoinit_dummy_decl = 1;
|
||||
|
||||
/* Check if this function has already been called: */
|
||||
if (_thread_initial) {
|
||||
if (_thread_initial)
|
||||
/* Only initialise the threaded application once. */
|
||||
}
|
||||
return;
|
||||
|
||||
/* Get the standard I/O flags before messing with them : */
|
||||
for (i = 0; i < 3; i++)
|
||||
if ((_pthread_stdio_flags[i] =
|
||||
_thread_sys_fcntl(i,F_GETFL, NULL)) == -1)
|
||||
PANIC("Cannot get stdio flags");
|
||||
|
||||
/*
|
||||
* Create a pipe that is written to by the signal handler to prevent
|
||||
* signals being missed in calls to _thread_sys_select:
|
||||
*/
|
||||
else if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
|
||||
if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
|
||||
/* Cannot create pipe, so abort: */
|
||||
PANIC("Cannot create kernel pipe");
|
||||
}
|
||||
|
@ -40,14 +40,40 @@ pthread_join(pthread_t pthread, void **thread_return)
|
||||
{
|
||||
int rval = 0;
|
||||
int status;
|
||||
pthread_t pthread1;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Check if this thread has been detached: */
|
||||
if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
|
||||
/* Point to the first thread in the list: */
|
||||
pthread1 = _thread_link_list;
|
||||
|
||||
/* Search for the thread to join to: */
|
||||
while (pthread1 != NULL && pthread1 != pthread) {
|
||||
/* Point to the next thread: */
|
||||
pthread1 = pthread1->nxt;
|
||||
}
|
||||
|
||||
if (pthread1 == NULL) {
|
||||
/* Point to the first thread in the dead thread list: */
|
||||
pthread1 = _thread_dead;
|
||||
|
||||
/* Search for the thread to join to: */
|
||||
while (pthread1 != NULL && pthread1 != pthread) {
|
||||
/* Point to the next thread: */
|
||||
pthread1 = pthread1->nxt;
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread1 == NULL) {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
|
||||
/* Check if this thread has been detached: */
|
||||
} else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
|
||||
/* Return an error: */
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
/* Check if the thread is not dead: */
|
||||
@ -70,7 +96,7 @@ pthread_join(pthread_t pthread, void **thread_return)
|
||||
}
|
||||
} else {
|
||||
/* Return an error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
}
|
||||
} else {
|
||||
|
@ -293,7 +293,7 @@ __asm__("fnsave %0": :"m"(*fdata));
|
||||
* Change the threads state to allow
|
||||
* it to be restarted:
|
||||
*/
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -823,14 +823,21 @@ __asm__("fnsave %0": :"m"(*fdata));
|
||||
static void
|
||||
_thread_signal(pthread_t pthread, int sig)
|
||||
{
|
||||
int done;
|
||||
long l;
|
||||
pthread_t new_pthread;
|
||||
struct sigaction act;
|
||||
void *arg;
|
||||
|
||||
/*
|
||||
* Assume that the signal will not be dealt with according
|
||||
* to the thread state:
|
||||
*/
|
||||
done = 0;
|
||||
|
||||
/* Process according to thread state: */
|
||||
switch (pthread->state) {
|
||||
/* States which do not change when a signal is trapped: */
|
||||
/* States which do not change when a signal is trapped: */
|
||||
case PS_COND_WAIT:
|
||||
case PS_DEAD:
|
||||
case PS_FDLR_WAIT:
|
||||
@ -844,7 +851,7 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Wait for child: */
|
||||
/* Wait for child: */
|
||||
case PS_WAIT_WAIT:
|
||||
/* Check if the signal is from a child exiting: */
|
||||
if (sig == SIGCHLD) {
|
||||
@ -852,42 +859,72 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
_thread_seterrno(pthread, 0);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
} else {
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
pthread->interrupted = 1;
|
||||
break;
|
||||
|
||||
/*
|
||||
* States that are interrupted by the occurrence of a signal
|
||||
* other than the scheduling alarm:
|
||||
*/
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
/* Waiting on I/O for zero or more file descriptors: */
|
||||
case PS_SELECT_WAIT:
|
||||
case PS_SLEEP_WAIT:
|
||||
case PS_SIGWAIT:
|
||||
pthread->data.select_data->nfds = -1;
|
||||
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
pthread->interrupted = 1;
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
break;
|
||||
|
||||
/*
|
||||
* States that are interrupted by the occurrence of a signal
|
||||
* other than the scheduling alarm:
|
||||
*/
|
||||
case PS_FDR_WAIT:
|
||||
case PS_FDW_WAIT:
|
||||
case PS_SLEEP_WAIT:
|
||||
/* Return the 'interrupted' error: */
|
||||
_thread_seterrno(pthread, EINTR);
|
||||
pthread->interrupted = 1;
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
|
||||
/* Return the signal number: */
|
||||
pthread->signo = sig;
|
||||
break;
|
||||
|
||||
/* Waiting on a signal: */
|
||||
case PS_SIGWAIT:
|
||||
/* Change the state of the thread to run: */
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
|
||||
/* Return the signal number: */
|
||||
pthread->signo = sig;
|
||||
|
||||
/* Flag the signal as dealt with: */
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this signal is being ignored: */
|
||||
if (pthread->act[sig - 1].sa_handler == SIG_IGN) {
|
||||
/*
|
||||
* Check if this signal has been dealt with, or is being
|
||||
* ignored:
|
||||
*/
|
||||
if (done || pthread->act[sig - 1].sa_handler == SIG_IGN) {
|
||||
/* Ignore the signal for this thread. */
|
||||
}
|
||||
/* Check if this signal is to use the default handler: */
|
||||
else if (pthread->act[sig - 1].sa_handler == SIG_DFL) {
|
||||
/* Process according to signal type: */
|
||||
switch (sig) {
|
||||
/* Signals which cause core dumps: */
|
||||
/* Signals which cause core dumps: */
|
||||
case SIGQUIT:
|
||||
case SIGILL:
|
||||
case SIGTRAP:
|
||||
@ -910,7 +947,7 @@ _thread_signal(pthread_t pthread, int sig)
|
||||
_thread_sys_sigreturn(&pthread->saved_sigcontext);
|
||||
break;
|
||||
|
||||
/* Default processing for other signals: */
|
||||
/* Default processing for other signals: */
|
||||
default:
|
||||
/*
|
||||
* ### Default processing is a problem to resolve!
|
||||
@ -983,6 +1020,8 @@ _thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
|
||||
{
|
||||
/* Change the state of the current thread: */
|
||||
_thread_run->state = state;
|
||||
_thread_run->fname = fname;
|
||||
_thread_run->lineno = lineno;
|
||||
|
||||
/* Schedule the next thread that is ready: */
|
||||
_thread_kern_sched(NULL);
|
||||
|
78
lib/libkse/thread/thr_kill.c
Normal file
78
lib/libkse/thread/thr_kill.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_kill(pthread_t pthread, int sig)
|
||||
{
|
||||
int rval = 0;
|
||||
int status;
|
||||
pthread_t p_pthread;
|
||||
|
||||
/* Check for invalid signal numbers: */
|
||||
if (sig < 0 || sig >= NSIG)
|
||||
/* Invalid signal: */
|
||||
rval = EINVAL;
|
||||
else {
|
||||
/* Assume that the search will succeed: */
|
||||
rval = 0;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Search for the thread: */
|
||||
p_pthread = _thread_link_list;
|
||||
while (p_pthread != NULL && p_pthread != pthread) {
|
||||
p_pthread = p_pthread->nxt;
|
||||
}
|
||||
|
||||
/* Check if the thread was not found: */
|
||||
if (p_pthread == NULL)
|
||||
/* Can't find the thread: */
|
||||
rval = ESRCH;
|
||||
else
|
||||
/* Increment the pending signal count: */
|
||||
p_pthread->sigpend[sig] += 1;
|
||||
|
||||
/* Unblock signals: */
|
||||
_thread_kern_sig_unblock(status);
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
#endif
|
@ -76,18 +76,18 @@ pthread_mutex_init(pthread_mutex_t * mutex,
|
||||
|
||||
/* Process according to mutex type: */
|
||||
switch (type) {
|
||||
/* Fast mutex: */
|
||||
/* Fast mutex: */
|
||||
case MUTEX_TYPE_FAST:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Counting mutex: */
|
||||
/* Counting mutex: */
|
||||
case MUTEX_TYPE_COUNTING_FAST:
|
||||
/* Reset the mutex count: */
|
||||
pmutex->m_data.m_count = 0;
|
||||
break;
|
||||
|
||||
/* Trap invalid mutex types: */
|
||||
/* Trap invalid mutex types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
errno = EINVAL;
|
||||
@ -130,18 +130,18 @@ pthread_mutex_destroy(pthread_mutex_t * mutex)
|
||||
|
||||
/* Process according to mutex type: */
|
||||
switch ((*mutex)->m_type) {
|
||||
/* Fast mutex: */
|
||||
/* Fast mutex: */
|
||||
case MUTEX_TYPE_FAST:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Counting mutex: */
|
||||
/* Counting mutex: */
|
||||
case MUTEX_TYPE_COUNTING_FAST:
|
||||
/* Reset the mutex count: */
|
||||
(*mutex)->m_data.m_count = 0;
|
||||
break;
|
||||
|
||||
/* Trap undefined mutex types: */
|
||||
/* Trap undefined mutex types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
errno = EINVAL;
|
||||
@ -348,7 +348,7 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
|
||||
*/
|
||||
else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
|
||||
/* Allow the new owner of the mutex to run: */
|
||||
(*mutex)->m_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -371,7 +371,7 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
|
||||
*/
|
||||
else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
|
||||
/* Allow the new owner of the mutex to run: */
|
||||
(*mutex)->m_owner->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
|
52
lib/libkse/thread/thr_mutexattr_destroy.c
Normal file
52
lib/libkse/thread/thr_mutexattr_destroy.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
free(*attr);
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -58,6 +58,15 @@
|
||||
*/
|
||||
#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
|
||||
|
||||
/*
|
||||
* State change macro:
|
||||
*/
|
||||
#define PTHREAD_NEW_STATE(thrd, newstate) { \
|
||||
(thrd)->state = newstate; \
|
||||
(thrd)->fname = __FILE__; \
|
||||
(thrd)->lineno = __LINE__; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue definitions.
|
||||
*/
|
||||
@ -206,19 +215,6 @@ struct sched_param {
|
||||
*/
|
||||
#define TIMESLICE_USEC 100000
|
||||
|
||||
/*
|
||||
* Flags.
|
||||
*/
|
||||
#define PTHREAD_DETACHED 0x1
|
||||
#define PTHREAD_SCOPE_SYSTEM 0x2
|
||||
#define PTHREAD_INHERIT_SCHED 0x4
|
||||
#define PTHREAD_NOFLOAT 0x8
|
||||
|
||||
#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED
|
||||
#define PTHREAD_CREATE_JOINABLE 0
|
||||
#define PTHREAD_SCOPE_PROCESS 0
|
||||
#define PTHREAD_EXPLICIT_SCHED 0
|
||||
|
||||
struct pthread_key {
|
||||
pthread_mutex_t mutex;
|
||||
long count;
|
||||
@ -407,6 +403,15 @@ struct pthread {
|
||||
/* Wait data. */
|
||||
union pthread_wait_data data;
|
||||
|
||||
/*
|
||||
* Set to TRUE if a blocking operation was
|
||||
* interrupted by a signal:
|
||||
*/
|
||||
int interrupted;
|
||||
|
||||
/* Signal number when in state PS_SIGWAIT: */
|
||||
int signo;
|
||||
|
||||
/* Miscellaneous data. */
|
||||
char flags;
|
||||
char pthread_priority;
|
||||
@ -416,6 +421,8 @@ struct pthread {
|
||||
|
||||
/* Cleanup handlers Link List */
|
||||
struct pthread_cleanup *cleanup;
|
||||
char *fname; /* Ptr to source file name */
|
||||
int lineno; /* Source line number. */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -426,7 +433,7 @@ struct pthread {
|
||||
SCLASS struct pthread _thread_kern_thread;
|
||||
|
||||
/* Ptr to the thread structure for the running thread: */
|
||||
SCLASS struct pthread *_thread_run
|
||||
SCLASS struct pthread * volatile _thread_run
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= &_thread_kern_thread;
|
||||
#else
|
||||
@ -437,7 +444,7 @@ SCLASS struct pthread *_thread_run
|
||||
* Ptr to the thread running in single-threaded mode or NULL if
|
||||
* running multi-threaded (default POSIX behaviour).
|
||||
*/
|
||||
SCLASS struct pthread *_thread_single
|
||||
SCLASS struct pthread * volatile _thread_single
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -445,7 +452,7 @@ SCLASS struct pthread *_thread_single
|
||||
#endif
|
||||
|
||||
/* Ptr to the first thread in the thread linked list: */
|
||||
SCLASS struct pthread *_thread_link_list
|
||||
SCLASS struct pthread * volatile _thread_link_list
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -481,7 +488,7 @@ SCLASS struct timeval kern_inc_prio_time
|
||||
#endif
|
||||
|
||||
/* Dead threads: */
|
||||
SCLASS struct pthread *_thread_dead
|
||||
SCLASS struct pthread * volatile _thread_dead
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= NULL;
|
||||
#else
|
||||
@ -505,7 +512,7 @@ SCLASS struct pthread_attr pthread_attr_default
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Default thread attributes: */
|
||||
/* Default mutex attributes: */
|
||||
SCLASS struct pthread_mutex_attr pthread_mutexattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { MUTEX_TYPE_FAST, 0 };
|
||||
@ -513,6 +520,21 @@ SCLASS struct pthread_mutex_attr pthread_mutexattr_default
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Default condition variable attributes: */
|
||||
SCLASS struct pthread_cond_attr pthread_condattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { COND_TYPE_FAST, 0 };
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard I/O file descriptors need special flag treatment since
|
||||
* setting one to non-blocking does all on *BSD. Sigh. This array
|
||||
* is used to store the initial flag settings.
|
||||
*/
|
||||
SCLASS int _pthread_stdio_flags[3];
|
||||
|
||||
/* File table information: */
|
||||
SCLASS struct fd_table_entry **_thread_fd_table
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
@ -558,7 +580,6 @@ void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
|
||||
void _thread_kern_set_timeout(struct timespec *);
|
||||
void _thread_kern_sig_block(int *);
|
||||
void _thread_kern_sig_unblock(int);
|
||||
void _thread_cleanup_pop(int);
|
||||
void _thread_sig_handler(int, int, struct sigcontext *);
|
||||
void _thread_start(void);
|
||||
void _thread_start_sig_handler(void);
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
read(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_READ, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking read syscall: */
|
||||
while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDR_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ read(int fd, void *buf, size_t nbytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
readv(int fd, const struct iovec * iov, int iovcnt)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_READ, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking readv syscall: */
|
||||
while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDR_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ readv(int fd, const struct iovec * iov, int iovcnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_READ);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -49,21 +49,21 @@ pthread_resume_np(pthread_t thread)
|
||||
/* Found the thread. Is it suspended? */
|
||||
if (pthread->state == PS_SUSPENDED) {
|
||||
/* Allow the thread to run. */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
ret = 0;
|
||||
} else if (pthread->state == PS_RUNNING) {
|
||||
/* Thread is already running. */
|
||||
ret = 0;
|
||||
} else {
|
||||
/* Thread is in some other state. */
|
||||
_thread_seterrno(_thread_run,EINVAL);
|
||||
errno = EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if thread was not found. */
|
||||
if (ret == -1) {
|
||||
/* No such thread */
|
||||
_thread_seterrno(_thread_run,ESRCH);
|
||||
errno = ESRCH;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ pthread_setprio(pthread_t pthread, int prio)
|
||||
/* Check if the priority is invalid: */
|
||||
if (prio < PTHREAD_MIN_PRIORITY || prio > PTHREAD_MAX_PRIORITY) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Block signals: */
|
||||
@ -63,7 +63,7 @@ pthread_setprio(pthread_t pthread, int prio)
|
||||
/* Check if the thread pointer is NULL: */
|
||||
if (pthread == NULL || pthread_p == NULL) {
|
||||
/* Return a 'search' error: */
|
||||
_thread_seterrno(_thread_run, ESRCH);
|
||||
errno = ESRCH;
|
||||
rval = -1;
|
||||
} else {
|
||||
/* Set the thread priority: */
|
||||
|
@ -97,7 +97,7 @@ _thread_sig_handler(int sig, int code, struct sigcontext * scp)
|
||||
_thread_seterrno(pthread, 0);
|
||||
|
||||
/* Change the state of the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
|
||||
/* Check if the signal number is out of range: */
|
||||
if (sig < 1 || sig > NSIG) {
|
||||
/* Return an invalid argument: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
/*
|
||||
|
92
lib/libkse/thread/thr_sigmask.c
Normal file
92
lib/libkse/thread/thr_sigmask.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
/* Check if the existing signal process mask is to be returned: */
|
||||
if (oset != NULL) {
|
||||
/* Return the current mask: */
|
||||
*oset = _thread_run->sigmask;
|
||||
}
|
||||
/* Check if a new signal set was provided by the caller: */
|
||||
if (set != NULL) {
|
||||
/* Block signals while the signal mask is changed: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Process according to what to do: */
|
||||
switch (how) {
|
||||
/* Block signals: */
|
||||
case SIG_BLOCK:
|
||||
/* Add signals to the existing mask: */
|
||||
_thread_run->sigmask |= *set;
|
||||
break;
|
||||
|
||||
/* Unblock signals: */
|
||||
case SIG_UNBLOCK:
|
||||
/* Clear signals from the existing mask: */
|
||||
_thread_run->sigmask &= ~(*set);
|
||||
break;
|
||||
|
||||
/* Set the signal process mask: */
|
||||
case SIG_SETMASK:
|
||||
/* Set the new mask: */
|
||||
_thread_run->sigmask = *set;
|
||||
break;
|
||||
|
||||
/* Trap invalid actions: */
|
||||
default:
|
||||
/* Return an invalid argument: */
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule the next thread in case there are signals that
|
||||
* now need to be acted on:
|
||||
*/
|
||||
_thread_kern_sched(NULL);
|
||||
}
|
||||
/* Return the completion status: */
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
@ -54,28 +54,28 @@ sigprocmask(int how, const sigset_t * set, sigset_t * oset)
|
||||
|
||||
/* Process according to what to do: */
|
||||
switch (how) {
|
||||
/* Block signals: */
|
||||
/* Block signals: */
|
||||
case SIG_BLOCK:
|
||||
/* Add signals to the existing mask: */
|
||||
_thread_run->sigmask |= *set;
|
||||
break;
|
||||
|
||||
/* Unblock signals: */
|
||||
/* Unblock signals: */
|
||||
case SIG_UNBLOCK:
|
||||
/* Clear signals from the existing mask: */
|
||||
_thread_run->sigmask &= ~(*set);
|
||||
break;
|
||||
|
||||
/* Set the signal process mask: */
|
||||
/* Set the signal process mask: */
|
||||
case SIG_SETMASK:
|
||||
/* Set the new mask: */
|
||||
_thread_run->sigmask = *set;
|
||||
break;
|
||||
|
||||
/* Trap invalid actions: */
|
||||
/* Trap invalid actions: */
|
||||
default:
|
||||
/* Return an invalid argument: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ sigsuspend(const sigset_t * set)
|
||||
_thread_run->sigmask = oset;
|
||||
} else {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
|
73
lib/libkse/thread/thr_sigwait.c
Normal file
73
lib/libkse/thread/thr_sigwait.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
sigwait(const sigset_t * set, int *sig)
|
||||
{
|
||||
int ret;
|
||||
int status;
|
||||
sigset_t oset;
|
||||
|
||||
/* Block signals: */
|
||||
_thread_kern_sig_block(&status);
|
||||
|
||||
/* Save the current sigmal mask: */
|
||||
oset = _thread_run->sigmask;
|
||||
|
||||
/* Combine the caller's mask with the current one: */
|
||||
_thread_run->sigmask |= *set;
|
||||
|
||||
/* Wait for a signal: */
|
||||
_thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
|
||||
|
||||
/* Block signals again: */
|
||||
_thread_kern_sig_block(NULL);
|
||||
|
||||
/* Return the signal number to the caller: */
|
||||
*sig = _thread_run->signo;
|
||||
|
||||
/* Restore the signal mask: */
|
||||
_thread_run->sigmask = oset;
|
||||
|
||||
/* Unblock signals: */
|
||||
_thread_kern_sig_unblock(status);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
@ -209,7 +209,7 @@ pthread_getspecific(pthread_key_t key)
|
||||
/* Check for errors: */
|
||||
if (pthread == NULL) {
|
||||
/* Return an invalid argument error: */
|
||||
_thread_seterrno(_thread_run, EINVAL);
|
||||
errno = EINVAL;
|
||||
data = NULL;
|
||||
}
|
||||
/* Check if there is specific data: */
|
||||
|
@ -53,14 +53,14 @@ pthread_suspend_np(pthread_t thread)
|
||||
_thread_seterrno(pthread,EINTR);
|
||||
}
|
||||
/* Suspend the thread. */
|
||||
pthread->state = PS_SUSPENDED;
|
||||
PTHREAD_NEW_STATE(pthread,PS_SUSPENDED);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
/* Check if thread was not found. */
|
||||
if (ret == -1) {
|
||||
/* No such thread */
|
||||
_thread_seterrno(_thread_run,ESRCH);
|
||||
errno = ESRCH;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
write(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read and write: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking write syscall: */
|
||||
while ((ret = _thread_sys_write(fd, buf, nbytes)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDW_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ write(int fd, const void *buf, size_t nbytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -42,22 +42,31 @@
|
||||
ssize_t
|
||||
writev(int fd, const struct iovec * iov, int iovcnt)
|
||||
{
|
||||
int nonblock;
|
||||
int ret;
|
||||
int status;
|
||||
if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
|
||||
_thread_seterrno(_thread_run, EBADF);
|
||||
ret = -1;
|
||||
} else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) {
|
||||
/* Cannot lock file descriptor. */
|
||||
} else {
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Lock the file descriptor for read and write: */
|
||||
if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL,
|
||||
__FILE__, __LINE__)) == 0) {
|
||||
/* Perform a non-blocking writev syscall: */
|
||||
while ((ret = _thread_sys_writev(fd, iov, iovcnt)) < 0) {
|
||||
if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
_thread_kern_sig_block(&status);
|
||||
_thread_run->data.fd.fd = fd;
|
||||
_thread_kern_set_timeout(NULL);
|
||||
_thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
|
||||
if (errno == EINTR) {
|
||||
|
||||
/* Reset the interrupted operation flag: */
|
||||
_thread_run->interrupted = 0;
|
||||
|
||||
_thread_kern_sched_state(PS_FDW_WAIT,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
/*
|
||||
* Check if the operation was
|
||||
* interrupted by a signal
|
||||
*/
|
||||
if (_thread_run->interrupted) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -65,9 +74,7 @@ writev(int fd, const struct iovec * iov, int iovcnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nonblock == 0) {
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
_thread_fd_unlock(fd, FD_RDWR);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ SHLIB_MINOR= 0
|
||||
CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS
|
||||
CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
|
||||
AINC= -I${.CURDIR}/../libc/${MACHINE} -I${.CURDIR}/uthread
|
||||
CLEANFILES+=tags
|
||||
PRECIOUSLIB= yes
|
||||
|
||||
.include "${.CURDIR}/db/Makefile.inc"
|
||||
@ -38,13 +37,4 @@ CFLAGS+= -DYP
|
||||
.endif
|
||||
.include "${.CURDIR}/${MACHINE}/sys/Makefile.inc"
|
||||
|
||||
beforeinstall: tags
|
||||
${INSTALL} ${COPY} -o bin -g bin -m 444 tags /var/db/libc_r.tags
|
||||
|
||||
tags: ${SRCS}
|
||||
ctags ${.ALLSRC:M*.c}
|
||||
egrep -o "^ENTRY(.*)|^FUNC(.*)|^SYSCALL(.*)" ${.ALLSRC:M*.s} | \
|
||||
sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
|
||||
>> tags; sort -o tags tags
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -9,13 +9,20 @@ SRCS+= \
|
||||
uthread_accept.c \
|
||||
uthread_attr_destroy.c \
|
||||
uthread_attr_init.c \
|
||||
uthread_attr_getdetachstate.c \
|
||||
uthread_attr_getstackaddr.c \
|
||||
uthread_attr_getstacksize.c \
|
||||
uthread_attr_setcreatesuspend_np.c \
|
||||
uthread_attr_setdetachstate.c \
|
||||
uthread_attr_setstackaddr.c \
|
||||
uthread_attr_setstacksize.c \
|
||||
uthread_autoinit.cc \
|
||||
uthread_bind.c \
|
||||
uthread_clean.c \
|
||||
uthread_close.c \
|
||||
uthread_cond.c \
|
||||
uthread_condattr_destroy.c \
|
||||
uthread_condattr_init.c \
|
||||
uthread_connect.c \
|
||||
uthread_create.c \
|
||||
uthread_detach.c \
|
||||
@ -44,12 +51,14 @@ SRCS+= \
|
||||
uthread_ioctl.c \
|
||||
uthread_join.c \
|
||||
uthread_kern.c \
|
||||
uthread_kill.c \
|
||||
uthread_listen.c \
|
||||
uthread_longjmp.c \
|
||||
uthread_mattr_init.c \
|
||||
uthread_mattr_kind_np.c \
|
||||
uthread_multi_np.c \
|
||||
uthread_mutex.c \
|
||||
uthread_mutexattr_destroy.c \
|
||||
uthread_nanosleep.c \
|
||||
uthread_once.c \
|
||||
uthread_open.c \
|
||||
@ -71,6 +80,7 @@ SRCS+= \
|
||||
uthread_sigaction.c \
|
||||
uthread_sigblock.c \
|
||||
uthread_single_np.c \
|
||||
uthread_sigmask.c \
|
||||
uthread_signal.c \
|
||||
uthread_sigprocmask.c \
|
||||
uthread_sigsetmask.c \
|
||||
|
@ -39,11 +39,19 @@
|
||||
int pthread_attr_destroy(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL)
|
||||
/* Invalid argument: */
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Free the memory allocated to the attribute object: */
|
||||
free(*attr);
|
||||
|
||||
/*
|
||||
* Leave the attribute pointer NULL now that the memory
|
||||
* has been freed:
|
||||
*/
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
|
57
lib/libpthread/thread/thr_attr_getdetachstate.c
Normal file
57
lib/libpthread/thread/thr_attr_getdetachstate.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || detachstate == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if the detached flag is set: */
|
||||
if ((*attr)->flags & PTHREAD_DETACHED)
|
||||
/* Return detached: */
|
||||
*detachstate = PTHREAD_CREATE_DETACHED;
|
||||
else
|
||||
/* Return joinable: */
|
||||
*detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libpthread/thread/thr_attr_getstackaddr.c
Normal file
52
lib/libpthread/thread/thr_attr_getstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack address: */
|
||||
*stackaddr = (*attr)->stackaddr_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libpthread/thread/thr_attr_getstacksize.c
Normal file
52
lib/libpthread/thread/thr_attr_getstacksize.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack size: */
|
||||
*stacksize = (*attr)->stacksize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -41,11 +41,16 @@ int pthread_attr_init(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_attr_t pattr;
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Allocate memory for the attribute object: */
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
|
||||
/* Insufficient memory: */
|
||||
ret = ENOMEM;
|
||||
else {
|
||||
/* Initialise the attribute object with the defaults: */
|
||||
memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
|
||||
|
||||
/* Return a pointer to the attribute object: */
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
|
59
lib/libpthread/thread/thr_attr_setdetachstate.c
Normal file
59
lib/libpthread/thread/thr_attr_setdetachstate.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL ||
|
||||
(detachstate != PTHREAD_CREATE_DETACHED &&
|
||||
detachstate != PTHREAD_CREATE_JOINABLE))
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if detached state: */
|
||||
if (detachstate == PTHREAD_CREATE_DETACHED)
|
||||
/* Set the detached flag: */
|
||||
(*attr)->flags |= PTHREAD_DETACHED;
|
||||
else
|
||||
/* Reset the detached flag: */
|
||||
(*attr)->flags &= ~PTHREAD_DETACHED;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
52
lib/libpthread/thread/thr_attr_setstackaddr.c
Normal file
52
lib/libpthread/thread/thr_attr_setstackaddr.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack address: */
|
||||
(*attr)->stackaddr_attr = stackaddr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
@ -38,10 +38,12 @@
|
||||
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||
{
|
||||
int ret;
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
} else {
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack size: */
|
||||
(*attr)->stacksize_attr = stacksize;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -37,11 +37,10 @@
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
int
|
||||
_thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
void
|
||||
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))) != NULL) {
|
||||
new->routine = routine;
|
||||
@ -49,15 +48,11 @@ _thread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
new->next = _thread_run->cleanup;
|
||||
|
||||
_thread_run->cleanup = new;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = ENOMEM;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
_thread_cleanup_pop(int execute)
|
||||
pthread_cleanup_pop(int execute)
|
||||
{
|
||||
struct pthread_cleanup *old;
|
||||
|
||||
|
@ -272,7 +272,7 @@ pthread_cond_signal(pthread_cond_t * cond)
|
||||
/* Bring the next thread off the condition queue: */
|
||||
if ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -309,7 +309,7 @@ pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
/* Enter a loop to bring all threads off the condition queue: */
|
||||
while ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
|
||||
/* Allow the thread to run: */
|
||||
pthread->state = PS_RUNNING;
|
||||
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
|
||||
}
|
||||
break;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user