Merge commit 'refs/top-bases/linux-configure-branch' into linux-configure-branch
This commit is contained in:
commit
26e41a1f82
|
@ -2,16 +2,21 @@ subdir-m += include
|
|||
DISTFILES = kernel.c mkdirp.c strlcpy.c taskq.c util.c
|
||||
DISTFILES += list.c strlcat.c strnlen.c u8_textprep.c
|
||||
|
||||
LIBRARY := libzport
|
||||
LIBRARY := libspl
|
||||
|
||||
# Compile as shared library. There's an extra useless host program
|
||||
# here called 'zu' because it was the easiest way I could convince
|
||||
# the kernel build system to construct a user space shared library.
|
||||
|
||||
HOSTCFLAGS += @HOSTCFLAGS@
|
||||
HOSTCFLAGS += -I@LIBDIR@/libzcommon/include
|
||||
HOSTCFLAGS += -I@LIBDIR@/libumem/include
|
||||
HOSTCFLAGS += -I@LIBDIR@/libspl/include
|
||||
|
||||
HOSTLDFLAGS += -lumem -L@LIBDIR@/libumem
|
||||
|
||||
# Additional shared library paths for executing binaries in-tree
|
||||
export LD_RUN_PATH = @LIBDIR@/libumem
|
||||
|
||||
hostprogs-y := zu
|
||||
always := $(hostprogs-y)
|
||||
|
||||
|
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ATOMIC_H
|
||||
#define _SYS_ATOMIC_H
|
||||
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_KERNEL) && defined(__GNUC__) && defined(_ASM_INLINES) && \
|
||||
(defined(__i386) || defined(__amd64))
|
||||
#include <asm/atomic.h>
|
||||
#endif
|
||||
|
||||
#if defined(_KERNEL) || defined(__STDC__)
|
||||
/*
|
||||
* Increment target.
|
||||
*/
|
||||
extern void atomic_inc_8(volatile uint8_t *);
|
||||
extern void atomic_inc_uchar(volatile uchar_t *);
|
||||
extern void atomic_inc_16(volatile uint16_t *);
|
||||
extern void atomic_inc_ushort(volatile ushort_t *);
|
||||
extern void atomic_inc_32(volatile uint32_t *);
|
||||
extern void atomic_inc_uint(volatile uint_t *);
|
||||
extern void atomic_inc_ulong(volatile ulong_t *);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern void atomic_inc_64(volatile uint64_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decrement target
|
||||
*/
|
||||
extern void atomic_dec_8(volatile uint8_t *);
|
||||
extern void atomic_dec_uchar(volatile uchar_t *);
|
||||
extern void atomic_dec_16(volatile uint16_t *);
|
||||
extern void atomic_dec_ushort(volatile ushort_t *);
|
||||
extern void atomic_dec_32(volatile uint32_t *);
|
||||
extern void atomic_dec_uint(volatile uint_t *);
|
||||
extern void atomic_dec_ulong(volatile ulong_t *);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern void atomic_dec_64(volatile uint64_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add delta to target
|
||||
*/
|
||||
extern void atomic_add_8(volatile uint8_t *, int8_t);
|
||||
extern void atomic_add_char(volatile uchar_t *, signed char);
|
||||
extern void atomic_add_16(volatile uint16_t *, int16_t);
|
||||
extern void atomic_add_short(volatile ushort_t *, short);
|
||||
extern void atomic_add_32(volatile uint32_t *, int32_t);
|
||||
extern void atomic_add_int(volatile uint_t *, int);
|
||||
extern void atomic_add_ptr(volatile void *, ssize_t);
|
||||
extern void atomic_add_long(volatile ulong_t *, long);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern void atomic_add_64(volatile uint64_t *, int64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* logical OR bits with target
|
||||
*/
|
||||
extern void atomic_or_8(volatile uint8_t *, uint8_t);
|
||||
extern void atomic_or_uchar(volatile uchar_t *, uchar_t);
|
||||
extern void atomic_or_16(volatile uint16_t *, uint16_t);
|
||||
extern void atomic_or_ushort(volatile ushort_t *, ushort_t);
|
||||
extern void atomic_or_32(volatile uint32_t *, uint32_t);
|
||||
extern void atomic_or_uint(volatile uint_t *, uint_t);
|
||||
extern void atomic_or_ulong(volatile ulong_t *, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern void atomic_or_64(volatile uint64_t *, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* logical AND bits with target
|
||||
*/
|
||||
extern void atomic_and_8(volatile uint8_t *, uint8_t);
|
||||
extern void atomic_and_uchar(volatile uchar_t *, uchar_t);
|
||||
extern void atomic_and_16(volatile uint16_t *, uint16_t);
|
||||
extern void atomic_and_ushort(volatile ushort_t *, ushort_t);
|
||||
extern void atomic_and_32(volatile uint32_t *, uint32_t);
|
||||
extern void atomic_and_uint(volatile uint_t *, uint_t);
|
||||
extern void atomic_and_ulong(volatile ulong_t *, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern void atomic_and_64(volatile uint64_t *, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As above, but return the new value. Note that these _nv() variants are
|
||||
* substantially more expensive on some platforms than the no-return-value
|
||||
* versions above, so don't use them unless you really need to know the
|
||||
* new value *atomically* (e.g. when decrementing a reference count and
|
||||
* checking whether it went to zero).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Increment target and return new value.
|
||||
*/
|
||||
extern uint8_t atomic_inc_8_nv(volatile uint8_t *);
|
||||
extern uchar_t atomic_inc_uchar_nv(volatile uchar_t *);
|
||||
extern uint16_t atomic_inc_16_nv(volatile uint16_t *);
|
||||
extern ushort_t atomic_inc_ushort_nv(volatile ushort_t *);
|
||||
extern uint32_t atomic_inc_32_nv(volatile uint32_t *);
|
||||
extern uint_t atomic_inc_uint_nv(volatile uint_t *);
|
||||
extern ulong_t atomic_inc_ulong_nv(volatile ulong_t *);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_inc_64_nv(volatile uint64_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decrement target and return new value.
|
||||
*/
|
||||
extern uint8_t atomic_dec_8_nv(volatile uint8_t *);
|
||||
extern uchar_t atomic_dec_uchar_nv(volatile uchar_t *);
|
||||
extern uint16_t atomic_dec_16_nv(volatile uint16_t *);
|
||||
extern ushort_t atomic_dec_ushort_nv(volatile ushort_t *);
|
||||
extern uint32_t atomic_dec_32_nv(volatile uint32_t *);
|
||||
extern uint_t atomic_dec_uint_nv(volatile uint_t *);
|
||||
extern ulong_t atomic_dec_ulong_nv(volatile ulong_t *);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_dec_64_nv(volatile uint64_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add delta to target
|
||||
*/
|
||||
extern uint8_t atomic_add_8_nv(volatile uint8_t *, int8_t);
|
||||
extern uchar_t atomic_add_char_nv(volatile uchar_t *, signed char);
|
||||
extern uint16_t atomic_add_16_nv(volatile uint16_t *, int16_t);
|
||||
extern ushort_t atomic_add_short_nv(volatile ushort_t *, short);
|
||||
extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t);
|
||||
extern uint_t atomic_add_int_nv(volatile uint_t *, int);
|
||||
extern void *atomic_add_ptr_nv(volatile void *, ssize_t);
|
||||
extern ulong_t atomic_add_long_nv(volatile ulong_t *, long);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_add_64_nv(volatile uint64_t *, int64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* logical OR bits with target and return new value.
|
||||
*/
|
||||
extern uint8_t atomic_or_8_nv(volatile uint8_t *, uint8_t);
|
||||
extern uchar_t atomic_or_uchar_nv(volatile uchar_t *, uchar_t);
|
||||
extern uint16_t atomic_or_16_nv(volatile uint16_t *, uint16_t);
|
||||
extern ushort_t atomic_or_ushort_nv(volatile ushort_t *, ushort_t);
|
||||
extern uint32_t atomic_or_32_nv(volatile uint32_t *, uint32_t);
|
||||
extern uint_t atomic_or_uint_nv(volatile uint_t *, uint_t);
|
||||
extern ulong_t atomic_or_ulong_nv(volatile ulong_t *, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_or_64_nv(volatile uint64_t *, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* logical AND bits with target and return new value.
|
||||
*/
|
||||
extern uint8_t atomic_and_8_nv(volatile uint8_t *, uint8_t);
|
||||
extern uchar_t atomic_and_uchar_nv(volatile uchar_t *, uchar_t);
|
||||
extern uint16_t atomic_and_16_nv(volatile uint16_t *, uint16_t);
|
||||
extern ushort_t atomic_and_ushort_nv(volatile ushort_t *, ushort_t);
|
||||
extern uint32_t atomic_and_32_nv(volatile uint32_t *, uint32_t);
|
||||
extern uint_t atomic_and_uint_nv(volatile uint_t *, uint_t);
|
||||
extern ulong_t atomic_and_ulong_nv(volatile ulong_t *, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_and_64_nv(volatile uint64_t *, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If *arg1 == arg2, set *arg1 = arg3; return old value
|
||||
*/
|
||||
extern uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t);
|
||||
extern uchar_t atomic_cas_uchar(volatile uchar_t *, uchar_t, uchar_t);
|
||||
extern uint16_t atomic_cas_16(volatile uint16_t *, uint16_t, uint16_t);
|
||||
extern ushort_t atomic_cas_ushort(volatile ushort_t *, ushort_t, ushort_t);
|
||||
extern uint32_t atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t);
|
||||
extern uint_t atomic_cas_uint(volatile uint_t *, uint_t, uint_t);
|
||||
extern void *atomic_cas_ptr(volatile void *, void *, void *);
|
||||
extern ulong_t atomic_cas_ulong(volatile ulong_t *, ulong_t, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_cas_64(volatile uint64_t *, uint64_t, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Swap target and return old value
|
||||
*/
|
||||
extern uint8_t atomic_swap_8(volatile uint8_t *, uint8_t);
|
||||
extern uchar_t atomic_swap_uchar(volatile uchar_t *, uchar_t);
|
||||
extern uint16_t atomic_swap_16(volatile uint16_t *, uint16_t);
|
||||
extern ushort_t atomic_swap_ushort(volatile ushort_t *, ushort_t);
|
||||
extern uint32_t atomic_swap_32(volatile uint32_t *, uint32_t);
|
||||
extern uint_t atomic_swap_uint(volatile uint_t *, uint_t);
|
||||
extern void *atomic_swap_ptr(volatile void *, void *);
|
||||
extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t);
|
||||
#if defined(_KERNEL) || defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Perform an exclusive atomic bit set/clear on a target.
|
||||
* Returns 0 if bit was sucessfully set/cleared, or -1
|
||||
* if the bit was already set/cleared.
|
||||
*/
|
||||
extern int atomic_set_long_excl(volatile ulong_t *, uint_t);
|
||||
extern int atomic_clear_long_excl(volatile ulong_t *, uint_t);
|
||||
|
||||
/*
|
||||
* Generic memory barrier used during lock entry, placed after the
|
||||
* memory operation that acquires the lock to guarantee that the lock
|
||||
* protects its data. No stores from after the memory barrier will
|
||||
* reach visibility, and no loads from after the barrier will be
|
||||
* resolved, before the lock acquisition reaches global visibility.
|
||||
*/
|
||||
extern void membar_enter(void);
|
||||
|
||||
/*
|
||||
* Generic memory barrier used during lock exit, placed before the
|
||||
* memory operation that releases the lock to guarantee that the lock
|
||||
* protects its data. All loads and stores issued before the barrier
|
||||
* will be resolved before the subsequent lock update reaches visibility.
|
||||
*/
|
||||
extern void membar_exit(void);
|
||||
|
||||
/*
|
||||
* Arrange that all stores issued before this point in the code reach
|
||||
* global visibility before any stores that follow; useful in producer
|
||||
* modules that update a data item, then set a flag that it is available.
|
||||
* The memory barrier guarantees that the available flag is not visible
|
||||
* earlier than the updated data, i.e. it imposes store ordering.
|
||||
*/
|
||||
extern void membar_producer(void);
|
||||
|
||||
/*
|
||||
* Arrange that all loads issued before this point in the code are
|
||||
* completed before any subsequent loads; useful in consumer modules
|
||||
* that check to see if data is available and read the data.
|
||||
* The memory barrier guarantees that the data is not sampled until
|
||||
* after the available flag has been seen, i.e. it imposes load ordering.
|
||||
*/
|
||||
extern void membar_consumer(void);
|
||||
#endif
|
||||
|
||||
#if !defined(_KERNEL) && !defined(__STDC__)
|
||||
extern void atomic_inc_8();
|
||||
extern void atomic_inc_uchar();
|
||||
extern void atomic_inc_16();
|
||||
extern void atomic_inc_ushort();
|
||||
extern void atomic_inc_32();
|
||||
extern void atomic_inc_uint();
|
||||
extern void atomic_inc_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern void atomic_inc_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern void atomic_dec_8();
|
||||
extern void atomic_dec_uchar();
|
||||
extern void atomic_dec_16();
|
||||
extern void atomic_dec_ushort();
|
||||
extern void atomic_dec_32();
|
||||
extern void atomic_dec_uint();
|
||||
extern void atomic_dec_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern void atomic_dec_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern void atomic_add_8();
|
||||
extern void atomic_add_char();
|
||||
extern void atomic_add_16();
|
||||
extern void atomic_add_short();
|
||||
extern void atomic_add_32();
|
||||
extern void atomic_add_int();
|
||||
extern void atomic_add_ptr();
|
||||
extern void atomic_add_long();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern void atomic_add_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern void atomic_or_8();
|
||||
extern void atomic_or_uchar();
|
||||
extern void atomic_or_16();
|
||||
extern void atomic_or_ushort();
|
||||
extern void atomic_or_32();
|
||||
extern void atomic_or_uint();
|
||||
extern void atomic_or_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern void atomic_or_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern void atomic_and_8();
|
||||
extern void atomic_and_uchar();
|
||||
extern void atomic_and_16();
|
||||
extern void atomic_and_ushort();
|
||||
extern void atomic_and_32();
|
||||
extern void atomic_and_uint();
|
||||
extern void atomic_and_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern void atomic_and_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_inc_8_nv();
|
||||
extern uchar_t atomic_inc_uchar_nv();
|
||||
extern uint16_t atomic_inc_16_nv();
|
||||
extern ushort_t atomic_inc_ushort_nv();
|
||||
extern uint32_t atomic_inc_32_nv();
|
||||
extern uint_t atomic_inc_uint_nv();
|
||||
extern ulong_t atomic_inc_ulong_nv();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_inc_64_nv();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_dec_8_nv();
|
||||
extern uchar_t atomic_dec_uchar_nv();
|
||||
extern uint16_t atomic_dec_16_nv();
|
||||
extern ushort_t atomic_dec_ushort_nv();
|
||||
extern uint32_t atomic_dec_32_nv();
|
||||
extern uint_t atomic_dec_uint_nv();
|
||||
extern ulong_t atomic_dec_ulong_nv();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_dec_64_nv();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_add_8_nv();
|
||||
extern uchar_t atomic_add_char_nv();
|
||||
extern uint16_t atomic_add_16_nv();
|
||||
extern ushort_t atomic_add_short_nv();
|
||||
extern uint32_t atomic_add_32_nv();
|
||||
extern uint_t atomic_add_int_nv();
|
||||
extern void *atomic_add_ptr_nv();
|
||||
extern ulong_t atomic_add_long_nv();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_add_64_nv();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_or_8_nv();
|
||||
extern uchar_t atomic_or_uchar_nv();
|
||||
extern uint16_t atomic_or_16_nv();
|
||||
extern ushort_t atomic_or_ushort_nv();
|
||||
extern uint32_t atomic_or_32_nv();
|
||||
extern uint_t atomic_or_uint_nv();
|
||||
extern ulong_t atomic_or_ulong_nv();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_or_64_nv();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_and_8_nv();
|
||||
extern uchar_t atomic_and_uchar_nv();
|
||||
extern uint16_t atomic_and_16_nv();
|
||||
extern ushort_t atomic_and_ushort_nv();
|
||||
extern uint32_t atomic_and_32_nv();
|
||||
extern uint_t atomic_and_uint_nv();
|
||||
extern ulong_t atomic_and_ulong_nv();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_and_64_nv();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_cas_8();
|
||||
extern uchar_t atomic_cas_uchar();
|
||||
extern uint16_t atomic_cas_16();
|
||||
extern ushort_t atomic_cas_ushort();
|
||||
extern uint32_t atomic_cas_32();
|
||||
extern uint_t atomic_cas_uint();
|
||||
extern void *atomic_cas_ptr();
|
||||
extern ulong_t atomic_cas_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_cas_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
extern uint8_t atomic_swap_8();
|
||||
extern uchar_t atomic_swap_uchar();
|
||||
extern uint16_t atomic_swap_16();
|
||||
extern ushort_t atomic_swap_ushort();
|
||||
extern uint32_t atomic_swap_32();
|
||||
extern uint_t atomic_swap_uint();
|
||||
extern void *atomic_swap_ptr();
|
||||
extern ulong_t atomic_swap_ulong();
|
||||
#if defined(_INT64_TYPE)
|
||||
extern uint64_t atomic_swap_64();
|
||||
#endif /* defined(_INT64_TYPE) */
|
||||
|
||||
|
||||
extern int atomic_set_long_excl();
|
||||
extern int atomic_clear_long_excl();
|
||||
|
||||
extern void membar_enter();
|
||||
extern void membar_exit();
|
||||
extern void membar_producer();
|
||||
extern void membar_consumer();
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
#if defined(_LP64) || defined(_ILP32)
|
||||
#define atomic_add_ip atomic_add_long
|
||||
#define atomic_add_ip_nv atomic_add_long_nv
|
||||
#define casip atomic_cas_ulong
|
||||
#endif
|
||||
|
||||
#if defined(__sparc)
|
||||
extern uint8_t ldstub(uint8_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Legacy kernel interfaces; they will go away (eventually).
|
||||
*/
|
||||
extern uint8_t cas8(uint8_t *, uint8_t, uint8_t);
|
||||
extern uint32_t cas32(uint32_t *, uint32_t, uint32_t);
|
||||
extern uint64_t cas64(uint64_t *, uint64_t, uint64_t);
|
||||
extern ulong_t caslong(ulong_t *, ulong_t, ulong_t);
|
||||
extern void *casptr(void *, void *, void *);
|
||||
extern void atomic_and_long(ulong_t *, ulong_t);
|
||||
extern void atomic_or_long(ulong_t *, ulong_t);
|
||||
#if defined(__sparc)
|
||||
extern uint32_t swapl(uint32_t *, uint32_t);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_ATOMIC_H */
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_BITMAP_H
|
||||
#define _SOL_SYS_BITMAP_H
|
||||
|
||||
#endif
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/*
|
||||
* University Copyright- Copyright (c) 1982, 1986, 1988
|
||||
* The Regents of the University of California
|
||||
* All Rights Reserved
|
||||
*
|
||||
* University Acknowledgment- Portions of this document are derived from
|
||||
* software developed by the University of California, Berkeley, and its
|
||||
* contributors.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BYTEORDER_H
|
||||
#define _SYS_BYTEORDER_H
|
||||
|
||||
|
||||
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/int_types.h>
|
||||
|
||||
#if defined(__GNUC__) && defined(_ASM_INLINES) && \
|
||||
(defined(__i386) || defined(__amd64))
|
||||
#include <asm/byteorder.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* macros for conversion between host and (internet) network byte order
|
||||
*/
|
||||
|
||||
#if defined(_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint)
|
||||
/* big-endian */
|
||||
#define ntohl(x) (x)
|
||||
#define ntohs(x) (x)
|
||||
#define htonl(x) (x)
|
||||
#define htons(x) (x)
|
||||
|
||||
#elif !defined(ntohl) /* little-endian */
|
||||
|
||||
#ifndef _IN_PORT_T
|
||||
#define _IN_PORT_T
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
|
||||
#ifndef _IN_ADDR_T
|
||||
#define _IN_ADDR_T
|
||||
typedef uint32_t in_addr_t;
|
||||
#endif
|
||||
|
||||
#if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5)
|
||||
extern uint32_t htonl(uint32_t);
|
||||
extern uint16_t htons(uint16_t);
|
||||
extern uint32_t ntohl(uint32_t);
|
||||
extern uint16_t ntohs(uint16_t);
|
||||
#else
|
||||
extern in_addr_t htonl(in_addr_t);
|
||||
extern in_port_t htons(in_port_t);
|
||||
extern in_addr_t ntohl(in_addr_t);
|
||||
extern in_port_t ntohs(in_port_t);
|
||||
#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */
|
||||
#endif
|
||||
|
||||
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
|
||||
|
||||
/*
|
||||
* Macros to reverse byte order
|
||||
*/
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
|
||||
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
|
||||
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
|
||||
|
||||
#define BMASK_8(x) ((x) & 0xff)
|
||||
#define BMASK_16(x) ((x) & 0xffff)
|
||||
#define BMASK_32(x) ((x) & 0xffffffff)
|
||||
#define BMASK_64(x) (x)
|
||||
|
||||
/*
|
||||
* Macros to convert from a specific byte order to/from native byte order
|
||||
*/
|
||||
#ifdef _BIG_ENDIAN
|
||||
#define BE_8(x) BMASK_8(x)
|
||||
#define BE_16(x) BMASK_16(x)
|
||||
#define BE_32(x) BMASK_32(x)
|
||||
#define BE_64(x) BMASK_64(x)
|
||||
#define LE_8(x) BSWAP_8(x)
|
||||
#define LE_16(x) BSWAP_16(x)
|
||||
#define LE_32(x) BSWAP_32(x)
|
||||
#define LE_64(x) BSWAP_64(x)
|
||||
#else
|
||||
#define LE_8(x) BMASK_8(x)
|
||||
#define LE_16(x) BMASK_16(x)
|
||||
#define LE_32(x) BMASK_32(x)
|
||||
#define LE_64(x) BMASK_64(x)
|
||||
#define BE_8(x) BSWAP_8(x)
|
||||
#define BE_16(x) BSWAP_16(x)
|
||||
#define BE_32(x) BSWAP_32(x)
|
||||
#define BE_64(x) BSWAP_64(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros to read unaligned values from a specific byte order to
|
||||
* native byte order
|
||||
*/
|
||||
|
||||
#define BE_IN8(xa) \
|
||||
*((uint8_t *)(xa))
|
||||
|
||||
#define BE_IN16(xa) \
|
||||
(((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
|
||||
|
||||
#define BE_IN32(xa) \
|
||||
(((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
|
||||
|
||||
#define BE_IN64(xa) \
|
||||
(((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
|
||||
|
||||
#define LE_IN8(xa) \
|
||||
*((uint8_t *)(xa))
|
||||
|
||||
#define LE_IN16(xa) \
|
||||
(((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
|
||||
|
||||
#define LE_IN32(xa) \
|
||||
(((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
|
||||
|
||||
#define LE_IN64(xa) \
|
||||
(((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
|
||||
|
||||
/*
|
||||
* Macros to write unaligned values from native byte order to a specific byte
|
||||
* order.
|
||||
*/
|
||||
|
||||
#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
|
||||
|
||||
#define BE_OUT16(xa, yv) \
|
||||
BE_OUT8((uint8_t *)(xa) + 1, yv); \
|
||||
BE_OUT8((uint8_t *)(xa), (yv) >> 8);
|
||||
|
||||
#define BE_OUT32(xa, yv) \
|
||||
BE_OUT16((uint8_t *)(xa) + 2, yv); \
|
||||
BE_OUT16((uint8_t *)(xa), (yv) >> 16);
|
||||
|
||||
#define BE_OUT64(xa, yv) \
|
||||
BE_OUT32((uint8_t *)(xa) + 4, yv); \
|
||||
BE_OUT32((uint8_t *)(xa), (yv) >> 32);
|
||||
|
||||
#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
|
||||
|
||||
#define LE_OUT16(xa, yv) \
|
||||
LE_OUT8((uint8_t *)(xa), yv); \
|
||||
LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
|
||||
|
||||
#define LE_OUT32(xa, yv) \
|
||||
LE_OUT16((uint8_t *)(xa), yv); \
|
||||
LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
|
||||
|
||||
#define LE_OUT64(xa, yv) \
|
||||
LE_OUT32((uint8_t *)(xa), yv); \
|
||||
LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
|
||||
|
||||
#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_BYTEORDER_H */
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_CMN_ERR_H
|
||||
#define _SOL_SYS_CMN_ERR_H
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_CRED_H
|
||||
#define _SOL_SYS_CRED_H
|
||||
|
||||
typedef struct cred cred_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,820 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_KSTAT_H
|
||||
#define _SYS_KSTAT_H
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Definition of general kernel statistics structures and /dev/kstat ioctls
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int kid_t; /* unique kstat id */
|
||||
|
||||
/*
|
||||
* Kernel statistics driver (/dev/kstat) ioctls
|
||||
*/
|
||||
|
||||
#define KSTAT_IOC_BASE ('K' << 8)
|
||||
|
||||
#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01
|
||||
#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02
|
||||
#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03
|
||||
|
||||
/*
|
||||
* /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor):
|
||||
*
|
||||
* kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL);
|
||||
* kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *);
|
||||
* kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *);
|
||||
*/
|
||||
|
||||
#define KSTAT_STRLEN 31 /* 30 chars + NULL; must be 16 * n - 1 */
|
||||
|
||||
/*
|
||||
* The generic kstat header
|
||||
*/
|
||||
|
||||
typedef struct kstat {
|
||||
/*
|
||||
* Fields relevant to both kernel and user
|
||||
*/
|
||||
hrtime_t ks_crtime; /* creation time (from gethrtime()) */
|
||||
struct kstat *ks_next; /* kstat chain linkage */
|
||||
kid_t ks_kid; /* unique kstat ID */
|
||||
char ks_module[KSTAT_STRLEN]; /* provider module name */
|
||||
uchar_t ks_resv; /* reserved, currently just padding */
|
||||
int ks_instance; /* provider module's instance */
|
||||
char ks_name[KSTAT_STRLEN]; /* kstat name */
|
||||
uchar_t ks_type; /* kstat data type */
|
||||
char ks_class[KSTAT_STRLEN]; /* kstat class */
|
||||
uchar_t ks_flags; /* kstat flags */
|
||||
void *ks_data; /* kstat type-specific data */
|
||||
uint_t ks_ndata; /* # of type-specific data records */
|
||||
size_t ks_data_size; /* total size of kstat data section */
|
||||
hrtime_t ks_snaptime; /* time of last data shapshot */
|
||||
/*
|
||||
* Fields relevant to kernel only
|
||||
*/
|
||||
int (*ks_update)(struct kstat *, int); /* dynamic update */
|
||||
void *ks_private; /* arbitrary provider-private data */
|
||||
int (*ks_snapshot)(struct kstat *, void *, int);
|
||||
void *ks_lock; /* protects this kstat's data */
|
||||
} kstat_t;
|
||||
|
||||
#ifdef _SYSCALL32
|
||||
|
||||
typedef int32_t kid32_t;
|
||||
|
||||
typedef struct kstat32 {
|
||||
/*
|
||||
* Fields relevant to both kernel and user
|
||||
*/
|
||||
hrtime_t ks_crtime;
|
||||
caddr32_t ks_next; /* struct kstat pointer */
|
||||
kid32_t ks_kid;
|
||||
char ks_module[KSTAT_STRLEN];
|
||||
uint8_t ks_resv;
|
||||
int32_t ks_instance;
|
||||
char ks_name[KSTAT_STRLEN];
|
||||
uint8_t ks_type;
|
||||
char ks_class[KSTAT_STRLEN];
|
||||
uint8_t ks_flags;
|
||||
caddr32_t ks_data; /* type-specific data */
|
||||
uint32_t ks_ndata;
|
||||
size32_t ks_data_size;
|
||||
hrtime_t ks_snaptime;
|
||||
/*
|
||||
* Fields relevant to kernel only (only needed here for padding)
|
||||
*/
|
||||
int32_t _ks_update;
|
||||
caddr32_t _ks_private;
|
||||
int32_t _ks_snapshot;
|
||||
caddr32_t _ks_lock;
|
||||
} kstat32_t;
|
||||
|
||||
#endif /* _SYSCALL32 */
|
||||
|
||||
/*
|
||||
* kstat structure and locking strategy
|
||||
*
|
||||
* Each kstat consists of a header section (a kstat_t) and a data section.
|
||||
* The system maintains a set of kstats, protected by kstat_chain_lock.
|
||||
* kstat_chain_lock protects all additions to/deletions from this set,
|
||||
* as well as all changes to kstat headers. kstat data sections are
|
||||
* *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL,
|
||||
* kstat clients (e.g. /dev/kstat) will acquire this lock for all of their
|
||||
* operations on that kstat. It is up to the kstat provider to decide whether
|
||||
* guaranteeing consistent data to kstat clients is sufficiently important
|
||||
* to justify the locking cost. Note, however, that most statistic updates
|
||||
* already occur under one of the provider's mutexes, so if the provider sets
|
||||
* ks_lock to point to that mutex, then kstat data locking is free.
|
||||
*
|
||||
* NOTE: variable-size kstats MUST employ kstat data locking, to prevent
|
||||
* data-size races with kstat clients.
|
||||
*
|
||||
* NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *)
|
||||
* in the kstat header so that users don't have to be exposed to all of the
|
||||
* kernel's lock-related data structures.
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
#define KSTAT_ENTER(k) \
|
||||
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); }
|
||||
|
||||
#define KSTAT_EXIT(k) \
|
||||
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); }
|
||||
|
||||
#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw))
|
||||
|
||||
#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw))
|
||||
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
/*
|
||||
* kstat time
|
||||
*
|
||||
* All times associated with kstats (e.g. creation time, snapshot time,
|
||||
* kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values,
|
||||
* as returned by gethrtime(). The accuracy of these timestamps is machine
|
||||
* dependent, but the precision (units) is the same across all platforms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat identity (KID)
|
||||
*
|
||||
* Each kstat is assigned a unique KID (kstat ID) when it is added to the
|
||||
* global kstat chain. The KID is used as a cookie by /dev/kstat to
|
||||
* request information about the corresponding kstat. There is also
|
||||
* an identity associated with the entire kstat chain, kstat_chain_id,
|
||||
* which is bumped each time a kstat is added or deleted. /dev/kstat uses
|
||||
* the chain ID to detect changes in the kstat chain (e.g., a new disk
|
||||
* coming online) between ioctl()s.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat module, kstat instance
|
||||
*
|
||||
* ks_module and ks_instance contain the name and instance of the module
|
||||
* that created the kstat. In cases where there can only be one instance,
|
||||
* ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its
|
||||
* module name.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat name
|
||||
*
|
||||
* ks_name gives a meaningful name to a kstat. The full kstat namespace
|
||||
* is module.instance.name, so the name only need be unique within a
|
||||
* module. kstat_create() will fail if you try to create a kstat with
|
||||
* an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are
|
||||
* allowed in kstat names, but strongly discouraged, since they hinder
|
||||
* awk-style processing at user level.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat type
|
||||
*
|
||||
* The kstat mechanism provides several flavors of kstat data, defined
|
||||
* below. The "raw" kstat type is just treated as an array of bytes; you
|
||||
* can use this to export any kind of data you want.
|
||||
*
|
||||
* Some kstat types allow multiple data structures per kstat, e.g.
|
||||
* KSTAT_TYPE_NAMED; others do not. This is part of the spec for each
|
||||
* kstat data type.
|
||||
*
|
||||
* User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To
|
||||
* get this information, read out the standard system kstat "kstat_types".
|
||||
*/
|
||||
|
||||
#define KSTAT_TYPE_RAW 0 /* can be anything */
|
||||
/* ks_ndata >= 1 */
|
||||
#define KSTAT_TYPE_NAMED 1 /* name/value pair */
|
||||
/* ks_ndata >= 1 */
|
||||
#define KSTAT_TYPE_INTR 2 /* interrupt statistics */
|
||||
/* ks_ndata == 1 */
|
||||
#define KSTAT_TYPE_IO 3 /* I/O statistics */
|
||||
/* ks_ndata == 1 */
|
||||
#define KSTAT_TYPE_TIMER 4 /* event timer */
|
||||
/* ks_ndata >= 1 */
|
||||
|
||||
#define KSTAT_NUM_TYPES 5
|
||||
|
||||
/*
|
||||
* kstat class
|
||||
*
|
||||
* Each kstat can be characterized as belonging to some broad class
|
||||
* of statistics, e.g. disk, tape, net, vm, streams, etc. This field
|
||||
* can be used as a filter to extract related kstats. The following
|
||||
* values are currently in use: disk, tape, net, controller, vm, kvm,
|
||||
* hat, streams, kstat, and misc. (The kstat class encompasses things
|
||||
* like kstat_types.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat flags
|
||||
*
|
||||
* Any of the following flags may be passed to kstat_create(). They are
|
||||
* all zero by default.
|
||||
*
|
||||
* KSTAT_FLAG_VIRTUAL:
|
||||
*
|
||||
* Tells kstat_create() not to allocate memory for the
|
||||
* kstat data section; instead, you will set the ks_data
|
||||
* field to point to the data you wish to export. This
|
||||
* provides a convenient way to export existing data
|
||||
* structures.
|
||||
*
|
||||
* KSTAT_FLAG_VAR_SIZE:
|
||||
*
|
||||
* The size of the kstat you are creating will vary over time.
|
||||
* For example, you may want to use the kstat mechanism to
|
||||
* export a linked list. NOTE: The kstat framework does not
|
||||
* manage the data section, so all variable-size kstats must be
|
||||
* virtual kstats. Moreover, variable-size kstats MUST employ
|
||||
* kstat data locking to prevent data-size races with kstat
|
||||
* clients. See the section on "kstat snapshot" for details.
|
||||
*
|
||||
* KSTAT_FLAG_WRITABLE:
|
||||
*
|
||||
* Makes the kstat's data section writable by root.
|
||||
* The ks_snapshot routine (see below) does not need to check for
|
||||
* this; permission checking is handled in the kstat driver.
|
||||
*
|
||||
* KSTAT_FLAG_PERSISTENT:
|
||||
*
|
||||
* Indicates that this kstat is to be persistent over time.
|
||||
* For persistent kstats, kstat_delete() simply marks the
|
||||
* kstat as dormant; a subsequent kstat_create() reactivates
|
||||
* the kstat. This feature is provided so that statistics
|
||||
* are not lost across driver close/open (e.g., raw disk I/O
|
||||
* on a disk with no mounted partitions.)
|
||||
* NOTE: Persistent kstats cannot be virtual, since ks_data
|
||||
* points to garbage as soon as the driver goes away.
|
||||
*
|
||||
* The following flags are maintained by the kstat framework:
|
||||
*
|
||||
* KSTAT_FLAG_DORMANT:
|
||||
*
|
||||
* For persistent kstats, indicates that the kstat is in the
|
||||
* dormant state (e.g., the corresponding device is closed).
|
||||
*
|
||||
* KSTAT_FLAG_INVALID:
|
||||
*
|
||||
* This flag is set when a kstat is in a transitional state,
|
||||
* e.g. between kstat_create() and kstat_install().
|
||||
* kstat clients must not attempt to access the kstat's data
|
||||
* if this flag is set.
|
||||
*/
|
||||
|
||||
#define KSTAT_FLAG_VIRTUAL 0x01
|
||||
#define KSTAT_FLAG_VAR_SIZE 0x02
|
||||
#define KSTAT_FLAG_WRITABLE 0x04
|
||||
#define KSTAT_FLAG_PERSISTENT 0x08
|
||||
#define KSTAT_FLAG_DORMANT 0x10
|
||||
#define KSTAT_FLAG_INVALID 0x20
|
||||
|
||||
/*
|
||||
* Dynamic update support
|
||||
*
|
||||
* The kstat mechanism allows for an optional ks_update function to update
|
||||
* kstat data. This is useful for drivers where the underlying device
|
||||
* keeps cheap hardware stats, but extraction is expensive. Instead of
|
||||
* constantly keeping the kstat data section up to date, you can supply a
|
||||
* ks_update function which updates the kstat's data section on demand.
|
||||
* To take advantage of this feature, simply set the ks_update field before
|
||||
* calling kstat_install().
|
||||
*
|
||||
* The ks_update function, if supplied, must have the following structure:
|
||||
*
|
||||
* int
|
||||
* foo_kstat_update(kstat_t *ksp, int rw)
|
||||
* {
|
||||
* if (rw == KSTAT_WRITE) {
|
||||
* ... update the native stats from ksp->ks_data;
|
||||
* return EACCES if you don't support this
|
||||
* } else {
|
||||
* ... update ksp->ks_data from the native stats
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The ks_update return codes are: 0 for success, EACCES if you don't allow
|
||||
* KSTAT_WRITE, and EIO for any other type of error.
|
||||
*
|
||||
* In general, the ks_update function may need to refer to provider-private
|
||||
* data; for example, it may need a pointer to the provider's raw statistics.
|
||||
* The ks_private field is available for this purpose. Its use is entirely
|
||||
* at the provider's discretion.
|
||||
*
|
||||
* All variable-size kstats MUST supply a ks_update routine, which computes
|
||||
* and sets ks_data_size (and ks_ndata if that is meaningful), since these
|
||||
* are needed to perform kstat snapshots (see below).
|
||||
*
|
||||
* No kstat locking should be done inside the ks_update routine. The caller
|
||||
* will already be holding the kstat's ks_lock (to ensure consistent data).
|
||||
*/
|
||||
|
||||
#define KSTAT_READ 0
|
||||
#define KSTAT_WRITE 1
|
||||
|
||||
/*
|
||||
* Kstat snapshot
|
||||
*
|
||||
* In order to get a consistent view of a kstat's data, clients must obey
|
||||
* the kstat's locking strategy. However, these clients may need to perform
|
||||
* operations on the data which could cause a fault (e.g. copyout()), or
|
||||
* operations which are simply expensive. Doing so could cause deadlock
|
||||
* (e.g. if you're holding a disk's kstat lock which is ultimately required
|
||||
* to resolve a copyout() fault), performance degradation (since the providers'
|
||||
* activity is serialized at the kstat lock), device timing problems, etc.
|
||||
*
|
||||
* To avoid these problems, kstat data is provided via snapshots. Taking
|
||||
* a snapshot is a simple process: allocate a wired-down kernel buffer,
|
||||
* acquire the kstat's data lock, copy the data into the buffer ("take the
|
||||
* snapshot"), and release the lock. This ensures that the kstat's data lock
|
||||
* will be held as briefly as possible, and that no faults will occur while
|
||||
* the lock is held.
|
||||
*
|
||||
* Normally, the snapshot is taken by default_kstat_snapshot(), which
|
||||
* timestamps the data (sets ks_snaptime), copies it, and does a little
|
||||
* massaging to deal with incomplete transactions on i/o kstats. However,
|
||||
* this routine only works for kstats with contiguous data (the typical case).
|
||||
* If you create a kstat whose data is, say, a linked list, you must provide
|
||||
* your own ks_snapshot routine. The routine you supply must have the
|
||||
* following prototype (replace "foo" with something appropriate):
|
||||
*
|
||||
* int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw);
|
||||
*
|
||||
* The minimal snapshot routine -- one which copies contiguous data that
|
||||
* doesn't need any massaging -- would be this:
|
||||
*
|
||||
* ksp->ks_snaptime = gethrtime();
|
||||
* if (rw == KSTAT_WRITE)
|
||||
* bcopy(buf, ksp->ks_data, ksp->ks_data_size);
|
||||
* else
|
||||
* bcopy(ksp->ks_data, buf, ksp->ks_data_size);
|
||||
* return (0);
|
||||
*
|
||||
* A more illuminating example is taking a snapshot of a linked list:
|
||||
*
|
||||
* ksp->ks_snaptime = gethrtime();
|
||||
* if (rw == KSTAT_WRITE)
|
||||
* return (EACCES); ... See below ...
|
||||
* for (foo = first_foo; foo; foo = foo->next) {
|
||||
* bcopy((char *) foo, (char *) buf, sizeof (struct foo));
|
||||
* buf = ((struct foo *) buf) + 1;
|
||||
* }
|
||||
* return (0);
|
||||
*
|
||||
* In the example above, we have decided that we don't want to allow
|
||||
* KSTAT_WRITE access, so we return EACCES if this is attempted.
|
||||
*
|
||||
* The key points are:
|
||||
*
|
||||
* (1) ks_snaptime must be set (via gethrtime()) to timestamp the data.
|
||||
* (2) Data gets copied from the kstat to the buffer on KSTAT_READ,
|
||||
* and from the buffer to the kstat on KSTAT_WRITE.
|
||||
* (3) ks_snapshot return values are: 0 for success, EACCES if you
|
||||
* don't allow KSTAT_WRITE, and EIO for any other type of error.
|
||||
*
|
||||
* Named kstats (see section on "Named statistics" below) containing long
|
||||
* strings (KSTAT_DATA_STRING) need special handling. The kstat driver
|
||||
* assumes that all strings are copied into the buffer after the array of
|
||||
* named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point
|
||||
* into the copy within the buffer. The default snapshot routine does this,
|
||||
* but overriding routines should contain at least the following:
|
||||
*
|
||||
* if (rw == KSTAT_READ) {
|
||||
* kstat_named_t *knp = buf;
|
||||
* char *end = knp + ksp->ks_ndata;
|
||||
* uint_t i;
|
||||
*
|
||||
* ... Do the regular copy ...
|
||||
* bcopy(ksp->ks_data, buf, sizeof (kstat_named_t) * ksp->ks_ndata);
|
||||
*
|
||||
* for (i = 0; i < ksp->ks_ndata; i++, knp++) {
|
||||
* if (knp[i].data_type == KSTAT_DATA_STRING &&
|
||||
* KSTAT_NAMED_STR_PTR(knp) != NULL) {
|
||||
* bcopy(KSTAT_NAMED_STR_PTR(knp), end,
|
||||
* KSTAT_NAMED_STR_BUFLEN(knp));
|
||||
* KSTAT_NAMED_STR_PTR(knp) = end;
|
||||
* end += KSTAT_NAMED_STR_BUFLEN(knp);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Named statistics.
|
||||
*
|
||||
* List of arbitrary name=value statistics.
|
||||
*/
|
||||
|
||||
typedef struct kstat_named {
|
||||
char name[KSTAT_STRLEN]; /* name of counter */
|
||||
uchar_t data_type; /* data type */
|
||||
union {
|
||||
char c[16]; /* enough for 128-bit ints */
|
||||
int32_t i32;
|
||||
uint32_t ui32;
|
||||
struct {
|
||||
union {
|
||||
char *ptr; /* NULL-term string */
|
||||
#if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
|
||||
caddr32_t ptr32;
|
||||
#endif
|
||||
char __pad[8]; /* 64-bit padding */
|
||||
} addr;
|
||||
uint32_t len; /* # bytes for strlen + '\0' */
|
||||
} str;
|
||||
/*
|
||||
* The int64_t and uint64_t types are not valid for a maximally conformant
|
||||
* 32-bit compilation environment (cc -Xc) using compilers prior to the
|
||||
* introduction of C99 conforming compiler (reference ISO/IEC 9899:1990).
|
||||
* In these cases, the visibility of i64 and ui64 is only permitted for
|
||||
* 64-bit compilation environments or 32-bit non-maximally conformant
|
||||
* C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
|
||||
* C99 ANSI C compilation environment, the long long type is supported.
|
||||
* The _INT64_TYPE is defined by the implementation (see sys/int_types.h).
|
||||
*/
|
||||
#if defined(_INT64_TYPE)
|
||||
int64_t i64;
|
||||
uint64_t ui64;
|
||||
#endif
|
||||
long l;
|
||||
ulong_t ul;
|
||||
|
||||
/* These structure members are obsolete */
|
||||
|
||||
longlong_t ll;
|
||||
u_longlong_t ull;
|
||||
float f;
|
||||
double d;
|
||||
} value; /* value of counter */
|
||||
} kstat_named_t;
|
||||
|
||||
#define KSTAT_DATA_CHAR 0
|
||||
#define KSTAT_DATA_INT32 1
|
||||
#define KSTAT_DATA_UINT32 2
|
||||
#define KSTAT_DATA_INT64 3
|
||||
#define KSTAT_DATA_UINT64 4
|
||||
|
||||
#if !defined(_LP64)
|
||||
#define KSTAT_DATA_LONG KSTAT_DATA_INT32
|
||||
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32
|
||||
#else
|
||||
#if !defined(_KERNEL)
|
||||
#define KSTAT_DATA_LONG KSTAT_DATA_INT64
|
||||
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64
|
||||
#else
|
||||
#define KSTAT_DATA_LONG 7 /* only visible to the kernel */
|
||||
#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */
|
||||
#endif /* !_KERNEL */
|
||||
#endif /* !_LP64 */
|
||||
|
||||
/*
|
||||
* Statistics exporting named kstats with long strings (KSTAT_DATA_STRING)
|
||||
* may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof
|
||||
* (kstat_named_t)). ks_data_size in these cases is equal to the sum of the
|
||||
* amount of space required to store the strings (ie, the sum of
|
||||
* KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the
|
||||
* space required to store the kstat_named_t's.
|
||||
*
|
||||
* The default update routine will update ks_data_size automatically for
|
||||
* variable-length kstats containing long strings (using the default update
|
||||
* routine only makes sense if the string is the only thing that is changing
|
||||
* in size, and ks_ndata is constant). Fixed-length kstats containing long
|
||||
* strings must explicitly change ks_data_size (after creation but before
|
||||
* initialization) to reflect the correct amount of space required for the
|
||||
* long strings and the kstat_named_t's.
|
||||
*/
|
||||
#define KSTAT_DATA_STRING 9
|
||||
|
||||
/* These types are obsolete */
|
||||
|
||||
#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64
|
||||
#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64
|
||||
#define KSTAT_DATA_FLOAT 5
|
||||
#define KSTAT_DATA_DOUBLE 6
|
||||
|
||||
#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
|
||||
|
||||
/*
|
||||
* Retrieve the pointer of the string contained in the given named kstat.
|
||||
*/
|
||||
#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
|
||||
|
||||
/*
|
||||
* Retrieve the length of the buffer required to store the string in the given
|
||||
* named kstat.
|
||||
*/
|
||||
#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len)
|
||||
|
||||
/*
|
||||
* Interrupt statistics.
|
||||
*
|
||||
* An interrupt is a hard interrupt (sourced from the hardware device
|
||||
* itself), a soft interrupt (induced by the system via the use of
|
||||
* some system interrupt source), a watchdog interrupt (induced by
|
||||
* a periodic timer call), spurious (an interrupt entry point was
|
||||
* entered but there was no interrupt condition to service),
|
||||
* or multiple service (an interrupt condition was detected and
|
||||
* serviced just prior to returning from any of the other types).
|
||||
*
|
||||
* Measurement of the spurious class of interrupts is useful for
|
||||
* autovectored devices in order to pinpoint any interrupt latency
|
||||
* problems in a particular system configuration.
|
||||
*
|
||||
* Devices that have more than one interrupt of the same
|
||||
* type should use multiple structures.
|
||||
*/
|
||||
|
||||
#define KSTAT_INTR_HARD 0
|
||||
#define KSTAT_INTR_SOFT 1
|
||||
#define KSTAT_INTR_WATCHDOG 2
|
||||
#define KSTAT_INTR_SPURIOUS 3
|
||||
#define KSTAT_INTR_MULTSVC 4
|
||||
|
||||
#define KSTAT_NUM_INTRS 5
|
||||
|
||||
typedef struct kstat_intr {
|
||||
uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */
|
||||
} kstat_intr_t;
|
||||
|
||||
#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data)
|
||||
|
||||
/*
|
||||
* I/O statistics.
|
||||
*/
|
||||
|
||||
typedef struct kstat_io {
|
||||
|
||||
/*
|
||||
* Basic counters.
|
||||
*
|
||||
* The counters should be updated at the end of service
|
||||
* (e.g., just prior to calling biodone()).
|
||||
*/
|
||||
|
||||
u_longlong_t nread; /* number of bytes read */
|
||||
u_longlong_t nwritten; /* number of bytes written */
|
||||
uint_t reads; /* number of read operations */
|
||||
uint_t writes; /* number of write operations */
|
||||
|
||||
/*
|
||||
* Accumulated time and queue length statistics.
|
||||
*
|
||||
* Accumulated time statistics are kept as a running sum
|
||||
* of "active" time. Queue length statistics are kept as a
|
||||
* running sum of the product of queue length and elapsed time
|
||||
* at that length -- i.e., a Riemann sum for queue length
|
||||
* integrated against time. (You can also think of the active time
|
||||
* as a Riemann sum, for the boolean function (queue_length > 0)
|
||||
* integrated against time, or you can think of it as the
|
||||
* Lebesgue measure of the set on which queue_length > 0.)
|
||||
*
|
||||
* ^
|
||||
* | _________
|
||||
* 8 | i4 |
|
||||
* | | |
|
||||
* Queue 6 | |
|
||||
* Length | _________ | |
|
||||
* 4 | i2 |_______| |
|
||||
* | | i3 |
|
||||
* 2_______| |
|
||||
* | i1 |
|
||||
* |_______________________________|
|
||||
* Time-> t1 t2 t3 t4
|
||||
*
|
||||
* At each change of state (entry or exit from the queue),
|
||||
* we add the elapsed time (since the previous state change)
|
||||
* to the active time if the queue length was non-zero during
|
||||
* that interval; and we add the product of the elapsed time
|
||||
* times the queue length to the running length*time sum.
|
||||
*
|
||||
* This method is generalizable to measuring residency
|
||||
* in any defined system: instead of queue lengths, think
|
||||
* of "outstanding RPC calls to server X".
|
||||
*
|
||||
* A large number of I/O subsystems have at least two basic
|
||||
* "lists" of transactions they manage: one for transactions
|
||||
* that have been accepted for processing but for which processing
|
||||
* has yet to begin, and one for transactions which are actively
|
||||
* being processed (but not done). For this reason, two cumulative
|
||||
* time statistics are defined here: wait (pre-service) time,
|
||||
* and run (service) time.
|
||||
*
|
||||
* All times are 64-bit nanoseconds (hrtime_t), as returned by
|
||||
* gethrtime().
|
||||
*
|
||||
* The units of cumulative busy time are accumulated nanoseconds.
|
||||
* The units of cumulative length*time products are elapsed time
|
||||
* times queue length.
|
||||
*
|
||||
* Updates to the fields below are performed implicitly by calls to
|
||||
* these five functions:
|
||||
*
|
||||
* kstat_waitq_enter()
|
||||
* kstat_waitq_exit()
|
||||
* kstat_runq_enter()
|
||||
* kstat_runq_exit()
|
||||
*
|
||||
* kstat_waitq_to_runq() (see below)
|
||||
* kstat_runq_back_to_waitq() (see below)
|
||||
*
|
||||
* Since kstat_waitq_exit() is typically followed immediately
|
||||
* by kstat_runq_enter(), there is a single kstat_waitq_to_runq()
|
||||
* function which performs both operations. This is a performance
|
||||
* win since only one timestamp is required.
|
||||
*
|
||||
* In some instances, it may be necessary to move a request from
|
||||
* the run queue back to the wait queue, e.g. for write throttling.
|
||||
* For these situations, call kstat_runq_back_to_waitq().
|
||||
*
|
||||
* These fields should never be updated by any other means.
|
||||
*/
|
||||
|
||||
hrtime_t wtime; /* cumulative wait (pre-service) time */
|
||||
hrtime_t wlentime; /* cumulative wait length*time product */
|
||||
hrtime_t wlastupdate; /* last time wait queue changed */
|
||||
hrtime_t rtime; /* cumulative run (service) time */
|
||||
hrtime_t rlentime; /* cumulative run length*time product */
|
||||
hrtime_t rlastupdate; /* last time run queue changed */
|
||||
|
||||
uint_t wcnt; /* count of elements in wait state */
|
||||
uint_t rcnt; /* count of elements in run state */
|
||||
|
||||
} kstat_io_t;
|
||||
|
||||
#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data)
|
||||
|
||||
/*
|
||||
* Event timer statistics - cumulative elapsed time and number of events.
|
||||
*
|
||||
* Updates to these fields are performed implicitly by calls to
|
||||
* kstat_timer_start() and kstat_timer_stop().
|
||||
*/
|
||||
|
||||
typedef struct kstat_timer {
|
||||
char name[KSTAT_STRLEN]; /* event name */
|
||||
uchar_t resv; /* reserved */
|
||||
u_longlong_t num_events; /* number of events */
|
||||
hrtime_t elapsed_time; /* cumulative elapsed time */
|
||||
hrtime_t min_time; /* shortest event duration */
|
||||
hrtime_t max_time; /* longest event duration */
|
||||
hrtime_t start_time; /* previous event start time */
|
||||
hrtime_t stop_time; /* previous event stop time */
|
||||
} kstat_timer_t;
|
||||
|
||||
#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data)
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
#include <sys/t_lock.h>
|
||||
|
||||
extern kid_t kstat_chain_id; /* bumped at each state change */
|
||||
extern void kstat_init(void); /* initialize kstat framework */
|
||||
|
||||
/*
|
||||
* Adding and deleting kstats.
|
||||
*
|
||||
* The typical sequence to add a kstat is:
|
||||
*
|
||||
* ksp = kstat_create(module, instance, name, class, type, ndata, flags);
|
||||
* if (ksp) {
|
||||
* ... provider initialization, if necessary
|
||||
* kstat_install(ksp);
|
||||
* }
|
||||
*
|
||||
* There are three logically distinct steps here:
|
||||
*
|
||||
* Step 1: System Initialization (kstat_create)
|
||||
*
|
||||
* kstat_create() performs system initialization. kstat_create()
|
||||
* allocates memory for the entire kstat (header plus data), initializes
|
||||
* all header fields, initializes the data section to all zeroes, assigns
|
||||
* a unique KID, and puts the kstat onto the system's kstat chain.
|
||||
* The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set),
|
||||
* because the provider (caller) has not yet had a chance to initialize
|
||||
* the data section.
|
||||
*
|
||||
* By default, kstats are exported to all zones on the system. A kstat may be
|
||||
* created via kstat_create_zone() to specify a zone to which the statistics
|
||||
* should be exported. kstat_zone_add() may be used to specify additional
|
||||
* zones to which the statistics are to be exported.
|
||||
*
|
||||
* Step 2: Provider Initialization
|
||||
*
|
||||
* The provider performs any necessary initialization of the data section,
|
||||
* e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set
|
||||
* the ks_data field at this time. The provider may also set the ks_update,
|
||||
* ks_snapshot, ks_private, and ks_lock fields if necessary.
|
||||
*
|
||||
* Step 3: Installation (kstat_install)
|
||||
*
|
||||
* Once the kstat is completely initialized, kstat_install() clears the
|
||||
* INVALID flag, thus making the kstat accessible to the outside world.
|
||||
* kstat_install() also clears the DORMANT flag for persistent kstats.
|
||||
*
|
||||
* Removing a kstat from the system
|
||||
*
|
||||
* kstat_delete(ksp) removes ksp from the kstat chain and frees all
|
||||
* associated system resources. NOTE: When you call kstat_delete(),
|
||||
* you must NOT be holding that kstat's ks_lock. Otherwise, you may
|
||||
* deadlock with a kstat reader.
|
||||
*
|
||||
* Persistent kstats
|
||||
*
|
||||
* From the provider's point of view, persistence is transparent. The only
|
||||
* difference between ephemeral (normal) kstats and persistent kstats
|
||||
* is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically,
|
||||
* this has the effect of making your data visible even when you're
|
||||
* not home. Persistence is important to tools like iostat, which want
|
||||
* to get a meaningful picture of disk activity. Without persistence,
|
||||
* raw disk i/o statistics could never accumulate: they would come and
|
||||
* go with each open/close of the raw device.
|
||||
*
|
||||
* The magic of persistence works by slightly altering the behavior of
|
||||
* kstat_create() and kstat_delete(). The first call to kstat_create()
|
||||
* creates a new kstat, as usual. However, kstat_delete() does not
|
||||
* actually delete the kstat: it performs one final update of the data
|
||||
* (i.e., calls the ks_update routine), marks the kstat as dormant, and
|
||||
* sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back
|
||||
* to their default values (since they might otherwise point to garbage,
|
||||
* e.g. if the provider is going away). kstat clients can still access
|
||||
* the dormant kstat just like a live kstat; they just continue to see
|
||||
* the final data values as long as the kstat remains dormant.
|
||||
* All subsequent kstat_create() calls simply find the already-existing,
|
||||
* dormant kstat and return a pointer to it, without altering any fields.
|
||||
* The provider then performs its usual initialization sequence, and
|
||||
* calls kstat_install(). kstat_install() uses the old data values to
|
||||
* initialize the native data (i.e., ks_update is called with KSTAT_WRITE),
|
||||
* thus making it seem like you were never gone.
|
||||
*/
|
||||
|
||||
extern kstat_t *kstat_create(const char *, int, const char *, const char *,
|
||||
uchar_t, uint_t, uchar_t);
|
||||
extern kstat_t *kstat_create_zone(const char *, int, const char *,
|
||||
const char *, uchar_t, uint_t, uchar_t, zoneid_t);
|
||||
extern void kstat_install(kstat_t *);
|
||||
extern void kstat_delete(kstat_t *);
|
||||
extern void kstat_named_setstr(kstat_named_t *knp, const char *src);
|
||||
extern void kstat_set_string(char *, const char *);
|
||||
extern void kstat_delete_byname(const char *, int, const char *);
|
||||
extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t);
|
||||
extern void kstat_named_init(kstat_named_t *, const char *, uchar_t);
|
||||
extern void kstat_timer_init(kstat_timer_t *, const char *);
|
||||
extern void kstat_waitq_enter(kstat_io_t *);
|
||||
extern void kstat_waitq_exit(kstat_io_t *);
|
||||
extern void kstat_runq_enter(kstat_io_t *);
|
||||
extern void kstat_runq_exit(kstat_io_t *);
|
||||
extern void kstat_waitq_to_runq(kstat_io_t *);
|
||||
extern void kstat_runq_back_to_waitq(kstat_io_t *);
|
||||
extern void kstat_timer_start(kstat_timer_t *);
|
||||
extern void kstat_timer_stop(kstat_timer_t *);
|
||||
|
||||
extern void kstat_zone_add(kstat_t *, zoneid_t);
|
||||
extern void kstat_zone_remove(kstat_t *, zoneid_t);
|
||||
extern int kstat_zone_find(kstat_t *, zoneid_t);
|
||||
|
||||
extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t);
|
||||
extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t);
|
||||
extern void kstat_rele(kstat_t *);
|
||||
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_KSTAT_H */
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1994 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sys/note.h: interface for annotating source with info for tools
|
||||
*
|
||||
* This is the underlying interface; NOTE (/usr/include/note.h) is the
|
||||
* preferred interface, but all exported header files should include this
|
||||
* file directly and use _NOTE so as not to take "NOTE" from the user's
|
||||
* namespace. For consistency, *all* kernel source should use _NOTE.
|
||||
*
|
||||
* By default, annotations expand to nothing. This file implements
|
||||
* that. Tools using annotations will interpose a different version
|
||||
* of this file that will expand annotations as needed.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_NOTE_H
|
||||
#define _SYS_NOTE_H
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _NOTE
|
||||
#define _NOTE(s)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_NOTE_H */
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_PROCESSOR_H
|
||||
#define _SOL_SYS_PROCESSOR_H
|
||||
|
||||
#define getcpuid() (-1)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_SDT_H
|
||||
#define _SOL_SYS_SDT_H
|
||||
|
||||
#define DTRACE_PROBE1(a,b,c) ((void) 0)
|
||||
#define DTRACE_PROBE2(a,b,c,d,e) ((void) 0)
|
||||
#define DTRACE_PROBE3(a,b,c,d,e,f,g) ((void) 0)
|
||||
#define DTRACE_PROBE4(a,b,c,d,e,f,g,h,i) ((void) 0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SOL_SYS_SYSEVENT_H
|
||||
#define _SOL_SYS_SYSEVENT_H
|
||||
|
||||
#endif
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include "zfs_config.h"
|
||||
|
||||
#ifdef HAVE_UNICODE
|
||||
#include_next <sys/u8_textprep.h>
|
||||
#else
|
||||
|
||||
#ifndef _SYS_U8_TEXTPREP_H
|
||||
#define _SYS_U8_TEXTPREP_H
|
||||
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unicode encoding conversion functions and their macros.
|
||||
*/
|
||||
#define UCONV_IN_BIG_ENDIAN 0x0001
|
||||
#define UCONV_OUT_BIG_ENDIAN 0x0002
|
||||
#define UCONV_IN_SYSTEM_ENDIAN 0x0004
|
||||
#define UCONV_OUT_SYSTEM_ENDIAN 0x0008
|
||||
#define UCONV_IN_LITTLE_ENDIAN 0x0010
|
||||
#define UCONV_OUT_LITTLE_ENDIAN 0x0020
|
||||
#define UCONV_IGNORE_NULL 0x0040
|
||||
#define UCONV_IN_ACCEPT_BOM 0x0080
|
||||
#define UCONV_OUT_EMIT_BOM 0x0100
|
||||
|
||||
extern int uconv_u16tou32(const uint16_t *, size_t *, uint32_t *, size_t *,
|
||||
int);
|
||||
extern int uconv_u16tou8(const uint16_t *, size_t *, uchar_t *, size_t *, int);
|
||||
extern int uconv_u32tou16(const uint32_t *, size_t *, uint16_t *, size_t *,
|
||||
int);
|
||||
extern int uconv_u32tou8(const uint32_t *, size_t *, uchar_t *, size_t *, int);
|
||||
extern int uconv_u8tou16(const uchar_t *, size_t *, uint16_t *, size_t *, int);
|
||||
extern int uconv_u8tou32(const uchar_t *, size_t *, uint32_t *, size_t *, int);
|
||||
|
||||
/*
|
||||
* UTF-8 text preparation functions and their macros.
|
||||
*
|
||||
* Among the macros defined, U8_CANON_DECOMP, U8_COMPAT_DECOMP, and
|
||||
* U8_CANON_COMP are not public interfaces and must not be used directly
|
||||
* at the flag input argument.
|
||||
*/
|
||||
#define U8_STRCMP_CS (0x00000001)
|
||||
#define U8_STRCMP_CI_UPPER (0x00000002)
|
||||
#define U8_STRCMP_CI_LOWER (0x00000004)
|
||||
|
||||
#define U8_CANON_DECOMP (0x00000010)
|
||||
#define U8_COMPAT_DECOMP (0x00000020)
|
||||
#define U8_CANON_COMP (0x00000040)
|
||||
|
||||
#define U8_STRCMP_NFD (U8_CANON_DECOMP)
|
||||
#define U8_STRCMP_NFC (U8_CANON_DECOMP | U8_CANON_COMP)
|
||||
#define U8_STRCMP_NFKD (U8_COMPAT_DECOMP)
|
||||
#define U8_STRCMP_NFKC (U8_COMPAT_DECOMP | U8_CANON_COMP)
|
||||
|
||||
#define U8_TEXTPREP_TOUPPER (U8_STRCMP_CI_UPPER)
|
||||
#define U8_TEXTPREP_TOLOWER (U8_STRCMP_CI_LOWER)
|
||||
|
||||
#define U8_TEXTPREP_NFD (U8_STRCMP_NFD)
|
||||
#define U8_TEXTPREP_NFC (U8_STRCMP_NFC)
|
||||
#define U8_TEXTPREP_NFKD (U8_STRCMP_NFKD)
|
||||
#define U8_TEXTPREP_NFKC (U8_STRCMP_NFKC)
|
||||
|
||||
#define U8_TEXTPREP_IGNORE_NULL (0x00010000)
|
||||
#define U8_TEXTPREP_IGNORE_INVALID (0x00020000)
|
||||
#define U8_TEXTPREP_NOWAIT (0x00040000)
|
||||
|
||||
#define U8_UNICODE_320 (0)
|
||||
#define U8_UNICODE_500 (1)
|
||||
#define U8_UNICODE_LATEST (U8_UNICODE_500)
|
||||
|
||||
#define U8_VALIDATE_ENTIRE (0x00100000)
|
||||
#define U8_VALIDATE_CHECK_ADDITIONAL (0x00200000)
|
||||
#define U8_VALIDATE_UCS2_RANGE (0x00400000)
|
||||
|
||||
#define U8_ILLEGAL_CHAR (-1)
|
||||
#define U8_OUT_OF_RANGE_CHAR (-2)
|
||||
|
||||
extern int u8_validate(char *, size_t, char **, int, int *);
|
||||
extern int u8_strcmp(const char *, const char *, size_t, int, size_t, int *);
|
||||
extern size_t u8_textprep_str(char *, size_t *, char *, size_t *, int, size_t,
|
||||
int *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_UNICODE */
|
||||
|
||||
#endif /* _SYS_U8_TEXTPREP_H */
|
|
@ -30,7 +30,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
#include <sys/spa.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/processor.h>
|
||||
#include <sys/zfs_context.h>
|
||||
|
|
Loading…
Reference in New Issue