diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 10 | ||||
-rw-r--r-- | linuxthreads/internals.h | 1 | ||||
-rw-r--r-- | linuxthreads/manager.c | 20 | ||||
-rw-r--r-- | linuxthreads/pthread.c | 48 |
4 files changed, 74 insertions, 5 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 2a69af79df..9e258849cb 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,13 @@ +1999-11-22 Ulrich Drepper <drepper@cygnus.com> + + * internals.h: Add prototype for __pthread_manager_event. + * manager.c (__pthread_manager_event): New function. + (pthread_start_thread_event): Correct computation of self. + Use INIT_THREAD_SELF. + * pthread.c (__pthread_manager_thread): Initialize p_lock. + (__pthread_initialize_manager): Respect event flags also for creation + of the manager thread. + 1999-11-08 Ulrich Drepper <drepper@cygnus.com> * pthread.c (__pthread_initialize_manager): Initialize diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h index f9eba6b94c..cd9091bd81 100644 --- a/linuxthreads/internals.h +++ b/linuxthreads/internals.h @@ -343,6 +343,7 @@ void __pthread_perform_cleanup(void); int __pthread_initialize_manager(void); void __pthread_message(char * fmt, ...); int __pthread_manager(void *reqfd); +int __pthread_manager_event(void *reqfd); void __pthread_manager_sighandler(int sig); void __pthread_reset_main_thread(void); void __fresetlockfiles(void); diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index 21a3f6875f..0168b8a11c 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -182,6 +182,21 @@ int __pthread_manager(void *arg) } } +int __pthread_manager_event(void *arg) +{ + /* If we have special thread_self processing, initialize it. */ +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(&__pthread_manager_thread, 1); +#endif + + /* Get the lock the manager will free once all is correctly set up. */ + __pthread_lock (THREAD_GETMEM((&__pthread_manager_thread), p_lock), NULL); + /* Free it immediately. */ + __pthread_unlock (THREAD_GETMEM((&__pthread_manager_thread), p_lock)); + + return __pthread_manager(arg); +} + /* Process creation */ static int pthread_start_thread(void *arg) @@ -232,8 +247,11 @@ static int pthread_start_thread(void *arg) static int pthread_start_thread_event(void *arg) { - pthread_descr self = thread_self (); + pthread_descr self = (pthread_descr) arg; +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(self, self->p_nr); +#endif /* Get the lock the manager will free once all is correctly set up. */ __pthread_lock (THREAD_GETMEM(self, p_lock), NULL); /* Free it immediately. */ diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c index ab1a0f189e..bddec8c757 100644 --- a/linuxthreads/pthread.c +++ b/linuxthreads/pthread.c @@ -84,7 +84,7 @@ struct _pthread_descr_struct __pthread_manager_thread = { 0, /* int p_tid */ 0, /* int p_pid */ 0, /* int p_priority */ - NULL, /* struct _pthread_fastlock * p_lock */ + &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */ 0, /* int p_signal */ NULL, /* sigjmp_buf * p_signal_buf */ NULL, /* sigjmp_buf * p_cancel_buf */ @@ -387,9 +387,49 @@ int __pthread_initialize_manager(void) return -1; } /* Start the thread manager */ - pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND - , (void *)(long)manager_pipe[0]); + pid = 0; + if (__pthread_initial_thread.p_report_events) + { + /* It's a bit more complicated. We have to report the creation of + the manager thread. */ + int idx = __td_eventword (TD_CREATE); + uint32_t mask = __td_eventmask (TD_CREATE); + + if ((mask & (__pthread_threads_events.event_bits[idx] + | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx])) + != 0) + { + pid = __clone(__pthread_manager_event, + (void **) __pthread_manager_thread_tos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); + + if (pid != -1) + { + /* Now fill in the information about the new thread in + the newly created thread's data structure. We cannot let + the new thread do this since we don't know whether it was + already scheduled when we send the event. */ + __pthread_manager_thread.p_eventbuf.eventdata = + &__pthread_manager_thread; + __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE; + __pthread_last_event = &__pthread_manager_thread; + __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1; + __pthread_manager_thread.p_pid = pid; + + /* Now call the function which signals the event. */ + __linuxthreads_create_event (); + + /* Now restart the thread. */ + __pthread_unlock(__pthread_manager_thread.p_lock); + } + } + } + + if (pid == 0) + pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); if (pid == -1) { free(__pthread_manager_thread_bos); __libc_close(manager_pipe[0]); |