From b336a9b1ad4279bb6b18989a94ed641ddf9b456d Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 14 Apr 2006 01:00:16 +0000 Subject: [PATCH] Supply version of wakeup() which only operate on threads blocked on the same cpu, or on a particular cpu. --- sys/kern/kern_synch.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-- sys/sys/param.h | 5 ++-- sys/sys/systm.h | 7 ++++-- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index a272c822c8..3d51ff994f 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -37,7 +37,7 @@ * * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 * $FreeBSD: src/sys/kern/kern_synch.c,v 1.87.2.6 2002/10/13 07:29:53 kbyanc Exp $ - * $DragonFly: src/sys/kern/kern_synch.c,v 1.57 2005/12/10 18:27:24 dillon Exp $ + * $DragonFly: src/sys/kern/kern_synch.c,v 1.58 2006/04/14 01:00:15 dillon Exp $ */ #include "opt_ktrace.h" @@ -654,7 +654,9 @@ restart: * should be ok since we are passing idents in the IPI rather then * thread pointers. */ - if ((mask = slpque_cpumasks[id]) != 0) { + if ((domain & PWAKEUP_MYCPU) == 0 && + (mask = slpque_cpumasks[id]) != 0 + ) { /* * Look for a cpu that might have work to do. Mask out cpus * which have already been processed. @@ -715,12 +717,18 @@ done: crit_exit(); } +/* + * Wakeup all threads tsleep()ing on the specified ident, on all cpus + */ void wakeup(void *ident) { _wakeup(ident, PWAKEUP_ENCODE(0, mycpu->gd_cpuid)); } +/* + * Wakeup one thread tsleep()ing on the specified ident, on any cpu. + */ void wakeup_one(void *ident) { @@ -728,12 +736,69 @@ wakeup_one(void *ident) _wakeup(ident, PWAKEUP_ENCODE(0, mycpu->gd_cpuid) | PWAKEUP_ONE); } +/* + * Wakeup threads tsleep()ing on the specified ident on the current cpu + * only. + */ +void +wakeup_mycpu(void *ident) +{ + _wakeup(ident, PWAKEUP_MYCPU); +} + +/* + * Wakeup one thread tsleep()ing on the specified ident on the current cpu + * only. + */ +void +wakeup_mycpu_one(void *ident) +{ + /* XXX potentially round-robin the first responding cpu */ + _wakeup(ident, PWAKEUP_MYCPU|PWAKEUP_ONE); +} + +/* + * Wakeup all thread tsleep()ing on the specified ident on the specified cpu + * only. + */ +void +wakeup_oncpu(globaldata_t gd, void *ident) +{ + if (gd == mycpu) { + _wakeup(ident, PWAKEUP_MYCPU); + } else { + lwkt_send_ipiq2(gd, _wakeup, ident, PWAKEUP_MYCPU); + } +} + +/* + * Wakeup one thread tsleep()ing on the specified ident on the specified cpu + * only. + */ +void +wakeup_oncpu_one(globaldata_t gd, void *ident) +{ + if (gd == mycpu) { + _wakeup(ident, PWAKEUP_MYCPU | PWAKEUP_ONE); + } else { + lwkt_send_ipiq2(gd, _wakeup, ident, PWAKEUP_MYCPU | PWAKEUP_ONE); + } +} + +/* + * Wakeup all threads waiting on the specified ident that slept using + * the specified domain, on all cpus. + */ void wakeup_domain(void *ident, int domain) { _wakeup(ident, PWAKEUP_ENCODE(domain, mycpu->gd_cpuid)); } +/* + * Wakeup one thread waiting on the specified ident that slept using + * the specified domain, on any cpu. + */ void wakeup_domain_one(void *ident, int domain) { diff --git a/sys/sys/param.h b/sys/sys/param.h index 6db2cdfdec..1e1b36a845 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -37,7 +37,7 @@ * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD: src/sys/sys/param.h,v 1.61.2.38 2003/05/22 17:12:01 fjoe Exp $ - * $DragonFly: src/sys/sys/param.h,v 1.31 2005/12/23 19:10:54 dillon Exp $ + * $DragonFly: src/sys/sys/param.h,v 1.32 2006/04/14 01:00:16 dillon Exp $ */ #ifndef _SYS_PARAM_H_ @@ -118,8 +118,9 @@ #define PCATCH 0x00000100 /* tsleep checks signals */ #define PUSRFLAG1 0x00000200 /* Subsystem specific flag */ #define PNORESCHED 0x00000400 /* No reschedule on wakeup */ +#define PWAKEUP_CPUMASK 0x00003FFF /* start cpu for chained wakeups */ +#define PWAKEUP_MYCPU 0x00004000 /* wakeup on current cpu only */ #define PWAKEUP_ONE 0x00008000 /* argument to wakeup: only one */ -#define PWAKEUP_CPUMASK 0x00007FFF /* (argument passed to wakeup) */ #define PDOMAIN_MASK 0xFFFF0000 /* address domains for wakeup */ #define PDOMAIN_UMTX 0x00010000 /* independant domain for UMTX */ #define PWAKEUP_ENCODE(domain, cpu) ((domain) | (cpu)) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 87b92cab90..824d0ffb54 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -37,7 +37,7 @@ * * @(#)systm.h 8.7 (Berkeley) 3/29/95 * $FreeBSD: src/sys/sys/systm.h,v 1.111.2.18 2002/12/17 18:04:02 sam Exp $ - * $DragonFly: src/sys/sys/systm.h,v 1.35 2006/03/12 20:44:43 dillon Exp $ + * $DragonFly: src/sys/sys/systm.h,v 1.36 2006/04/14 01:00:16 dillon Exp $ */ #ifndef _SYS_SYSTM_H_ @@ -301,9 +301,12 @@ void tsleep_interlock (void *chan); void tstop (struct proc *); void wakeup (void *chan); void wakeup_one (void *chan); +void wakeup_mycpu (void *chan); +void wakeup_mycpu_one (void *chan); +void wakeup_oncpu (struct globaldata *gd, void *chan); +void wakeup_oncpu_one (struct globaldata *gd, void *chan); void wakeup_domain (void *chan, int domain); void wakeup_domain_one (void *chan, int domain); -void wakeup_oncpu (void *, int, int); /* * Common `dev_t' stuff are declared here to avoid #include poisoning -- 2.11.4.GIT