umem_impl.h revision 2
/*
* 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
* 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
*/
/*
*/
#ifndef _UMEM_IMPL_H
#define _UMEM_IMPL_H
#include <umem.h>
#include <sys/sysmacros.h>
#include <thread.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* umem memory allocator: implementation-private data structures
*/
/*
* Internal flags for umem_cache_create
*/
#define UMC_QCACHE 0x00100000
#define UMC_INTERNAL 0x80000000
/*
* Cache flags
*/
#define UMEM_STACK_DEPTH umem_stack_depth
#define UMEM_FREE_PATTERN 0xdeadbeefdeadbeefULL
#define UMEM_UNINITIALIZED_PATTERN 0xbaddcafebaddcafeULL
#define UMEM_REDZONE_PATTERN 0xfeedfacefeedfaceULL
#define UMEM_REDZONE_BYTE 0xbb
#define UMEM_FATAL_FLAGS (UMEM_NOFAIL)
#define UMEM_SLEEP_FLAGS (0)
/*
* Redzone size encodings for umem_alloc() / umem_free(). We encode the
* allocation size, rather than storing it directly, so that umem_free()
* can distinguish frees of the wrong size from redzone violations.
*/
#define UMEM_SIZE_DECODE(x) ((x) / 251)
/*
* The bufctl (buffer control) structure keeps some minimal information
* about each buffer: its address, its slab, and its current linkage,
* which is either on the slab's freelist (if the buffer is free), or
* on the cache's buf-to-bufctl hash table (if the buffer is allocated).
* In the case of non-hashed, or "raw", caches (the common case), only
* the freelist linkage is necessary: the buffer address is at a fixed
* offset from the bufctl address, and the slab is at the end of the page.
*
* NOTE: bc_next must be the first field; raw buffers have linkage only.
*/
typedef struct umem_bufctl {
void *bc_addr; /* address of buffer */
/*
* The UMF_AUDIT version of the bufctl structure. The beginning of this
* structure must be identical to the normal bufctl structure so that
* pointers are interchangeable.
*/
#define UMEM_BUFCTL_AUDIT_SIZE_DEPTH(frames) \
/*
* umem_bufctl_audits must be allocated from a UMC_NOHASH cache, so we
* require that 2 of them, plus 2 buftags, plus a umem_slab_t, all fit on
* a single page.
*
* For ILP32, this is about 1000 frames.
* For LP64, this is about 490 frames.
*/
#define UMEM_BUFCTL_AUDIT_ALIGN 32
#define UMEM_BUFCTL_AUDIT_MAX_SIZE \
sizeof (umem_buftag_t), UMEM_BUFCTL_AUDIT_ALIGN))
#define UMEM_MAX_STACK_DEPTH \
UMEM_BUFCTL_AUDIT_SIZE_DEPTH(0)) / sizeof (uintptr_t))
typedef struct umem_bufctl_audit {
void *bc_addr; /* address of buffer */
void *bc_contents; /* contents at last free */
int bc_depth; /* stack depth */
#define UMEM_LOCAL_BUFCTL_AUDIT(bcpp) \
*(bcpp) = (umem_bufctl_audit_t *) \
#define UMEM_BUFCTL_AUDIT_SIZE \
/*
* A umem_buftag structure is appended to each buffer whenever any of the
* UMF_BUFTAG flags (UMF_DEADBEEF, UMF_REDZONE, UMF_VERIFY) are set.
*/
typedef struct umem_buftag {
#define UMEM_BUFTAG_ALLOC 0xa110c8edUL
#define UMEM_BUFTAG_FREE 0xf4eef4eeUL
typedef struct umem_slab {
void *slab_base; /* base of allocated memory */
long slab_refcnt; /* outstanding allocations */
long slab_chunks; /* chunks (bufs) in this slab */
} umem_slab_t;
#define UMEM_HASH_INITIAL 64
((cp)->cache_hash_table + \
typedef struct umem_magazine {
void *mag_next;
/*
* The magazine types for fast per-cpu allocation
*/
typedef struct umem_magtype {
int mt_magsize; /* magazine size (number of rounds) */
int mt_align; /* magazine alignment */
#define UMEM_CACHE_SIZE(ncpus) \
typedef struct umem_cpu_cache {
int cc_rounds; /* number of objects in loaded mag */
int cc_prounds; /* number of objects in previous mag */
int cc_magsize; /* number of rounds in a full mag */
int cc_flags; /* CPU-local copy of cache_flags */
#ifndef _LP64
#endif
/*
* The magazine lists used in the depot.
*/
typedef struct umem_maglist {
long ml_total; /* number of magazines */
long ml_min; /* min since last update */
long ml_reaplimit; /* max reapable magazines */
#define UMEM_CACHE_NAMELEN 31
struct umem_cache {
/*
* Statistics
*/
/*
* Cache properties
*/
void *cache_private; /* opaque arg to callbacks */
int cache_cflags; /* cache creation flags */
int cache_flags; /* various cache state info */
int cache_uflags; /* UMU_* flags */
/*
* Slab layer
*/
/*
* Depot layer
*/
/*
* Per-CPU layer
*/
};
typedef struct umem_cpu_log_header {
char *clh_current;
int clh_chunk;
int clh_hits;
sizeof (size_t) - 2 * sizeof (int)];
typedef struct umem_log_header {
char *lh_base;
int *lh_free;
int lh_nchunks;
int lh_head;
int lh_tail;
int lh_hits;
typedef struct umem_cpu {
} umem_cpu_t;
#define UMEM_MAXBUF 16384
/*
* For 64 bits, buffers >= 16 bytes must be 16-byte aligned
*/
#ifdef _LP64
#define UMEM_SECOND_ALIGN 16
#else
#define UMEM_SECOND_ALIGN UMEM_ALIGN
#endif
#define MEMALIGN_MAGIC 0x3e3a1000
#ifdef _LP64
#endif
#define UMU_MAGAZINE_RESIZE 0x00000001
#define UMU_HASH_RESCALE 0x00000002
#define UMU_REAP 0x00000004
#define UMU_NOTIFY 0x08000000
#define UMU_ACTIVE 0x80000000
#define UMEM_READY_INIT_FAILED -1
#define UMEM_READY_STARTUP 1
#define UMEM_READY_INITING 2
#define UMEM_READY 3
#ifdef UMEM_STANDALONE
#endif
#ifdef __cplusplus
}
#endif
#endif /* _UMEM_IMPL_H */