The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/zfs/unique.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 /*
   22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   23  * Use is subject to license terms.
   24  */
   25 
   26 
   27 
   28 #include <sys/zfs_context.h>
   29 #include <sys/avl.h>
   30 #include <sys/unique.h>
   31 
   32 static avl_tree_t unique_avl;
   33 static kmutex_t unique_mtx;
   34 
   35 typedef struct unique {
   36         avl_node_t un_link;
   37         uint64_t un_value;
   38 } unique_t;
   39 
   40 #define UNIQUE_MASK ((1ULL << UNIQUE_BITS) - 1)
   41 
   42 static int
   43 unique_compare(const void *a, const void *b)
   44 {
   45         const unique_t *una = (const unique_t *)a;
   46         const unique_t *unb = (const unique_t *)b;
   47 
   48         return (TREE_CMP(una->un_value, unb->un_value));
   49 }
   50 
   51 void
   52 unique_init(void)
   53 {
   54         avl_create(&unique_avl, unique_compare,
   55             sizeof (unique_t), offsetof(unique_t, un_link));
   56         mutex_init(&unique_mtx, NULL, MUTEX_DEFAULT, NULL);
   57 }
   58 
   59 void
   60 unique_fini(void)
   61 {
   62         avl_destroy(&unique_avl);
   63         mutex_destroy(&unique_mtx);
   64 }
   65 
   66 uint64_t
   67 unique_create(void)
   68 {
   69         uint64_t value = unique_insert(0);
   70         unique_remove(value);
   71         return (value);
   72 }
   73 
   74 uint64_t
   75 unique_insert(uint64_t value)
   76 {
   77         avl_index_t idx;
   78         unique_t *un = kmem_alloc(sizeof (unique_t), KM_SLEEP);
   79 
   80         un->un_value = value;
   81 
   82         mutex_enter(&unique_mtx);
   83         while (un->un_value == 0 || un->un_value & ~UNIQUE_MASK ||
   84             avl_find(&unique_avl, un, &idx)) {
   85                 mutex_exit(&unique_mtx);
   86                 (void) random_get_pseudo_bytes((void*)&un->un_value,
   87                     sizeof (un->un_value));
   88                 un->un_value &= UNIQUE_MASK;
   89                 mutex_enter(&unique_mtx);
   90         }
   91 
   92         avl_insert(&unique_avl, un, idx);
   93         mutex_exit(&unique_mtx);
   94 
   95         return (un->un_value);
   96 }
   97 
   98 void
   99 unique_remove(uint64_t value)
  100 {
  101         unique_t un_tofind;
  102         unique_t *un;
  103 
  104         un_tofind.un_value = value;
  105         mutex_enter(&unique_mtx);
  106         un = avl_find(&unique_avl, &un_tofind, NULL);
  107         if (un != NULL) {
  108                 avl_remove(&unique_avl, un);
  109                 kmem_free(un, sizeof (unique_t));
  110         }
  111         mutex_exit(&unique_mtx);
  112 }

Cache object: f51d8847abf05ede2b5ae95b2a1eba61


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.