code:
/*-
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)queue.h	8.5 (Berkeley) 8/20/94
 * $FreeBSD: release/9.0.0/sys/sys/queue.h 221843 2011-05-13 15:49:23Z mdf $
 */

#ifndef _SYS_QUEUE_H_
#define	_SYS_QUEUE_H_

#include <sys/cdefs.h>

/*
 * This file defines four types of data structures: singly-linked lists,
 * singly-linked tail queues, lists and tail queues.
 *
 * A singly-linked list is headed by a single forward pointer. The elements
 * are singly linked for minimum space and pointer manipulation overhead at
 * the expense of O(n) removal for arbitrary elements. New elements can be
 * added to the list after an existing element or at the head of the list.
 * Elements being removed from the head of the list should use the explicit
 * macro for this purpose for optimum efficiency. A singly-linked list may
 * only be traversed in the forward direction.  Singly-linked lists are ideal
 * for applications with large datasets and few or no removals or for
 * implementing a LIFO queue.
 *
 * A singly-linked tail queue is headed by a pair of pointers, one to the
 * head of the list and the other to the tail of the list. The elements are
 * singly linked for minimum space and pointer manipulation overhead at the
 * expense of O(n) removal for arbitrary elements. New elements can be added
 * to the list after an existing element, at the head of the list, or at the
 * end of the list. Elements being removed from the head of the tail queue
 * should use the explicit macro for this purpose for optimum efficiency.
 * A singly-linked tail queue may only be traversed in the forward direction.
 * Singly-linked tail queues are ideal for applications with large datasets
 * and few or no removals or for implementing a FIFO queue.
 *
 * A list is headed by a single forward pointer (or an array of forward
 * pointers for a hash table header). The elements are doubly linked
 * so that an arbitrary element can be removed without a need to
 * traverse the list. New elements can be added to the list before
 * or after an existing element or at the head of the list. A list
 * may only be traversed in the forward direction.
 *
 * A tail queue is headed by a pair of pointers, one to the head of the
 * list and the other to the tail of the list. The elements are doubly
 * linked so that an arbitrary element can be removed without a need to
 * traverse the list. New elements can be added to the list before or
 * after an existing element, at the head of the list, or at the end of
 * the list. A tail queue may be traversed in either direction.
 *
 * For details on the use of these macros, see the queue(3) manual page.
 *
 *
 *				SLIST	LIST	STAILQ	TAILQ
 * _HEAD			+	+	+	+
 * _HEAD_INITIALIZER		+	+	+	+
 * _ENTRY			+	+	+	+
 * _INIT			+	+	+	+
 * _EMPTY			+	+	+	+
 * _FIRST			+	+	+	+
 * _NEXT			+	+	+	+
 * _PREV			-	-	-	+
 * _LAST			-	-	+	+
 * _FOREACH			+	+	+	+
 * _FOREACH_SAFE		+	+	+	+
 * _FOREACH_REVERSE		-	-	-	+
 * _FOREACH_REVERSE_SAFE	-	-	-	+
 * _INSERT_HEAD			+	+	+	+
 * _INSERT_BEFORE		-	+	-	+
 * _INSERT_AFTER		+	+	+	+
 * _INSERT_TAIL			-	-	+	+
 * _CONCAT			-	-	+	+
 * _REMOVE_AFTER		+	-	+	-
 * _REMOVE_HEAD			+	-	+	-
 * _REMOVE			+	+	+	+
 * _SWAP			+	+	+	+
 *
 */
#ifdef QUEUE_MACRO_DEBUG
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
	char * lastfile;
	int lastline;
	char * prevfile;
	int prevline;
};

#define	TRACEBUF	struct qm_trace trace;
#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
#define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)

#define	QMD_TRACE_HEAD(head) do {					\
	(head)->trace.prevline = (head)->trace.lastline;		\
	(head)->trace.prevfile = (head)->trace.lastfile;		\
	(head)->trace.lastline = __LINE__;				\
	(head)->trace.lastfile = __FILE__;				\
} while (0)

#define	QMD_TRACE_ELEM(elem) do {					\
	(elem)->trace.prevline = (elem)->trace.lastline;		\
	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
	(elem)->trace.lastline = __LINE__;				\
	(elem)->trace.lastfile = __FILE__;				\
} while (0)

#else
#define	QMD_TRACE_ELEM(elem)
#define	QMD_TRACE_HEAD(head)
#define	QMD_SAVELINK(name, link)
#define	TRACEBUF
#define	TRASHIT(x)
#endif	/* QUEUE_MACRO_DEBUG */

/*
 * Singly-linked List declarations.
 */
#define	SLIST_HEAD(name, type)						\
struct name {								\
	struct type *slh_first;	/* first element */			\
}

#define	SLIST_HEAD_INITIALIZER(head)					\
	{ NULL }

#define	SLIST_ENTRY(type)						\
struct {								\
	struct type *sle_next;	/* next element */			\
}

/*
 * Singly-linked List functions.
 */
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)

#define	SLIST_FIRST(head)	((head)->slh_first)

#define	SLIST_FOREACH(var, head, field)					\
	for ((var) = SLIST_FIRST((head));				\
	    (var);							\
	    (var) = SLIST_NEXT((var), field))

#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = SLIST_FIRST((head));				\
	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
	    (var) = (tvar))

#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
	for ((varp) = &SLIST_FIRST((head));				\
	    ((var) = *(varp)) != NULL;					\
	    (varp) = &SLIST_NEXT((var), field))

#define	SLIST_INIT(head) do {						\
	SLIST_FIRST((head)) = NULL;					\
} while (0)

#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
	SLIST_NEXT((slistelm), field) = (elm);				\
} while (0)

#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
	SLIST_FIRST((head)) = (elm);					\
} while (0)

#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)

#define	SLIST_REMOVE(head, elm, type, field) do {			\
	QMD_SAVELINK(oldnext, (elm)->field.sle_next);			\
	if (SLIST_FIRST((head)) == (elm)) {				\
		SLIST_REMOVE_HEAD((head), field);			\
	}								\
	else {								\
		struct type *curelm = SLIST_FIRST((head));		\
		while (SLIST_NEXT(curelm, field) != (elm))		\
			curelm = SLIST_NEXT(curelm, field);		\
		SLIST_REMOVE_AFTER(curelm, field);			\
	}								\
	TRASHIT(*oldnext);						\
} while (0)

#define SLIST_REMOVE_AFTER(elm, field) do {				\
	SLIST_NEXT(elm, field) =					\
	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
} while (0)

#define	SLIST_REMOVE_HEAD(head, field) do {				\
	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
} while (0)

#define SLIST_SWAP(head1, head2, type) do {				\
	struct type *swap_first = SLIST_FIRST(head1);			\
	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
	SLIST_FIRST(head2) = swap_first;				\
} while (0)

/*
 * Singly-linked Tail queue declarations.
 */
#define	STAILQ_HEAD(name, type)						\
struct name {								\
	struct type *stqh_first;/* first element */			\
	struct type **stqh_last;/* addr of last next element */		\
}

#define	STAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).stqh_first }

#define	STAILQ_ENTRY(type)						\
struct {								\
	struct type *stqe_next;	/* next element */			\
}

/*
 * Singly-linked Tail queue functions.
 */
#define	STAILQ_CONCAT(head1, head2) do {				\
	if (!STAILQ_EMPTY((head2))) {					\
		*(head1)->stqh_last = (head2)->stqh_first;		\
		(head1)->stqh_last = (head2)->stqh_last;		\
		STAILQ_INIT((head2));					\
	}								\
} while (0)

#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)

#define	STAILQ_FIRST(head)	((head)->stqh_first)

#define	STAILQ_FOREACH(var, head, field)				\
	for((var) = STAILQ_FIRST((head));				\
	   (var);							\
	   (var) = STAILQ_NEXT((var), field))

#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = STAILQ_FIRST((head));				\
	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
	    (var) = (tvar))

#define	STAILQ_INIT(head) do {						\
	STAILQ_FIRST((head)) = NULL;					\
	(head)->stqh_last = &STAILQ_FIRST((head));			\
} while (0)

#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
	STAILQ_NEXT((tqelm), field) = (elm);				\
} while (0)

#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
	STAILQ_FIRST((head)) = (elm);					\
} while (0)

#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
	STAILQ_NEXT((elm), field) = NULL;				\
	*(head)->stqh_last = (elm);					\
	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
} while (0)

#define	STAILQ_LAST(head, type, field)					\
	(STAILQ_EMPTY((head)) ?						\
		NULL :							\
	        ((struct type *)(void *)				\
		((char *)((head)->stqh_last) - __offsetof(struct type, field))))

#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)

#define	STAILQ_REMOVE(head, elm, type, field) do {			\
	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
	if (STAILQ_FIRST((head)) == (elm)) {				\
		STAILQ_REMOVE_HEAD((head), field);			\
	}								\
	else {								\
		struct type *curelm = STAILQ_FIRST((head));		\
		while (STAILQ_NEXT(curelm, field) != (elm))		\
			curelm = STAILQ_NEXT(curelm, field);		\
		STAILQ_REMOVE_AFTER(head, curelm, field);		\
	}								\
	TRASHIT(*oldnext);						\
} while (0)

