wait.h revision 297459
1219820Sjeff/*- 2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc. 3219820Sjeff * Copyright (c) 2010 iX Systems, Inc. 4219820Sjeff * Copyright (c) 2010 Panasas, Inc. 5270710Shselasky * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6219820Sjeff * All rights reserved. 7219820Sjeff * 8219820Sjeff * Redistribution and use in source and binary forms, with or without 9219820Sjeff * modification, are permitted provided that the following conditions 10219820Sjeff * are met: 11219820Sjeff * 1. Redistributions of source code must retain the above copyright 12219820Sjeff * notice unmodified, this list of conditions, and the following 13219820Sjeff * disclaimer. 14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 15219820Sjeff * notice, this list of conditions and the following disclaimer in the 16219820Sjeff * documentation and/or other materials provided with the distribution. 17219820Sjeff * 18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28289644Shselasky * 29289644Shselasky * $FreeBSD: head/sys/compat/linuxkpi/common/include/linux/wait.h 297459 2016-03-31 17:11:58Z np $ 30219820Sjeff */ 31219820Sjeff#ifndef _LINUX_WAIT_H_ 32219820Sjeff#define _LINUX_WAIT_H_ 33219820Sjeff 34219820Sjeff#include <linux/spinlock.h> 35219820Sjeff#include <linux/sched.h> 36219820Sjeff#include <linux/list.h> 37297459Snp#include <linux/jiffies.h> 38219820Sjeff 39219820Sjeff#include <sys/param.h> 40219820Sjeff#include <sys/systm.h> 41219820Sjeff#include <sys/sleepqueue.h> 42219820Sjeff#include <sys/kernel.h> 43219820Sjeff#include <sys/proc.h> 44219820Sjeff 45289564Shselaskytypedef struct { 46289564Shselasky} wait_queue_t; 47289564Shselasky 48289564Shselaskytypedef struct { 49219820Sjeff unsigned int wchan; 50289564Shselasky} wait_queue_head_t; 51219820Sjeff 52289564Shselasky#define init_waitqueue_head(x) \ 53289564Shselasky do { } while (0) 54219820Sjeff 55219820Sjeffstatic inline void 56289564Shselasky__wake_up(wait_queue_head_t *q, int all) 57219820Sjeff{ 58219820Sjeff int wakeup_swapper; 59219820Sjeff void *c; 60219820Sjeff 61219820Sjeff c = &q->wchan; 62219820Sjeff sleepq_lock(c); 63219820Sjeff if (all) 64219820Sjeff wakeup_swapper = sleepq_broadcast(c, SLEEPQ_SLEEP, 0, 0); 65219820Sjeff else 66219820Sjeff wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0); 67219820Sjeff sleepq_release(c); 68219820Sjeff if (wakeup_swapper) 69219820Sjeff kick_proc0(); 70219820Sjeff} 71219820Sjeff 72219820Sjeff#define wake_up(q) __wake_up(q, 0) 73219820Sjeff#define wake_up_nr(q, nr) __wake_up(q, 1) 74219820Sjeff#define wake_up_all(q) __wake_up(q, 1) 75219820Sjeff#define wake_up_interruptible(q) __wake_up(q, 0) 76219820Sjeff#define wake_up_interruptible_nr(q, nr) __wake_up(q, 1) 77219820Sjeff#define wake_up_interruptible_all(q, nr) __wake_up(q, 1) 78219820Sjeff 79219820Sjeff#define wait_event(q, cond) \ 80219820Sjeffdo { \ 81219820Sjeff void *c = &(q).wchan; \ 82219820Sjeff if (!(cond)) { \ 83219820Sjeff for (;;) { \ 84219820Sjeff sleepq_lock(c); \ 85219820Sjeff if (cond) { \ 86219820Sjeff sleepq_release(c); \ 87219820Sjeff break; \ 88219820Sjeff } \ 89219820Sjeff sleepq_add(c, NULL, "completion", SLEEPQ_SLEEP, 0); \ 90219820Sjeff sleepq_wait(c, 0); \ 91219820Sjeff } \ 92219820Sjeff } \ 93219820Sjeff} while (0) 94219820Sjeff 95219820Sjeff#define wait_event_interruptible(q, cond) \ 96219820Sjeff({ \ 97219820Sjeff void *c = &(q).wchan; \ 98219820Sjeff int _error; \ 99219820Sjeff \ 100219820Sjeff _error = 0; \ 101219820Sjeff if (!(cond)) { \ 102219820Sjeff for (; _error == 0;) { \ 103219820Sjeff sleepq_lock(c); \ 104219820Sjeff if (cond) { \ 105219820Sjeff sleepq_release(c); \ 106219820Sjeff break; \ 107219820Sjeff } \ 108219820Sjeff sleepq_add(c, NULL, "completion", \ 109219820Sjeff SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0); \ 110219820Sjeff if (sleepq_wait_sig(c, 0)) \ 111219820Sjeff _error = -ERESTARTSYS; \ 112219820Sjeff } \ 113219820Sjeff } \ 114219820Sjeff -_error; \ 115219820Sjeff}) 116219820Sjeff 117297459Snp#define wait_event_interruptible_timeout(q, cond, timeout) \ 118297459Snp({ \ 119297459Snp void *c = &(q).wchan; \ 120297459Snp long end = jiffies + timeout; \ 121297459Snp int __ret = 0; \ 122297459Snp int __rc = 0; \ 123297459Snp \ 124297459Snp if (!(cond)) { \ 125297459Snp for (; __rc == 0;) { \ 126297459Snp sleepq_lock(c); \ 127297459Snp if (cond) { \ 128297459Snp sleepq_release(c); \ 129297459Snp __ret = 1; \ 130297459Snp break; \ 131297459Snp } \ 132297459Snp sleepq_add(c, NULL, "completion", \ 133297459Snp SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0); \ 134297459Snp sleepq_set_timeout(c, linux_timer_jiffies_until(end));\ 135297459Snp __rc = sleepq_timedwait_sig (c, 0); \ 136297459Snp if (__rc != 0) { \ 137297459Snp /* check for timeout or signal. \ 138297459Snp * 0 if the condition evaluated to false\ 139297459Snp * after the timeout elapsed, 1 if the \ 140297459Snp * condition evaluated to true after the\ 141297459Snp * timeout elapsed. \ 142297459Snp */ \ 143297459Snp if (__rc == EWOULDBLOCK) \ 144297459Snp __ret = (cond); \ 145297459Snp else \ 146297459Snp __ret = -ERESTARTSYS; \ 147297459Snp } \ 148297459Snp \ 149297459Snp } \ 150297459Snp } else { \ 151297459Snp /* return remaining jiffies (at least 1) if the \ 152297459Snp * condition evaluated to true before the timeout \ 153297459Snp * elapsed. \ 154297459Snp */ \ 155297459Snp __ret = (end - jiffies); \ 156297459Snp if( __ret < 1 ) \ 157297459Snp __ret = 1; \ 158297459Snp } \ 159297459Snp __ret; \ 160297459Snp}) 161297459Snp 162297459Snp 163289564Shselaskystatic inline int 164289564Shselaskywaitqueue_active(wait_queue_head_t *q) 165289564Shselasky{ 166289564Shselasky return 0; /* XXX: not really implemented */ 167289564Shselasky} 168219820Sjeff 169289564Shselasky#define DEFINE_WAIT(name) \ 170289564Shselasky wait_queue_t name = {} 171289564Shselasky 172289564Shselaskystatic inline void 173289564Shselaskyprepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) 174289564Shselasky{ 175289564Shselasky} 176289564Shselasky 177289564Shselaskystatic inline void 178289564Shselaskyfinish_wait(wait_queue_head_t *q, wait_queue_t *wait) 179289564Shselasky{ 180289564Shselasky} 181289564Shselasky 182219820Sjeff#endif /* _LINUX_WAIT_H_ */ 183