From 923f75011953091f1e0c5b734f7ff98f71f9791b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 9 Jan 2003 06:53:27 +0000 Subject: [PATCH] 2003-01-08 Roland McGrath Support for new Linux 2.5 thread features. * defs.h [LINUX]: Define __NR_exit_group if not defined. (struct tcb): New members nclone_threads, nclone_detached, and nclone_waiting. (TCB_CLONE_DETACHED, TCB_CLONE_THREAD, TCB_GROUP_EXITING): New macros. (waiting_parent): Macro removed. (pid2tcb): Declare it. * process.c (internal_clone) [TCB_CLONE_THREAD]: Reparent the new child to our parent if we are a CLONE_THREAD child ourselves. Maintain TCB_CLONE_THREAD and TCB_CLONE_DETACHED flags and counts. (internal_wait) [TCB_CLONE_THREAD]: Factor out detached children when determining if we have any. If TCB_CLONE_THREAD is set, check parent's children instead of our own, and bump nclone_waiting count. (internal_exit) [__NR_exit_group]: Set the TCB_GROUP_EXITING flag if the syscall was exit_group. * syscall.c (internal_syscall): Use internal_exit for exit_group. * strace.c (pid2tcb): No longer static. (alloctcb) [TCB_CLONE_THREAD]: Initialize new fields. (droptcb) [TCB_CLONE_THREAD]: Maintain new fields. If we have thread children, set TCB_EXITING and don't clear the TCB. (resume) [TCB_CLONE_THREAD]: Decrement parent's nclone_waiting. (detach) [TCB_CLONE_THREAD]: When calling resume, check all thread children of our parent that might be waiting for us too. [TCB_GROUP_EXITING] (handle_group_exit): New function. (trace) [TCB_GROUP_EXITING]: Use that in place of detach or droptcb. --- defs.h | 30 ++++++++++++++++++++++++++---- syscall.c | 3 +++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/defs.h b/defs.h index fecafee1..11d0877d 100644 --- a/defs.h +++ b/defs.h @@ -261,6 +261,11 @@ struct tcb { struct tcb *parent; /* Parent of this process */ int nchildren; /* # of traced children */ int waitpid; /* pid(s) this process is waiting for */ +#ifdef LINUX + int nclone_threads; /* # of nchildren with CLONE_THREAD */ + int nclone_detached; /* # of nchildren with CLONE_DETACHED */ + int nclone_waiting; /* clone threads in wait4 (TCB_SUSPENDED) */ +#endif /* (1st arg of wait4()) */ long baddr; /* `Breakpoint' address */ long inst[2]; /* Instructions on above */ @@ -297,6 +302,26 @@ struct tcb { # if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) # define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */ # endif +# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */ +# define TCB_CLONE_THREAD 010000 /* CLONE_THREAD set in creating syscall */ +# define TCB_GROUP_EXITING 020000 /* TCB_EXITING was exit_group, not _exit */ +# include +# ifndef __NR_exit_group +# /* Hack: Most headers around are too old to have __NR_exit_group. */ +# ifdef ALPHA +# define __NR_exit_group 405 +# elif defined I386 +# define __NR_exit_group 252 +# elif defined IA64 +# define __NR_exit_group 1236 +# elif defined POWERPC +# define __NR_exit_group 234 +# elif defined S390 || defined S390X +# define __NR_exit_group 248 +# elif defined SPARC +# define __NR_exit_group 188 +# endif /* ALPHA et al */ +# endif /* !__NR_exit_group */ #endif /* LINUX */ /* qualifier flags */ @@ -314,10 +339,6 @@ struct tcb { #define syserror(tcp) ((tcp)->u_error != 0) #define verbose(tcp) (qual_flags[(tcp)->scno] & QUAL_VERBOSE) #define abbrev(tcp) (qual_flags[(tcp)->scno] & QUAL_ABBREV) -#define waiting_parent(tcp) \ - (tcp->parent && \ - (tcp->parent->flags & TCB_SUSPENDED) && \ - (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) struct xlat { int val; @@ -371,6 +392,7 @@ extern struct tcb *tcp_last; extern int set_personality P((int personality)); extern char *xlookup P((struct xlat *, int)); extern struct tcb *alloctcb P((int)); +extern struct tcb *pid2tcb P((int)); extern void droptcb P((struct tcb *)); extern void set_sortby P((char *)); diff --git a/syscall.c b/syscall.c index 204b8ace..578db441 100644 --- a/syscall.c +++ b/syscall.c @@ -669,6 +669,9 @@ struct tcb *tcp; #endif #ifdef SYS32_exit case SYS32_exit: +#endif +#ifdef __NR_exit_group + case __NR_exit_group: #endif internal_exit(tcp); break;