summaryrefslogtreecommitdiffstats
path: root/lib/libc_r
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1997-02-05 23:26:09 +0000
committerjulian <julian@FreeBSD.org>1997-02-05 23:26:09 +0000
commitc2f7c3e4893b6b5c4494d549b3645e06664bc1b1 (patch)
treeb2e6d3017e236268263978b585f2150cd10b1689 /lib/libc_r
parent321f03c8eddd8cf5aa81836ff1932a74156d30cb (diff)
downloadFreeBSD-src-c2f7c3e4893b6b5c4494d549b3645e06664bc1b1.zip
FreeBSD-src-c2f7c3e4893b6b5c4494d549b3645e06664bc1b1.tar.gz
Submitted by: John Birrell
uthreads update from the author.
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/Makefile10
-rw-r--r--lib/libc_r/net/Makefile.inc10
-rw-r--r--lib/libc_r/uthread/Makefile.inc10
-rw-r--r--lib/libc_r/uthread/pthread_private.h59
-rw-r--r--lib/libc_r/uthread/uthread_accept.c4
-rw-r--r--lib/libc_r/uthread/uthread_attr_destroy.c16
-rw-r--r--lib/libc_r/uthread/uthread_attr_getdetachstate.c57
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstackaddr.c52
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstacksize.c52
-rw-r--r--lib/libc_r/uthread/uthread_attr_init.c13
-rw-r--r--lib/libc_r/uthread/uthread_attr_setdetachstate.c59
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstackaddr.c52
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstacksize.c10
-rw-r--r--lib/libc_r/uthread/uthread_clean.c11
-rw-r--r--lib/libc_r/uthread/uthread_cond.c4
-rw-r--r--lib/libc_r/uthread/uthread_condattr_destroy.c52
-rw-r--r--lib/libc_r/uthread/uthread_condattr_init.c58
-rw-r--r--lib/libc_r/uthread/uthread_create.c6
-rw-r--r--lib/libc_r/uthread/uthread_detach.c6
-rw-r--r--lib/libc_r/uthread/uthread_exit.c10
-rw-r--r--lib/libc_r/uthread/uthread_fd.c51
-rw-r--r--lib/libc_r/uthread/uthread_getprio.c2
-rw-r--r--lib/libc_r/uthread/uthread_info.c13
-rw-r--r--lib/libc_r/uthread/uthread_init.c20
-rw-r--r--lib/libc_r/uthread/uthread_join.c32
-rw-r--r--lib/libc_r/uthread/uthread_kern.c71
-rw-r--r--lib/libc_r/uthread/uthread_kill.c78
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c16
-rw-r--r--lib/libc_r/uthread/uthread_mutexattr_destroy.c52
-rw-r--r--lib/libc_r/uthread/uthread_read.c37
-rw-r--r--lib/libc_r/uthread/uthread_readv.c37
-rw-r--r--lib/libc_r/uthread/uthread_resume_np.c6
-rw-r--r--lib/libc_r/uthread/uthread_setprio.c4
-rw-r--r--lib/libc_r/uthread/uthread_shutdown.c2
-rw-r--r--lib/libc_r/uthread/uthread_sig.c2
-rw-r--r--lib/libc_r/uthread/uthread_sigaction.c2
-rw-r--r--lib/libc_r/uthread/uthread_sigmask.c92
-rw-r--r--lib/libc_r/uthread/uthread_sigprocmask.c10
-rw-r--r--lib/libc_r/uthread/uthread_sigsuspend.c2
-rw-r--r--lib/libc_r/uthread/uthread_sigwait.c73
-rw-r--r--lib/libc_r/uthread/uthread_socketpair.c20
-rw-r--r--lib/libc_r/uthread/uthread_spec.c2
-rw-r--r--lib/libc_r/uthread/uthread_suspend_np.c4
-rw-r--r--lib/libc_r/uthread/uthread_write.c37
-rw-r--r--lib/libc_r/uthread/uthread_writev.c37
45 files changed, 1045 insertions, 208 deletions
diff --git a/lib/libc_r/Makefile b/lib/libc_r/Makefile
index f1584ff..dab6210 100644
--- a/lib/libc_r/Makefile
+++ b/lib/libc_r/Makefile
@@ -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>
diff --git a/lib/libc_r/net/Makefile.inc b/lib/libc_r/net/Makefile.inc
index 9e41a60..bb7e4be 100644
--- a/lib/libc_r/net/Makefile.inc
+++ b/lib/libc_r/net/Makefile.inc
@@ -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"
diff --git a/lib/libc_r/uthread/Makefile.inc b/lib/libc_r/uthread/Makefile.inc
index c275b5f..cd85700 100644
--- a/lib/libc_r/uthread/Makefile.inc
+++ b/lib/libc_r/uthread/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 \
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index a16bdea..064888f 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -59,6 +59,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.
*/
struct pthread_queue {
@@ -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);
diff --git a/lib/libc_r/uthread/uthread_accept.c b/lib/libc_r/uthread/uthread_accept.c
index 2aa206e..e240cde 100644
--- a/lib/libc_r/uthread/uthread_accept.c
+++ b/lib/libc_r/uthread/uthread_accept.c
@@ -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);
diff --git a/lib/libc_r/uthread/uthread_attr_destroy.c b/lib/libc_r/uthread/uthread_attr_destroy.c
index be6b2a2..1f4b2c8 100644
--- a/lib/libc_r/uthread/uthread_attr_destroy.c
+++ b/lib/libc_r/uthread/uthread_attr_destroy.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;
}
diff --git a/lib/libc_r/uthread/uthread_attr_getdetachstate.c b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
new file mode 100644
index 0000000..4715cb6
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_attr_getstackaddr.c b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
new file mode 100644
index 0000000..1850a32
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_attr_getstacksize.c b/lib/libc_r/uthread/uthread_attr_getstacksize.c
new file mode 100644
index 0000000..de81106
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getstacksize.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_attr_init.c b/lib/libc_r/uthread/uthread_attr_init.c
index 7dade97..c64e29f 100644
--- a/lib/libc_r/uthread/uthread_attr_init.c
+++ b/lib/libc_r/uthread/uthread_attr_init.c
@@ -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;
}
diff --git a/lib/libc_r/uthread/uthread_attr_setdetachstate.c b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
new file mode 100644
index 0000000..6ec0dbc
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_attr_setstackaddr.c b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
new file mode 100644
index 0000000..ce54915
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_attr_setstacksize.c b/lib/libc_r/uthread/uthread_attr_setstacksize.c
index 5e59798..94e575e 100644
--- a/lib/libc_r/uthread/uthread_attr_setstacksize.c
+++ b/lib/libc_r/uthread/uthread_attr_setstacksize.c
@@ -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;
}
diff --git a/lib/libc_r/uthread/uthread_clean.c b/lib/libc_r/uthread/uthread_clean.c
index 99893f6..9319f85 100644
--- a/lib/libc_r/uthread/uthread_clean.c
+++ b/lib/libc_r/uthread/uthread_clean.c
@@ -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;
diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c
index 4395380..2fe4532 100644
--- a/lib/libc_r/uthread/uthread_cond.c
+++ b/lib/libc_r/uthread/uthread_cond.c
@@ -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;
diff --git a/lib/libc_r/uthread/uthread_condattr_destroy.c b/lib/libc_r/uthread/uthread_condattr_destroy.c
new file mode 100644
index 0000000..b20f183
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_condattr_destroy.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_condattr_init.c b/lib/libc_r/uthread/uthread_condattr_init.c
new file mode 100644
index 0000000..f94e438
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_condattr_init.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index 1d57f8a..e4925a9 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -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);
diff --git a/lib/libc_r/uthread/uthread_detach.c b/lib/libc_r/uthread/uthread_detach.c
index f24d16f..08cace4 100644
--- a/lib/libc_r/uthread/uthread_detach.c
+++ b/lib/libc_r/uthread/uthread_detach.c
@@ -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;
}
diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c
index 6066206..15bcfa3 100644
--- a/lib/libc_r/uthread/uthread_exit.c
+++ b/lib/libc_r/uthread/uthread_exit.c
@@ -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;
diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c
index ad6e9f3..4c74080 100644
--- a/lib/libc_r/uthread/uthread_fd.c
+++ b/lib/libc_r/uthread/uthread_fd.c
@@ -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;
+
+ 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: */
- } else {
- _thread_sys_fcntl(fd, F_SETFL, _thread_fd_table[fd]->flags | O_NONBLOCK);
+ /* 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.
diff --git a/lib/libc_r/uthread/uthread_getprio.c b/lib/libc_r/uthread/uthread_getprio.c
index 345f6ce..85bd261 100644
--- a/lib/libc_r/uthread/uthread_getprio.c
+++ b/lib/libc_r/uthread/uthread_getprio.c
@@ -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: */
diff --git a/lib/libc_r/uthread/uthread_info.c b/lib/libc_r/uthread/uthread_info.c
index e69145f..be25d45 100644
--- a/lib/libc_r/uthread/uthread_info.c
+++ b/lib/libc_r/uthread/uthread_info.c
@@ -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++) {
/*
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index d044063..2adc34f 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -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");
}
diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c
index d0093ae..161482e 100644
--- a/lib/libc_r/uthread/uthread_join.c
+++ b/lib/libc_r/uthread/uthread_join.c
@@ -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);
+ /* 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: */
+ errno = ESRCH;
+ rval = -1;
+
/* Check if this thread has been detached: */
- if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
+ } else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) {
/* Return an error: */
- _thread_seterrno(_thread_run, ESRCH);
+ 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 {
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
index 1db4da6..679b315 100644
--- a/lib/libc_r/uthread/uthread_kern.c
+++ b/lib/libc_r/uthread/uthread_kern.c
@@ -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:
- */
+ /* Waiting on I/O for zero or more file descriptors: */
+ case PS_SELECT_WAIT:
+ 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_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_SELECT_WAIT:
case PS_SLEEP_WAIT:
- case PS_SIGWAIT:
/* 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);
+
+ /* 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);
diff --git a/lib/libc_r/uthread/uthread_kill.c b/lib/libc_r/uthread/uthread_kill.c
new file mode 100644
index 0000000..eb2c6b7
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_kill.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
index dc9be3c..82a26e8 100644
--- a/lib/libc_r/uthread/uthread_mutex.c
+++ b/lib/libc_r/uthread/uthread_mutex.c
@@ -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;
diff --git a/lib/libc_r/uthread/uthread_mutexattr_destroy.c b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
new file mode 100644
index 0000000..cf2e09f
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_read.c b/lib/libc_r/uthread/uthread_read.c
index 9158844..504143d 100644
--- a/lib/libc_r/uthread/uthread_read.c
+++ b/lib/libc_r/uthread/uthread_read.c
@@ -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);
}
diff --git a/lib/libc_r/uthread/uthread_readv.c b/lib/libc_r/uthread/uthread_readv.c
index acb72ac..fed418b 100644
--- a/lib/libc_r/uthread/uthread_readv.c
+++ b/lib/libc_r/uthread/uthread_readv.c
@@ -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);
}
diff --git a/lib/libc_r/uthread/uthread_resume_np.c b/lib/libc_r/uthread/uthread_resume_np.c
index a254814..934df58 100644
--- a/lib/libc_r/uthread/uthread_resume_np.c
+++ b/lib/libc_r/uthread/uthread_resume_np.c
@@ -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);
}
diff --git a/lib/libc_r/uthread/uthread_setprio.c b/lib/libc_r/uthread/uthread_setprio.c
index e052ec3..4b49ed0 100644
--- a/lib/libc_r/uthread/uthread_setprio.c
+++ b/lib/libc_r/uthread/uthread_setprio.c
@@ -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: */
diff --git a/lib/libc_r/uthread/uthread_shutdown.c b/lib/libc_r/uthread/uthread_shutdown.c
index b2e7eac..5e06910 100644
--- a/lib/libc_r/uthread/uthread_shutdown.c
+++ b/lib/libc_r/uthread/uthread_shutdown.c
@@ -62,7 +62,7 @@ shutdown(int fd, int how)
}
break;
default:
- _thread_seterrno(_thread_run, EBADF);
+ errno = EBADF;
ret = -1;
break;
}
diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c
index c3ec191..e73d5a2 100644
--- a/lib/libc_r/uthread/uthread_sig.c
+++ b/lib/libc_r/uthread/uthread_sig.c
@@ -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);
}
}
diff --git a/lib/libc_r/uthread/uthread_sigaction.c b/lib/libc_r/uthread/uthread_sigaction.c
index c733667..dd08405 100644
--- a/lib/libc_r/uthread/uthread_sigaction.c
+++ b/lib/libc_r/uthread/uthread_sigaction.c
@@ -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 {
/*
diff --git a/lib/libc_r/uthread/uthread_sigmask.c b/lib/libc_r/uthread/uthread_sigmask.c
new file mode 100644
index 0000000..94f64cb
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigmask.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_sigprocmask.c b/lib/libc_r/uthread/uthread_sigprocmask.c
index d6e3197..b4a8d84 100644
--- a/lib/libc_r/uthread/uthread_sigprocmask.c
+++ b/lib/libc_r/uthread/uthread_sigprocmask.c
@@ -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;
}
diff --git a/lib/libc_r/uthread/uthread_sigsuspend.c b/lib/libc_r/uthread/uthread_sigsuspend.c
index a26b6b9..14cf74b 100644
--- a/lib/libc_r/uthread/uthread_sigsuspend.c
+++ b/lib/libc_r/uthread/uthread_sigsuspend.c
@@ -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: */
diff --git a/lib/libc_r/uthread/uthread_sigwait.c b/lib/libc_r/uthread/uthread_sigwait.c
new file mode 100644
index 0000000..4f95190
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigwait.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_socketpair.c b/lib/libc_r/uthread/uthread_socketpair.c
index 61da7ae..22e40a6 100644
--- a/lib/libc_r/uthread/uthread_socketpair.c
+++ b/lib/libc_r/uthread/uthread_socketpair.c
@@ -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
diff --git a/lib/libc_r/uthread/uthread_spec.c b/lib/libc_r/uthread/uthread_spec.c
index 4447a75..8d06c52 100644
--- a/lib/libc_r/uthread/uthread_spec.c
+++ b/lib/libc_r/uthread/uthread_spec.c
@@ -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: */
diff --git a/lib/libc_r/uthread/uthread_suspend_np.c b/lib/libc_r/uthread/uthread_suspend_np.c
index fb90c1d..d065b73 100644
--- a/lib/libc_r/uthread/uthread_suspend_np.c
+++ b/lib/libc_r/uthread/uthread_suspend_np.c
@@ -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);
}
diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c
index fb69129..2baa19f 100644
--- a/lib/libc_r/uthread/uthread_write.c
+++ b/lib/libc_r/uthread/uthread_write.c
@@ -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);
}
diff --git a/lib/libc_r/uthread/uthread_writev.c b/lib/libc_r/uthread/uthread_writev.c
index f40e611..2a3c0c8 100644
--- a/lib/libc_r/uthread/uthread_writev.c
+++ b/lib/libc_r/uthread/uthread_writev.c
@@ -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);
}
OpenPOWER on IntegriCloud