On Tue, 2005-12-13 at 22:38 -0800, Linus Torvalds wrote: > > Now it's not idle any more. The "select()" will have exited, but X now has > an agenda: it needs to inform all the clients that the mouse has moved. > That basically ends up looping over the internal X client list, and for > each client that shows interest (which tends to be most of them ;), X > does: > > - a couple of malloc() calls to create the packet to be written for that > client > - a writev() call that actually sends the packet out to the client.
Not quite. X filters motion events fairly agressively, it will only send the motion to the window containing the pointer, and only then if the application asks for it. In the old days, most apps didn't ask for motion when the button wasn't pressed, I suspect most do these days. But, that's still only one application, and most motion events probably don't result in any new requests. The X server, being a child of the 80s, avoids malloc like the plague, so when sending events, it carefully re-uses existing buffers, sending a stream of motion events to a single application shouldn't cause any memory allocation to occur within the X server. However, when you cross window boundaries, things change a lot. In this case, the window manager wants to repaint the window boarders, and a lot more clients receive events -- the old and new windows receive a stream of window crossing events. All of those clients get scheduled, and as they're otherwise completely idle, they'll get pretty high priority. The toolkits in each application and the window manager spend some time dealing with these events, and all conflict with the X server for the CPU. > Quite frankly, the simplest solution by far would be that X used a real > thread for mouse handling (and possibly other things, but mouse screen > updates really do tend to be special. I don't think X uses signals for > anything else than mouse updates and timers, for example). Yes, this would be easy to do, except that linking in pthreads causes all sorts of other things to change (like most of glibc) and might cause some significant performance regressions. Avoiding pthreads might well be advisable here. > That's really what it is all about. It uses SIGIO to approximate having a > real thread, but we all know that there's "real threading" and then > there's "fake threads". Yeah, sorry about that -- SunOS didn't have threads when I first hacked up the SIGIO solution. It shouldn't be hard to try this though. The SIGIO solution does have the advantage that the sprite handling code is atomic wrt the rest of the X server -- it 'knows' it will never be preempted by other accesses to the graphics hardware. Sometimes this matters a lot; as in the case where you must indirectly address device registers. The sprite code can preserve the address register across its own execution and ensure that all of the rest of the driver will remain blissfully unaware of its actions. This used to matter a whole lot; I would hope that most hardware exposes raw registers for the sprite position these days. Doing full-on device locking for the whole driver would take a bunch of work, and remain prone to mistakes. I should try this on a kdrive server and see how well it does. > Now, I know there's been at least experimental multi-threaded X servers > around for something like two decades by now. I do not believe that it has > ever been production quality, though (I think it was at some point planned > to be a standard feature of X11r6, that certainly did _not_ happen). The multi-threaded X server turned out to never be a win; it tried to execute multiple client requests in parallel, but (as we know now from extensive profiling), the X server sits waiting for the graphics hardware most of the time, and that is purely single threaded. So, you end up with a bunch of threads blocked waiting for the graphics accelerator. Given the difficulty of multi-threaded programming, and the total lack of any measureable performance improvement, we bailed on that design. It was fun on a multi-processor software-rendered machine though. > Of course, it's actually much more likely that it just makes X very very > flaky. For example, if X uses siglongjmp() or something like that in a > signal handler (which it may well do), taking a signal in the "idle > thread" and then longjumping into smewhere else would do some seriously > horribly bad things. oh, ick. No, the X server doesn't longjmp during a signal handler. In fact, the only setjmp/longjmp code is deep inside FreeType error handling stuff. -keith
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Desktop_architects mailing list [email protected] https://lists.osdl.org/mailman/listinfo/desktop_architects