#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
	if ((STAILQ_NEXT(elm, field) =					\
	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
} while (0)

#define	STAILQ_REMOVE_HEAD(head, field) do {				\
	if ((STAILQ_FIRST((head)) =					\
	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
		(head)->stqh_last = &STAILQ_FIRST((head));		\
} while (0)

#define STAILQ_SWAP(head1, head2, type) do {				\
	struct type *swap_first = STAILQ_FIRST(head1);			\
	struct type **swap_last = (head1)->stqh_last;			\
	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
	(head1)->stqh_last = (head2)->stqh_last;			\
	STAILQ_FIRST(head2) = swap_first;				\
	(head2)->stqh_last = swap_last;					\
	if (STAILQ_EMPTY(head1))					\
		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
	if (STAILQ_EMPTY(head2))					\
		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
} while (0)

/*
 * List declarations.
 */
#define	LIST_HEAD(name, type)						\
struct name {								\
	struct type *lh_first;	/* first element */			\
}

#define	LIST_HEAD_INITIALIZER(head)					\
	{ NULL }

#define	LIST_ENTRY(type)						\
struct {								\
	struct type *le_next;	/* next element */			\
	struct type **le_prev;	/* address of previous next element */	\
}

/*
 * List functions.
 */

#if (defined(_KERNEL) && defined(INVARIANTS))
#define	QMD_LIST_CHECK_HEAD(head, field) do {				\
	if (LIST_FIRST((head)) != NULL &&				\
	    LIST_FIRST((head))->field.le_prev !=			\
	     &LIST_FIRST((head)))					\
		panic("Bad list head %p first->prev != head", (head));	\
} while (0)

#define	QMD_LIST_CHECK_NEXT(elm, field) do {				\
	if (LIST_NEXT((elm), field) != NULL &&				\
	    LIST_NEXT((elm), field)->field.le_prev !=			\
	     &((elm)->field.le_next))					\
	     	panic("Bad link elm %p next->prev != elm", (elm));	\
} while (0)

#define	QMD_LIST_CHECK_PREV(elm, field) do {				\
	if (*(elm)->field.le_prev != (elm))				\
		panic("Bad link elm %p prev->next != elm", (elm));	\
} while (0)
#else
#define	QMD_LIST_CHECK_HEAD(head, field)
#define	QMD_LIST_CHECK_NEXT(elm, field)
#define	QMD_LIST_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */

#define	LIST_EMPTY(head)	((head)->lh_first == NULL)

#define	LIST_FIRST(head)	((head)->lh_first)

#define	LIST_FOREACH(var, head, field)					\
	for ((var) = LIST_FIRST((head));				\
	    (var);							\
	    (var) = LIST_NEXT((var), field))

#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = LIST_FIRST((head));				\
	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
	    (var) = (tvar))

#define	LIST_INIT(head) do {						\
	LIST_FIRST((head)) = NULL;					\
} while (0)

#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
	QMD_LIST_CHECK_NEXT(listelm, field);				\
	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
		LIST_NEXT((listelm), field)->field.le_prev =		\
		    &LIST_NEXT((elm), field);				\
	LIST_NEXT((listelm), field) = (elm);				\
	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
} while (0)

#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
	QMD_LIST_CHECK_PREV(listelm, field);				\
	(elm)->field.le_prev = (listelm)->field.le_prev;		\
	LIST_NEXT((elm), field) = (listelm);				\
	*(listelm)->field.le_prev = (elm);				\
	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
} while (0)

#define	LIST_INSERT_HEAD(head, elm, field) do {				\
	QMD_LIST_CHECK_HEAD((head), field);				\
	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
	LIST_FIRST((head)) = (elm);					\
	(elm)->field.le_prev = &LIST_FIRST((head));			\
} while (0)

#define	LIST_NEXT(elm, field)	((elm)->field.le_next)

#define	LIST_REMOVE(elm, field) do {					\
	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
	QMD_LIST_CHECK_NEXT(elm, field);				\
	QMD_LIST_CHECK_PREV(elm, field);				\
	if (LIST_NEXT((elm), field) != NULL)				\
		LIST_NEXT((elm), field)->field.le_prev = 		\
		    (elm)->field.le_prev;				\
	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
	TRASHIT(*oldnext);						\
	TRASHIT(*oldprev);						\
} while (0)

#define LIST_SWAP(head1, head2, type, field) do {			\
	struct type *swap_tmp = LIST_FIRST((head1));			\
	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
	LIST_FIRST((head2)) = swap_tmp;					\
	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
		swap_tmp->field.le_prev = &LIST_FIRST((head1));		\
	if ((swap_tmp = LIST_FIRST((head2))) != NULL)			\
		swap_tmp->field.le_prev = &LIST_FIRST((head2));		\
} while (0)

/*
 * Tail queue declarations.
 */
#define	TAILQ_HEAD(name, type)						\
struct name {								\
	struct type *tqh_first;	/* first element */			\
	struct type **tqh_last;	/* addr of last next element */		\
	TRACEBUF							\
}

#define	TAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).tqh_first }

#define	TAILQ_ENTRY(type)						\
struct {								\
	struct type *tqe_next;	/* next element */			\
	struct type **tqe_prev;	/* address of previous next element */	\
	TRACEBUF							\
}

/*
 * Tail queue functions.
 */
#if (defined(_KERNEL) && defined(INVARIANTS))
#define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
	if (!TAILQ_EMPTY(head) &&					\
	    TAILQ_FIRST((head))->field.tqe_prev !=			\
	     &TAILQ_FIRST((head)))					\
		panic("Bad tailq head %p first->prev != head", (head));	\
} while (0)

#define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
	if (*(head)->tqh_last != NULL)					\
	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
} while (0)

#define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
	if (TAILQ_NEXT((elm), field) != NULL &&				\
	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
	     &((elm)->field.tqe_next))					\
		panic("Bad link elm %p next->prev != elm", (elm));	\
} while (0)

#define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
	if (*(elm)->field.tqe_prev != (elm))				\
		panic("Bad link elm %p prev->next != elm", (elm));	\
} while (0)
#else
#define	QMD_TAILQ_CHECK_HEAD(head, field)
#define	QMD_TAILQ_CHECK_TAIL(head, headname)
#define	QMD_TAILQ_CHECK_NEXT(elm, field)
#define	QMD_TAILQ_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */

#define	TAILQ_CONCAT(head1, head2, field) do {				\
	if (!TAILQ_EMPTY(head2)) {					\
		*(head1)->tqh_last = (head2)->tqh_first;		\
		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
		(head1)->tqh_last = (head2)->tqh_last;			\
		TAILQ_INIT((head2));					\
		QMD_TRACE_HEAD(head1);					\
		QMD_TRACE_HEAD(head2);					\
	}								\
} while (0)

#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)

#define	TAILQ_FIRST(head)	((head)->tqh_first)

#define	TAILQ_FOREACH(var, head, field)					\
	for ((var) = TAILQ_FIRST((head));				\
	    (var);							\
	    (var) = TAILQ_NEXT((var), field))

#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = TAILQ_FIRST((head));				\
	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
	    (var) = (tvar))

#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
	for ((var) = TAILQ_LAST((head), headname);			\
	    (var);							\
	    (var) = TAILQ_PREV((var), headname, field))

#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
	for ((var) = TAILQ_LAST((head), headname);			\
	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
	    (var) = (tvar))

#define	TAILQ_INIT(head) do {						\
	TAILQ_FIRST((head)) = NULL;					\
	(head)->tqh_last = &TAILQ_FIRST((head));			\
	QMD_TRACE_HEAD(head);						\
} while (0)

#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
		    &TAILQ_NEXT((elm), field);				\
	else {								\
		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
		QMD_TRACE_HEAD(head);					\
	}								\
	TAILQ_NEXT((listelm), field) = (elm);				\
	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
	QMD_TRACE_ELEM(&(elm)->field);					\
	QMD_TRACE_ELEM(&listelm->field);				\
} while (0)

#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
	QMD_TAILQ_CHECK_PREV(listelm, field);				\
	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
	TAILQ_NEXT((elm), field) = (listelm);				\
	*(listelm)->field.tqe_prev = (elm);				\
	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
	QMD_TRACE_ELEM(&(elm)->field);					\
	QMD_TRACE_ELEM(&listelm->field);				\
} while (0)

#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
	QMD_TAILQ_CHECK_HEAD(head, field);				\
	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
		TAILQ_FIRST((head))->field.tqe_prev =			\
		    &TAILQ_NEXT((elm), field);				\
	else								\
		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
	TAILQ_FIRST((head)) = (elm);					\
	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
	QMD_TRACE_HEAD(head);						\
	QMD_TRACE_ELEM(&(elm)->field);					\
} while (0)

#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
	QMD_TAILQ_CHECK_TAIL(head, field);				\
	TAILQ_NEXT((elm), field) = NULL;				\
	(elm)->field.tqe_prev = (head)->tqh_last;			\
	*(head)->tqh_last = (elm);					\
	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
	QMD_TRACE_HEAD(head);						\
	QMD_TRACE_ELEM(&(elm)->field);					\
} while (0)

#define	TAILQ_LAST(head, headname)					\
	(*(((struct headname *)((head)->tqh_last))->tqh_last))

#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)

#define	TAILQ_PREV(elm, headname, field)				\
	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))

#define	TAILQ_REMOVE(head, elm, field) do {				\
	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
	QMD_TAILQ_CHECK_NEXT(elm, field);				\
	QMD_TAILQ_CHECK_PREV(elm, field);				\
	if ((TAILQ_NEXT((elm), field)) != NULL)				\
		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
		    (elm)->field.tqe_prev;				\
	else {								\
		(head)->tqh_last = (elm)->field.tqe_prev;		\
		QMD_TRACE_HEAD(head);					\
	}								\
	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
	TRASHIT(*oldnext);						\
	TRASHIT(*oldprev);						\
	QMD_TRACE_ELEM(&(elm)->field);					\
} while (0)

