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