2001-11-30  Andreas Schwab  <schwab@suse.de>

	* pthread.c (pthread_handle_sigcancel) [THREAD_SELF]: Double check
	that self is the manager thread, and initialize the thread
	register if not.
	(thread_self_stack) [THREAD_SELF]: New function to find self via
	stack pointer.
	* manager.c (pthread_handle_create): Don't block cancel signal any
	more.

	(THREAD_GETMEM_NC):
This commit is contained in:
Ulrich Drepper 2001-11-30 21:14:09 +00:00
parent 096f115125
commit c3317d1e8b
3 changed files with 47 additions and 17 deletions

View File

@ -1,3 +1,13 @@
2001-11-30 Andreas Schwab <schwab@suse.de>
* pthread.c (pthread_handle_sigcancel) [THREAD_SELF]: Double check
that self is the manager thread, and initialize the thread
register if not.
(thread_self_stack) [THREAD_SELF]: New function to find self via
stack pointer.
* manager.c (pthread_handle_create): Don't block cancel signal any
more.
2001-11-29 Andreas Jaeger <aj@suse.de> 2001-11-29 Andreas Jaeger <aj@suse.de>
* sysdeps/x86_64/pt-machine.h: Use %gs as thread specific * sysdeps/x86_64/pt-machine.h: Use %gs as thread specific

View File

@ -534,7 +534,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
size_t guardsize = 0; size_t guardsize = 0;
int pagesize = __getpagesize(); int pagesize = __getpagesize();
int saved_errno; int saved_errno;
sigset_t newmask, oldmask;
/* First check whether we have to change the policy and if yes, whether /* First check whether we have to change the policy and if yes, whether
we can do this. Normally this should be done by examining the we can do this. Normally this should be done by examining the
@ -620,11 +619,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
if ((mask & (__pthread_threads_events.event_bits[idx] if ((mask & (__pthread_threads_events.event_bits[idx]
| event_maskp->event_bits[idx])) != 0) | event_maskp->event_bits[idx])) != 0)
{ {
/* Block cancel signal in the child until it is fully
initialized. */
sigemptyset(&newmask);
sigaddset(&newmask, __pthread_sig_cancel);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
/* Lock the mutex the child will use now so that it will stop. */ /* Lock the mutex the child will use now so that it will stop. */
__pthread_lock(new_thread->p_lock, NULL); __pthread_lock(new_thread->p_lock, NULL);
@ -653,7 +647,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
__pthread_sig_cancel, new_thread); __pthread_sig_cancel, new_thread);
#endif #endif
saved_errno = errno; saved_errno = errno;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if (pid != -1) if (pid != -1)
{ {
/* Now fill in the information about the new thread in /* Now fill in the information about the new thread in
@ -679,11 +672,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
} }
if (pid == 0) if (pid == 0)
{ {
/* Block cancel signal in the child until it is fully
initialized. */
sigemptyset(&newmask);
sigaddset(&newmask, __pthread_sig_cancel);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
#ifdef NEED_SEPARATE_REGISTER_STACK #ifdef NEED_SEPARATE_REGISTER_STACK
pid = __clone2(pthread_start_thread, pid = __clone2(pthread_start_thread,
(void **)new_thread_bottom, (void **)new_thread_bottom,
@ -700,7 +688,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
__pthread_sig_cancel, new_thread); __pthread_sig_cancel, new_thread);
#endif /* !NEED_SEPARATE_REGISTER_STACK */ #endif /* !NEED_SEPARATE_REGISTER_STACK */
saved_errno = errno; saved_errno = errno;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
} }
/* Check if cloning succeeded */ /* Check if cloning succeeded */
if (pid == -1) { if (pid == -1) {

View File

@ -709,7 +709,7 @@ int pthread_equal(pthread_t thread1, pthread_t thread2)
#ifndef THREAD_SELF #ifndef THREAD_SELF
pthread_descr __pthread_find_self() pthread_descr __pthread_find_self(void)
{ {
char * sp = CURRENT_STACK_FRAME; char * sp = CURRENT_STACK_FRAME;
pthread_handle h; pthread_handle h;
@ -721,6 +721,21 @@ pthread_descr __pthread_find_self()
return h->h_descr; return h->h_descr;
} }
#else
static pthread_descr thread_self_stack(void)
{
char *sp = CURRENT_STACK_FRAME;
pthread_handle h;
if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos)
return &__pthread_manager_thread;
h = __pthread_handles + 2;
while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom))
h++;
return h->h_descr;
}
#endif #endif
/* Thread scheduling */ /* Thread scheduling */
@ -769,7 +784,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
return 0; return 0;
} }
int __pthread_yield () int __pthread_yield (void)
{ {
/* For now this is equivalent with the POSIX call. */ /* For now this is equivalent with the POSIX call. */
return sched_yield (); return sched_yield ();
@ -841,9 +856,27 @@ static void pthread_handle_sigcancel(int sig)
if (self == &__pthread_manager_thread) if (self == &__pthread_manager_thread)
{ {
#ifdef THREAD_SELF
/* A new thread might get a cancel signal before it is fully
initialized, so that the thread register might still point to the
manager thread. Double check that this is really the manager
thread. */
pthread_descr real_self = thread_self_stack();
if (real_self == &__pthread_manager_thread)
{
__pthread_manager_sighandler(sig); __pthread_manager_sighandler(sig);
return; return;
} }
/* Oops, thread_self() isn't working yet.. */
self = real_self;
# ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(self, self->p_nr);
# endif
#else
__pthread_manager_sighandler(sig);
return;
#endif
}
if (__builtin_expect (__pthread_exit_requested, 0)) { if (__builtin_expect (__pthread_exit_requested, 0)) {
/* Main thread should accumulate times for thread manager and its /* Main thread should accumulate times for thread manager and its
children, so that timings for main thread account for all threads. */ children, so that timings for main thread account for all threads. */
@ -884,7 +917,7 @@ static void pthread_handle_sigdebug(int sig)
Notice that we can't free the stack segments, as the forked thread Notice that we can't free the stack segments, as the forked thread
may hold pointers into them. */ may hold pointers into them. */
void __pthread_reset_main_thread() void __pthread_reset_main_thread(void)
{ {
pthread_descr self = thread_self(); pthread_descr self = thread_self();
struct rlimit limit; struct rlimit limit;