xref: /netbsd-src/common/lib/libprop/prop_object_impl.h (revision 6620d0c742a83dd1df44b8aafc725336ff288696)
1*6620d0c7Sthorpej /*	$NetBSD: prop_object_impl.h,v 1.36 2020/06/12 00:02:26 thorpej Exp $	*/
2774eb1a3Sthorpej 
3774eb1a3Sthorpej /*-
4a792b843Sthorpej  * Copyright (c) 2006, 2020 The NetBSD Foundation, Inc.
5774eb1a3Sthorpej  * All rights reserved.
6774eb1a3Sthorpej  *
7774eb1a3Sthorpej  * This code is derived from software contributed to The NetBSD Foundation
8774eb1a3Sthorpej  * by Jason R. Thorpe.
9774eb1a3Sthorpej  *
10774eb1a3Sthorpej  * Redistribution and use in source and binary forms, with or without
11774eb1a3Sthorpej  * modification, are permitted provided that the following conditions
12774eb1a3Sthorpej  * are met:
13774eb1a3Sthorpej  * 1. Redistributions of source code must retain the above copyright
14774eb1a3Sthorpej  *    notice, this list of conditions and the following disclaimer.
15774eb1a3Sthorpej  * 2. Redistributions in binary form must reproduce the above copyright
16774eb1a3Sthorpej  *    notice, this list of conditions and the following disclaimer in the
17774eb1a3Sthorpej  *    documentation and/or other materials provided with the distribution.
18774eb1a3Sthorpej  *
19774eb1a3Sthorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20774eb1a3Sthorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21774eb1a3Sthorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22774eb1a3Sthorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23774eb1a3Sthorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24774eb1a3Sthorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25774eb1a3Sthorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26774eb1a3Sthorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27774eb1a3Sthorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28774eb1a3Sthorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29774eb1a3Sthorpej  * POSSIBILITY OF SUCH DAMAGE.
30774eb1a3Sthorpej  */
31774eb1a3Sthorpej 
32774eb1a3Sthorpej #ifndef _PROPLIB_PROP_OBJECT_IMPL_H_
33774eb1a3Sthorpej #define	_PROPLIB_PROP_OBJECT_IMPL_H_
34774eb1a3Sthorpej 
358319f966Sthorpej #if defined(HAVE_NBTOOL_CONFIG_H)
368319f966Sthorpej #include "nbtool_config.h"
378319f966Sthorpej #endif
388319f966Sthorpej 
3925b42587Sthorpej #if defined(_KERNEL) || defined(_STANDALONE)
4025b42587Sthorpej #include <lib/libkern/libkern.h>
4125b42587Sthorpej #else
4225b42587Sthorpej #include <inttypes.h>
4325b42587Sthorpej #endif
4425b42587Sthorpej 
45e835604cSjoerg #include "prop_stack.h"
46e835604cSjoerg 
47774eb1a3Sthorpej struct _prop_object_externalize_context {
48774eb1a3Sthorpej 	char *		poec_buf;		/* string buffer */
49774eb1a3Sthorpej 	size_t		poec_capacity;		/* capacity of buffer */
50774eb1a3Sthorpej 	size_t		poec_len;		/* current length of string */
51774eb1a3Sthorpej 	unsigned int	poec_depth;		/* nesting depth */
52774eb1a3Sthorpej };
53774eb1a3Sthorpej 
5404377267Sthorpej bool		_prop_object_externalize_start_tag(
55774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
56774eb1a3Sthorpej 				const char *);
5704377267Sthorpej bool		_prop_object_externalize_end_tag(
58774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
59774eb1a3Sthorpej 				const char *);
6004377267Sthorpej bool		_prop_object_externalize_empty_tag(
61774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
62774eb1a3Sthorpej 				const char *);
6304377267Sthorpej bool		_prop_object_externalize_append_cstring(
64774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
65774eb1a3Sthorpej 				const char *);
6604377267Sthorpej bool		_prop_object_externalize_append_encoded_cstring(
67774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
68774eb1a3Sthorpej 				const char *);
6904377267Sthorpej bool		_prop_object_externalize_append_char(
70774eb1a3Sthorpej 				struct _prop_object_externalize_context *,
71774eb1a3Sthorpej 				unsigned char);
7204377267Sthorpej bool		_prop_object_externalize_header(
73d21620b2Sthorpej 				struct _prop_object_externalize_context *);
7404377267Sthorpej bool		_prop_object_externalize_footer(
75d21620b2Sthorpej 				struct _prop_object_externalize_context *);
76774eb1a3Sthorpej 
77774eb1a3Sthorpej struct _prop_object_externalize_context *
78774eb1a3Sthorpej 	_prop_object_externalize_context_alloc(void);
79774eb1a3Sthorpej void	_prop_object_externalize_context_free(
80774eb1a3Sthorpej 				struct _prop_object_externalize_context *);
81774eb1a3Sthorpej 
82774eb1a3Sthorpej typedef enum {
83774eb1a3Sthorpej 	_PROP_TAG_TYPE_START,			/* e.g. <dict> */
84774eb1a3Sthorpej 	_PROP_TAG_TYPE_END,			/* e.g. </dict> */
85774eb1a3Sthorpej 	_PROP_TAG_TYPE_EITHER
86774eb1a3Sthorpej } _prop_tag_type_t;
87774eb1a3Sthorpej 
88774eb1a3Sthorpej struct _prop_object_internalize_context {
89774eb1a3Sthorpej 	const char *poic_xml;
90774eb1a3Sthorpej 	const char *poic_cp;
91774eb1a3Sthorpej 
92774eb1a3Sthorpej 	const char *poic_tag_start;
93774eb1a3Sthorpej 
94774eb1a3Sthorpej 	const char *poic_tagname;
95774eb1a3Sthorpej 	size_t      poic_tagname_len;
96774eb1a3Sthorpej 	const char *poic_tagattr;
97774eb1a3Sthorpej 	size_t      poic_tagattr_len;
98774eb1a3Sthorpej 	const char *poic_tagattrval;
99774eb1a3Sthorpej 	size_t      poic_tagattrval_len;
100774eb1a3Sthorpej 
10104377267Sthorpej 	bool   poic_is_empty_element;
102774eb1a3Sthorpej 	_prop_tag_type_t poic_tag_type;
103774eb1a3Sthorpej };
104774eb1a3Sthorpej 
1054ce0dc3aSthorpej typedef enum {
106e835604cSjoerg 	_PROP_OBJECT_FREE_DONE,
107e835604cSjoerg 	_PROP_OBJECT_FREE_RECURSE,
108e835604cSjoerg 	_PROP_OBJECT_FREE_FAILED
1094ce0dc3aSthorpej } _prop_object_free_rv_t;
110e835604cSjoerg 
1114ce0dc3aSthorpej typedef enum {
1124deb5931Sjoerg 	_PROP_OBJECT_EQUALS_FALSE,
1134deb5931Sjoerg 	_PROP_OBJECT_EQUALS_TRUE,
1144deb5931Sjoerg 	_PROP_OBJECT_EQUALS_RECURSE
1154ce0dc3aSthorpej } _prop_object_equals_rv_t;
1164deb5931Sjoerg 
117774eb1a3Sthorpej #define	_PROP_EOF(c)		((c) == '\0')
118774eb1a3Sthorpej #define	_PROP_ISSPACE(c)	\
119272b1fe3Schristos 	((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
120774eb1a3Sthorpej 
121774eb1a3Sthorpej #define	_PROP_TAG_MATCH(ctx, t)					\
122774eb1a3Sthorpej 	_prop_object_internalize_match((ctx)->poic_tagname,	\
123774eb1a3Sthorpej 				       (ctx)->poic_tagname_len,	\
124774eb1a3Sthorpej 				       (t), strlen(t))
125774eb1a3Sthorpej 
126774eb1a3Sthorpej #define	_PROP_TAGATTR_MATCH(ctx, a)				\
127774eb1a3Sthorpej 	_prop_object_internalize_match((ctx)->poic_tagattr,	\
128774eb1a3Sthorpej 				       (ctx)->poic_tagattr_len,	\
129774eb1a3Sthorpej 				       (a), strlen(a))
130774eb1a3Sthorpej 
131774eb1a3Sthorpej #define	_PROP_TAGATTRVAL_MATCH(ctx, a)				  \
132774eb1a3Sthorpej 	_prop_object_internalize_match((ctx)->poic_tagattrval,	  \
133774eb1a3Sthorpej 				       (ctx)->poic_tagattrval_len,\
134774eb1a3Sthorpej 				       (a), strlen(a))
135774eb1a3Sthorpej 
13604377267Sthorpej bool		_prop_object_internalize_find_tag(
137774eb1a3Sthorpej 				struct _prop_object_internalize_context *,
138774eb1a3Sthorpej 				const char *, _prop_tag_type_t);
13904377267Sthorpej bool		_prop_object_internalize_match(const char *, size_t,
140774eb1a3Sthorpej 					       const char *, size_t);
141774eb1a3Sthorpej prop_object_t	_prop_object_internalize_by_tag(
142774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
14304377267Sthorpej bool		_prop_object_internalize_decode_string(
144774eb1a3Sthorpej 				struct _prop_object_internalize_context *,
145774eb1a3Sthorpej 				char *, size_t, size_t *, const char **);
14639dccbf2Sjoerg prop_object_t	_prop_generic_internalize(const char *, const char *);
147774eb1a3Sthorpej 
148774eb1a3Sthorpej struct _prop_object_internalize_context *
149774eb1a3Sthorpej 		_prop_object_internalize_context_alloc(const char *);
150774eb1a3Sthorpej void		_prop_object_internalize_context_free(
151774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
152774eb1a3Sthorpej 
153d21620b2Sthorpej #if !defined(_KERNEL) && !defined(_STANDALONE)
15404377267Sthorpej bool		_prop_object_externalize_write_file(const char *,
155d21620b2Sthorpej 						    const char *, size_t);
156d21620b2Sthorpej 
157d21620b2Sthorpej struct _prop_object_internalize_mapped_file {
158d21620b2Sthorpej 	char *	poimf_xml;
159d21620b2Sthorpej 	size_t	poimf_mapsize;
160d21620b2Sthorpej };
161d21620b2Sthorpej 
162d21620b2Sthorpej struct _prop_object_internalize_mapped_file *
163d21620b2Sthorpej 		_prop_object_internalize_map_file(const char *);
164d21620b2Sthorpej void		_prop_object_internalize_unmap_file(
165d21620b2Sthorpej 				struct _prop_object_internalize_mapped_file *);
166d21620b2Sthorpej #endif /* !_KERNEL && !_STANDALONE */
167d21620b2Sthorpej 
168e835604cSjoerg typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
169e835604cSjoerg 				struct _prop_object_internalize_context *);
1704ce0dc3aSthorpej typedef bool (*prop_object_internalizer_continue_t)(prop_stack_t,
1714ce0dc3aSthorpej 				prop_object_t *,
1724ce0dc3aSthorpej 				struct _prop_object_internalize_context *,
1734ce0dc3aSthorpej 				void *, prop_object_t);
174e835604cSjoerg 
175774eb1a3Sthorpej 	/* These are here because they're required by shared code. */
176e835604cSjoerg bool		_prop_array_internalize(prop_stack_t, prop_object_t *,
177774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
178e835604cSjoerg bool		_prop_bool_internalize(prop_stack_t, prop_object_t *,
179774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
180e835604cSjoerg bool		_prop_data_internalize(prop_stack_t, prop_object_t *,
181774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
182e835604cSjoerg bool		_prop_dictionary_internalize(prop_stack_t, prop_object_t *,
183774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
184e835604cSjoerg bool		_prop_number_internalize(prop_stack_t, prop_object_t *,
185774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
186e835604cSjoerg bool		_prop_string_internalize(prop_stack_t, prop_object_t *,
187774eb1a3Sthorpej 				struct _prop_object_internalize_context *);
188774eb1a3Sthorpej 
1893e69f1b2Sthorpej struct _prop_object_type {
190e835604cSjoerg 	/* type indicator */
191e835604cSjoerg 	uint32_t	pot_type;
192e835604cSjoerg 	/* func to free object */
1934ce0dc3aSthorpej 	_prop_object_free_rv_t
1944ce0dc3aSthorpej 			(*pot_free)(prop_stack_t, prop_object_t *);
195e835604cSjoerg 	/*
196e835604cSjoerg 	 * func to free the child returned by pot_free with stack == NULL.
197e835604cSjoerg 	 *
1984deb5931Sjoerg 	 * Must be implemented if pot_free can return anything other than
1994deb5931Sjoerg 	 * _PROP_OBJECT_FREE_DONE.
200e835604cSjoerg 	 */
201e835604cSjoerg 	void	(*pot_emergency_free)(prop_object_t);
202e835604cSjoerg 	/* func to externalize object */
203e835604cSjoerg 	bool	(*pot_extern)(struct _prop_object_externalize_context *,
204774eb1a3Sthorpej 			      void *);
205e835604cSjoerg 	/* func to test quality */
2064ce0dc3aSthorpej 	_prop_object_equals_rv_t
2074ce0dc3aSthorpej 		(*pot_equals)(prop_object_t, prop_object_t,
2084deb5931Sjoerg 			      void **, void **,
2094deb5931Sjoerg 			      prop_object_t *, prop_object_t *);
2104deb5931Sjoerg 	/*
2114deb5931Sjoerg 	 * func to finish equality iteration.
2124deb5931Sjoerg 	 *
2134deb5931Sjoerg 	 * Must be implemented if pot_equals can return
2144deb5931Sjoerg 	 * _PROP_OBJECT_EQUALS_RECURSE
2154deb5931Sjoerg 	 */
2164deb5931Sjoerg 	void	(*pot_equals_finish)(prop_object_t, prop_object_t);
217e51aea32Shaad 	void    (*pot_lock)(void);
218e51aea32Shaad 	void    (*pot_unlock)(void);
219774eb1a3Sthorpej };
220774eb1a3Sthorpej 
2213e69f1b2Sthorpej struct _prop_object {
2223e69f1b2Sthorpej 	const struct _prop_object_type *po_type;/* type descriptor */
2233e69f1b2Sthorpej 	uint32_t	po_refcnt;		/* reference count */
2243e69f1b2Sthorpej };
2253e69f1b2Sthorpej 
2263e69f1b2Sthorpej void		_prop_object_init(struct _prop_object *,
2273e69f1b2Sthorpej 				  const struct _prop_object_type *);
228774eb1a3Sthorpej void		_prop_object_fini(struct _prop_object *);
229774eb1a3Sthorpej 
230774eb1a3Sthorpej struct _prop_object_iterator {
231774eb1a3Sthorpej 	prop_object_t	(*pi_next_object)(void *);
232774eb1a3Sthorpej 	void		(*pi_reset)(void *);
233774eb1a3Sthorpej 	prop_object_t	pi_obj;
234774eb1a3Sthorpej 	uint32_t	pi_version;
235774eb1a3Sthorpej };
236774eb1a3Sthorpej 
237b6e6025dSpooka #define _PROP_NOTHREAD_ONCE_DECL(x)	static bool x = false;
238b6e6025dSpooka #define _PROP_NOTHREAD_ONCE_RUN(x,f)					\
239b6e6025dSpooka 	do {								\
240b6e6025dSpooka 		if ((x) == false) {					\
241b6e6025dSpooka 			f();						\
242b6e6025dSpooka 			x = true;					\
243b6e6025dSpooka 		}							\
244b6e6025dSpooka 	} while (/*CONSTCOND*/0)
245b6e6025dSpooka 
246774eb1a3Sthorpej #if defined(_KERNEL)
247774eb1a3Sthorpej 
248774eb1a3Sthorpej /*
249774eb1a3Sthorpej  * proplib in the kernel...
250774eb1a3Sthorpej  */
251774eb1a3Sthorpej 
252eb2acb85Sthorpej #include <sys/param.h>
253774eb1a3Sthorpej #include <sys/malloc.h>
254774eb1a3Sthorpej #include <sys/pool.h>
255774eb1a3Sthorpej #include <sys/systm.h>
25679ba10e0Sad #include <sys/rwlock.h>
257b6e6025dSpooka #include <sys/once.h>
258774eb1a3Sthorpej 
259774eb1a3Sthorpej #define	_PROP_ASSERT(x)			KASSERT(x)
260774eb1a3Sthorpej 
261774eb1a3Sthorpej #define	_PROP_MALLOC(s, t)		malloc((s), (t), M_WAITOK)
262774eb1a3Sthorpej #define	_PROP_CALLOC(s, t)		malloc((s), (t), M_WAITOK | M_ZERO)
2633e69f1b2Sthorpej #define	_PROP_REALLOC(v, s, t)		realloc((v), (s), (t), M_WAITOK)
264774eb1a3Sthorpej #define	_PROP_FREE(v, t)		free((v), (t))
265774eb1a3Sthorpej 
266774eb1a3Sthorpej #define	_PROP_POOL_GET(p)		pool_get(&(p), PR_WAITOK)
267774eb1a3Sthorpej #define	_PROP_POOL_PUT(p, v)		pool_put(&(p), (v))
268774eb1a3Sthorpej 
269fbd53556Spooka struct prop_pool_init {
270fbd53556Spooka 	struct pool *pp;
271fbd53556Spooka 	size_t size;
272fbd53556Spooka 	const char *wchan;
273fbd53556Spooka };
274fbd53556Spooka #define	_PROP_POOL_INIT(pp, size, wchan)				\
275fbd53556Spooka struct pool pp;								\
276fbd53556Spooka static const struct prop_pool_init _link_ ## pp[1] = {			\
277fbd53556Spooka 	{ &pp, size, wchan }						\
278fbd53556Spooka };									\
279fbd53556Spooka __link_set_add_rodata(prop_linkpools, _link_ ## pp);
280774eb1a3Sthorpej 
281774eb1a3Sthorpej #define	_PROP_MALLOC_DEFINE(t, s, l)					\
282774eb1a3Sthorpej 		MALLOC_DEFINE(t, s, l);
283774eb1a3Sthorpej 
284b6e6025dSpooka #define	_PROP_MUTEX_DECL_STATIC(x)	static kmutex_t x;
285b6e6025dSpooka #define	_PROP_MUTEX_INIT(x)		mutex_init(&(x),MUTEX_DEFAULT,IPL_NONE)
286b6e6025dSpooka #define	_PROP_MUTEX_LOCK(x)		mutex_enter(&(x))
287b6e6025dSpooka #define	_PROP_MUTEX_UNLOCK(x)		mutex_exit(&(x))
288eff71884Sthorpej 
28979ba10e0Sad #define	_PROP_RWLOCK_DECL(x)		krwlock_t x ;
29079ba10e0Sad #define	_PROP_RWLOCK_INIT(x)		rw_init(&(x))
29179ba10e0Sad #define	_PROP_RWLOCK_RDLOCK(x)		rw_enter(&(x), RW_READER)
29279ba10e0Sad #define	_PROP_RWLOCK_WRLOCK(x)		rw_enter(&(x), RW_WRITER)
29379ba10e0Sad #define	_PROP_RWLOCK_UNLOCK(x)		rw_exit(&(x))
29479ba10e0Sad #define	_PROP_RWLOCK_DESTROY(x)		rw_destroy(&(x))
29535fe7cdcSxtraeme 
296b6e6025dSpooka #define _PROP_ONCE_DECL(x)		static ONCE_DECL(x);
297b6e6025dSpooka #define _PROP_ONCE_RUN(x,f)		RUN_ONCE(&(x), f)
298b6e6025dSpooka 
299c303bcbeSpooka #include <sys/atomic.h>
300c303bcbeSpooka 
301a792b843Sthorpej #define	_PROP_ATOMIC_LOAD(x)		atomic_load_relaxed(x)
302c303bcbeSpooka #define _PROP_ATOMIC_INC32(x)		atomic_inc_32(x)
303c303bcbeSpooka #define _PROP_ATOMIC_DEC32(x)		atomic_dec_32(x)
304c303bcbeSpooka #define _PROP_ATOMIC_INC32_NV(x, v)	v = atomic_inc_32_nv(x)
305c303bcbeSpooka #define _PROP_ATOMIC_DEC32_NV(x, v)	v = atomic_dec_32_nv(x)
306c303bcbeSpooka 
307774eb1a3Sthorpej #elif defined(_STANDALONE)
308774eb1a3Sthorpej 
309774eb1a3Sthorpej /*
310774eb1a3Sthorpej  * proplib in a standalone environment...
311774eb1a3Sthorpej  */
312774eb1a3Sthorpej 
313774eb1a3Sthorpej #include <lib/libsa/stand.h>
314774eb1a3Sthorpej 
315774eb1a3Sthorpej void *		_prop_standalone_calloc(size_t);
3163e69f1b2Sthorpej void *		_prop_standalone_realloc(void *, size_t);
317774eb1a3Sthorpej 
318774eb1a3Sthorpej #define	_PROP_ASSERT(x)			/* nothing */
319774eb1a3Sthorpej 
320774eb1a3Sthorpej #define	_PROP_MALLOC(s, t)		alloc((s))
321774eb1a3Sthorpej #define	_PROP_CALLOC(s, t)		_prop_standalone_calloc((s))
3223e69f1b2Sthorpej #define	_PROP_REALLOC(v, s, t)		_prop_standalone_realloc((v), (s))
323774eb1a3Sthorpej #define	_PROP_FREE(v, t)		dealloc((v), 0)		/* XXX */
324774eb1a3Sthorpej 
325774eb1a3Sthorpej #define	_PROP_POOL_GET(p)		alloc((p))
326774eb1a3Sthorpej #define	_PROP_POOL_PUT(p, v)		dealloc((v), (p))
327774eb1a3Sthorpej 
328774eb1a3Sthorpej #define	_PROP_POOL_INIT(p, s, d)	static const size_t p = s;
329774eb1a3Sthorpej 
330774eb1a3Sthorpej #define	_PROP_MALLOC_DEFINE(t, s, l)	/* nothing */
331774eb1a3Sthorpej 
332eb2acb85Sthorpej #define	_PROP_MUTEX_DECL_STATIC(x)	/* nothing */
333b6e6025dSpooka #define	_PROP_MUTEX_INIT(x)		/* nothing */
334eff71884Sthorpej #define	_PROP_MUTEX_LOCK(x)		/* nothing */
335eff71884Sthorpej #define	_PROP_MUTEX_UNLOCK(x)		/* nothing */
336eff71884Sthorpej 
337eb2acb85Sthorpej #define	_PROP_RWLOCK_DECL(x)		/* nothing */
338eb2acb85Sthorpej #define	_PROP_RWLOCK_INIT(x)		/* nothing */
339eb2acb85Sthorpej #define	_PROP_RWLOCK_RDLOCK(x)		/* nothing */
340eb2acb85Sthorpej #define	_PROP_RWLOCK_WRLOCK(x)		/* nothing */
341eb2acb85Sthorpej #define	_PROP_RWLOCK_UNLOCK(x)		/* nothing */
342a8e91bcbSdbj #define	_PROP_RWLOCK_DESTROY(x)		/* nothing */
34335fe7cdcSxtraeme 
344b6e6025dSpooka #define _PROP_ONCE_DECL(x)		_PROP_NOTHREAD_ONCE_DECL(x)
345b6e6025dSpooka #define _PROP_ONCE_RUN(x,f)		_PROP_NOTHREAD_ONCE_RUN(x,f)
346b6e6025dSpooka 
347a792b843Sthorpej #define	_PROP_ATOMIC_LOAD(x)		*(x)
348c303bcbeSpooka #define _PROP_ATOMIC_INC32(x)		++*(x)
349c303bcbeSpooka #define _PROP_ATOMIC_DEC32(x)		--*(x)
350c303bcbeSpooka #define _PROP_ATOMIC_INC32_NV(x, v)	v = ++*(x)
351c303bcbeSpooka #define _PROP_ATOMIC_DEC32_NV(x, v)	v = --*(x)
352c303bcbeSpooka 
353774eb1a3Sthorpej #else
354774eb1a3Sthorpej 
355774eb1a3Sthorpej /*
356774eb1a3Sthorpej  * proplib in user space...
357774eb1a3Sthorpej  */
358774eb1a3Sthorpej 
359774eb1a3Sthorpej #include <assert.h>
360774eb1a3Sthorpej #include <string.h>
361774eb1a3Sthorpej #include <stdio.h>
362774eb1a3Sthorpej #include <stdlib.h>
36325b42587Sthorpej #include <stddef.h>
364774eb1a3Sthorpej 
365dc579d1dSchristos #define	_PROP_ASSERT(x)			/*LINTED*/assert(x)
366774eb1a3Sthorpej 
367774eb1a3Sthorpej #define	_PROP_MALLOC(s, t)		malloc((s))
368ab821170Smartin #define	_PROP_CALLOC(s, t)		calloc(1, (s))
3693e69f1b2Sthorpej #define	_PROP_REALLOC(v, s, t)		realloc((v), (s))
370774eb1a3Sthorpej #define	_PROP_FREE(v, t)		free((v))
371774eb1a3Sthorpej 
372774eb1a3Sthorpej #define	_PROP_POOL_GET(p)		malloc((p))
373774eb1a3Sthorpej #define	_PROP_POOL_PUT(p, v)		free((v))
374774eb1a3Sthorpej 
375774eb1a3Sthorpej #define	_PROP_POOL_INIT(p, s, d)	static const size_t p = s;
376774eb1a3Sthorpej 
377774eb1a3Sthorpej #define	_PROP_MALLOC_DEFINE(t, s, l)	/* nothing */
378774eb1a3Sthorpej 
379eff71884Sthorpej #if defined(__NetBSD__) && defined(_LIBPROP)
380eff71884Sthorpej /*
381eff71884Sthorpej  * Use the same mechanism as libc; we get pthread mutexes for threaded
382eff71884Sthorpej  * programs and do-nothing stubs for non-threaded programs.
383eff71884Sthorpej  */
384c303bcbeSpooka #include <sys/atomic.h>
385eff71884Sthorpej #include "reentrant.h"
386b6e6025dSpooka #define	_PROP_MUTEX_DECL_STATIC(x)	static mutex_t x;
387b6e6025dSpooka #define	_PROP_MUTEX_INIT(x)		mutex_init(&(x), NULL)
388eff71884Sthorpej #define	_PROP_MUTEX_LOCK(x)		mutex_lock(&(x))
389eff71884Sthorpej #define	_PROP_MUTEX_UNLOCK(x)		mutex_unlock(&(x))
390eb2acb85Sthorpej 
391eb2acb85Sthorpej #define	_PROP_RWLOCK_DECL(x)		rwlock_t x ;
392eb2acb85Sthorpej #define	_PROP_RWLOCK_INIT(x)		rwlock_init(&(x), NULL)
393eb2acb85Sthorpej #define	_PROP_RWLOCK_RDLOCK(x)		rwlock_rdlock(&(x))
394eb2acb85Sthorpej #define	_PROP_RWLOCK_WRLOCK(x)		rwlock_wrlock(&(x))
395eb2acb85Sthorpej #define	_PROP_RWLOCK_UNLOCK(x)		rwlock_unlock(&(x))
396eb2acb85Sthorpej #define	_PROP_RWLOCK_DESTROY(x)		rwlock_destroy(&(x))
397b6e6025dSpooka 
398b6e6025dSpooka #define _PROP_ONCE_DECL(x)						\
399b6e6025dSpooka 	static pthread_once_t x = PTHREAD_ONCE_INIT;
400b6e6025dSpooka #define _PROP_ONCE_RUN(x,f)		thr_once(&(x), (void(*)(void))f);
401b6e6025dSpooka 
402a792b843Sthorpej #define	_PROP_ATOMIC_LOAD(x)		*(x)
403c303bcbeSpooka #define _PROP_ATOMIC_INC32(x)		atomic_inc_32(x)
404c303bcbeSpooka #define _PROP_ATOMIC_DEC32(x)		atomic_dec_32(x)
405c303bcbeSpooka #define _PROP_ATOMIC_INC32_NV(x, v)	v = atomic_inc_32_nv(x)
406c303bcbeSpooka #define _PROP_ATOMIC_DEC32_NV(x, v)	v = atomic_dec_32_nv(x)
407c303bcbeSpooka 
408eff71884Sthorpej #elif defined(HAVE_NBTOOL_CONFIG_H)
409eff71884Sthorpej /*
410eff71884Sthorpej  * None of NetBSD's build tools are multi-threaded.
411eff71884Sthorpej  */
412eb2acb85Sthorpej #define	_PROP_MUTEX_DECL_STATIC(x)	/* nothing */
413b6e6025dSpooka #define	_PROP_MUTEX_INIT(x)		/* nothing */
414eff71884Sthorpej #define	_PROP_MUTEX_LOCK(x)		/* nothing */
415eff71884Sthorpej #define	_PROP_MUTEX_UNLOCK(x)		/* nothing */
416eb2acb85Sthorpej 
417eb2acb85Sthorpej #define	_PROP_RWLOCK_DECL(x)		/* nothing */
418eb2acb85Sthorpej #define	_PROP_RWLOCK_INIT(x)		/* nothing */
419eb2acb85Sthorpej #define	_PROP_RWLOCK_RDLOCK(x)		/* nothing */
420eb2acb85Sthorpej #define	_PROP_RWLOCK_WRLOCK(x)		/* nothing */
421eb2acb85Sthorpej #define	_PROP_RWLOCK_UNLOCK(x)		/* nothing */
422eb2acb85Sthorpej #define	_PROP_RWLOCK_DESTROY(x)		/* nothing */
423b6e6025dSpooka 
424b6e6025dSpooka #define _PROP_ONCE_DECL(x)		_PROP_NOTHREAD_ONCE_DECL(x)
425b6e6025dSpooka #define _PROP_ONCE_RUN(x,f)		_PROP_NOTHREAD_ONCE_RUN(x,f)
426c303bcbeSpooka 
427a792b843Sthorpej #define	_PROP_ATOMIC_LOAD(x)		*(x)
428c303bcbeSpooka #define _PROP_ATOMIC_INC32(x)		++*(x)
429c303bcbeSpooka #define _PROP_ATOMIC_DEC32(x)		--*(x)
430c303bcbeSpooka #define _PROP_ATOMIC_INC32_NV(x, v)	v = ++*(x)
431c303bcbeSpooka #define _PROP_ATOMIC_DEC32_NV(x, v)	v = --*(x)
432c303bcbeSpooka 
433eff71884Sthorpej #else
434eff71884Sthorpej /*
435eff71884Sthorpej  * Use pthread mutexes everywhere else.
436eff71884Sthorpej  */
437eff71884Sthorpej #include <pthread.h>
438b6e6025dSpooka #define	_PROP_MUTEX_DECL_STATIC(x)	static pthread_mutex_t x;
439b6e6025dSpooka #define	_PROP_MUTEX_INIT(x)		pthread_mutex_init(&(x), NULL)
440eff71884Sthorpej #define	_PROP_MUTEX_LOCK(x)		pthread_mutex_lock(&(x))
441eff71884Sthorpej #define	_PROP_MUTEX_UNLOCK(x)		pthread_mutex_unlock(&(x))
442eb2acb85Sthorpej 
443eb2acb85Sthorpej #define	_PROP_RWLOCK_DECL(x)		pthread_rwlock_t x ;
444eb2acb85Sthorpej #define	_PROP_RWLOCK_INIT(x)		pthread_rwlock_init(&(x), NULL)
445eb2acb85Sthorpej #define	_PROP_RWLOCK_RDLOCK(x)		pthread_rwlock_rdlock(&(x))
446eb2acb85Sthorpej #define	_PROP_RWLOCK_WRLOCK(x)		pthread_rwlock_wrlock(&(x))
447eb2acb85Sthorpej #define	_PROP_RWLOCK_UNLOCK(x)		pthread_rwlock_unlock(&(x))
448eb2acb85Sthorpej #define	_PROP_RWLOCK_DESTROY(x)		pthread_rwlock_destroy(&(x))
449b6e6025dSpooka 
450b6e6025dSpooka #define _PROP_ONCE_DECL(x)						\
451b6e6025dSpooka 	static pthread_once_t x = PTHREAD_ONCE_INIT;
452b6e6025dSpooka #define _PROP_ONCE_RUN(x,f)		pthread_once(&(x),(void(*)(void))f)
453eff71884Sthorpej 
454c303bcbeSpooka #define _PROP_NEED_REFCNT_MTX
455c303bcbeSpooka 
456a792b843Sthorpej #define	_PROP_ATOMIC_LOAD(x)		*(x)
457a792b843Sthorpej 
458c303bcbeSpooka #define _PROP_ATOMIC_INC32(x)						\
459c303bcbeSpooka do {									\
460c303bcbeSpooka 	pthread_mutex_lock(&_prop_refcnt_mtx);				\
461c303bcbeSpooka 	(*(x))++;							\
462c303bcbeSpooka 	pthread_mutex_unlock(&_prop_refcnt_mtx);			\
463c303bcbeSpooka } while (/*CONSTCOND*/0)
464c303bcbeSpooka 
465c303bcbeSpooka #define _PROP_ATOMIC_DEC32(x)						\
466c303bcbeSpooka do {									\
467c303bcbeSpooka 	pthread_mutex_lock(&_prop_refcnt_mtx);				\
468c303bcbeSpooka 	(*(x))--;							\
469c303bcbeSpooka 	pthread_mutex_unlock(&_prop_refcnt_mtx);			\
470c303bcbeSpooka } while (/*CONSTCOND*/0)
471c303bcbeSpooka 
472c303bcbeSpooka #define _PROP_ATOMIC_INC32_NV(x, v)					\
473c303bcbeSpooka do {									\
474c303bcbeSpooka 	pthread_mutex_lock(&_prop_refcnt_mtx);				\
475c303bcbeSpooka 	v = ++(*(x));							\
476c303bcbeSpooka 	pthread_mutex_unlock(&_prop_refcnt_mtx);			\
477c303bcbeSpooka } while (/*CONSTCOND*/0)
478c303bcbeSpooka 
479c303bcbeSpooka #define _PROP_ATOMIC_DEC32_NV(x, v)					\
480c303bcbeSpooka do {									\
481c303bcbeSpooka 	pthread_mutex_lock(&_prop_refcnt_mtx);				\
482c303bcbeSpooka 	v = --(*(x));							\
483c303bcbeSpooka 	pthread_mutex_unlock(&_prop_refcnt_mtx);			\
484c303bcbeSpooka } while (/*CONSTCOND*/0)
485c303bcbeSpooka 
486c303bcbeSpooka #endif
487774eb1a3Sthorpej #endif /* _KERNEL */
488774eb1a3Sthorpej 
489d9fd2cbcSthorpej /*
490d9fd2cbcSthorpej  * Language features.
491d9fd2cbcSthorpej  */
492d9fd2cbcSthorpej #if defined(__NetBSD__)
493d9fd2cbcSthorpej #include <sys/cdefs.h>
494d9fd2cbcSthorpej #define	_PROP_ARG_UNUSED		__unused
495*6620d0c7Sthorpej #if defined(__clang__)
496*6620d0c7Sthorpej #define	_PROP_DEPRECATED(s, m)		/* delete */
497*6620d0c7Sthorpej #else /* ! __clang__ */
498*6620d0c7Sthorpej #define	_PROP_DEPRECATED(s, m)		__warn_references(s, m)
499*6620d0c7Sthorpej #endif /* __clang__ */
500d9fd2cbcSthorpej #else
501d9fd2cbcSthorpej #define	_PROP_ARG_UNUSED		/* delete */
502a792b843Sthorpej #define	_PROP_DEPRECATED(s, m)		/* delete */
503d9fd2cbcSthorpej #endif /* __NetBSD__ */
504d9fd2cbcSthorpej 
505774eb1a3Sthorpej #endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */
506