#define TAILQ_SWAP(head1, head2, type, field) do {			\
	struct type *swap_first = (head1)->tqh_first;			\
	struct type **swap_last = (head1)->tqh_last;			\
	(head1)->tqh_first = (head2)->tqh_first;			\
	(head1)->tqh_last = (head2)->tqh_last;				\
	(head2)->tqh_first = swap_first;				\
	(head2)->tqh_last = swap_last;					\
	if ((swap_first = (head1)->tqh_first) != NULL)			\
		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
	else								\
		(head1)->tqh_last = &(head1)->tqh_first;		\
	if ((swap_first = (head2)->tqh_first) != NULL)			\
		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
	else								\
		(head2)->tqh_last = &(head2)->tqh_first;		\
} while (0)

#endif /* !_SYS_QUEUE_H_ */


code:
/*-
 * Copyright (c) 2010 The FreeBSD Foundation
 * All rights reserved.
 *
 * This software was developed by Edward Tomasz Napierala under sponsorship
 * from the FreeBSD Foundation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/racct.h 226092 2011-10-07 06:46:46Z trasz $
 */

/*
 * Resource accounting.
 */

#ifndef _RACCT_H_
#define	_RACCT_H_

#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/types.h>

struct proc;
struct rctl_rule_link;
struct ucred;

/*
 * Resources.
 */
#define	RACCT_UNDEFINED		-1
#define	RACCT_CPU		0
#define	RACCT_DATA		1
#define	RACCT_STACK		2
#define	RACCT_CORE		3
#define	RACCT_RSS		4
#define	RACCT_MEMLOCK		5
#define	RACCT_NPROC		6
#define	RACCT_NOFILE		7
#define	RACCT_VMEM		8
#define	RACCT_NPTS		9
#define	RACCT_SWAP		10
#define	RACCT_NTHR		11
#define	RACCT_MSGQQUEUED	12
#define	RACCT_MSGQSIZE		13
#define	RACCT_NMSGQ		14
#define	RACCT_NSEM		15
#define	RACCT_NSEMOP		16
#define	RACCT_NSHM		17
#define	RACCT_SHMSIZE		18
#define	RACCT_WALLCLOCK		19
#define	RACCT_MAX		RACCT_WALLCLOCK

/*
 * Resource properties.
 */
#define	RACCT_IN_MILLIONS	0x01
#define	RACCT_RECLAIMABLE	0x02
#define	RACCT_INHERITABLE	0x04
#define	RACCT_DENIABLE		0x08
#define	RACCT_SLOPPY		0x10

extern int racct_types[];

/*
 * Amount stored in c_resources[] is 10**6 times bigger than what's
 * visible to the userland.  It gets fixed up when retrieving resource
 * usage or adding rules.
 */
#define	RACCT_IS_IN_MILLIONS(X)	(racct_types[X] & RACCT_IN_MILLIONS)

/*
 * Resource usage can drop, as opposed to only grow.
 */
#define	RACCT_IS_RECLAIMABLE(X)	(racct_types[X] & RACCT_RECLAIMABLE)

/*
 * Children inherit resource usage.
 */
#define	RACCT_IS_INHERITABLE(X)	(racct_types[X] & RACCT_INHERITABLE)

/*
 * racct_{add,set}(9) can actually return an error and not update resource
 * usage counters.  Note that even when resource is not deniable, allocating
 * resource might cause signals to be sent by RCTL code.
 */
#define	RACCT_IS_DENIABLE(X)		(racct_types[X] & RACCT_DENIABLE)

/*
 * Per-process resource usage information makes no sense, but per-credential
 * one does.  This kind of resources are usually allocated for process, but
 * freed using credentials.
 */
#define	RACCT_IS_SLOPPY(X)		(racct_types[X] & RACCT_SLOPPY)

/*
 * The 'racct' structure defines resource consumption for a particular
 * subject, such as process or jail.
 *
 * This structure must be filled with zeroes initially.
 */
struct racct {
	int64_t				r_resources[RACCT_MAX + 1];
	LIST_HEAD(, rctl_rule_link)	r_rule_links;
};

int	racct_add(struct proc *p, int resource, uint64_t amount);
void	racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
void	racct_add_force(struct proc *p, int resource, uint64_t amount);
int	racct_set(struct proc *p, int resource, uint64_t amount);
void	racct_set_force(struct proc *p, int resource, uint64_t amount);
void	racct_sub(struct proc *p, int resource, uint64_t amount);
void	racct_sub_cred(struct ucred *cred, int resource, uint64_t amount);
uint64_t	racct_get_limit(struct proc *p, int resource);
uint64_t	racct_get_available(struct proc *p, int resource);

void	racct_create(struct racct **racctp);
void	racct_destroy(struct racct **racctp);

int	racct_proc_fork(struct proc *parent, struct proc *child);
void	racct_proc_fork_done(struct proc *child);
void	racct_proc_exit(struct proc *p);

void	racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
	    struct ucred *newcred);

#endif /* !_RACCT_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 2000 Mark R. V. Murray
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/random.h 136433 2004-10-12 14:55:59Z rwatson $
 */

#ifndef	_SYS_RANDOM_H_
#define	_SYS_RANDOM_H_

#ifdef _KERNEL

int read_random(void *, int);

/*
 * Note: if you add or remove members of esource, remember to also update the
 * KASSERT regarding what valid members are in random_harvest_internal().
 */
enum esource {
	RANDOM_START = 0,
	RANDOM_WRITE = 0,
	RANDOM_KEYBOARD,
	RANDOM_MOUSE,
	RANDOM_NET,
	RANDOM_INTERRUPT,
	RANDOM_PURE,
	ENTROPYSOURCE
};
void random_harvest(void *, u_int, u_int, u_int, enum esource);

/* Allow the sysadmin to select the broad category of
 * entropy types to harvest
 */
struct harvest_select {
	int ethernet;
	int point_to_point;
	int interrupt;
	int swi;
};

extern struct harvest_select harvest;

#endif /* _KERNEL */

#endif /* _SYS_RANDOM_H_ */


code:
/*-
 * Copyright (c) 2010 The FreeBSD Foundation
 * All rights reserved.
 *
 * This software was developed by Edward Tomasz Napierala under sponsorship
 * from the FreeBSD Foundation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/rctl.h 221362 2011-05-03 07:32:58Z trasz $
 */

/*
 * Resource Limits.
 */

#ifndef _RCTL_H_
#define	_RCTL_H_

#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/_task.h>

struct proc;
struct uidinfo;
struct loginclass;
struct prison_racct;
struct ucred;
struct rctl_rule_link;

#ifdef _KERNEL

/*
 * Rules describe an action to be taken when conditions defined
 * in the rule are met.  There is no global list of rules; instead,
 * rules are linked to by the racct structures for all the subjects
 * they apply to - for example, a rule of type "user" is linked to the
 * appropriate struct uidinfo, and to all the processes of that user.
 *
 * 'rr_refcount' is equal to the number of rctl_rule_link structures
 * pointing to the rule.
 *
 * This structure must never change after being added, via rctl_rule_link
 * structures, to subjects.  In order to change a rule, add a new rule
 * and remove the previous one.
 */
struct rctl_rule {
	int		rr_subject_type;
	union {
		struct proc		*rs_proc;
		struct uidinfo		*rs_uip;
		struct loginclass	*rs_loginclass;
		struct prison_racct	*rs_prison_racct;
	} rr_subject;
	int		rr_per;
	int		rr_resource;
	int		rr_action;
	int64_t		rr_amount;
	u_int		rr_refcount;
	struct task	rr_task;
};

/*
 * Allowed values for rr_subject_type and rr_per fields.
 */
#define	RCTL_SUBJECT_TYPE_UNDEFINED	-1
#define	RCTL_SUBJECT_TYPE_PROCESS	0x0000
#define	RCTL_SUBJECT_TYPE_USER		0x0001
#define	RCTL_SUBJECT_TYPE_LOGINCLASS	0x0003
#define	RCTL_SUBJECT_TYPE_JAIL		0x0004
#define	RCTL_SUBJECT_TYPE_MAX		RCTL_SUBJECT_TYPE_JAIL

/*
 * Allowed values for rr_action field.
 */
