Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef	_LIBUUTIL_IMPL_H
     28 #define	_LIBUUTIL_IMPL_H
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #include <libuutil.h>
     33 #include <pthread.h>
     34 
     35 #include <sys/avl_impl.h>
     36 #include <sys/byteorder.h>
     37 
     38 #ifdef	__cplusplus
     39 extern "C" {
     40 #endif
     41 
     42 void uu_set_error(uint_t);
     43 #pragma rarely_called(uu_set_error)
     44 
     45 /*PRINTFLIKE1*/
     46 void uu_panic(const char *format, ...);
     47 #pragma rarely_called(uu_panic)
     48 
     49 struct uu_dprintf {
     50 	char	*uud_name;
     51 	uu_dprintf_severity_t uud_severity;
     52 	uint_t	uud_flags;
     53 };
     54 
     55 /*
     56  * For debugging purposes, libuutil keeps around linked lists of all uu_lists
     57  * and uu_avls, along with pointers to their parents.  These can cause false
     58  * negatives when looking for memory leaks, so we encode the pointers by
     59  * storing them with swapped endianness;  this is not perfect, but it's about
     60  * the best we can do without wasting a lot of space.
     61  */
     62 #ifdef _LP64
     63 #define	UU_PTR_ENCODE(ptr)		BSWAP_64((uintptr_t)(void *)(ptr))
     64 #else
     65 #define	UU_PTR_ENCODE(ptr)		BSWAP_32((uintptr_t)(void *)(ptr))
     66 #endif
     67 
     68 #define	UU_PTR_DECODE(ptr)		((void *)UU_PTR_ENCODE(ptr))
     69 
     70 /*
     71  * uu_list structures
     72  */
     73 typedef struct uu_list_node_impl {
     74 	struct uu_list_node_impl *uln_next;
     75 	struct uu_list_node_impl *uln_prev;
     76 } uu_list_node_impl_t;
     77 
     78 struct uu_list_walk {
     79 	uu_list_walk_t	*ulw_next;
     80 	uu_list_walk_t	*ulw_prev;
     81 
     82 	uu_list_t	*ulw_list;
     83 	int8_t		ulw_dir;
     84 	uint8_t		ulw_robust;
     85 	uu_list_node_impl_t *ulw_next_result;
     86 };
     87 
     88 struct uu_list {
     89 	uintptr_t	ul_next_enc;
     90 	uintptr_t	ul_prev_enc;
     91 
     92 	uu_list_pool_t	*ul_pool;
     93 	uintptr_t	ul_parent_enc;	/* encoded parent pointer */
     94 	size_t		ul_offset;
     95 	size_t		ul_numnodes;
     96 	uint8_t		ul_debug;
     97 	uint8_t		ul_sorted;
     98 	uint8_t		ul_index;	/* mark for uu_list_index_ts */
     99 
    100 	uu_list_node_impl_t ul_null_node;
    101 	uu_list_walk_t	ul_null_walk;	/* for robust walkers */
    102 };
    103 
    104 #define	UU_LIST_PTR(ptr)		((uu_list_t *)UU_PTR_DECODE(ptr))
    105 
    106 #define	UU_LIST_POOL_MAXNAME	64
    107 
    108 struct uu_list_pool {
    109 	uu_list_pool_t	*ulp_next;
    110 	uu_list_pool_t	*ulp_prev;
    111 
    112 	char		ulp_name[UU_LIST_POOL_MAXNAME];
    113 	size_t		ulp_nodeoffset;
    114 	size_t		ulp_objsize;
    115 	uu_compare_fn_t	*ulp_cmp;
    116 	uint8_t		ulp_debug;
    117 	uint8_t		ulp_last_index;
    118 	pthread_mutex_t	ulp_lock;		/* protects null_list */
    119 	uu_list_t	ulp_null_list;
    120 };
    121 
    122 /*
    123  * uu_avl structures
    124  */
    125 typedef struct avl_node		uu_avl_node_impl_t;
    126 
    127 struct uu_avl_walk {
    128 	uu_avl_walk_t	*uaw_next;
    129 	uu_avl_walk_t	*uaw_prev;
    130 
    131 	uu_avl_t	*uaw_avl;
    132 	void		*uaw_next_result;
    133 	int8_t		uaw_dir;
    134 	uint8_t		uaw_robust;
    135 };
    136 
    137 struct uu_avl {
    138 	uintptr_t	ua_next_enc;
    139 	uintptr_t	ua_prev_enc;
    140 
    141 	uu_avl_pool_t	*ua_pool;
    142 	uintptr_t	ua_parent_enc;
    143 	uint8_t		ua_debug;
    144 	uint8_t		ua_index;	/* mark for uu_avl_index_ts */
    145 
    146 	struct avl_tree	ua_tree;
    147 	uu_avl_walk_t	ua_null_walk;
    148 };
    149 
    150 #define	UU_AVL_PTR(x)		((uu_avl_t *)UU_PTR_DECODE(x))
    151 
    152 #define	UU_AVL_POOL_MAXNAME	64
    153 
    154 struct uu_avl_pool {
    155 	uu_avl_pool_t	*uap_next;
    156 	uu_avl_pool_t	*uap_prev;
    157 
    158 	char		uap_name[UU_AVL_POOL_MAXNAME];
    159 	size_t		uap_nodeoffset;
    160 	size_t		uap_objsize;
    161 	uu_compare_fn_t	*uap_cmp;
    162 	uint8_t		uap_debug;
    163 	uint8_t		uap_last_index;
    164 	pthread_mutex_t	uap_lock;		/* protects null_avl */
    165 	uu_avl_t	uap_null_avl;
    166 };
    167 
    168 /*
    169  * atfork() handlers
    170  */
    171 void uu_avl_lockup(void);
    172 void uu_avl_release(void);
    173 
    174 void uu_list_lockup(void);
    175 void uu_list_release(void);
    176 
    177 #ifdef	__cplusplus
    178 }
    179 #endif
    180 
    181 #endif	/* _LIBUUTIL_IMPL_H */
    182