Annotation of sys/uvm/uvm_stat.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: uvm_stat.h,v 1.14 2006/01/16 13:11:06 mickey Exp $ */
! 2: /* $NetBSD: uvm_stat.h,v 1.19 2001/02/04 10:55:58 mrg Exp $ */
! 3:
! 4: /*
! 5: *
! 6: * Copyright (c) 1997 Charles D. Cranor and Washington University.
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. All advertising materials mentioning features or use of this software
! 18: * must display the following acknowledgement:
! 19: * This product includes software developed by Charles D. Cranor and
! 20: * Washington University.
! 21: * 4. The name of the author may not be used to endorse or promote products
! 22: * derived from this software without specific prior written permission.
! 23: *
! 24: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 25: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 26: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 27: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 28: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 29: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 30: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 31: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 32: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 33: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 34: *
! 35: * from: Id: uvm_stat.h,v 1.1.2.4 1998/02/07 01:16:56 chs Exp
! 36: */
! 37:
! 38: #ifndef _UVM_UVM_STAT_H_
! 39: #define _UVM_UVM_STAT_H_
! 40:
! 41: #include <sys/queue.h>
! 42:
! 43: /*
! 44: * uvm_stat: monitor what is going on with uvm (or whatever)
! 45: */
! 46:
! 47: /*
! 48: * counters [XXX: maybe replace event counters with this]
! 49: */
! 50:
! 51: #define UVMCNT_MASK 0xf /* rest are private */
! 52: #define UVMCNT_CNT 0 /* normal counter */
! 53: #define UVMCNT_DEV 1 /* device event counter */
! 54:
! 55: struct uvm_cnt {
! 56: int c; /* the value */
! 57: int t; /* type */
! 58: struct uvm_cnt *next; /* global list of cnts */
! 59: char *name; /* counter name */
! 60: void *p; /* private data */
! 61: };
! 62:
! 63: #ifdef _KERNEL
! 64:
! 65: extern struct uvm_cnt *uvm_cnt_head;
! 66:
! 67: /*
! 68: * counter operations. assume spl is set ok.
! 69: */
! 70:
! 71: #define UVMCNT_INIT(CNT,TYP,VAL,NAM,PRIV) \
! 72: do { \
! 73: CNT.c = VAL; \
! 74: CNT.t = TYP; \
! 75: CNT.next = uvm_cnt_head; \
! 76: uvm_cnt_head = &CNT; \
! 77: CNT.name = NAM; \
! 78: CNT.p = PRIV; \
! 79: } while (0)
! 80:
! 81: #define UVMCNT_SET(C,V) \
! 82: do { \
! 83: (C).c = (V); \
! 84: } while (0)
! 85:
! 86: #define UVMCNT_ADD(C,V) \
! 87: do { \
! 88: (C).c += (V); \
! 89: } while (0)
! 90:
! 91: #define UVMCNT_INCR(C) UVMCNT_ADD(C,1)
! 92: #define UVMCNT_DECR(C) UVMCNT_ADD(C,-1)
! 93:
! 94: #endif /* _KERNEL */
! 95:
! 96: /*
! 97: * history/tracing
! 98: */
! 99:
! 100: struct uvm_history_ent {
! 101: struct timeval tv; /* time stamp */
! 102: char *fmt; /* printf format */
! 103: size_t fmtlen; /* length of printf format */
! 104: char *fn; /* function name */
! 105: size_t fnlen; /* length of function name */
! 106: u_long call; /* function call number */
! 107: u_long v[4]; /* values */
! 108: };
! 109:
! 110: struct uvm_history {
! 111: const char *name; /* name of this this history */
! 112: size_t namelen; /* length of name, not including null */
! 113: LIST_ENTRY(uvm_history) list; /* link on list of all histories */
! 114: int n; /* number of entries */
! 115: int f; /* next free one */
! 116: simple_lock_data_t l; /* lock on this history */
! 117: struct uvm_history_ent *e; /* the malloc'd entries */
! 118: };
! 119:
! 120: LIST_HEAD(uvm_history_head, uvm_history);
! 121:
! 122: /*
! 123: * grovelling lists all at once. we currently do not allow more than
! 124: * 32 histories to exist, as the way to dump a number of them at once
! 125: * is by calling uvm_hist() with a bitmask.
! 126: */
! 127:
! 128: /* this is used to set the size of some arrays */
! 129: #define MAXHISTS 32 /* do not change this! */
! 130:
! 131: /* and these are the bit values of each history */
! 132: #define UVMHIST_MAPHIST 0x00000001 /* maphist */
! 133: #define UVMHIST_PDHIST 0x00000002 /* pdhist */
! 134: #define UVMHIST_UBCHIST 0x00000004 /* ubchist */
! 135: #define UVMHIST_PGHIST 0x00000008 /* pghist */
! 136:
! 137: #ifdef _KERNEL
! 138:
! 139: /*
! 140: * macros to use the history/tracing code. note that UVMHIST_LOG
! 141: * must take 4 arguments (even if they are ignored by the format).
! 142: */
! 143: #ifndef UVMHIST
! 144: #define UVMHIST_DECL(NAME)
! 145: #define UVMHIST_INIT(NAME,N)
! 146: #define UVMHIST_INIT_STATIC(NAME,BUF)
! 147: #define UVMHIST_LOG(NAME,FMT,A,B,C,D)
! 148: #define UVMHIST_CALLED(NAME)
! 149: #define UVMHIST_FUNC(FNAME)
! 150: #define uvmhist_dump(NAME)
! 151: #else
! 152: extern struct uvm_history_head uvm_histories;
! 153:
! 154: #define UVMHIST_DECL(NAME) struct uvm_history NAME
! 155:
! 156: #define UVMHIST_INIT(NAME,N) \
! 157: do { \
! 158: (NAME).name = __STRING(NAME); \
! 159: (NAME).namelen = strlen((NAME).name); \
! 160: (NAME).n = (N); \
! 161: (NAME).f = 0; \
! 162: simple_lock_init(&(NAME).l); \
! 163: (NAME).e = (struct uvm_history_ent *) \
! 164: malloc(sizeof(struct uvm_history_ent) * (N), M_TEMP, \
! 165: M_WAITOK); \
! 166: memset((NAME).e, 0, sizeof(struct uvm_history_ent) * (N)); \
! 167: LIST_INSERT_HEAD(&uvm_histories, &(NAME), list); \
! 168: } while (0)
! 169:
! 170: #define UVMHIST_INIT_STATIC(NAME,BUF) \
! 171: do { \
! 172: (NAME).name = __STRING(NAME); \
! 173: (NAME).namelen = strlen((NAME).name); \
! 174: (NAME).n = sizeof(BUF) / sizeof(struct uvm_history_ent); \
! 175: (NAME).f = 0; \
! 176: simple_lock_init(&(NAME).l); \
! 177: (NAME).e = (struct uvm_history_ent *) (BUF); \
! 178: memset((NAME).e, 0, sizeof(struct uvm_history_ent) * (NAME).n); \
! 179: LIST_INSERT_HEAD(&uvm_histories, &(NAME), list); \
! 180: } while (0)
! 181:
! 182: #if defined(UVMHIST_PRINT)
! 183: extern int uvmhist_print_enabled;
! 184: #define UVMHIST_PRINTNOW(E) \
! 185: do { \
! 186: if (uvmhist_print_enabled) { \
! 187: uvmhist_print(E); \
! 188: DELAY(100000); \
! 189: } \
! 190: } while (0)
! 191: #else
! 192: #define UVMHIST_PRINTNOW(E) /* nothing */
! 193: #endif
! 194:
! 195: #define UVMHIST_LOG(NAME,FMT,A,B,C,D) \
! 196: do { \
! 197: int _i_, _s_ = splhigh(); \
! 198: simple_lock(&(NAME).l); \
! 199: _i_ = (NAME).f; \
! 200: (NAME).f = (_i_ + 1) % (NAME).n; \
! 201: simple_unlock(&(NAME).l); \
! 202: splx(_s_); \
! 203: if (!cold) \
! 204: microtime(&(NAME).e[_i_].tv); \
! 205: (NAME).e[_i_].fmt = (FMT); \
! 206: (NAME).e[_i_].fmtlen = strlen((NAME).e[_i_].fmt); \
! 207: (NAME).e[_i_].fn = _uvmhist_name; \
! 208: (NAME).e[_i_].fnlen = strlen((NAME).e[_i_].fn); \
! 209: (NAME).e[_i_].call = _uvmhist_call; \
! 210: (NAME).e[_i_].v[0] = (u_long)(A); \
! 211: (NAME).e[_i_].v[1] = (u_long)(B); \
! 212: (NAME).e[_i_].v[2] = (u_long)(C); \
! 213: (NAME).e[_i_].v[3] = (u_long)(D); \
! 214: UVMHIST_PRINTNOW(&((NAME).e[_i_])); \
! 215: } while (0)
! 216:
! 217: #define UVMHIST_CALLED(NAME) \
! 218: do { \
! 219: { \
! 220: int s = splhigh(); \
! 221: simple_lock(&(NAME).l); \
! 222: _uvmhist_call = _uvmhist_cnt++; \
! 223: simple_unlock(&(NAME).l); \
! 224: splx(s); \
! 225: } \
! 226: UVMHIST_LOG(NAME,"called!", 0, 0, 0, 0); \
! 227: } while (0)
! 228:
! 229: #define UVMHIST_FUNC(FNAME) \
! 230: static int _uvmhist_cnt = 0; \
! 231: static char *_uvmhist_name = FNAME; \
! 232: int _uvmhist_call;
! 233:
! 234: static __inline void uvmhist_print(struct uvm_history_ent *);
! 235:
! 236: static __inline void
! 237: uvmhist_print(e)
! 238: struct uvm_history_ent *e;
! 239: {
! 240: printf("%06ld.%06ld ", e->tv.tv_sec, e->tv.tv_usec);
! 241: printf("%s#%ld: ", e->fn, e->call);
! 242: printf(e->fmt, e->v[0], e->v[1], e->v[2], e->v[3]);
! 243: printf("\n");
! 244: }
! 245: #endif /* UVMHIST */
! 246:
! 247: #endif /* _KERNEL */
! 248:
! 249: #endif /* _UVM_UVM_STAT_H_ */
CVSweb