#define	RCTL_ACTION_UNDEFINED		-1
#define	RCTL_ACTION_SIGHUP		SIGHUP
#define	RCTL_ACTION_SIGINT		SIGINT
#define	RCTL_ACTION_SIGQUIT		SIGQUIT
#define	RCTL_ACTION_SIGILL		SIGILL
#define	RCTL_ACTION_SIGTRAP		SIGTRAP
#define	RCTL_ACTION_SIGABRT		SIGABRT
#define	RCTL_ACTION_SIGEMT		SIGEMT
#define	RCTL_ACTION_SIGFPE		SIGFPE
#define	RCTL_ACTION_SIGKILL		SIGKILL
#define	RCTL_ACTION_SIGBUS		SIGBUS
#define	RCTL_ACTION_SIGSEGV		SIGSEGV
#define	RCTL_ACTION_SIGSYS		SIGSYS
#define	RCTL_ACTION_SIGPIPE		SIGPIPE
#define	RCTL_ACTION_SIGALRM		SIGALRM
#define	RCTL_ACTION_SIGTERM		SIGTERM
#define	RCTL_ACTION_SIGURG		SIGURG
#define	RCTL_ACTION_SIGSTOP		SIGSTOP
#define	RCTL_ACTION_SIGTSTP		SIGTSTP
#define	RCTL_ACTION_SIGCHLD		SIGCHLD
#define	RCTL_ACTION_SIGTTIN		SIGTTIN
#define	RCTL_ACTION_SIGTTOU		SIGTTOU
#define	RCTL_ACTION_SIGIO		SIGIO
#define	RCTL_ACTION_SIGXCPU		SIGXCPU
#define	RCTL_ACTION_SIGXFSZ		SIGXFSZ
#define	RCTL_ACTION_SIGVTALRM		SIGVTALRM
#define	RCTL_ACTION_SIGPROF		SIGPROF
#define	RCTL_ACTION_SIGWINCH		SIGWINCH
#define	RCTL_ACTION_SIGINFO		SIGINFO
#define	RCTL_ACTION_SIGUSR1		SIGUSR1
#define	RCTL_ACTION_SIGUSR2		SIGUSR2
#define	RCTL_ACTION_SIGTHR		SIGTHR
#define	RCTL_ACTION_SIGNAL_MAX		RCTL_ACTION_SIGTHR
#define	RCTL_ACTION_DENY		(RCTL_ACTION_SIGNAL_MAX + 1)
#define	RCTL_ACTION_LOG			(RCTL_ACTION_SIGNAL_MAX + 2)
#define	RCTL_ACTION_DEVCTL		(RCTL_ACTION_SIGNAL_MAX + 3)
#define	RCTL_ACTION_MAX			RCTL_ACTION_DEVCTL

#define	RCTL_AMOUNT_UNDEFINED		-1

struct rctl_rule *rctl_rule_alloc(int flags);
struct rctl_rule *rctl_rule_duplicate(const struct rctl_rule *rule, int flags);
void	rctl_rule_acquire(struct rctl_rule *rule);
void	rctl_rule_release(struct rctl_rule *rule);
int	rctl_rule_add(struct rctl_rule *rule);
int	rctl_rule_remove(struct rctl_rule *filter);
int	rctl_enforce(struct proc *p, int resource, uint64_t amount);
uint64_t rctl_get_limit(struct proc *p, int resource);
uint64_t rctl_get_available(struct proc *p, int resource);
const char *rctl_resource_name(int resource);
void	rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred);
int	rctl_proc_fork(struct proc *parent, struct proc *child);
void	rctl_racct_release(struct racct *racct);
#else /* !_KERNEL */

/*
 * Syscall interface.
 */
__BEGIN_DECLS
int	rctl_get_racct(const char *inbufp, size_t inbuflen, char *outbufp,
	    size_t outbuflen);
int	rctl_get_rules(const char *inbufp, size_t inbuflen, char *outbufp,
	    size_t outbuflen);
int	rctl_get_limits(const char *inbufp, size_t inbuflen, char *outbufp,
	    size_t outbuflen);
int	rctl_add_rule(const char *inbufp, size_t inbuflen, char *outbufp,
	    size_t outbuflen);
int	rctl_remove_rule(const char *inbufp, size_t inbuflen, char *outbufp,
	    size_t outbuflen);
__END_DECLS

#endif /* !_KERNEL */

#endif /* !_RCTL_H_ */


code:
/*-
 * Copyright (c) 1982, 1986, 1988, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)reboot.h	8.3 (Berkeley) 12/13/94
 * $FreeBSD: release/9.0.0/sys/sys/reboot.h 139825 2005-01-07 02:29:27Z imp $
 */

#ifndef _SYS_REBOOT_H_
#define	_SYS_REBOOT_H_

/*
 * Arguments to reboot system call.  These are passed to
 * the boot program and on to init.
 */
#define	RB_AUTOBOOT	0	/* flags for system auto-booting itself */

#define	RB_ASKNAME	0x001	/* ask for file name to reboot from */
#define	RB_SINGLE	0x002	/* reboot to single user only */
#define	RB_NOSYNC	0x004	/* dont sync before reboot */
#define	RB_HALT		0x008	/* don't reboot, just halt */
#define	RB_INITNAME	0x010	/* name given for /etc/init (unused) */
#define	RB_DFLTROOT	0x020	/* use compiled-in rootdev */
#define	RB_KDB		0x040	/* give control to kernel debugger */
#define	RB_RDONLY	0x080	/* mount root fs read-only */
#define	RB_DUMP		0x100	/* dump kernel memory before reboot */
#define	RB_MINIROOT	0x200	/* mini-root present in memory at boot time */
#define	RB_VERBOSE	0x800	/* print all potentially useful info */
#define	RB_SERIAL	0x1000	/* use serial port as console */
#define	RB_CDROM	0x2000	/* use cdrom as root */
#define	RB_POWEROFF	0x4000	/* turn the power off if possible */
#define	RB_GDB		0x8000	/* use GDB remote debugger instead of DDB */
#define	RB_MUTE		0x10000	/* start up with the console muted */
#define	RB_SELFTEST	0x20000	/* don't complete the boot; do selftest */
#define	RB_RESERVED1	0x40000	/* reserved for internal use of boot blocks */
#define	RB_RESERVED2	0x80000	/* reserved for internal use of boot blocks */
#define	RB_PAUSE	0x100000 /* pause after each output line during probe */
#define	RB_MULTIPLE	0x20000000	/* use multiple consoles */

#define	RB_BOOTINFO	0x80000000	/* have `struct bootinfo *' arg */

#endif


code:
/*-
 * Copyright (c) 2005 John Baldwin <jhb@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/refcount.h 180763 2008-07-23 16:44:20Z des $
 */

#ifndef __SYS_REFCOUNT_H__
#define __SYS_REFCOUNT_H__

#include <machine/atomic.h>

#ifdef _KERNEL
#include <sys/systm.h>
#else
#define	KASSERT(exp, msg)	/* */
#endif

static __inline void
refcount_init(volatile u_int *count, u_int value)
{

	*count = value;
}

static __inline void
refcount_acquire(volatile u_int *count)
{

	atomic_add_acq_int(count, 1);
}

static __inline int
refcount_release(volatile u_int *count)
{
	u_int old;

	/* XXX: Should this have a rel membar? */
	old = atomic_fetchadd_int(count, -1);
	KASSERT(old > 0, ("negative refcount %p", count));
	return (old == 1);
}

#endif	/* ! __SYS_REFCOUNT_H__ */


code:
/*-
 * Copyright (c) 2001 Robert N. M. Watson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/regression.h 129096 2004-05-10 18:38:07Z rwatson $
 */
#ifndef _SYS_REGRESSION_H_
#define	_SYS_REGRESSION_H_

#ifndef _KERNEL
/*
 * System calls associated with regression testing functions in kernel.
 */
int	__setugid(int _flag);
#endif /* !_KERNEL */

#endif /* !_SYS_REGRESSION_H_ */


code:
/*-
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)resource.h	8.4 (Berkeley) 1/9/95
 * $FreeBSD: release/9.0.0/sys/sys/resource.h 210220 2010-07-18 11:13:36Z trasz $
 */

#ifndef _SYS_RESOURCE_H_
#define	_SYS_RESOURCE_H_

#include <sys/cdefs.h>
#include <sys/_timeval.h>
#include <sys/_types.h>

/*
 * Process priority specifications to get/setpriority.
 */
#define	PRIO_MIN	-20
#define	PRIO_MAX	20

#define	PRIO_PROCESS	0
#define	PRIO_PGRP	1
#define	PRIO_USER	2

/*
 * Resource utilization information.
 *
 * All fields are only modified by curthread and
 * no locks are required to read.
 */

#define	RUSAGE_SELF	0
#define	RUSAGE_CHILDREN	-1
#define	RUSAGE_THREAD	1

struct rusage {
	struct timeval ru_utime;	/* user time used */
	struct timeval ru_stime;	/* system time used */
	long	ru_maxrss;		/* max resident set size */
#define	ru_first	ru_ixrss
	long	ru_ixrss;		/* integral shared memory size */
	long	ru_idrss;		/* integral unshared data " */
	long	ru_isrss;		/* integral unshared stack " */
	long	ru_minflt;		/* page reclaims */
	long	ru_majflt;		/* page faults */
	long	ru_nswap;		/* swaps */
	long	ru_inblock;		/* block input operations */
	long	ru_oublock;		/* block output operations */
	long	ru_msgsnd;		/* messages sent */
	long	ru_msgrcv;		/* messages received */
	long	ru_nsignals;		/* signals received */
	long	ru_nvcsw;		/* voluntary context switches */
	long	ru_nivcsw;		/* involuntary " */
#define	ru_last		ru_nivcsw
};

/*
 * Resource limits
 */
#define	RLIMIT_CPU	0		/* maximum cpu time in seconds */
#define	RLIMIT_FSIZE	1		/* maximum file size */
#define	RLIMIT_DATA	2		/* data size */
#define	RLIMIT_STACK	3		/* stack size */
#define	RLIMIT_CORE	4		/* core file size */
#define	RLIMIT_RSS	5		/* resident set size */
#define	RLIMIT_MEMLOCK	6		/* locked-in-memory address space */
#define	RLIMIT_NPROC	7		/* number of processes */
#define	RLIMIT_NOFILE	8		/* number of open files */
#define	RLIMIT_SBSIZE	9		/* maximum size of all socket buffers */
#define	RLIMIT_VMEM	10		/* virtual process size (incl. mmap) */
#define	RLIMIT_AS	RLIMIT_VMEM	/* standard name for RLIMIT_VMEM */
#define	RLIMIT_NPTS	11		/* pseudo-terminals */
#define	RLIMIT_SWAP	12		/* swap used */

#define	RLIM_NLIMITS	13		/* number of resource limits */

