master
  1/*	$NetBSD: sleepq.h,v 1.36 2022/10/26 23:24:59 riastradh Exp $	*/
  2
  3/*-
  4 * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020
  5 *     The NetBSD Foundation, Inc.
  6 * All rights reserved.
  7 *
  8 * This code is derived from software contributed to The NetBSD Foundation
  9 * by Jason R. Thorpe and Andrew Doran.
 10 *
 11 * Redistribution and use in source and binary forms, with or without
 12 * modification, are permitted provided that the following conditions
 13 * are met:
 14 * 1. Redistributions of source code must retain the above copyright
 15 *    notice, this list of conditions and the following disclaimer.
 16 * 2. Redistributions in binary form must reproduce the above copyright
 17 *    notice, this list of conditions and the following disclaimer in the
 18 *    documentation and/or other materials provided with the distribution.
 19 *
 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 30 * POSSIBILITY OF SUCH DAMAGE.
 31 */
 32
 33#ifndef	_SYS_SLEEPQ_H_
 34#define	_SYS_SLEEPQ_H_
 35
 36#include <sys/lwp.h>
 37#include <sys/mutex.h>
 38#include <sys/pool.h>
 39#include <sys/queue.h>
 40#include <sys/sched.h>
 41#include <sys/syncobj.h>
 42#include <sys/param.h>
 43
 44/*
 45 * Generic sleep queues.
 46 */
 47
 48typedef struct sleepq sleepq_t;
 49
 50void	sleepq_init(sleepq_t *);
 51void	sleepq_remove(sleepq_t *, lwp_t *);
 52void	sleepq_enqueue(sleepq_t *, wchan_t, const char *, struct syncobj *,
 53	    bool);
 54void	sleepq_transfer(lwp_t *, sleepq_t *, sleepq_t *, wchan_t, const char *,
 55	    struct syncobj *, kmutex_t *, bool);
 56void	sleepq_uncatch(lwp_t *);
 57void	sleepq_unsleep(lwp_t *, bool);
 58void	sleepq_timeout(void *);
 59void	sleepq_wake(sleepq_t *, wchan_t, u_int, kmutex_t *);
 60int	sleepq_abort(kmutex_t *, int);
 61void	sleepq_changepri(lwp_t *, pri_t);
 62void	sleepq_lendpri(lwp_t *, pri_t);
 63int	sleepq_block(int, bool, struct syncobj *);
 64
 65#ifdef _KERNEL
 66
 67#include <sys/kernel.h>
 68
 69typedef union {
 70	kmutex_t	lock;
 71	uint8_t		pad[COHERENCY_UNIT];
 72} sleepqlock_t;
 73
 74/*
 75 * Return non-zero if it is unsafe to sleep.
 76 *
 77 * XXX This only exists because panic() is broken.
 78 */
 79static __inline bool
 80sleepq_dontsleep(lwp_t *l)
 81{
 82
 83	return cold || (doing_shutdown && (panicstr || CURCPU_IDLE_P()));
 84}
 85
 86/*
 87 * Prepare to block on a sleep queue, after which any interlock can be
 88 * safely released.
 89 */
 90static __inline void
 91sleepq_enter(sleepq_t *sq, lwp_t *l, kmutex_t *mp)
 92{
 93
 94	/*
 95	 * Acquire the per-LWP mutex and lend it ours sleep queue lock.
 96	 * Once interlocked, we can release the kernel lock.
 97	 */
 98	lwp_lock(l);
 99	lwp_unlock_to(l, mp);
100	KERNEL_UNLOCK_ALL(NULL, &l->l_biglocks);
101}
102
103#endif
104
105#include <sys/sleeptab.h>
106
107#endif	/* _SYS_SLEEPQ_H_ */