> Date: Fri, 15 Mar 2013 15:20:34 +1100
> From: Jonathan Gray <[email protected]>
>
> The following diff changes wakeup so it will return
> the number of processes it has woken up. Mostly
> useful for debugging and error checking.
>
> I initialy had a seperate function to check for a pending
> wakeup but switched to the following after a suggestion from guenther.
I'm not terribly excited by this change. Especially since you're
doing this for what's essentially just an error path in some shitty
Linux code. I have some fears that this will get abused. In my mind
it is quite fundamental that you call wakeup() without caring whether
anybody is sleeping on the channel.
> Index: sys/sys/systm.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/systm.h,v
> retrieving revision 1.95
> diff -u -p -r1.95 systm.h
> --- sys/sys/systm.h 9 Feb 2013 20:56:35 -0000 1.95
> +++ sys/sys/systm.h 15 Mar 2013 03:14:16 -0000
> @@ -252,8 +252,8 @@ int sleep_finish_signal(struct sleep_sta
> void sleep_queue_init(void);
>
> struct mutex;
> -void wakeup_n(const volatile void *, int);
> -void wakeup(const volatile void *);
> +int wakeup_n(const volatile void *, int);
> +int wakeup(const volatile void *);
> #define wakeup_one(c) wakeup_n((c), 1)
> int tsleep(const volatile void *, int, const char *, int);
> int msleep(const volatile void *, struct mutex *, int, const char*, int);
> Index: sys/kern/kern_synch.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_synch.c,v
> retrieving revision 1.104
> diff -u -p -r1.104 kern_synch.c
> --- sys/kern/kern_synch.c 21 Aug 2012 19:51:58 -0000 1.104
> +++ sys/kern/kern_synch.c 15 Mar 2013 04:09:07 -0000
> @@ -350,13 +350,13 @@ unsleep(struct proc *p)
> /*
> * Make a number of processes sleeping on the specified identifier runnable.
> */
> -void
> +int
> wakeup_n(const volatile void *ident, int n)
> {
> struct slpque *qp;
> struct proc *p;
> struct proc *pnext;
> - int s;
> + int s, woken = 0;
>
> SCHED_LOCK(s);
> qp = &slpque[LOOKUP(ident)];
> @@ -370,20 +370,24 @@ wakeup_n(const volatile void *ident, int
> --n;
> p->p_wchan = 0;
> TAILQ_REMOVE(qp, p, p_runq);
> - if (p->p_stat == SSLEEP)
> + if (p->p_stat == SSLEEP) {
> setrunnable(p);
> + woken++;
> + }
> }
> }
> SCHED_UNLOCK(s);
> +
> + return (woken);
> }
>
> /*
> * Make all processes sleeping on the specified identifier runnable.
> */
> -void
> +int
> wakeup(const volatile void *chan)
> {
> - wakeup_n(chan, -1);
> + return (wakeup_n(chan, -1));
> }
>
> int
> Index: share/man/man9/tsleep.9
> ===================================================================
> RCS file: /cvs/src/share/man/man9/tsleep.9,v
> retrieving revision 1.6
> diff -u -p -r1.6 tsleep.9
> --- share/man/man9/tsleep.9 8 Apr 2010 00:16:28 -0000 1.6
> +++ share/man/man9/tsleep.9 15 Mar 2013 03:18:42 -0000
> @@ -43,7 +43,7 @@
> .Fn "tsleep" "void *ident" "int priority" "const char *wmesg" "int timo"
> .Ft int
> .Fn "msleep" "void *ident" "struct mutex *mtx" "int priority" "const char
> *wmesg" "int timo"
> -.Ft void
> +.Ft int
> .Fn "wakeup" "void *ident"
> .Sh DESCRIPTION
> These functions implement voluntary context switching.
> @@ -170,6 +170,8 @@ and
> otherwise.
> If they return as a result of a timeout, the return value is
> .Er EWOULDBLOCK .
> +.Fn wakeup
> +returns the number of processes that have been woken up.
> .Sh CODE REFERENCES
> These functions are implemented in the file
> .Pa sys/kern/kern_synch.c .
>
>