#define	RLIM_INFINITY	((rlim_t)(((uint64_t)1 << 63) - 1))
/* XXX Missing: RLIM_SAVED_MAX, RLIM_SAVED_CUR */

/*
 * Resource limit string identifiers
 */

#ifdef _RLIMIT_IDENT
static char *rlimit_ident[RLIM_NLIMITS] = {
	"cpu",
	"fsize",
	"data",
	"stack",
	"core",
	"rss",
	"memlock",
	"nproc",
	"nofile",
	"sbsize",
	"vmem",
	"npts",
	"swap",
};
#endif

#ifndef _RLIM_T_DECLARED
typedef	__rlim_t	rlim_t;
#define	_RLIM_T_DECLARED
#endif

struct rlimit {
	rlim_t	rlim_cur;		/* current (soft) limit */
	rlim_t	rlim_max;		/* maximum value for rlim_cur */
};

#if __BSD_VISIBLE

struct orlimit {
	__int32_t	rlim_cur;	/* current (soft) limit */
	__int32_t	rlim_max;	/* maximum value for rlim_cur */
};

struct loadavg {
	__fixpt_t	ldavg[3];
	long		fscale;
};

#define	CP_USER		0
#define	CP_NICE		1
#define	CP_SYS		2
#define	CP_INTR		3
#define	CP_IDLE		4
#define	CPUSTATES	5

#endif	/* __BSD_VISIBLE */

#ifdef _KERNEL

extern struct loadavg averunnable;
void	read_cpu_time(long *cp_time);	/* Writes array of CPUSTATES */

#else

__BEGIN_DECLS
/* XXX 2nd arg to [gs]etpriority() should be an id_t */
int	getpriority(int, int);
int	getrlimit(int, struct rlimit *);
int	getrusage(int, struct rusage *);
int	setpriority(int, int, int);
int	setrlimit(int, const struct rlimit *);
__END_DECLS

#endif	/* _KERNEL */
#endif	/* !_SYS_RESOURCE_H_ */


code:
/*-
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)resourcevar.h	8.4 (Berkeley) 1/9/95
 * $FreeBSD: release/9.0.0/sys/sys/resourcevar.h 224188 2011-07-18 17:33:08Z jhb $
 */

#ifndef	_SYS_RESOURCEVAR_H_
#define	_SYS_RESOURCEVAR_H_

#include <sys/resource.h>
#include <sys/queue.h>
#ifdef _KERNEL
#include <sys/_lock.h>
#include <sys/_mutex.h>
#endif

/*
 * Kernel per-process accounting / statistics
 * (not necessarily resident except when running).
 *
 * Locking key:
 *      b - created at fork, never changes
 *      c - locked by proc mtx
 *      j - locked by proc slock
 *      k - only accessed by curthread
 */
struct pstats {
#define	pstat_startzero	p_cru
	struct	rusage p_cru;		/* Stats for reaped children. */
	struct	itimerval p_timer[3];	/* (j) Virtual-time timers. */
#define	pstat_endzero	pstat_startcopy

#define	pstat_startcopy	p_prof
	struct uprof {			/* Profile arguments. */
		caddr_t	pr_base;	/* (c + j) Buffer base. */
		u_long	pr_size;	/* (c + j) Buffer size. */
		u_long	pr_off;		/* (c + j) PC offset. */
		u_long	pr_scale;	/* (c + j) PC scaling. */
	} p_prof;
#define	pstat_endcopy	p_start
	struct	timeval p_start;	/* (b) Starting time. */
};

#ifdef _KERNEL

/*
 * Kernel shareable process resource limits.  Because this structure
 * is moderately large but changes infrequently, it is normally
 * shared copy-on-write after forks.
 */
struct plimit {
	struct	rlimit pl_rlimit[RLIM_NLIMITS];
	int	pl_refcnt;		/* number of references */
};

struct racct;

/*-
 * Per uid resource consumption.  This structure is used to track
 * the total resource consumption (process count, socket buffer size,
 * etc) for the uid and impose limits.
 *
 * Locking guide:
 * (a) Constant from inception
 * (b) Lockless, updated using atomics
 * (c) Locked by global uihashtbl_mtx
 * (d) Locked by the ui_vmsize_mtx
 */
struct uidinfo {
	LIST_ENTRY(uidinfo) ui_hash;	/* (c) hash chain of uidinfos */
	struct mtx ui_vmsize_mtx;
	vm_ooffset_t ui_vmsize;		/* (d) swap reservation by uid */
	long	ui_sbsize;		/* (b) socket buffer space consumed */
	long	ui_proccnt;		/* (b) number of processes */
	long	ui_ptscnt;		/* (b) number of pseudo-terminals */
	uid_t	ui_uid;			/* (a) uid */
	u_int	ui_ref;			/* (b) reference count */
	struct racct *ui_racct;		/* (a) resource accounting */
};

#define	UIDINFO_VMSIZE_LOCK(ui)		mtx_lock(&((ui)->ui_vmsize_mtx))
#define	UIDINFO_VMSIZE_UNLOCK(ui)	mtx_unlock(&((ui)->ui_vmsize_mtx))

struct proc;
struct rusage_ext;
struct thread;

void	 addupc_intr(struct thread *td, uintfptr_t pc, u_int ticks);
void	 addupc_task(struct thread *td, uintfptr_t pc, u_int ticks);
void	 calccru(struct proc *p, struct timeval *up, struct timeval *sp);
void	 calcru(struct proc *p, struct timeval *up, struct timeval *sp);
int	 chgproccnt(struct uidinfo *uip, int diff, rlim_t maxval);
int	 chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
	    rlim_t maxval);
int	 chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
int	 fuswintr(void *base);
struct plimit
	*lim_alloc(void);
void	 lim_copy(struct plimit *dst, struct plimit *src);
rlim_t	 lim_cur(struct proc *p, int which);
void	 lim_fork(struct proc *p1, struct proc *p2);
void	 lim_free(struct plimit *limp);
struct plimit
	*lim_hold(struct plimit *limp);
rlim_t	 lim_max(struct proc *p, int which);
void	 lim_rlimit(struct proc *p, int which, struct rlimit *rlp);
void	 ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2,
	    struct rusage_ext *rux2);
void	 rucollect(struct rusage *ru, struct rusage *ru2);
void	 rufetch(struct proc *p, struct rusage *ru);
void	 rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up,
	    struct timeval *sp);
void	 rufetchtd(struct thread *td, struct rusage *ru);
void	 ruxagg(struct proc *p, struct thread *td);
int	 suswintr(void *base, int word);
struct uidinfo
	*uifind(uid_t uid);
void	 uifree(struct uidinfo *uip);
void	 uihashinit(void);
void	 uihold(struct uidinfo *uip);
void	 ui_racct_foreach(void (*callback)(struct racct *racct,
	    void *arg2, void *arg3), void *arg2, void *arg3);

#endif /* _KERNEL */
#endif /* !_SYS_RESOURCEVAR_H_ */


code:
/*-
 * Copyright 1998 Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby
 * granted, provided that both the above copyright notice and this
 * permission notice appear in all copies, that both the above
 * copyright notice and this permission notice appear in all
 * supporting documentation, and that the name of M.I.T. not be used
 * in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.  M.I.T. makes
 * no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied
 * warranty.
 *
 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/rman.h 221220 2011-04-29 20:05:19Z jhb $
 */

#ifndef _SYS_RMAN_H_
#define	_SYS_RMAN_H_	1

#ifndef	_KERNEL
#include <sys/queue.h>
#else
#include <machine/_bus.h>
#include <machine/resource.h>
#endif

#define	RF_ALLOCATED	0x0001	/* resource has been reserved */
#define	RF_ACTIVE	0x0002	/* resource allocation has been activated */
#define	RF_SHAREABLE	0x0004	/* resource permits contemporaneous sharing */
#define	RF_TIMESHARE	0x0008	/* resource permits time-division sharing */
#define	RF_WANTED	0x0010	/* somebody is waiting for this resource */
#define	RF_FIRSTSHARE	0x0020	/* first in sharing list */
#define	RF_PREFETCHABLE	0x0040	/* resource is prefetchable */
#define	RF_OPTIONAL	0x0080	/* for bus_alloc_resources() */

#define	RF_ALIGNMENT_SHIFT	10 /* alignment size bit starts bit 10 */
#define	RF_ALIGNMENT_MASK	(0x003F << RF_ALIGNMENT_SHIFT)
				/* resource address alignemnt size bit mask */
#define	RF_ALIGNMENT_LOG2(x)	((x) << RF_ALIGNMENT_SHIFT)
#define	RF_ALIGNMENT(x)		(((x) & RF_ALIGNMENT_MASK) >> RF_ALIGNMENT_SHIFT)

enum	rman_type { RMAN_UNINIT = 0, RMAN_GAUGE, RMAN_ARRAY };

/*
 * String length exported to userspace for resource names, etc.
 */
#define RM_TEXTLEN	32

/*
 * Userspace-exported structures.
 */
struct u_resource {
	uintptr_t	r_handle;		/* resource uniquifier */
	uintptr_t	r_parent;		/* parent rman */
	uintptr_t	r_device;		/* device owning this resource */
	char		r_devname[RM_TEXTLEN];	/* device name XXX obsolete */

	u_long		r_start;		/* offset in resource space */
	u_long		r_size;			/* size in resource space */
	u_int		r_flags;		/* RF_* flags */
};

struct u_rman {
	uintptr_t	rm_handle;		/* rman uniquifier */
	char		rm_descr[RM_TEXTLEN];	/* rman description */

