Index: alpha/alpha/genassym.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/genassym.c,v retrieving revision 1.10 diff -u -r1.10 genassym.c --- genassym.c 1999/11/22 15:23:58 1.10 +++ genassym.c 1999/12/05 19:59:39 @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -83,6 +83,9 @@ OFF(P_MD_PCBPADDR, struct proc, p_md.md_pcbpaddr); OFF(P_MD_HAE, struct proc, p_md.md_hae); CONST1(MDP_HAEUSED); + + OFF(P_ASTFLAGS, struct proc, p_astflags); + CONST1(AST_RESCHED) OFF(CHIPSET_WRITE_HAE, struct alpha_chipset, write_hae); Index: alpha/alpha/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/machdep.c,v retrieving revision 1.66 diff -u -r1.66 machdep.c --- machdep.c 1999/12/03 07:20:22 1.66 +++ machdep.c 1999/12/04 05:49:57 @@ -1433,6 +1433,7 @@ */ SIGSETOLD(p->p_sigmask, ksc.sc_mask); SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); set_regs(p, (struct reg *)ksc.sc_regs); p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc; @@ -1493,6 +1494,7 @@ p->p_sigmask = uc.uc_sigmask; SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); /* XXX ksc.sc_ownedfp ? */ alpha_fpstate_drop(p); Index: alpha/alpha/swtch.s =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/swtch.s,v retrieving revision 1.14 diff -u -r1.14 swtch.s --- swtch.s 1999/11/10 21:14:24 1.14 +++ swtch.s 1999/12/05 21:58:46 @@ -82,7 +82,6 @@ /**************************************************************************/ -IMPORT(want_resched, 4) IMPORT(Lev1map, 8) /* @@ -195,8 +194,12 @@ * in which case curproc would be NULL. */ stq s2, curproc /* curproc = p */ - stl zero, want_resched /* we've rescheduled */ + ldbu t0, P_ASTFLAGS(s2) + bic t0, AST_RESCHED, t1 + stb t1, P_ASTFLAGS(s2) + stl t1, astpending + /* * Now running on the new u struct. * Restore registers and return. @@ -270,6 +273,7 @@ beq t2, Lrestoreregs /* no: return */ /* We've got an AST. Handle it. */ + stl zero, astpending /* clear it now! */ ldiq a0, ALPHA_PSL_IPL_0 /* drop IPL to zero */ call_pal PAL_OSF1_swpipl mov sp, a0 /* only arg is frame */ Index: alpha/alpha/trap.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/trap.c,v retrieving revision 1.22 diff -u -r1.22 trap.c --- trap.c 1999/11/10 21:14:24 1.22 +++ trap.c 1999/12/05 22:00:22 @@ -96,30 +96,6 @@ u_int64_t pc; u_quad_t oticks; { - int sig, s; - - /* take pending signals */ - while ((sig = CURSIG(p)) != 0) - postsig(sig); - p->p_priority = p->p_usrpri; - if (want_resched) { - /* - * Since we are curproc, a clock interrupt could - * change our priority without changing run queues - * (the running process is not kept on a run queue). - * If this happened after we setrunqueue ourselves but - * before we switch()'ed, we might not be on the queue - * indicated by our priority. - */ - s = splstatclock(); - setrunqueue(p); - p->p_stats->p_ru.ru_nivcsw++; - mi_switch(); - splx(s); - while ((sig = CURSIG(p)) != 0) - postsig(sig); - } - /* * If profiling, charge recent system time to the trapped pc. */ @@ -127,7 +103,7 @@ addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); } - curpriority = p->p_priority; + curpriority = p->p_usrpri; } static void @@ -706,6 +682,7 @@ { register struct proc *p; u_quad_t sticks; + int sig, s; p = curproc; sticks = p->p_sticks; @@ -716,11 +693,35 @@ cnt.v_soft++; - astpending = 0; - if (p->p_flag & P_OWEUPC) { - p->p_flag &= ~P_OWEUPC; + if (astison(p, AST_PROFTICK)) { + astoff(p, AST_PROFTICK); addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); + } + + if (astison(p, AST_RESCHED)) { + astoff(p, AST_RESCHED); + /* + * Since we are curproc, a clock interrupt could + * change our priority without changing run queues + * (the running process is not kept on a run queue). + * If this happened after we setrunqueue ourselves but + * before we switch()'ed, we might not be on the queue + * indicated by our priority. + */ + p->p_priority = p->p_usrpri; + s = splhigh(); + setrunqueue(p); + p->p_stats->p_ru.ru_nivcsw++; + mi_switch(); + splx(s); + } + + /* take pending signals */ + if (astison(p, AST_SIGNAL)) { + astoff(p, AST_SIGNAL); + while ((sig = CURSIG(p)) != 0) + postsig(sig); } userret(p, framep->tf_regs[FRAME_PC], sticks); Index: alpha/include/cpu.h =================================================================== RCS file: /home/ncvs/src/sys/alpha/include/cpu.h,v retrieving revision 1.11 diff -u -r1.11 cpu.h --- cpu.h 1999/11/22 15:14:54 1.11 +++ cpu.h 1999/12/05 20:00:56 @@ -71,29 +71,42 @@ * Preempt the current process if in interrupt from user mode, * or after the current trap/syscall if in system mode. */ -#define need_resched() { want_resched = 1; aston(); } +#define need_resched() if (curproc) aston(curproc, AST_RESCHED) -#define resched_wanted() want_resched - /* * Give a profiling tick to the current process when the user profiling * buffer pages are invalid. On the hp300, request an ast to send us * through trap, marking the proc as needing a profiling tick. */ -#define need_proftick(p) { (p)->p_flag |= P_OWEUPC; aston(); } +#define need_proftick(p) aston(p, AST_PROFTICK) /* * Notify the current process (p) that it has a signal pending, * process as soon as possible. */ -#define signotify(p) aston() +#define signotify(p) aston(p, AST_SIGNAL) + +#define aston(p, flag) \ + do { \ + (p)->p_astflags |= (flag); \ + if ((p) == curproc) \ + astpending = 1; \ + } while (0) + +#define astoff(p, flag) \ + do { \ + (p)->p_astflags &= ~(flag); \ + } while (0) + +#define astison(p, flag) ((p)->p_astflags & (flag)) -#define aston() (astpending = 1) +#define AST_RESCHED 1 +#define AST_PROFTICK 2 +#define AST_SIGNAL 4 #ifdef KERNEL u_int32_t astpending; /* need to trap before returning to user mode */ u_int32_t intr_nesting_level; /* bookeeping only; counts software intr */ -u_int32_t want_resched; /* resched() was called */ #endif Index: i386/i386/exception.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/exception.s,v retrieving revision 1.65 diff -u -r1.65 exception.s --- exception.s 1999/11/26 05:02:06 1.65 +++ exception.s 1999/12/04 05:45:13 @@ -136,57 +136,8 @@ pushl $0; TRAP(T_MCHK) IDTVEC(rsvd) pushl $0; TRAP(T_RESERVED) - IDTVEC(fpu) -#if NNPX > 0 - /* - * Handle like an interrupt (except for accounting) so that we can - * call npx_intr to clear the error. It would be better to handle - * npx interrupts as traps. Nested interrupts would probably have - * to be converted to ASTs. - */ - pushl $0 /* dummy error code */ - pushl $0 /* dummy trap type */ - pushal - pushl %ds - pushl %es /* now stack frame is a trap frame */ - pushl %fs - movl $KDSEL,%eax - movl %ax,%ds - movl %ax,%es - MOVL_KPSEL_EAX - movl %ax,%fs - FAKE_MCOUNT(13*4(%esp)) - -#ifdef SMP - MPLOCKED incl _cnt+V_TRAP - FPU_LOCK - ECPL_LOCK -#ifdef CPL_AND_CML - movl _cml,%eax - pushl %eax /* save original cml */ -#else - movl _cpl,%eax - pushl %eax /* save original cpl */ -#endif /* CPL_AND_CML */ - ECPL_UNLOCK - pushl $0 /* dummy unit to finish intr frame */ -#else /* SMP */ - movl _cpl,%eax - pushl %eax - pushl $0 /* dummy unit to finish intr frame */ - incl _cnt+V_TRAP -#endif /* SMP */ - - call _npx_intr - - incb _intr_nesting_level - MEXITCOUNT - jmp _doreti -#else /* NNPX > 0 */ pushl $0; TRAP(T_ARITHTRAP) -#endif /* NNPX > 0 */ - IDTVEC(align) TRAP(T_ALIGNFLT) Index: i386/i386/genassym.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/genassym.c,v retrieving revision 1.82 diff -u -r1.82 genassym.c --- genassym.c 1999/10/11 20:33:04 1.82 +++ genassym.c 1999/12/05 18:44:51 @@ -68,7 +68,7 @@ #ifdef SMP #include #endif -#include +#include #include #include #include @@ -86,6 +86,7 @@ printf("#define\tVM_PMAP %#x\n", OS(vmspace, vm_pmap)); printf("#define\tPM_ACTIVE %#x\n", OS(pmap, pm_active)); printf("#define\tP_ADDR %#x\n", OS(proc, p_addr)); + printf("#define\tP_ASTFLAGS %#x\n", OS(proc, p_astflags)); printf("#define\tP_STAT %#x\n", OS(proc, p_stat)); printf("#define\tP_WCHAN %#x\n", OS(proc, p_wchan)); #ifdef SMP @@ -94,6 +95,7 @@ #endif printf("#define\tSSLEEP %d\n", SSLEEP); printf("#define\tSRUN %d\n", SRUN); + printf("#define\tAST_RESCHED %d\n", AST_RESCHED); printf("#define\tV_TRAP %#x\n", OS(vmmeter, v_trap)); printf("#define\tV_SYSCALL %#x\n", OS(vmmeter, v_syscall)); printf("#define\tV_INTR %#x\n", OS(vmmeter, v_intr)); @@ -189,6 +191,7 @@ #ifdef USER_LDT printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, gd_currentldt)); #endif + printf("#define\tGD_ASTPENDING %#x\n", OS(globaldata, gd_astpending)); #ifdef SMP printf("#define\tGD_CPUID %#x\n", OS(globaldata, gd_cpuid)); printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, gd_cpu_lockid)); Index: i386/i386/globals.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/globals.s,v retrieving revision 1.13 diff -u -r1.13 globals.s --- globals.s 1999/08/28 00:43:44 1.13 +++ globals.s 1999/12/05 18:45:25 @@ -79,6 +79,9 @@ .set gd_currentldt,globaldata + GD_CURRENTLDT #endif + .globl gd_astpending + .set gd_astpending,globaldata + GD_ASTPENDING + #ifndef SMP .globl _curproc, _curpcb, _npxproc .globl _common_tss, _switchtime, _switchticks @@ -97,6 +100,9 @@ .globl _currentldt .set _currentldt,globaldata + GD_CURRENTLDT #endif + + .globl _astpending + .set _astpending,globaldata + GD_ASTPENDING #endif #ifdef SMP Index: i386/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.379 diff -u -r1.379 machdep.c --- machdep.c 1999/11/24 01:02:58 1.379 +++ machdep.c 1999/12/04 05:45:14 @@ -855,6 +855,7 @@ SIGSETOLD(p->p_sigmask, scp->sc_mask); SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); regs->tf_ebp = scp->sc_fp; regs->tf_esp = scp->sc_sp; regs->tf_eip = scp->sc_pc; @@ -967,6 +968,7 @@ p->p_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); return(EJUSTRETURN); } Index: i386/i386/mp_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.112 diff -u -r1.112 mp_machdep.c --- mp_machdep.c 1999/11/27 12:32:20 1.112 +++ mp_machdep.c 1999/12/05 18:38:45 @@ -64,10 +64,9 @@ #include #include #include +#include #include #include -#include -#include #include /** TEST_DEFAULT_CONFIG, TEST_TEST1 */ #include #include @@ -2239,10 +2238,10 @@ prof = &p->p_stats->p_prof; if (pc >= prof->pr_off && (i = PC_TO_INDEX(pc, prof)) < prof->pr_size) { - if ((p->p_flag & P_OWEUPC) == 0) { + if (!astison(p, AST_PROFTICK)) { prof->pr_addr = pc; prof->pr_ticks = 1; - p->p_flag |= P_OWEUPC; + aston(p, AST_PROFTICK); } *astmap |= (1 << id); } Index: i386/i386/swtch.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/swtch.s,v retrieving revision 1.87 diff -u -r1.87 swtch.s --- swtch.s 1999/08/28 00:43:51 1.87 +++ swtch.s 1999/12/05 19:27:02 @@ -63,10 +63,6 @@ .globl _hlt_vector _hlt_vector: .long _default_halt /* pointer to halt routine */ - .globl _panic - - .globl _want_resched -_want_resched: .long 0 /* we need to re-run the scheduler */ #if defined(SWTCH_OPTIM_STATS) .globl _swtch_optim_stats, _tlb_flush_count _swtch_optim_stats: .long 0 /* number of _swtch_optims */ @@ -356,11 +352,12 @@ CROSSJUMP(je, _idle, jne) /* if no proc, idle */ movl %eax,%ecx - movl $0,%eax - movl %eax,_want_resched + andb $~AST_RESCHED,P_ASTFLAGS(%ecx) + movb P_ASTFLAGS(%ecx),%al + movb %al,_astpending #ifdef DIAGNOSTIC - cmpl %eax,P_WCHAN(%ecx) + cmpl $0,P_WCHAN(%ecx) jne badsw1 cmpb $SRUN,P_STAT(%ecx) jne badsw2 Index: i386/i386/trap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/trap.c,v retrieving revision 1.143 diff -u -r1.143 trap.c --- trap.c 1999/11/09 01:44:19 1.143 +++ trap.c 1999/12/05 22:02:09 @@ -155,41 +155,6 @@ struct trapframe *frame; u_quad_t oticks; { - int sig, s; - - while ((sig = CURSIG(p)) != 0) - postsig(sig); - -#if 0 - if (!want_resched && - (p->p_priority <= p->p_usrpri) && - (p->p_rtprio.type == RTP_PRIO_NORMAL)) { - int newpriority; - p->p_estcpu += 1; - newpriority = PUSER + p->p_estcpu / 4 + 2 * p->p_nice; - newpriority = min(newpriority, MAXPRI); - p->p_usrpri = newpriority; - } -#endif - - p->p_priority = p->p_usrpri; - if (want_resched) { - /* - * Since we are curproc, clock will normally just change - * our priority without moving us from one queue to another - * (since the running process is not on a queue.) - * If that happened after we setrunqueue ourselves but before we - * mi_switch()'ed, we might not be on the queue indicated by - * our priority. - */ - s = splhigh(); - setrunqueue(p); - p->p_stats->p_ru.ru_nivcsw++; - mi_switch(); - splx(s); - while ((sig = CURSIG(p)) != 0) - postsig(sig); - } /* * Charge system time if profiling. */ @@ -197,7 +162,7 @@ addupc_task(p, frame->tf_eip, (u_int)(p->p_sticks - oticks) * psratio); - curpriority = p->p_priority; + curpriority = p->p_usrpri; } /* @@ -215,6 +180,7 @@ u_quad_t sticks = 0; int i = 0, ucode = 0, type, code; vm_offset_t eva; + int sig, s; if (!(frame.tf_eflags & PSL_I)) { /* @@ -307,17 +273,49 @@ break; case T_ARITHTRAP: /* arithmetic trap */ +#if NNPX > 0 + ucode = npxtrap(); +#else ucode = code; +#endif i = SIGFPE; break; case T_ASTFLT: /* Allow process switch */ - astoff(); cnt.v_soft++; - if (p->p_flag & P_OWEUPC) { - p->p_flag &= ~P_OWEUPC; + if (astison(p, AST_PROFTICK)) { + astoff(p, AST_PROFTICK); addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); + } + if (astison(p, AST_RESCHED)) { + astoff(p, AST_RESCHED); + /* + * Since we are curproc, clock will normally + * just change our priority without moving us + * from one queue to another (since the running + * process is not on a queue.) If that happened + * after we setrunqueue ourselves but before we + * mi_switch()'ed, we might not be on the queue + * indicated by our priority. + */ + p->p_priority = p->p_usrpri; + s = splhigh(); + setrunqueue(p); + p->p_stats->p_ru.ru_nivcsw++; + mi_switch(); + splx(s); + } + if (astison(p, AST_SIGNAL)) { + astoff(p, AST_SIGNAL); + while ((sig = CURSIG(p)) != 0) + postsig(sig); + } + if (astison(p, AST_NPXTRAP)) { + astoff(p, AST_NPXTRAP); + ucode = npxtrap(); + i = SIGFPE; + break; } goto out; Index: i386/include/asnames.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/asnames.h,v retrieving revision 1.43 diff -u -r1.43 asnames.h --- asnames.h 1999/11/19 16:49:28 1.43 +++ asnames.h 1999/12/05 18:45:40 @@ -155,7 +155,6 @@ #define _arith_invalid arith_invalid #define _arith_overflow arith_overflow #define _arith_underflow arith_underflow -#define _astpending astpending #define _bcopy bcopy #define _bcopy_vector bcopy_vector #define _bigJump bigJump @@ -321,7 +320,6 @@ #define _vm86paddr vm86paddr #define _vm86pcb vm86pcb #define _vm_page_zero_idle vm_page_zero_idle -#define _want_resched want_resched #define _wm_sqrt wm_sqrt #endif /* __ELF__ */ @@ -333,6 +331,7 @@ #define FS(x) x #endif +#define _astpending FS(astpending) #define _common_tss FS(common_tss) #define _common_tssd FS(common_tssd) #define _cpuid FS(cpuid) @@ -340,6 +339,8 @@ #define _curpcb FS(curpcb) #define _curproc FS(curproc) #define _currentldt FS(currentldt) +#define _idlestack FS(idlestack) +#define _idlestack_top FS(idlestack_top) #define _inside_intr FS(inside_intr) #define _npxproc FS(npxproc) #define _other_cpus FS(other_cpus) @@ -355,8 +356,6 @@ #define _switchticks FS(switchticks) #define _switchtime FS(switchtime) #define _tss_gdt FS(tss_gdt) -#define _idlestack FS(idlestack) -#define _idlestack_top FS(idlestack_top) #endif Index: i386/include/cpu.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/cpu.h,v retrieving revision 1.41 diff -u -r1.41 cpu.h --- cpu.h 1999/08/28 00:44:09 1.41 +++ cpu.h 1999/12/05 19:14:45 @@ -83,10 +83,8 @@ * Preempt the current process if in interrupt from user mode, * or after the current trap/syscall if in system mode. */ -#define need_resched() { want_resched = 1; aston(); } +#define need_resched() if (curproc) aston(curproc, AST_RESCHED) -#define resched_wanted() want_resched - /* * Arrange to handle pending profiling ticks before returning to user mode. * @@ -94,16 +92,37 @@ * single tick and the P_OWEUPC flag served as a counter. Now there is a * counter in the proc table and flag isn't really necessary. */ -#define need_proftick(p) { (p)->p_flag |= P_OWEUPC; aston(); } +#define need_proftick(p) aston(p, AST_PROFTICK) /* * Notify the current process (p) that it has a signal pending, * process as soon as possible. + */ +#define signotify(p) aston(p, AST_SIGNAL) + +/* + * Delayed handling of FPU exception via IRQ13 interrupt. */ -#define signotify(p) aston() +#define need_npxtrap(p) aston(p, AST_NPXTRAP) -#define aston() do { astpending = 1; } while (0) -#define astoff() +#define aston(p, flag) \ + do { \ + (p)->p_astflags |= (flag); \ + if ((p) == curproc) \ + astpending = 1; \ + } while (0) + +#define astoff(p, flag) \ + do { \ + (p)->p_astflags &= ~(flag); \ + } while (0) + +#define astison(p, flag) ((p)->p_astflags & (flag)) + +#define AST_RESCHED 1 +#define AST_PROFTICK 2 +#define AST_SIGNAL 4 +#define AST_NPXTRAP 8 /* * CTL_MACHDEP definitions. @@ -125,11 +144,12 @@ } #ifdef KERNEL -extern int astpending; +#ifndef astpending +extern u_char astpending; +#endif extern char btext[]; extern char etext[]; extern u_char intr_nesting_level; -extern int want_resched; /* resched was called */ void fork_trampoline __P((void)); void fork_return __P((struct proc *, struct trapframe)); Index: i386/include/globaldata.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/globaldata.h,v retrieving revision 1.11 diff -u -r1.11 globaldata.h --- globaldata.h 1999/08/28 00:44:12 1.11 +++ globaldata.h 1999/12/05 18:46:01 @@ -51,6 +51,7 @@ #ifdef USER_LDT int gd_currentldt; #endif + u_char gd_astpending; #ifdef SMP u_int gd_cpuid; u_int gd_cpu_lockid; Index: i386/include/globals.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/globals.h,v retrieving revision 1.4 diff -u -r1.4 globals.h --- globals.h 1999/08/28 00:44:12 1.4 +++ globals.h 1999/12/05 18:46:12 @@ -95,6 +95,8 @@ #define currentldt GLOBAL_LVALUE(currentldt, int) #endif +#define astpending GLOBAL_LVALUE(astpending, u_char) + #ifdef SMP #define cpuid GLOBAL_RVALUE(cpuid, u_int) #define other_cpus GLOBAL_LVALUE(other_cpus, u_int) @@ -123,6 +125,8 @@ #ifdef USER_LDT GLOBAL_FUNC(currentldt) #endif + +GLOBAL_FUNC(astpending) #ifdef SMP GLOBAL_FUNC(cpuid) Index: i386/include/npx.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/npx.h,v retrieving revision 1.16 diff -u -r1.16 npx.h --- npx.h 1999/08/28 00:44:19 1.16 +++ npx.h 1999/11/08 23:44:45 @@ -145,6 +145,7 @@ void npxexit __P((struct proc *p)); void npxinit __P((int control)); void npxsave __P((struct save87 *addr)); +int npxtrap __P((void)); #endif #endif /* !_MACHINE_NPX_H_ */ Index: i386/isa/apic_vector.s =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/apic_vector.s,v retrieving revision 1.47 diff -u -r1.47 apic_vector.s --- apic_vector.s 1999/11/19 16:49:30 1.47 +++ apic_vector.s 1999/12/05 18:49:53 @@ -159,24 +159,6 @@ #endif /** FAST_WITHOUTCPL */ -/* - * - */ -#define PUSH_FRAME \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs - -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp - #define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 @@ -702,7 +684,7 @@ movl _cpl, %eax #endif pushl %eax - movl $1, _astpending /* XXX */ + movb $1, _astpending /* XXX */ AVCPL_UNLOCK lock incb _intr_nesting_level @@ -716,10 +698,13 @@ lock btrl %eax, CNAME(resched_cpus) jnc 2f - movl $1, CNAME(want_resched) + movl _curproc, %eax + testl %eax, %eax + jz 2f + orb $AST_RESCHED, P_ASTFLAGS(%eax) lock incl CNAME(want_resched_cnt) -2: +2: lock incl CNAME(cpuast_cnt) MEXITCOUNT Index: i386/isa/icu_vector.s =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/icu_vector.s,v retrieving revision 1.14 diff -u -r1.14 icu_vector.s --- icu_vector.s 1999/08/28 00:44:42 1.14 +++ icu_vector.s 1999/11/09 00:01:24 @@ -110,14 +110,9 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; \ - pushl %ds ; /* save our data and extra segments ... */ \ - pushl %es ; \ - pushl %fs ; \ + PUSH_FRAME ; /* save general and segment registers ... */ \ movl $KDSEL,%eax ; /* ... and reload with kernel's own ... */ \ - movl %ax,%ds ; /* ... early for obsolete reasons */ \ + movl %ax,%ds ; /* ... segments early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ maybe_extra_ipending ; \ @@ -157,11 +152,7 @@ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp ; \ + POP_FRAME ; \ iret MCOUNT_LABEL(bintr) Index: i386/isa/ipl.s =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/ipl.s,v retrieving revision 1.32 diff -u -r1.32 ipl.s --- ipl.s 1999/11/19 16:49:30 1.32 +++ ipl.s 1999/12/04 05:45:18 @@ -67,9 +67,6 @@ .globl _softtty_imask _softtty_imask: .long SWI_TTY_MASK - .globl _astpending -_astpending: .long 0 - /* pending interrupts blocked by splxxx() */ .globl _ipending _ipending: .long 0 @@ -331,7 +328,7 @@ ALIGN_TEXT doreti_ast: - movl $0,_astpending + movb $0,_astpending sti movl $T_ASTFLT,TF_TRAPNO(%esp) call _trap Index: i386/isa/npx.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/npx.c,v retrieving revision 1.78 diff -u -r1.78 npx.c --- npx.c 1999/09/21 10:51:47 1.78 +++ npx.c 1999/11/17 02:09:31 @@ -59,18 +59,16 @@ #ifndef SMP #include #endif +#include #include -#include #include #include #include -#include #ifndef SMP #include #endif #include #include -#include #ifndef SMP #include @@ -122,8 +120,10 @@ typedef u_char bool_t; static int npx_attach __P((device_t dev)); - void npx_intr __P((void *)); static void npx_identify __P((driver_t *driver, device_t parent)); +#ifndef SMP +static void npx_intr __P((void *)); +#endif static int npx_probe __P((device_t dev)); static int npx_probe1 __P((device_t dev)); #ifdef I586_CPU @@ -711,13 +711,24 @@ * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable * solution for signals other than SIGFPE. */ -void +int +npxtrap() +{ + u_short control; + + fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); + fnstcw(&control); + fnclex(); + + return (fpetable[(curpcb->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | + (curpcb->pcb_savefpu.sv_ex_sw & 0x40)]); +} + +#ifndef SMP +static void npx_intr(dummy) void *dummy; { - int code; - u_short control; - struct intrframe *frame; if (npxproc == NULL || !npx_exists) { printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", @@ -731,53 +742,9 @@ } outb(0xf0, 0); - fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); - fnstcw(&control); - fnclex(); - - /* - * Pass exception to process. - */ - frame = (struct intrframe *)&dummy; /* XXX */ - if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { - /* - * Interrupt is essentially a trap, so we can afford to call - * the SIGFPE handler (if any) as soon as the interrupt - * returns. - * - * XXX little or nothing is gained from this, and plenty is - * lost - the interrupt frame has to contain the trap frame - * (this is otherwise only necessary for the rescheduling trap - * in doreti, and the frame for that could easily be set up - * just before it is used). - */ - curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); - /* - * Encode the appropriate code for detailed information on - * this exception. - */ - code = - fpetable[(curpcb->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | - (curpcb->pcb_savefpu.sv_ex_sw & 0x40)]; - trapsignal(curproc, SIGFPE, code); - } else { - /* - * Nested interrupt. These losers occur when: - * o an IRQ13 is bogusly generated at a bogus time, e.g.: - * o immediately after an fnsave or frstor of an - * error state. - * o a couple of 386 instructions after - * "fstpl _memvar" causes a stack overflow. - * These are especially nasty when combined with a - * trace trap. - * o an IRQ13 occurs at the same time as another higher- - * priority interrupt. - * - * Treat them like a true async interrupt. - */ - psignal(curproc, SIGFPE); - } + need_npxtrap(curproc); } +#endif /* * Implement device not available (DNA) exception Index: i386/isa/vector.s =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/vector.s,v retrieving revision 1.32 diff -u -r1.32 vector.s --- vector.s 1999/08/28 00:45:04 1.32 +++ vector.s 1999/11/09 00:01:58 @@ -106,6 +106,21 @@ * loading segregs. */ +#define PUSH_FRAME \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ + pushl %ds ; /* save data and extra segments */ \ + pushl %es ; \ + pushl %fs + +#define POP_FRAME \ + popl %fs ; \ + popl %es ; \ + popl %ds ; \ + popal ; \ + addl $4+4,%esp + #ifdef APIC_IO #include "i386/isa/apic_vector.s" #else Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.71 diff -u -r1.71 kern_sig.c --- kern_sig.c 1999/11/21 19:03:10 1.71 +++ kern_sig.c 1999/12/04 05:45:26 @@ -455,6 +455,7 @@ break; case SIG_UNBLOCK: SIGSETNAND(p->p_sigmask, *set); + SIGNOTIFY(p); break; case SIG_SETMASK: SIG_CANTMASK(*set); @@ -462,6 +463,7 @@ SIGSETLO(p->p_sigmask, *set); else p->p_sigmask = *set; + SIGNOTIFY(p); break; default: error = EINVAL; @@ -645,6 +647,7 @@ SIG2OSIG(p->p_sigmask, p->p_retval[0]); SIGSETLO(p->p_sigmask, set); (void) spl0(); + SIGNOTIFY(p); return (0); } #endif /* COMPAT_43 || COMPAT_SUNOS */ @@ -1044,6 +1047,9 @@ */ if (action == SIG_HOLD && (!(prop & SA_CONT) || p->p_stat != SSTOP)) return; + + signotify(p); + s = splhigh(); switch (p->p_stat) { @@ -1157,10 +1163,8 @@ * other than kicking ourselves if we are running. * It will either never be noticed, or noticed very soon. */ - if (p == curproc) - signotify(p); #ifdef SMP - else if (p->p_stat == SRUN) + if (p->p_stat == SRUN) forward_signal(p); #endif goto out; Index: pc98/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/pc98/i386/machdep.c,v retrieving revision 1.146 diff -u -r1.146 machdep.c --- machdep.c 1999/11/25 12:43:07 1.146 +++ machdep.c 1999/12/04 05:46:04 @@ -868,6 +868,7 @@ SIGSETOLD(p->p_sigmask, scp->sc_mask); SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); regs->tf_ebp = scp->sc_fp; regs->tf_esp = scp->sc_sp; regs->tf_eip = scp->sc_pc; @@ -980,6 +981,7 @@ p->p_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); + SIGNOTIFY(p); return(EJUSTRETURN); } Index: pc98/pc98/npx.c =================================================================== RCS file: /home/ncvs/src/sys/pc98/pc98/npx.c,v retrieving revision 1.52 diff -u -r1.52 npx.c --- npx.c 1999/09/22 12:01:36 1.52 +++ npx.c 1999/12/05 01:26:20 @@ -60,18 +60,16 @@ #ifndef SMP #include #endif +#include #include -#include #include #include #include -#include #ifndef SMP #include #endif #include #include -#include #ifndef SMP #include @@ -129,8 +127,10 @@ #define NPXIRQ 8 static int npx_attach __P((device_t dev)); - void npx_intr __P((void *)); static void npx_identify __P((driver_t *driver, device_t parent)); +#ifndef SMP +static void npx_intr __P((void *)); +#endif static int npx_probe __P((device_t dev)); static int npx_probe1 __P((device_t dev)); #ifdef I586_CPU @@ -764,13 +764,24 @@ * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable * solution for signals other than SIGFPE. */ -void +int +npxtrap() +{ + u_short control; + + fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); + fnstcw(&control); + fnclex(); + + return (fpetable[(curpcb->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | + (curpcb->pcb_savefpu.sv_ex_sw & 0x40)]); +} + +#ifndef SMP +static void npx_intr(dummy) void *dummy; { - int code; - u_short control; - struct intrframe *frame; if (npxproc == NULL || !npx_exists) { printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", @@ -788,53 +799,9 @@ #else outb(0xf0, 0); #endif - fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); - fnstcw(&control); - fnclex(); - - /* - * Pass exception to process. - */ - frame = (struct intrframe *)&dummy; /* XXX */ - if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { - /* - * Interrupt is essentially a trap, so we can afford to call - * the SIGFPE handler (if any) as soon as the interrupt - * returns. - * - * XXX little or nothing is gained from this, and plenty is - * lost - the interrupt frame has to contain the trap frame - * (this is otherwise only necessary for the rescheduling trap - * in doreti, and the frame for that could easily be set up - * just before it is used). - */ - curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); - /* - * Encode the appropriate code for detailed information on - * this exception. - */ - code = - fpetable[(curpcb->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | - (curpcb->pcb_savefpu.sv_ex_sw & 0x40)]; - trapsignal(curproc, SIGFPE, code); - } else { - /* - * Nested interrupt. These losers occur when: - * o an IRQ13 is bogusly generated at a bogus time, e.g.: - * o immediately after an fnsave or frstor of an - * error state. - * o a couple of 386 instructions after - * "fstpl _memvar" causes a stack overflow. - * These are especially nasty when combined with a - * trace trap. - * o an IRQ13 occurs at the same time as another higher- - * priority interrupt. - * - * Treat them like a true async interrupt. - */ - psignal(curproc, SIGFPE); - } + need_npxtrap(curproc); } +#endif /* * Implement device not available (DNA) exception Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.95 diff -u -r1.95 proc.h --- proc.h 1999/11/28 12:12:14 1.95 +++ proc.h 1999/12/04 05:46:13 @@ -191,11 +191,12 @@ short p_locks; /* DEBUG: lockmgr count of held locks */ short p_simple_locks; /* DEBUG: count of held simple locks */ - unsigned int p_stops; /* procfs event bitmask */ - unsigned int p_stype; /* procfs stop event type */ + u_int p_stops; /* procfs event bitmask */ + u_int p_stype; /* procfs stop event type */ char p_step; /* procfs stop *once* flag */ - unsigned char p_pfsflags; /* procfs flags */ - char p_pad3[2]; /* padding for alignment */ + u_char p_pfsflags; /* procfs flags */ + u_char p_astflags; /* AST flags */ + char p_pad3[1]; /* padding for alignment */ register_t p_retval[2]; /* syscall aux returns */ struct sigiolst p_sigiolst; /* list of sigio sources */ int p_sigparent; /* signal to parent on exit */ Index: sys/signalvar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/signalvar.h,v retrieving revision 1.31 diff -u -r1.31 signalvar.h --- signalvar.h 1999/10/14 17:29:53 1.31 +++ signalvar.h 1999/12/05 00:45:10 @@ -44,8 +44,6 @@ * Kernel signal definitions and data structures, * not exported to user programs. */ -int __sigisempty __P((sigset_t *set)); -int __sigseteq __P((sigset_t *set1, sigset_t *set2)); /* * Process signal actions and state, needed only within the process @@ -125,6 +123,8 @@ #define SIGSETEQ(set1, set2) __sigseteq(&(set1), &(set2)) #define SIGSETNEQ(set1, set2) (!__sigseteq(&(set1), &(set2))) +#define SIGSETMASKED(set, mask) __sigsetmasked(&(set), &(mask)) + #define SIGSETOR(set1, set2) \ do { \ int __i; \ @@ -164,7 +164,7 @@ #define SIG2OSIG(sig, osig) osig = (sig).__bits[0] #define OSIG2SIG(osig, sig) SIGEMPTYSET(sig); (sig).__bits[0] = osig -extern __inline int +static __inline int __sigisempty(sigset_t *set) { int i; @@ -176,7 +176,7 @@ return (1); } -extern __inline int +static __inline int __sigseteq(sigset_t *set1, sigset_t *set2) { int i; @@ -188,6 +188,18 @@ return (1); } +static __inline int +__sigsetmasked(sigset_t *set, sigset_t *mask) +{ + int i; + + for (i = 0; i < _SIG_WORDS; i++) { + if (set->__bits[i] & ~mask->__bits[i]) + return (0); + } + return (1); +} + #ifdef KERNEL struct pgrp; @@ -211,7 +223,6 @@ void sigexit __P((struct proc *p, int signum)); void siginit __P((struct proc *p)); void trapsignal __P((struct proc *p, int sig, u_long code)); -int __cursig __P((struct proc *p)); /* * Machine-dependent functions: @@ -219,25 +230,16 @@ void sendsig __P((sig_t action, int sig, sigset_t *retmask, u_long code)); /* - * Inline functions: - */ -#define CURSIG(p) __cursig(p) - -/* * Determine signal that should be delivered to process p, the current * process, 0 if none. If there is a pending stop signal with default * action, the process stops in issignal(). */ -extern __inline int __cursig(struct proc *p) -{ - sigset_t tmpset; - - tmpset = p->p_siglist; - SIGSETNAND(tmpset, p->p_sigmask); - return ((SIGISEMPTY(p->p_siglist) || - (!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))) - ? 0 : issignal(p)); -} +#define __SIGPEND(p) \ + (!SIGISEMPTY((p)->p_siglist) && \ + (!SIGSETMASKED((p)->p_siglist, (p)->p_sigmask) || \ + (p)->p_flag & P_TRACED)) +#define CURSIG(p) (__SIGPEND(p) ? issignal(p) : 0) +#define SIGNOTIFY(p) do { if (__SIGPEND(p)) signotify(p); } while (0) #endif /* KERNEL */