File:  [DragonFly] / src / sys / sys / kobj.h
Revision 1.6: download - view: text, annotated - select for diffs
Thu Apr 1 08:41:24 2004 UTC (10 years ago) by joerg
Branches: MAIN
CVS tags: HEAD
KObj extension stage I/III

Isolate the reference counting for kobj classes in special functions to
allow clean locking in the next step.

Merge all calls of kobj_class_compile either into the new
kobj_class_instantiate or into kobj_init and make it static. Same for
kobj_class_free.

Remove kobj_class_compile_static, it wasn't used and is pretty pointless
since the kobj framework is not used before the VM subsystem has been
initialized.

    1: /*-
    2:  * Copyright (c) 2000 Doug Rabson
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  *
   14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24:  * SUCH DAMAGE.
   25:  *
   26:  * $FreeBSD: src/sys/sys/kobj.h,v 1.8 2003/09/22 21:32:49 peter Exp $
   27:  * $DragonFly: src/sys/sys/kobj.h,v 1.6 2004/04/01 08:41:24 joerg Exp $
   28:  */
   29: 
   30: #ifndef _SYS_KOBJ_H_
   31: #define _SYS_KOBJ_H_
   32: 
   33: /*
   34:  * Forward declarations
   35:  */
   36: typedef struct kobj		*kobj_t;
   37: typedef struct kobj_class	*kobj_class_t;
   38: typedef struct kobj_method	kobj_method_t;
   39: typedef int			(*kobjop_t)(void);
   40: typedef struct kobj_ops		*kobj_ops_t;
   41: typedef struct kobjop_desc	*kobjop_desc_t;
   42: struct malloc_type;
   43: 
   44: struct kobj_method {
   45: 	kobjop_desc_t	desc;
   46: 	kobjop_t	func;
   47: };
   48: 
   49: /*
   50:  * A class is simply a method table and a sizeof value. When the first
   51:  * instance of the class is created, the method table will be compiled
   52:  * into a form more suited to efficient method dispatch. This compiled
   53:  * method table is always the first field of the object.
   54:  */
   55: #define KOBJ_CLASS_FIELDS						\
   56: 	const char	*name;		/* class name */		\
   57: 	kobj_method_t	*methods;	/* method table */		\
   58: 	size_t		size;		/* object size */		\
   59: 	u_int		refs;		/* reference count */		\
   60: 	kobj_ops_t	ops		/* compiled method table */
   61: 
   62: struct kobj_class {
   63: 	KOBJ_CLASS_FIELDS;
   64: };
   65: 
   66: /*
   67:  * Implementation of kobj.
   68:  */
   69: #define KOBJ_FIELDS				\
   70: 	kobj_ops_t	ops
   71: 
   72: struct kobj {
   73: 	KOBJ_FIELDS;
   74: };
   75: 
   76: /*
   77:  * The ops table is used as a cache of results from kobj_lookup_method().
   78:  */
   79: 
   80: #define KOBJ_CACHE_SIZE	256
   81: 
   82: struct kobj_ops {
   83: 	kobj_method_t	cache[KOBJ_CACHE_SIZE];
   84: 	kobj_class_t	cls;
   85: };
   86: 
   87: struct kobjop_desc {
   88: 	unsigned int	id;	/* unique ID */
   89: 	kobjop_t	deflt;	/* default implementation */
   90: };
   91: 
   92: /*
   93:  * Shorthand for constructing method tables.
   94:  */
   95: #define KOBJMETHOD(NAME, FUNC) { &NAME##_desc, (kobjop_t) FUNC }
   96: 
   97: #define DEFINE_CLASS(name, methods, size)	\
   98: 						\
   99: struct kobj_class name ## _class = {		\
  100: 	#name, methods, size			\
  101: }
  102: 
  103: /*
  104:  * Compile class for the first instance and add a reference.
  105:  */
  106: void		kobj_class_instantiate(kobj_class_t cls);
  107: 
  108: /*
  109:  * Remove a reference and free method table with the last instance.
  110:  */
  111: void		kobj_class_uninstantiate(kobj_class_t cls);
  112: 
  113: /*
  114:  * Allocate memory for and initialise a new object.
  115:  */
  116: kobj_t		kobj_create(kobj_class_t cls,
  117: 			    struct malloc_type *mtype,
  118: 			    int mflags);
  119: 
  120: /*
  121:  * Initialise a pre-allocated object.
  122:  */
  123: void		kobj_init(kobj_t obj, kobj_class_t cls);
  124: 
  125: /*
  126:  * Delete an object. If mtype is non-zero, free the memory.
  127:  */
  128: void		kobj_delete(kobj_t obj, struct malloc_type *mtype);
  129: 
  130: /*
  131:  * Maintain stats on hits/misses in lookup caches.
  132:  */
  133: #ifdef KOBJ_STATS
  134: extern u_int kobj_lookup_hits;
  135: extern u_int kobj_lookup_misses;
  136: #endif
  137: 
  138: /*
  139:  * Lookup the method in the cache and if it isn't there look it up the
  140:  * slow way.
  141:  */
  142: #ifdef KOBJ_STATS
  143: #define KOBJOPLOOKUP(OPS,OP) do {					\
  144: 	kobjop_desc_t _desc = &OP##_##desc;				\
  145: 	kobj_method_t *_ce =						\
  146: 	    &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)];		\
  147: 	if (_ce->desc != _desc) {					\
  148: 		kobj_lookup_misses++;					\
  149: 		kobj_lookup_method(OPS->cls->methods, _ce, _desc);	\
  150: 	} else {							\
  151: 		kobj_lookup_hits++;					\
  152: 	}								\
  153: 	_m = _ce->func;							\
  154: } while(0)
  155: #else
  156: #define KOBJOPLOOKUP(OPS,OP) do {					\
  157: 	kobjop_desc_t _desc = &OP##_##desc;				\
  158: 	kobj_method_t *_ce = &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)]; \
  159: 	if (_ce->desc != _desc)						\
  160: 		kobj_lookup_method(OPS->cls->methods, _ce, _desc);	\
  161: 		_m = _ce->func;						\
  162: 	} while(0)
  163: #endif /* !KOBJ_STATS */
  164: 
  165: void kobj_lookup_method(kobj_method_t *methods,
  166: 			kobj_method_t *ce,
  167: 			kobjop_desc_t desc);
  168: 
  169: #endif /* !_SYS_KOBJ_H_ */