	u_long		rm_start;		/* base of managed region */
	u_long		rm_size;		/* size of managed region */
	enum rman_type	rm_type;		/* region type */
};

#ifdef _KERNEL

/*
 * The public (kernel) view of struct resource
 *
 * NB: Changing the offset/size/type of existing fields in struct resource
 * NB: breaks the device driver ABI and is strongly FORBIDDEN.
 * NB: Appending new fields is probably just misguided.
 */

struct resource {
	struct resource_i	*__r_i;
	bus_space_tag_t		r_bustag; /* bus_space tag */
	bus_space_handle_t	r_bushandle;	/* bus_space handle */
};

struct resource_i;

TAILQ_HEAD(resource_head, resource_i);

struct rman {
	struct	resource_head 	rm_list;
	struct	mtx *rm_mtx;	/* mutex used to protect rm_list */
	TAILQ_ENTRY(rman)	rm_link; /* link in list of all rmans */
	u_long	rm_start;	/* index of globally first entry */
	u_long	rm_end;		/* index of globally last entry */
	enum	rman_type rm_type; /* what type of resource this is */
	const	char *rm_descr;	/* text descripion of this resource */
};
TAILQ_HEAD(rman_head, rman);

int	rman_activate_resource(struct resource *r);
int	rman_adjust_resource(struct resource *r, u_long start, u_long end);
int	rman_await_resource(struct resource *r, int pri, int timo);
int	rman_first_free_region(struct rman *rm, u_long *start, u_long *end);
bus_space_handle_t rman_get_bushandle(struct resource *);
bus_space_tag_t rman_get_bustag(struct resource *);
u_long	rman_get_end(struct resource *);
struct device *rman_get_device(struct resource *);
u_int	rman_get_flags(struct resource *);
int	rman_get_rid(struct resource *);
u_long	rman_get_size(struct resource *);
u_long	rman_get_start(struct resource *);
void   *rman_get_virtual(struct resource *);
int	rman_deactivate_resource(struct resource *r);
int	rman_fini(struct rman *rm);
int	rman_init(struct rman *rm);
int	rman_init_from_resource(struct rman *rm, struct resource *r);
int	rman_last_free_region(struct rman *rm, u_long *start, u_long *end);
uint32_t rman_make_alignment_flags(uint32_t size);
int	rman_manage_region(struct rman *rm, u_long start, u_long end);
int	rman_is_region_manager(struct resource *r, struct rman *rm);
int	rman_release_resource(struct resource *r);
struct resource *rman_reserve_resource(struct rman *rm, u_long start,
					u_long end, u_long count,
					u_int flags, struct device *dev);
struct resource *rman_reserve_resource_bound(struct rman *rm, u_long start,
					u_long end, u_long count, u_long bound,
					u_int flags, struct device *dev);
void	rman_set_bushandle(struct resource *_r, bus_space_handle_t _h);
void	rman_set_bustag(struct resource *_r, bus_space_tag_t _t);
void	rman_set_device(struct resource *_r, struct device *_dev);
void	rman_set_end(struct resource *_r, u_long _end);
void	rman_set_rid(struct resource *_r, int _rid);
void	rman_set_start(struct resource *_r, u_long _start);
void	rman_set_virtual(struct resource *_r, void *_v);

extern	struct rman_head rman_head;

#endif /* _KERNEL */

#endif /* !_SYS_RMAN_H_ */


code:
/*-
 * Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/rmlock.h 212112 2010-09-01 19:50:03Z mlaier $
 */

#ifndef _SYS_RMLOCK_H_
#define _SYS_RMLOCK_H_

#include <sys/mutex.h>
#include <sys/sx.h>
#include <sys/_lock.h>
#include <sys/_rmlock.h>

#ifdef _KERNEL

/*
 * Flags passed to rm_init(9).
 */
#define	RM_NOWITNESS	0x00000001
#define	RM_RECURSE	0x00000002
#define	RM_SLEEPABLE	0x00000004

void	rm_init(struct rmlock *rm, const char *name);
void	rm_init_flags(struct rmlock *rm, const char *name, int opts);
void	rm_destroy(struct rmlock *rm);
int	rm_wowned(struct rmlock *rm);
void	rm_sysinit(void *arg);
void	rm_sysinit_flags(void *arg);

void	_rm_wlock_debug(struct rmlock *rm, const char *file, int line);
void	_rm_wunlock_debug(struct rmlock *rm, const char *file, int line);
int	_rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker,
	    int trylock, const char *file, int line);
void	_rm_runlock_debug(struct rmlock *rm,  struct rm_priotracker *tracker,
	    const char *file, int line);

void	_rm_wlock(struct rmlock *rm);
void	_rm_wunlock(struct rmlock *rm);
int	_rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker,
	    int trylock);
void	_rm_runlock(struct rmlock *rm,  struct rm_priotracker *tracker);

/*
 * Public interface for lock operations.
 */
#ifndef LOCK_DEBUG
#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/rmlock.h>
#endif

#if LOCK_DEBUG > 0
#define	rm_wlock(rm)	_rm_wlock_debug((rm), LOCK_FILE, LOCK_LINE)
#define	rm_wunlock(rm)	_rm_wunlock_debug((rm), LOCK_FILE, LOCK_LINE)
#define	rm_rlock(rm,tracker)  \
    ((void)_rm_rlock_debug((rm),(tracker), 0, LOCK_FILE, LOCK_LINE ))
#define	rm_try_rlock(rm,tracker)  \
    _rm_rlock_debug((rm),(tracker), 1, LOCK_FILE, LOCK_LINE )
#define	rm_runlock(rm,tracker)	\
    _rm_runlock_debug((rm), (tracker), LOCK_FILE, LOCK_LINE )
#else
#define	rm_wlock(rm)			_rm_wlock((rm))
#define	rm_wunlock(rm)			_rm_wunlock((rm))
#define	rm_rlock(rm,tracker)		((void)_rm_rlock((rm),(tracker), 0))
#define	rm_try_rlock(rm,tracker)	_rm_rlock((rm),(tracker), 1)
#define	rm_runlock(rm,tracker)		_rm_runlock((rm), (tracker))
#endif

struct rm_args {
	struct rmlock	*ra_rm;
	const char 	*ra_desc;
};

struct rm_args_flags {
	struct rmlock	*ra_rm;
	const char 	*ra_desc;
	int		ra_opts;
};

#define	RM_SYSINIT(name, rm, desc)       				\
	static struct rm_args name##_args = {				\
		(rm),							\
		(desc),							\
	};								\
	SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rm_sysinit, &name##_args);					\
	SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rm_destroy, (rm))

#define	RM_SYSINIT_FLAGS(name, rm, desc, opts)       			\
	static struct rm_args name##_args = {				\
		(rm),							\
		(desc),							\
                (opts),							\
	};								\
	SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rm_sysinit_flags, &name##_args);				\
	SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rm_destroy, (rm))

#endif /* _KERNEL */
#endif /* !_SYS_RMLOCK_H_ */


code:
/*-
 * Copyright (c) 1994, Henrik Vestergaard Draboel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Henrik Vestergaard Draboel.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/rtprio.h 165898 2007-01-08 21:21:45Z imp $
 */

#ifndef _SYS_RTPRIO_H_
#define _SYS_RTPRIO_H_

#include <sys/priority.h>

/*
 * Process realtime-priority specifications to rtprio.
 */

/* priority types.  Start at 1 to catch uninitialized fields. */

#define RTP_PRIO_REALTIME	PRI_REALTIME	/* real time process */
#define RTP_PRIO_NORMAL		PRI_TIMESHARE	/* time sharing process */
#define RTP_PRIO_IDLE		PRI_IDLE	/* idle process */

/* RTP_PRIO_FIFO is POSIX.1B SCHED_FIFO.
 */

#define RTP_PRIO_FIFO_BIT	PRI_FIFO_BIT
#define RTP_PRIO_FIFO		PRI_FIFO
#define RTP_PRIO_BASE(P)	PRI_BASE(P)
#define RTP_PRIO_IS_REALTIME(P) PRI_IS_REALTIME(P)
#define RTP_PRIO_NEED_RR(P)	PRI_NEED_RR(P)

/* priority range */
#define RTP_PRIO_MIN		0	/* Highest priority */
#define RTP_PRIO_MAX		31	/* Lowest priority */

/*
 * rtprio() syscall functions
 */
#define RTP_LOOKUP		0
#define RTP_SET			1

#ifndef LOCORE
/*
 * Scheduling class information.
 */
struct rtprio {
	u_short type;			/* scheduling class */
	u_short prio;
};

#ifdef _KERNEL
struct thread;
int	rtp_to_pri(struct rtprio *, struct thread *);
void	pri_to_rtp(struct thread *, struct rtprio *);
#endif
#endif

#ifndef _KERNEL
#include <sys/cdefs.h>

__BEGIN_DECLS
int	rtprio(int, pid_t, struct rtprio *);
int	rtprio_thread(int, lwpid_t, struct rtprio *);
__END_DECLS
#endif	/* !_KERNEL */
#endif	/* !_SYS_RTPRIO_H_ */


code:
/*-
 * Copyright (c) 2001 Jake Burkholder <jake@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/runq.h 177435 2008-03-20 05:51:16Z jeff $
 */

#ifndef	_RUNQ_H_
#define	_RUNQ_H_

#include <machine/runq.h>

struct thread;

/*
 * Run queue parameters.
 */

#define	RQ_NQS		(64)		/* Number of run queues. */
#define	RQ_PPQ		(4)		/* Priorities per queue. */

