diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/alpha/alpha/trap.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/alpha/alpha/trap.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/alpha/alpha/trap.c Fri Aug 27 20:38:33 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/alpha/alpha/trap.c Fri Oct 29 17:21:30 1999 *************** *** 39,44 **** --- 39,45 ---- #include #include #include + #include #include #include #include *************** *** 71,78 **** struct proc *fpcurproc; /* current user of the FPU */ - void userret __P((struct proc *, u_int64_t, u_quad_t)); - unsigned long Sfloat_to_reg __P((unsigned int)); unsigned int reg_to_Sfloat __P((unsigned long)); unsigned long Tfloat_reg_cvt __P((unsigned long)); --- 72,77 ---- *************** *** 87,136 **** static void printtrap __P((const unsigned long, const unsigned long, const unsigned long, const unsigned long, struct trapframe *, int, int)); - /* - * Define the code needed before returning to user mode, for - * trap and syscall. - */ - void - userret(p, pc, oticks) - register struct proc *p; - 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. - */ - if (p->p_flag & P_PROFIL) { - addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); - } - - curpriority = p->p_priority; - } - static void printtrap(a0, a1, a2, entry, framep, isfatal, user) const unsigned long a0, a1, a2, entry; --- 86,91 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/alpha/include/cpu.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/alpha/include/cpu.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/alpha/include/cpu.h Fri Aug 27 20:38:42 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/alpha/include/cpu.h Fri Oct 29 17:21:30 1999 *************** *** 77,84 **** */ #define need_resched() { want_resched = 1; aston(); } - #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 --- 77,82 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/conf/options /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/conf/options *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/conf/options Mon Oct 25 18:07:30 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/conf/options Fri Oct 29 17:21:30 1999 *************** *** 69,78 **** UCONSOLE ICMP_BANDLIM ! # POSIX kernel options P1003_1B opt_posix.h _KPOSIX_PRIORITY_SCHEDULING opt_posix.h _KPOSIX_VERSION opt_posix.h # Do we want the config file compiled into the kernel? INCLUDE_CONFIG_FILE opt_config.h --- 69,89 ---- UCONSOLE ICMP_BANDLIM ! # POSIX kernel options. P1003_1B and priority scheduling are ! # now on by default. There are NO_ options to turn them off. ! # The positive options will go away after a grace period. ! ! NO_P1003_1B opt_posix.h P1003_1B opt_posix.h + NO_KPOSIX_PRIORITY_SCHEDULING opt_posix.h _KPOSIX_PRIORITY_SCHEDULING opt_posix.h _KPOSIX_VERSION opt_posix.h + + # Compile time disabling of RTPRIO + NO_RTPRIO opt_sched.h + + # Use RTPRIO and SMP even though it doesn't work + RTPRIO_AND_SMP_ANYWAY opt_sched.h # Do we want the config file compiled into the kernel? INCLUDE_CONFIG_FILE opt_config.h diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/dev/amr/amr.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/dev/amr/amr.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/dev/amr/amr.c Tue Oct 26 19:18:57 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/dev/amr/amr.c Fri Oct 29 17:21:30 1999 *************** *** 34,39 **** --- 34,40 ---- #include #include #include + #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/dev/mlx/mlx.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/dev/mlx/mlx.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/dev/mlx/mlx.c Tue Oct 26 19:20:42 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/dev/mlx/mlx.c Fri Oct 29 17:21:31 1999 *************** *** 34,39 **** --- 34,40 ---- #include #include #include + #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/conf/LINT /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/conf/LINT *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/conf/LINT Wed Oct 27 02:30:10 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/conf/LINT Fri Oct 29 17:21:31 1999 *************** *** 106,111 **** --- 106,112 ---- # Mandatory: options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O + options RTPRIO_AND_SMP_ANYWAY # Even though they don't work together # Optional, these are the defaults plus 1: options NCPU=5 # number of CPUs diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/mp_machdep.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/mp_machdep.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/mp_machdep.c Fri Oct 15 17:38:15 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/mp_machdep.c Fri Oct 29 17:21:31 1999 *************** *** 29,34 **** --- 29,37 ---- #include "opt_cpu.h" #include "opt_user_ldt.h" + #warning Make non-SCHEDULER_FRIEND before commit + #define SCHEDULER_FRIEND + #ifdef SMP #include #else *************** *** 39,44 **** --- 42,48 ---- #include #include #include + #include #include #include #include *************** *** 2324,2336 **** } if (p != NULL) { p->p_cpticks++; ! if (++p->p_estcpu == 0) ! p->p_estcpu--; ! if ((p->p_estcpu & 3) == 0) { ! resetpriority(p); ! if (p->p_priority >= PUSER) ! p->p_priority = p->p_usrpri; ! } /* Update resource usage integrals and maximums. */ if ((pstats = p->p_stats) != NULL && --- 2328,2334 ---- } if (p != NULL) { p->p_cpticks++; ! update_estcpu(p); /* Update resource usage integrals and maximums. */ if ((pstats = p->p_stats) != NULL && diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/trap.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/trap.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/trap.c Fri Aug 27 20:43:51 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/trap.c Fri Oct 29 17:21:31 1999 *************** *** 51,56 **** --- 51,57 ---- #include #include #include + #include #include #include #include *************** *** 143,205 **** "machine check trap", /* 28 T_MCHK */ }; - static __inline void userret __P((struct proc *p, struct trapframe *frame, - u_quad_t oticks)); - #if defined(I586_CPU) && !defined(NO_F00F_HACK) extern int has_f00f_bug; #endif - - static __inline void - userret(p, frame, oticks) - struct proc *p; - 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. - */ - if (p->p_flag & P_PROFIL) - addupc_task(p, frame->tf_eip, - (u_int)(p->p_sticks - oticks) * psratio); - - curpriority = p->p_priority; - } /* * Exception, fault, and trap interface to the FreeBSD kernel. --- 144,152 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/vm_machdep.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/vm_machdep.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/i386/vm_machdep.c Mon Oct 11 10:50:03 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/i386/vm_machdep.c Fri Oct 29 17:21:31 1999 *************** *** 50,55 **** --- 50,56 ---- #include #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/ibcs2/ibcs2_misc.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/ibcs2/ibcs2_misc.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/ibcs2/ibcs2_misc.c Wed Sep 29 11:12:09 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/ibcs2/ibcs2_misc.c Fri Oct 29 17:21:31 1999 *************** *** 65,70 **** --- 65,71 ---- #include #include #include + #include #include #include #include *************** *** 924,937 **** struct ibcs2_nice_args *uap; { int error; struct setpriority_args sa; SCARG(&sa, which) = PRIO_PROCESS; SCARG(&sa, who) = 0; ! SCARG(&sa, prio) = p->p_nice + SCARG(uap, incr); if ((error = setpriority(p, &sa)) != 0) return EPERM; ! p->p_retval[0] = p->p_nice; return 0; } --- 925,941 ---- struct ibcs2_nice_args *uap; { int error; + int nice; struct setpriority_args sa; + nice = synch_proc_priority(p, 0); + SCARG(&sa, which) = PRIO_PROCESS; SCARG(&sa, who) = 0; ! SCARG(&sa, prio) = nice + SCARG(uap, incr); if ((error = setpriority(p, &sa)) != 0) return EPERM; ! p->p_retval[0] = nice; return 0; } diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/include/cpu.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/include/cpu.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/include/cpu.h Fri Aug 27 20:44:09 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/include/cpu.h Fri Oct 29 17:21:31 1999 *************** *** 85,92 **** */ #define need_resched() { want_resched = 1; aston(); } - #define resched_wanted() want_resched - /* * Arrange to handle pending profiling ticks before returning to user mode. * --- 85,90 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/isa/elink.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/isa/elink.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/i386/isa/elink.c Fri Aug 27 20:44:41 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/i386/isa/elink.c Fri Oct 29 17:21:30 1999 *************** *** 58,72 **** /* * The `ID sequence' is really just snapshots of an 8-bit CRC register as 0 * bits are shifted in. Different board types use different polynomials. */ void ! elink_idseq(u_char p) { register int i; register u_char c; c = 0xff; for (i = 255; i; i--) { outb(ELINK_ID_PORT, c); if (c & 0x80) { c <<= 1; --- 58,75 ---- /* * The `ID sequence' is really just snapshots of an 8-bit CRC register as 0 * bits are shifted in. Different board types use different polynomials. + * + * Bit_delay is the appropriate bit delay for this architecture. */ void ! elink_idseq(u_char p, void (*bit_delay)(void)) { register int i; register u_char c; c = 0xff; for (i = 255; i; i--) { + (*bit_delay)(); outb(ELINK_ID_PORT, c); if (c & 0x80) { c <<= 1; diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/init_main.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/init_main.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/init_main.c Mon Oct 11 11:19:08 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/init_main.c Fri Oct 29 17:21:31 1999 *************** *** 51,56 **** --- 51,57 ---- #include #include #include + #include #include #include #include *************** *** 318,326 **** p->p_flag = P_INMEM | P_SYSTEM; p->p_stat = SRUN; ! p->p_nice = NZERO; ! p->p_rtprio.type = RTP_PRIO_NORMAL; ! p->p_rtprio.prio = 0; /* * Link for kernel based threads --- 319,325 ---- p->p_flag = P_INMEM | P_SYSTEM; p->p_stat = SRUN; ! synch_proc0_init(p); /* * Link for kernel based threads diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_clock.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_clock.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_clock.c Sun Oct 10 12:18:36 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_clock.c Mon Nov 1 13:35:54 1999 *************** *** 48,53 **** --- 48,54 ---- #include #include #include + #include #include #include #include *************** *** 371,376 **** --- 372,378 ---- register struct gmonparam *g; int i; #endif + static int schedclk; /* XXX NetBSD "schedclk" fallback */ register struct proc *p; struct pstats *pstats; long rss; *************** *** 392,398 **** * If this process is being profiled record the tick. */ p->p_uticks++; ! if (p->p_nice > NZERO) cp_time[CP_NICE]++; else cp_time[CP_USER]++; --- 394,401 ---- * If this process is being profiled record the tick. */ p->p_uticks++; ! ! if (synch_proc_isnice(p)) cp_time[CP_NICE]++; else cp_time[CP_USER]++; *************** *** 446,473 **** * programs: the amount of time in each cpu state. */ - /* - * We adjust the priority of the current process. The priority of - * a process gets worse as it accumulates CPU time. The cpu usage - * estimator (p_estcpu) is increased here. The formula for computing - * priorities (in kern_synch.c) will compute a different value each - * time p_estcpu increases by 4. The cpu usage estimator ramps up - * quite quickly when the process is running (linearly), and decays - * away exponentially, at a rate which is proportionally slower when - * the system is busy. The basic principal is that the system will - * 90% forget that the process used a lot of CPU time in 5 * loadav - * seconds. This causes the system to favor processes which haven't - * run much recently, and to round-robin among other processes. - */ if (p != NULL) { p->p_cpticks++; ! if (++p->p_estcpu == 0) ! p->p_estcpu--; ! if ((p->p_estcpu & 3) == 0) { ! resetpriority(p); ! if (p->p_priority >= PUSER) ! p->p_priority = p->p_usrpri; ! } /* Update resource usage integrals and maximums. */ if ((pstats = p->p_stats) != NULL && --- 449,462 ---- * programs: the amount of time in each cpu state. */ if (p != NULL) { p->p_cpticks++; ! ! /* XXX Call estcpu as if this is a NetBSD "schedclock" ! * fallback. ! */ ! if ((++schedclk & 3) == 0) ! update_estcpu(p); /* Update resource usage integrals and maximums. */ if ((pstats = p->p_stats) != NULL && diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_exit.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_exit.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_exit.c Mon Oct 11 16:33:12 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_exit.c Fri Oct 29 17:21:31 1999 *************** *** 48,53 **** --- 48,54 ---- #include #include #include + #include #include #include #include *************** *** 427,437 **** nfound++; if (p->p_stat == SZOMB) { ! /* charge childs scheduling cpu usage to parent */ ! if (curproc->p_pid != 1) { ! curproc->p_estcpu = min(curproc->p_estcpu + ! p->p_estcpu, UCHAR_MAX); ! } q->p_retval[0] = p->p_pid; #ifdef COMPAT_43 --- 428,434 ---- nfound++; if (p->p_stat == SZOMB) { ! synch_zombie_charge(p); q->p_retval[0] = p->p_pid; #ifdef COMPAT_43 diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_fork.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_fork.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_fork.c Mon Oct 11 11:19:08 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_fork.c Fri Oct 29 17:21:31 1999 *************** *** 49,54 **** --- 49,55 ---- #include #include #include + #include #include #include #include *************** *** 436,445 **** } #endif ! /* ! * set priority of child to be that of parent ! */ ! p2->p_estcpu = p1->p_estcpu; /* * This begins the section where we must prevent the parent --- 437,443 ---- } #endif ! synch_fork(p1, p2); /* * This begins the section where we must prevent the parent diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_resource.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_resource.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_resource.c Mon Oct 11 11:19:09 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_resource.c Fri Oct 29 17:21:31 1999 *************** *** 49,54 **** --- 49,55 ---- #include #include #include + #include #include #include *************** *** 57,63 **** #include #include - static int donice __P((struct proc *curp, struct proc *chgp, int n)); /* dosetrlimit non-static: Needed by SysVR4 emulator */ int dosetrlimit __P((struct proc *p, u_int which, struct rlimit *limp)); --- 58,63 ---- *************** *** 88,94 **** p = pfind(uap->who); if (p == 0) break; ! low = p->p_nice; break; case PRIO_PGRP: { --- 88,94 ---- p = pfind(uap->who); if (p == 0) break; ! low = synch_proc_priority(p, 0); break; case PRIO_PGRP: { *************** *** 100,107 **** break; for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) { ! if (p->p_nice < low) ! low = p->p_nice; } break; } --- 100,108 ---- break; for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) { ! int pri = synch_proc_priority(p, 0); ! if (pri < low) ! low = pri; } break; } *************** *** 109,118 **** case PRIO_USER: if (uap->who == 0) uap->who = curp->p_ucred->cr_uid; ! for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) if (p->p_ucred->cr_uid == uap->who && ! p->p_nice < low) ! low = p->p_nice; break; default: --- 110,121 ---- case PRIO_USER: if (uap->who == 0) uap->who = curp->p_ucred->cr_uid; ! for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { ! int pri = synch_proc_priority(p, 0); if (p->p_ucred->cr_uid == uap->who && ! pri < low) ! low = pri; ! } break; default: *************** *** 186,213 **** return (error); } - static int - donice(curp, chgp, n) - register struct proc *curp, *chgp; - register int n; - { - register struct pcred *pcred = curp->p_cred; - - if (pcred->pc_ucred->cr_uid && pcred->p_ruid && - pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid && - pcred->p_ruid != chgp->p_ucred->cr_uid) - return (EPERM); - if (n > PRIO_MAX) - n = PRIO_MAX; - if (n < PRIO_MIN) - n = PRIO_MIN; - if (n < chgp->p_nice && suser(curp)) - return (EACCES); - chgp->p_nice = n; - (void)resetpriority(chgp); - return (0); - } - /* rtprio system call */ #ifndef _SYS_SYSPROTO_H_ struct rtprio_args { --- 189,194 ---- *************** *** 228,234 **** register struct rtprio_args *uap; { register struct proc *p; - register struct pcred *pcred = curp->p_cred; struct rtprio rtp; int error; --- 209,214 ---- *************** *** 244,290 **** if (p == 0) return (ESRCH); ! switch (uap->function) { ! case RTP_LOOKUP: ! return (copyout(&p->p_rtprio, uap->rtp, sizeof(struct rtprio))); ! case RTP_SET: ! if (pcred->pc_ucred->cr_uid && pcred->p_ruid && ! pcred->pc_ucred->cr_uid != p->p_ucred->cr_uid && ! pcred->p_ruid != p->p_ucred->cr_uid) ! return (EPERM); ! /* disallow setting rtprio in most cases if not superuser */ ! if (suser(curp)) { ! /* can't set someone else's */ ! if (uap->pid) ! return (EPERM); ! /* can't set realtime priority */ ! /* ! * Realtime priority has to be restricted for reasons which should be ! * obvious. However, for idle priority, there is a potential for ! * system deadlock if an idleprio process gains a lock on a resource ! * that other processes need (and the idleprio process can't run ! * due to a CPU-bound normal process). Fix me! XXX ! */ ! #if 0 ! if (RTP_PRIO_IS_REALTIME(rtp.type)) ! #endif ! if (rtp.type != RTP_PRIO_NORMAL) ! return (EPERM); ! } ! switch (rtp.type) { ! #ifdef RTP_PRIO_FIFO ! case RTP_PRIO_FIFO: ! #endif ! case RTP_PRIO_REALTIME: ! case RTP_PRIO_NORMAL: ! case RTP_PRIO_IDLE: ! if (rtp.prio > RTP_PRIO_MAX) ! return (EINVAL); ! p->p_rtprio = rtp; ! return (0); ! default: ! return (EINVAL); ! } default: return (EINVAL); --- 224,237 ---- if (p == 0) return (ESRCH); ! switch (uap->function) { ! case RTP_LOOKUP: { ! (void)synch_proc_priority(p, &rtp); ! return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); ! } ! case RTP_SET: ! return dortprio(curp, p, &rtp); ! default: return (EINVAL); diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_sig.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_sig.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_sig.c Tue Oct 12 09:14:18 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_sig.c Fri Oct 29 17:21:31 1999 *************** *** 50,55 **** --- 50,56 ---- #include #include #include + #include #include #include #include *************** *** 1025,1033 **** action = SIG_DFL; } ! if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) && (p->p_flag & P_TRACED) == 0) ! p->p_nice = NZERO; if (prop & SA_CONT) SIG_STOPSIGMASK(p->p_siglist); --- 1026,1037 ---- action = SIG_DFL; } ! /* ! * Ensure that a process that is being killed can run. ! */ ! if (action == SIG_DFL && (prop & SA_KILL) && (p->p_flag & P_TRACED) == 0) ! synch_proc_killing(p); if (prop & SA_CONT) SIG_STOPSIGMASK(p->p_siglist); *************** *** 1176,1186 **** /*NOTREACHED*/ runfast: ! /* ! * Raise priority to at least PUSER. ! */ ! if (p->p_priority > PUSER) ! p->p_priority = PUSER; run: setrunnable(p); out: --- 1180,1187 ---- /*NOTREACHED*/ runfast: ! synch_proc_runfast(p); ! run: setrunnable(p); out: diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_subr.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_subr.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_subr.c Fri Aug 27 20:46:14 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_subr.c Fri Oct 29 17:21:31 1999 *************** *** 43,48 **** --- 43,49 ---- #include #include #include + #include #include #include #include *************** *** 53,60 **** #include #include - static void uio_yield __P((void)); - int uiomove(cp, n, uio) register caddr_t cp; --- 54,59 ---- *************** *** 91,98 **** case UIO_USERSPACE: case UIO_USERISPACE: ! if (ticks - switchticks >= hogticks) ! uio_yield(); if (uio->uio_rw == UIO_READ) error = copyout(cp, iov->iov_base, cnt); else --- 90,97 ---- case UIO_USERSPACE: case UIO_USERISPACE: ! if (resched_wanted()) ! synch_yield(curproc, 0); if (uio->uio_rw == UIO_READ) error = copyout(cp, iov->iov_base, cnt); else *************** *** 153,160 **** case UIO_USERSPACE: case UIO_USERISPACE: ! if (ticks - switchticks >= hogticks) ! uio_yield(); if (uio->uio_rw == UIO_READ) { #ifdef ENABLE_VFS_IOOPT if (vfs_ioopt && ((cnt & PAGE_MASK) == 0) && --- 152,159 ---- case UIO_USERSPACE: case UIO_USERISPACE: ! if (resched_wanted()) ! synch_yield(curproc, 0); if (uio->uio_rw == UIO_READ) { #ifdef ENABLE_VFS_IOOPT if (vfs_ioopt && ((cnt & PAGE_MASK) == 0) && *************** *** 235,242 **** cnt &= ~PAGE_MASK; ! if (ticks - switchticks >= hogticks) ! uio_yield(); error = vm_uiomove(&curproc->p_vmspace->vm_map, obj, uio->uio_offset, cnt, (vm_offset_t) iov->iov_base, &npagesmoved); --- 234,241 ---- cnt &= ~PAGE_MASK; ! if (resched_wanted()) ! synch_yield(curproc, 0); error = vm_uiomove(&curproc->p_vmspace->vm_map, obj, uio->uio_offset, cnt, (vm_offset_t) iov->iov_base, &npagesmoved); *************** *** 413,431 **** LIST_INIT(&hashtbl[i]); *nentries = hashsize; return (hashtbl); - } - - static void - uio_yield() - { - struct proc *p; - int s; - - p = curproc; - p->p_priority = p->p_usrpri; - s = splhigh(); - setrunqueue(p); - p->p_stats->p_ru.ru_nivcsw++; - mi_switch(); - splx(s); } --- 412,415 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_switch.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_switch.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_switch.c Thu Aug 19 12:06:08 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_switch.c Fri Oct 29 17:21:31 1999 *************** *** 26,35 **** --- 26,43 ---- * $FreeBSD: src/sys/kern/kern_switch.c,v 1.3 1999/08/19 16:06:08 peter Exp $ */ + /* + * Enable access to scheduler members. + */ + #define SCHEDULER_FRIEND + + #include "opt_sched.h" + #include #include #include #include + #include #include #include *************** *** 46,56 **** * queue. */ struct rq queues[NQS]; - struct rq rtqueues[NQS]; - struct rq idqueues[NQS]; u_int32_t queuebits; u_int32_t rtqueuebits; u_int32_t idqueuebits; /* * Initialize the run queues at boot time. --- 54,67 ---- * queue. */ struct rq queues[NQS]; u_int32_t queuebits; + + #ifndef NO_RTPRIO + struct rq rtqueues[NQS]; u_int32_t rtqueuebits; + struct rq idqueues[NQS]; u_int32_t idqueuebits; + #endif /* * Initialize the run queues at boot time. *************** *** 62,69 **** --- 73,82 ---- for (i = 0; i < NQS; i++) { TAILQ_INIT(&queues[i]); + #ifndef NO_RTPRIO TAILQ_INIT(&rtqueues[i]); TAILQ_INIT(&idqueues[i]); + #endif } } SYSINIT(runqueue, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, rqinit, NULL) *************** *** 82,87 **** --- 95,105 ---- u_int8_t pri; KASSERT(p->p_stat == SRUN, ("setrunqueue: proc not SRUN")); + #ifdef NO_RTPRIO + pri = p->p_priority >> 2; + q = &queues[pri]; + queuebits |= 1 << pri; + #else if (p->p_rtprio.type == RTP_PRIO_NORMAL) { pri = p->p_priority >> 2; q = &queues[pri]; *************** *** 98,103 **** --- 116,133 ---- } else { panic("setrunqueue: invalid rtprio type"); } + #endif + + /* XXX This is a little dangerous. We're looking up which + * queue to take the process off in remrunqueue from the scheduling + * class and saving this index in the proc. + * Instead here we ought to save everything + * (return a pointer to a {whichqueue,queuebits} structure) - + * then there isn't the possibility of someone changing + * p_rtprio.type and then calling remrunqueue. Also we don't need + * to look the queue up. + */ + p->p_rqindex = pri; /* remember the queue index */ TAILQ_INSERT_TAIL(q, p, p_procq); } *************** *** 115,120 **** --- 145,154 ---- u_int8_t pri; pri = p->p_rqindex; + #ifdef NO_RTPRIO + q = &queues[pri]; + which = &queuebits; + #else if (p->p_rtprio.type == RTP_PRIO_NORMAL) { q = &queues[pri]; which = &queuebits; *************** *** 128,133 **** --- 162,168 ---- } else { panic("remrunqueue: invalid rtprio type"); } + #endif TAILQ_REMOVE(q, p, p_procq); if (TAILQ_EMPTY(q)) { KASSERT((*which & (1 << pri)) != 0, *************** *** 144,150 **** --- 179,189 ---- u_int32_t procrunnable(void) { + #ifdef NO_RTPRIO + return (queuebits); + #else return (rtqueuebits || queuebits || idqueuebits); + #endif } /* *************** *** 159,164 **** --- 198,204 ---- * are mapped four priority levels per queue, this may allow the cpu to * choose a slightly lower priority process in order to preserve the cpu * caches. + * XXX This affinity doesn't play with a FIFO scheduler. */ struct proc * chooseproc(void) *************** *** 171,176 **** --- 211,226 ---- u_char id; #endif + #ifdef NO_RTPRIO + if (queuebits) { + pri = ffs(queuebits) - 1; + q = &queues[pri]; + which = &queuebits; + } else { + return NULL; + } + #else + if (rtqueuebits) { pri = ffs(rtqueuebits) - 1; q = &rtqueues[pri]; *************** *** 186,194 **** --- 236,248 ---- } else { return NULL; } + #endif p = TAILQ_FIRST(q); KASSERT(p, ("chooseproc: no proc on busy queue")); + #ifdef SMP + /* XXX Take this out for non-roundrobin scheduling classes */ + /* wander down the current run queue for this pri level for a match */ id = cpuid; while (p->p_lastcpu != id) { *************** *** 199,204 **** --- 253,259 ---- } } #endif + TAILQ_REMOVE(q, p, p_procq); if (TAILQ_EMPTY(q)) *which &= ~(1 << pri); diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_synch.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_synch.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_synch.c Wed Sep 29 11:03:42 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_synch.c Mon Nov 1 15:40:47 1999 *************** *** 39,49 **** --- 39,56 ---- * $FreeBSD: src/sys/kern/kern_synch.c,v 1.79 1999/09/29 15:03:42 marcel Exp $ */ + /* + * Enable access to scheduler members. + */ + #define SCHEDULER_FRIEND + #include "opt_ktrace.h" + #include "opt_sched.h" #include #include #include + #include #include #include #include *************** *** 62,72 **** #endif #include /* for UCHAR_MAX = typeof(p_priority)_MAX */ static void sched_setup __P((void *dummy)); SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) ! u_char curpriority; ! int hogticks; int lbolt; int sched_quantum; /* Roundrobin scheduling quantum in ticks. */ --- 69,94 ---- #endif #include /* for UCHAR_MAX = typeof(p_priority)_MAX */ + + /* RTPRIO doesn't work with SMP yet. + */ + #if defined(SMP) && !defined(NO_RTPRIO) && !defined RTPRIO_AND_SMP_ANYWAY + #error RTPRIO and SMP work incorrectly together (but sorta work). \ + Enable either NO_RTPRIO or RTPRIO_AND_SMP_ANYWAY + #endif + + #ifdef NO_RTPRIO + #define NORMAL_SCHEDULER(P) (1) + #define REALTIME_SCHEDULER(P) (0) + #else + #define NORMAL_SCHEDULER(P) ((P)->p_rtprio.type == RTP_PRIO_NORMAL) + #define REALTIME_SCHEDULER(P) (RTP_PRIO_IS_REALTIME((P)->p_rtprio.type)) + #endif + static void sched_setup __P((void *dummy)); SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) ! static int hogticks; int lbolt; int sched_quantum; /* Roundrobin scheduling quantum in ticks. */ *************** *** 74,79 **** --- 96,108 ---- static void roundrobin __P((void *arg)); static void schedcpu __P((void *arg)); static void updatepri __P((struct proc *p)); + static void resetpriority __P((struct proc *p)); + + + #define NICE_WEIGHT 2 /* priorities per nice level */ + #define PPQ (128 / NQS) /* priorities per queue */ + + #define MAX_ESTCPU (NICE_WEIGHT * PRIO_MAX - PPQ) /* As in NetBSD */ static int sysctl_kern_quantum SYSCTL_HANDLER_ARGS *************** *** 94,121 **** SYSCTL_PROC(_kern, OID_AUTO, quantum, CTLTYPE_INT|CTLFLAG_RW, 0, sizeof sched_quantum, sysctl_kern_quantum, "I", ""); ! /* maybe_resched: Decide if you need to reschedule or not ! * taking the priorities and schedulers into account. */ ! static void maybe_resched(struct proc *chk) { ! struct proc *p = curproc; /* XXX */ ! /* ! * Compare priorities if the new process is on the same scheduler, ! * otherwise the one on the more realtimeish scheduler wins. ! * ! * XXX idle scheduler still broken because proccess stays on idle ! * scheduler during waits (such as when getting FS locks). If a ! * standard process becomes runaway cpu-bound, the system can lockup ! * due to idle-scheduler processes in wakeup never getting any cpu. ! */ ! if (p == 0 || ! (chk->p_priority < curpriority && RTP_PRIO_BASE(p->p_rtprio.type) == RTP_PRIO_BASE(chk->p_rtprio.type)) || ! RTP_PRIO_BASE(chk->p_rtprio.type) < RTP_PRIO_BASE(p->p_rtprio.type) ! ) { need_resched(); } } int --- 123,216 ---- SYSCTL_PROC(_kern, OID_AUTO, quantum, CTLTYPE_INT|CTLFLAG_RW, 0, sizeof sched_quantum, sysctl_kern_quantum, "I", ""); ! static u_short curpriority; ! ! /* ! * prioritize: Compute the priority for a process. ! * ! * For normal processes this is basically the kernel priority divided ! * by the number of priorities per queue, that is, which priority ! * queue it is in. ! * ! * For fixed-scheduler priorities this is the priority ! * in the low byte together with the class in the high byte. */ ! ! #ifdef NO_RTPRIO ! #define prioritize(P) ((P)->p_priority / PPQ) ! #else ! ! /* ! * prioritize: Compute a priority based on the type of scheduler. ! */ ! static u_short ! prioritize(struct proc *p) { ! u_short priority; ! int class = RTP_PRIO_BASE(p->p_rtprio.type); ! if (class == RTP_PRIO_NORMAL) ! priority = (RTP_PRIO_NORMAL << 8) | (p->p_priority / PPQ); ! else ! priority = (class << 8) | p->p_rtprio.prio; ! ! return priority; ! } ! #endif ! ! /* ! * curpriority_cmp: Compare the priorities. Return: ! * <0: p < curpriority ! * 0: p == curpriority ! * >0: p > curpriority ! */ ! ! static int ! curpriority_cmp(struct proc *p) ! { ! return prioritize(p) - curpriority; ! } ! ! /* ! * maybe_resched: Decide if you need to reschedule or not, ! * taking the priorities and schedulers into account. ! * ! * This function needs to be call AFTER chk->p_priority has ! * been updated. ! */ ! static void ! maybe_resched(struct proc *chk) ! { ! if (curproc == 0) { need_resched(); } + else if (chk == curproc) { + /* + * If chk is curproc, we may need to preempt if + * we're making our priority less favorable. + * Yield the CPU. + */ + if (curpriority_cmp(chk) > 0) { + /* + * XXX Possibly increment nvcsw here, + * though we don't actually know. + */ + need_resched(); + } + } + /* + * If chk is not the curproc, we want to preempt if chk has + * a more favorable priority than curproc. + * + * We shouldn't preempt the current process because of the + * priority of a sleeping or stopped process. + * + */ + else if ((chk->p_flag & P_INMEM) && + chk->p_stat == SRUN && + curpriority_cmp(chk) < 0) { + need_resched(); + } } int *************** *** 132,147 **** roundrobin(arg) void *arg; { ! #ifndef SMP struct proc *p = curproc; /* XXX */ ! #endif ! ! #ifdef SMP need_resched(); forward_roundrobin(); ! #else ! if (p == 0 || RTP_PRIO_NEED_RR(p->p_rtprio.type)) ! need_resched(); #endif timeout(roundrobin, NULL, sched_quantum); --- 227,244 ---- roundrobin(arg) void *arg; { ! #if !defined(SMP) && !defined(NO_RTPRIO) struct proc *p = curproc; /* XXX */ ! ! if (p == 0 || RTP_PRIO_NEED_RR(p->p_rtprio.type)) { ! need_resched(); ! } ! #else need_resched(); + + #ifdef SMP forward_roundrobin(); ! #endif #endif timeout(roundrobin, NULL, sched_quantum); *************** *** 154,160 **** * Note that, as ps(1) mentions, this can let percentages * total over 100% (I've seen 137.9% for 3 processes). * ! * Note that statclock() updates p_estcpu and p_cpticks asynchronously. * * We wish to decay away 90% of p_estcpu in (5 * loadavg) seconds. * That is, the system wants to compute a value of decay such --- 251,257 ---- * Note that, as ps(1) mentions, this can let percentages * total over 100% (I've seen 137.9% for 3 processes). * ! * Note that update_estcpu() updates p_estcpu and p_cpticks independently. * * We wish to decay away 90% of p_estcpu in (5 * loadavg) seconds. * That is, the system wants to compute a value of decay such *************** *** 238,243 **** --- 335,366 ---- #define CCPU_SHIFT 11 /* + * Adjust the run queues in case the priority has changed enough + * to move a process into another run queue. + * + * Must be called splhigh(). + */ + + static void + adjust_runqueues(struct proc *p) + { + if (p->p_priority >= PUSER) { + if ((p != curproc) && + #ifdef SMP + (u_char)p->p_oncpu == 0xff && /* idle */ + #endif + p->p_stat == SRUN && + (p->p_flag & P_INMEM) && + (p->p_priority / PPQ) != (p->p_usrpri / PPQ)) { + remrunqueue(p); + p->p_priority = p->p_usrpri; + setrunqueue(p); + } else + p->p_priority = p->p_usrpri; + } + } + + /* * Recompute process priorities, every hz ticks. */ /* ARGSUSED */ *************** *** 248,254 **** register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); register struct proc *p; register int realstathz, s; - register unsigned int newcpu; realstathz = stathz ? stathz : hz; for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { --- 371,376 ---- *************** *** 281,303 **** (p->p_cpticks * FSCALE / realstathz)) >> FSHIFT; #endif p->p_cpticks = 0; ! newcpu = (u_int) decay_cpu(loadfac, p->p_estcpu) + p->p_nice; ! p->p_estcpu = min(newcpu, UCHAR_MAX); ! resetpriority(p); ! if (p->p_priority >= PUSER) { ! #define PPQ (128 / NQS) /* priorities per queue */ ! if ((p != curproc) && ! #ifdef SMP ! p->p_oncpu == 0xff && /* idle */ ! #endif ! p->p_stat == SRUN && ! (p->p_flag & P_INMEM) && ! (p->p_priority / PPQ) != (p->p_usrpri / PPQ)) { ! remrunqueue(p); ! p->p_priority = p->p_usrpri; ! setrunqueue(p); ! } else ! p->p_priority = p->p_usrpri; } splx(s); } --- 403,413 ---- (p->p_cpticks * FSCALE / realstathz)) >> FSHIFT; #endif p->p_cpticks = 0; ! if (NORMAL_SCHEDULER(p)) { ! p->p_estcpu = (u_int) decay_cpu(loadfac, p->p_estcpu); ! resetpriority(p); ! adjust_runqueues(p); ! maybe_resched(p); } splx(s); } *************** *** 315,332 **** updatepri(p) register struct proc *p; { ! register unsigned int newcpu = p->p_estcpu; ! register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); ! ! if (p->p_slptime > 5 * loadfac) ! p->p_estcpu = 0; ! else { ! p->p_slptime--; /* the first time was done in schedcpu */ ! while (newcpu && --p->p_slptime) ! newcpu = (int) decay_cpu(loadfac, newcpu); ! p->p_estcpu = min(newcpu, UCHAR_MAX); } ! resetpriority(p); } /* --- 425,447 ---- updatepri(p) register struct proc *p; { ! if (NORMAL_SCHEDULER(p) && p->p_slptime > 1) { ! register unsigned int newcpu = p->p_estcpu; ! register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); ! ! if (p->p_slptime > 5 * loadfac) ! p->p_estcpu = 0; ! else { ! p->p_slptime--; /* first time was done in schedcpu */ ! while (newcpu && --p->p_slptime) ! newcpu = (int) decay_cpu(loadfac, newcpu); ! p->p_estcpu = newcpu; ! } ! resetpriority(p); ! adjust_runqueues(p); ! maybe_resched(p); } ! p->p_slptime = 0; } /* *************** *** 440,446 **** p->p_stats->p_ru.ru_nvcsw++; mi_switch(); resume: ! curpriority = p->p_usrpri; splx(s); p->p_flag &= ~P_SINTR; if (p->p_flag & P_TIMEOUT) { --- 555,561 ---- p->p_stats->p_ru.ru_nvcsw++; mi_switch(); resume: ! curpriority = prioritize(p); splx(s); p->p_flag &= ~P_SINTR; if (p->p_flag & P_TIMEOUT) { *************** *** 579,585 **** p->p_stats->p_ru.ru_nvcsw++; mi_switch(); resume: ! curpriority = p->p_usrpri; splx(s); p->p_flag &= ~P_SINTR; --- 694,700 ---- p->p_stats->p_ru.ru_nvcsw++; mi_switch(); resume: ! curpriority = prioritize(p); splx(s); p->p_flag &= ~P_SINTR; *************** *** 676,686 **** } /* ! * Make all processes sleeping on the specified identifier runnable. */ ! void ! wakeup(ident) ! register void *ident; { register struct slpquehead *qp; register struct proc *p; --- 791,800 ---- } /* ! * Implement common wakeup code for wakeup_one and wakeup. */ ! static void ! wakeup_some(void *ident, int one_only) { register struct slpquehead *qp; register struct proc *p; *************** *** 695,703 **** p->p_wchan = 0; if (p->p_stat == SSLEEP) { /* OPTIMIZED EXPANSION OF setrunnable(p); */ ! if (p->p_slptime > 1) ! updatepri(p); ! p->p_slptime = 0; p->p_stat = SRUN; if (p->p_flag & P_INMEM) { setrunqueue(p); --- 809,815 ---- p->p_wchan = 0; if (p->p_stat == SSLEEP) { /* OPTIMIZED EXPANSION OF setrunnable(p); */ ! updatepri(p); p->p_stat = SRUN; if (p->p_flag & P_INMEM) { setrunqueue(p); *************** *** 707,713 **** wakeup((caddr_t)&proc0); } /* END INLINE EXPANSION */ ! goto restart; } } } --- 819,827 ---- wakeup((caddr_t)&proc0); } /* END INLINE EXPANSION */ ! if (!one_only) ! goto restart; ! break; } } } *************** *** 715,758 **** } /* * Make a process sleeping on the specified identifier runnable. ! * May wake more than one process if a target prcoess is currently * swapped out. */ void wakeup_one(ident) register void *ident; { ! register struct slpquehead *qp; ! register struct proc *p; ! int s; ! ! s = splhigh(); ! qp = &slpque[LOOKUP(ident)]; ! ! for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) { ! if (p->p_wchan == ident) { ! TAILQ_REMOVE(qp, p, p_procq); ! p->p_wchan = 0; ! if (p->p_stat == SSLEEP) { ! /* OPTIMIZED EXPANSION OF setrunnable(p); */ ! if (p->p_slptime > 1) ! updatepri(p); ! p->p_slptime = 0; ! p->p_stat = SRUN; ! if (p->p_flag & P_INMEM) { ! setrunqueue(p); ! maybe_resched(p); ! break; ! } else { ! p->p_flag |= P_SWAPINREQ; ! wakeup((caddr_t)&proc0); ! } ! /* END INLINE EXPANSION */ ! } ! } ! } ! splx(s); } /* --- 829,853 ---- } /* + * Make all processes sleeping on the specified identifier runnable. + */ + void + wakeup(ident) + register void *ident; + { + wakeup_some(ident, 0); + } + + /* * Make a process sleeping on the specified identifier runnable. ! * May wake more than one process if a target process is currently * swapped out. */ void wakeup_one(ident) register void *ident; { ! wakeup_some(ident, 1); } /* *************** *** 856,867 **** break; } p->p_stat = SRUN; if (p->p_flag & P_INMEM) setrunqueue(p); splx(s); ! if (p->p_slptime > 1) ! updatepri(p); ! p->p_slptime = 0; if ((p->p_flag & P_INMEM) == 0) { p->p_flag |= P_SWAPINREQ; wakeup((caddr_t)&proc0); --- 951,965 ---- break; } p->p_stat = SRUN; + + /* Put on the run queue corresponding to the priority passed in + * the sleep call. + */ if (p->p_flag & P_INMEM) setrunqueue(p); splx(s); ! updatepri(p); ! if ((p->p_flag & P_INMEM) == 0) { p->p_flag |= P_SWAPINREQ; wakeup((caddr_t)&proc0); *************** *** 872,894 **** /* * Compute the priority of a process when running in user mode. ! * Arrange to reschedule if the resulting priority is better * than that of the current process. */ ! void resetpriority(p) register struct proc *p; { register unsigned int newpriority; ! if (p->p_rtprio.type == RTP_PRIO_NORMAL) { ! newpriority = PUSER + p->p_estcpu / 4 + 2 * p->p_nice; ! newpriority = min(newpriority, MAXPRI); ! p->p_usrpri = newpriority; } ! maybe_resched(p); } /* ARGSUSED */ static void sched_setup(dummy) --- 970,1431 ---- /* * Compute the priority of a process when running in user mode. ! * ! * Unlike the original 4.4Lite resetpriority, this no longer ! * arranges to reschedule if the resulting priority is better * than that of the current process. */ ! static void resetpriority(p) register struct proc *p; { register unsigned int newpriority; ! newpriority = PUSER + p->p_estcpu + NICE_WEIGHT * (p->p_nice - NZERO); ! newpriority = min(newpriority, MAXPRI); ! p->p_usrpri = newpriority; ! } ! ! /* ! * We adjust the priority of the current process. The priority of ! * a process gets worse as it accumulates CPU time. The cpu usage ! * estimator (p_estcpu) is increased here. The formula for computing ! * priorities (in schedcpu()) will compute a different value each ! * time p_estcpu increases. The cpu usage estimator ramps up ! * quite quickly when the process is running (linearly), and decays ! * away exponentially, at a rate which is proportionally slower when ! * the system is busy. The basic principal is that the system will ! * 90% forget that the process used a lot of CPU time in 5 * loadav ! * seconds. This causes the system to favor processes which haven't ! * run much recently, and to round-robin among other processes. ! */ ! void ! update_estcpu(p) ! register struct proc *p; ! { ! if (NORMAL_SCHEDULER(p) && p->p_estcpu < MAX_ESTCPU) { ! p->p_estcpu++; ! resetpriority(p); ! if (p->p_priority >= PUSER) ! p->p_priority = p->p_usrpri; ! } ! } ! ! /* ! * synch_yield: Yield the CPU. ! * ! * Provide compatability with the "yield" system call from sys/thread. ! * I'm not sure if this behavior, which sinks you to the bottom of your ! * priorities, is needed. ! * ! * Without this flag you go to the end of your priority queue, and so if ! * you are still the highest priority process you will continue. This ! * is the POSIX defined behavior. ! * ! * The flag is ignored unless the current process is in the normal ! * scheduler class. ! */ ! ! int ! synch_yield(struct proc *p, const int is_thread) ! { ! int s = splhigh(); ! KASSERT(p == curproc, ("synch_yield")); ! ! if (NORMAL_SCHEDULER(p) && is_thread) ! p->p_priority = MAXPRI; ! ! setrunqueue(p); ! ! /* ! * XXX In the RTPRIO case ru_nvcsw can include unneeded ! * voluntary context switches to ourself. ! */ ! ! p->p_stats->p_ru.ru_nvcsw++; ! mi_switch(); ! splx(s); ! ! return 0; ! } ! ! /* ! * Initialize the scheduling info for proc0 ! */ ! void ! synch_proc0_init(struct proc *p0) ! { ! p0->p_nice = NZERO; ! ! #ifndef NO_RTPRIO ! p0->p_rtprio.type = RTP_PRIO_NORMAL; ! p0->p_rtprio.prio = 0; ! #endif ! } ! ! /* ! * Is a process running at a nice level? For now say idle priority ! * and nice processes are nice. ! */ ! int ! synch_proc_isnice(struct proc *p) ! { ! #ifdef NO_RTPRIO ! return p->p_nice > NZERO; ! #else ! return ( (p->p_rtprio.type == RTP_PRIO_IDLE) || ! (NORMAL_SCHEDULER(p) && p->p_nice > NZERO) ); ! #endif ! } ! ! /* ! * Return the current process priority. Since clients ! * expect this to return "p_nice" for now it does, and those ! * that know can get back the rtp. ! * ! * vm_glue uses this (p->p_nice) for selecting what to swap ! * back in. ! * ! * "ibcs2_nice" uses this to get back the nice value. ! */ ! int ! synch_proc_priority(struct proc *p, struct rtprio *rtp) ! { ! int nice; ! #ifdef NO_RTPRIO ! nice = p->p_nice; ! #else ! if (rtp) ! *rtp = p->p_rtprio; ! ! switch(p->p_rtprio.type) { ! case RTP_PRIO_REALTIME: ! nice = PRIO_MIN; ! break; ! ! case RTP_PRIO_IDLE: ! nice = PRIO_MAX; ! break; ! ! case RTP_PRIO_NORMAL: ! default: ! nice = p->p_nice; ! break; } ! #endif ! ! return nice; ! } ! ! /* ! * Ensure that a process that is being killed can run. ! * ! */ ! void ! synch_proc_killing(struct proc *p) ! { ! if (p->p_nice > NZERO) ! return donice(0, p, NZERO); } + /* + * Ensure we run fast. + */ + void + synch_proc_runfast(struct proc *p) + { + /* + * Raise kernel priority to at least PUSER. + */ + if (p->p_priority > PUSER) + p->p_priority = PUSER; + } + + /* + * Force a process to run. This is called in vm_pageout_scan when + * it selects a process to kill. Be careful if you change this + * that it works properly for all flavors of processes - donice + * is guaranteed to; the old version didn't. Since curproc better + * be the pager this should work. + * + */ + int + synch_proc_force_runnable(struct proc *p) + { + return donice(0, p, PRIO_MIN); + } + + /* + * Don't swapout a realtime process or one waiting on a critical event + * of some kind. This is used by swapout_procs in deciding what can + * be swapped out. + */ + int + synch_proc_unswappable(struct proc *p) + { + #ifdef NO_RTPRIO + return ((p->p_priority & 0x7f) < PSOCK); + #else + return ( (p->p_rtprio.type == RTP_PRIO_REALTIME) || + ((p->p_priority & 0x7f) < PSOCK) ); + #endif + } + + /* + * Return true for a process waiting at a high kernel priority process. + * This is used in vm_meter for keeping track of statitics of jobs in + * "disk wait". Historically these were the uninterruptible sleeping + * processes. I'm not sure if this has much meaning now. + */ + int + synch_proc_uninterruptible(struct proc *p) + { + return p->p_priority <= PZERO; + } + + /* + * Charge a zombie process to the estimated CPU time for the parent. + * XXX FreeBSD extension - sysctl'ize. + */ + void + synch_zombie_charge(struct proc *p) + { + /* charge child's scheduling cpu usage to parent */ + if (curproc->p_pid != 1) { + curproc->p_estcpu = + min(curproc->p_estcpu + p->p_estcpu, MAX_ESTCPU); + } + } + + /* + * Set up for a fork. + * XXX FreeBSD extension - sysctl'ize. + */ + void + synch_fork(struct proc *parent, struct proc *child) + { + /* + * set priority of child to be that of parent + */ + child->p_estcpu = parent->p_estcpu; + } + + /* + * synch_compare: Decide which of two runnable processes is to be + * preferred. + * + * The runner with the highest cpu utilization is picked (p_estcpu). + * Ties are broken by picking the highest pid. + * + * This is taken from and currently only used in tty.c. + */ + int + synch_compare(struct proc *p1, struct proc *p2) + { + if (p2->p_estcpu > p1->p_estcpu) + return (1); + if (p1->p_estcpu > p2->p_estcpu) + return (0); + return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ + } + + /* + * resched_wanted: Do we want to reschedule. + * + * XXX This was added to get around DOS attacks via huge uiomoves in + * rawio. The only client is kern_subr. + * We shouldn't do this if curproc is rtprio unless we need a reschedule. + */ + + int + resched_wanted(void) + { + return (ticks - switchticks >= hogticks); + } + + int + donice(curp, chgp, n) + register struct proc *curp, *chgp; + register int n; + { + int s; + register struct pcred *pcred; + + if (n > PRIO_MAX) + n = PRIO_MAX; + if (n < PRIO_MIN) + n = PRIO_MIN; + + if (curp) { + pcred = curp->p_cred; + + if (pcred->pc_ucred->cr_uid && pcred->p_ruid && + pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid && + pcred->p_ruid != chgp->p_ucred->cr_uid) + return (EPERM); + + if (n < chgp->p_nice && suser(curp)) + return (EACCES); + + } + + s = splhigh(); + + chgp->p_nice = n; + + /* Be sure that if you're switching schedulers you + * get it off the correct run queue: + */ + + #ifndef NO_RTPRIO + if (!NORMAL_SCHEDULER(chgp) && + (chgp != curproc) && + #ifdef SMP + (u_char)chgp->p_oncpu == 0xff && /* idle */ + #endif + chgp->p_stat == SRUN && + (chgp->p_flag & P_INMEM)) { + remrunqueue(chgp); + chgp->p_rtprio.type = RTP_PRIO_NORMAL; + setrunqueue(chgp); + } else { + chgp->p_rtprio.type = RTP_PRIO_NORMAL; + resetpriority(chgp); + adjust_runqueues(chgp); + } + #else + resetpriority(chgp); + adjust_runqueues(chgp); + #endif + splx(s); + + maybe_resched(chgp); + + return (0); + } + + int + dortprio(struct proc *curp, struct proc *chgp, struct rtprio *rtp) + { + #ifdef NO_RTPRIO + return ENOSYS; + #else + register struct pcred *pcred = curp->p_cred; + + if (pcred->pc_ucred->cr_uid && pcred->p_ruid && + pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid && + pcred->p_ruid != chgp->p_ucred->cr_uid) + return (EPERM); + + /* disallow setting rtprio in most cases if not superuser */ + if (suser(curp)) { + /* can't set someone else's */ + if (curp != chgp) + return (EPERM); + /* + * Realtime priority has to be restricted for reasons which should be + * obvious. However, for idle priority, there is a potential for + * system deadlock if an idleprio process gains a lock on a resource + * that other processes need (and the idleprio process can't run + * due to a CPU-bound normal process). Fix me! XXX + * + * Be careful when the above restriction is removed not to let a + * regular process lower its nice value. + * + */ + #if 0 + if (RTP_PRIO_IS_REALTIME(rtp->type)) + #endif + if (rtp->type != RTP_PRIO_NORMAL) + return (EPERM); + } + + switch (rtp->type) { + #ifdef RTP_PRIO_FIFO + case RTP_PRIO_FIFO: + #endif + case RTP_PRIO_REALTIME: + case RTP_PRIO_NORMAL: + case RTP_PRIO_IDLE: + if (rtp->prio > RTP_PRIO_MAX) + return (EINVAL); + if ((chgp != curproc) && + #ifdef SMP + (u_char)chgp->p_oncpu == 0xff && /* idle */ + #endif + chgp->p_stat == SRUN && + (chgp->p_flag & P_INMEM) && + (chgp->p_rtprio.type != rtp->type || + chgp->p_rtprio.prio != rtp->prio)) { + remrunqueue(chgp); + chgp->p_rtprio = *rtp; + setrunqueue(chgp); + } else + chgp->p_rtprio = *rtp; + maybe_resched(chgp); + return (0); + + default: + return (EINVAL); + } + #endif /* NO_RTPRIO */ + } + + /* + * Define the code needed before returning to user mode, for + * trap and syscall. + * + * XXX Moved to machine independent on FreeBSD. Notes: + * + * For i386: No longer inline. Second arg is now "frame->tf_eip". + * For alpha: mi_switch now "splhigh() instead of "splstatclock()". + * + * Perusing 4.4Lite showed that for multiple architectures this can be + * done MI, perhaps having to pass some methods and a cookie as well. + */ + + void + userret(p, pc, oticks) + struct proc *p; + const register_t pc; + const 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 = splhigh(); + 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. + */ + if (p->p_flag & P_PROFIL) { + addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); + } + + curpriority = prioritize(p); + } + + /* ARGSUSED */ static void sched_setup(dummy) *************** *** 898,901 **** roundrobin(NULL); schedcpu(NULL); } - --- 1435,1437 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_threads.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_threads.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/kern_threads.c Fri Aug 27 20:46:15 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/kern_threads.c Fri Oct 29 17:21:32 1999 *************** *** 53,58 **** --- 53,59 ---- #include #include #include + #include #include #include *************** *** 140,156 **** */ int yield(struct proc *p, struct yield_args *uap) { - int s; - p->p_retval[0] = 0; ! ! s = splhigh(); ! p->p_priority = MAXPRI; ! setrunqueue(p); ! p->p_stats->p_ru.ru_nvcsw++; ! mi_switch(); ! splx(s); ! ! return(0); } - --- 141,146 ---- */ int yield(struct proc *p, struct yield_args *uap) { p->p_retval[0] = 0; ! return synch_yield(p, 1); } diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/subr_prof.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/subr_prof.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/subr_prof.c Mon Oct 11 22:54:23 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/subr_prof.c Fri Oct 29 17:21:32 1999 *************** *** 382,387 **** --- 382,391 ---- * Scale is a fixed-point number with the binary point 16 bits * into the value, and is <= 1.0. pc is at most 32 bits, so the * intermediate result is at most 48 bits. + * + * XXX the above is not true. pc is u_long and is 64 bits on the alpha. + * Now that it is "register_t" and is obviously not true. + * */ #define PC_TO_INDEX(pc, prof) \ ((int)(((u_quad_t)((pc) - (prof)->pr_off) * \ *************** *** 403,409 **** void addupc_intr(p, pc, ticks) register struct proc *p; ! register u_long pc; u_int ticks; { register struct uprof *prof; --- 407,413 ---- void addupc_intr(p, pc, ticks) register struct proc *p; ! register register_t pc; u_int ticks; { register struct uprof *prof; *************** *** 433,439 **** void addupc_task(p, pc, ticks) register struct proc *p; ! register u_long pc; u_int ticks; { register struct uprof *prof; --- 437,443 ---- void addupc_task(p, pc, ticks) register struct proc *p; ! register register_t pc; u_int ticks; { register struct uprof *prof; diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/sys_generic.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/sys_generic.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/sys_generic.c Thu Oct 14 06:50:06 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/sys_generic.c Fri Oct 29 17:21:32 1999 *************** *** 49,54 **** --- 49,55 ---- #include #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/sys_process.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/sys_process.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/sys_process.c Mon Oct 11 11:19:11 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/sys_process.c Fri Oct 29 17:21:32 1999 *************** *** 35,40 **** --- 35,41 ---- #include #include #include + #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/tty.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/tty.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/tty.c Wed Sep 29 11:03:42 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/tty.c Fri Oct 29 17:21:32 1999 *************** *** 78,83 **** --- 78,84 ---- #include #endif #include + #include #define TTYDEFCHARS #include #undef TTYDEFCHARS *************** *** 2269,2277 **** * The algorithm for picking the "interesting" process is thus: * * 1) Only foreground processes are eligible - implied. ! * 2) Runnable processes are favored over anything else. The runner ! * with the highest cpu utilization is picked (p_estcpu). Ties are ! * broken by picking the highest pid. * 3) The sleeper with the shortest sleep time is next. With ties, * we pick out just "short-term" sleepers (P_SINTR == 0). * 4) Further ties are broken by picking the highest pid. --- 2270,2277 ---- * The algorithm for picking the "interesting" process is thus: * * 1) Only foreground processes are eligible - implied. ! * 2) Runnable processes are favored over anything else. We defer to ! * "synch_compare" to decide how to choose between two runners. * 3) The sleeper with the shortest sleep time is next. With ties, * we pick out just "short-term" sleepers (P_SINTR == 0). * 4) Further ties are broken by picking the highest pid. *************** *** 2298,2311 **** case ONLYB: return (1); case BOTH: ! /* ! * tie - favor one with highest recent cpu utilization ! */ ! if (p2->p_estcpu > p1->p_estcpu) ! return (1); ! if (p1->p_estcpu > p2->p_estcpu) ! return (0); ! return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ } /* * weed out zombies --- 2298,2304 ---- case ONLYB: return (1); case BOTH: ! return synch_compare(p1, p2); } /* * weed out zombies diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/uipc_socket2.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/uipc_socket2.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/uipc_socket2.c Sat Oct 9 16:42:10 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/uipc_socket2.c Fri Oct 29 17:21:32 1999 *************** *** 41,46 **** --- 41,47 ---- #include /* for maxfiles */ #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/uipc_syscalls.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/uipc_syscalls.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/uipc_syscalls.c Thu Oct 14 01:16:16 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/uipc_syscalls.c Fri Oct 29 17:21:32 1999 *************** *** 47,52 **** --- 47,53 ---- #include #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/vfs_subr.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/vfs_subr.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/kern/vfs_subr.c Mon Oct 11 11:19:12 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/kern/vfs_subr.c Fri Oct 29 17:21:32 1999 *************** *** 49,54 **** --- 49,55 ---- #include #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/miscfs/procfs/procfs_ctl.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/miscfs/procfs/procfs_ctl.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/miscfs/procfs/procfs_ctl.c Wed Sep 29 11:03:46 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/miscfs/procfs/procfs_ctl.c Fri Oct 29 17:21:32 1999 *************** *** 43,48 **** --- 43,49 ---- #include #include #include + #include #include #include #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/ksched.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/ksched.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/ksched.c Tue May 19 17:11:52 1998 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/ksched.c Fri Oct 29 17:16:06 1999 *************** *** 37,45 **** #include #include #include #include #include - #include /* For need_resched */ #include --- 37,45 ---- #include #include #include + #include #include #include #include *************** *** 50,103 **** struct timespec rr_interval; }; ! int ksched_attach(struct ksched **p) { struct ksched *ksched= p31b_malloc(sizeof(*ksched)); ksched->rr_interval.tv_sec = 0; ksched->rr_interval.tv_nsec = 1000000000L / roundrobin_interval(); ! *p = ksched; return 0; } ! int ksched_detach(struct ksched *p) { ! p31b_free(p); return 0; } /* ! * XXX About priorities * * POSIX 1003.1b requires that numerically higher priorities be of * higher priority. It also permits sched_setparam to be ! * implementation defined for SCHED_OTHER. I don't like ! * the notion of inverted priorites for normal processes when ! * you can use "setpriority" for that. ! * ! * I'm rejecting sched_setparam for SCHED_OTHER with EINVAL. */ ! /* Macros to convert between the unix (lower numerically is higher priority) * and POSIX 1003.1b (higher numerically is higher priority) */ ! #define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P)) ! #define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P)) ! /* These improve readability a bit for me: */ ! #define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX) ! #define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN) static __inline int ! getscheduler(int *ret, struct ksched *ksched, struct proc *p) { int e = 0; ! switch (p->p_rtprio.type) { case RTP_PRIO_FIFO: *ret = SCHED_FIFO; --- 50,110 ---- struct timespec rr_interval; }; ! int ksched_attach(struct ksched **kp) { struct ksched *ksched= p31b_malloc(sizeof(*ksched)); ksched->rr_interval.tv_sec = 0; ksched->rr_interval.tv_nsec = 1000000000L / roundrobin_interval(); ! *kp = ksched; return 0; } ! int ksched_detach(struct ksched *kp) { ! p31b_free(kp); return 0; } /* ! * About priorities: * * POSIX 1003.1b requires that numerically higher priorities be of * higher priority. It also permits sched_setparam to be ! * implementation defined for SCHED_OTHER. We'll use ! * the normal "setpriority()" priorities and treat a ! * call for setting the scheduler similar to setpriority(). ! * They still need to be reflected to make higher priorities higher. */ ! /* Macros to convert between the RTP_PRIO (lower numerically is higher priority) * and POSIX 1003.1b (higher numerically is higher priority) */ ! #define p4prio_to_rtprio(P) (RTP_PRIO_MAX - (P)) ! #define rtprio_to_p4prio(P) (RTP_PRIO_MAX - (P)) ! ! #define P1B_PRIO_MIN rtprio_to_p4prio(RTP_PRIO_MAX) ! #define P1B_PRIO_MAX rtprio_to_p4prio(RTP_PRIO_MIN) ! /* Similar macros for the BSD flavor p_nice priorities: */ ! #define p4prio_to_p_nice(P) (-(P + PRIO_MIN)) ! #define p_nice_to_p4prio(P) (-(P - PRIO_MAX)) ! ! #define P_NICE_PRIO_MIN p_nice_to_p4prio(PRIO_MAX) ! #define P_NICE_PRIO_MAX p_nice_to_p4prio(PRIO_MIN) static __inline int ! getscheduler(int *ret, struct ksched *ksched, struct proc *curp, struct proc *chgp) { + struct rtprio rtp; int e = 0; + (void)synch_proc_priority(chgp, &rtp); ! switch (rtp.type) { case RTP_PRIO_FIFO: *ret = SCHED_FIFO; *************** *** 107,143 **** *ret = SCHED_RR; break; ! default: *ret = SCHED_OTHER; break; } return e; } int ksched_setparam(int *ret, struct ksched *ksched, ! struct proc *p, const struct sched_param *param) { int e, policy; ! e = getscheduler(&policy, ksched, p); if (e == 0) ! { ! if (policy == SCHED_OTHER) ! e = EINVAL; ! else ! e = ksched_setscheduler(ret, ksched, p, policy, param); ! } return e; } int ksched_getparam(int *ret, struct ksched *ksched, ! struct proc *p, struct sched_param *param) { ! if (RTP_PRIO_IS_REALTIME(p->p_rtprio.type)) ! param->sched_priority = rtpprio_to_p4prio(p->p_rtprio.prio); return 0; } --- 114,172 ---- *ret = SCHED_RR; break; ! case RTP_PRIO_NORMAL: *ret = SCHED_OTHER; break; + + case RTP_PRIO_IDLE: + *ret = SCHED_IDLE; + break; + + default: + e = ESRCH; + break; } return e; } int ksched_setparam(int *ret, struct ksched *ksched, ! struct proc *curp, struct proc *chgp, const struct sched_param *param) { int e, policy; ! e = getscheduler(&policy, ksched, curp, chgp); if (e == 0) ! e = ksched_setscheduler(ret, ksched, ! curp, chgp, policy, param); return e; } int ksched_getparam(int *ret, struct ksched *ksched, ! struct proc *curp, struct proc *chgp, struct sched_param *param) { ! struct rtprio rtp; ! int e = 0; ! int nice = synch_proc_priority(chgp, &rtp); ! ! switch (rtp.type) ! { ! case RTP_PRIO_FIFO: ! case RTP_PRIO_REALTIME: ! case RTP_PRIO_IDLE: ! param->sched_priority = rtprio_to_p4prio(rtp.prio); ! break; ! ! case RTP_PRIO_NORMAL: ! param->sched_priority = p_nice_to_p4prio(nice); ! break; ! ! default: ! e = EFAULT; ! break; ! } return 0; } *************** *** 146,156 **** * XXX The priority and scheduler modifications should * be moved into published interfaces in kern/kern_sync. * ! * The permissions to modify process p were checked in "p31b_proc()". * */ int ksched_setscheduler(int *ret, struct ksched *ksched, ! struct proc *p, int policy, const struct sched_param *param) { int e = 0; struct rtprio rtp; --- 175,186 ---- * XXX The priority and scheduler modifications should * be moved into published interfaces in kern/kern_sync. * ! * The permissions to modify process chgp were checked in "p31b_proc()". * */ int ksched_setscheduler(int *ret, struct ksched *ksched, ! struct proc *curp, struct proc *chgp, ! int policy, const struct sched_param *param) { int e = 0; struct rtprio rtp; *************** *** 159,212 **** { case SCHED_RR: case SCHED_FIFO: if (param->sched_priority >= P1B_PRIO_MIN && param->sched_priority <= P1B_PRIO_MAX) { ! rtp.prio = p4prio_to_rtpprio(param->sched_priority); ! rtp.type = (policy == SCHED_FIFO) ! ? RTP_PRIO_FIFO : RTP_PRIO_REALTIME; - p->p_rtprio = rtp; - need_resched(); } else e = EPERM; - - break; case SCHED_OTHER: { ! rtp.type = RTP_PRIO_NORMAL; ! rtp.prio = p4prio_to_rtpprio(param->sched_priority); ! p->p_rtprio = rtp; ! ! /* XXX Simply revert to whatever we had for last ! * normal scheduler priorities. ! * This puts a requirement ! * on the scheduling code: You must leave the ! * scheduling info alone. ! */ ! need_resched(); } break; } return e; } ! int ksched_getscheduler(int *ret, struct ksched *ksched, struct proc *p) { ! return getscheduler(ret, ksched, p); } /* ksched_yield: Yield the CPU. */ int ksched_yield(int *ret, struct ksched *ksched) { ! need_resched(); ! return 0; } int ksched_get_priority_max(int *ret, struct ksched *ksched, int policy) --- 189,251 ---- { case SCHED_RR: case SCHED_FIFO: + case SCHED_IDLE: if (param->sched_priority >= P1B_PRIO_MIN && param->sched_priority <= P1B_PRIO_MAX) { ! rtp.prio = p4prio_to_rtprio(param->sched_priority); ! ! if (policy == SCHED_RR) ! rtp.type = RTP_PRIO_REALTIME; ! else if (policy == SCHED_FIFO) ! rtp.type = RTP_PRIO_FIFO; ! else ! rtp.type = RTP_PRIO_IDLE; ! ! return dortprio(curp, chgp, &rtp); } else e = EPERM; break; + /* XXX One thing I really don't like about this + * implementation is you'll have to provide a + * nice value to revert to. Either the process + * will have to do a "getparam" at the start and save it, + * (should always work), + * or we'll have to add some magic value (say PRIO_MAX + 1) + * that means "don't touch my nice value", and we'll + * have to include that as a valid priority in the + * "get_priority_min" call. + */ case SCHED_OTHER: + if (param->sched_priority >= P_NICE_PRIO_MIN && + param->sched_priority <= P_NICE_PRIO_MAX) { ! return donice(curp, chgp, ! p4prio_to_p_nice(param->sched_priority)); } + else + e = EPERM; break; } return e; } ! int ksched_getscheduler(int *ret, struct ksched *ksched, ! struct proc *curp, struct proc *chgp) { ! return getscheduler(ret, ksched, curp, chgp); } /* ksched_yield: Yield the CPU. */ int ksched_yield(int *ret, struct ksched *ksched) { ! return synch_yield(curproc, 0); } int ksched_get_priority_max(int *ret, struct ksched *ksched, int policy) *************** *** 217,227 **** { case SCHED_FIFO: case SCHED_RR: ! *ret = RTP_PRIO_MAX; break; case SCHED_OTHER: ! *ret = PRIO_MAX; break; default: --- 256,267 ---- { case SCHED_FIFO: case SCHED_RR: ! case SCHED_IDLE: ! *ret = P1B_PRIO_MAX; break; case SCHED_OTHER: ! *ret = P_NICE_PRIO_MAX; break; default: *************** *** 239,249 **** { case SCHED_FIFO: case SCHED_RR: *ret = P1B_PRIO_MIN; break; case SCHED_OTHER: ! *ret = PRIO_MIN; break; default: --- 279,290 ---- { case SCHED_FIFO: case SCHED_RR: + case SCHED_IDLE: *ret = P1B_PRIO_MIN; break; case SCHED_OTHER: ! *ret = P_NICE_PRIO_MIN; break; default: *************** *** 254,260 **** } int ksched_rr_get_interval(int *ret, struct ksched *ksched, ! struct proc *p, struct timespec *timespec) { *timespec = ksched->rr_interval; --- 295,301 ---- } int ksched_rr_get_interval(int *ret, struct ksched *ksched, ! struct proc *curp, struct proc *chgp, struct timespec *timespec) { *timespec = ksched->rr_interval; diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/ksem.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/ksem.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/ksem.c Sat Oct 30 03:37:12 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/ksem.c Mon Nov 1 09:57:40 1999 *************** *** 0 **** --- 1,118 ---- + /* + * Copyright (c) 1999 HD Associates, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/kern/kern_switch.c,v 1.3 1999/08/19 16:06:08 peter Exp $ + */ + + #include + + struct ksem { + int foo; + }; + + int ksem_attach(struct ksem **kp) + { + struct ksem *ksem= p31b_malloc(sizeof(*ksem)); + *kp = ksem; + return 0; + } + + int ksem_detach(struct ksem *kp) + { + p31b_free(kp); + + return 0; + } + + int ksem_init(int *ret, struct ksem *ksem, + sem_t *sem, int pshared, unsigned int value) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_destroy(int *ret, struct ksem *ksem, + sem_t *sem) + { + *ret = -1; + return ENOSYS; + } + + sem_t + ksem_open(int *ret, struct ksem *ksem, + const char *name, int oflag, ...) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_close(int *ret, struct ksem *ksem, + sem_t *sem) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_unlink(int *ret, struct ksem *ksem, + const char *name) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_wait(int *ret, struct ksem *ksem, + sem_t *sem) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_trywait(int *ret, struct ksem *ksem, + sem_t *sem) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_post(int *ret, struct ksem *ksem, + sem_t *sem) + { + *ret = -1; + return ENOSYS; + } + + int + ksem_getvalue(int *ret, struct ksem *ksem, + sem_t *sem, int *sval) + { + *ret = -1; + return ENOSYS; + } diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/p1003_1b.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/p1003_1b.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/p1003_1b.c Sat Apr 17 04:36:05 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/p1003_1b.c Fri Oct 29 17:16:06 1999 *************** *** 63,93 **** #if 0 /* ! * This is stolen from CANSIGNAL in kern_sig: * ! * Can process p, with pcred pc, do "write flavor" operations to process q? */ ! #define CAN_AFFECT(p, pc, q) \ ((pc)->pc_ucred->cr_uid == 0 || \ (pc)->p_ruid == (q)->p_cred->p_ruid || \ (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \ (pc)->p_ruid == (q)->p_ucred->cr_uid || \ (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid) #else ! #define CAN_AFFECT(p, pc, q) ((pc)->pc_ucred->cr_uid == 0) #endif /* * p31b_proc: Look up a proc from a PID. If proc is 0 it is * my own proc. */ ! int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) { int ret = 0; struct proc *other_proc = 0; if (pid == 0) ! other_proc = p; else other_proc = pfind(pid); --- 63,100 ---- #if 0 /* ! * This is from CANSIGNAL in kern_sig: * ! * Can process CURP, with pcred pc, do "write flavor" operations to process q? */ ! #define CAN_AFFECT(rw, CURP, pc, q) \ ((pc)->pc_ucred->cr_uid == 0 || \ (pc)->p_ruid == (q)->p_cred->p_ruid || \ (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \ (pc)->p_ruid == (q)->p_ucred->cr_uid || \ (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid) #else ! #define CAN_AFFECT(rw, CURP, pc, q) ((rw == 0) || ((pc)->pc_ucred->cr_uid == 0)) #endif /* * p31b_proc: Look up a proc from a PID. If proc is 0 it is * my own proc. + * + * If perms[ind] is zero this is "read" flavor; + * if perms[ind] is one this is "write" flavor. + * + * The current policy is only root can write, anyone can read. + * */ ! int p31b_proc(const int *perms, int ind, ! struct proc *curp, pid_t pid, struct proc **pp) { int ret = 0; struct proc *other_proc = 0; if (pid == 0) ! other_proc = curp; else other_proc = pfind(pid); *************** *** 95,101 **** { /* Enforce permission policy. */ ! if (CAN_AFFECT(p, p->p_cred, other_proc)) *pp = other_proc; else ret = EPERM; --- 102,108 ---- { /* Enforce permission policy. */ ! if (CAN_AFFECT(perms[ind], curp, curp->p_cred, other_proc)) *pp = other_proc; else ret = EPERM; *************** *** 111,122 **** * start to use this when they shouldn't. That will be removed if annoying. */ int ! syscall_not_present(struct proc *p, const char *s, struct nosys_args *uap) { log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n", ! p->p_comm, p->p_pid, s); ! /* a " return nosys(p, uap); " here causes a core dump. */ return ENOSYS; --- 118,129 ---- * start to use this when they shouldn't. That will be removed if annoying. */ int ! syscall_not_present(struct proc *curp, const char *s, struct nosys_args *uap) { log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n", ! curp->p_comm, curp->p_pid, s); ! /* a " return nosys(curp, uap); " here causes a core dump. */ return ENOSYS; *************** *** 143,148 **** --- 150,159 ---- #else + /* Permissions + */ + static const int ksched_op_rw[] = KSCHED_OP_RW; + /* Configured in kernel version: */ static struct ksched *ksched; *************** *** 157,188 **** return ret; } ! int sched_setparam(struct proc *p, struct sched_setparam_args *uap) { int e; struct sched_param sched_param; copyin(uap->param, &sched_param, sizeof(sched_param)); (void) (0 ! || (e = p31b_proc(p, uap->pid, &p)) ! || (e = ksched_setparam(&p->p_retval[0], ksched, p, (const struct sched_param *)&sched_param)) ); return e; } ! int sched_getparam(struct proc *p, struct sched_getparam_args *uap) { int e; struct sched_param sched_param; (void) (0 ! || (e = p31b_proc(p, uap->pid, &p)) ! || (e = ksched_getparam(&p->p_retval[0], ksched, p, &sched_param)) ); if (!e) --- 168,204 ---- return ret; } ! int sched_setparam(struct proc *curp, struct sched_setparam_args *uap) { int e; + struct proc *other; struct sched_param sched_param; copyin(uap->param, &sched_param, sizeof(sched_param)); (void) (0 ! || (e = p31b_proc(ksched_op_rw, ! (int)SCHED_SETPARAM, curp, uap->pid, &other)) ! || (e = ksched_setparam(&curp->p_retval[0], ksched, curp, other, (const struct sched_param *)&sched_param)) ); return e; } ! int sched_getparam(struct proc *curp, struct sched_getparam_args *uap) { int e; + struct proc *other; struct sched_param sched_param; (void) (0 ! || (e = p31b_proc(ksched_op_rw, ! (int)SCHED_GETPARAM, curp, uap->pid, &other)) ! || (e = ksched_getparam(&curp->p_retval[0], ksched, ! curp, other, &sched_param)) ); if (!e) *************** *** 190,252 **** return e; } ! int sched_setscheduler(struct proc *p, struct sched_setscheduler_args *uap) { int e; struct sched_param sched_param; copyin(uap->param, &sched_param, sizeof(sched_param)); (void) (0 ! || (e = p31b_proc(p, uap->pid, &p)) ! || (e = ksched_setscheduler(&p->p_retval[0], ! ksched, p, uap->policy, (const struct sched_param *)&sched_param)) ); return e; } ! int sched_getscheduler(struct proc *p, struct sched_getscheduler_args *uap) { int e; (void) (0 ! || (e = p31b_proc(p, uap->pid, &p)) ! || (e = ksched_getscheduler(&p->p_retval[0], ksched, p)) ); return e; } ! int sched_yield(struct proc *p, struct sched_yield_args *uap) { ! return ksched_yield(&p->p_retval[0], ksched); } ! int sched_get_priority_max(struct proc *p, struct sched_get_priority_max_args *uap) { ! return ksched_get_priority_max(&p->p_retval[0], ksched, uap->policy); } ! int sched_get_priority_min(struct proc *p, struct sched_get_priority_min_args *uap) { ! return ksched_get_priority_min(&p->p_retval[0], ksched, uap->policy); - } - int sched_rr_get_interval(struct proc *p, - struct sched_rr_get_interval_args *uap) - { - int e; - - (void) (0 - || (e = p31b_proc(p, uap->pid, &p)) - || (e = ksched_rr_get_interval(&p->p_retval[0], ksched, - p, uap->interval)) - ); - - return e; } #endif --- 206,280 ---- return e; } ! int sched_setscheduler(struct proc *curp, struct sched_setscheduler_args *uap) { int e; + struct proc *other; struct sched_param sched_param; copyin(uap->param, &sched_param, sizeof(sched_param)); (void) (0 ! || (e = p31b_proc(ksched_op_rw, ! (int)SCHED_SETSCHEDULER, curp, uap->pid, &other)) ! || (e = ksched_setscheduler(&curp->p_retval[0], ! ksched, curp, other, uap->policy, (const struct sched_param *)&sched_param)) ); return e; } ! int sched_getscheduler(struct proc *curp, struct sched_getscheduler_args *uap) { int e; + struct proc *other; + (void) (0 + || (e = p31b_proc(ksched_op_rw, + (int)SCHED_GETSCHEDULER, curp, uap->pid, &other)) + || (e = ksched_getscheduler(&curp->p_retval[0], ksched, curp, other)) + ); + + return e; + } + + int sched_rr_get_interval(struct proc *curp, + struct sched_rr_get_interval_args *uap) + { + int e; + struct proc *other; + (void) (0 ! || (e = p31b_proc(ksched_op_rw, ! (int)SCHED_RR_GET_INTERVAL, curp, uap->pid, &other)) ! || (e = ksched_rr_get_interval(&curp->p_retval[0], ksched, ! curp, other, uap->interval)) ); return e; } ! ! /* XXX These should still check some permissions. ! */ ! int sched_yield(struct proc *curp, struct sched_yield_args *uap) { ! return ksched_yield(&curp->p_retval[0], ksched); } ! ! int sched_get_priority_max(struct proc *curp, struct sched_get_priority_max_args *uap) { ! return ksched_get_priority_max(&curp->p_retval[0], ksched, uap->policy); } ! ! int sched_get_priority_min(struct proc *curp, struct sched_get_priority_min_args *uap) { ! return ksched_get_priority_min(&curp->p_retval[0], ksched, uap->policy); } #endif diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/posix4.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/posix4.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/posix4.h Sat Apr 17 04:36:05 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/posix4.h Fri Oct 29 17:16:06 1999 *************** *** 60,66 **** #define p31b_malloc(SIZE) malloc((SIZE), M_P31B, M_WAITOK) #define p31b_free(P) free((P), M_P31B) ! int p31b_proc __P((struct proc *, pid_t, struct proc **)); void p31b_setcfg __P((int, int)); --- 60,66 ---- #define p31b_malloc(SIZE) malloc((SIZE), M_P31B, M_WAITOK) #define p31b_free(P) free((P), M_P31B) ! int p31b_proc __P((const int *, int, struct proc *, pid_t, struct proc **)); void p31b_setcfg __P((int, int)); *************** *** 94,113 **** int ksched_detach(struct ksched *); int ksched_setparam(int *, struct ksched *, ! struct proc *, const struct sched_param *); int ksched_getparam(int *, struct ksched *, ! struct proc *, struct sched_param *); int ksched_setscheduler(int *, struct ksched *, ! struct proc *, int, const struct sched_param *); ! int ksched_getscheduler(int *, struct ksched *, struct proc *); int ksched_yield(int *, struct ksched *); int ksched_get_priority_max(int *, struct ksched *, int); int ksched_get_priority_min(int *, struct ksched *, int); ! int ksched_rr_get_interval(int *, struct ksched *, struct proc *, struct timespec *); #endif /* _KPOSIX_PRIORITY_SCHEDULING */ --- 94,113 ---- int ksched_detach(struct ksched *); int ksched_setparam(int *, struct ksched *, ! struct proc *, struct proc *, const struct sched_param *); int ksched_getparam(int *, struct ksched *, ! struct proc *, struct proc *, struct sched_param *); int ksched_setscheduler(int *, struct ksched *, ! struct proc *, struct proc *, int, const struct sched_param *); ! int ksched_getscheduler(int *, struct ksched *, struct proc *, struct proc *); int ksched_yield(int *, struct ksched *); int ksched_get_priority_max(int *, struct ksched *, int); int ksched_get_priority_min(int *, struct ksched *, int); ! int ksched_rr_get_interval(int *, struct ksched *, struct proc *, struct proc *, struct timespec *); #endif /* _KPOSIX_PRIORITY_SCHEDULING */ diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/sched.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/sched.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/posix4/sched.h Tue May 12 01:11:51 1998 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/posix4/sched.h Fri Oct 29 17:16:06 1999 *************** *** 49,54 **** --- 49,61 ---- #define SCHED_OTHER 2 #define SCHED_RR 3 + #if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) + + /* BSD idprio */ + #define SCHED_IDLE 4 + + #endif + struct sched_param { int sched_priority; diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/_posix.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/_posix.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/_posix.h Fri Aug 27 20:51:32 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/_posix.h Fri Oct 29 17:16:06 1999 *************** *** 51,60 **** * XXX Complain if you think this dumb. */ ! /* Make P1003 structures visible for the kernel if ! * the P1003_1B option is in effect. */ ! #ifdef P1003_1B #define _P1003_1B_VISIBLE #ifndef _KPOSIX_VERSION #define _KPOSIX_VERSION 199309L --- 51,76 ---- * XXX Complain if you think this dumb. */ ! /* Make P1003 structures visible for the kernel unless ! * the NO_P1003_1B option is in effect. */ ! #ifndef NO_P1003_1B ! ! /* Turn on standard features that are always present if P1003_1B ! * is enabled here. The nested ifndef are for a grace period for old ! * kernel options. ! */ ! ! #ifndef P1003_1B ! #define P1003_1B ! #endif ! ! #ifndef NO_KPOSIX_PRIORITY_SCHEDULING ! #ifndef _KPOSIX_PRIORITY_SCHEDULING ! #define _KPOSIX_PRIORITY_SCHEDULING ! #endif ! #endif ! #define _P1003_1B_VISIBLE #ifndef _KPOSIX_VERSION #define _KPOSIX_VERSION 199309L diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/proc.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/proc.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/proc.h Mon Oct 11 16:33:16 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/proc.h Sat Oct 30 11:32:34 1999 *************** *** 42,47 **** --- 42,65 ---- #ifndef _SYS_PROC_H_ #define _SYS_PROC_H_ + #ifdef KERNEL + /* + * XXX Temporary hack to be sure all scheduling members are accessed properly + * Remove "opt_sched.h" along with the "friend" stuff when taking out. + */ + #include "opt_sched.h" + #ifdef SCHEDULER_FRIEND + #define p_sched_estcpu p_estcpu + #define p_sched_priority p_priority + #define p_sched_usrpri p_usrpri + #define p_sched_nice p_nice + #ifndef NO_RTPRIO + #define p_sched_rtprio p_rtprio + #endif /* !NO_RTPRIO */ + #endif /* SCHEDULER_FRIEND */ + #endif + + #include /* Machine-dependent proc substruct. */ #include /* For struct callout_handle. */ #include *************** *** 153,159 **** struct vmspace *p_vmspace; /* Address space. */ /* scheduling */ ! u_int p_estcpu; /* Time averaged value of p_cpticks. */ int p_cpticks; /* Ticks of cpu time. */ fixpt_t p_pctcpu; /* %cpu for this process during p_swtime */ void *p_wchan; /* Sleep address. */ --- 171,177 ---- struct vmspace *p_vmspace; /* Address space. */ /* scheduling */ ! u_int p_sched_estcpu; /* Time averaged value of p_cpticks. */ int p_cpticks; /* Ticks of cpu time. */ fixpt_t p_pctcpu; /* %cpu for this process during p_swtime */ void *p_wchan; /* Sleep address. */ *************** *** 201,216 **** sigset_t p_sigmask; /* Current signal mask. */ stack_t p_sigstk; /* sp & on stack state variable */ ! u_char p_priority; /* Process priority. */ ! u_char p_usrpri; /* User-priority based on p_cpu and p_nice. */ ! char p_nice; /* Process "nice" value. */ char p_comm[MAXCOMLEN+1]; struct pgrp *p_pgrp; /* Pointer to process group. */ struct sysentvec *p_sysent; /* System call dispatch information. */ ! struct rtprio p_rtprio; /* Realtime priority. */ struct prison *p_prison; /* End area that is copied on creation. */ #define p_endcopy p_addr --- 219,234 ---- sigset_t p_sigmask; /* Current signal mask. */ stack_t p_sigstk; /* sp & on stack state variable */ ! u_char p_sched_priority; /* Process priority. */ ! u_char p_sched_usrpri; /* User-priority based on p_cpu and p_nice. */ ! char p_sched_nice; /* Process "nice" value. */ char p_comm[MAXCOMLEN+1]; struct pgrp *p_pgrp; /* Pointer to process group. */ struct sysentvec *p_sysent; /* System call dispatch information. */ ! struct rtprio p_sched_rtprio; /* Realtime priority. */ struct prison *p_prison; /* End area that is copied on creation. */ #define p_endcopy p_addr *************** *** 352,358 **** extern struct timeval switchtime; /* Uptime at last context switch */ #endif extern struct proc proc0; /* Process slot for swapper. */ - extern int hogticks; /* Limit on kernel cpu hogs. */ extern int nprocs, maxproc; /* Current and max number of procs. */ extern int maxprocperuid; /* Max procs per uid. */ extern int sched_quantum; /* Scheduling quantum in ticks */ --- 370,375 ---- *************** *** 362,376 **** extern struct proclist zombproc; /* List of zombie processes. */ extern struct proc *initproc, *pageproc, *updateproc; /* Process slots for init, pager. */ - #define NQS 32 /* 32 run queues. */ - TAILQ_HEAD(rq, proc); - extern struct rq queues[]; - extern struct rq rtqueues[]; - extern struct rq idqueues[]; - extern int whichqs; /* Bit mask summary of non-empty Q's. */ - extern int whichrtqs; /* Bit mask summary of non-empty Q's. */ - extern int whichidqs; /* Bit mask summary of non-empty Q's. */ - struct proc *pfind __P((pid_t)); /* Find process by id. */ struct pgrp *pgfind __P((pid_t)); /* Find process group by id. */ --- 379,384 ---- *************** *** 383,401 **** void fixjobc __P((struct proc *p, struct pgrp *pgrp, int entering)); int inferior __P((struct proc *p)); int leavepgrp __P((struct proc *p)); ! void mi_switch __P((void)); void procinit __P((void)); - void resetpriority __P((struct proc *)); - int roundrobin_interval __P((void)); - void setrunnable __P((struct proc *)); - void setrunqueue __P((struct proc *)); - void sleepinit __P((void)); int suser __P((struct proc *)); int suser_xxx __P((struct ucred *cred, struct proc *proc, int flag)); - void remrunqueue __P((struct proc *)); - void cpu_switch __P((struct proc *)); - void unsleep __P((struct proc *)); - void wakeup_one __P((void *chan)); void cpu_exit __P((struct proc *)) __dead2; void exit1 __P((struct proc *, int)) __dead2; --- 391,400 ---- void fixjobc __P((struct proc *p, struct pgrp *pgrp, int entering)); int inferior __P((struct proc *p)); int leavepgrp __P((struct proc *p)); ! void procinit __P((void)); int suser __P((struct proc *)); int suser_xxx __P((struct ucred *cred, struct proc *proc, int flag)); void cpu_exit __P((struct proc *)) __dead2; void exit1 __P((struct proc *, int)) __dead2; *************** *** 407,415 **** int cpu_coredump __P((struct proc *, struct vnode *, struct ucred *)); void setsugid __P((struct proc *p)); void faultin __P((struct proc *p)); - - struct proc * chooseproc __P((void)); - u_int32_t procrunnable __P((void)); #endif /* KERNEL */ --- 406,411 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/resource.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/resource.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/resource.h Sat Oct 9 16:42:17 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/resource.h Fri Oct 29 17:21:32 1999 *************** *** 131,136 **** --- 131,138 ---- #ifdef KERNEL extern struct loadavg averunnable; + struct rtprio; + struct proc; #else #include diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/resourcevar.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/resourcevar.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/resourcevar.h Fri Aug 27 20:51:58 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/resourcevar.h Fri Oct 29 17:21:32 1999 *************** *** 86,93 **** #ifdef KERNEL struct proc; ! void addupc_intr __P((struct proc *p, u_long pc, u_int ticks)); ! void addupc_task __P((struct proc *p, u_long pc, u_int ticks)); void calcru __P((struct proc *p, struct timeval *up, struct timeval *sp, struct timeval *ip)); int fuswintr __P((void *base)); --- 86,93 ---- #ifdef KERNEL struct proc; ! void addupc_intr __P((struct proc *p, register_t pc, u_int ticks)); ! void addupc_task __P((struct proc *p, register_t pc, u_int ticks)); void calcru __P((struct proc *p, struct timeval *up, struct timeval *sp, struct timeval *ip)); int fuswintr __P((void *base)); diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/synch.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/synch.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/synch.h Fri Oct 29 17:21:32 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/synch.h Mon Nov 1 14:45:48 1999 *************** *** 0 **** --- 1,86 ---- + /* + * Copyright (c) 1999 HD Associates, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/kern/kern_switch.c,v 1.3 1999/08/19 16:06:08 peter Exp $ + */ + #ifndef _SYS_SYNCH_H_ + #define _SYS_SYNCH_H_ + #ifdef KERNEL + + #include + #include + #include + + struct proc; + struct rtprio; + + #define NQS 32 /* 32 run queues. */ + TAILQ_HEAD(rq, proc); + + /* kern_synch */ + + int donice __P((struct proc *, struct proc *, int)); + int dortprio __P((struct proc *, struct proc *, struct rtprio *)); + void mi_switch __P((void)); + int resched_wanted __P((void)); + int roundrobin_interval __P((void)); + void setrunnable __P((struct proc *)); + void sleepinit __P((void)); + int synch_compare __P((struct proc *, struct proc *)); + void synch_fork __P((struct proc *, struct proc *)); + void synch_proc0_init __P((struct proc *)); + int synch_proc_force_runnable __P((struct proc *)); + int synch_proc_isnice __P((struct proc *)); + void synch_proc_killing __P((struct proc *)); + int synch_proc_priority __P((struct proc *, struct rtprio *)); + void synch_proc_runfast __P((struct proc *)); + int synch_proc_uninterruptible __P((struct proc *)); + int synch_proc_unswappable __P((struct proc *)); + int synch_yield __P((struct proc *, const int)); + void synch_zombie_charge __P((struct proc *)); + void unsleep __P((struct proc *)); + void update_estcpu __P((struct proc *)); + void userret __P((struct proc *, const register_t, const u_quad_t)); + void wakeup __P((void *)); + void wakeup_one __P((void *)); + + /* kern_switch */ + + /* XXX can't these be static now */ + + extern struct rq queues[]; + extern struct rq rtqueues[]; + extern struct rq idqueues[]; + extern int whichqs; /* Bit mask summary of non-empty Q's. */ + extern int whichrtqs; /* Bit mask summary of non-empty Q's. */ + extern int whichidqs; /* Bit mask summary of non-empty Q's. */ + + u_int32_t procrunnable __P((void)); + void remrunqueue __P((struct proc *)); + void setrunqueue __P((struct proc *)); + struct proc * chooseproc __P((void)); + + #endif /* KERNEL */ + #endif /* !_SYS_SYNCH_H_ */ diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/systm.h /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/systm.h *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/sys/systm.h Sun Sep 26 14:19:49 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/sys/systm.h Fri Oct 29 17:21:33 1999 *************** *** 58,65 **** extern int selwait; /* select timeout address */ - extern u_char curpriority; /* priority of current process */ - extern int physmem; /* physical memory */ extern dev_t dumpdev; /* dump device */ --- 58,63 ---- diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_glue.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_glue.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_glue.c Fri Sep 17 00:56:39 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_glue.c Fri Oct 29 17:21:33 1999 *************** *** 68,73 **** --- 68,74 ---- #include #include #include + #include #include #include #include *************** *** 342,348 **** pri = p->p_swtime + p->p_slptime; if ((p->p_flag & P_SWAPINREQ) == 0) { ! pri -= p->p_nice * 8; } /* --- 343,349 ---- pri = p->p_swtime + p->p_slptime; if ((p->p_flag & P_SWAPINREQ) == 0) { ! pri -= synch_proc_priority(p, 0) * 8; } /* *************** *** 429,447 **** case SSLEEP: case SSTOP: /* ! * do not swapout a realtime process */ ! if (RTP_PRIO_IS_REALTIME(p->p_rtprio.type)) continue; /* ! * Do not swapout a process waiting on a critical ! * event of some kind. Also guarantee swap_idle_threshold1 ! * time in memory. */ ! if (((p->p_priority & 0x7f) < PSOCK) || ! (p->p_slptime < swap_idle_threshold1)) continue; /* --- 430,446 ---- case SSLEEP: case SSTOP: + /* ! * Do not swapout unswappable processes. */ ! if (synch_proc_unswappable(p)) continue; /* ! * Guarantee swap_idle_threshold1 time in memory. */ ! if (p->p_slptime < swap_idle_threshold1) continue; /* diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_meter.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_meter.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_meter.c Fri Sep 17 00:56:40 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_meter.c Fri Oct 29 17:21:33 1999 *************** *** 36,41 **** --- 36,42 ---- #include #include + #include #include #include #include *************** *** 82,88 **** for (nrun = 0, p = allproc.lh_first; p != 0; p = p->p_list.le_next) { switch (p->p_stat) { case SSLEEP: ! if (p->p_priority > PZERO || p->p_slptime != 0) continue; /* fall through */ case SRUN: --- 83,89 ---- for (nrun = 0, p = allproc.lh_first; p != 0; p = p->p_list.le_next) { switch (p->p_stat) { case SSLEEP: ! if (!synch_proc_uninterruptible(p) || p->p_slptime != 0) continue; /* fall through */ case SRUN: *************** *** 157,163 **** case SSLEEP: case SSTOP: if (p->p_flag & P_INMEM) { ! if (p->p_priority <= PZERO) totalp->t_dw++; else if (p->p_slptime < maxslp) totalp->t_sl++; --- 158,164 ---- case SSLEEP: case SSTOP: if (p->p_flag & P_INMEM) { ! if (synch_proc_uninterruptible(p)) totalp->t_dw++; else if (p->p_slptime < maxslp) totalp->t_sl++; diff -c -N -r /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_pageout.c /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_pageout.c *** /hosts/rt/B/old-sd1-A/dufault/posix4/current/usr/src/sys/vm/vm_pageout.c Fri Sep 17 00:56:40 1999 --- /hosts/rt/B/old-sd1-A/dufault/posix4/new/usr/src/sys/vm/vm_pageout.c Fri Oct 29 17:21:33 1999 *************** *** 77,82 **** --- 77,83 ---- #include #include #include + #include #include #include #include *************** *** 1129,1137 **** } if (bigproc != NULL) { killproc(bigproc, "out of swap space"); ! bigproc->p_estcpu = 0; ! bigproc->p_nice = PRIO_MIN; ! resetpriority(bigproc); wakeup(&cnt.v_free_count); } } --- 1130,1136 ---- } if (bigproc != NULL) { killproc(bigproc, "out of swap space"); ! (void)synch_proc_force_runnable(bigproc); wakeup(&cnt.v_free_count); } }