kobj.h revision 59820
1272343Sngie/*- 2272343Sngie * Copyright (c) 2000 Doug Rabson 3272343Sngie * All rights reserved. 4272343Sngie * 5272343Sngie * Redistribution and use in source and binary forms, with or without 6272343Sngie * modification, are permitted provided that the following conditions 7272343Sngie * are met: 8272343Sngie * 1. Redistributions of source code must retain the above copyright 9272343Sngie * notice, this list of conditions and the following disclaimer. 10272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer in the 12272343Sngie * documentation and/or other materials provided with the distribution. 13272343Sngie * 14272343Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15272343Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16272343Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17272343Sngie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18272343Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20272343Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22272343Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23272343Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24272343Sngie * SUCH DAMAGE. 25272343Sngie * 26272343Sngie * $FreeBSD: head/sys/sys/kobj.h 59820 2000-05-01 10:45:15Z dfr $ 27272343Sngie */ 28272343Sngie 29272343Sngie#ifndef _SYS_KOBJ_H_ 30272343Sngie#define _SYS_KOBJ_H_ 31272343Sngie 32272343Sngie/* 33272343Sngie * Forward declarations 34272343Sngie */ 35272343Sngietypedef struct kobj *kobj_t; 36272343Sngietypedef struct kobj_class *kobj_class_t; 37272343Sngietypedef struct kobj_method kobj_method_t; 38272343Sngietypedef int (*kobjop_t)(void); 39272343Sngietypedef struct kobj_ops *kobj_ops_t; 40272343Sngietypedef struct kobjop_desc *kobjop_desc_t; 41272343Sngiestruct malloc_type; 42272343Sngie 43272343Sngiestruct kobj_method { 44272343Sngie kobjop_desc_t desc; 45272343Sngie kobjop_t func; 46272343Sngie}; 47272343Sngie 48272343Sngie/* 49272343Sngie * A class is simply a method table and a sizeof value. When the first 50272343Sngie * instance of the class is created, the method table will be compiled 51272343Sngie * into a form more suited to efficient method dispatch. This compiled 52272343Sngie * method table is always the first field of the object. 53272343Sngie */ 54272343Sngie#define KOBJ_CLASS_FIELDS \ 55272343Sngie const char *name; /* class name */ \ 56272343Sngie kobj_method_t *methods; /* method table */ \ 57272343Sngie size_t size; /* object size */ \ 58272343Sngie u_int refs; /* reference count */ \ 59272343Sngie kobj_ops_t ops /* compiled method table */ 60272343Sngie 61272343Sngiestruct kobj_class { 62272343Sngie KOBJ_CLASS_FIELDS; 63272343Sngie}; 64272343Sngie 65272343Sngie/* 66272343Sngie * Implementation of kobj. 67272343Sngie */ 68272343Sngie#define KOBJ_FIELDS \ 69272343Sngie kobj_ops_t ops; 70272343Sngie 71272343Sngiestruct kobj { 72272343Sngie KOBJ_FIELDS; 73272343Sngie}; 74272343Sngie 75272343Sngie/* 76272343Sngie * The ops table is used as a cache of results from kobj_lookup_method(). 77272343Sngie */ 78272343Sngie 79272343Sngie#define KOBJ_CACHE_SIZE 256 80272343Sngie 81272343Sngiestruct kobj_ops { 82272343Sngie kobj_method_t cache[KOBJ_CACHE_SIZE]; 83272343Sngie kobj_class_t cls; 84272343Sngie}; 85272343Sngie 86272343Sngiestruct kobjop_desc { 87272343Sngie unsigned int id; /* unique ID */ 88272343Sngie kobjop_t deflt; /* default implementation */ 89272343Sngie}; 90272343Sngie 91272343Sngie/* 92272343Sngie * Shorthand for constructing method tables. 93272343Sngie */ 94272343Sngie#define KOBJMETHOD(NAME, FUNC) { &NAME##_desc, (kobjop_t) FUNC } 95272343Sngie 96272343Sngie#define DEFINE_CLASS(name, methods, size) \ 97272343Sngie \ 98272343Sngiestruct kobj_class name ## _class = { \ 99272343Sngie #name, methods, size \ 100272343Sngie} 101272343Sngie 102272343Sngie/* 103272343Sngie * Compile the method table in a class. 104272343Sngie */ 105272343Sngievoid kobj_class_compile(kobj_class_t cls); 106272343Sngie 107272343Sngie/* 108272343Sngie * Free the compiled method table in a class. 109272343Sngie */ 110272343Sngievoid kobj_class_free(kobj_class_t cls); 111272343Sngie 112272343Sngie/* 113272343Sngie * Allocate memory for and initalise a new object. 114272343Sngie */ 115272343Sngiekobj_t kobj_create(kobj_class_t cls, 116272343Sngie struct malloc_type *mtype, 117272343Sngie int mflags); 118272343Sngie 119272343Sngie/* 120272343Sngie * Initialise a pre-allocated object. 121272343Sngie */ 122void kobj_init(kobj_t obj, kobj_class_t cls); 123 124/* 125 * Delete an object. If mtype is non-zero, free the memory. 126 */ 127void kobj_delete(kobj_t obj, struct malloc_type *mtype); 128 129/* 130 * Maintain stats on hits/misses in lookup caches. 131 */ 132#ifdef KOBJ_STATS 133extern int kobj_lookup_hits; 134extern int kobj_lookup_misses; 135#define KOBJOPHIT do { kobj_lookup_hits++; } while (0) 136#define KOBJOPMISS do { kobj_lookup_misses++; } while (0) 137#else 138#define KOBJOPHIT do { } while (0) 139#define KOBJOPMISS do { } while (0) 140#endif 141 142/* 143 * Lookup the method in the cache and if it isn't there look it up the 144 * slow way. 145 */ 146#define KOBJOPLOOKUP(OPS,OP) do { \ 147 kobjop_desc_t _desc = &OP##_##desc; \ 148 kobj_method_t *_ce = \ 149 &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)]; \ 150 if (_ce->desc != _desc) { \ 151 KOBJOPMISS; \ 152 kobj_lookup_method(OPS->cls->methods, _ce, _desc); \ 153 } else { \ 154 KOBJOPHIT; \ 155 } \ 156 _m = _ce->func; \ 157} while(0) 158 159void kobj_lookup_method(kobj_method_t *methods, 160 kobj_method_t *ce, 161 kobjop_desc_t desc); 162 163#endif /* !_SYS_KOBJ_H_ */ 164