diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/os/fork.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/sys/thread.h | 1 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/syscall.c | 4 | ||||
-rw-r--r-- | usr/src/uts/sparc/os/syscall.c | 12 | ||||
-rw-r--r-- | usr/src/uts/sparc/v9/ml/syscall_trap.s | 3 |
5 files changed, 21 insertions, 7 deletions
diff --git a/usr/src/uts/common/os/fork.c b/usr/src/uts/common/os/fork.c index a28569b18d..c276ea332f 100644 --- a/usr/src/uts/common/os/fork.c +++ b/usr/src/uts/common/os/fork.c @@ -334,6 +334,7 @@ cfork(int isvfork, int isfork1) /* for each entry in the parent's lwp directory... */ for (i = 0, ldp = p->p_lwpdir; i < p->p_lwpdir_sz; i++, ldp++) { klwp_t *clwp; + kthread_t *ct; if ((lep = ldp->ld_entry) == NULL) continue; @@ -342,17 +343,22 @@ cfork(int isvfork, int isfork1) clwp = forklwp(ttolwp(t), cp, t->t_tid); if (clwp == NULL) goto forklwperr; + ct = lwptot(clwp); /* * Inherit lwp_wait()able and daemon flags. */ - lwptot(clwp)->t_proc_flag |= + ct->t_proc_flag |= (t->t_proc_flag & (TP_TWAIT|TP_DAEMON)); /* * Keep track of the clone of curthread to * post return values through lwp_setrval(). + * Mark other threads for special treatment + * by lwp_rtt() / post_syscall(). */ if (t == curthread) clone = clwp; + else + ct->t_flag |= T_FORKALL; } else { /* * Replicate zombie lwps in the child. diff --git a/usr/src/uts/common/sys/thread.h b/usr/src/uts/common/sys/thread.h index 805812e8f0..bf60447de0 100644 --- a/usr/src/uts/common/sys/thread.h +++ b/usr/src/uts/common/sys/thread.h @@ -350,6 +350,7 @@ typedef struct _kthread { #define T_WAKEABLE 0x0002 /* thread is blocked, signals enabled */ #define T_TOMASK 0x0004 /* use lwp_sigoldmask on return from signal */ #define T_TALLOCSTK 0x0008 /* thread structure allocated from stk */ +#define T_FORKALL 0x0010 /* thread was cloned by forkall() */ #define T_WOULDBLOCK 0x0020 /* for lockfs */ #define T_DONTBLOCK 0x0040 /* for lockfs */ #define T_DONTPEND 0x0080 /* for lockfs */ diff --git a/usr/src/uts/intel/ia32/os/syscall.c b/usr/src/uts/intel/ia32/os/syscall.c index 8ca3634c1c..b53c04ff92 100644 --- a/usr/src/uts/intel/ia32/os/syscall.c +++ b/usr/src/uts/intel/ia32/os/syscall.c @@ -19,8 +19,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -589,6 +590,7 @@ sig_check: */ lwp->lwp_eosys = NORMALRETURN; clear_stale_fd(); + t->t_flag &= ~T_FORKALL; /* * If a single-step trap occurred on a syscall (see trap()) diff --git a/usr/src/uts/sparc/os/syscall.c b/usr/src/uts/sparc/os/syscall.c index 380de9212b..8f985e6a95 100644 --- a/usr/src/uts/sparc/os/syscall.c +++ b/usr/src/uts/sparc/os/syscall.c @@ -677,11 +677,14 @@ post_syscall(long rval1, long rval2) * The default action is to redo the trap instruction. * We increment the pc and npc past it for NORMALRETURN. * JUSTRETURN has set up a new pc and npc already. - * RESTARTSYS automatically restarts by leaving pc and npc - * alone. + * If we are a cloned thread of forkall(), don't + * adjust here because we have already inherited + * the adjusted values from our clone. */ - rp->r_pc = rp->r_npc; - rp->r_npc += 4; + if (!(t->t_flag & T_FORKALL)) { + rp->r_pc = rp->r_npc; + rp->r_npc += 4; + } } /* @@ -726,6 +729,7 @@ sig_check: */ lwp->lwp_eosys = NORMALRETURN; clear_stale_fd(); + t->t_flag &= ~T_FORKALL; if (t->t_astflag | t->t_sig_check) { /* diff --git a/usr/src/uts/sparc/v9/ml/syscall_trap.s b/usr/src/uts/sparc/v9/ml/syscall_trap.s index e3ada480e7..72c131afb6 100644 --- a/usr/src/uts/sparc/v9/ml/syscall_trap.s +++ b/usr/src/uts/sparc/v9/ml/syscall_trap.s @@ -578,7 +578,7 @@ lwp_rtt(void) ldn [THREAD_REG + T_STACK], %l7 call __dtrace_probe___proc_start sub %l7, STACK_BIAS, %sp - ba 0f + ba,a,pt %xcc, 0f ENTRY_NP(lwp_rtt) ldn [THREAD_REG + T_STACK], %l7 @@ -593,5 +593,6 @@ lwp_rtt(void) ldx [%l7 + O1_OFF], %o1 ba,a,pt %xcc, user_rtt SET_SIZE(lwp_rtt) + SET_SIZE(lwp_rtt_initial) #endif /* lint */ |