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