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: /* ---------------------------       */