mirror of
https://git.freebsd.org/ports.git
synced 2025-06-17 10:40:46 -04:00
1245 lines
40 KiB
Text
1245 lines
40 KiB
Text
diff -ur ./Makefile ../linuxthreads-0.71.new/Makefile
|
|
--- ./Makefile Wed Sep 17 02:17:23 1997
|
|
+++ ../linuxthreads-0.71.new/Makefile Wed Oct 27 18:13:29 1999
|
|
@@ -1,107 +1,74 @@
|
|
-#### Configuration section
|
|
+LIB=lthread
|
|
+SHLIB_MAJOR= 0
|
|
+SHLIB_MINOR= 7
|
|
+
|
|
+.if !defined(MACHINE_ARCH)
|
|
+MACHINE_ARCH!= /usr/bin/uname -m
|
|
+.endif
|
|
+
|
|
+.if !defined(LIBSRC_BASE)
|
|
+LIBSRC_BASE= /usr/src/lib
|
|
+.endif
|
|
+
|
|
+.if !defined(PREFIX)
|
|
+PREFIX= /usr/local
|
|
+.endif
|
|
+
|
|
+LIBDIR= ${PREFIX}/lib
|
|
+
|
|
+.PATH: ${.CURDIR}/libc_r
|
|
+
|
|
+CFLAGS+=-Wall
|
|
+#CFLAGS+=-g -O0 -Wall -DDEBUG
|
|
+CFLAGS+=-DCOMPILING_LINUXTHREADS
|
|
+
|
|
+#This option should not be enabled unless libc has been patched
|
|
+#CLAGS+= -DUSE_RECURSIVE_SPINLOCK
|
|
+
|
|
+# USETHR_FUNCTIONS will use the FreeBSD syscalls thr_sleep and thr_wakeup
|
|
+# instead of the default linux threads suspend/restart. I thought this
|
|
+# would be a lot faster, but in testing, it doesn't seem to be. Also,
|
|
+# there might be a thread exit problem with this code still.
|
|
+#CFLAGS+= -DUSETHR_FUNCTIONS
|
|
+
|
|
+CFLAGS+= -I${.CURDIR}
|
|
+CFLAGS+= -I${LIBSRC_BASE}/libc/stdtime
|
|
+CFLAGS+= -I${LIBSRC_BASE}/libc/${MACHINE_ARCH}
|
|
+CFLAGS+= -DLIBC_RCS
|
|
+CFLAGS+= -DLINUXTHREADS
|
|
+
|
|
+# Only use if libc has been patched to include the new thread safe
|
|
+# lib/libc/stdtime/localtime.c
|
|
+#CFLAGS+= -DNEWLIBC
|
|
|
|
-# Where to install
|
|
-
|
|
-INCLUDEDIR=/usr/include
|
|
-LIBDIR=/usr/lib
|
|
-SHAREDLIBDIR=/lib
|
|
-MANDIR=/usr/man/man3
|
|
-
|
|
-# Compilation options
|
|
-
|
|
-CC=gcc
|
|
-
|
|
-CFLAGS=-pipe -O2 -Wall
|
|
-#CFLAGS+=-g -DDEBUG # for debugging
|
|
-
|
|
-PICCFLAGS=-fpic
|
|
-PICLDFLAGS=-shared -Wl,-soname,$(shell echo $@ | sed 's/\.[^.]$$//')
|
|
-
|
|
-# Define this as "yes" if you're using H.J.Lu's libc 5.2.18, 5.3.12, or 5.4.x
|
|
-# (standard on most Linux distributions for Intel processors).
|
|
-# Define this as "no" if you're using a different C library,
|
|
-# e.g. libc 6, also known as glibc
|
|
-
|
|
-LIBC_5_SUPPORT=yes
|
|
-
|
|
-#### End of configuration section
|
|
-
|
|
-# Determine architecture
|
|
-
|
|
-ARCH:=$(shell uname -m | sed -e 's/i.86/i386/')
|
|
-
|
|
-ifeq ($(ARCH),i386)
|
|
-CFLAGS+=-m486
|
|
-endif
|
|
-
|
|
-CFLAGS+=-D__BUILDING_LINUXTHREADS -Isysdeps/$(ARCH)
|
|
+AINC= -I${LIBSRC_BASE}/libc/${MACHINE_ARCH}
|
|
|
|
# Contents of the library
|
|
-OBJS=pthread.o manager.o attr.o join.o mutex.o condvar.o specific.o cancel.o \
|
|
- signals.o lockfile.o errno.o fork.o sleep.o semaphore.o
|
|
+SRCS= attr.c join.c mutex.c condvar.c specific.c cancel.c
|
|
+SRCS+= signals.c fork.c errno.c manager.c pthread.c
|
|
+SRCS+= clone.S _atomic_lock.S sched.c uthread_file.c lclone.c
|
|
+SRCS+= getservby_r.c getpw_r.c getprotoby_r.c getnetby_r.c gethostby_r.c
|
|
+SRCS+= getgr_r.c libc_thread.c uthread_rwlock.c uthread_rwlockattr.c
|
|
+SRCS+= stack.c stack_attr.c
|
|
+#Note: spinlock.c appears redundant to the spinlock calls in linux threads.
|
|
+#However, this particular implementation is needed to make libc thread
|
|
+#safe. the _spinlock call overrides a stub function in libc.
|
|
+SRCS+= spinlock.c
|
|
+
|
|
+#libc is not ready for this
|
|
+#SRCS+= syscalls.c libc_calls.c
|
|
+
|
|
+beforeinstall:
|
|
+ ${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 555 \
|
|
+ ${PREFIX}/include/pthread/linuxthreads
|
|
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/pthread.h \
|
|
+ ${PREFIX}/include/pthread/linuxthreads/pthread.h
|
|
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/pthread_rw.h \
|
|
+ ${PREFIX}/include/pthread/linuxthreads/pthread_rw.h
|
|
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/pthread_stack.h \
|
|
+ ${PREFIX}/include/pthread/linuxthreads/pthread_stack.h
|
|
+
|
|
+.include <bsd.lib.mk>
|
|
|
|
-ifneq ($(wildcard sysdeps/$(ARCH)/clone.[cS]),)
|
|
-OBJS+=clone.o
|
|
-endif
|
|
-ifneq ($(wildcard sysdeps/$(ARCH)/syscalls.[cS]),)
|
|
-OBJS+=syscalls.o
|
|
-endif
|
|
-
|
|
-vpath %.c sysdeps/$(ARCH)
|
|
-vpath %.S sysdeps/$(ARCH)
|
|
-
|
|
-# The reentrant libc code (taken from libc-5.3.9)
|
|
-ifeq ($(LIBC_5_SUPPORT),yes)
|
|
-vpath %.h libc_r
|
|
-vpath %.c libc_r
|
|
-CFLAGS+=-Ilibc_r -D_POSIX_THREADS
|
|
-OBJS+=stdio.o getnetby_r.o getprotoby_r.o getservby_r.o \
|
|
- gethostby_r.o getpw_r.o malloc.o dirent.o
|
|
-endif
|
|
-
|
|
-LIB=libpthread.a
|
|
-SHOBJS=$(OBJS:%.o=%.pic)
|
|
-SHLIB=libpthread.so.0.7
|
|
-SHLIB0=libpthread.so
|
|
-
|
|
-all: $(LIB) $(SHLIB)
|
|
- cd man; $(MAKE) all
|
|
-
|
|
-$(LIB): $(OBJS)
|
|
- ar rc $(LIB) $(OBJS)
|
|
-
|
|
-$(SHLIB): $(SHOBJS)
|
|
- $(CC) $(PICLDFLAGS) -o $@ $(SHOBJS)
|
|
-
|
|
-clean:
|
|
- rm -f $(LIB) $(SHLIB) *.o *.pic *~ libc_r/*~ sysdeps/*/*~
|
|
- cd man; $(MAKE) clean
|
|
-
|
|
-install:
|
|
- install pthread.h $(INCLUDEDIR)/pthread.h
|
|
- install semaphore.h $(INCLUDEDIR)/semaphore.h
|
|
-ifeq ($(LIBC_5_SUPPORT),yes)
|
|
- test -f /usr/include/sched.h || install sched.h $(INCLUDEDIR)/sched.h
|
|
-endif
|
|
- install $(LIB) $(LIBDIR)/$(LIB)
|
|
- install $(SHLIB) $(SHAREDLIBDIR)/$(SHLIB)
|
|
- rm -f $(LIBDIR)/$(SHLIB0)
|
|
- ln -s $(SHAREDLIBDIR)/$(SHLIB) $(LIBDIR)/$(SHLIB0)
|
|
- ldconfig -n $(SHAREDLIBDIR)
|
|
- cd man; $(MAKE) MANDIR=$(MANDIR) install
|
|
-
|
|
-.SUFFIXES: .pic
|
|
-
|
|
-%.pic: %.c
|
|
- $(CC) $(CFLAGS) $(PICCFLAGS) -c $< -o $@
|
|
-
|
|
-%.pic: %.S
|
|
- $(CC) $(CFLAGS) $(PICCFLAGS) -c $< -o $@
|
|
-
|
|
-depend:
|
|
- $(CC) $(CFLAGS) -MM *.c libc_r/*.c | \
|
|
- sed -e 's/^\(.*\)\.o:/\1.o \1.pic:/' \
|
|
- -e 's/sysdeps\/$(ARCH)/sysdeps\/$$(ARCH)/' > .depend
|
|
|
|
-include .depend
|
|
|
|
Only in ../linuxthreads-0.71.new: README.FreeBSD
|
|
Only in ../linuxthreads-0.71.new: _atomic_lock.S
|
|
diff -ur ./attr.c ../linuxthreads-0.71.new/attr.c
|
|
--- ./attr.c Sun Mar 9 10:14:32 1997
|
|
+++ ../linuxthreads-0.71.new/attr.c Wed Oct 27 18:13:29 1999
|
|
@@ -22,10 +22,10 @@
|
|
{
|
|
attr->detachstate = PTHREAD_CREATE_JOINABLE;
|
|
attr->schedpolicy = SCHED_OTHER;
|
|
- attr->schedparam.sched_priority = 0;
|
|
+ attr->schedparam.sched_priority = DEFAULT_PRIORITY;
|
|
attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
|
|
attr->scope = PTHREAD_SCOPE_SYSTEM;
|
|
- return 0;
|
|
+ return (_pthread_set_stack_defaults (attr));
|
|
}
|
|
|
|
int pthread_attr_destroy(pthread_attr_t *attr)
|
|
diff -ur ./cancel.c ../linuxthreads-0.71.new/cancel.c
|
|
--- ./cancel.c Sun Dec 29 08:12:09 1996
|
|
+++ ../linuxthreads-0.71.new/cancel.c Wed Oct 27 18:13:29 1999
|
|
@@ -16,7 +16,6 @@
|
|
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "restart.h"
|
|
|
|
int pthread_setcancelstate(int state, int * oldstate)
|
|
Only in ../linuxthreads-0.71.new: clone.S
|
|
Only in ../linuxthreads-0.71.new: clone.h
|
|
diff -ur ./condvar.c ../linuxthreads-0.71.new/condvar.c
|
|
--- ./condvar.c Sun Jun 15 03:26:04 1997
|
|
+++ ../linuxthreads-0.71.new/condvar.c Wed Oct 27 18:13:29 1999
|
|
@@ -19,16 +19,13 @@
|
|
#include <sys/time.h>
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "queue.h"
|
|
#include "restart.h"
|
|
|
|
-static void remove_from_queue(pthread_queue * q, pthread_descr th);
|
|
-
|
|
int pthread_cond_init(pthread_cond_t *cond,
|
|
const pthread_condattr_t *cond_attr)
|
|
{
|
|
- cond->c_spinlock = 0;
|
|
+ _spin_init(&cond->c_spinlock);
|
|
queue_init(&cond->c_waiting);
|
|
return 0;
|
|
}
|
|
@@ -52,6 +49,7 @@
|
|
release(&cond->c_spinlock);
|
|
pthread_mutex_unlock(mutex);
|
|
suspend_with_cancellation(self);
|
|
+ ASSERT(self->p_nextwaiting == NULL && cond->c_waiting.head != self);
|
|
pthread_mutex_lock(mutex);
|
|
/* This is a cancellation point */
|
|
if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
|
|
@@ -70,8 +68,9 @@
|
|
const struct timespec * reltime)
|
|
{
|
|
volatile pthread_descr self = thread_self();
|
|
- sigset_t unblock, initial_mask;
|
|
int retsleep;
|
|
+#ifndef USETHR_FUNCTIONS
|
|
+ sigset_t unblock, initial_mask;
|
|
sigjmp_buf jmpbuf;
|
|
|
|
/* Wait on the condition */
|
|
@@ -107,24 +106,39 @@
|
|
or the timeout occurred (retsleep == 0)
|
|
or another interrupt occurred (retsleep == -1) */
|
|
/* Re-acquire the spinlock */
|
|
- acquire(&cond->c_spinlock);
|
|
/* This is a cancellation point */
|
|
- if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
|
|
- remove_from_queue(&cond->c_waiting, self);
|
|
- release(&cond->c_spinlock);
|
|
- pthread_mutex_lock(mutex);
|
|
+ acquire(&cond->c_spinlock);
|
|
+ remove_from_queue(&cond->c_waiting, self);
|
|
+ release(&cond->c_spinlock);
|
|
+ pthread_mutex_lock(mutex);
|
|
+ if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE)
|
|
pthread_exit(PTHREAD_CANCELED);
|
|
- }
|
|
/* If not signaled: also remove ourselves and return an error code */
|
|
- if (self->p_signal == 0) {
|
|
- remove_from_queue(&cond->c_waiting, self);
|
|
- release(&cond->c_spinlock);
|
|
- pthread_mutex_lock(mutex);
|
|
+ if (self->p_signal == 0)
|
|
return retsleep == 0 ? ETIMEDOUT : EINTR;
|
|
- }
|
|
- /* Otherwise, return normally */
|
|
+#else
|
|
+ acquire(&cond->c_spinlock);
|
|
+ enqueue(&cond->c_waiting, self);
|
|
+ release(&cond->c_spinlock);
|
|
+ pthread_mutex_unlock(mutex);
|
|
+ retsleep = 0;
|
|
+ if (!(self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE))
|
|
+ /* We really should make thr_sleep return EINTR too. It just
|
|
+ returns EAGAIN if it timed out, or 0 if awakened (or
|
|
+ EINVAL if bad parameter.
|
|
+ */
|
|
+ retsleep = syscall(SYS_thr_sleep, reltime);
|
|
+
|
|
+ acquire(&cond->c_spinlock);
|
|
+ if (self->p_nextwaiting != NULL || cond->c_waiting.head == self)
|
|
+ remove_from_queue(&cond->c_waiting, self);
|
|
release(&cond->c_spinlock);
|
|
pthread_mutex_lock(mutex);
|
|
+ if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE)
|
|
+ pthread_exit(PTHREAD_CANCELED);
|
|
+ if (retsleep)
|
|
+ return retsleep == EAGAIN ? ETIMEDOUT : EINTR;
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -181,25 +195,24 @@
|
|
return 0;
|
|
}
|
|
|
|
-/* Auxiliary function on queues */
|
|
-
|
|
-static void remove_from_queue(pthread_queue * q, pthread_descr th)
|
|
+int remove_from_queue(pthread_queue * q, pthread_descr th)
|
|
{
|
|
pthread_descr t;
|
|
|
|
- if (q->head == NULL) return;
|
|
+ if (q->head == NULL) return 0;
|
|
if (q->head == th) {
|
|
q->head = th->p_nextwaiting;
|
|
if (q->head == NULL) q->tail = NULL;
|
|
th->p_nextwaiting = NULL;
|
|
- return;
|
|
+ return 1;
|
|
}
|
|
for (t = q->head; t->p_nextwaiting != NULL; t = t->p_nextwaiting) {
|
|
if (t->p_nextwaiting == th) {
|
|
t->p_nextwaiting = th->p_nextwaiting;
|
|
if (th->p_nextwaiting == NULL) q->tail = t;
|
|
th->p_nextwaiting = NULL;
|
|
- return;
|
|
+ return 1;
|
|
}
|
|
}
|
|
+ return 0;
|
|
}
|
|
diff -ur ./errno.c ../linuxthreads-0.71.new/errno.c
|
|
--- ./errno.c Sun Dec 29 06:05:37 1996
|
|
+++ ../linuxthreads-0.71.new/errno.c Wed Oct 27 18:13:29 1999
|
|
@@ -19,15 +19,8 @@
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
|
|
-int * __errno_location()
|
|
+int * __error()
|
|
{
|
|
pthread_descr self = thread_self();
|
|
return &(self->p_errno);
|
|
}
|
|
-
|
|
-int * __h_errno_location()
|
|
-{
|
|
- pthread_descr self = thread_self();
|
|
- return &(self->p_h_errno);
|
|
-}
|
|
-
|
|
Only in ../linuxthreads-0.71.new: getgr_r.c
|
|
diff -ur ./internals.h ../linuxthreads-0.71.new/internals.h
|
|
--- ./internals.h Fri Dec 5 02:28:20 1997
|
|
+++ ../linuxthreads-0.71.new/internals.h Wed Oct 27 18:15:29 1999
|
|
@@ -17,12 +17,37 @@
|
|
/* Includes */
|
|
|
|
#include <sys/types.h>
|
|
+#include <sys/queue.h>
|
|
+#include <sys/mman.h>
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
-#include <gnu-stabs.h> /* for weak_alias */
|
|
-#include <linux/mm.h>
|
|
+#include "clone.h"
|
|
+#include "spinlock.h"
|
|
+#include "private.h"
|
|
+
|
|
+#define __getpid getpid
|
|
+#define __fork _fork
|
|
+#define __nanosleep _nanosleep
|
|
+#if 0
|
|
+#define __WCLONE WLINUXCLONE
|
|
+#else
|
|
+#define __WCLONE clone_flag
|
|
+#endif
|
|
+#ifndef MAP_STACK
|
|
+#define MAP_STACK 0
|
|
+#endif
|
|
+#define DEFAULT_PRIORITY 20
|
|
+#define THREAD_SELF \
|
|
+{ \
|
|
+ char *sp = CURRENT_STACK_FRAME; \
|
|
+ if (sp >= __pthread_initial_thread_bos) \
|
|
+ return &__pthread_initial_thread; \
|
|
+ else if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos) \
|
|
+ return &__pthread_manager_thread; \
|
|
+ else \
|
|
+ return GET_TLS_FROM_STACK(sp); \
|
|
+}
|
|
|
|
-#include "pt-machine.h"
|
|
|
|
/* Arguments passed to thread creation routine */
|
|
|
|
@@ -34,7 +59,7 @@
|
|
struct sched_param schedparam; /* initial scheduling parameters (if any) */
|
|
};
|
|
|
|
-#define PTHREAD_START_ARGS_INITIALIZER { NULL, NULL, 0, 0, { 0 } }
|
|
+#define PTHREAD_START_ARGS_INITIALIZER { NULL, NULL, { { 0 } }, 0, { 0 } }
|
|
|
|
/* We keep thread specific data in a special data structure, a two-level
|
|
array. The top-level array contains pointers to dynamically allocated
|
|
@@ -61,7 +86,7 @@
|
|
pthread_t p_tid; /* Thread identifier */
|
|
int p_pid; /* PID of Unix process */
|
|
int p_priority; /* Thread priority (== 0 if not realtime) */
|
|
- int * p_spinlock; /* Spinlock for synchronized accesses */
|
|
+ spinlock_t * p_spinlock; /* Spinlock for synchronized accesses */
|
|
int p_signal; /* last signal received */
|
|
sigjmp_buf * p_signal_jmp; /* where to siglongjmp on a signal or NULL */
|
|
sigjmp_buf * p_cancel_jmp; /* where to siglongjmp on a cancel or NULL */
|
|
@@ -77,16 +102,20 @@
|
|
char p_canceled; /* cancellation request pending */
|
|
int p_errno; /* error returned by last system call */
|
|
int p_h_errno; /* error returned by last netdb function */
|
|
+ int stacksize;
|
|
+ pthread_mutex_t smutex;
|
|
struct pthread_start_args p_start_args; /* arguments for thread creation */
|
|
void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */
|
|
+ TAILQ_ENTRY(_pthread_descr_struct) qe;
|
|
+ char time_buf[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + 3 + 2 + 1 + 1];
|
|
+ struct tm local_tm;
|
|
};
|
|
|
|
/* The type of thread handles. */
|
|
|
|
typedef struct pthread_handle_struct * pthread_handle;
|
|
-
|
|
struct pthread_handle_struct {
|
|
- int h_spinlock; /* Spinlock for sychronized access */
|
|
+ spinlock_t h_spinlock; /* Spinlock for sychronized access */
|
|
pthread_descr h_descr; /* Thread descriptor or NULL if invalid */
|
|
};
|
|
|
|
@@ -255,12 +284,13 @@
|
|
void __pthread_reset_main_thread(void);
|
|
void __fresetlockfiles(void);
|
|
|
|
-/* System calls not declared in libc 5 */
|
|
+int _sigsuspend __P((const sigset_t *));
|
|
+pid_t _fork __P((void));
|
|
+ssize_t _write __P((int, const void *, size_t));
|
|
+int _close __P((int));
|
|
+int _nanosleep __P((const struct timespec *, struct timespec *));
|
|
+int _sched_yield __P((void));
|
|
|
|
-int __clone(int (*child_function)(void *), void ** child_stack, int flags,
|
|
- void * arg);
|
|
-int __nanosleep(const struct timespec * rqtp, struct timespec * rmtp);
|
|
-int __sched_yield(void);
|
|
int __sched_setparam(pid_t pid, const struct sched_param *param);
|
|
int __sched_getparam(pid_t pid, struct sched_param *param);
|
|
int __sched_setscheduler(pid_t pid, int policy,
|
|
diff -ur ./join.c ../linuxthreads-0.71.new/join.c
|
|
--- ./join.c Sun Dec 29 08:12:10 1996
|
|
+++ ../linuxthreads-0.71.new/join.c Wed Oct 27 18:13:29 1999
|
|
@@ -17,7 +17,6 @@
|
|
#include <unistd.h>
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "restart.h"
|
|
|
|
void pthread_exit(void * retval)
|
|
@@ -48,7 +47,7 @@
|
|
if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
|
|
request.req_thread = self;
|
|
request.req_kind = REQ_MAIN_THREAD_EXIT;
|
|
- write(__pthread_manager_request, (char *)&request, sizeof(request));
|
|
+ _write(__pthread_manager_request, (char *)&request, sizeof(request));
|
|
suspend(self);
|
|
}
|
|
/* Exit the process (but don't flush stdio streams, and don't run
|
|
@@ -98,7 +97,7 @@
|
|
request.req_thread = self;
|
|
request.req_kind = REQ_FREE;
|
|
request.req_args.free.thread = th;
|
|
- write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
+ _write(__pthread_manager_request, (char *)&request, sizeof(request));
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -135,7 +134,7 @@
|
|
request.req_thread = thread_self();
|
|
request.req_kind = REQ_FREE;
|
|
request.req_args.free.thread = th;
|
|
- write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
+ _write(__pthread_manager_request, (char *)&request, sizeof(request));
|
|
}
|
|
return 0;
|
|
}
|
|
Only in ../linuxthreads-0.71.new: lclone.c
|
|
Only in ../linuxthreads-0.71.new: libc_calls.c
|
|
Only in ../linuxthreads-0.71.new: libc_private.h
|
|
diff -ur ./libc_r/getprotoby_r.c ../linuxthreads-0.71.new/libc_r/getprotoby_r.c
|
|
--- ./libc_r/getprotoby_r.c Sat Nov 16 06:38:10 1996
|
|
+++ ../linuxthreads-0.71.new/libc_r/getprotoby_r.c Wed Oct 27 18:13:29 1999
|
|
@@ -1,4 +1,4 @@
|
|
-#include "../pthread.h"
|
|
+#include "pthread.h"
|
|
#include <netdb.h>
|
|
#include <string.h>
|
|
|
|
Only in ../linuxthreads-0.71.new/libc_r: getprotoby_r.c.orig
|
|
diff -ur ./libc_r/getpw_r.c ../linuxthreads-0.71.new/libc_r/getpw_r.c
|
|
--- ./libc_r/getpw_r.c Sat Nov 2 08:01:49 1996
|
|
+++ ../linuxthreads-0.71.new/libc_r/getpw_r.c Wed Oct 27 18:13:29 1999
|
|
@@ -2,7 +2,7 @@
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <pwd.h>
|
|
-#include "../pthread.h"
|
|
+#include "pthread.h"
|
|
|
|
static pthread_mutex_t getpw_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
Only in ../linuxthreads-0.71.new/libc_r: getpw_r.c.orig
|
|
diff -ur ./libc_r/getservby_r.c ../linuxthreads-0.71.new/libc_r/getservby_r.c
|
|
--- ./libc_r/getservby_r.c Sat Nov 16 06:38:10 1996
|
|
+++ ../linuxthreads-0.71.new/libc_r/getservby_r.c Wed Oct 27 18:13:29 1999
|
|
@@ -1,4 +1,4 @@
|
|
-#include "../pthread.h"
|
|
+#include "pthread.h"
|
|
#include <netdb.h>
|
|
#include <string.h>
|
|
|
|
Only in ../linuxthreads-0.71.new/libc_r: getservby_r.c.orig
|
|
Only in ../linuxthreads-0.71.new: libc_spinlock.h
|
|
Only in ../linuxthreads-0.71.new: libc_thread.c
|
|
diff -ur ./manager.c ../linuxthreads-0.71.new/manager.c
|
|
--- ./manager.c Mon Dec 1 02:48:51 1997
|
|
+++ ../linuxthreads-0.71.new/manager.c Wed Oct 27 18:13:29 1999
|
|
@@ -22,20 +22,16 @@
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h> /* for select */
|
|
-#include <sys/types.h> /* for select */
|
|
-#include <sys/mman.h> /* for mmap */
|
|
#include <sys/wait.h> /* for waitpid macros */
|
|
-#include <linux/sched.h>
|
|
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "restart.h"
|
|
|
|
/* Array of active threads. Entry 0 is reserved for the initial thread. */
|
|
|
|
struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
|
|
-{ { 0, &__pthread_initial_thread}, /* All NULLs */ };
|
|
+{ { _SPINLOCK_INITIALIZER, &__pthread_initial_thread}, /* All NULLs */ };
|
|
|
|
/* Mapping from stack segment to thread descriptor. */
|
|
/* Stack segment numbers are also indices into the __pthread_handles array. */
|
|
@@ -43,7 +39,7 @@
|
|
|
|
static inline pthread_descr thread_segment(int seg)
|
|
{
|
|
- return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
|
|
+ return (pthread_descr)(_thread_stack_start - (seg - 1) * _stackspacing)
|
|
- 1;
|
|
}
|
|
|
|
@@ -71,6 +67,8 @@
|
|
static void pthread_reap_children();
|
|
static void pthread_kill_all_threads(int sig, int main_thread_also);
|
|
|
|
+extern int clone_flag;
|
|
+
|
|
/* The server thread managing requests for thread creation and termination */
|
|
|
|
int __pthread_manager(void * arg)
|
|
@@ -147,6 +145,9 @@
|
|
{
|
|
pthread_descr self = (pthread_descr) arg;
|
|
void * outcome;
|
|
+
|
|
+ pthread_mutex_lock (&self->smutex);
|
|
+
|
|
/* Initialize special thread_self processing, if any. */
|
|
#ifdef INIT_THREAD_SELF
|
|
INIT_THREAD_SELF(self);
|
|
@@ -157,9 +158,8 @@
|
|
/* Initial signal mask is that of the creating thread. (Otherwise,
|
|
we'd just inherit the mask of the thread manager.) */
|
|
sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL);
|
|
- /* Set the scheduling policy and priority for the new thread, if needed */
|
|
- if (self->p_start_args.schedpolicy != SCHED_OTHER)
|
|
- __sched_setscheduler(self->p_pid, self->p_start_args.schedpolicy,
|
|
+ /* Set the scheduling policy and priority for the new thread */
|
|
+ __sched_setscheduler(self->p_pid, self->p_start_args.schedpolicy,
|
|
&self->p_start_args.schedparam);
|
|
/* Run the thread code */
|
|
outcome = self->p_start_args.start_routine(self->p_start_args.arg);
|
|
@@ -176,27 +176,47 @@
|
|
int pid;
|
|
pthread_descr new_thread;
|
|
pthread_t new_thread_id;
|
|
+ pthread_attr_t *cattr, _cattr;
|
|
int i;
|
|
+ caddr_t newaddr;
|
|
+ int newsize;
|
|
+
|
|
+ cattr = &_cattr;
|
|
+ if (attr == NULL) {
|
|
+ pthread_attr_init (cattr);
|
|
+ } else {
|
|
+ _cattr = *attr;
|
|
+ if (_pthread_check_stackattr (cattr)){
|
|
+ return (EINVAL);
|
|
+ }
|
|
+ }
|
|
+ newsize = _tlspagesize + cattr->stack_size;
|
|
|
|
/* Find a free stack segment for the current stack */
|
|
for (sseg = 1; ; sseg++) {
|
|
if (sseg >= PTHREAD_THREADS_MAX) return EAGAIN;
|
|
+ /* XXXX do we need to acquire a lock on the handle here ? */
|
|
if (__pthread_handles[sseg].h_descr != NULL) continue;
|
|
new_thread = thread_segment(sseg);
|
|
+ if (cattr->stack_addr != NULL && cattr->stack_addr != new_thread)
|
|
+ continue;
|
|
/* Allocate space for stack and thread descriptor. */
|
|
- if (mmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
|
|
- INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN, -1, 0)
|
|
- != (caddr_t) -1) break;
|
|
+ newaddr = (caddr_t)(new_thread+1) - newsize;
|
|
+ if (mmap(newaddr, newsize,
|
|
+ PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
+ MAP_STACK | MAP_PRIVATE | MAP_ANON | MAP_FIXED,
|
|
+ -1, 0)
|
|
+ != MAP_FAILED) break;
|
|
/* It seems part of this segment is already mapped. Try the next. */
|
|
}
|
|
+
|
|
/* Allocate new thread identifier */
|
|
pthread_threads_counter += PTHREAD_THREADS_MAX;
|
|
new_thread_id = sseg + pthread_threads_counter;
|
|
/* Initialize the thread descriptor */
|
|
new_thread->p_nextwaiting = NULL;
|
|
new_thread->p_tid = new_thread_id;
|
|
- new_thread->p_priority = 0;
|
|
+ new_thread->p_priority = DEFAULT_PRIORITY;
|
|
new_thread->p_spinlock = &(__pthread_handles[sseg].h_spinlock);
|
|
new_thread->p_signal = 0;
|
|
new_thread->p_signal_jmp = NULL;
|
|
@@ -212,14 +232,16 @@
|
|
new_thread->p_canceled = 0;
|
|
new_thread->p_errno = 0;
|
|
new_thread->p_h_errno = 0;
|
|
+ new_thread->stacksize = newsize;
|
|
for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++)
|
|
new_thread->p_specific[i] = NULL;
|
|
/* Initialize the thread handle */
|
|
- __pthread_handles[sseg].h_spinlock = 0; /* should already be 0 */
|
|
+ _spin_init (new_thread->p_spinlock);
|
|
__pthread_handles[sseg].h_descr = new_thread;
|
|
/* Determine scheduling parameters for the thread */
|
|
new_thread->p_start_args.schedpolicy = SCHED_OTHER;
|
|
- if (attr != NULL && attr->schedpolicy != SCHED_OTHER) {
|
|
+ new_thread->p_start_args.schedparam.sched_priority = new_thread->p_priority;
|
|
+ if (attr != NULL) {
|
|
switch(attr->inheritsched) {
|
|
case PTHREAD_EXPLICIT_SCHED:
|
|
new_thread->p_start_args.schedpolicy = attr->schedpolicy;
|
|
@@ -237,6 +259,9 @@
|
|
new_thread->p_start_args.start_routine = start_routine;
|
|
new_thread->p_start_args.arg = arg;
|
|
new_thread->p_start_args.mask = *mask;
|
|
+
|
|
+ pthread_mutex_init (&new_thread->smutex, NULL);
|
|
+ pthread_mutex_lock (&new_thread->smutex);
|
|
/* Do the cloning */
|
|
pid = __clone(pthread_start_thread, (void **) new_thread,
|
|
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
|
@@ -245,11 +270,15 @@
|
|
/* Check if cloning succeeded */
|
|
if (pid == -1) {
|
|
/* Free the stack */
|
|
- munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
|
|
- INITIAL_STACK_SIZE);
|
|
+ munmap(newaddr, newsize);
|
|
__pthread_handles[sseg].h_descr = NULL;
|
|
- return errno;
|
|
+ return EAGAIN;
|
|
}
|
|
+ /* Shouldn't we have blocked pthread_start_thread at its inception
|
|
+ so we can complete the rest of the pthread_create routines
|
|
+ before it runs? Otherwise, pthread_start_thread and its
|
|
+ user function can begin before we're done?
|
|
+ */
|
|
/* Insert new thread in doubly linked list of active threads */
|
|
new_thread->p_prevlive = __pthread_main_thread;
|
|
new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
|
|
@@ -260,6 +289,7 @@
|
|
new_thread->p_pid = pid;
|
|
/* We're all set */
|
|
*thread = new_thread_id;
|
|
+ pthread_mutex_unlock (&new_thread->smutex);
|
|
return 0;
|
|
}
|
|
|
|
@@ -277,7 +307,7 @@
|
|
/* If initial thread, nothing to free */
|
|
if (th == &__pthread_initial_thread) return;
|
|
/* Free the stack and thread descriptor area */
|
|
- munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
|
|
+ munmap((caddr_t) ((char *)(th+1) - th->stacksize), th->stacksize);
|
|
}
|
|
|
|
/* Handle threads that have exited */
|
|
diff -ur ./mutex.c ../linuxthreads-0.71.new/mutex.c
|
|
--- ./mutex.c Thu Dec 4 06:33:42 1997
|
|
+++ ../linuxthreads-0.71.new/mutex.c Wed Oct 27 18:13:29 1999
|
|
@@ -17,14 +17,13 @@
|
|
#include <stddef.h>
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "queue.h"
|
|
#include "restart.h"
|
|
|
|
int pthread_mutex_init(pthread_mutex_t * mutex,
|
|
const pthread_mutexattr_t * mutex_attr)
|
|
{
|
|
- mutex->m_spinlock = 0;
|
|
+ _spin_init (&mutex->m_spinlock);
|
|
mutex->m_count = 0;
|
|
mutex->m_owner = NULL;
|
|
mutex->m_kind =
|
|
@@ -84,10 +83,11 @@
|
|
|
|
int pthread_mutex_lock(pthread_mutex_t * mutex)
|
|
{
|
|
- pthread_descr self;
|
|
+ pthread_descr self = thread_self();
|
|
|
|
while(1) {
|
|
acquire(&mutex->m_spinlock);
|
|
+ remove_from_queue(&mutex->m_waiting, self);
|
|
switch(mutex->m_kind) {
|
|
case PTHREAD_MUTEX_FAST_NP:
|
|
if (mutex->m_count == 0) {
|
|
@@ -95,10 +95,8 @@
|
|
release(&mutex->m_spinlock);
|
|
return 0;
|
|
}
|
|
- self = thread_self();
|
|
break;
|
|
case PTHREAD_MUTEX_RECURSIVE_NP:
|
|
- self = thread_self();
|
|
if (mutex->m_count == 0 || mutex->m_owner == self) {
|
|
mutex->m_count++;
|
|
mutex->m_owner = self;
|
|
@@ -107,7 +105,6 @@
|
|
}
|
|
break;
|
|
case PTHREAD_MUTEX_ERRORCHECK_NP:
|
|
- self = thread_self();
|
|
if (mutex->m_count == 0) {
|
|
mutex->m_count = 1;
|
|
mutex->m_owner = self;
|
|
@@ -183,14 +180,14 @@
|
|
attr->mutexkind = kind;
|
|
return 0;
|
|
}
|
|
-weak_alias(__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np);
|
|
+#pragma weak pthread_mutexattr_setkind_np=__pthread_mutexattr_setkind_np
|
|
|
|
int __pthread_mutexattr_getkind_np(const pthread_mutexattr_t *attr, int *kind)
|
|
{
|
|
*kind = attr->mutexkind;
|
|
return 0;
|
|
}
|
|
-weak_alias(__pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np);
|
|
+#pragma weak pthread_mutexattr_getkind_np=__pthread_mutexattr_getkind_np
|
|
|
|
/* Once-only execution */
|
|
|
|
@@ -223,18 +220,3 @@
|
|
return 0;
|
|
}
|
|
|
|
-/* Internal locks for libc 5.2.18 */
|
|
-
|
|
-static pthread_mutex_t libc_libio_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
-static pthread_mutex_t libc_localtime_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
-static pthread_mutex_t libc_gmtime_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
-
|
|
-/* The variables below are defined as weak symbols in libc,
|
|
- initialized to NULL pointers, and with dummy pthread_mutex_*
|
|
- functions (weak symbols also) that do nothing. If we provide
|
|
- our implementations of pthread_mutex_*, we must also provide
|
|
- initialized pointers to mutexes for those variables. */
|
|
-
|
|
-pthread_mutex_t * __libc_libio_lock = &libc_libio_lock;
|
|
-pthread_mutex_t * __libc_localtime_lock = &libc_localtime_lock;
|
|
-pthread_mutex_t * __libc_gmtime_lock = &libc_gmtime_lock;
|
|
diff -ur ./pthread.c ../linuxthreads-0.71.new/pthread.c
|
|
--- ./pthread.c Sun Nov 23 09:58:49 1997
|
|
+++ ../linuxthreads-0.71.new/pthread.c Wed Oct 27 18:13:29 1999
|
|
@@ -1,4 +1,4 @@
|
|
-/* Linuxthreads - a simple clone()-based implementation of Posix */
|
|
+/* Linuxthread - a simple clone()-based implementation of Posix */
|
|
/* threads for Linux. */
|
|
/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
|
|
/* */
|
|
@@ -24,7 +24,6 @@
|
|
#include <sys/wait.h>
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
#include "restart.h"
|
|
|
|
/* Descriptor of the initial thread */
|
|
@@ -35,7 +34,7 @@
|
|
NULL, /* pthread_descr p_nextwaiting */
|
|
PTHREAD_THREADS_MAX, /* pthread_t p_tid */
|
|
0, /* int p_pid */
|
|
- 0, /* int p_priority */
|
|
+ DEFAULT_PRIORITY, /* int p_priority */
|
|
&__pthread_handles[0].h_spinlock, /* int * p_spinlock */
|
|
0, /* int p_signal */
|
|
NULL, /* sigjmp_buf * p_signal_buf */
|
|
@@ -52,6 +51,8 @@
|
|
0, /* char p_canceled */
|
|
0, /* int p_errno */
|
|
0, /* int p_h_errno */
|
|
+ 0, /* int stacksize */
|
|
+ PTHREAD_MUTEX_INITIALIZER,
|
|
PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
|
|
{NULL} /* void ** p_specific[PTHREAD_KEY_1STLEVEL] */
|
|
};
|
|
@@ -65,7 +66,7 @@
|
|
NULL, /* pthread_descr p_nextwaiting */
|
|
0, /* int p_tid */
|
|
0, /* int p_pid */
|
|
- 0, /* int p_priority */
|
|
+ DEFAULT_PRIORITY, /* int p_priority */
|
|
NULL, /* int * p_spinlock */
|
|
0, /* int p_signal */
|
|
NULL, /* sigjmp_buf * p_signal_buf */
|
|
@@ -82,6 +83,8 @@
|
|
0, /* char p_canceled */
|
|
0, /* int p_errno */
|
|
0, /* int p_h_errno */
|
|
+ 0, /* int stacksize */
|
|
+ PTHREAD_MUTEX_INITIALIZER,
|
|
PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
|
|
{NULL} /* void ** p_specific[PTHREAD_KEY_1STLEVEL] */
|
|
};
|
|
@@ -119,9 +122,12 @@
|
|
int __pthread_exit_requested = 0;
|
|
int __pthread_exit_code = 0;
|
|
|
|
+int clone_flag = 0;
|
|
+
|
|
/* Forward declarations */
|
|
|
|
-static void pthread_exit_process(int retcode, void * arg);
|
|
+/* XXXX fix this */
|
|
+static void pthread_exit_process(void);
|
|
static void pthread_handle_sigcancel(int sig);
|
|
|
|
/* Initialize the pthread library.
|
|
@@ -137,14 +143,15 @@
|
|
{
|
|
struct sigaction sa;
|
|
sigset_t mask;
|
|
+ int status;
|
|
|
|
/* If already done (e.g. by a constructor called earlier!), bail out */
|
|
if (__pthread_initial_thread_bos != NULL) return;
|
|
/* For the initial stack, reserve at least STACK_SIZE bytes of stack
|
|
below the current stack address, and align that on a
|
|
STACK_SIZE boundary. */
|
|
- __pthread_initial_thread_bos =
|
|
- (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
|
|
+
|
|
+ __pthread_initial_thread_bos = (char *)STACK_START;
|
|
/* Update the descriptor for the initial thread. */
|
|
__pthread_initial_thread.p_pid = __getpid();
|
|
/* If we have special thread_self processing, initialize that for the
|
|
@@ -168,10 +175,17 @@
|
|
sigemptyset(&mask);
|
|
sigaddset(&mask, PTHREAD_SIG_RESTART);
|
|
sigprocmask(SIG_BLOCK, &mask, NULL);
|
|
+
|
|
+ /* This is FreeBSD specific, and is designed to detect pre/post March 1
|
|
+ * kernels, and adjust wait processing accordingly.
|
|
+ */
|
|
+ if (waitpid(-1, &status, WNOHANG | WLINUXCLONE) >= 0 || errno != EINVAL)
|
|
+ clone_flag = WLINUXCLONE;
|
|
+
|
|
/* Register an exit function to kill all other threads. */
|
|
/* Do it early so that user-registered atexit functions are called
|
|
before pthread_exit_process. */
|
|
- on_exit(pthread_exit_process, NULL);
|
|
+ atexit(pthread_exit_process);
|
|
}
|
|
|
|
static int pthread_initialize_manager(void)
|
|
@@ -196,7 +210,7 @@
|
|
/* Start the thread manager */
|
|
__pthread_manager_pid =
|
|
__clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
|
|
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
|
|
+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | PTHREAD_SIG_RESTART,
|
|
(void *) manager_pipe[0]);
|
|
if (__pthread_manager_pid == -1) {
|
|
free(__pthread_manager_thread_bos);
|
|
@@ -205,6 +219,7 @@
|
|
__pthread_manager_request = -1;
|
|
return -1;
|
|
}
|
|
+ _pthread_stack_init();
|
|
return 0;
|
|
}
|
|
|
|
@@ -215,6 +230,7 @@
|
|
{
|
|
pthread_descr self = thread_self();
|
|
struct pthread_request request;
|
|
+
|
|
if (__pthread_manager_request < 0) {
|
|
if (pthread_initialize_manager() < 0) return EAGAIN;
|
|
}
|
|
@@ -225,7 +241,7 @@
|
|
request.req_args.create.arg = arg;
|
|
sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
|
|
&request.req_args.create.mask);
|
|
- write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
+ _write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
suspend(self);
|
|
if (self->p_retcode == 0) *thread = (pthread_t) self->p_retval;
|
|
return self->p_retcode;
|
|
@@ -262,7 +278,7 @@
|
|
release(&handle->h_spinlock);
|
|
return errno;
|
|
}
|
|
- th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
|
|
+ th->p_priority = param->sched_priority;
|
|
release(&handle->h_spinlock);
|
|
return 0;
|
|
}
|
|
@@ -289,8 +305,10 @@
|
|
|
|
/* Process-wide exit() request */
|
|
|
|
-static void pthread_exit_process(int retcode, void * arg)
|
|
+static void pthread_exit_process(void)
|
|
{
|
|
+ int retcode = 0;
|
|
+
|
|
struct pthread_request request;
|
|
pthread_descr self = thread_self();
|
|
|
|
@@ -298,7 +316,7 @@
|
|
request.req_thread = self;
|
|
request.req_kind = REQ_PROCESS_EXIT;
|
|
request.req_args.exit.code = retcode;
|
|
- write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
+ _write(__pthread_manager_request, (char *) &request, sizeof(request));
|
|
suspend(self);
|
|
/* Main thread should accumulate times for thread manager and its
|
|
children, so that timings for main thread account for all threads. */
|
|
@@ -365,8 +383,8 @@
|
|
free(__pthread_manager_thread_bos);
|
|
__pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
|
|
/* Close the two ends of the pipe */
|
|
- close(__pthread_manager_request);
|
|
- close(__pthread_manager_reader);
|
|
+ _close(__pthread_manager_request);
|
|
+ _close(__pthread_manager_reader);
|
|
__pthread_manager_request = __pthread_manager_reader = -1;
|
|
}
|
|
/* Update the pid of the main thread */
|
|
@@ -382,12 +400,12 @@
|
|
void __pthread_kill_other_threads_np(void)
|
|
{
|
|
/* Terminate all other threads and thread manager */
|
|
- pthread_exit_process(0, NULL);
|
|
+ pthread_exit_process();
|
|
/* Make current thread the main thread in case the calling thread
|
|
changes its mind, does not exec(), and creates new threads instead. */
|
|
__pthread_reset_main_thread();
|
|
}
|
|
-weak_alias(__pthread_kill_other_threads_np, pthread_kill_other_threads_np);
|
|
+#pragma weak pthread_kill_other_threads_np=__pthread_kill_other_threads_np
|
|
|
|
/* Debugging aid */
|
|
|
|
@@ -398,7 +416,7 @@
|
|
char buffer[1024];
|
|
sprintf(buffer, "%05d : ", __getpid());
|
|
sprintf(buffer + 8, fmt, arg);
|
|
- write(2, buffer, strlen(buffer));
|
|
+ _write(2, buffer, strlen(buffer));
|
|
}
|
|
|
|
#endif
|
|
diff -ur ./pthread.h ../linuxthreads-0.71.new/pthread.h
|
|
--- ./pthread.h Thu Dec 4 06:33:41 1997
|
|
+++ ../linuxthreads-0.71.new/pthread.h Wed Oct 27 18:13:29 1999
|
|
@@ -14,19 +14,13 @@
|
|
|
|
#ifndef _PTHREAD_H
|
|
|
|
-#define _PTHREAD_H 1
|
|
-#include <features.h>
|
|
-
|
|
+#define _PTHREAD_H
|
|
#define __need_sigset_t
|
|
#include <signal.h>
|
|
#define __need_timespec
|
|
#include <time.h>
|
|
|
|
-#ifdef __BUILDING_LINUXTHREADS
|
|
-#include <linux/sched.h>
|
|
-#else
|
|
-#include <sched.h>
|
|
-#endif
|
|
+#include <posix4/sched.h>
|
|
|
|
#ifndef _REENTRANT
|
|
#define _REENTRANT
|
|
@@ -67,6 +61,17 @@
|
|
/* Thread descriptors */
|
|
typedef struct _pthread_descr_struct * _pthread_descr;
|
|
|
|
+#ifndef SPINLOCK_DEFINED
|
|
+typedef struct {
|
|
+ volatile long access_lock;
|
|
+ volatile long lock_owner;
|
|
+ volatile char *fname;
|
|
+ volatile int lineno;
|
|
+} spinlock_t;
|
|
+#define _SPINLOCK_INITIALIZER { 0, 0, 0, 0 }
|
|
+#define SPINLOCK_DEFINED
|
|
+#endif
|
|
+
|
|
/* Waiting queues (not abstract because mutexes and conditions aren't). */
|
|
struct _pthread_queue {
|
|
_pthread_descr head; /* First element, or NULL if queue empty. */
|
|
@@ -75,24 +80,24 @@
|
|
|
|
/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER). */
|
|
typedef struct {
|
|
- int m_spinlock; /* Spin lock to guarantee mutual exclusion. */
|
|
+ spinlock_t m_spinlock; /* Spin lock to guarantee mutual exclusion. */
|
|
int m_count; /* 0 if free, > 0 if taken. */
|
|
_pthread_descr m_owner; /* Owner of mutex (for recursive mutexes) */
|
|
int m_kind; /* Kind of mutex */
|
|
struct _pthread_queue m_waiting; /* Threads waiting on this mutex. */
|
|
} pthread_mutex_t;
|
|
|
|
-#define PTHREAD_MUTEX_INITIALIZER {0, 0, 0, PTHREAD_MUTEX_FAST_NP, {0, 0}}
|
|
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
|
|
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}}
|
|
+#define PTHREAD_MUTEX_INITIALIZER {_SPINLOCK_INITIALIZER, 0, 0, PTHREAD_MUTEX_FAST_NP, {0, 0}}
|
|
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {_SPINLOCK_INITIALIZER, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
|
|
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP {_SPINLOCK_INITIALIZER, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}}
|
|
|
|
/* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */
|
|
typedef struct {
|
|
- int c_spinlock; /* Spin lock to protect the queue. */
|
|
+ spinlock_t c_spinlock; /* Spin lock to protect the queue. */
|
|
struct _pthread_queue c_waiting; /* Threads waiting on this condition. */
|
|
} pthread_cond_t;
|
|
|
|
-#define PTHREAD_COND_INITIALIZER {0, {0, 0}}
|
|
+#define PTHREAD_COND_INITIALIZER {_SPINLOCK_INITIALIZER, {0, 0}}
|
|
|
|
/* Attributes */
|
|
|
|
@@ -117,6 +122,9 @@
|
|
struct sched_param schedparam;
|
|
int inheritsched;
|
|
int scope;
|
|
+ void * stack_addr;
|
|
+ int stack_size;
|
|
+ int guard_size;
|
|
} pthread_attr_t;
|
|
|
|
enum {
|
|
@@ -464,6 +472,10 @@
|
|
Should be called just before invoking one of the exec*() functions. */
|
|
|
|
extern void pthread_kill_other_threads_np __P((void));
|
|
+
|
|
+#ifdef COMPILING_LINUXTHREADS
|
|
+#include "pthread_stack.h"
|
|
+#endif
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
Only in ../linuxthreads-0.71.new: pthread_private.h
|
|
Only in ../linuxthreads-0.71.new: pthread_rw.h
|
|
Only in ../linuxthreads-0.71.new: pthread_stack.h
|
|
diff -ur ./queue.h ../linuxthreads-0.71.new/queue.h
|
|
--- ./queue.h Fri Dec 5 02:28:21 1997
|
|
+++ ../linuxthreads-0.71.new/queue.h Wed Oct 27 18:13:29 1999
|
|
@@ -60,3 +60,5 @@
|
|
}
|
|
return th;
|
|
}
|
|
+
|
|
+int remove_from_queue(pthread_queue * q, pthread_descr th);
|
|
diff -ur ./restart.h ../linuxthreads-0.71.new/restart.h
|
|
--- ./restart.h Fri Dec 5 02:28:21 1997
|
|
+++ ../linuxthreads-0.71.new/restart.h Wed Oct 27 18:13:29 1999
|
|
@@ -14,6 +14,9 @@
|
|
|
|
/* Primitives for controlling thread execution */
|
|
|
|
+#include <stdio.h>
|
|
+
|
|
+#ifndef USETHR_FUNCTIONS
|
|
static inline void restart(pthread_descr th)
|
|
{
|
|
kill(th->p_pid, PTHREAD_SIG_RESTART);
|
|
@@ -27,7 +30,7 @@
|
|
sigdelset(&mask, PTHREAD_SIG_RESTART); /* Unblock the restart signal */
|
|
do {
|
|
self->p_signal = 0;
|
|
- sigsuspend(&mask); /* Wait for signal */
|
|
+ _sigsuspend(&mask); /* Wait for signal */
|
|
} while (self->p_signal != PTHREAD_SIG_RESTART);
|
|
}
|
|
|
|
@@ -44,7 +47,7 @@
|
|
if (! (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE)) {
|
|
do {
|
|
self->p_signal = 0;
|
|
- sigsuspend(&mask); /* Wait for a signal */
|
|
+ _sigsuspend(&mask); /* Wait for signal */
|
|
} while (self->p_signal != PTHREAD_SIG_RESTART);
|
|
}
|
|
self->p_cancel_jmp = NULL;
|
|
@@ -53,3 +56,29 @@
|
|
sigprocmask(SIG_SETMASK, &mask, NULL);
|
|
}
|
|
}
|
|
+#else
|
|
+
|
|
+#include <sys/syscall.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+static inline void restart(pthread_descr th)
|
|
+{
|
|
+ syscall(SYS_thr_wakeup, th->p_pid);
|
|
+}
|
|
+
|
|
+static inline void suspend(pthread_descr self)
|
|
+{
|
|
+ syscall(SYS_thr_sleep, NULL);
|
|
+}
|
|
+
|
|
+static inline void suspend_with_cancellation(pthread_descr self)
|
|
+{
|
|
+ /* What we think happens here is that if a PTHREAD_SIG_CANCEL
|
|
+ is sent, thr_sleep will be awaken. It should return
|
|
+ EINTR, but it will just return 0 unless we fix it.
|
|
+
|
|
+ So we shouldn't need any of the fancy jmpbuf stuff
|
|
+ */
|
|
+ syscall(SYS_thr_sleep, NULL);
|
|
+}
|
|
+#endif
|
|
diff -ur ./signals.c ../linuxthreads-0.71.new/signals.c
|
|
--- ./signals.c Fri Dec 12 09:21:47 1997
|
|
+++ ../linuxthreads-0.71.new/signals.c Wed Oct 27 18:13:29 1999
|
|
@@ -18,7 +18,6 @@
|
|
#include <errno.h>
|
|
#include "pthread.h"
|
|
#include "internals.h"
|
|
-#include "spinlock.h"
|
|
|
|
int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask)
|
|
{
|
|
@@ -36,9 +35,11 @@
|
|
case SIG_BLOCK:
|
|
sigdelset(&mask, PTHREAD_SIG_CANCEL);
|
|
break;
|
|
+
|
|
case SIG_UNBLOCK:
|
|
sigdelset(&mask, PTHREAD_SIG_RESTART);
|
|
break;
|
|
+
|
|
}
|
|
newmask = &mask;
|
|
}
|
|
@@ -67,7 +68,7 @@
|
|
}
|
|
|
|
/* The set of signals on which some thread is doing a sigwait */
|
|
-static sigset_t sigwaited = 0;
|
|
+static sigset_t sigwaited = { { 0 } };
|
|
static pthread_mutex_t sigwaited_mut = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_cond_t sigwaited_changed = PTHREAD_COND_INITIALIZER;
|
|
|
|
@@ -115,7 +116,7 @@
|
|
/* Reset the signal count */
|
|
self->p_signal = 0;
|
|
/* Unblock the signals and wait for them */
|
|
- sigsuspend(&mask);
|
|
+ _sigsuspend(&mask);
|
|
}
|
|
}
|
|
self->p_cancel_jmp = NULL;
|
|
diff -ur ./spinlock.h ../linuxthreads-0.71.new/spinlock.h
|
|
--- ./spinlock.h Fri Dec 5 02:28:22 1997
|
|
+++ ../linuxthreads-0.71.new/spinlock.h Wed Oct 27 18:13:29 1999
|
|
@@ -15,17 +15,20 @@
|
|
|
|
/* Spin locks */
|
|
|
|
-static inline void acquire(int * spinlock)
|
|
+#include "libc_spinlock.h"
|
|
+
|
|
+
|
|
+static inline void acquire(spinlock_t *lck)
|
|
{
|
|
- while (testandset(spinlock)) __sched_yield();
|
|
+ _spin_lock (lck);
|
|
}
|
|
|
|
-static inline void release(int * spinlock)
|
|
+static inline void release(spinlock_t *lck)
|
|
{
|
|
#ifndef RELEASE
|
|
- *spinlock = 0;
|
|
+ _spin_unlock (lck);;
|
|
#else
|
|
- RELEASE(spinlock);
|
|
+ RELEASE(lck);
|
|
#endif
|
|
}
|
|
|