/*
 * Head of run queues.
 */
TAILQ_HEAD(rqhead, thread);

/*
 * Bit array which maintains the status of a run queue.  When a queue is
 * non-empty the bit corresponding to the queue number will be set.
 */
struct rqbits {
	rqb_word_t rqb_bits[RQB_LEN];
};

/*
 * Run queue structure.  Contains an array of run queues on which processes
 * are placed, and a structure to maintain the status of each queue.
 */
struct runq {
	struct	rqbits rq_status;
	struct	rqhead rq_queues[RQ_NQS];
};

void	runq_add(struct runq *, struct thread *, int);
void	runq_add_pri(struct runq *, struct thread *, u_char, int);
int	runq_check(struct runq *);
struct	thread *runq_choose(struct runq *);
struct	thread *runq_choose_from(struct runq *, u_char);
struct	thread *runq_choose_fuzz(struct runq *, int);
void	runq_init(struct runq *);
void	runq_remove(struct runq *, struct thread *);
void	runq_remove_idx(struct runq *, struct thread *, u_char *);

#endif


code:
/*-
 * Copyright (c) 2006 John Baldwin <jhb@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/rwlock.h 197643 2009-09-30 13:26:31Z attilio $
 */

#ifndef _SYS_RWLOCK_H_
#define _SYS_RWLOCK_H_

#include <sys/_lock.h>
#include <sys/_rwlock.h>
#include <sys/lock_profile.h>
#include <sys/lockstat.h>

#ifdef _KERNEL
#include <sys/pcpu.h>
#include <machine/atomic.h>
#endif

/*
 * The rw_lock field consists of several fields.  The low bit indicates
 * if the lock is locked with a read (shared) or write (exclusive) lock.
 * A value of 0 indicates a write lock, and a value of 1 indicates a read
 * lock.  Bit 1 is a boolean indicating if there are any threads waiting
 * for a read lock.  Bit 2 is a boolean indicating if there are any threads
 * waiting for a write lock.  The rest of the variable's definition is
 * dependent on the value of the first bit.  For a write lock, it is a
 * pointer to the thread holding the lock, similar to the mtx_lock field of
 * mutexes.  For read locks, it is a count of read locks that are held.
 *
 * When the lock is not locked by any thread, it is encoded as a read lock
 * with zero waiters.
 */

#define	RW_LOCK_READ		0x01
#define	RW_LOCK_READ_WAITERS	0x02
#define	RW_LOCK_WRITE_WAITERS	0x04
#define	RW_LOCK_WRITE_SPINNER	0x08
#define	RW_LOCK_FLAGMASK						\
	(RW_LOCK_READ | RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS |	\
	RW_LOCK_WRITE_SPINNER)
#define	RW_LOCK_WAITERS		(RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS)

#define	RW_OWNER(x)		((x) & ~RW_LOCK_FLAGMASK)
#define	RW_READERS_SHIFT	4
#define	RW_READERS(x)		(RW_OWNER((x)) >> RW_READERS_SHIFT)
#define	RW_READERS_LOCK(x)	((x) << RW_READERS_SHIFT | RW_LOCK_READ)
#define	RW_ONE_READER		(1 << RW_READERS_SHIFT)

#define	RW_UNLOCKED		RW_READERS_LOCK(0)
#define	RW_DESTROYED		(RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS)

#ifdef _KERNEL

#define	rw_recurse	lock_object.lo_data

/* Very simple operations on rw_lock. */

/* Try to obtain a write lock once. */
#define	_rw_write_lock(rw, tid)						\
	atomic_cmpset_acq_ptr(&(rw)->rw_lock, RW_UNLOCKED, (tid))

/* Release a write lock quickly if there are no waiters. */
#define	_rw_write_unlock(rw, tid)					\
	atomic_cmpset_rel_ptr(&(rw)->rw_lock, (tid), RW_UNLOCKED)

/*
 * Full lock operations that are suitable to be inlined in non-debug
 * kernels.  If the lock cannot be acquired or released trivially then
 * the work is deferred to another function.
 */

/* Acquire a write lock. */
#define	__rw_wlock(rw, tid, file, line) do {				\
	uintptr_t _tid = (uintptr_t)(tid);				\
						                        \
	if (!_rw_write_lock((rw), _tid))				\
		_rw_wlock_hard((rw), _tid, (file), (line));		\
	else 								\
		LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, \
		    rw, 0, 0, (file), (line));				\
} while (0)

/* Release a write lock. */
#define	__rw_wunlock(rw, tid, file, line) do {				\
	uintptr_t _tid = (uintptr_t)(tid);				\
									\
	if ((rw)->rw_recurse)						\
		(rw)->rw_recurse--;					\
	else if (!_rw_write_unlock((rw), _tid))				\
		_rw_wunlock_hard((rw), _tid, (file), (line));		\
} while (0)

/*
 * Function prototypes.  Routines that start with _ are not part of the
 * external API and should not be called directly.  Wrapper macros should
 * be used instead.
 */

#define	rw_init(rw, name)	rw_init_flags((rw), (name), 0)
void	rw_init_flags(struct rwlock *rw, const char *name, int opts);
void	rw_destroy(struct rwlock *rw);
void	rw_sysinit(void *arg);
void	rw_sysinit_flags(void *arg);
int	rw_wowned(struct rwlock *rw);
void	_rw_wlock(struct rwlock *rw, const char *file, int line);
int	_rw_try_wlock(struct rwlock *rw, const char *file, int line);
void	_rw_wunlock(struct rwlock *rw, const char *file, int line);
void	_rw_rlock(struct rwlock *rw, const char *file, int line);
int	_rw_try_rlock(struct rwlock *rw, const char *file, int line);
void	_rw_runlock(struct rwlock *rw, const char *file, int line);
void	_rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file,
	    int line);
void	_rw_wunlock_hard(struct rwlock *rw, uintptr_t tid, const char *file,
	    int line);
int	_rw_try_upgrade(struct rwlock *rw, const char *file, int line);
void	_rw_downgrade(struct rwlock *rw, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void	_rw_assert(struct rwlock *rw, int what, const char *file, int line);
#endif

/*
 * Public interface for lock operations.
 */

#ifndef LOCK_DEBUG
#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/rwlock.h>
#endif
#if LOCK_DEBUG > 0 || defined(RWLOCK_NOINLINE)
#define	rw_wlock(rw)		_rw_wlock((rw), LOCK_FILE, LOCK_LINE)
#define	rw_wunlock(rw)		_rw_wunlock((rw), LOCK_FILE, LOCK_LINE)
#else
#define	rw_wlock(rw)							\
	__rw_wlock((rw), curthread, LOCK_FILE, LOCK_LINE)
#define	rw_wunlock(rw)							\
	__rw_wunlock((rw), curthread, LOCK_FILE, LOCK_LINE)
#endif
#define	rw_rlock(rw)		_rw_rlock((rw), LOCK_FILE, LOCK_LINE)
#define	rw_runlock(rw)		_rw_runlock((rw), LOCK_FILE, LOCK_LINE)
#define	rw_try_rlock(rw)	_rw_try_rlock((rw), LOCK_FILE, LOCK_LINE)
#define	rw_try_upgrade(rw)	_rw_try_upgrade((rw), LOCK_FILE, LOCK_LINE)
#define	rw_try_wlock(rw)	_rw_try_wlock((rw), LOCK_FILE, LOCK_LINE)
#define	rw_downgrade(rw)	_rw_downgrade((rw), LOCK_FILE, LOCK_LINE)
#define	rw_unlock(rw)	do {						\
	if (rw_wowned(rw))						\
		rw_wunlock(rw);						\
	else								\
		rw_runlock(rw);						\
} while (0)
#define	rw_sleep(chan, rw, pri, wmesg, timo)				\
	_sleep((chan), &(rw)->lock_object, (pri), (wmesg), (timo))

#define	rw_initialized(rw)	lock_initalized(&(rw)->lock_object)

struct rw_args {
	struct rwlock	*ra_rw;
	const char 	*ra_desc;
};

struct rw_args_flags {
	struct rwlock	*ra_rw;
	const char 	*ra_desc;
	int		ra_flags;
};

