summaryrefslogtreecommitdiff
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2002-07-23 22:17:36 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-07-23 22:17:36 -0700
commit97db62cc99a0d92650fbf23b7fbc034107eb01f3 (patch)
treea708e1efa64cb8020b108b949857358e0a1cf19b /kernel/fork.c
parent9e7cec8858f964d3be10e2f703c841cf05871e09 (diff)
[PATCH] scheduler fixes
- introduce new type of context-switch locking, this is a must-have for ia64 and sparc64. - load_balance() bug noticed by Scott Rhine and myself: scan the whole list to find imbalance number of tasks, not just the tail of the list. - sched_yield() fix: use current->array not rq->active.
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 8fbe794a5ece..020db0f0e5b9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -611,7 +611,6 @@ struct task_struct *do_fork(unsigned long clone_flags,
unsigned long stack_size)
{
int retval;
- unsigned long flags;
struct task_struct *p = NULL;
struct completion vfork;
@@ -675,6 +674,7 @@ struct task_struct *do_fork(unsigned long clone_flags,
init_completion(&vfork);
}
spin_lock_init(&p->alloc_lock);
+ spin_lock_init(&p->switch_lock);
clear_tsk_thread_flag(p,TIF_SIGPENDING);
init_sigpending(&p->pending);
@@ -740,8 +740,13 @@ struct task_struct *do_fork(unsigned long clone_flags,
* total amount of pending timeslices in the system doesnt change,
* resulting in more scheduling fairness.
*/
- local_irq_save(flags);
- p->time_slice = (current->time_slice + 1) >> 1;
+ local_irq_disable();
+ p->time_slice = (current->time_slice + 1) >> 1;
+ /*
+ * The remainder of the first timeslice might be recovered by
+ * the parent if the child exits early enough.
+ */
+ p->first_time_slice = 1;
current->time_slice >>= 1;
p->sleep_timestamp = jiffies;
if (!current->time_slice) {
@@ -753,11 +758,10 @@ struct task_struct *do_fork(unsigned long clone_flags,
current->time_slice = 1;
preempt_disable();
scheduler_tick(0, 0);
- local_irq_restore(flags);
+ local_irq_enable();
preempt_enable();
} else
- local_irq_restore(flags);
-
+ local_irq_enable();
/*
* Ok, add it to the run-queues and make it
* visible to the rest of the system.