wait.h revision 300671
1156Srgrimes/*-
250472Speter * Copyright (c) 2010 Isilon Systems, Inc.
374462Salfred * Copyright (c) 2010 iX Systems, Inc.
4156Srgrimes * Copyright (c) 2010 Panasas, Inc.
574462Salfred * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6156Srgrimes * All rights reserved.
7156Srgrimes *
8156Srgrimes * Redistribution and use in source and binary forms, with or without
9156Srgrimes * modification, are permitted provided that the following conditions
10156Srgrimes * are met:
11156Srgrimes * 1. Redistributions of source code must retain the above copyright
12156Srgrimes *    notice unmodified, this list of conditions, and the following
13156Srgrimes *    disclaimer.
14156Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
15156Srgrimes *    notice, this list of conditions and the following disclaimer in the
16156Srgrimes *    documentation and/or other materials provided with the distribution.
17156Srgrimes *
18156Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19156Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20156Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21156Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22156Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23156Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24156Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25156Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26156Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27156Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28156Srgrimes *
2925815Sjkh * $FreeBSD: head/sys/compat/linuxkpi/common/include/linux/wait.h 300671 2016-05-25 09:04:06Z hselasky $
30156Srgrimes */
31156Srgrimes#ifndef	_LINUX_WAIT_H_
3274462Salfred#define	_LINUX_WAIT_H_
33156Srgrimes
34156Srgrimes#include <linux/compiler.h>
35156Srgrimes#include <linux/spinlock.h>
3674462Salfred#include <linux/sched.h>
3774462Salfred#include <linux/list.h>
3874462Salfred#include <linux/jiffies.h>
3974462Salfred
4074462Salfred#include <sys/param.h>
4174462Salfred#include <sys/systm.h>
4274462Salfred#include <sys/sleepqueue.h>
4374462Salfred#include <sys/kernel.h>
4474462Salfred#include <sys/proc.h>
4574462Salfred
4674462Salfredtypedef struct {
4774462Salfred} wait_queue_t;
4874462Salfred
4974462Salfredtypedef struct {
5074462Salfred	unsigned int	wchan;
5174462Salfred} wait_queue_head_t;
5274462Salfred
5374462Salfred#define	init_waitqueue_head(x) \
5474462Salfred    do { } while (0)
5574462Salfred
5674462Salfredstatic inline void
5774462Salfred__wake_up(wait_queue_head_t *q, int all)
5874462Salfred{
5974462Salfred	int wakeup_swapper;
6074462Salfred	void *c;
6174462Salfred
6274462Salfred	c = &q->wchan;
6374462Salfred	sleepq_lock(c);
6474462Salfred	if (all)
6574462Salfred		wakeup_swapper = sleepq_broadcast(c, SLEEPQ_SLEEP, 0, 0);
66460Srgrimes	else
6715041Sjoerg		wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0);
68	sleepq_release(c);
69	if (wakeup_swapper)
70		kick_proc0();
71}
72
73#define	wake_up(q)				__wake_up(q, 0)
74#define	wake_up_nr(q, nr)			__wake_up(q, 1)
75#define	wake_up_all(q)				__wake_up(q, 1)
76#define	wake_up_interruptible(q)		__wake_up(q, 0)
77#define	wake_up_interruptible_nr(q, nr)		__wake_up(q, 1)
78#define	wake_up_interruptible_all(q, nr)	__wake_up(q, 1)
79
80#define	wait_event(q, cond)						\
81do {									\
82	void *c = &(q).wchan;						\
83	if (!(cond)) {							\
84		for (;;) {						\
85			if (unlikely(SCHEDULER_STOPPED()))		\
86				break;					\
87			sleepq_lock(c);					\
88			if (cond) {					\
89				sleepq_release(c);			\
90				break;					\
91			}						\
92			sleepq_add(c, NULL, "completion", SLEEPQ_SLEEP, 0); \
93			sleepq_wait(c, 0);				\
94		}							\
95	}								\
96} while (0)
97
98#define	wait_event_interruptible(q, cond)				\
99({									\
100	void *c = &(q).wchan;						\
101	int _error;							\
102									\
103	_error = 0;							\
104	if (!(cond)) {							\
105		for (; _error == 0;) {					\
106			if (unlikely(SCHEDULER_STOPPED()))		\
107				break;					\
108			sleepq_lock(c);					\
109			if (cond) {					\
110				sleepq_release(c);			\
111				break;					\
112			}						\
113			sleepq_add(c, NULL, "completion",		\
114			    SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0);	\
115			if (sleepq_wait_sig(c, 0))			\
116				_error = -ERESTARTSYS;			\
117		}							\
118	}								\
119	-_error;							\
120})
121
122#define	wait_event_interruptible_timeout(q, cond, timeout)		\
123({									\
124	void *c = &(q).wchan;						\
125	long end = jiffies + timeout;					\
126	int __ret = 0;	 						\
127	int __rc = 0;							\
128									\
129	if (!(cond)) {							\
130		for (; __rc == 0;) {					\
131			if (unlikely(SCHEDULER_STOPPED()))		\
132				break;					\
133			sleepq_lock(c);					\
134			if (cond) {					\
135				sleepq_release(c);			\
136				__ret = 1;				\
137				break;					\
138			}						\
139			sleepq_add(c, NULL, "completion",		\
140			SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0);	\
141			sleepq_set_timeout(c, linux_timer_jiffies_until(end));\
142			__rc = sleepq_timedwait_sig (c, 0);		\
143			if (__rc != 0) {				\
144				/* check for timeout or signal. 	\
145				 * 0 if the condition evaluated to false\
146				 * after the timeout elapsed,  1 if the \
147				 * condition evaluated to true after the\
148				 * timeout elapsed.			\
149				 */					\
150				if (__rc == EWOULDBLOCK)		\
151					__ret = (cond);			\
152				 else					\
153					__ret = -ERESTARTSYS;		\
154			}						\
155									\
156		}							\
157	} else {							\
158		/* return remaining jiffies (at least 1) if the 	\
159		 * condition evaluated to true before the timeout	\
160		 * elapsed.						\
161		 */							\
162		__ret = (end - jiffies);				\
163		if( __ret < 1 )						\
164			__ret = 1;					\
165	}								\
166	__ret;								\
167})
168
169
170static inline int
171waitqueue_active(wait_queue_head_t *q)
172{
173	return 0;	/* XXX: not really implemented */
174}
175
176#define DEFINE_WAIT(name)	\
177	wait_queue_t name = {}
178
179static inline void
180prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
181{
182}
183
184static inline void
185finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
186{
187}
188
189#endif	/* _LINUX_WAIT_H_ */
190