FreeBSD ZFS
The Zettabyte File System
|
00001 /* 00002 * CDDL HEADER START 00003 * 00004 * The contents of this file are subject to the terms of the 00005 * Common Development and Distribution License (the "License"). 00006 * You may not use this file except in compliance with the License. 00007 * 00008 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 00009 * or http://www.opensolaris.org/os/licensing. 00010 * See the License for the specific language governing permissions 00011 * and limitations under the License. 00012 * 00013 * When distributing Covered Code, include this CDDL HEADER in each 00014 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 00015 * If applicable, add the following below this CDDL HEADER, with the 00016 * fields enclosed by brackets "[]" replaced with your own identifying 00017 * information: Portions Copyright [yyyy] [name of copyright owner] 00018 * 00019 * CDDL HEADER END 00020 */ 00021 /* 00022 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 00023 */ 00024 00025 #ifndef _SYS_REFCOUNT_H 00026 #define _SYS_REFCOUNT_H 00027 00028 #include <sys/cdefs.h> 00029 #include <sys/types.h> 00030 #include_next <sys/refcount.h> 00031 #include <sys/list.h> 00032 #include <sys/zfs_context.h> 00033 00034 #ifdef __cplusplus 00035 extern "C" { 00036 #endif 00037 00043 #define FTAG ((char *)__func__) 00044 00045 #ifdef ZFS_DEBUG 00046 typedef struct reference { 00047 list_node_t ref_link; 00048 void *ref_holder; 00049 uint64_t ref_number; 00050 uint8_t *ref_removed; 00051 } reference_t; 00052 00053 typedef struct refcount { 00054 kmutex_t rc_mtx; 00055 list_t rc_list; 00056 list_t rc_removed; 00057 int64_t rc_count; 00058 int64_t rc_removed_count; 00059 } refcount_t; 00060 00061 void refcount_create(refcount_t *rc); 00062 void refcount_destroy(refcount_t *rc); 00063 void refcount_destroy_many(refcount_t *rc, uint64_t number); 00064 int refcount_is_zero(refcount_t *rc); 00065 int64_t refcount_count(refcount_t *rc); 00066 int64_t refcount_add(refcount_t *rc, void *holder_tag); 00067 int64_t refcount_remove(refcount_t *rc, void *holder_tag); 00068 int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_tag); 00069 int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder_tag); 00070 void refcount_transfer(refcount_t *dst, refcount_t *src); 00071 00072 void refcount_sysinit(void); 00073 void refcount_fini(void); 00074 00075 #else /* ZFS_DEBUG */ 00076 00077 typedef struct refcount { 00078 uint64_t rc_count; 00079 } refcount_t; 00080 00081 #define refcount_create(rc) ((rc)->rc_count = 0) 00082 #define refcount_destroy(rc) ((rc)->rc_count = 0) 00083 #define refcount_destroy_many(rc, number) ((rc)->rc_count = 0) 00084 #define refcount_is_zero(rc) ((rc)->rc_count == 0) 00085 #define refcount_count(rc) ((rc)->rc_count) 00086 #define refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1) 00087 #define refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1) 00088 #define refcount_add_many(rc, number, holder) \ 00089 atomic_add_64_nv(&(rc)->rc_count, number) 00090 #define refcount_remove_many(rc, number, holder) \ 00091 atomic_add_64_nv(&(rc)->rc_count, -number) 00092 #define refcount_transfer(dst, src) { \ 00093 uint64_t __tmp = (src)->rc_count; \ 00094 atomic_add_64(&(src)->rc_count, -__tmp); \ 00095 atomic_add_64(&(dst)->rc_count, __tmp); \ 00096 } 00097 00098 #define refcount_sysinit() 00099 #define refcount_fini() 00100 00101 #endif /* ZFS_DEBUG */ 00102 00103 #ifdef __cplusplus 00104 } 00105 #endif 00106 00107 #endif /* _SYS_REFCOUNT_H */