clock.c

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 /* ------------------------ */ 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899