1
0
Files
irix-657m-src/irix/cmd/tk/tkm.h
2022-09-29 17:59:04 +03:00

794 lines
25 KiB
C

/**************************************************************************
* *
* Copyright (C) 1994-1996 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ifndef __TK_H__
#define __TK_H__
#ident "$Id: tkm.h,v 1.35 1997/02/19 22:31:17 cp Exp $"
#ifndef CELL
#error included by non-CELL configuration
#endif
#include "sgidefs.h"
#include "stdarg.h"
#ifndef _KERNEL
#include "stdio.h"
#else
#include "ksys/object.h"
#endif
/*
* Public interface for token management - both client and server side.
*
* Naming convention:
* tkc_ client calls
* tks_ server calls
*
* Each token controlled object has a set of up to 10 tokens associated with it.
* The state for the client set of tokens is maintained in the tkc_state_t
* data structure. This structure is allocated by the client using
* the TKC_DECL macro.
* Most operations take token sets (tk_set_t) and disposition sets (tk_disp_t)
* thus permitting operations on a number of individual tokens (classes)
* at once.
*/
/*
* Token sets & levels and manipulation macros
*/
#define TK_MAXTOKENS 10 /* max tokens per object */
#define TK_READ 1 /* shared read */
#define TK_WRITE 2 /* exclusive write */
#define TK_SWRITE 4 /* shared write */
#define TK_LWIDTH 3 /* 3 bits */
typedef __uint32_t tk_set_t;
/* TK_MAKE is the basic macro for constructing
* token sets. It can be used for both static/runtime construction.
* Token sets can be constructed using:
* TK_ADD_SET - for static / runtime initialization
* TK_SUB_SET - for static / runtime initialization
* TK_COMBINE_SET for runtime use
* TK_DIFF_SET for runtime use
*
* One may assume that token sets are assignable.
*/
#define TK_MAKE(c,l) ((l) << ((c) * TK_LWIDTH))
#define TK_ADD_SET(t, t2) ((t) | (t2))
#define TK_SUB_SET(t, t2) ((t) & ~(t2))
#define TK_NULLSET (0)
#define TK_IS_IN_SET(t, t2) ((t) & (t2))
#define TK_INTERSECT_SET(t, t2) ((t) & (t2))
#define TK_COMBINE_SET(t1, t2) ((t1) |= (t2))
#define TK_DIFF_SET(t, t2) ((t) &= ~(t2))
#define TK_GET_CLASS(t, c) (((t) >> ((c) * TK_LWIDTH)) & 0x7)
#define TK_GET_LEVEL(t, c) (((t) >> ((c) * TK_LWIDTH)) & 0x7)
/*
* all tokens all levels - useful when calling tkc_returning and
* want simply to 'send them all back'
*/
#define TK_SET_ALL 0x3fffffff
/*
* token singleton set
*/
typedef __uint32_t tk_singleton_t;
#define TK_MAKE_SINGLETON(c,l) (l | ((c) << TK_LWIDTH) | 0x80000000)
/*
* various flag values
*/
#define TK_WAIT 1 /* tkc_returning */
/*
* disposition of tokens - used as the 'why' in (*tkc_return), (*tks_recall),
* tks_return(), tkc_recall().
* There are 3 reasons a token can be returned: CLIENT_INITIATED,
* SERVER_CONDITIONAL, and SERVER_MANDATORY.
* These must be constructed using the macros below.
* In general, tk_disp_t's are passed from the token module out to the
* various callouts and need to be passed to the server via an ipc/rpc.
* In a few cases, a disposition set needs to be constructed - in many
* of these cases, simply passing TK_DISP_CLIENT_ALL works well since
* the token module doesn't mind having extra disposition bits on.
*/
typedef __uint32_t tk_disp_t;
/*
* reasons for 'why' a token is being returned. These values should
* be used in the macros below to construct a tk_disp_t
*/
#define TK_SERVER_CONDITIONAL 0x1 /* server asking for token */
#define TK_SERVER_MANDATORY 0x2 /* server demanding token */
#define TK_CLIENT_INITIATED 0x4 /* client initiated
* return (via tkc_recall()),
* return (via tkc_returning()),
* return (via *(tkc_obtain))
* return (via tkc_obtaining())
*/
#define TK_MAKE_DISP(c,l) ((l) << ((c) * TK_LWIDTH))
#define TK_ADD_DISP(t, t2) ((t) | (t2))
#define TK_SUB_DISP(t, t2) ((t) & ~(t2))
#define TK_DISP_COND_ALL 01111111111
#define TK_DISP_MAND_ALL 02222222222
#define TK_DISP_CLIENT_ALL 04444444444
/*
* these macros tell whether a disposition set has any of a particular kind
*/
#define TK_DISP_ANY_CONDITIONAL(td) ((td) & TK_DISP_COND_ALL)
#define TK_DISP_ANY_MANDATORY(td) ((td) & TK_DISP_MAND_ALL)
#define TK_DISP_ANY_CLIENT(td) ((td) & TK_DISP_CLIENT_ALL)
/*
* Client object state - this data structure is present in each object
* It is totally opaque to the application and consists of 4 pointers
* plus 1 32 bit quantity per token in the set.
*/
typedef void *tkc_state_t;
/*
* Token Server state
*/
typedef void *tks_state_t;
/*
* Application interface state - contains information that is
* likely to be constant for many objects within the same application.
* It includes the callback routines, etc.
*/
typedef struct {
/*
* (*tkc_obtain) - called when the token client module needs a token
* set that it doesn't already have.
*
* The tokens obtained is inferred from
* taking the 'toobtain' set and subtracting the 'refused' set.
* It is the responsibility of the callout to set the return
* token sets ('refused') no matter what.
*/
void (*tkc_obtain)(
void *, /* client object pointer */
tk_set_t, /* tokens to be obtained */
tk_set_t, /* tokens to be returned */
tk_disp_t, /* disposition of tokens to be returned */
tk_set_t *); /* tokens refused */
/*
* (*tkc_return) - called when the token client module wants to return
* a token set
* The final argument gives the disposition of each of the
* tokens in the 2 sets. The sets don't overlap.
* For 2nd token set (don't know), the disposition will never be CLIENT
*
* The client object manager MUST call tkc_return on all tokens
* in the first set (to be returned)
*
* For tokens with the CLIENT disposition, tkc_returned() may only be
* called after a successful RPC to the server.
* For the other cases, tkc_returned may be called immediately after
* the one-way msg to the server is sent.
*
* Note that this callout may be called many times in response to
* a single tkc_recall() call.
*/
void (*tkc_return)(
tkc_state_t, /* client token data */
void *, /* client object pointer */
tk_set_t, /* tokens to be returned */
tk_set_t, /* tokens client doesn't know about */
tk_disp_t); /* disposition of tokens */
} tkc_ifstate_t;
/*
* Macro for declaring the appropriate sized client token state struct
*/
#if (_MIPS_SZPTR == 32)
#define TKC_DECL(name, n) tkc_state_t name[n + 4]
#elif (_MIPS_SZPTR == 64)
#define TKC_DECL(name, n) tkc_state_t name[(n+1)/2 + 4]
#else
BOMB!!
#endif
/*
* tkc_init - one time client side initialization
*/
extern void tkc_init(void);
/*
* tkc_create - create client side of a token managed object
*/
extern void tkc_create(
char *, /* name (up to TK_NAME_SZ-1 chars) */
tkc_state_t *, /* object state to set up */
void *, /* client object pointer */
tkc_ifstate_t *, /* interface state */
int, /* # of tokens in set */
tk_set_t, /* tokens to mark as already present */
tk_set_t, /* tokens to mark as held (subset of previous
* set) */
void *); /* tag for tracing */
extern void tkc_create_local(
char *, /* name (up to TK_NAME_SZ-1 chars) */
tkc_state_t *, /* object state to set up */
tks_state_t *, /* object server pointer */
int, /* # of tokens in set */
tk_set_t, /* tokens to mark as already present */
tk_set_t, /* tokens to mark as held (subset of previous
* set) */
void *); /* tag for tracing */
/*
* tkc_destroy - stop managing an object.
* It is assumed that NO tokens are owned/cached and NO requests for any
* more tokens can come in.
*/
extern void tkc_destroy(
tkc_state_t *); /* object to be destroyed */
/*
* tks_free - reset state and destroy object.
*/
extern void tkc_free(
tkc_state_t *); /* object to be freed */
/*
* tks_copy - copy state.
*/
extern void tkc_copy(
tkc_state_t *, /* source object */
tkc_state_t *); /* destination object */
/*
* tkc_destroy_local - stop managing a local object
* Any cached tokens are flushed back to the (local) server.
* It is assumed that NO tokens are owned and NO requests for any more tokens
* can come in
*/
extern void tkc_destroy_local(
tkc_state_t *); /* object to be destroyed */
/*
* tkc_acquire - get a token(s)
* tkc_acquire1 - acquire a single token - FAST path for cached/owned tokens
* The tokens are obtained from the server if they are not present
* on the client cell and held. While held, they cannot be forceably recalled.
*
* tkc_acquire1 returns 0 if token was acquired, !0 otherwise
*/
extern void tkc_acquire(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens requested */
tk_set_t *); /* tokens acquired */
extern int tkc_acquire1(
tkc_state_t *, /* object containing tokens */
tk_singleton_t); /* single token to acquire */
/*
* tkc_obtaining - guts of tkc_acquire - a set of tokens wanted is passed
* in and 4 sets are passed back. Tokens requested but not in any set
* may be assumed to have already been obtained. Since classes must be acquired
* in ascending order, the 'get-later' set will include those classes of the
* initial set which haven't yet been looked at.
*
* Once the tokens have been obtained/returned - tkc_obtained must be called
* to inform the client module that the tokens have been dealt with.
* The disposition argument to tkc_obtained should be the same as the
* disposition passed back in tkc_obtaining.
*/
extern void tkc_obtaining(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens requested */
tk_set_t *, /* tokens to obtain */
tk_set_t *, /* tokens to return */
tk_disp_t *, /* disposition of tokens to return */
tk_set_t *, /* tokens that were refused */
tk_set_t *); /* get later please! */
extern void tkc_obtained(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens which have been obtained */
tk_set_t, /* tokens server refused to give */
tk_disp_t); /* disposition of return tokens refused */
/*
* tkc_release - release a held token
*/
extern void tkc_release(
tkc_state_t *, /* object containing tokens */
tk_set_t); /* tokens to release */
extern void tkc_release1(
tkc_state_t *, /* object containing tokens */
tk_singleton_t);
/*
* tkc_hold - hold a token. No attempt is made to acquire the token if
* it is not on the client. The set of successfully held tokens is returned.
*/
extern tk_set_t tkc_hold(
tkc_state_t *, /* object containing tokens */
tk_set_t); /* tokens requested */
/*
* tkc_recall - respond to a server request to return a token.
*
* It can also be used by the client to optimize recall transactions - if
* the client knows that soon one will be acquiring a token that would likely
* require a recall - one can plan ahead and force the recall early.
*
* This call is basically asynchronous - if the token is in a state where
* it can't be sent back - it is marked for future handling. Thus
* it is perfectly legal to call tkc_recall on a token which the caller
* has currently held. When the caller finally calls tkc_release, the
* token will be sent back.
*/
extern void tkc_recall(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens to return */
tk_disp_t); /* client or server initiated?? */
/*
* tkc_returning - return a set of tokens by pushing them back to the server.
* If last parameter is TK_WAIT then any tokens that are held, in the
* process of being recalled will be waited for - otherwise
* tokens in these states are ignored. It's important not to have
* any of the tokens passed in the return set 'held' - if one passes
* TK_WAIT then one will deadlock.
* This can improve performance if the client knows that it won't be needing
* the token for a long time and its likely that someone else will
*
* This is also used to remove any client held tokens before destroying
* the object. For this call, the 'return' set may contain multiple
* levels per class and classes that the client doesn't currently have.
* This call is basically synchronous - all the results are known when the
* call returns.
* The set returned in the OUT parameter MUST be sent to tkc_returned().
* The 'why' parameter is of course always filled in with CLIENT_INITIATED
* but is useful when wishing to combine sets with other sets.
*/
extern void tkc_returning(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens to return */
tk_set_t *, /* OUT:tokens ok to return */
tk_disp_t *, /* OUT: disposition of ok tokens */
int); /* flags: wait for tokens in transit */
/*
* tkc_returned - return a set of tokens
* Used by the client to disposition a set of tokens. It must call this
* in 1 of 2 cases:
* 1) to return tokens required by a call to (*tkc_return)()
* In this case, it can call tkc_returned before or after sending
* the one-way message to the server which contains the tokens
* 2) to return tokens initiated via tkc_returning()
* In this case, tkc_returned must be called only after the server
* has acknowledged the return (via an RPC)
* NOTE: this routine updates client state only - it does NOT perform any
* callouts - to 'return' tokens, one must use tkc_recall or tkc_returning.
*/
extern void tkc_returned(
tkc_state_t *, /* object containing tokens */
tk_set_t, /* tokens to return */
tk_set_t); /* tokens refused to be returned */
/*
* tk_print_tk_set - print token set
*/
#ifndef _KERNEL
extern void tk_print_tk_set(tk_set_t, FILE *, char *, ...);
#else
extern void tk_print_tk_set(tk_set_t, char *, ...);
#endif
/*
* tkc_print - print info about client token object
*/
#ifndef _KERNEL
extern void tkc_print(tkc_state_t *, FILE *, char *, ...);
#else
extern void tkc_print(tkc_state_t *, char *, ...);
#endif
/*
* Token Server
*/
/*
* client handle - token system can handle any unique value
*/
typedef int tks_ch_t;
/*
* Application interface state - contains information that is
* likely to be constant for many objects within the same application.
* It includes the callback routines, etc.
*/
typedef struct {
/*
* tks_recall - called when the server wishes to have a token recalled.
* The disposition will be either SERVER_MANDATORY or SERVER_CONDITIONAL
* for each token.
*/
void (*tks_recall)(
void *, /* server object pointer */
tks_ch_t, /* client handle */
tk_set_t, /* tokens to be recalled */
tk_disp_t); /* disposition */
/*
* tks_recalled - called when a recall operation is complete
* Note that in the returned tk_set_t's that level doesn't matter
* just the class
*/
void (*tks_recalled)(
void *, /* server object pointer */
tk_set_t, /* tokens that were recalled */
tk_set_t); /* tokens that weren't recalled */
/*
* tks_idle - called when a class goes idle. This is only
* called if the class was tagged as wanting idle notification
* via tks_notify_idle
* Note: there is no locking during this call - object manager
* must provide some synchronization.
*/
void (*tks_idle)(
void *, /* server object pointer */
tk_set_t); /* set that went idle */
} tks_ifstate_t;
#if (_MIPS_SZPTR == 32)
#define TKS_DECL(name, n) tks_state_t name[n + 6]
#elif (_MIPS_SZPTR == 64)
#define TKS_DECL(name, n) tks_state_t name[(n+1)/2 + 5]
#else
BOMB!!
#endif
/*
* tks_init - one time server side initialization
*/
extern void tks_init(void);
/*
* tks_create - create server side of a token managed object
*/
extern void tks_create(
char *, /* name (up to TK_NAME_SZ-1 chars) */
tks_state_t *, /* object state to set up */
void *, /* server object pointer */
tks_ifstate_t *, /* interface state */
int, /* # of tokens in set */
void *); /* tag for tracing */
/*
* tks_destroy - stop managing an object.
* It is assumed that NO requests for any more tokens can come in.
*/
extern void tks_destroy(
tks_state_t *); /* object to be destroyed */
/*
* tks_free - reset state and destroy object.
*/
extern void tks_free(
tks_state_t *); /* object to be freed */
/*
* tks_obtain - obtain a set of tokens on behalf of a client.
* Does not return until all tokens are either granted, or the client
* already has them.
*
* Currently the refused set will always be 0.
*/
extern void tks_obtain(
tks_state_t *, /* object containing token */
tks_ch_t, /* handle for client making request */
tk_set_t, /* tokens wanted */
tk_set_t *, /* tokens granted */
tk_set_t *, /* tokens refused */
tk_set_t *); /* tokens already held by client */
/*
* tks_return - return a set of tokens
* The last argument encodes per token why each is being returned. The reason
* is either TK_SERVER_RECALL, TK_SERVER_REVOKE, or TK_CLIENT_INITIATED
* XXX currently the 'refused' set is not supported for applications.
*/
extern void tks_return(
tks_state_t *, /* object containing token */
tks_ch_t, /* client handle */
tk_set_t, /* tokens to be returned */
tk_set_t, /* tokens refused to be returned */
tk_set_t, /* tokens unknown to client */
tk_disp_t); /* disposition for each token */
/*
* tks_recall - retrieve tokens - all tokens for the specified class(es)
* are requested to be sent home upon last use.
* This will invoke (*tks_recall)() for each client that has the token
* granted AT THE TIME tks_recall() was called.
* The client MUST respond and call tks_return() with 3 sets of tokens:
* 1) set to be returned
* 2) set refused to be returned
* 3) set client didn't think it had
* The third set can result from message races
* Once all classes have been recalled - the (*tks_recalled)() function is
* called
*
* Note that only 1 tks_recall is permitted to be outstanding for a given
* tks_state_t. Also, the tk_set_t simply specifies which classes are to
* be recalled - the level doesn't matter.
*
* Sequence:
* tks_recall (app originated) ->
* (*tks_recall) (server callout function) ->
* RPC to client ->
* tkc_recall ->
* (*tkc_return) (client callout function) ->
* RPC back to server ->
* tks_return ...
* (*tks_recalled) when all RPCs complete
*/
extern void tks_recall(
tks_state_t *, /* object containing token */
tk_set_t, /* tokens to be recalled */
tk_set_t *); /* tokens refused, null for async callout */
/*
* tks_iterate - call specified function for each client cell that
* has the the specified token
* The callout is called once per client.
* Progress can we altered by various return codes from the callout.
* Returns last returned value from callout.
*/
typedef enum {
TKS_STOP, TKS_CONTINUE, TKS_RETRY
} tks_iter_t;
/* flag values */
#define TKS_STABLE 0x0001 /* caller asserts that token set it stable
* no in-progress obtains or recalls
* This is a debugging flag only
*/
extern tks_iter_t tks_iterate(
tks_state_t *, /* object containing token */
tk_set_t, /* tokens to search for */
int, /* flag */
tks_iter_t (*)(
void *, /* server object pointer */
tks_ch_t, /* client handle */
tk_set_t, /* tokens client owns */
va_list), /* args */
...); /* args */
/*
* tks_cleancell - For the passed in cell, clear any grants it has
* corresponding to the passed in tk_set_t.
* This routine handles 'returning' the token if it has an outstanding
* recall, thus the (*recalled) callout or (*obtain) could
* be called as the result of this call.
*
* The result is:
* If the token was the subject of a tks_recall,
* the resultant (*recalled)() callout will have
* the token(s) in the 'weren't recalled' list.
*
* If the token was waiting for a recall due to an obtain pending
* for a conflicting level, the obtain will be failed.
*
* If the token was simply granted to the client w/ no other activity
* the token is assumed returned safely.
*/
/* flag values */
#define TKS_CHECK 0x0001 /* don't do anything - just return token
* set client has
*/
extern void tks_cleancell(
tks_state_t *, /* object containing token */
tks_ch_t, /* client handle */
tk_set_t, /* tokens to cleanup */
tk_set_t *, /* tokens cleaned */
int); /* flags */
/*
* tks_notify_idle
* Mark a set of classes to be notified when they go idle (no grants).
* When a class goes idle the (*tks_idle)() callout will be called
*/
extern void tks_notify_idle(
tks_state_t *, /* object containing token */
tk_set_t); /* tokens to notify on idle */
/*
* tks_state
* Call out to the supplied function with the sets of tokens that
* are either held or being currently revoked/recalled.
*/
extern void tks_state(
tks_state_t *, /* object containing tokens */
tks_ch_t, /* client we are interested in */
void (*)(
void *, /* server object pointer */
tks_ch_t, /* client handle */
tk_set_t, /* unrecalled tokens client owns */
tk_set_t)); /* tokens being recalled or revoked */
#ifdef _KERNEL
/*
* tks_bag - return total state of the token service for
* the associated object. An object data is filles with data
* encapsulating the token state of all tokens and the current clients.
* The token state is marked as undergoing migration and further token
* activity is not expected.
* It is assumed that the object is in a quiesced state when this
* is called so that the state is frozen. This routine is used during
* token server migration.
*/
extern void tks_bag(
tks_state_t *, /* object to be migrated */
obj_bag_t); /* object bag to use for migrated data */
/*
* tks_unbag - re-establish token server state for an object from
* bagged data.
*/
extern int tks_unbag(
tks_state_t *, /* object to be migrated */
obj_bag_t); /* pointer to bag with migrated data */
/*
* tks_isclient - determine if a cell is a client of an object
*/
extern int tks_isclient(
tks_state_t *, /* object of interest */
tks_ch_t); /* cell */
#endif
/*
* tks_print - print info about a token object
*/
#ifndef _KERNEL
extern void tks_print(tks_state_t *, FILE *, char *, ...);
#else
extern void tks_print(tks_state_t *, char *, ...);
#endif
/*
* Common routines/data structures
*/
/*
* Metering info - dynamically allocated per token client or server if
* metering is requested
*/
#define TK_NAME_SZ 16
typedef struct tk_meter_s {
struct tk_meter_s *tm_link; /* forward meter link */
void *tm_h; /* pointer to token handle */
void *tm_tag; /* user-set tag for tracing */
char tm_name[TK_NAME_SZ]; /* name! */
char tm_which; /* client or server */
union {
struct tkc_class_data {
unsigned int tm_acquire; /* # acquire attempts
* via tkc_obtaining or via tkc_hold
*/
unsigned int tm_acq_cached;/* # of acquires where token
* was immediately avail
* either cached or already owned
*/
unsigned int tm_acq_conflict;/* # of acquires where token
* level conflicted with one
* cell already had
*/
unsigned int tm_acq_outbound;/* # of acquires where token
* is in process of being sent
* back due to recall, return
* conflicting level, etc.
*/
unsigned int tm_recall; /* # tkc_recall */
unsigned int tm_return; /* # tkc_returns */
} tm_cclass_data[TK_MAXTOKENS];
struct tks_class_data {
char *tm_trackcrecall; /* bitmap - track conditional recalls */
char *tm_trackmrecall; /* bitmap - track mandatory recalls */
unsigned int tm_obtain; /* # calls to tks_obtain */
unsigned int tm_return; /* # tks_returns */
unsigned int tm_revrace;/* # races where client says 'eh'
* and we think client still has token
* (SERVER_MANDATORY)
*/
unsigned int tm_mrecall;/* # of mandatory recalls */
unsigned int tm_revracecur; /* current number of revraces for
* this particular revoke
* Used to debug infinite loops
*/
unsigned int tm_recrace;/* # races where client says 'eh'
* and we think client still has token
* RECALL
*/
unsigned int tm_recracecur; /* current number of recraces for
* this particular recall
* Used to debug infinite loops
*/
} tm_sclass_data[TK_MAXTOKENS];
} tm_data;
} tk_meter_t;
#define TK_METER_CLIENT 1
#define TK_METER_SERVER 2
/* turn on metering for client */
extern tk_meter_t *tkc_meteron(
tkc_state_t *,
char *, /* name */
void *); /* tag */
/* retrieve meter struct */
extern tk_meter_t *tkc_meter(tkc_state_t *);
/* turn off metering */
extern void tkc_meteroff(tkc_state_t *);
/* turn on metering for server */
extern tk_meter_t *tks_meteron(
tks_state_t *,
char *, /* name */
void *); /* tag */
/* retrieve meter struct */
extern tk_meter_t *tks_meter(tks_state_t *);
/* turn off metering */
extern void tks_meteroff(tks_state_t *);
/*
* tk_printlog - dump log entries
* FILE * - where to dump
* int - dump last 'n' entries - (-1) for all
* int - how verbose (from selections below)
* char * - criteria (NULL to print everything)
*/
#define TK_LOG_TS 0x1 /* add time stamps and obj pointer */
#define TK_LOG_STATE 0x2 /* print state of all tokens after each op */
#define TK_LOG_ALL 0xf /* print everything */
#ifndef _KERNEL
extern void tk_printlog(FILE *, int, int, char *);
#else
extern void tk_printlog(int, int, char *);
#endif
/*
* tuneables
*/
/* if set to 1 then tracing will print as it gets entries */
extern int __tk_tracenow;
/* tracing buffer size */
extern unsigned int __tk_tracemax;
/* default metering */
extern int __tk_defaultmeter;
/* # of metering hash bucket */
extern unsigned int __tk_meterhash;
#endif