1*bf9518a6Sthorpej /* $NetBSD: vmem_impl.h,v 1.8 2023/12/03 19:34:08 thorpej Exp $ */ 2cca299e0Spara 3cca299e0Spara /*- 4cca299e0Spara * Copyright (c)2006 YAMAMOTO Takashi, 5cca299e0Spara * All rights reserved. 6cca299e0Spara * 7cca299e0Spara * Redistribution and use in source and binary forms, with or without 8cca299e0Spara * modification, are permitted provided that the following conditions 9cca299e0Spara * are met: 10cca299e0Spara * 1. Redistributions of source code must retain the above copyright 11cca299e0Spara * notice, this list of conditions and the following disclaimer. 12cca299e0Spara * 2. Redistributions in binary form must reproduce the above copyright 13cca299e0Spara * notice, this list of conditions and the following disclaimer in the 14cca299e0Spara * documentation and/or other materials provided with the distribution. 15cca299e0Spara * 16cca299e0Spara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17cca299e0Spara * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18cca299e0Spara * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19cca299e0Spara * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20cca299e0Spara * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21cca299e0Spara * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22cca299e0Spara * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23cca299e0Spara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24cca299e0Spara * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25cca299e0Spara * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26cca299e0Spara * SUCH DAMAGE. 27cca299e0Spara */ 28cca299e0Spara 29cca299e0Spara /* 30cca299e0Spara * Data structures private to vmem. 31cca299e0Spara */ 32cca299e0Spara 33cca299e0Spara #ifndef _SYS_VMEM_IMPL_H_ 34cca299e0Spara #define _SYS_VMEM_IMPL_H_ 35cca299e0Spara 36cca299e0Spara #include <sys/types.h> 37cca299e0Spara 38cca299e0Spara #if defined(_KERNEL) 3919d40baaSpara #define QCACHE 408635cb3dSthorpej #include <sys/pool.h> 41cca299e0Spara #include <sys/vmem.h> 42cca299e0Spara 43cca299e0Spara #define LOCK_DECL(name) \ 44cca299e0Spara kmutex_t name; char lockpad[COHERENCY_UNIT - sizeof(kmutex_t)] 45cca299e0Spara 46cca299e0Spara #define CONDVAR_DECL(name) \ 47cca299e0Spara kcondvar_t name 48cca299e0Spara 49cca299e0Spara #else /* defined(_KERNEL) */ 50cca299e0Spara #include <stdio.h> 51cca299e0Spara #include <errno.h> 52cca299e0Spara #include <assert.h> 53cca299e0Spara #include <stdlib.h> 54cca299e0Spara #include <string.h> 55cca299e0Spara 56cca299e0Spara #include "vmem.h" 57cca299e0Spara 58cca299e0Spara #define LOCK_DECL(name) /* nothing */ 59cca299e0Spara #define CONDVAR_DECL(name) /* nothing */ 60cca299e0Spara #endif /* defined(_KERNEL) */ 61cca299e0Spara 62cca299e0Spara #define VMEM_MAXORDER (sizeof(vmem_size_t) * CHAR_BIT) 63cca299e0Spara 64cca299e0Spara typedef struct vmem_btag bt_t; 65cca299e0Spara 66471b216bSchristos TAILQ_HEAD(vmem_seglist, vmem_btag); 67cca299e0Spara LIST_HEAD(vmem_freelist, vmem_btag); 68cca299e0Spara LIST_HEAD(vmem_hashlist, vmem_btag); 69cca299e0Spara 70cca299e0Spara #if defined(QCACHE) 7119d40baaSpara #define VMEM_QCACHE_IDX_MAX 16 72cca299e0Spara 73cca299e0Spara #define QC_NAME_MAX 16 74cca299e0Spara 75cca299e0Spara struct qcache { 76cca299e0Spara pool_cache_t qc_cache; 77cca299e0Spara vmem_t *qc_vmem; 78cca299e0Spara char qc_name[QC_NAME_MAX]; 79cca299e0Spara }; 80cca299e0Spara typedef struct qcache qcache_t; 81cca299e0Spara #define QC_POOL_TO_QCACHE(pool) ((qcache_t *)(pool->pr_qcache)) 82cca299e0Spara #endif /* defined(QCACHE) */ 83cca299e0Spara 84cca299e0Spara #define VMEM_NAME_MAX 16 85cca299e0Spara 86cca299e0Spara /* vmem arena */ 87cca299e0Spara struct vmem { 88cca299e0Spara CONDVAR_DECL(vm_cv); 89cca299e0Spara LOCK_DECL(vm_lock); 90cca299e0Spara vm_flag_t vm_flags; 91cca299e0Spara vmem_import_t *vm_importfn; 92cca299e0Spara vmem_release_t *vm_releasefn; 93cca299e0Spara size_t vm_nfreetags; 94cca299e0Spara LIST_HEAD(, vmem_btag) vm_freetags; 95cca299e0Spara void *vm_arg; 96cca299e0Spara struct vmem_seglist vm_seglist; 97cca299e0Spara struct vmem_freelist vm_freelist[VMEM_MAXORDER]; 98cca299e0Spara size_t vm_hashsize; 99576fda24Sad size_t vm_hashmask; 100cca299e0Spara size_t vm_nbusytag; 101576fda24Sad size_t vm_maxbusytag; 102cca299e0Spara struct vmem_hashlist *vm_hashlist; 103cca299e0Spara struct vmem_hashlist vm_hash0; 104cca299e0Spara size_t vm_quantum_mask; 105cca299e0Spara int vm_quantum_shift; 106cca299e0Spara size_t vm_size; 107cca299e0Spara size_t vm_inuse; 108cca299e0Spara char vm_name[VMEM_NAME_MAX+1]; 109cca299e0Spara LIST_ENTRY(vmem) vm_alllist; 110cca299e0Spara 111cca299e0Spara #if defined(QCACHE) 112cca299e0Spara /* quantum cache */ 113cca299e0Spara size_t vm_qcache_max; 114cca299e0Spara struct pool_allocator vm_qcache_allocator; 115cca299e0Spara qcache_t vm_qcache_store[VMEM_QCACHE_IDX_MAX]; 116cca299e0Spara qcache_t *vm_qcache[VMEM_QCACHE_IDX_MAX]; 117cca299e0Spara #endif /* defined(QCACHE) */ 118cca299e0Spara }; 119cca299e0Spara 120cca299e0Spara /* boundary tag */ 121cca299e0Spara struct vmem_btag { 122471b216bSchristos TAILQ_ENTRY(vmem_btag) bt_seglist; 123cca299e0Spara union { 124cca299e0Spara LIST_ENTRY(vmem_btag) u_freelist; /* BT_TYPE_FREE */ 125cca299e0Spara LIST_ENTRY(vmem_btag) u_hashlist; /* BT_TYPE_BUSY */ 126cca299e0Spara } bt_u; 127cca299e0Spara #define bt_hashlist bt_u.u_hashlist 128cca299e0Spara #define bt_freelist bt_u.u_freelist 129cca299e0Spara vmem_addr_t bt_start; 130cca299e0Spara vmem_size_t bt_size; 13106f1a2daSthorpej short bt_type; 13206f1a2daSthorpej short bt_flags; 133cca299e0Spara }; 134cca299e0Spara 135cca299e0Spara #define BT_TYPE_SPAN 1 136cca299e0Spara #define BT_TYPE_SPAN_STATIC 2 137cca299e0Spara #define BT_TYPE_FREE 3 138cca299e0Spara #define BT_TYPE_BUSY 4 139cca299e0Spara #define BT_ISSPAN_P(bt) ((bt)->bt_type <= BT_TYPE_SPAN_STATIC) 140cca299e0Spara 141*bf9518a6Sthorpej #define BT_F_PRIVATE 0x0001 142*bf9518a6Sthorpej 143cca299e0Spara #define BT_END(bt) ((bt)->bt_start + (bt)->bt_size - 1) 144cca299e0Spara 145*bf9518a6Sthorpej /* 146*bf9518a6Sthorpej * Provide an estimated number of boundary tags needed for a given 147*bf9518a6Sthorpej * number of allocations from the vmem arena. This estimate is 148*bf9518a6Sthorpej * based on 2 boundary tags per allocation (see vmem_xalloc()) and 149*bf9518a6Sthorpej * 2 boundary tags per added span (one to describe the span, one to 150*bf9518a6Sthorpej * describe the span's free space; see vmem_add1()). 151*bf9518a6Sthorpej */ 152*bf9518a6Sthorpej #define VMEM_EST_BTCOUNT(ns, na) (((ns) * 2) + ((na) * 2)) 153*bf9518a6Sthorpej 154bbb1b1e0Sthorpej vmem_t * vmem_init(vmem_t *, const char *, vmem_addr_t, vmem_size_t, 155bbb1b1e0Sthorpej vmem_size_t, vmem_import_t *, vmem_release_t *, vmem_t *, 156bbb1b1e0Sthorpej vmem_size_t, vm_flag_t, int); 157*bf9518a6Sthorpej void vmem_add_bts(vmem_t *, struct vmem_btag *, unsigned int); 158bbb1b1e0Sthorpej 159cca299e0Spara #endif /* !_SYS_VMEM_IMPL_H_ */ 160