04400 #include "../h/param.h" 04401 #include "../h/systm.h" 04402 #include "../h/callo.h" 04403 #include "../h/seg.h" 04404 #include "../h/dir.h" 04405 #include "../h/user.h" 04406 #include "../h/proc.h" 04407 #include "../h/reg.h" 04408 04409 #define SCHMAG 8/10 04410 04411 /* 04412 * clock is called straight from 04413 * the real time clock interrupt. 04414 * 04415 * Functions: 04416 * reprime clock 04417 * copy *switches to display 04418 * implement callouts 04419 * maintain user/system times 04420 * maintain date 04421 * profile 04422 * lightning bolt wakeup (every second) 04423 * alarm clock signals 04424 * jab the scheduler 04425 */ 04426 04427 clock(dev, sp, r1, nps, r0, pc, ps) 04428 dev_t dev; 04429 caddr_t pc; 04430 { 04431 register struct callo *p1, *p2; 04432 register struct proc *pp; 04433 int a; 04434 extern caddr_t waitloc; 04435 04436 /* 04437 * restart clock 04438 */ 04439 04440 lks->r[0] = 0115; 04441 04442 /* 04443 * display register 04444 */ 04445 04446 display(); 04447 /* 04448 * callouts 04449 * if none, just continue 04450 * else update first non-zero time 04451 */ 04452 04453 if(callout[0].c_func == NULL) 04454 goto out; 04455 p2 = &callout[0]; 04456 while(p2->c_time<=0 && p2->c_func!=NULL) 04457 p2++; 04458 p2->c_time--; 04459 04460 /* 04461 * if ps is high, just return 04462 */ 04463 if (BASEPRI(ps)) 04464 goto out; 04465 04466 /* 04467 * callout 04468 */ 04469 04470 spl5(); 04471 if(callout[0].c_time <= 0) { 04472 p1 = &callout[0]; 04473 while(p1->c_func != 0 && p1->c_time <= 0) { 04474 (*p1->c_func)(p1->c_arg); 04475 p1++; 04476 } 04477 p2 = &callout[0]; 04478 while(p2->c_func = p1->c_func) { 04479 p2->c_time = p1->c_time; 04480 p2->c_arg = p1->c_arg; 04481 p1++; 04482 p2++; 04483 } 04484 } 04485 04486 /* 04487 * lightning bolt time-out 04488 * and time of day 04489 */ 04490 out: 04491 a = dk_busy&07; 04492 if (USERMODE(ps)) { 04493 u.u_utime++; 04494 if(u.u_prof.pr_scale) 04495 addupc(pc, &u.u_prof, 1); 04496 if(u.u_procp->p_nice > NZERO) 04497 a += 8; 04498 } else { 04499 a += 16; 04500 if (pc == waitloc) 04501 a += 8; 04502 u.u_stime++; 04503 } 04504 dk_time[a] += 1; 04505 pp = u.u_procp; 04506 if(++pp->p_cpu == 0) 04507 pp->p_cpu--; 04508 if(++lbolt >= HZ) { 04509 if (BASEPRI(ps)) 04510 return; 04511 lbolt -= HZ; 04512 ++time; 04513 spl1(); 04514 runrun++; 04515 wakeup((caddr_t)&lbolt); 04516 for(pp = &proc[0]; pp < &proc[NPROC]; pp++) 04517 if (pp->p_stat && pp->p_stat04518 if(pp->p_time != 127) 04519 pp->p_time++; 04520 if(pp->p_clktim) 04521 if(--pp->p_clktim == 0) 04522 psignal(pp, SIGCLK); 04523 a = (pp->p_cpu & 0377)*SCHMAG + pp->p_nice - NZERO; 04524 if(a < 0) 04525 a = 0; 04526 if(a > 255) 04527 a = 255; 04528 pp->p_cpu = a; 04529 if(pp->p_pri >= PUSER) 04530 setpri(pp); 04531 } 04532 if(runin!=0) { 04533 runin = 0; 04534 wakeup((caddr_t)&runin); 04535 } 04536 } 04537 } 04538 04539 /* 04540 * timeout is called to arrange that 04541 * fun(arg) is called in tim/HZ seconds. 04542 * An entry is sorted into the callout 04543 * structure. The time in each structure 04544 * entry is the number of HZ's more 04545 * than the previous entry. 04546 * In this way, decrementing the 04547 * first entry has the effect of 04548 * updating all entries. 04549 * 04550 * The panic is there because there is nothing 04551 * intelligent to be done if an entry won't fit. 04552 */ 04553 timeout(fun, arg, tim) 04554 int (*fun)(); 04555 caddr_t arg; 04556 { 04557 register struct callo *p1, *p2; 04558 register int t; 04559 int s; 04560 04561 t = tim; 04562 p1 = &callout[0]; 04563 s = spl7(); 04564 while(p1->c_func != 0 && p1->c_time <= t) { 04565 t -= p1->c_time; 04566 p1++; 04567 } 04568 if (p1 >= &callout[NCALL-1]) 04569 panic("Timeout table overflow"); 04570 p1->c_time -= t; 04571 p2 = p1; 04572 while(p2->c_func != 0) 04573 p2++; 04574 while(p2 >= p1) { 04575 (p2+1)->c_time = p2->c_time; 04576 (p2+1)->c_func = p2->c_func; 04577 (p2+1)->c_arg = p2->c_arg; 04578 p2--; 04579 } 04580 p1->c_time = t; 04581 p1->c_func = fun; 04582 p1->c_arg = arg; 04583 splx(s); 04584 } 04585 04586 04587 04588 04589 04590 04591 04592 04593 04594 04595 04596 04597 04598 04599