pmacdona@sol.uvic.ca (Peter MacDonald) (04/01/91)
Here's another vote of confidence for nice (sysupd2) on the 386. Problem Log: My only complaint was that this posting was for two facilities on the ST: nice and profile. Since I am only drooling for nice, and since the upgrade needed some coddling to work on the PC, I found myself wishing that they had been posted as separate upgrades. However, grateful to have the upgrades at all, I forged ahead. For the record, I am using 1.5.10 (thx AST) with 386 patches (thx Bruce), Virtual consoles (thx Gordon), and Shared Text (thx Gary). I don't know if any of these affect clock.c, so be warned that my clock.cdif is not against virgin 1.5.10. You may also need to fix a couple of other minor patching difficulties other than the following two points: 1) Ignore all the st*.cdif files. They are all for profile. 2) The clock.cdif failed on two major hunks. The first failure can be ignored, but the second is important. You can, hand edit clock.c (as I did) or you can try the cdif that follows which I made of clock.c after hand editing it. I hope this is of some use to someone. /-------------------- START OF CLOCK.CDIF --------------------/ *** clock.c~ Sun Mar 10 19:42:31 1991 --- clock.c Sat Mar 30 07:18:51 1991 *************** *** 34,39 **** --- 34,40 ---- /* Constant definitions. */ #define MILLISEC 100 /* how often to call the scheduler (msec) */ #define SCHED_RATE (MILLISEC*HZ/1000) /* number of ticks per schedule */ + #define PRIO_MASK 0x03 /* bit mask used for priority decreasing */ /* Clock parameters. */ #if (CHIP == INTEL) *************** *** 55,62 **** PRIVATE time_t next_alarm; /* probable time of next alarm */ PRIVATE time_t pending_ticks; /* ticks seen by low level only */ PRIVATE time_t realtime; /* real time clock */ - PRIVATE int sched_ticks = SCHED_RATE; /* counter: when 0, call scheduler */ - PRIVATE struct proc *prev_ptr; /* last user process run by clock task */ PRIVATE message mc; /* message buffer for both input and output */ PRIVATE void (*watch_dog[NR_TASKS+1])(); /* watch_dog functions to call */ --- 56,61 ---- *************** *** 197,207 **** } /* If a user process has been running too long, pick another one. */ ! if (--sched_ticks == 0) { ! if (bill_ptr == prev_ptr) lock_sched(); /* process has run too long */ ! sched_ticks = SCHED_RATE; /* reset quantum */ ! prev_ptr = bill_ptr; /* new previous process */ ! } #if (CHIP == M68000) if (rdy_head[SHADOW_Q]) unshadow(rdy_head[SHADOW_Q]); #endif --- 196,206 ---- } /* If a user process has been running too long, pick another one. */ ! if (++bill_ptr->quantum_time >= SCHED_RATE) { ! /* process has used full time slice. Run another one */ ! lock_sched(); ! } ! #if (CHIP == M68000) if (rdy_head[SHADOW_Q]) unshadow(rdy_head[SHADOW_Q]); #endif *************** *** 272,278 **** } #endif ! #if (CHIP == M68000) #include "staddr.h" #include "stmfp.h" --- 271,277 ---- } #endif ! #if (MACHINE == ATARI) #include "staddr.h" #include "stmfp.h" *************** *** 314,321 **** * These are used for accounting. It does not matter if proc.c * is changing them, provided they are always valid pointers, * since at worst the previous process would be billed. ! * next_alarm, realtime, sched_ticks, bill_ptr, prev_ptr, ! * rdy_head[USER_Q]: * These are tested to decide whether to call interrupt(). It * does not matter if the test is sometimes (rarely) backwards * due to a race, since this will only delay the high-level --- 313,319 ---- * These are used for accounting. It does not matter if proc.c * is changing them, provided they are always valid pointers, * since at worst the previous process would be billed. ! * next_alarm, realtime, bill_ptr, rdy_head[USER_Q]: * These are tested to decide whether to call interrupt(). It * does not matter if the test is sometimes (rarely) backwards * due to a race, since this will only delay the high-level *************** *** 329,340 **** * This is protected by an explicit lock in clock.c. Don't * update realtime directly, since there are too many * references to it to guard conveniently. - * sched_ticks, prev_ptr: - * Updating these competes with similar code in do_clocktick(). - * No lock is necessary, because if bad things happen here - * (like sched_ticks going negative), the code in do_clocktick() - * will restore the variables to reasonable values, and an - * occasional missed or extra sched() is harmless. * * Are these complications worth the trouble? Well, they make the system 15% * faster on a 5MHz 8088, and make task debugging much easier since there are --- 327,332 ---- *************** *** 357,392 **** if (rp != bill_ptr) ++bill_ptr->sys_time; ++pending_ticks; ! #if (CHIP != M68000) ! tty_wakeup(); /* possibly wake up TTY */ ! pr_restart(); /* possibly restart printer */ ! #endif ! #if (CHIP == M68000) ! kb_timer(); /* keyboard repeat */ ! if (sched_ticks == 1) fd_timer(); /* floppy deselect */ ! ! /* If input characters are accumulating on an RS232 line, process them. */ ! if (flush_flag) { ! if ( (((int)(realtime+pending_ticks)) & FLUSH_MASK) == 0) rs_flush(); ! /* only low-order bits of realtime mattered */ ! } ! #endif ! ! if (next_alarm <= realtime + pending_ticks || ! sched_ticks == 1 && ! bill_ptr == prev_ptr && ! #if (CHIP != M68000) ! rdy_head[USER_Q] != NIL_PROC) { ! #else ! (rdy_head[USER_Q] != NIL_PROC || rdy_head[SHADOW_Q] != NIL_PROC)) { ! #endif interrupt(CLOCK); return; } ! ! if (--sched_ticks == 0) { ! /* If bill_ptr == prev_ptr, no ready users so don't need sched(). */ ! sched_ticks = SCHED_RATE; /* reset quantum */ ! prev_ptr = bill_ptr; /* new previous process */ ! } ! } --- 349,384 ---- if (rp != bill_ptr) ++bill_ptr->sys_time; ++pending_ticks; ! ! tty_wakeup(); /* possibly wake up TTY */ ! #if (CHIP == INTEL) ! pr_restart(); /* possibly restart printer */ ! #endif ! ! /* increase process priority for all ready-to-run user processes in the ! * user process queue(s) in a fixed time interval. --kub ! */ ! if ( ((realtime + pending_ticks) & PRIO_MASK) == 0 ) { ! for (rp = rdy_head[USER_Q]; rp; rp = rp->p_nextready) ! rp->curr_prio--; ! } ! ! /* switch to clock task's do_clocktick routine if more work is to do */ ! if (next_alarm <= (realtime + pending_ticks) || /* trigger an alarm */ ! bill_ptr->quantum_time >= SCHED_RATE-1 && /* process switch */ ! rdy_head[USER_Q] != NIL_PROC && ! (bill_ptr != rdy_head[USER_Q] || bill_ptr->p_nextready != NIL_PROC)) { interrupt(CLOCK); return; } ! /* If time slice has been used up but no other ready user processes exists ! * no sched() call is needed. The only effect of that call would be a ! * priority recalculation, so inline it here. --kub ! */ ! if (++bill_ptr->quantum_time >= SCHED_RATE) { ! bill_ptr->curr_prio = calc_prio (bill_ptr); ! bill_ptr->quantum_last = bill_ptr->quantum_time; ! bill_ptr->quantum_time = 0; /* reset quantum */ ! } ! } !