patch-1.3.11 linux/kernel/sched.c
Next file: linux/mm/swap.c
Previous file: linux/kernel/ksyms.c
Back to the patch index
Back to the overall index
- Lines: 177
- Date:
Mon Jul 17 17:38:34 1995
- Orig file:
v1.3.10/linux/kernel/sched.c
- Orig date:
Fri Jun 16 22:02:56 1995
diff -u --recursive --new-file v1.3.10/linux/kernel/sched.c linux/kernel/sched.c
@@ -92,8 +92,27 @@
struct kernel_stat kstat = { 0 };
-unsigned long itimer_ticks = 0;
-unsigned long itimer_next = ~0;
+/*
+ * Wake up a process. Put it on the run-queue if it's not
+ * already there. The "current" process is always on the
+ * run-queue, and as such you're allowed to do the simpler
+ * "current->state = TASK_RUNNING" to mark yourself runnable
+ * without the overhead of this.
+ *
+ * (actually, the run-queue isn't implemented yet, so this
+ * function is mostly a dummy one)
+ */
+inline void wake_up_process(struct task_struct * p)
+{
+ long oldstate;
+
+ oldstate = xchg(&p->state, TASK_RUNNING);
+ /* already on run-queue? */
+ if (oldstate == TASK_RUNNING || p == current)
+ return;
+ if (p->counter > current->counter + 3)
+ need_resched = 1;
+}
/*
* 'schedule()' is the scheduler function. It's a very simple and nice
@@ -103,16 +122,12 @@
* NOTE!! Task 0 is the 'idle' task, which gets called when no other
* tasks can run. It can not be killed, and it cannot sleep. The 'state'
* information in task[0] is never used.
- *
- * The "confuse_gcc" goto is used only to get better assembly code..
- * Dijkstra probably hates me.
*/
asmlinkage void schedule(void)
{
int c;
struct task_struct * p;
struct task_struct * next;
- unsigned long ticks;
/* check alarm, wake up any interruptible tasks that have got a signal */
@@ -121,69 +136,35 @@
intr_count = 0;
}
run_task_queue(&tq_scheduler);
- cli();
- ticks = itimer_ticks;
- itimer_ticks = 0;
- itimer_next = ~0;
- sti();
+
+ if (current->state == TASK_INTERRUPTIBLE) {
+ if (current->signal & ~current->blocked)
+ current->state = TASK_RUNNING;
+ }
need_resched = 0;
nr_running = 0;
- p = &init_task;
- for (;;) {
- if ((p = p->next_task) == &init_task)
- goto confuse_gcc1;
- if (ticks && p->it_real_value) {
- if (p->it_real_value <= ticks) {
- send_sig(SIGALRM, p, 1);
- if (!p->it_real_incr) {
- p->it_real_value = 0;
- goto end_itimer;
- }
- do {
- p->it_real_value += p->it_real_incr;
- } while (p->it_real_value <= ticks);
- }
- p->it_real_value -= ticks;
- if (p->it_real_value < itimer_next)
- itimer_next = p->it_real_value;
- }
-end_itimer:
- if (p->state != TASK_INTERRUPTIBLE)
- continue;
- if (p->signal & ~p->blocked) {
- p->state = TASK_RUNNING;
- continue;
- }
- if (p->timeout && p->timeout <= jiffies) {
- p->timeout = 0;
- p->state = TASK_RUNNING;
- }
- }
-confuse_gcc1:
/* this is the scheduler proper: */
-#if 0
- /* give processes that go to sleep a bit higher priority.. */
- /* This depends on the values for TASK_XXX */
- /* This gives smoother scheduling for some things, but */
- /* can be very unfair under some circumstances, so.. */
- if (TASK_UNINTERRUPTIBLE >= (unsigned) current->state &&
- current->counter < current->priority*2) {
- ++current->counter;
- }
-#endif
c = -1000;
- next = p = &init_task;
- for (;;) {
- if ((p = p->next_task) == &init_task)
- goto confuse_gcc2;
- if (p->state == TASK_RUNNING) {
- nr_running++;
- if (p->counter > c)
- c = p->counter, next = p;
+ next = &init_task;
+ for_each_task(p) {
+ switch (p->state) {
+ case TASK_INTERRUPTIBLE:
+ if (!p->timeout)
+ continue;
+ if (p->timeout > jiffies)
+ continue;
+ p->timeout = 0;
+ p->state = TASK_RUNNING;
+ /* fall through */
+ case TASK_RUNNING:
+ nr_running++;
+ if (p->counter > c)
+ c = p->counter, next = p;
}
}
-confuse_gcc2:
+
+ /* if all runnable processes have "counter == 0", re-calculate counters */
if (!c) {
for_each_task(p)
p->counter = (p->counter >> 1) + p->priority;
@@ -219,11 +200,8 @@
do {
if ((p = tmp->task) != NULL) {
if ((p->state == TASK_UNINTERRUPTIBLE) ||
- (p->state == TASK_INTERRUPTIBLE)) {
- p->state = TASK_RUNNING;
- if (p->counter > current->counter + 3)
- need_resched = 1;
- }
+ (p->state == TASK_INTERRUPTIBLE))
+ wake_up_process(p);
}
if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n",
@@ -246,11 +224,8 @@
return;
do {
if ((p = tmp->task) != NULL) {
- if (p->state == TASK_INTERRUPTIBLE) {
- p->state = TASK_RUNNING;
- if (p->counter > current->counter + 3)
- need_resched = 1;
- }
+ if (p->state == TASK_INTERRUPTIBLE)
+ wake_up_process(p);
}
if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n",
@@ -665,9 +640,6 @@
mark_bh(TIMER_BH);
}
cli();
- itimer_ticks++;
- if (itimer_ticks > itimer_next)
- need_resched = 1;
if (timer_head.next->expires < jiffies)
mark_bh(TIMER_BH);
if (tq_timer != &tq_last)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this