Hi all, Here's an updated rough proto-spec for the userspace side of the continuous-parameter polling interface, intended for hwmon, batteries and their ilk, and maybe even the input infrastructure. Compared to the parent post, this version adds a second parameter to the ioctl (see discussion elsewhere in this thread), and corrects a few inaccuracies. With an event-based data source, this interface allows polling with no time interrupts on tickless kernels. With a polling-based data source and a bit of luck, the frequency of polling = frequency of induced timer interrupts will be the minimum that satisfies the greediest client (even if there are many). In general, complicated data sources can be handled optimally by custom driver+infrastructure code. All of this is completely transparent to userspace, which just states its needs and has its every desire fulfilled. Hardware readouts are obtained from a dedicated file - a sysfs attribute (as in hwmon and tp_smapi) or a device file (as in the input infrastructure). The file has the following properties: 1. A new ioctl DELAYED_UPDATE, with parameters min_wait and min_fresh, meaning: "I want an a fresh readout. If I poll() this FD with POLLIN then send an input-ready event at time is T+min_wait, or when you have a readout that was received from the hardware at time T+min_fresh, whichever is *later*. Likewise if I select()". Here T is the time of the ioctl call and min_wait>=min_fresh. 2. When the file is opened in O_NONBLOCKing mode, read() always return the latest cached readout rather than querying the hardware (unless the latter has negligible cost). 3. When the file is opened in normal (blocking) mode, read() blocks until a fresh readout is available and returns this readout; see below. To illustrate, here's an example of a proper polling loop (sans error checking). This app wants to refresh its display when the data has changed, but not more often than once per second. It wants the readouts to be reasonly spaced: they should be obtained at least 700ms apart. And it needs to update its GUI every 3 seconds regardless of readouts. In some linux/foo.h: -------------------------- struct delayed_update_req { int min_wait; int min_fresh; }; -------------------------- Application code: -------------------------- /* Open attribute file with O_NONBLOCK so that all reads will * return cached values instead of blocking: */ int fd = open("/whatever/voltage", O_NONBLOCK|O_RDONLY); /* Read and process latest cached attribute value: */ read(fd, ...); ... while (1) { const struct delayed_update_req dureq = { .min_wait=1000, min_fresh=700 }; struct pollfd ufds = { .fd=fd, events=POLLIN }; /* Tell the driver we want a fresh readout, but no sooner than * 1sec from now, and we want the readout to reflect reality no * sooner than 700ms now: */ ioctl(fd, DELAYED_UPDATE, &dureq); /* Wait for an update for at most 3 seconds. Nominally this will * block for at least 1 second, because of the above ioct. If we * were reading multiple attributes, we could poll them all * simultaneously. */ poll(&ufds, 1, 3000); /* Read latest cached attribute value: */ read(fd, ...); ... handle readout, update GUI ... } -------------------------- Legacy and lightweight applications (e.g., cat from shell) will open the file in blocking mode. In this case, a "read(fd, ...)" has semantics equivalent to the following O_NONBLOCK-mode code: -------------------------- const struct delayed_update_req dureq = { .min_wait=0, min_fresh=0 }; /* Tell driver we want an immediate update: */ ioctl(fd, DELAYED_UPDATE, &dureq); /* Wait indefinitely for an update: */ poll(&ufds, 1, -1); /* Read the latest cached attribute value: */ read(fd, ...); -------------------------- Similarly, select() and poll() on non-blocking files acts like you did "ioctl(fd, DELAYED_UPDATE, &dureq)" with dureq={0,0} and then waited for a refresh or timeout. If we want to penalize code which doesn't use nonblocking mode and delayed updates, we can increase the implicit dureq.min_wait above from 0 to a sufficiently nasty (driver-dependent?) delay. Comments? (I still can't implement this myself. Just trying to elucidate my suggestion.) Shem - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html