149594Sbostic /*- 249594Sbostic * Copyright (c) 1982, 1986, 1991 The Regents of the University of California. 349594Sbostic * All rights reserved. 423366Smckusick * 549594Sbostic * %sccs.include.redist.c% 649594Sbostic * 7*55294Storek * @(#)kern_clock.c 7.24 (Berkeley) 07/16/92 823366Smckusick */ 99Sbill 1017088Sbloom #include "param.h" 1117088Sbloom #include "systm.h" 1229946Skarels #include "dkstat.h" 1317088Sbloom #include "callout.h" 1417088Sbloom #include "kernel.h" 1517088Sbloom #include "proc.h" 1648979Skarels #include "resourcevar.h" 179Sbill 1847546Skarels #include "machine/cpu.h" 1935406Skarels 2010291Smckusick #ifdef GPROF 2154791Storek #include "gmon.h" 2254791Storek extern u_short *kcount; 2310291Smckusick #endif 2410291Smckusick 258124Sroot /* 268124Sroot * Clock handling routines. 278124Sroot * 2854791Storek * This code is written to operate with two timers that run independently of 2954791Storek * each other. The main clock, running hz times per second, is used to keep 3054791Storek * track of real time. The second timer handles kernel and user profiling, 3154791Storek * and does resource use estimation. If the second timer is programmable, 3254791Storek * it is randomized to avoid aliasing between the two clocks. For example, 3354791Storek * the randomization prevents an adversary from always giving up the cpu 3454791Storek * just before its quantum expires. Otherwise, it would never accumulate 3554791Storek * cpu ticks. The mean frequency of the second timer is stathz. 3654791Storek * 3754791Storek * If no second timer exists, stathz will be zero; in this case we drive 3854791Storek * profiling and statistics off the main clock. This WILL NOT be accurate; 3954791Storek * do not do it unless absolutely necessary. 4054791Storek * 4154791Storek * The statistics clock may (or may not) be run at a higher rate while 4254791Storek * profiling. This profile clock runs at profhz. We require that profhz 4354791Storek * be an integral multiple of stathz. 4454791Storek * 4554791Storek * If the statistics clock is running fast, it must be divided by the ratio 4654791Storek * profhz/stathz for statistics. (For profiling, every tick counts.) 478124Sroot */ 481559Sbill 498124Sroot /* 508124Sroot * TODO: 5112747Ssam * allocate more timeout table slots when table overflows. 528124Sroot */ 5326265Skarels 5417007Smckusick /* 5517007Smckusick * Bump a timeval by a small number of usec's. 5617007Smckusick */ 5717007Smckusick #define BUMPTIME(t, usec) { \ 5854791Storek register volatile struct timeval *tp = (t); \ 5954791Storek register long us; \ 6017007Smckusick \ 6154791Storek tp->tv_usec = us = tp->tv_usec + (usec); \ 6254791Storek if (us >= 1000000) { \ 6354791Storek tp->tv_usec = us - 1000000; \ 6417007Smckusick tp->tv_sec++; \ 6517007Smckusick } \ 6617007Smckusick } 6717007Smckusick 6854124Smckusick int stathz; 6953011Ssklower int profhz; 7054138Smckusick int profprocs; 7154791Storek static int psratio, psdiv, pscnt; /* prof => stat divider */ 7254791Storek 7354791Storek volatile struct timeval time; 7454791Storek volatile struct timeval mono_time; 7554791Storek 768124Sroot /* 7754791Storek * Initialize clock frequencies and start both clocks running. 788124Sroot */ 7954791Storek void 8054791Storek initclocks() 8154791Storek { 8254791Storek register int i; 8354791Storek 8454791Storek /* 8554791Storek * Set divisors to 1 (normal case) and let the machine-specific 8654791Storek * code do its bit. 8754791Storek */ 8854791Storek psdiv = pscnt = 1; 8954791Storek cpu_initclocks(); 9054791Storek 9154791Storek /* 9254791Storek * Compute profhz/stathz, and fix profhz if needed. 9354791Storek */ 9454791Storek i = stathz ? stathz : hz; 9554791Storek if (profhz == 0) 9654791Storek profhz = i; 9754791Storek psratio = profhz / i; 9854791Storek } 9954791Storek 10054791Storek /* 10154791Storek * The real-time timer, interrupting hz times per second. 10254791Storek */ 10354791Storek void 10444774Swilliam hardclock(frame) 10554791Storek register struct clockframe *frame; 1069Sbill { 1072768Swnj register struct callout *p1; 10854791Storek register struct proc *p; 109*55294Storek register int delta, needsoft; 11028947Skarels extern int tickdelta; 11128947Skarels extern long timedelta; 1129Sbill 1138124Sroot /* 1148124Sroot * Update real-time timeout queue. 1158124Sroot * At front of queue are some number of events which are ``due''. 1168124Sroot * The time to these is <= 0 and if negative represents the 1178124Sroot * number of ticks which have passed since it was supposed to happen. 1188124Sroot * The rest of the q elements (times > 0) are events yet to happen, 1198124Sroot * where the time for each is given as a delta from the previous. 1208124Sroot * Decrementing just the first of these serves to decrement the time 1218124Sroot * to all events. 1228124Sroot */ 12354791Storek needsoft = 0; 12454791Storek for (p1 = calltodo.c_next; p1 != NULL; p1 = p1->c_next) { 12512747Ssam if (--p1->c_time > 0) 12612747Ssam break; 12716172Skarels needsoft = 1; 12812747Ssam if (p1->c_time == 0) 12912747Ssam break; 13012747Ssam } 131138Sbill 13254791Storek p = curproc; 13354791Storek if (p) { 13454791Storek register struct pstats *pstats; 13554791Storek 1368124Sroot /* 13754791Storek * Run current process's virtual and profile time, as needed. 1388124Sroot */ 13954791Storek pstats = p->p_stats; 14054791Storek if (CLKF_USERMODE(frame) && 14154791Storek timerisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) && 14247546Skarels itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) 14340674Smarc psignal(p, SIGVTALRM); 14447546Skarels if (timerisset(&pstats->p_timer[ITIMER_PROF].it_value) && 14547546Skarels itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) 14640674Smarc psignal(p, SIGPROF); 1479Sbill } 1488124Sroot 1498124Sroot /* 15054791Storek * If no separate statistics clock is available, run it from here. 15111392Ssam */ 15254124Smckusick if (stathz == 0) 15354791Storek statclock(frame); 15411392Ssam 15511392Ssam /* 156*55294Storek * Increment the time-of-day. The increment is just ``tick'' unless 157*55294Storek * we are still adjusting the clock; see adjtime(). 1588124Sroot */ 159*55294Storek if (timedelta == 0) 160*55294Storek delta = tick; 161*55294Storek else { 162*55294Storek delta = tick + tickdelta; 163*55294Storek timedelta -= tickdelta; 16417356Skarels } 165*55294Storek BUMPTIME(&time, delta); 166*55294Storek BUMPTIME(&mono_time, delta); 16754791Storek 16854791Storek /* 16954791Storek * Process callouts at a very low cpu priority, so we don't keep the 17054791Storek * relatively high clock interrupt priority any longer than necessary. 17154791Storek */ 17216525Skarels if (needsoft) { 17354791Storek if (CLKF_BASEPRI(frame)) { 17416525Skarels /* 17516525Skarels * Save the overhead of a software interrupt; 17616525Skarels * it will happen as soon as we return, so do it now. 17716525Skarels */ 17854791Storek (void)splsoftclock(); 17954791Storek softclock(); 18016525Skarels } else 18116525Skarels setsoftclock(); 18216525Skarels } 1832442Swnj } 1842442Swnj 1858124Sroot /* 18654791Storek * Software (low priority) clock interrupt. 1878124Sroot * Run periodic events from timeout queue. 1888124Sroot */ 1892609Swnj /*ARGSUSED*/ 19054791Storek void 19154791Storek softclock() 1922442Swnj { 19354791Storek register struct callout *c; 19454791Storek register void *arg; 19554791Storek register void (*func) __P((void *)); 19654791Storek register int s; 1972442Swnj 19854791Storek s = splhigh(); 19954791Storek while ((c = calltodo.c_next) != NULL && c->c_time <= 0) { 20054791Storek func = c->c_func; 20154791Storek arg = c->c_arg; 20254791Storek calltodo.c_next = c->c_next; 20354791Storek c->c_next = callfree; 20454791Storek callfree = c; 2059157Ssam splx(s); 20654791Storek (*func)(arg); 20754791Storek (void) splhigh(); 2082442Swnj } 20954791Storek splx(s); 2109Sbill } 2119Sbill 2129Sbill /* 21347546Skarels * Arrange that (*func)(arg) is called in t/hz seconds. 21412747Ssam */ 21554791Storek void 21647546Skarels timeout(func, arg, t) 21754791Storek void (*func) __P((void *)); 21854791Storek void *arg; 21912747Ssam register int t; 2209Sbill { 2213542Swnj register struct callout *p1, *p2, *pnew; 22254791Storek register int s; 2239Sbill 22454791Storek s = splhigh(); 22518282Smckusick if (t <= 0) 22612747Ssam t = 1; 2273542Swnj pnew = callfree; 2283542Swnj if (pnew == NULL) 2293542Swnj panic("timeout table overflow"); 2303542Swnj callfree = pnew->c_next; 2313542Swnj pnew->c_arg = arg; 23247546Skarels pnew->c_func = func; 2333542Swnj for (p1 = &calltodo; (p2 = p1->c_next) && p2->c_time < t; p1 = p2) 2349742Ssam if (p2->c_time > 0) 2359742Ssam t -= p2->c_time; 2363542Swnj p1->c_next = pnew; 2373542Swnj pnew->c_next = p2; 2383542Swnj pnew->c_time = t; 2393542Swnj if (p2) 2403542Swnj p2->c_time -= t; 2419Sbill splx(s); 2429Sbill } 2437305Ssam 2447305Ssam /* 2457305Ssam * untimeout is called to remove a function timeout call 2467305Ssam * from the callout structure. 2477305Ssam */ 24854791Storek void 24947546Skarels untimeout(func, arg) 25054791Storek void (*func) __P((void *)); 25154791Storek void *arg; 2527305Ssam { 2537305Ssam register struct callout *p1, *p2; 2547305Ssam register int s; 2557305Ssam 25626265Skarels s = splhigh(); 25754791Storek for (p1 = &calltodo; (p2 = p1->c_next) != NULL; p1 = p2) { 25847546Skarels if (p2->c_func == func && p2->c_arg == arg) { 2598112Sroot if (p2->c_next && p2->c_time > 0) 2607305Ssam p2->c_next->c_time += p2->c_time; 2617305Ssam p1->c_next = p2->c_next; 2627305Ssam p2->c_next = callfree; 2637305Ssam callfree = p2; 2647305Ssam break; 2657305Ssam } 2667305Ssam } 2677305Ssam splx(s); 2687305Ssam } 2698112Sroot 2708124Sroot /* 2718124Sroot * Compute number of hz until specified time. 2728124Sroot * Used to compute third argument to timeout() from an 2738124Sroot * absolute time. 2748124Sroot */ 27554791Storek int 2768112Sroot hzto(tv) 2778112Sroot struct timeval *tv; 2788112Sroot { 27954791Storek register long ticks, sec; 28054791Storek int s; 2818112Sroot 2828124Sroot /* 2838124Sroot * If number of milliseconds will fit in 32 bit arithmetic, 2848124Sroot * then compute number of milliseconds to time and scale to 2858124Sroot * ticks. Otherwise just compute number of hz in time, rounding 2868124Sroot * times greater than representible to maximum value. 2878124Sroot * 2888124Sroot * Delta times less than 25 days can be computed ``exactly''. 2898124Sroot * Maximum value for any timeout in 10ms ticks is 250 days. 2908124Sroot */ 29154791Storek s = splhigh(); 2928124Sroot sec = tv->tv_sec - time.tv_sec; 2938124Sroot if (sec <= 0x7fffffff / 1000 - 1000) 2948124Sroot ticks = ((tv->tv_sec - time.tv_sec) * 1000 + 2958124Sroot (tv->tv_usec - time.tv_usec) / 1000) / (tick / 1000); 2968124Sroot else if (sec <= 0x7fffffff / hz) 2978124Sroot ticks = sec * hz; 2988124Sroot else 2998124Sroot ticks = 0x7fffffff; 3008112Sroot splx(s); 3018112Sroot return (ticks); 3028112Sroot } 30352668Smckusick 30452668Smckusick /* 30554791Storek * Start profiling on a process. 30654791Storek * 30754791Storek * Kernel profiling passes proc0 which never exits and hence 30854791Storek * keeps the profile clock running constantly. 30954791Storek */ 31054791Storek void 31154791Storek startprofclock(p) 31254791Storek register struct proc *p; 31354791Storek { 31454791Storek int s; 31554791Storek 31654791Storek if ((p->p_flag & SPROFIL) == 0) { 31754791Storek p->p_flag |= SPROFIL; 31854791Storek if (++profprocs == 1 && stathz != 0) { 31954791Storek s = splstatclock(); 32054791Storek psdiv = pscnt = psratio; 32154791Storek setstatclockrate(profhz); 32254791Storek splx(s); 32354791Storek } 32454791Storek } 32554791Storek } 32654791Storek 32754791Storek /* 32854791Storek * Stop profiling on a process. 32954791Storek */ 33054791Storek void 33154791Storek stopprofclock(p) 33254791Storek register struct proc *p; 33354791Storek { 33454791Storek int s; 33554791Storek 33654791Storek if (p->p_flag & SPROFIL) { 33754791Storek p->p_flag &= ~SPROFIL; 33854791Storek if (--profprocs == 0 && stathz != 0) { 33954791Storek s = splstatclock(); 34054791Storek psdiv = pscnt = 1; 34154791Storek setstatclockrate(stathz); 34254791Storek splx(s); 34354791Storek } 34454791Storek } 34554791Storek } 34654791Storek 34754791Storek int dk_ndrive = DK_NDRIVE; 34854791Storek 34954791Storek /* 35054791Storek * Statistics clock. Grab profile sample, and if divider reaches 0, 35154791Storek * do process and kernel statistics. 35254791Storek */ 35354791Storek void 35454791Storek statclock(frame) 35554791Storek register struct clockframe *frame; 35654791Storek { 35754791Storek #ifdef GPROF 35854791Storek register struct gmonparam *g; 35954791Storek #endif 36054791Storek register struct proc *p; 36154791Storek register int i; 36254791Storek 36354791Storek if (CLKF_USERMODE(frame)) { 36454791Storek p = curproc; 36554791Storek if (p->p_flag & SPROFIL) 36654791Storek addupc_intr(p, CLKF_PC(frame), 1); 36754791Storek if (--pscnt > 0) 36854791Storek return; 36954791Storek /* 37054791Storek * Came from user mode; CPU was in user state. 37154791Storek * If this process is being profiled record the tick. 37254791Storek */ 37354791Storek p->p_uticks++; 37454791Storek if (p->p_nice > NZERO) 37554791Storek cp_time[CP_NICE]++; 37654791Storek else 37754791Storek cp_time[CP_USER]++; 37854791Storek } else { 37954791Storek #ifdef GPROF 38054791Storek /* 38154791Storek * Kernel statistics are just like addupc_intr, only easier. 38254791Storek */ 38354791Storek g = &_gmonparam; 38454791Storek if (g->state == GMON_PROF_ON) { 38554791Storek i = CLKF_PC(frame) - g->lowpc; 38654791Storek if (i < g->textsize) 38754886Storek kcount[i / (HISTFRACTION * sizeof(*kcount))]++; 38854791Storek } 38954791Storek #endif 39054791Storek if (--pscnt > 0) 39154791Storek return; 39254791Storek /* 39354791Storek * Came from kernel mode, so we were: 39454791Storek * - handling an interrupt, 39554791Storek * - doing syscall or trap work on behalf of the current 39654791Storek * user process, or 39754791Storek * - spinning in the idle loop. 39854791Storek * Whichever it is, charge the time as appropriate. 39954791Storek * Note that we charge interrupts to the current process, 40054791Storek * regardless of whether they are ``for'' that process, 40154791Storek * so that we know how much of its real time was spent 40254791Storek * in ``non-process'' (i.e., interrupt) work. 40354791Storek */ 40454791Storek p = curproc; 40554791Storek if (CLKF_INTR(frame)) { 40654791Storek if (p != NULL) 40754791Storek p->p_iticks++; 40854791Storek cp_time[CP_INTR]++; 40954791Storek } else if (p != NULL) { 41054791Storek p->p_sticks++; 41154791Storek cp_time[CP_SYS]++; 41254791Storek } else 41354791Storek cp_time[CP_IDLE]++; 41454791Storek } 41554791Storek pscnt = psdiv; 41654791Storek 41754791Storek /* 41854791Storek * We maintain statistics shown by user-level statistics 41954791Storek * programs: the amount of time in each cpu state, and 42054791Storek * the amount of time each of DK_NDRIVE ``drives'' is busy. 42154791Storek * 42254791Storek * XXX should either run linked list of drives, or (better) 42354791Storek * grab timestamps in the start & done code. 42454791Storek */ 42554791Storek for (i = 0; i < DK_NDRIVE; i++) 42654791Storek if (dk_busy & (1 << i)) 42754791Storek dk_time[i]++; 42854791Storek 42954791Storek /* 43054791Storek * We adjust the priority of the current process. 43154791Storek * The priority of a process gets worse as it accumulates 43254791Storek * CPU time. The cpu usage estimator (p_cpu) is increased here 43354791Storek * and the formula for computing priorities (in kern_synch.c) 43454791Storek * will compute a different value each time the p_cpu increases 43554791Storek * by 4. The cpu usage estimator ramps up quite quickly when 43654791Storek * the process is running (linearly), and decays away 43754791Storek * exponentially, at a rate which is proportionally slower 43854791Storek * when the system is busy. The basic principal is that the 43954791Storek * system will 90% forget that a process used a lot of CPU 44054791Storek * time in 5*loadav seconds. This causes the system to favor 44154791Storek * processes which haven't run much recently, and to 44254791Storek * round-robin among other processes. 44354791Storek */ 44454791Storek if (p != NULL) { 44554791Storek p->p_cpticks++; 44654791Storek if (++p->p_cpu == 0) 44754791Storek p->p_cpu--; 44854791Storek if ((p->p_cpu & 3) == 0) { 44954791Storek setpri(p); 45054791Storek if (p->p_pri >= PUSER) 45154791Storek p->p_pri = p->p_usrpri; 45254791Storek } 45354791Storek } 45454791Storek } 45554791Storek 45654791Storek /* 45752668Smckusick * Return information about system clocks. 45852668Smckusick */ 45952668Smckusick /* ARGSUSED */ 46052668Smckusick kinfo_clockrate(op, where, acopysize, arg, aneeded) 46152668Smckusick int op; 46252668Smckusick register char *where; 46352668Smckusick int *acopysize, arg, *aneeded; 46452668Smckusick { 46552668Smckusick int buflen, error; 46652668Smckusick struct clockinfo clockinfo; 46752668Smckusick 46852668Smckusick *aneeded = sizeof(clockinfo); 46952668Smckusick if (where == NULL) 47052668Smckusick return (0); 47152668Smckusick /* 47252668Smckusick * Check for enough buffering. 47352668Smckusick */ 47452668Smckusick buflen = *acopysize; 47552668Smckusick if (buflen < sizeof(clockinfo)) { 47652668Smckusick *acopysize = 0; 47752668Smckusick return (0); 47852668Smckusick } 47952668Smckusick /* 48052668Smckusick * Copyout clockinfo structure. 48152668Smckusick */ 48252668Smckusick clockinfo.hz = hz; 48352668Smckusick clockinfo.tick = tick; 48452668Smckusick clockinfo.profhz = profhz; 48554791Storek clockinfo.stathz = stathz ? stathz : hz; 48652668Smckusick if (error = copyout((caddr_t)&clockinfo, where, sizeof(clockinfo))) 48752668Smckusick return (error); 48852668Smckusick *acopysize = sizeof(clockinfo); 48952668Smckusick return (0); 49052668Smckusick } 491