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/lib/libspl/include/umem.h

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, 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 https://opensource.org/licenses/CDDL-1.0.
   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 2008 Sun Microsystems, Inc.  All rights reserved.
   24  * Use is subject to license terms.
   25  */
   26 
   27 #ifndef _LIBSPL_UMEM_H
   28 #define _LIBSPL_UMEM_H
   29 
   30 /*
   31  * XXX: We should use the real portable umem library if it is detected
   32  * at configure time.  However, if the library is not available, we can
   33  * use a trivial malloc based implementation.  This obviously impacts
   34  * performance, but unless you are using a full userspace build of zpool for
   35  * something other than ztest, you are likely not going to notice or care.
   36  *
   37  * https://labs.omniti.com/trac/portableumem
   38  */
   39 #include <sys/debug.h>
   40 
   41 #include <stdlib.h>
   42 #include <stdio.h>
   43 #include <string.h>
   44 
   45 #ifdef  __cplusplus
   46 extern "C" {
   47 #endif
   48 
   49 typedef void vmem_t;
   50 
   51 /*
   52  * Flags for umem_alloc/umem_free
   53  */
   54 #define UMEM_DEFAULT            0x0000  /* normal -- may fail */
   55 #define UMEM_NOFAIL             0x0100  /* Never fails */
   56 
   57 /*
   58  * Flags for umem_cache_create()
   59  */
   60 #define UMC_NODEBUG             0x00020000
   61 
   62 #define UMEM_CACHE_NAMELEN      31
   63 
   64 typedef int umem_nofail_callback_t(void);
   65 typedef int umem_constructor_t(void *, void *, int);
   66 typedef void umem_destructor_t(void *, void *);
   67 typedef void umem_reclaim_t(void *);
   68 
   69 typedef struct umem_cache {
   70         char                    cache_name[UMEM_CACHE_NAMELEN + 1];
   71         size_t                  cache_bufsize;
   72         size_t                  cache_align;
   73         umem_constructor_t      *cache_constructor;
   74         umem_destructor_t       *cache_destructor;
   75         umem_reclaim_t          *cache_reclaim;
   76         void                    *cache_private;
   77         void                    *cache_arena;
   78         int                     cache_cflags;
   79 } umem_cache_t;
   80 
   81 /* Prototypes for functions to provide defaults for umem envvars */
   82 const char *_umem_debug_init(void);
   83 const char *_umem_options_init(void);
   84 const char *_umem_logging_init(void);
   85 
   86 __attribute__((alloc_size(1)))
   87 static inline void *
   88 umem_alloc(size_t size, int flags)
   89 {
   90         void *ptr = NULL;
   91 
   92         do {
   93                 ptr = malloc(size);
   94         } while (ptr == NULL && (flags & UMEM_NOFAIL));
   95 
   96         return (ptr);
   97 }
   98 
   99 __attribute__((alloc_size(1)))
  100 static inline void *
  101 umem_alloc_aligned(size_t size, size_t align, int flags)
  102 {
  103         void *ptr = NULL;
  104         int rc = EINVAL;
  105 
  106         do {
  107                 rc = posix_memalign(&ptr, align, size);
  108         } while (rc == ENOMEM && (flags & UMEM_NOFAIL));
  109 
  110         if (rc == EINVAL) {
  111                 fprintf(stderr, "%s: invalid memory alignment (%zd)\n",
  112                     __func__, align);
  113                 if (flags & UMEM_NOFAIL)
  114                         abort();
  115                 return (NULL);
  116         }
  117 
  118         return (ptr);
  119 }
  120 
  121 __attribute__((alloc_size(1)))
  122 static inline void *
  123 umem_zalloc(size_t size, int flags)
  124 {
  125         void *ptr = NULL;
  126 
  127         ptr = umem_alloc(size, flags);
  128         if (ptr)
  129                 memset(ptr, 0, size);
  130 
  131         return (ptr);
  132 }
  133 
  134 static inline void
  135 umem_free(const void *ptr, size_t size __maybe_unused)
  136 {
  137         free((void *)ptr);
  138 }
  139 
  140 /*
  141  * umem_free_aligned was added for supporting portability
  142  * with non-POSIX platforms that require a different free
  143  * to be used with aligned allocations.
  144  */
  145 static inline void
  146 umem_free_aligned(void *ptr, size_t size __maybe_unused)
  147 {
  148 #ifndef _WIN32
  149         free((void *)ptr);
  150 #else
  151         _aligned_free(ptr);
  152 #endif
  153 }
  154 
  155 static inline void
  156 umem_nofail_callback(umem_nofail_callback_t *cb __maybe_unused)
  157 {}
  158 
  159 static inline umem_cache_t *
  160 umem_cache_create(
  161     const char *name, size_t bufsize, size_t align,
  162     umem_constructor_t *constructor,
  163     umem_destructor_t *destructor,
  164     umem_reclaim_t *reclaim,
  165     void *priv, void *vmp, int cflags)
  166 {
  167         umem_cache_t *cp;
  168 
  169         cp = (umem_cache_t *)umem_alloc(sizeof (umem_cache_t), UMEM_DEFAULT);
  170         if (cp) {
  171                 strlcpy(cp->cache_name, name, UMEM_CACHE_NAMELEN);
  172                 cp->cache_bufsize = bufsize;
  173                 cp->cache_align = align;
  174                 cp->cache_constructor = constructor;
  175                 cp->cache_destructor = destructor;
  176                 cp->cache_reclaim = reclaim;
  177                 cp->cache_private = priv;
  178                 cp->cache_arena = vmp;
  179                 cp->cache_cflags = cflags;
  180         }
  181 
  182         return (cp);
  183 }
  184 
  185 static inline void
  186 umem_cache_destroy(umem_cache_t *cp)
  187 {
  188         umem_free(cp, sizeof (umem_cache_t));
  189 }
  190 
  191 static inline void *
  192 umem_cache_alloc(umem_cache_t *cp, int flags)
  193 {
  194         void *ptr = NULL;
  195 
  196         if (cp->cache_align != 0)
  197                 ptr = umem_alloc_aligned(
  198                     cp->cache_bufsize, cp->cache_align, flags);
  199         else
  200                 ptr = umem_alloc(cp->cache_bufsize, flags);
  201 
  202         if (ptr && cp->cache_constructor)
  203                 cp->cache_constructor(ptr, cp->cache_private, UMEM_DEFAULT);
  204 
  205         return (ptr);
  206 }
  207 
  208 static inline void
  209 umem_cache_free(umem_cache_t *cp, void *ptr)
  210 {
  211         if (cp->cache_destructor)
  212                 cp->cache_destructor(ptr, cp->cache_private);
  213 
  214         if (cp->cache_align != 0)
  215                 umem_free_aligned(ptr, cp->cache_bufsize);
  216         else
  217                 umem_free(ptr, cp->cache_bufsize);
  218 }
  219 
  220 static inline void
  221 umem_cache_reap_now(umem_cache_t *cp __maybe_unused)
  222 {
  223 }
  224 
  225 #ifdef  __cplusplus
  226 }
  227 #endif
  228 
  229 #endif

Cache object: 7421c4eba5cf1b8aca0e66910dd4b546


[ 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.