home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / kernel / sched.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-22  |  20.8 KB  |  842 lines

  1. /*
  2.  *  linux/kernel/sched.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. /*
  8.  * 'sched.c' is the main kernel file. It contains scheduling primitives
  9.  * (sleep_on, wakeup, schedule etc) as well as a number of simple system
  10.  * call functions (type getpid(), which just extracts a field from
  11.  * current-task
  12.  */
  13.  
  14. #include <linux/config.h>
  15. #include <linux/signal.h>
  16. #include <linux/sched.h>
  17. #include <linux/timer.h>
  18. #include <linux/kernel.h>
  19. #include <linux/kernel_stat.h>
  20. #include <linux/sys.h>
  21. #include <linux/fdreg.h>
  22. #include <linux/errno.h>
  23. #include <linux/time.h>
  24. #include <linux/ptrace.h>
  25. #include <linux/segment.h>
  26. #include <linux/delay.h>
  27. #include <linux/interrupt.h>
  28.  
  29. #include <asm/system.h>
  30. #include <asm/io.h>
  31. #include <asm/segment.h>
  32.  
  33. #define TIMER_IRQ 0
  34.  
  35. #include <linux/timex.h>
  36.  
  37. /*
  38.  * kernel variables
  39.  */
  40. long tick = 1000000 / HZ;               /* timer interrupt period */
  41. volatile struct timeval xtime;        /* The current time */
  42. int tickadj = 500/HZ;            /* microsecs */
  43.  
  44. /*
  45.  * phase-lock loop variables
  46.  */
  47. int time_status = TIME_BAD;     /* clock synchronization status */
  48. long time_offset = 0;           /* time adjustment (us) */
  49. long time_constant = 0;         /* pll time constant */
  50. long time_tolerance = MAXFREQ;  /* frequency tolerance (ppm) */
  51. long time_precision = 1;     /* clock precision (us) */
  52. long time_maxerror = 0x70000000;/* maximum error */
  53. long time_esterror = 0x70000000;/* estimated error */
  54. long time_phase = 0;            /* phase offset (scaled us) */
  55. long time_freq = 0;             /* frequency offset (scaled ppm) */
  56. long time_adj = 0;              /* tick adjust (scaled 1 / HZ) */
  57. long time_reftime = 0;          /* time at last adjustment (s) */
  58.  
  59. long time_adjust = 0;
  60. long time_adjust_step = 0;
  61.  
  62. int need_resched = 0;
  63.  
  64. /*
  65.  * Tell us the machine setup..
  66.  */
  67. int hard_math = 0;        /* set by boot/head.S */
  68. int x86 = 0;            /* set by boot/head.S to 3 or 4 */
  69. int ignore_irq13 = 0;        /* set if exception 16 works */
  70. int wp_works_ok = 0;        /* set if paging hardware honours WP */ 
  71.  
  72. /*
  73.  * Bus types ..
  74.  */
  75. int EISA_bus = 0;
  76.  
  77. extern int _setitimer(int, struct itimerval *, struct itimerval *);
  78. unsigned long * prof_buffer = NULL;
  79. unsigned long prof_len = 0;
  80.  
  81. #define _S(nr) (1<<((nr)-1))
  82.  
  83. extern void mem_use(void);
  84.  
  85. extern int timer_interrupt(void);
  86. asmlinkage int system_call(void);
  87.  
  88. static unsigned long init_kernel_stack[1024];
  89. struct task_struct init_task = INIT_TASK;
  90.  
  91. unsigned long volatile jiffies=0;
  92.  
  93. struct task_struct *current = &init_task;
  94. struct task_struct *last_task_used_math = NULL;
  95.  
  96. struct task_struct * task[NR_TASKS] = {&init_task, };
  97.  
  98. long user_stack [ PAGE_SIZE>>2 ] ;
  99.  
  100. struct {
  101.     long * a;
  102.     short b;
  103.     } stack_start = { & user_stack [PAGE_SIZE>>2] , KERNEL_DS };
  104.  
  105. struct kernel_stat kstat =
  106.     { 0, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  107.  
  108. /*
  109.  * int 0x80 entry points.. Moved away from the header file, as
  110.  * iBCS2 may also want to use the '<linux/sys.h>' headers..
  111.  */
  112. #ifdef __cplusplus
  113. extern "C" {
  114. #endif
  115.  
  116. int sys_ni_syscall(void)
  117. {
  118.     return -EINVAL;
  119. }
  120.  
  121. fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
  122. sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
  123. sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
  124. sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
  125. sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
  126. sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
  127. sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
  128. sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
  129. sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
  130. sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
  131. sys_olduname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
  132. sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
  133. sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending,
  134. sys_sethostname, sys_setrlimit, sys_getrlimit, sys_getrusage,
  135. sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups,
  136. sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib,
  137. sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap, sys_truncate,
  138. sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, sys_setpriority,
  139. sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, sys_socketcall,
  140. sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat,
  141. sys_newfstat, sys_uname, sys_iopl, sys_vhangup, sys_idle, sys_vm86,
  142. sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,
  143. sys_clone, sys_setdomainname, sys_newuname, sys_modify_ldt,
  144. sys_adjtimex, sys_mprotect, sys_sigprocmask, sys_create_module,
  145. sys_init_module, sys_delete_module, sys_get_kernel_syms, sys_quotactl,
  146. sys_getpgid, sys_fchdir, sys_bdflush };
  147.  
  148. /* So we don't have to do any more manual updating.... */
  149. int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
  150.  
  151. #ifdef __cplusplus
  152. }
  153. #endif
  154.  
  155. /*
  156.  *  'math_state_restore()' saves the current math information in the
  157.  * old math state array, and gets the new ones from the current task
  158.  *
  159.  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
  160.  * Don't touch unless you *really* know how it works.
  161.  */
  162. asmlinkage void math_state_restore(void)
  163. {
  164.     __asm__ __volatile__("clts");
  165.     if (last_task_used_math == current)
  166.         return;
  167.     timer_table[COPRO_TIMER].expires = jiffies+50;
  168.     timer_active |= 1<<COPRO_TIMER;    
  169.     if (last_task_used_math)
  170.         __asm__("fnsave %0":"=m" (last_task_used_math->tss.i387));
  171.     else
  172.         __asm__("fnclex");
  173.     last_task_used_math = current;
  174.     if (current->used_math) {
  175.         __asm__("frstor %0": :"m" (current->tss.i387));
  176.     } else {
  177.         __asm__("fninit");
  178.         current->used_math=1;
  179.     }
  180.     timer_active &= ~(1<<COPRO_TIMER);
  181. }
  182.  
  183. #ifndef CONFIG_MATH_EMULATION
  184.  
  185. asmlinkage void math_emulate(long arg)
  186. {
  187.   printk("math-emulation not enabled and no coprocessor found.\n");
  188.   printk("killing %s.\n",current->comm);
  189.   send_sig(SIGFPE,current,1);
  190.   schedule();
  191. }
  192.  
  193. #endif /* CONFIG_MATH_EMULATION */
  194.  
  195. unsigned long itimer_ticks = 0;
  196. unsigned long itimer_next = ~0;
  197. static unsigned long lost_ticks = 0;
  198.  
  199. /*
  200.  *  'schedule()' is the scheduler function. It's a very simple and nice
  201.  * scheduler: it's not perfect, but certainly works for most things.
  202.  * The one thing you might take a look at is the signal-handler code here.
  203.  *
  204.  *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
  205.  * tasks can run. It can not be killed, and it cannot sleep. The 'state'
  206.  * information in task[0] is never used.
  207.  *
  208.  * The "confuse_gcc" goto is used only to get better assembly code..
  209.  * Djikstra probably hates me.
  210.  */
  211. asmlinkage void schedule(void)
  212. {
  213.     int c;
  214.     struct task_struct * p;
  215.     struct task_struct * next;
  216.     unsigned long ticks;
  217.  
  218. /* check alarm, wake up any interruptible tasks that have got a signal */
  219.  
  220.     cli();
  221.     ticks = itimer_ticks;
  222.     itimer_ticks = 0;
  223.     itimer_next = ~0;
  224.     sti();
  225.     need_resched = 0;
  226.     p = &init_task;
  227.     for (;;) {
  228.         if ((p = p->next_task) == &init_task)
  229.             goto confuse_gcc1;
  230.         if (ticks && p->it_real_value) {
  231.             if (p->it_real_value <= ticks) {
  232.                 send_sig(SIGALRM, p, 1);
  233.                 if (!p->it_real_incr) {
  234.                     p->it_real_value = 0;
  235.                     goto end_itimer;
  236.                 }
  237.                 do {
  238.                     p->it_real_value += p->it_real_incr;
  239.                 } while (p->it_real_value <= ticks);
  240.             }
  241.             p->it_real_value -= ticks;
  242.             if (p->it_real_value < itimer_next)
  243.                 itimer_next = p->it_real_value;
  244.         }
  245. end_itimer:
  246.         if (p->state != TASK_INTERRUPTIBLE)
  247.             continue;
  248.         if (p->signal & ~p->blocked) {
  249.             p->state = TASK_RUNNING;
  250.             continue;
  251.         }
  252.         if (p->timeout && p->timeout <= jiffies) {
  253.             p->timeout = 0;
  254.             p->state = TASK_RUNNING;
  255.         }
  256.     }
  257. confuse_gcc1:
  258.  
  259. /* this is the scheduler proper: */
  260. #if 0
  261.     /* give processes that go to sleep a bit higher priority.. */
  262.     /* This depends on the values for TASK_XXX */
  263.     /* This gives smoother scheduling for some things, but */
  264.     /* can be very unfair under some circumstances, so.. */
  265.      if (TASK_UNINTERRUPTIBLE >= (unsigned) current->state &&
  266.         current->counter < current->priority*2) {
  267.         ++current->counter;
  268.     }
  269. #endif
  270.     c = -1;
  271.     next = p = &init_task;
  272.     for (;;) {
  273.         if ((p = p->next_task) == &init_task)
  274.             goto confuse_gcc2;
  275.         if (p->state == TASK_RUNNING && p->counter > c)
  276.             c = p->counter, next = p;
  277.     }
  278. confuse_gcc2:
  279.     if (!c) {
  280.         for_each_task(p)
  281.             p->counter = (p->counter >> 1) + p->priority;
  282.     }
  283.     if(current != next)
  284.         kstat.context_swtch++;
  285.     switch_to(next);
  286.     /* Now maybe reload the debug registers */
  287.     if(current->debugreg[7]){
  288.         loaddebug(0);
  289.         loaddebug(1);
  290.         loaddebug(2);
  291.         loaddebug(3);
  292.         loaddebug(6);
  293.     };
  294. }
  295.  
  296. asmlinkage int sys_pause(void)
  297. {
  298.     current->state = TASK_INTERRUPTIBLE;
  299.     schedule();
  300.     return -ERESTARTNOHAND;
  301. }
  302.  
  303. /*
  304.  * wake_up doesn't wake up stopped processes - they have to be awakened
  305.  * with signals or similar.
  306.  *
  307.  * Note that this doesn't need cli-sti pairs: interrupts may not change
  308.  * the wait-queue structures directly, but only call wake_up() to wake
  309.  * a process. The process itself must remove the queue once it has woken.
  310.  */
  311. void wake_up(struct wait_queue **q)
  312. {
  313.     struct wait_queue *tmp;
  314.     struct task_struct * p;
  315.  
  316.     if (!q || !(tmp = *q))
  317.         return;
  318.     do {
  319.         if ((p = tmp->task) != NULL) {
  320.             if ((p->state == TASK_UNINTERRUPTIBLE) ||
  321.                 (p->state == TASK_INTERRUPTIBLE)) {
  322.                 p->state = TASK_RUNNING;
  323.                 if (p->counter > current->counter)
  324.                     need_resched = 1;
  325.             }
  326.         }
  327.         if (!tmp->next) {
  328.             printk("wait_queue is bad (eip = %08lx)\n",((unsigned long *) q)[-1]);
  329.             printk("        q = %p\n",q);
  330.             printk("       *q = %p\n",*q);
  331.             printk("      tmp = %p\n",tmp);
  332.             break;
  333.         }
  334.         tmp = tmp->next;
  335.     } while (tmp != *q);
  336. }
  337.  
  338. void wake_up_interruptible(struct wait_queue **q)
  339. {
  340.     struct wait_queue *tmp;
  341.     struct task_struct * p;
  342.  
  343.     if (!q || !(tmp = *q))
  344.         return;
  345.     do {
  346.         if ((p = tmp->task) != NULL) {
  347.             if (p->state == TASK_INTERRUPTIBLE) {
  348.                 p->state = TASK_RUNNING;
  349.                 if (p->counter > current->counter)
  350.                     need_resched = 1;
  351.             }
  352.         }
  353.         if (!tmp->next) {
  354.             printk("wait_queue is bad (eip = %08lx)\n",((unsigned long *) q)[-1]);
  355.             printk("        q = %p\n",q);
  356.             printk("       *q = %p\n",*q);
  357.             printk("      tmp = %p\n",tmp);
  358.             break;
  359.         }
  360.         tmp = tmp->next;
  361.     } while (tmp != *q);
  362. }
  363.  
  364. void __down(struct semaphore * sem)
  365. {
  366.     struct wait_queue wait = { current, NULL };
  367.     add_wait_queue(&sem->wait, &wait);
  368.     current->state = TASK_UNINTERRUPTIBLE;
  369.     while (sem->count <= 0) {
  370.         schedule();
  371.         current->state = TASK_UNINTERRUPTIBLE;
  372.     }
  373.     current->state = TASK_RUNNING;
  374.     remove_wait_queue(&sem->wait, &wait);
  375. }
  376.  
  377. static inline void __sleep_on(struct wait_queue **p, int state)
  378. {
  379.     unsigned long flags;
  380.     struct wait_queue wait = { current, NULL };
  381.  
  382.     if (!p)
  383.         return;
  384.     if (current == task[0])
  385.         panic("task[0] trying to sleep");
  386.     current->state = state;
  387.     add_wait_queue(p, &wait);
  388.     save_flags(flags);
  389.     sti();
  390.     schedule();
  391.     remove_wait_queue(p, &wait);
  392.     restore_flags(flags);
  393. }
  394.  
  395. void interruptible_sleep_on(struct wait_queue **p)
  396. {
  397.     __sleep_on(p,TASK_INTERRUPTIBLE);
  398. }
  399.  
  400. void sleep_on(struct wait_queue **p)
  401. {
  402.     __sleep_on(p,TASK_UNINTERRUPTIBLE);
  403. }
  404.  
  405. static struct timer_list * next_timer = NULL;
  406.  
  407. void add_timer(struct timer_list * timer)
  408. {
  409.     unsigned long flags;
  410.     struct timer_list ** p;
  411.  
  412.     if (!timer)
  413.         return;
  414.     timer->next = NULL;
  415.     p = &next_timer;
  416.     save_flags(flags);
  417.     cli();
  418.     while (*p) {
  419.         if ((*p)->expires > timer->expires) {
  420.             (*p)->expires -= timer->expires;
  421.             timer->next = *p;
  422.             break;
  423.         }
  424.         timer->expires -= (*p)->expires;
  425.         p = &(*p)->next;
  426.     }
  427.     *p = timer;
  428.     restore_flags(flags);
  429. }
  430.  
  431. int del_timer(struct timer_list * timer)
  432. {
  433.     unsigned long flags;
  434.     unsigned long expires = 0;
  435.     struct timer_list **p;
  436.  
  437.     p = &next_timer;
  438.     save_flags(flags);
  439.     cli();
  440.     while (*p) {
  441.         if (*p == timer) {
  442.             if ((*p = timer->next) != NULL)
  443.                 (*p)->expires += timer->expires;
  444.             timer->expires += expires;
  445.             restore_flags(flags);
  446.             return 1;
  447.         }
  448.         expires += (*p)->expires;
  449.         p = &(*p)->next;
  450.     }
  451.     restore_flags(flags);
  452.     return 0;
  453. }
  454.  
  455. unsigned long timer_active = 0;
  456. struct timer_struct timer_table[32];
  457.  
  458. /*
  459.  * Hmm.. Changed this, as the GNU make sources (load.c) seems to
  460.  * imply that avenrun[] is the standard name for this kind of thing.
  461.  * Nothing else seems to be standardized: the fractional size etc
  462.  * all seem to differ on different machines.
  463.  */
  464. unsigned long avenrun[3] = { 0,0,0 };
  465.  
  466. /*
  467.  * Nr of active tasks - counted in fixed-point numbers
  468.  */
  469. static unsigned long count_active_tasks(void)
  470. {
  471.     struct task_struct **p;
  472.     unsigned long nr = 0;
  473.  
  474.     for(p = &LAST_TASK; p > &FIRST_TASK; --p)
  475.         if (*p && ((*p)->state == TASK_RUNNING ||
  476.                (*p)->state == TASK_UNINTERRUPTIBLE ||
  477.                (*p)->state == TASK_SWAPPING))
  478.             nr += FIXED_1;
  479.     return nr;
  480. }
  481.  
  482. static inline void calc_load(void)
  483. {
  484.     unsigned long active_tasks; /* fixed-point */
  485.     static int count = LOAD_FREQ;
  486.  
  487.     if (count-- > 0)
  488.         return;
  489.     count = LOAD_FREQ;
  490.     active_tasks = count_active_tasks();
  491.     CALC_LOAD(avenrun[0], EXP_1, active_tasks);
  492.     CALC_LOAD(avenrun[1], EXP_5, active_tasks);
  493.     CALC_LOAD(avenrun[2], EXP_15, active_tasks);
  494. }
  495.  
  496. /*
  497.  * this routine handles the overflow of the microsecond field
  498.  *
  499.  * The tricky bits of code to handle the accurate clock support
  500.  * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
  501.  * They were originally developed for SUN and DEC kernels.
  502.  * All the kudos should go to Dave for this stuff.
  503.  *
  504.  * These were ported to Linux by Philip Gladstone.
  505.  */
  506. static void second_overflow(void)
  507. {
  508.     long ltemp;
  509.     /* last time the cmos clock got updated */
  510.     static long last_rtc_update=0;
  511.     extern int set_rtc_mmss(unsigned long);
  512.  
  513.     /* Bump the maxerror field */
  514.     time_maxerror = (0x70000000-time_maxerror < time_tolerance) ?
  515.       0x70000000 : (time_maxerror + time_tolerance);
  516.  
  517.     /* Run the PLL */
  518.     if (time_offset < 0) {
  519.         ltemp = (-(time_offset+1) >> (SHIFT_KG + time_constant)) + 1;
  520.         time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
  521.         time_offset += (time_adj * HZ) >> (SHIFT_SCALE - SHIFT_UPDATE);
  522.         time_adj = - time_adj;
  523.     } else if (time_offset > 0) {
  524.         ltemp = ((time_offset-1) >> (SHIFT_KG + time_constant)) + 1;
  525.         time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
  526.         time_offset -= (time_adj * HZ) >> (SHIFT_SCALE - SHIFT_UPDATE);
  527.     } else {
  528.         time_adj = 0;
  529.     }
  530.  
  531.     time_adj += (time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE))
  532.         + FINETUNE;
  533.  
  534.     /* Handle the leap second stuff */
  535.     switch (time_status) {
  536.         case TIME_INS:
  537.         /* ugly divide should be replaced */
  538.         if (xtime.tv_sec % 86400 == 0) {
  539.             xtime.tv_sec--; /* !! */
  540.             time_status = TIME_OOP;
  541.             printk("Clock: inserting leap second 23:59:60 GMT\n");
  542.         }
  543.         break;
  544.  
  545.         case TIME_DEL:
  546.         /* ugly divide should be replaced */
  547.         if (xtime.tv_sec % 86400 == 86399) {
  548.             xtime.tv_sec++;
  549.             time_status = TIME_OK;
  550.             printk("Clock: deleting leap second 23:59:59 GMT\n");
  551.         }
  552.         break;
  553.  
  554.         case TIME_OOP:
  555.         time_status = TIME_OK;
  556.         break;
  557.     }
  558.     if (xtime.tv_sec > last_rtc_update + 660)
  559.       if (set_rtc_mmss(xtime.tv_sec) == 0)
  560.         last_rtc_update = xtime.tv_sec;
  561. }
  562.  
  563. /*
  564.  * disregard lost ticks for now.. We don't care enough.
  565.  */
  566. static void timer_bh(void * unused)
  567. {
  568.     unsigned long mask;
  569.     struct timer_struct *tp;
  570.  
  571.     cli();
  572.     while (next_timer && next_timer->expires == 0) {
  573.         void (*fn)(unsigned long) = next_timer->function;
  574.         unsigned long data = next_timer->data;
  575.         next_timer = next_timer->next;
  576.         sti();
  577.         fn(data);
  578.         cli();
  579.     }
  580.     sti();
  581.     
  582.     for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
  583.         if (mask > timer_active)
  584.             break;
  585.         if (!(mask & timer_active))
  586.             continue;
  587.         if (tp->expires > jiffies)
  588.             continue;
  589.         timer_active &= ~mask;
  590.         tp->fn();
  591.         sti();
  592.     }
  593. }
  594.  
  595. /*
  596.  * The int argument is really a (struct pt_regs *), in case the
  597.  * interrupt wants to know from where it was called. The timer
  598.  * irq uses this to decide if it should update the user or system
  599.  * times.
  600.  */
  601. static void do_timer(struct pt_regs * regs)
  602. {
  603.     unsigned long mask;
  604.     struct timer_struct *tp;
  605.  
  606.     long ltemp;
  607.  
  608.     /* Advance the phase, once it gets to one microsecond, then
  609.      * advance the tick more.
  610.      */
  611.     time_phase += time_adj;
  612.     if (time_phase < -FINEUSEC) {
  613.         ltemp = -time_phase >> SHIFT_SCALE;
  614.         time_phase += ltemp << SHIFT_SCALE;
  615.         xtime.tv_usec += tick + time_adjust_step - ltemp;
  616.     }
  617.     else if (time_phase > FINEUSEC) {
  618.         ltemp = time_phase >> SHIFT_SCALE;
  619.         time_phase -= ltemp << SHIFT_SCALE;
  620.         xtime.tv_usec += tick + time_adjust_step + ltemp;
  621.     } else
  622.         xtime.tv_usec += tick + time_adjust_step;
  623.  
  624.     if (time_adjust)
  625.     {
  626.         /* We are doing an adjtime thing. 
  627.          *
  628.          * Modify the value of the tick for next time.
  629.          * Note that a positive delta means we want the clock
  630.          * to run fast. This means that the tick should be bigger
  631.          *
  632.          * Limit the amount of the step for *next* tick to be
  633.          * in the range -tickadj .. +tickadj
  634.          */
  635.          if (time_adjust > tickadj)
  636.            time_adjust_step = tickadj;
  637.          else if (time_adjust < -tickadj)
  638.            time_adjust_step = -tickadj;
  639.          else
  640.            time_adjust_step = time_adjust;
  641.          
  642.         /* Reduce by this step the amount of time left  */
  643.         time_adjust -= time_adjust_step;
  644.     }
  645.     else
  646.         time_adjust_step = 0;
  647.  
  648.     if (xtime.tv_usec >= 1000000) {
  649.         xtime.tv_usec -= 1000000;
  650.         xtime.tv_sec++;
  651.         second_overflow();
  652.     }
  653.  
  654.     jiffies++;
  655.     calc_load();
  656.     if ((VM_MASK & regs->eflags) || (3 & regs->cs)) {
  657.         current->utime++;
  658.         if (current != task[0]) {
  659.             if (current->priority < 15)
  660.                 kstat.cpu_nice++;
  661.             else
  662.                 kstat.cpu_user++;
  663.         }
  664.         /* Update ITIMER_VIRT for current task if not in a system call */
  665.         if (current->it_virt_value && !(--current->it_virt_value)) {
  666.             current->it_virt_value = current->it_virt_incr;
  667.             send_sig(SIGVTALRM,current,1);
  668.         }
  669.     } else {
  670.         current->stime++;
  671.         if(current != task[0])
  672.             kstat.cpu_system++;
  673. #ifdef CONFIG_PROFILE
  674.         if (prof_buffer && current != task[0]) {
  675.             unsigned long eip = regs->eip;
  676.             eip >>= 2;
  677.             if (eip < prof_len)
  678.                 prof_buffer[eip]++;
  679.         }
  680. #endif
  681.     }
  682.     if (current == task[0] || (--current->counter)<=0) {
  683.         current->counter=0;
  684.         need_resched = 1;
  685.     }
  686.     /* Update ITIMER_PROF for the current task */
  687.     if (current->it_prof_value && !(--current->it_prof_value)) {
  688.         current->it_prof_value = current->it_prof_incr;
  689.         send_sig(SIGPROF,current,1);
  690.     }
  691.     for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
  692.         if (mask > timer_active)
  693.             break;
  694.         if (!(mask & timer_active))
  695.             continue;
  696.         if (tp->expires > jiffies)
  697.             continue;
  698.         mark_bh(TIMER_BH);
  699.     }
  700.     cli();
  701.     itimer_ticks++;
  702.     if (itimer_ticks > itimer_next)
  703.         need_resched = 1;
  704.     if (next_timer) {
  705.         if (next_timer->expires) {
  706.             next_timer->expires--;
  707.             if (!next_timer->expires)
  708.                 mark_bh(TIMER_BH);
  709.         } else {
  710.             lost_ticks++;
  711.             mark_bh(TIMER_BH);
  712.         }
  713.     }
  714.     sti();
  715. }
  716.  
  717. asmlinkage int sys_alarm(long seconds)
  718. {
  719.     struct itimerval it_new, it_old;
  720.  
  721.     it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
  722.     it_new.it_value.tv_sec = seconds;
  723.     it_new.it_value.tv_usec = 0;
  724.     _setitimer(ITIMER_REAL, &it_new, &it_old);
  725.     return(it_old.it_value.tv_sec + (it_old.it_value.tv_usec / 1000000));
  726. }
  727.  
  728. asmlinkage int sys_getpid(void)
  729. {
  730.     return current->pid;
  731. }
  732.  
  733. asmlinkage int sys_getppid(void)
  734. {
  735.     return current->p_opptr->pid;
  736. }
  737.  
  738. asmlinkage int sys_getuid(void)
  739. {
  740.     return current->uid;
  741. }
  742.  
  743. asmlinkage int sys_geteuid(void)
  744. {
  745.     return current->euid;
  746. }
  747.  
  748. asmlinkage int sys_getgid(void)
  749. {
  750.     return current->gid;
  751. }
  752.  
  753. asmlinkage int sys_getegid(void)
  754. {
  755.     return current->egid;
  756. }
  757.  
  758. asmlinkage int sys_nice(long increment)
  759. {
  760.     int newprio;
  761.  
  762.     if (increment < 0 && !suser())
  763.         return -EPERM;
  764.     newprio = current->priority - increment;
  765.     if (newprio < 1)
  766.         newprio = 1;
  767.     if (newprio > 35)
  768.         newprio = 35;
  769.     current->priority = newprio;
  770.     return 0;
  771. }
  772.  
  773. static void show_task(int nr,struct task_struct * p)
  774. {
  775.     static char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
  776.  
  777.     printk("%-8s %3d ", p->comm, (p == current) ? -nr : nr);
  778.     if (((unsigned) p->state) < sizeof(stat_nam)/sizeof(char *))
  779.         printk(stat_nam[p->state]);
  780.     else
  781.         printk(" ");
  782.     if (p == current)
  783.         printk(" current  ");
  784.     else
  785.         printk(" %08lX ", ((unsigned long *)p->tss.esp)[3]);
  786.     printk("%5lu %5d %6d ",
  787.         p->tss.esp - p->kernel_stack_page, p->pid, p->p_pptr->pid);
  788.     if (p->p_cptr)
  789.         printk("%5d ", p->p_cptr->pid);
  790.     else
  791.         printk("      ");
  792.     if (p->p_ysptr)
  793.         printk("%7d", p->p_ysptr->pid);
  794.     else
  795.         printk("       ");
  796.     if (p->p_osptr)
  797.         printk(" %5d\n", p->p_osptr->pid);
  798.     else
  799.         printk("\n");
  800. }
  801.  
  802. void show_state(void)
  803. {
  804.     int i;
  805.  
  806.     printk("                         free                        sibling\n");
  807.     printk("  task             PC    stack   pid father child younger older\n");
  808.     for (i=0 ; i<NR_TASKS ; i++)
  809.         if (task[i])
  810.             show_task(i,task[i]);
  811. }
  812.  
  813. void sched_init(void)
  814. {
  815.     int i;
  816.     struct desc_struct * p;
  817.  
  818.     bh_base[TIMER_BH].routine = timer_bh;
  819.     if (sizeof(struct sigaction) != 16)
  820.         panic("Struct sigaction MUST be 16 bytes");
  821.     set_tss_desc(gdt+FIRST_TSS_ENTRY,&init_task.tss);
  822.     set_ldt_desc(gdt+FIRST_LDT_ENTRY,&default_ldt,1);
  823.     set_system_gate(0x80,&system_call);
  824.     p = gdt+2+FIRST_TSS_ENTRY;
  825.     for(i=1 ; i<NR_TASKS ; i++) {
  826.         task[i] = NULL;
  827.         p->a=p->b=0;
  828.         p++;
  829.         p->a=p->b=0;
  830.         p++;
  831.     }
  832. /* Clear NT, so that we won't have troubles with that later on */
  833.     __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
  834.     load_TR(0);
  835.     load_ldt(0);
  836.     outb_p(0x34,0x43);        /* binary, mode 2, LSB/MSB, ch 0 */
  837.     outb_p(LATCH & 0xff , 0x40);    /* LSB */
  838.     outb(LATCH >> 8 , 0x40);    /* MSB */
  839.     if (request_irq(TIMER_IRQ,(void (*)(int)) do_timer)!=0)
  840.         panic("Could not allocate timer IRQ!");
  841. }
  842.