[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On Wed, May 09, 2001 at 07:45:05PM +0200, a.mottola@xxxxxxxxxx wrote:
> ...and I can restart working on QNX Allegro - having the new faster PC made me to discover why the keyboard was not working anymore with expal; it could be a matter of thread priorities...
> expal consumes a lot of CPU cycles doing PgFlush() calls (on QNX this flushes the draw buffer), so the events handling threads is postponed in the scheduled threads. You know, with pthreads execution time is always given to the thread with the highest priority, and as in expal the main thread is a lot busy, the other one which handles the keyboard among other things, is almost never executed... The result is that with my old K6-200 the keyboard was not responding anymore, even after some minutes, while with the K7-850 expal exits when a key is pressed, but with a delay of about 1 second since the keypress.
I saw similar things with thread-based event polling in Unix X
driver. The problems totally went away, though, when I did the
non-obvious thing -- I made the polling thread be less
CPU-intensive. :) Try putting a `usleep(10000)' at the start of
your event fetching loop (don't put it at the end, or your
`continue' will bypass it). Or ever just `usleep(10)', as I
tried first (I got the units wrong). Both sorted it out in X.
A better way is to use `poll' or `select', but that won't work
for your QNX events. It'll work nicely for Linux keyboard and
mouse input, when I get around to implementing that.
The reason this works, AFAIK, is that the scheduler has a hard
time deciding how important a thread in when that thread is
constantly busy. Maybe it's important; maybe it's not. But if
the thread occasionally sleeps for a bit, the scheduler knows
that it's not busy at that stage, and consequently that when
it's *not* sleeping, it can be assumed to be more busy than a
thread which never sleeps at all.
This is especially true of threads which poll() or select() --
these threads don't need to do anything until the event happens,
and when it does happen, they want to respond immediately. You
can't poll() or select() for what you're doing, but performing a
usleep(10000) is sort of like saying, "I've got nothing to do at
the moment, but I will have something urgent to do in 10ms".
I don't know how much of this can be corroborated from kernel
sources (I haven't even looked) but the effects of adding the
sleep calls seem to confirm that this is the case.
> Now, how to solve this? A solution would be to give CPU time away somewhere in the main thread, but that can be done only if the programmer puts a sched_yield() call inside his loop; another solution could be to assign a priority to the threads at startup, but I don΄t know if something like this is possible in pthreads, nor how to do it...
In Linux, you need root privileges, and you must select a
different scheduling algorithm to SCHED_OTHER (the default),
which is only valid at priority 0. But, the other algorithms
both totally preempt any lower-priority processes, which is
nearly all processes on your system! By this, I mean that if
you have chosen a higher priority, and never block or yield, all
your daemons and other system programs (shells on other
consoles, etc) will stop completely. See `man sched_setparam'.
George
--
Random project update:
22/06/2000: AllegroGL documentation: http://allegrogl.sourceforge.net/
See under `Documentation' for the AllegroGL Reference Manual in
various formats.