summaryrefslogtreecommitdiff
path: root/sys/kern/sched_bsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/sched_bsd.c')
-rw-r--r--sys/kern/sched_bsd.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c
index 523e240a4b1..ff39ea3d1ad 100644
--- a/sys/kern/sched_bsd.c
+++ b/sys/kern/sched_bsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched_bsd.c,v 1.1 2004/07/29 06:25:45 tedu Exp $ */
+/* $OpenBSD: sched_bsd.c,v 1.2 2005/05/25 23:17:47 niklas Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*-
@@ -65,7 +65,9 @@ int rrticks_init; /* # of hardclock ticks per roundrobin() */
int whichqs; /* Bit mask summary of non-empty Q's. */
struct prochd qs[NQS];
-struct SIMPLELOCK sched_lock;
+#ifdef MULTIPROCESSOR
+struct mutex sched_mutex = MUTEX_INITIALIZER(IPL_SCHED);
+#endif
void scheduler_start(void);
@@ -260,7 +262,7 @@ schedcpu(arg)
struct timeout *to = (struct timeout *)arg;
fixpt_t loadfac = loadfactor(averunnable.ldavg[0]);
struct proc *p;
- int s;
+ int s, t;
unsigned int newcpu;
int phz;
@@ -274,6 +276,7 @@ schedcpu(arg)
KASSERT(phz);
for (p = LIST_FIRST(&allproc); p != 0; p = LIST_NEXT(p, p_list)) {
+ SCHED_LOCK(s);
/*
* Increment time in/out of memory and sleep time
* (if sleeping). We ignore overflow; with 16-bit int's
@@ -287,9 +290,11 @@ schedcpu(arg)
* If the process has slept the entire second,
* stop recalculating its priority until it wakes up.
*/
- if (p->p_slptime > 1)
+ if (p->p_slptime > 1) {
+ SCHED_UNLOCK(s);
continue;
- s = splstatclock(); /* prevent state changes */
+ }
+ t = splstatclock();
/*
* p_pctcpu is only for ps.
*/
@@ -305,8 +310,7 @@ schedcpu(arg)
p->p_cpticks = 0;
newcpu = (u_int) decay_cpu(loadfac, p->p_estcpu);
p->p_estcpu = newcpu;
- splx(s);
- SCHED_LOCK(s);
+ splx(t);
resetpriority(p);
if (p->p_priority >= PUSER) {
if ((p != curproc) &&
@@ -355,13 +359,13 @@ updatepri(p)
void
sched_unlock_idle(void)
{
- SIMPLE_UNLOCK(&sched_lock);
+ mtx_leave(&sched_mutex);
}
void
sched_lock_idle(void)
{
- SIMPLE_LOCK(&sched_lock);
+ mtx_enter(&sched_mutex);
}
#endif /* MULTIPROCESSOR || LOCKDEBUG */
@@ -379,9 +383,7 @@ yield()
p->p_priority = p->p_usrpri;
setrunqueue(p);
p->p_stats->p_ru.ru_nvcsw++;
- mi_switch();
- SCHED_ASSERT_UNLOCKED();
- splx(s);
+ mi_switch(s);
}
/*
@@ -408,19 +410,17 @@ preempt(newp)
p->p_stat = SRUN;
setrunqueue(p);
p->p_stats->p_ru.ru_nivcsw++;
- mi_switch();
- SCHED_ASSERT_UNLOCKED();
- splx(s);
+ mi_switch(s);
}
/*
- * Must be called at splstatclock() or higher.
+ * Must be called at splsched() or higher.
*/
void
-mi_switch()
+mi_switch(int s)
{
- struct proc *p = curproc; /* XXX */
+ struct proc *p = curproc;
struct rlimit *rlim;
struct timeval tv;
#if defined(MULTIPROCESSOR)
@@ -432,20 +432,6 @@ mi_switch()
SCHED_ASSERT_LOCKED();
-#if defined(MULTIPROCESSOR)
- /*
- * Release the kernel_lock, as we are about to yield the CPU.
- * The scheduler lock is still held until cpu_switch()
- * selects a new process and removes it from the run queue.
- */
- if (p->p_flag & P_BIGLOCK)
-#ifdef notyet
- hold_count = spinlock_release_all(&kernel_lock);
-#else
- hold_count = __mp_release_all(&kernel_lock);
-#endif
-#endif
-
/*
* Compute the amount of time during which the current
* process was running, and add that to its total so far.
@@ -483,6 +469,7 @@ mi_switch()
*/
rlim = &p->p_rlimit[RLIMIT_CPU];
if ((rlim_t)p->p_rtime.tv_sec >= rlim->rlim_cur) {
+ SCHED_UNLOCK(s);
if ((rlim_t)p->p_rtime.tv_sec >= rlim->rlim_max) {
psignal(p, SIGKILL);
} else {
@@ -490,8 +477,23 @@ mi_switch()
if (rlim->rlim_cur < rlim->rlim_max)
rlim->rlim_cur += 5;
}
+ SCHED_LOCK(s);
}
+#if defined(MULTIPROCESSOR)
+ /*
+ * Release the kernel_lock, as we are about to yield the CPU.
+ * The scheduler lock is still held until cpu_switch()
+ * selects a new process and removes it from the run queue.
+ */
+ if (p->p_flag & P_BIGLOCK)
+#ifdef notyet
+ hold_count = spinlock_release_all(&kernel_lock);
+#else
+ hold_count = __mp_release_all(&kernel_lock);
+#endif
+#endif
+
/*
* Process is about to yield the CPU; clear the appropriate
* scheduling flags.
@@ -534,12 +536,9 @@ mi_switch()
* we reacquire the interlock.
*/
if (p->p_flag & P_BIGLOCK)
-#ifdef notyet
- spinlock_acquire_count(&kernel_lock, hold_count);
-#else
__mp_acquire_count(&kernel_lock, hold_count);
#endif
-#endif
+ splx(s);
}
/*
@@ -553,7 +552,6 @@ rqinit()
for (i = 0; i < NQS; i++)
qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
- SIMPLE_LOCK_INIT(&sched_lock);
}
static __inline void
@@ -601,8 +599,7 @@ resched_proc(struct proc *p, u_char pri)
* and awakening the swapper if it isn't in memory.
*/
void
-setrunnable(p)
- register struct proc *p;
+setrunnable(struct proc *p)
{
SCHED_ASSERT_LOCKED();
@@ -634,7 +631,7 @@ setrunnable(p)
updatepri(p);
p->p_slptime = 0;
if ((p->p_flag & P_INMEM) == 0)
- wakeup((caddr_t)&proc0);
+ sched_wakeup((caddr_t)&proc0);
else
resched_proc(p, p->p_priority);
}
@@ -679,10 +676,10 @@ schedclock(p)
{
int s;
- p->p_estcpu = ESTCPULIM(p->p_estcpu + 1);
SCHED_LOCK(s);
+ p->p_estcpu = ESTCPULIM(p->p_estcpu + 1);
resetpriority(p);
- SCHED_UNLOCK(s);
if (p->p_priority >= PUSER)
p->p_priority = p->p_usrpri;
+ SCHED_UNLOCK(s);
}