Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/kernel.h
Show First 20 Lines • Show All 220 Lines • ▼ Show 20 Lines | |||||
struct sysinit { | struct sysinit { | ||||
enum sysinit_sub_id subsystem; /* subsystem identifier*/ | enum sysinit_sub_id subsystem; /* subsystem identifier*/ | ||||
enum sysinit_elem_order order; /* init order within subsystem*/ | enum sysinit_elem_order order; /* init order within subsystem*/ | ||||
sysinit_cfunc_t func; /* function */ | sysinit_cfunc_t func; /* function */ | ||||
const void *udata; /* multiplexer/argument */ | const void *udata; /* multiplexer/argument */ | ||||
}; | }; | ||||
/* | /* | ||||
* Default: no special processing | * All macros prefixed by double underscore are internal to the | ||||
* | * sysinit implementation and should not be used outside the scope of | ||||
* The C_ version of SYSINIT is for data pointers to const | * the implementation and may be subject to change! | ||||
* data ( and functions taking data pointers to const data ). | |||||
* At the moment it is no different from SYSINIT and thus | |||||
* still results in warnings. | |||||
* | |||||
* The casts are necessary to have the compiler produce the | |||||
* correct warnings when -Wcast-qual is used. | |||||
* | |||||
*/ | */ | ||||
#ifdef TSLOG | |||||
struct sysinit_tslog { | |||||
sysinit_cfunc_t func; | |||||
const void * data; | |||||
const char * name; | |||||
}; | |||||
static inline void | |||||
sysinit_tslog_shim(const void * data) | |||||
{ | |||||
const struct sysinit_tslog * x = data; | |||||
TSRAW(curthread, TS_ENTER, "SYSINIT", x->name); | #ifdef TSLOG | ||||
(x->func)(x->data); | #define __SI_FUNCTION_PRE(type, name) \ | ||||
TSRAW(curthread, TS_EXIT, "SYSINIT", x->name); | TSRAW(curthread, TS_ENTER, #type, #name) | ||||
} | #define __SI_FUNCTION_POST(type, name) \ | ||||
#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ | TSRAW(curthread, TS_EXIT, #type, #name) | ||||
static struct sysinit_tslog uniquifier ## _sys_init_tslog = { \ | |||||
func, \ | |||||
(ident), \ | |||||
#uniquifier \ | |||||
}; \ | |||||
static struct sysinit uniquifier ## _sys_init = { \ | |||||
subsystem, \ | |||||
order, \ | |||||
sysinit_tslog_shim, \ | |||||
&uniquifier ## _sys_init_tslog \ | |||||
}; \ | |||||
DATA_WSET(sysinit_set,uniquifier ## _sys_init) | |||||
#else | #else | ||||
#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ | #define __SI_FUNCTION_PRE(type, name) \ | ||||
static struct sysinit uniquifier ## _sys_init = { \ | do { } while (0) | ||||
subsystem, \ | #define __SI_FUNCTION_POST(type, name) \ | ||||
order, \ | do { } while (0) | ||||
func, \ | |||||
(ident) \ | |||||
}; \ | |||||
DATA_WSET(sysinit_set,uniquifier ## _sys_init) | |||||
#endif | #endif | ||||
#define SYSINIT(uniquifier, subsystem, order, func, ident) \ | |||||
C_SYSINIT(uniquifier, subsystem, order, \ | |||||
(sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)(ident)) | |||||
/* | /* | ||||
* Called on module unload: no special processing | * Explanation of arguments for the __SI_REGISTER() macro: | ||||
* | |||||
* @param uniq An identifier for the needed functions and structures. | |||||
* @param type sysinit_set or sysuninit_set, depending on use case. | |||||
* @param _sub SI_SUB_XXX enum. | |||||
* @param _order SI_ORDER_XXX enum. | |||||
* @param _func Pointer to callback function. | |||||
* @param ... Arguments for callback function, if any. | |||||
* | |||||
* This macro create two functions. The first function calls the given | |||||
* function and passes the given argument, also called shim function. | |||||
* The second function is the actual constructor function. This way | |||||
* pointer casting between types is avoided entirely. | |||||
*/ | */ | ||||
#define C_SYSUNINIT(uniquifier, subsystem, order, func, ident) \ | #define __SI_REGISTER(uniq, type, _sub, _order, _func, ...) \ | ||||
static struct sysinit uniquifier ## _sys_uninit = { \ | static void \ | ||||
subsystem, \ | type##_##uniq##_shim(const void *arg __unused) \ | ||||
order, \ | { \ | ||||
func, \ | __SI_FUNCTION_PRE(type, _func); \ | ||||
(ident) \ | (_func)(__VA_ARGS__); \ | ||||
__SI_FUNCTION_POST(type, _func); \ | |||||
} \ | |||||
static struct sysinit type##_##uniq = { \ | |||||
.subsystem = _sub, \ | |||||
.order = _order, \ | |||||
.func = &type##_##uniq##_shim, \ | |||||
.udata = NULL, \ | |||||
}; \ | }; \ | ||||
DATA_WSET(sysuninit_set,uniquifier ## _sys_uninit) | DATA_WSET(type, type##_##uniq); \ | ||||
struct __hack | |||||
#define SYSUNINIT(uniquifier, subsystem, order, func, ident) \ | /* | ||||
C_SYSUNINIT(uniquifier, subsystem, order, \ | * Sysinit API macro, called on kernel or module load: | ||||
(sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)(ident)) | */ | ||||
#define SYSINIT(uniq, sub, order, ...) \ | |||||
__SI_REGISTER(uniq, sysinit_set, sub, order, __VA_ARGS__) | |||||
/* | |||||
* Sysuninit API macros, called on kernel shutdown or module unload: | |||||
*/ | |||||
#define SYSUNINIT(uniq, sub, order, ...) \ | |||||
__SI_REGISTER(uniq, sysuinit_set, sub, order, __VA_ARGS__) | |||||
void sysinit_add(struct sysinit **set, struct sysinit **set_end); | void sysinit_add(struct sysinit **set, struct sysinit **set_end); | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
/* | /* | ||||
* Infrastructure for tunable 'constants'. Value may be specified at compile | * Infrastructure for tunable 'constants'. Value may be specified at compile | ||||
* time or kernel load time. Rules relating tunables together can be placed | * time or kernel load time. Rules relating tunables together can be placed | ||||
▲ Show 20 Lines • Show All 179 Lines • Show Last 20 Lines |