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

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Desktop_architects mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/desktop_architects

Reply via email to