Manuel Tobias Schiller wrote: > Well, blocking all other threads is a bad thing in itself, because I > tend to lose button events when I can't poll them in time (remeber, > button polling is done with ioctls, it's got nothing to do with the > poll() syscall; poll() will only tell when a write to the device is > possible without blocking). Besides, blocking all threads inside > usleep() or inside poll() or select() is all the same to the > application (it won't wake up in these 50 ms to poll the buttons when > it's time to do so) and therefore the realisation of making the process > block is not really that important, because streaming the mpeg data is > not critical when it comes to timing (the kernel level driver has 16 kb > buffers, for a 128 kbit stream, a full buffer lasts for a whole > second), but button polling (which has to be done via ioctls) is timing > critical, because this is what determines the responsiveness of the > application. One should probably poll the button status 25 to 50 times > per second; this won't take much time however, because the operation is > reasonably fast, so the button polling thread can remain blocked most > of the time.
Out of curiosity, I've tested how much CPU the following program uses and how bad latency gets. The CPU is virtually idle and the latency stays below 30 ms most of the time even when playing three videos to utilize the CPU completely at the same time. Your button polling thread wouldn't do anything else than this except using some light-weight ioctl() calls instead of gettimeofday(), right? So I don't think the button polling has to waste a lot CPU time. #include <sys/types.h> #include <sys/time.h> #include <poll.h> #include <stdio.h> int main(void) { static struct timeval tv0; static unsigned long max_d; gettimeofday(&tv0, NULL); for (;;) { static struct timeval tv; unsigned long d; poll(NULL, 0, 10 /* ms */); gettimeofday(&tv, NULL); d = (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; tv0 = tv; if (d > max_d) { max_d = d; printf("max. %lu ms\n", max_d); } } return 0; } My suggestion would be to use such a helper process to poll for button events and pass the collected events over a socket created with socketpair(). Even if you use it for testing only, it might be useful to sort out the timing issues. In your main process you can then poll() for the button events without busy-loop alike polling. Of course, without real-time scheduling there's no guarantee that all button events are registered. If the CPU is rather slow or heavily loaded, the 50 ms latency might not be achievable constantly. As far as I understood, the problem is that these events cause no interrupt and are also edge-triggered, meaning they're lost if you don't catch them in time. I agree that handling the button events inside the kernel is probably the best option. -- Christian
pgpFUHpuFqQqs.pgp
Description: PGP signature