summaryrefslogtreecommitdiff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog10
-rw-r--r--linuxthreads/internals.h1
-rw-r--r--linuxthreads/manager.c20
-rw-r--r--linuxthreads/pthread.c48
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]);