#define	RW_SYSINIT(name, rw, desc)					\
	static struct rw_args name##_args = {				\
		(rw),							\
		(desc),							\
	};								\
	SYSINIT(name##_rw_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rw_sysinit, &name##_args);					\
	SYSUNINIT(name##_rw_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rw_destroy, (rw))

#define	RW_SYSINIT_FLAGS(name, rw, desc, flags)				\
	static struct rw_args_flags name##_args = {			\
		(rw),							\
		(desc),							\
		(flags),						\
	};								\
	SYSINIT(name##_rw_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rw_sysinit_flags, &name##_args);				\
	SYSUNINIT(name##_rw_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
	    rw_destroy, (rw))

/*
 * Options passed to rw_init_flags().
 */
#define	RW_DUPOK	0x01
#define	RW_NOPROFILE	0x02
#define	RW_NOWITNESS	0x04
#define	RW_QUIET	0x08
#define	RW_RECURSE	0x10

/*
 * The INVARIANTS-enabled rw_assert() functionality.
 *
 * The constants need to be defined for INVARIANT_SUPPORT infrastructure
 * support as _rw_assert() itself uses them and the latter implies that
 * _rw_assert() must build.
 */
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#define	RA_LOCKED		LA_LOCKED
#define	RA_RLOCKED		LA_SLOCKED
#define	RA_WLOCKED		LA_XLOCKED
#define	RA_UNLOCKED		LA_UNLOCKED
#define	RA_RECURSED		LA_RECURSED
#define	RA_NOTRECURSED		LA_NOTRECURSED
#endif

#ifdef INVARIANTS
#define	rw_assert(rw, what)	_rw_assert((rw), (what), LOCK_FILE, LOCK_LINE)
#else
#define	rw_assert(rw, what)
#endif

#endif /* _KERNEL */
#endif /* !_SYS_RWLOCK_H_ */


code:
/*-
 * Copyright (c) 2000-2008 Poul-Henning Kamp
 * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      $FreeBSD: release/9.0.0/sys/sys/sbuf.h 221993 2011-05-16 16:18:40Z phk $
 */

#ifndef _SYS_SBUF_H_
#define	_SYS_SBUF_H_

#include <sys/_types.h>

struct sbuf;
typedef int (sbuf_drain_func)(void *, const char *, int);

/*
 * Structure definition
 */
struct sbuf {
	char		*s_buf;		/* storage buffer */
	sbuf_drain_func	*s_drain_func;	/* drain function */
	void		*s_drain_arg;	/* user-supplied drain argument */
	int		 s_error;	/* current error code */
	ssize_t		 s_size;	/* size of storage buffer */
	ssize_t		 s_len;		/* current length of string */
#define	SBUF_FIXEDLEN	0x00000000	/* fixed length buffer (default) */
#define	SBUF_AUTOEXTEND	0x00000001	/* automatically extend buffer */
#define	SBUF_USRFLAGMSK	0x0000ffff	/* mask of flags the user may specify */
#define	SBUF_DYNAMIC	0x00010000	/* s_buf must be freed */
#define	SBUF_FINISHED	0x00020000	/* set by sbuf_finish() */
#define	SBUF_DYNSTRUCT	0x00080000	/* sbuf must be freed */
	int		 s_flags;	/* flags */
};

__BEGIN_DECLS
/*
 * API functions
 */
struct sbuf	*sbuf_new(struct sbuf *, char *, int, int);
#define		 sbuf_new_auto()				\
	sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND)
void		 sbuf_clear(struct sbuf *);
int		 sbuf_setpos(struct sbuf *, ssize_t);
int		 sbuf_bcat(struct sbuf *, const void *, size_t);
int		 sbuf_bcpy(struct sbuf *, const void *, size_t);
int		 sbuf_cat(struct sbuf *, const char *);
int		 sbuf_cpy(struct sbuf *, const char *);
int		 sbuf_printf(struct sbuf *, const char *, ...)
	__printflike(2, 3);
int		 sbuf_vprintf(struct sbuf *, const char *, __va_list)
	__printflike(2, 0);
int		 sbuf_putc(struct sbuf *, int);
void		 sbuf_set_drain(struct sbuf *, sbuf_drain_func *, void *);
int		 sbuf_trim(struct sbuf *);
int		 sbuf_error(const struct sbuf *);
int		 sbuf_finish(struct sbuf *);
char		*sbuf_data(struct sbuf *);
ssize_t		 sbuf_len(struct sbuf *);
int		 sbuf_done(const struct sbuf *);
void		 sbuf_delete(struct sbuf *);

#ifdef _KERNEL
struct uio;
struct sbuf	*sbuf_uionew(struct sbuf *, struct uio *, int *);
int		 sbuf_bcopyin(struct sbuf *, const void *, size_t);
int		 sbuf_copyin(struct sbuf *, const void *, size_t);
#endif
__END_DECLS

#endif


code:
/*-
 * Copyright (c) 1996, 1997
 *      HD Associates, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by HD Associates, Inc
 *      and Jukka Antero Ukkonen.
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*-
 * Copyright (c) 2002-2008, Jeffrey Roberson <jeff@freebsd.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice unmodified, this list of conditions, and the following
 *    disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/sched.h 216791 2010-12-29 09:26:46Z davidxu $
 */

#ifndef _SCHED_H_
#define	_SCHED_H_

#ifdef _KERNEL
/*
 * General scheduling info.
 *
 * sched_load:
 *	Total runnable non-ithread threads in the system.
 *
 * sched_runnable:
 *	Runnable threads for this processor.
 */
int	sched_load(void);
int	sched_rr_interval(void);
int	sched_runnable(void);

/*
 * Proc related scheduling hooks.
 */
void	sched_exit(struct proc *p, struct thread *childtd);
void	sched_fork(struct thread *td, struct thread *childtd);
void	sched_fork_exit(struct thread *td);
void	sched_class(struct thread *td, int class);
void	sched_nice(struct proc *p, int nice);

/*
 * Threads are switched in and out, block on resources, have temporary
 * priorities inherited from their procs, and use up cpu time.
 */
void	sched_exit_thread(struct thread *td, struct thread *child);
void	sched_fork_thread(struct thread *td, struct thread *child);
void	sched_lend_prio(struct thread *td, u_char prio);
void	sched_lend_user_prio(struct thread *td, u_char pri);
fixpt_t	sched_pctcpu(struct thread *td);
void	sched_prio(struct thread *td, u_char prio);
void	sched_sleep(struct thread *td, int prio);
void	sched_switch(struct thread *td, struct thread *newtd, int flags);
void	sched_throw(struct thread *td);
void	sched_unlend_prio(struct thread *td, u_char prio);
void	sched_user_prio(struct thread *td, u_char prio);
void	sched_userret(struct thread *td);
void	sched_wakeup(struct thread *td);
void	sched_preempt(struct thread *td);

/*
 * Threads are moved on and off of run queues
 */
void	sched_add(struct thread *td, int flags);
void	sched_clock(struct thread *td);
void	sched_rem(struct thread *td);
void	sched_tick(int cnt);
void	sched_relinquish(struct thread *td);
struct thread *sched_choose(void);
void	sched_idletd(void *);

/*
 * Binding makes cpu affinity permanent while pinning is used to temporarily
 * hold a thread on a particular CPU.
 */
void	sched_bind(struct thread *td, int cpu);
static __inline void sched_pin(void);
void	sched_unbind(struct thread *td);
static __inline void sched_unpin(void);
int	sched_is_bound(struct thread *td);
void	sched_affinity(struct thread *td);

/*
 * These procedures tell the process data structure allocation code how
 * many bytes to actually allocate.
 */
int	sched_sizeof_proc(void);
int	sched_sizeof_thread(void);

/*
 * This routine provides a consistent thread name for use with KTR graphing
 * functions.
 */
char	*sched_tdname(struct thread *td);

static __inline void
sched_pin(void)
{
	curthread->td_pinned++;
}

static __inline void
sched_unpin(void)
{
	curthread->td_pinned--;
}

/* sched_add arguments (formerly setrunqueue) */
#define	SRQ_BORING	0x0000		/* No special circumstances. */
#define	SRQ_YIELDING	0x0001		/* We are yielding (from mi_switch). */
#define	SRQ_OURSELF	0x0002		/* It is ourself (from mi_switch). */
#define	SRQ_INTR	0x0004		/* It is probably urgent. */
#define	SRQ_PREEMPTED	0x0008		/* has been preempted.. be kind */
#define	SRQ_BORROWING	0x0010		/* Priority updated due to prio_lend */

/* Scheduler stats. */
#ifdef SCHED_STATS
DPCPU_DECLARE(long, sched_switch_stats[SWT_COUNT]);

#define	SCHED_STAT_DEFINE_VAR(name, ptr, descr)				\
static void name ## _add_proc(void *dummy __unused)			\
{									\
									\
	SYSCTL_ADD_PROC(NULL,						\
	    SYSCTL_STATIC_CHILDREN(_kern_sched_stats), OID_AUTO,	\
	    #name, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,		\
	    ptr, 0, sysctl_dpcpu_long, "LU", descr);			\
}									\
SYSINIT(name, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, name ## _add_proc, NULL);

#define	SCHED_STAT_DEFINE(name, descr)					\
    DPCPU_DEFINE(unsigned long, name);					\
    SCHED_STAT_DEFINE_VAR(name, &DPCPU_NAME(name), descr)
/*
 * Sched stats are always incremented in critical sections so no atomic
 * is necesssary to increment them.
 */
#define SCHED_STAT_INC(var)     DPCPU_GET(var)++;
#else
#define	SCHED_STAT_DEFINE_VAR(name, descr, ptr)
#define	SCHED_STAT_DEFINE(name, descr)
#define SCHED_STAT_INC(var)			(void)0
#endif

/*
 * Fixup scheduler state for proc0 and thread0
 */
void schedinit(void);
#endif /* _KERNEL */

/* POSIX 1003.1b Process Scheduling */

/*
 * POSIX scheduling policies
 */
#define SCHED_FIFO      1
#define SCHED_OTHER     2
#define SCHED_RR        3

struct sched_param {
        int     sched_priority;
};

/*
 * POSIX scheduling declarations for userland.
 */
#ifndef _KERNEL
#include <sys/cdefs.h>
#include <sys/_types.h>

#ifndef _PID_T_DECLARED
typedef __pid_t         pid_t;
#define _PID_T_DECLARED
#endif

struct timespec;

__BEGIN_DECLS
int     sched_get_priority_max(int);
int     sched_get_priority_min(int);
int     sched_getparam(pid_t, struct sched_param *);
int     sched_getscheduler(pid_t);
int     sched_rr_get_interval(pid_t, struct timespec *);
int     sched_setparam(pid_t, const struct sched_param *);
int     sched_setscheduler(pid_t, int, const struct sched_param *);
int     sched_yield(void);
__END_DECLS

#endif
#endif /* !_SCHED_H_ */