RFC: Adding a hw.features[2] sysctl

Nathan Lay nslay at comcast.net
Sun Jan 13 20:23:02 PST 2008


Igor Mozolevsky wrote:
> On 14/01/2008, Nathan Lay <nslay at comcast.net> wrote:
>   
>> Igor Mozolevsky wrote:
>>     
>>> On 13/01/2008, Peter Jeremy <peterjeremy at optushome.com.au> wrote:
>>>
>>>
>>>       
>>>> IMHO, no.  Virtually all similar FreeBSD information is exported via
>>>> sysctl and this sort of information fits neatly into the existing
>>>> MIB tree as either dev.cpu.N.features or hw.cpu.features
>>>>
>>>>         
>>> /dev/sndstat?
>>>
>>> If it's in /dev you can do neat tricks like ioctl-ing queries (like
>>> ioctl(/dev/cpuinfo, CINFOCTL_HAS_FEATURES, CINFO_SSE3|CINFO_SSSE3))
>>> instead of having *every* app parse the result of a sysctl; most of
>>> the time you'd only want to check for specific feature , it's much
>>> easier to do an ioctl that returns a boolean.
>>>       
>> Or perhaps, create an ioctl that returns a bitmask of all available CPU
>> features.  This way, only one ioctl() call is necessary and allows
>> programs to query any and all features in an inexpensive way.  Calling
>> ioctl() for each feature query is comparably more expensive.
>>     
>
> You won't you'd OR all of the features you want to check; but yes,
> having a param that returns the whole lot would also be great, as well
> as the driver returning human-readable representation if it was open
> for writing... The idea is to allow the flexibility, so that the
> programmers/users are free to choose what suits them, and not being
> forced into having to do only one thing. :-)
>
>
> Igor
>
>   
Yes, but suppose a program needs to make these queries more than 
once...for whatever reason?  For example, a closed source math code 
might need to figure out which version of a function to execute at run 
time based on available CPU features.  It will likely have to issue 
these ioctl() calls more than once (even with OR). 

For example:

if ( ioctl( fd, CINFOCTL_HAS_FEATURES, <OR'd features> ) ) 
LU_factor_<features>( ... );
else if ( ioctl( fd, CINFOCTL_HAS_FEATURES, <other OR'd features> ) ) 
LU_factor_<other features>( ... );
etc...

If the ioctl returns a bitmask with all available CPU features, then 
only one ioctl() call is needed.  The features can easily be queried 
from the bitmask.  One can make it even easier and more readable by 
making a macro like FD_ISSET to do such queries.

A rough example:

cpu_features_t mask;

fd = open( "/dev/cpuinfo", O_RDONLY );
ioctl( fd, SIOCGCPUFEATURES, (caddr_t)&mask );
close( fd );

if ( CPU_HAS_FEATURES(mask, CPU_SSE|CPU_SSE2) ) { ... }
...
if ( CPU_HAS_FEATURES(mask, ... ) ) ...

Or something like that

The bitmask solution also makes it reasonably easy to generate a human 
readable string.  Just go through each bit.  No ioctl needed for that 
either.  A simple program can be written to analyze the bitmask and 
output human readable version of the features.

Best Regards,
Nathan Lay



More information about the freebsd-current mailing list