altered pthread implementation for GNU/kFreeBSD
Hi,
Please would you consider including Petr's patch in experimental
uploads so that it can be more widely tested?
Thanks!
2011/9/20 Petr Salinger <Petr.Salinger@seznam.cz>:
> Hi,
>
> as you might know, our eglibc pthread implementation
> is still linuxthreads based. I tried to alter current
> LT version to use some thread primitives from kernel.
>
> Instead of processes it uses kernel threads,
> there is still a thread manager.
> But it should fix #639658.
>
> The hackish patch is attached, the geting/seting
> of pthread scheduler priority have to be reimplemented.
>
> There is no regression in our glibc testsuite on ka.
> But it definitely needs more testing, on both real HW
> and inside emulators.
>
> Please test this partial patch, upload into experimental would be nice.
>
> Petr
--
Robert Millan
diff -u a/linuxthreads/attr.c b/linuxthreads/attr.c
--- a/linuxthreads/attr.c 2006-08-17 03:23:45.000000000 +0200
+++ b/linuxthreads/attr.c 2011-09-20 17:02:25.000000000 +0200
@@ -365,11 +365,11 @@
? PTHREAD_CREATE_DETACHED
: PTHREAD_CREATE_JOINABLE);
- attr->__schedpolicy = __sched_getscheduler (descr->p_pid);
+ attr->__schedpolicy = __sched_getscheduler (getpid());
if (attr->__schedpolicy == -1)
return errno;
- if (__sched_getparam (descr->p_pid,
+ if (__sched_getparam (getpid(),
(struct sched_param *) &attr->__schedparam) != 0)
return errno;
diff -u a/linuxthreads/cancel.c b/linuxthreads/cancel.c
--- a/linuxthreads/cancel.c 2006-08-17 03:23:45.000000000 +0200
+++ b/linuxthreads/cancel.c 2011-09-20 17:02:25.000000000 +0200
@@ -89,7 +89,7 @@
int pthread_cancel(pthread_t thread)
{
pthread_handle handle = thread_handle(thread);
- int pid;
+ long ktid;
int dorestart = 0;
pthread_descr th;
pthread_extricate_if *pextricate;
@@ -112,7 +112,7 @@
}
pextricate = th->p_extricate;
- pid = th->p_pid;
+ ktid = th->p_ktid;
/* If the thread has registered an extrication interface, then
invoke the interface. If it returns 1, then we succeeded in
@@ -139,7 +139,7 @@
if (dorestart)
restart(th);
else
- kill(pid, __pthread_sig_cancel);
+ __thr_kill(ktid, __pthread_sig_cancel);
return 0;
}
diff -u a/linuxthreads/descr.h b/linuxthreads/descr.h
--- a/linuxthreads/descr.h 2011-09-20 19:38:20.000000000 +0200
+++ b/linuxthreads/descr.h 2011-09-20 17:44:58.000000000 +0200
@@ -26,6 +26,42 @@
#include <lowlevellock.h>
#include <tls.h>
+
+extern long int syscall (long int __sysno, ...);
+#include <sys/syscall.h>
+// should be in <sys/thr.h>
+struct rtprio;
+struct thr_param {
+ void (*start_func)(void *); /* thread entry function. */
+ void *arg; /* argument for entry function. */
+ char *stack_base; /* stack base address. */
+ size_t stack_size; /* stack size. */
+ char *tls_base; /* tls base address. */
+ size_t tls_size; /* tls size. */
+ long *child_tid; /* address to store new TID. */
+ long *parent_tid; /* parent accesses the new TID here. */
+ int flags; /* thread flags. */
+ struct rtprio *rtp; /* Real-time scheduling priority */
+ void *spare[3]; /* TODO: cpu affinity mask etc. */
+};
+
+#define KTID_TERMINATED 1
+static inline int __thr_self(long *ktid)
+{ return syscall(SYS_thr_self, ktid);};
+
+static inline int __thr_kill(long ktid, int signo)
+{ return syscall(SYS_thr_kill, ktid, signo);};
+
+static inline int __thr_exit(long *ktid) // also *ktid = KTID_TERMINATED, wakeup(ktid)
+{ return syscall(SYS_thr_exit, ktid);}; // returns only for last thread in process
+
+static inline int __thr_new(struct thr_param *param, int param_size)
+{ return syscall(SYS_thr_new, param, param_size);};
+
+static inline int __lll_wait(long *addr, long val)
+{ return syscall(SYS__umtx_op, addr, UMTX_OP_WAIT, val, NULL, NULL);};
+
+
/* Fast thread-specific data internal to libc. */
enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
_LIBC_TSD_KEY_DL_ERROR,
@@ -202,6 +238,8 @@
size_t p_alloca_cutoff; /* Maximum size which should be allocated
using alloca() instead of malloc(). */
/* New elements must be added at the end. */
+ long p_ktid; /* kernel thread ID */
+
/* This member must be last. */
char end_padding[];
diff -u a/linuxthreads/join.c b/linuxthreads/join.c
--- a/linuxthreads/join.c 2006-08-17 03:23:45.000000000 +0200
+++ b/linuxthreads/join.c 2011-09-20 17:02:25.000000000 +0200
@@ -89,6 +89,9 @@
}
/* Threads other than the main one terminate without flushing stdio streams
or running atexit functions. */
+
+ __thr_kill(__manager_thread->p_ktid, __pthread_sig_cancel);
+ __thr_exit(&(self->p_ktid));
_exit(0);
}
diff -u a/linuxthreads/manager.c b/linuxthreads/manager.c
--- a/linuxthreads/manager.c 2006-08-17 03:23:45.000000000 +0200
+++ b/linuxthreads/manager.c 2011-09-20 19:04:23.000000000 +0200
@@ -151,13 +151,16 @@
while(1) {
n = __poll(&ufd, 1, 2000);
+#if 0
+ /* iff the main thread terminated abnormally, the signal should kill all threads already */
/* Check for termination of the main thread */
if (getppid() == 1) {
pthread_kill_all_threads(SIGKILL, 0);
_exit(0);
}
+#endif
/* Check for dead children */
- if (terminated_children) {
+ if (terminated_children || main_thread_exiting) {
terminated_children = 0;
pthread_reap_children();
}
@@ -182,7 +185,7 @@
request.req_args.create.fn,
request.req_args.create.arg,
&request.req_args.create.mask,
- request.req_thread->p_pid,
+ request.req_thread->p_ktid,
request.req_thread->p_report_events,
&request.req_thread->p_eventbuf.eventmask);
restart(request.req_thread);
@@ -271,10 +274,13 @@
#endif
/* Make sure our pid field is initialized, just in case we get there
before our father has initialized it. */
- THREAD_SETMEM(self, p_pid, __getpid());
+ // done in kernel
+ // __thr_self(&ktid);
+ // THREAD_SETMEM(self, p_ktid, ktid);
/* 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);
+#if 0
/* Set the scheduling policy and priority for the new thread, if needed */
if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
/* Explicit scheduling attributes were provided: apply them */
@@ -290,6 +296,7 @@
__sched_setscheduler(THREAD_GETMEM(self, p_pid),
SCHED_OTHER, &default_params);
}
+#endif
#if !(USE_TLS && HAVE___THREAD)
/* Initialize thread-locale current locale to point to the global one.
With __thread support, the variable's initializer takes care of this. */
@@ -324,7 +331,9 @@
#endif
/* Make sure our pid field is initialized, just in case we get there
before our father has initialized it. */
- THREAD_SETMEM(self, p_pid, __getpid());
+ // done in kernel
+ // __thr_self(&ktid);
+ // THREAD_SETMEM(self, p_ktid, ktid);
/* Get the lock the manager will free once all is correctly set up. */
__pthread_lock (THREAD_GETMEM(self, p_lock), NULL);
/* Free it immediately. */
@@ -586,7 +595,7 @@
td_thr_events_t *event_maskp)
{
size_t sseg;
- int pid;
+ int rv;
pthread_descr new_thread;
char *stack_addr;
char * new_thread_bottom;
@@ -595,6 +604,7 @@
size_t guardsize = 0, stksize = 0;
int pagesize = __getpagesize();
int saved_errno = 0;
+ struct thr_param p;
#ifdef USE_TLS
new_thread = _dl_allocate_tls (NULL);
@@ -690,6 +700,7 @@
new_thread->p_detached = attr->__detachstate;
new_thread->p_userstack = attr->__stackaddr_set;
+#if 0
switch(attr->__inheritsched) {
case PTHREAD_EXPLICIT_SCHED:
new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
@@ -702,6 +713,7 @@
__sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
break;
}
+#endif
new_thread->p_priority =
new_thread->p_start_args.schedparam.sched_priority;
}
@@ -717,7 +729,7 @@
__pthread_manager_adjust_prio(new_thread->p_priority);
/* Do the cloning. We have to use two different functions depending
on whether we are debugging or not. */
- pid = 0; /* Note that the thread never can have PID zero. */
+ rv = 0;
if (report_events)
{
/* See whether the TD_CREATE event bit is set in any of the
@@ -733,30 +745,22 @@
/* We have to report this event. */
#ifdef NEED_SEPARATE_REGISTER_STACK
- /* Perhaps this version should be used on all platforms. But
- this requires that __clone2 be uniformly supported
- everywhere.
-
- And there is some argument for changing the __clone2
- interface to pass sp and bsp instead, making it more IA64
- specific, but allowing stacks to grow outward from each
- other, to get less paging and fewer mmaps. */
- pid = __clone2(pthread_start_thread_event,
- (void **)new_thread_bottom,
- (char *)stack_addr - new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+#error unimplemented SEPARATE_REGISTER_STACK
#elif _STACK_GROWS_UP
- pid = __clone(pthread_start_thread_event, (void *) new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+#error unimplemented _STACK_GROWS_UP
#else
- pid = __clone(pthread_start_thread_event, stack_addr,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+ memset(&p, 0, sizeof(p));
+ p.start_func = pthread_start_thread_event;
+ p.arg = new_thread;
+ p.stack_base = new_thread_bottom;
+ p.stack_size = stack_addr - new_thread_bottom;
+ p.tls_base = new_thread;
+ p.child_tid = &(new_thread->p_ktid);
+
+ rv = __thr_new(&p, sizeof(p));
#endif
saved_errno = errno;
- if (pid != -1)
+ if (rv != -1)
{
/* Now fill in the information about the new thread in
the newly created thread's data structure. We cannot let
@@ -769,7 +773,7 @@
/* We have to set the PID here since the callback function
in the debug library will need it and we cannot guarantee
the child got scheduled before the debugger. */
- new_thread->p_pid = pid;
+ // kernel already done that
/* Now call the function which signals the event. */
__linuxthreads_create_event ();
@@ -779,27 +783,31 @@
}
}
}
- if (pid == 0)
+
+ if (rv == 0)
{
#ifdef NEED_SEPARATE_REGISTER_STACK
- pid = __clone2(pthread_start_thread,
- (void **)new_thread_bottom,
- (char *)stack_addr - new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+#error unimplemented SEPARATE_REGISTER_STACK
#elif _STACK_GROWS_UP
- pid = __clone(pthread_start_thread, (void *) new_thread_bottom,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+#error unimplemented _STACK_GROWS_UP
#else
- pid = __clone(pthread_start_thread, stack_addr,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM |
- __pthread_sig_cancel, new_thread);
+
+ memset(&p, 0, sizeof(p));
+ p.start_func = pthread_start_thread;
+ p.arg = new_thread;
+ p.stack_base = new_thread_bottom;
+ p.stack_size = stack_addr - new_thread_bottom;
+ p.tls_base = new_thread;
+ p.child_tid = &(new_thread->p_ktid);
+
+ rv = __thr_new(&p, sizeof(p));
+
#endif /* !NEED_SEPARATE_REGISTER_STACK */
saved_errno = errno;
}
+
/* Check if cloning succeeded */
- if (pid == -1) {
+ if (rv == -1) {
/* Free the stack if we allocated it */
if (attr == NULL || !attr->__stackaddr_set)
{
@@ -843,7 +851,7 @@
__pthread_main_thread->p_nextlive = new_thread;
/* Set pid field of the new thread, in case we get there before the
child starts. */
- new_thread->p_pid = pid;
+ // kernel already done that
return 0;
}
@@ -928,17 +936,18 @@
/* Handle threads that have exited */
-static void pthread_exited(pid_t pid)
+static void pthread_reap_children(void)
{
- pthread_descr th;
+ pthread_descr th, tth;
int detached;
+
/* Find thread with that pid */
for (th = __pthread_main_thread->p_nextlive;
th != __pthread_main_thread;
th = th->p_nextlive) {
- if (th->p_pid == pid) {
+ if (th->p_ktid == KTID_TERMINATED) {
/* Remove thread from list of active threads */
- th->p_nextlive->p_prevlive = th->p_prevlive;
+ tth = th->p_nextlive->p_prevlive = th->p_prevlive;
th->p_prevlive->p_nextlive = th->p_nextlive;
/* Mark thread as exited, and if detached, free its resources */
__pthread_lock(th->p_lock, NULL);
@@ -966,7 +975,7 @@
__pthread_unlock(th->p_lock);
if (detached)
pthread_free(th);
- break;
+ th = tth;
}
}
/* If all threads have exited and the main thread is pending on a
@@ -978,22 +987,6 @@
}
}
-static void pthread_reap_children(void)
-{
- pid_t pid;
- int status;
-
- while ((pid = waitpid_not_cancel(-1, &status, WNOHANG | __WCLONE)) > 0) {
- pthread_exited(pid);
- if (WIFSIGNALED(status)) {
- /* If a thread died due to a signal, send the same signal to
- all other threads, including the main thread. */
- pthread_kill_all_threads(WTERMSIG(status), 1);
- _exit(0);
- }
- }
-}
-
/* Try to free the resources of a thread when requested by pthread_join
or pthread_detach on a terminated thread. */
@@ -1030,10 +1023,10 @@
for (th = __pthread_main_thread->p_nextlive;
th != __pthread_main_thread;
th = th->p_nextlive) {
- kill(th->p_pid, sig);
+ __thr_kill(th->p_ktid, sig);
}
if (main_thread_also) {
- kill(__pthread_main_thread->p_pid, sig);
+ __thr_kill(__pthread_main_thread->p_ktid, sig);
}
}
@@ -1071,18 +1064,24 @@
for (th = issuing_thread->p_nextlive;
th != issuing_thread;
th = th->p_nextlive) {
- kill(th->p_pid, __pthread_sig_cancel);
+ __thr_kill(th->p_ktid, __pthread_sig_cancel);
}
/* Now, wait for all these threads, so that they don't become zombies
and their times are properly added to the thread manager's times. */
for (th = issuing_thread->p_nextlive;
th != issuing_thread;
th = th->p_nextlive) {
- waitpid(th->p_pid, NULL, __WCLONE);
+ if (th == __pthread_main_thread) // it waits for thread manager
+ continue;
+ long ktid;
+ while (KTID_TERMINATED != (ktid = th->p_ktid))
+ __lll_wait(&(th->p_ktid), ktid);
}
__fresetlockfiles();
restart(issuing_thread);
- _exit(0);
+ __thr_exit(&(manager_thread->p_ktid));
+ // should not return */
+ _exit(__pthread_exit_code);
}
/* Handler for __pthread_sig_cancel in thread manager thread */
@@ -1114,11 +1113,12 @@
void __pthread_manager_adjust_prio(int thread_prio)
{
struct sched_param param;
-
+#if 0
if (thread_prio <= manager_thread->p_priority) return;
param.sched_priority =
thread_prio < __sched_get_priority_max(SCHED_FIFO)
? thread_prio + 1 : thread_prio;
__sched_setscheduler(manager_thread->p_pid, SCHED_FIFO, ¶m);
manager_thread->p_priority = thread_prio;
+#endif
}
diff -u a/linuxthreads/pthread.c b/linuxthreads/pthread.c
--- a/linuxthreads/pthread.c 2011-09-20 19:38:19.000000000 +0200
+++ b/linuxthreads/pthread.c 2011-09-20 17:28:00.000000000 +0200
@@ -520,6 +522,7 @@
{
struct sigaction sa;
sigset_t mask;
+ long ktid;
/* If already done (e.g. by a constructor called earlier!), bail out */
if (__pthread_initial_thread_bos != NULL) return;
@@ -548,14 +551,16 @@
#endif
#ifdef USE_TLS
/* Update the descriptor for the initial thread. */
- THREAD_SETMEM (((pthread_descr) NULL), p_pid, __getpid());
+ __thr_self(&ktid);
+ THREAD_SETMEM (((pthread_descr) NULL), p_ktid, ktid);
# ifndef HAVE___THREAD
/* Likewise for the resolver state _res. */
THREAD_SETMEM (((pthread_descr) NULL), p_resp, &_res);
# endif
#else
/* Update the descriptor for the initial thread. */
- __pthread_initial_thread.p_pid = __getpid();
+ __thr_self(&ktid);
+ __pthread_initial_thread.p_ktid = ktid;
/* Likewise for the resolver state _res. */
__pthread_initial_thread.p_resp = &_res;
#endif
@@ -629,7 +634,8 @@
int __pthread_initialize_manager(void)
{
int manager_pipe[2];
- int pid;
+ int rv;
+ struct thr_param p;
struct pthread_request request;
int report_events;
pthread_descr mgr;
@@ -743,7 +749,7 @@
__pthread_manager_reader = manager_pipe[0]; /* reading end */
/* Start the thread manager */
- pid = 0;
+ rv = 0;
#ifdef USE_TLS
if (__linuxthreads_initial_report_events != 0)
THREAD_SETMEM (((pthread_descr) NULL), p_report_events,
@@ -776,24 +782,22 @@
__pthread_lock(mgr->p_lock, NULL);
#ifdef NEED_SEPARATE_REGISTER_STACK
- pid = __clone2(__pthread_manager_event,
- (void **) __pthread_manager_thread_bos,
- THREAD_MANAGER_STACK_SIZE,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
- mgr);
+#error unimplemented SEPARATE_REGISTER_STACK
#elif _STACK_GROWS_UP
- pid = __clone(__pthread_manager_event,
- (void **) __pthread_manager_thread_bos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
- mgr);
+#error unimplemented STACK_GROWS_UP
#else
- pid = __clone(__pthread_manager_event,
- (void **) __pthread_manager_thread_tos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM,
- mgr);
+ memset(&p, 0, sizeof(p));
+ p.start_func = __pthread_manager_event;
+ p.arg = mgr;
+ p.stack_base = __pthread_manager_thread_bos;
+ p.stack_size = __pthread_manager_thread_tos - __pthread_manager_thread_bos;
+ p.tls_base = mgr;
+ p.child_tid = &(mgr->p_ktid);
+
+ rv = __thr_new(&p, sizeof(p));
#endif
- if (pid != -1)
+ if (rv != -1)
{
/* Now fill in the information about the new thread in
the newly created thread's data structure. We cannot let
@@ -803,7 +807,6 @@
mgr->p_eventbuf.eventnum = TD_CREATE;
__pthread_last_event = mgr;
mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1;
- mgr->p_pid = pid;
/* Now call the function which signals the event. */
__linuxthreads_create_event ();
@@ -814,21 +817,26 @@
}
}
- if (__builtin_expect (pid, 0) == 0)
+ if (__builtin_expect (rv, 0) == 0)
{
+
#ifdef NEED_SEPARATE_REGISTER_STACK
- pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
- THREAD_MANAGER_STACK_SIZE,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
+#error unimplemented SEPARATE_REGISTER_STACK
#elif _STACK_GROWS_UP
- pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
+#error unimplemented STACK_GROWS_UP
#else
- pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr);
+ memset(&p, 0, sizeof(p));
+ p.start_func = __pthread_manager;
+ p.arg = mgr;
+ p.stack_base = __pthread_manager_thread_bos;
+ p.stack_size = __pthread_manager_thread_tos - __pthread_manager_thread_bos;
+ p.tls_base = mgr;
+ p.child_tid = &(mgr->p_ktid);
+
+ rv = __thr_new(&p, sizeof(p));
#endif
}
- if (__builtin_expect (pid, 0) == -1) {
+ if (__builtin_expect (rv, 0) == -1) {
#ifdef USE_TLS
_dl_deallocate_tls (tcbp, true);
#endif
@@ -838,7 +846,6 @@
return -1;
}
mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1;
- mgr->p_pid = pid;
/* Make gdb aware of new thread manager */
if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0)
{
@@ -998,7 +1005,7 @@
return ESRCH;
}
th = handle->h_descr;
- if (__builtin_expect (__sched_setscheduler(th->p_pid, policy, param) == -1,
+ if (__builtin_expect (__sched_setscheduler(getpid(), policy, param) == -1,
0)) {
__pthread_unlock(&handle->h_lock);
return errno;
@@ -1022,7 +1029,7 @@
__pthread_unlock(&handle->h_lock);
return ESRCH;
}
- pid = handle->h_descr->p_pid;
+ pid = getpid();
__pthread_unlock(&handle->h_lock);
pol = __sched_getscheduler(pid);
if (__builtin_expect (pol, 0) == -1) return errno;
@@ -1062,9 +1069,11 @@
if (self == __pthread_main_thread)
{
#ifdef USE_TLS
- waitpid(manager_thread->p_pid, NULL, __WCLONE);
+ long ktid;
+ while (KTID_TERMINATED != (ktid = manager_thread->p_ktid))
+ __lll_wait(&(manager_thread->p_ktid), ktid);
#else
- waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
+#error TLS required
#endif
/* Since all threads have been asynchronously terminated
(possibly holding locks), free cannot be used any more.
@@ -1128,9 +1137,11 @@
children, so that timings for main thread account for all threads. */
if (self == __pthread_main_thread) {
#ifdef USE_TLS
- waitpid(manager_thread->p_pid, NULL, __WCLONE);
+ long ktid;
+ while (KTID_TERMINATED != (ktid = manager_thread->p_ktid))
+ __lll_wait(&(manager_thread->p_ktid), ktid);
#else
- waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
+#error TLS required
#endif
}
_exit(__pthread_exit_code);
@@ -1170,6 +1181,7 @@
void __pthread_reset_main_thread(void)
{
+ long ktid;
pthread_descr self = thread_self();
if (__pthread_manager_request != -1) {
@@ -1183,7 +1195,8 @@
}
/* Update the pid of the main thread */
- THREAD_SETMEM(self, p_pid, __getpid());
+ __thr_self(&ktid);
+ THREAD_SETMEM(self, p_ktid, ktid);
/* Make the forked thread the main thread */
__pthread_main_thread = self;
THREAD_SETMEM(self, p_nextlive, self);
@@ -1289,7 +1302,7 @@
void __pthread_restart_old(pthread_descr th)
{
if (pthread_atomic_increment(&th->p_resume_count) == -1)
- kill(th->p_pid, __pthread_sig_restart);
+ __thr_kill(th->p_ktid, __pthread_sig_restart);
}
void __pthread_suspend_old(pthread_descr self)
@@ -1383,7 +1396,7 @@
memory so the woken thread will have a consistent view. Complementary
read barriers are present to the suspend functions. */
WRITE_MEMORY_BARRIER();
- kill(th->p_pid, __pthread_sig_restart);
+ __thr_kill(th->p_ktid, __pthread_sig_restart);
}
/* There is no __pthread_suspend_new because it would just
diff -u a/linuxthreads/signals.c b/linuxthreads/signals.c
--- a/linuxthreads/signals.c 2011-09-20 19:38:19.000000000 +0200
+++ b/linuxthreads/signals.c 2011-09-20 17:02:25.000000000 +0200
@@ -57,16 +57,16 @@
int pthread_kill(pthread_t thread, int signo)
{
pthread_handle handle = thread_handle(thread);
- int pid;
+ long ktid;
__pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread)) {
__pthread_unlock(&handle->h_lock);
return ESRCH;
}
- pid = handle->h_descr->p_pid;
+ ktid = handle->h_descr->p_ktid;
__pthread_unlock(&handle->h_lock);
- if (kill(pid, signo) == -1)
+ if (__thr_kill(ktid, signo) == -1)
return errno;
else
return 0;
Reply to: