summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-03-12 06:58:49 +0000
committermav <mav@FreeBSD.org>2013-03-12 06:58:49 +0000
commitca616198e5ffd9e04aa3190d1c3ff9b78383b083 (patch)
tree95fcd091ce327eb126b36b8374f04bc80e63216f /sys/kern/kern_synch.c
parent9b31bc755831124ab769b7338fe5d4d1e21f20bf (diff)
downloadFreeBSD-src-ca616198e5ffd9e04aa3190d1c3ff9b78383b083.zip
FreeBSD-src-ca616198e5ffd9e04aa3190d1c3ff9b78383b083.tar.gz
Make kern_nanosleep() and pause_sbt() to use per-CPU sleep queues.
This removes significant sleep queue lock congestion on multithreaded microbenchmarks, making them scale to multiple CPUs almost linearly.
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 5aae8d8..81471ca 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -85,7 +85,7 @@ SYSINIT(synch_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, synch_setup,
NULL);
int hogticks;
-static int pause_wchan;
+static uint8_t pause_wchan[MAXCPU];
static struct callout loadav_callout;
@@ -198,7 +198,8 @@ _sleep(void *ident, struct lock_object *lock, int priority,
if (TD_ON_SLEEPQ(td))
sleepq_remove(td, td->td_wchan);
- if (ident == &pause_wchan)
+ if ((uint8_t *)ident >= &pause_wchan[0] &&
+ (uint8_t *)ident <= &pause_wchan[MAXCPU - 1])
sleepq_flags = SLEEPQ_PAUSE;
else
sleepq_flags = SLEEPQ_SLEEP;
@@ -372,7 +373,7 @@ pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags)
DELAY((sbt & 0xffffffff) / SBT_1US);
return (0);
}
- return (_sleep(&pause_wchan, NULL, 0, wmesg, sbt, pr, flags));
+ return (_sleep(&pause_wchan[curcpu], NULL, 0, wmesg, sbt, pr, flags));
}
/*
OpenPOWER on IntegriCloud