1250551Sjeff/* 2250551Sjeff * Copyright (c) 2013 EMC Corp. 3250551Sjeff * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org> 4250551Sjeff * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com> 5250551Sjeff * All rights reserved. 6250551Sjeff * 7250551Sjeff * Redistribution and use in source and binary forms, with or without 8250551Sjeff * modification, are permitted provided that the following conditions 9250551Sjeff * are met: 10250551Sjeff * 1. Redistributions of source code must retain the above copyright 11250551Sjeff * notice, this list of conditions and the following disclaimer. 12250551Sjeff * 2. Redistributions in binary form must reproduce the above copyright 13250551Sjeff * notice, this list of conditions and the following disclaimer in the 14250551Sjeff * documentation and/or other materials provided with the distribution. 15250551Sjeff * 16250551Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17250551Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18250551Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19250551Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20250551Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21250551Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22250551Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23250551Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24250551Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25250551Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26250551Sjeff * SUCH DAMAGE. 27250551Sjeff * 28250551Sjeff * $FreeBSD$ 29250551Sjeff */ 30250551Sjeff 31250551Sjeff#ifndef _SYS_PCTRIE_H_ 32250551Sjeff#define _SYS_PCTRIE_H_ 33250551Sjeff 34250551Sjeff#include <sys/_pctrie.h> 35250551Sjeff 36250551Sjeff#ifdef _KERNEL 37250551Sjeff 38250551Sjeff#define PCTRIE_DEFINE(name, type, field, allocfn, freefn) \ 39250551Sjeff \ 40250551SjeffCTASSERT(sizeof(((struct type *)0)->field) == sizeof(uint64_t)); \ 41250578Sjeff/* \ 42250578Sjeff * XXX This assert protects flag bits, it does not enforce natural \ 43250578Sjeff * alignment. 32bit architectures do not naturally align 64bit fields. \ 44250578Sjeff */ \ 45250578SjeffCTASSERT((__offsetof(struct type, field) & (sizeof(uint32_t) - 1)) == 0); \ 46250551Sjeff \ 47250551Sjeffstatic __inline struct type * \ 48250551Sjeffname##_PCTRIE_VAL2PTR(uint64_t *val) \ 49250551Sjeff{ \ 50250551Sjeff \ 51250551Sjeff if (val == NULL) \ 52250551Sjeff return (NULL); \ 53250551Sjeff return (struct type *) \ 54250551Sjeff ((uintptr_t)val - __offsetof(struct type, field)); \ 55250551Sjeff} \ 56250551Sjeff \ 57250551Sjeffstatic __inline uint64_t * \ 58250551Sjeffname##_PCTRIE_PTR2VAL(struct type *ptr) \ 59250551Sjeff{ \ 60250551Sjeff \ 61250551Sjeff return &ptr->field; \ 62250551Sjeff} \ 63250551Sjeff \ 64250551Sjeffstatic __inline int \ 65250551Sjeffname##_PCTRIE_INSERT(struct pctrie *ptree, struct type *ptr) \ 66250551Sjeff{ \ 67250551Sjeff \ 68250551Sjeff return pctrie_insert(ptree, name##_PCTRIE_PTR2VAL(ptr), \ 69250551Sjeff allocfn); \ 70250551Sjeff} \ 71250551Sjeff \ 72250551Sjeffstatic __inline struct type * \ 73250551Sjeffname##_PCTRIE_LOOKUP(struct pctrie *ptree, uint64_t key) \ 74250551Sjeff{ \ 75250551Sjeff \ 76250551Sjeff return name##_PCTRIE_VAL2PTR(pctrie_lookup(ptree, key)); \ 77250551Sjeff} \ 78250551Sjeff \ 79250551Sjeffstatic __inline struct type * \ 80250551Sjeffname##_PCTRIE_LOOKUP_LE(struct pctrie *ptree, uint64_t key) \ 81250551Sjeff{ \ 82250551Sjeff \ 83250551Sjeff return name##_PCTRIE_VAL2PTR(pctrie_lookup_le(ptree, key)); \ 84250551Sjeff} \ 85250551Sjeff \ 86260266Sdimstatic __inline __unused struct type * \ 87250551Sjeffname##_PCTRIE_LOOKUP_GE(struct pctrie *ptree, uint64_t key) \ 88250551Sjeff{ \ 89250551Sjeff \ 90250551Sjeff return name##_PCTRIE_VAL2PTR(pctrie_lookup_ge(ptree, key)); \ 91250551Sjeff} \ 92250551Sjeff \ 93260266Sdimstatic __inline __unused void \ 94250551Sjeffname##_PCTRIE_RECLAIM(struct pctrie *ptree) \ 95250551Sjeff{ \ 96250551Sjeff \ 97250551Sjeff pctrie_reclaim_allnodes(ptree, freefn); \ 98250551Sjeff} \ 99250551Sjeff \ 100250551Sjeffstatic __inline void \ 101250551Sjeffname##_PCTRIE_REMOVE(struct pctrie *ptree, uint64_t key) \ 102250551Sjeff{ \ 103250551Sjeff \ 104250551Sjeff pctrie_remove(ptree, key, freefn); \ 105250551Sjeff} 106250551Sjeff 107250551Sjefftypedef void *(*pctrie_alloc_t)(struct pctrie *ptree); 108250551Sjefftypedef void (*pctrie_free_t)(struct pctrie *ptree, void *node); 109250551Sjeff 110250551Sjeffint pctrie_insert(struct pctrie *ptree, uint64_t *val, 111250551Sjeff pctrie_alloc_t allocfn); 112250551Sjeffuint64_t *pctrie_lookup(struct pctrie *ptree, uint64_t key); 113250551Sjeffuint64_t *pctrie_lookup_ge(struct pctrie *ptree, uint64_t key); 114250551Sjeffuint64_t *pctrie_lookup_le(struct pctrie *ptree, uint64_t key); 115250551Sjeffvoid pctrie_reclaim_allnodes(struct pctrie *ptree, 116250551Sjeff pctrie_free_t freefn); 117250551Sjeffvoid pctrie_remove(struct pctrie *ptree, uint64_t key, 118250551Sjeff pctrie_free_t freefn); 119250551Sjeffsize_t pctrie_node_size(void); 120250551Sjeffint pctrie_zone_init(void *mem, int size, int flags); 121250551Sjeff 122250551Sjeff#endif /* _KERNEL */ 123250551Sjeff#endif /* !_SYS_PCTRIE_H_ */ 124