tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Some changes to autoconfiguration APIs



> I have reworked it on the thorpej-cfargs2 branch.  It addresses the concerns$ 

> Old example:

>                 c->c_dev = config_found(sc->sc_dev, &pa, pciprint,
>                     CFARG_SUBMATCH, config_stdsubmatch,
>                     CFARG_LOCATORS, locs,
>                     CFARG_DEVHANDLE, devhandle,
>                     CFARG_EOL);

> New example:

>                 c->c_dev = config_found(sc->sc_dev, &pa, pciprint,
>                     CFARGS(.submatch = config_stdsubmatch,
>                            .locators = locs,
>                            .devhandle = devhandle));

May or may not be useful here, but when I've wanted to do something
like that and have had concernes about type safety, I've done things
like (to map to this problem space)

	c->c_dev = config_found(sc->sc_dev, &pa, pciprint,
		CFARG_SUBMATCH(config_stdsubmatch),
		CFARG_LOCATORS(locs),
		CFARG_DEVHANDLE(devhandle),
		CFARG_EOL);

via macros like

#define CFARG__SUBMATCH 0x70001
#define CFARG_SUBMATCH(x) CFARG__SUBMATCH, cfarg_check_submatch((x))
extern int (*cfarg_check_submatch(int (*)(device_t, whatever)))(device_t, whatever);
#define CFARG__LOCATORS 0x70002
#define CFARG_LOCATORS(x) CFARG__LOCATORS, cfarg_check_locators((x))
extern whatever *cfarg_check_locators(whatever *);

Then cfarg_check_* simply return their arguments directly:

int (*cfarg_check_submatch(int (*fn)(device_t, whatever)))(device_t, whatever)
{
	return(fn);
}

whatever *cfarg_check_locators(whatever *arg)
{
	return(arg);
}

(I usually pick sequential values some distance from zero for what here
are CFARG__*, to reduce the risk of hitting a valid value
accidentally.)

If the argument-checking functions prove to be a performance problem,
make them extern inline, I think it is, though that's
compiler-specific.  I think I've even seen
__attribute__((__force_inline__)) or some such.

After all, the best way to check that something is suitable to pass as
an argument of a specific type to a function is to pass it as one!
Completely avoids struct versioning headaches, too.

Skip the inlines and this technique is portable to even old C variants,
as long as they support some form of varargs/stdarg.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse%rodents-montreal.org@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Home | Main Index | Thread Index | Old Index