On Thu, Nov 05, 2020 at 04:09:13AM +0100, Kent Gibson wrote: > Wrt "fast as possible", what are you optimising for - minimal latency or > maximal throughput? For minimal latency you want to read just the next > event. For maximal throughput you want to minimise the number of > ioctls/syscalls and so dump the kernel event fifo into a userspace > buffer. I believe that the target actually is both as you suggest later. > The library should allow the user to select what they are optimising > for, so you may want to consider two event_read() flavours, one that gets > just the next event and another that fills a buffer. The single form may > just call the buffer form with n=1, or it may be able to be slightly > optimised as it could avoid buffer range checks. > Both should accept the line request fd, rather than the line or line bulk > that they currently do. > And in both cases the user should provide the space for the event(s) to > be written to. The C-API does allow this in the released version. It provides gpiod_line_event_read with a user-supplied buffer for single-event reads and it provides gpiod_line_event_read_multiple with a user-supplied array for minimizing the syscall count. Bindings such as C++ also expose these (even though the C++ one performs the allocation). Of course keeping these properties would be good for the reasons you detailed. > > For config: I believe an opaque request config structure will require > > a lot of getter/setter boiler plate code for not much profit. > > > > The profit being a guarantee of ABI stability and backward compatibility, > while still being free to completely rework the implementation > internally? I think you can gain this profit without opaqueness. A user can only use those aspects of a config that did exist a the time the code is developed. For that reason, there can be multiple versions of a configuration type and the consumer can use whatever type they happend to see when the code was compiled. The current configuration type can be typedefd to a standard name and only needs to be API compatible with previous config types (i.e. only add new fields with default initializers). In C++, one can leverage function overloads to implement that. In C, you can use symbol versioning or do poor-mans-symbol- versioning by #defineing the consuming function names to versioned ones. The only downside of this seems to be that libgpiod would have to keep the old types and overloads for all eternity. When doing this, it is important that consumers do not pass around pointers to a config to code compiled with a different libgpiod as these types may be different and have a different storage layout. For the config, this seems fairly unlikely. Helmut