3700: #
3701: #include "../param.h"
3702: #include "../systm.h"
3703: #include "../user.h"
3704: #include "../proc.h"
3705:
3706: #define UMODE 0170000
3707: #define SCHMAG 10
3708:
3709: /*
3710: * clock is called straight from
3711: * the real time clock interrupt.
3712: *
3713: * Functions:
3714: * reprime clock
3715: * copy *switches to display
3716: * implement callouts
3717: * maintain user/system times
3718: * maintain date
3719: * profile
3720: * tout wakeup (sys sleep)
3721: * lightning bolt wakeup (every 4 sec)
3722: * alarm clock signals
3723: * jab the scheduler
3724: */
3725: clock(dev, sp, r1, nps, r0, pc, ps)
3726: {
3727: register struct callo *p1, *p2;
3728: register struct proc *pp;
3729:
3730: /*
3731: * restart clock
3732: */
3733:
3734: *lks = 0115;
3735:
3736: /*
3737: * display register
3738: */
3739:
3740: display();
3741:
3742: /*
3743: * callouts
3744: * if none, just return
3745: * else update first non-zero time
3746: */
3747:
3748: if(callout[0].c_func == 0)
3749: goto out;
3750: p2 = &callout[0];
3751: while(p2->c_time<=0 && p2->c_func!=0)
3752: p2++;
3753: p2->c_time--;
3754:
3755: /*
3756: * if ps is high, just return
3757: */
3758:
3759: if((ps&0340) != 0)
3760: goto out;
3761:
3762: /*
3763: * callout
3764: */
3765:
3766: spl5();
3767: if(callout[0].c_time <= 0) {
3768: p1 = &callout[0];
3769: while(p1->c_func != 0 && p1->c_time <= 0) {
3770: (*p1->c_func)(p1->c_arg);
3771: p1++;
3772: }
3773: p2 = &callout[0];
3774: while(p2->c_func = p1->c_func) {
3775: p2->c_time = p1->c_time;
3776: p2->c_arg = p1->c_arg;
3777: p1++;
3778: p2++;
3779: }
3780: }
3781:
3782: /*
3783: * lightning bolt time-out
3784: * and time of day
3785: */
3786:
3787: out:
3788: if((ps&UMODE) == UMODE) {
3789: u.u_utime++;
3790: if(u.u_prof[3])
3791: incupc(pc, u.u_prof);
3792: } else
3793: u.u_stime++;
3794: pp = u.u_procp;
3795: if(++pp->p_cpu == 0)
3796: pp->p_cpu--;
3797: if(++lbolt >= HZ) {
3798: if((ps&0340) != 0)
3799: return;
3800: lbolt =- HZ;
3801: if(++time[1] == 0)
3802: ++time[0];
3803: spl1();
3804: if(time[1]==tout[1] && time[0]==tout[0])
3805: wakeup(tout);
3806: if((time[1]&03) == 0) {
3807: runrun++;
3808: wakeup(&lbolt);
3809: }
3810: for(pp = &proc[0]; pp < &proc[NPROC]; pp++)
3811: if (pp->p_stat) {
3812: if(pp->p_time != 127)
3813: pp->p_time++;
3814: if((pp->p_cpu & 0377) > SCHMAG)
3815: pp->p_cpu =- SCHMAG; else
3816: pp->p_cpu = 0;
3817: if(pp->p_pri > PUSER)
3818: setpri(pp);
3819: }
3820: if(runin!=0) {
3821: runin = 0;
3822: wakeup(&runin);
3823: }
3824: if((ps&UMODE) == UMODE) {
3825: u.u_ar0 = &r0;
3826: if(issig())
3827: psig();
3828: setpri(u.u_procp);
3829: }
3830: }
3831: }
3832: /* --------------------------- */
3833:
3834: /*
3835: * timeout is called to arrange that
3836: * fun(arg) is called in tim/HZ seconds.
3837: * An entry is sorted into the callout
3838: * structure. The time in each structure
3839: * entry is the number of HZ's more
3840: * than the previous entry.
3841: * In this way, decrementing the
3842: * first entry has the effect of
3843: * updating all entries.
3844: */
3845: timeout(fun, arg, tim)
3846: {
3847: register struct callo *p1, *p2;
3848: register t;
3849: int s;
3850:
3851: t = tim;
3852: s = PS->integ;
3853: p1 = &callout[0];
3854: spl7();
3855: while(p1->c_func != 0 && p1->c_time <= t) {
3856: t =- p1->c_time;
3857: p1++;
3858: }
3859: p1->c_time =- t;
3860: p2 = p1;
3861: while(p2->c_func != 0)
3862: p2++;
3863: while(p2 >= p1) {
3864: (p2+1)->c_time = p2->c_time;
3865: (p2+1)->c_func = p2->c_func;
3866: (p2+1)->c_arg = p2->c_arg;
3867: p2--;
3868: }
3869: p1->c_time = t;
3870: p1->c_func = fun;
3871: p1->c_arg = arg;
3872: PS->integ = s;
3873: }
3874: /* --------------------------- */