1eda14cbcSMatt Macy /* 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * Redistribution and use in source and binary forms, with or without 5eda14cbcSMatt Macy * modification, are permitted provided that the following conditions 6eda14cbcSMatt Macy * are met: 7eda14cbcSMatt Macy * 1. Redistributions of source code must retain the above copyright 8eda14cbcSMatt Macy * notice, this list of conditions and the following disclaimer. 9eda14cbcSMatt Macy * 2. Redistributions in binary form must reproduce the above copyright 10eda14cbcSMatt Macy * notice, this list of conditions and the following disclaimer in the 11eda14cbcSMatt Macy * documentation and/or other materials provided with the distribution. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14eda14cbcSMatt Macy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15eda14cbcSMatt Macy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16eda14cbcSMatt Macy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17eda14cbcSMatt Macy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18eda14cbcSMatt Macy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19eda14cbcSMatt Macy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20eda14cbcSMatt Macy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21eda14cbcSMatt Macy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22eda14cbcSMatt Macy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23eda14cbcSMatt Macy * SUCH DAMAGE. 24eda14cbcSMatt Macy * 25eda14cbcSMatt Macy * $FreeBSD$ 26eda14cbcSMatt Macy */ 27eda14cbcSMatt Macy 28eda14cbcSMatt Macy #ifndef _SYS_CCOMPAT_H 29eda14cbcSMatt Macy #define _SYS_CCOMPAT_H 30eda14cbcSMatt Macy 31eda14cbcSMatt Macy struct hlist_node { 32eda14cbcSMatt Macy struct hlist_node *next, **pprev; 33eda14cbcSMatt Macy }; 34eda14cbcSMatt Macy 35eda14cbcSMatt Macy struct hlist_head { 36eda14cbcSMatt Macy struct hlist_node *first; 37eda14cbcSMatt Macy }; 38eda14cbcSMatt Macy 39eda14cbcSMatt Macy typedef struct { 40eda14cbcSMatt Macy volatile int counter; 41eda14cbcSMatt Macy } atomic_t; 42eda14cbcSMatt Macy 43eda14cbcSMatt Macy #define hlist_for_each(p, head) \ 44eda14cbcSMatt Macy for (p = (head)->first; p; p = (p)->next) 45eda14cbcSMatt Macy 46eda14cbcSMatt Macy #define hlist_entry(ptr, type, field) container_of(ptr, type, field) 47eda14cbcSMatt Macy 48eda14cbcSMatt Macy #define container_of(ptr, type, member) \ 49c03c5b1cSMartin Matuska /* CSTYLED */ \ 50eda14cbcSMatt Macy ({ \ 51eda14cbcSMatt Macy const __typeof(((type *)0)->member) *__p = (ptr); \ 52eda14cbcSMatt Macy (type *)((uintptr_t)__p - offsetof(type, member)); \ 53eda14cbcSMatt Macy }) 54eda14cbcSMatt Macy 55eda14cbcSMatt Macy static inline void 56eda14cbcSMatt Macy hlist_add_head(struct hlist_node *n, struct hlist_head *h) 57eda14cbcSMatt Macy { 58eda14cbcSMatt Macy n->next = h->first; 59eda14cbcSMatt Macy if (h->first != NULL) 60eda14cbcSMatt Macy h->first->pprev = &n->next; 61eda14cbcSMatt Macy WRITE_ONCE(h->first, n); 62eda14cbcSMatt Macy n->pprev = &h->first; 63eda14cbcSMatt Macy } 64eda14cbcSMatt Macy 65eda14cbcSMatt Macy static inline void 66eda14cbcSMatt Macy hlist_del(struct hlist_node *n) 67eda14cbcSMatt Macy { 68eda14cbcSMatt Macy WRITE_ONCE(*(n->pprev), n->next); 69eda14cbcSMatt Macy if (n->next != NULL) 70eda14cbcSMatt Macy n->next->pprev = n->pprev; 71eda14cbcSMatt Macy } 72eda14cbcSMatt Macy /* BEGIN CSTYLED */ 73eda14cbcSMatt Macy #define HLIST_HEAD_INIT { } 74eda14cbcSMatt Macy #define HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT 75eda14cbcSMatt Macy #define INIT_HLIST_HEAD(head) (head)->first = NULL 76eda14cbcSMatt Macy 77eda14cbcSMatt Macy #define INIT_HLIST_NODE(node) \ 78eda14cbcSMatt Macy do { \ 79eda14cbcSMatt Macy (node)->next = NULL; \ 80eda14cbcSMatt Macy (node)->pprev = NULL; \ 81eda14cbcSMatt Macy } while (0) 82eda14cbcSMatt Macy 83eda14cbcSMatt Macy /* END CSTYLED */ 84eda14cbcSMatt Macy static inline int 85eda14cbcSMatt Macy atomic_read(const atomic_t *v) 86eda14cbcSMatt Macy { 87eda14cbcSMatt Macy return (READ_ONCE(v->counter)); 88eda14cbcSMatt Macy } 89eda14cbcSMatt Macy 90eda14cbcSMatt Macy static inline int 91eda14cbcSMatt Macy atomic_inc(atomic_t *v) 92eda14cbcSMatt Macy { 93eda14cbcSMatt Macy return (atomic_fetchadd_int(&v->counter, 1) + 1); 94eda14cbcSMatt Macy } 95eda14cbcSMatt Macy 96eda14cbcSMatt Macy static inline int 97eda14cbcSMatt Macy atomic_dec(atomic_t *v) 98eda14cbcSMatt Macy { 99eda14cbcSMatt Macy return (atomic_fetchadd_int(&v->counter, -1) - 1); 100eda14cbcSMatt Macy } 101eda14cbcSMatt Macy #endif 102