I know I said this before, but take a look at XInitThreads(). If you
do not call XInitThreads() then you can not make Xlib calls from
multiple threads. It doesn’t matter if you wrap Xlib calls with your
own locks. You must call XInitThreads.
Before this discussion goes any further I think everyone needs to
examine their assumptions. The assumption that the current design of
SDL and Xlib are bugs are the ones I would examine first.
Bob Pendleton
Well, you’re wrong. X11 (the protocol) is not thread-safe,
X Window System Protocol Version 11 is a protocol not code. It can not
be either thread safe or thread unsafe.
I meant that the ordering of the messages is important, you can’t
hussle the messages of two different threads and send them to the
X server.
There is in fact a very nice
library designed to use the X Window System Protocol Version 11 in an
asynchronous way from multiple threads.
Oh, BTW, you seem to be a bit hung up on names so I’m trying to use
the correct names everywhere not matter how much extra typing that
requires.
and libx11
is not thread-safe (reentrant) period.
That is correct. I did not say that it was. I said that if you want to
use it from multiple threads you have to tell it that you are going to
do that by calling XInitThreads. I made the sad assumption that if you
were aware of XInitThreads you would also know about XLockDisplay()
and XUnlockDisplay() and know that they are the correct way to look
access to the library. I also assumed that if you were not aware of
the standard method for using Xlib from multiple threads you would
look it up. Clearly I was wrong.
I never coded for X directly in my life before, so it was not unlikely
that I made some errors
Thanks for pointing this out. I looked up the webpages again that I read
from which I had gotten the idea that there were two different
libs, and there aren’t, I read it wrong. Thus, you’re right that
my current implementation (even though it works in my case)
isn’t the correct one and I’ll replace my own mutex with calls to
XLockDisplay() / XUnlockDisplay(), and add the initialization call.
[…snip…]
Anyway, it seems that Donny Viszneki does understand what I’m trying
to say. Maybe he can explain it more clearly then me.
Yeah, maybe he can. Clearly I don’t know what I’m talking about. It is
blink. I never said that. I just think we have some communication
problem because the essention of my post is still true and the story
of XInitTheads / XLockDisplay / XUnlockDisplay doesn’t change that.
Since Donny clearly understood what I meant I thought he might be
able to help here.
funny, when I went to look up XInitThreads I grabbed my first edition
"The X Window System in a Nutshell" and it wasn’t in there, I had to
grab my more recent edition of the O’Reilly "Xlib Programming Manual"
to find it. There was no support for multithreading in Xlib when the
first edition was published. I really only keep the first editions as
souvenirs. They are pretty badly out of date. Back then I was on the X
consortium board, Tim sent first editions of all his X books to
everyone on the board. I ported X to a bunch of different computers. I
did the first 24 and 32 bit versions of the server and the first
server to support 1024x786 and larger resolutions. I designed and
implemented the first overlay extension for X. It did not make it into
the standard. I also implemented the first extension for changing the
virtual window. It required an extension because we changed the pixel
depth as well as the virtual screen. Lets see, I’m pretty sure I did
the first X server to support stereo (quad buffered 32 bit). Yeah,
that was a long time ago. Clearly I don’t know shit about X. Thanks
for pointing that out to me.
Sorry to take so long to get back to you. I was asked at the last
minute to teach a class that required me to have a Windows development
environment. Reinstalling windows from the restore disks should not
have taken much more that a day… But, the restore disks didn’t have
the drivers. After I got the drivers the first reinstall was undone by
my leaving an unprotected Windows machine on the Internet. Ok, so I
figured out the misconfiguration of my router/firewall… Then the
hard drive made this interesting noise. After getting a new drive the
video card started showing green random green dots. New video card…
New power supply to support the card. And, I still had to do all the
prep for the class.
I was a founding member of the First Church of Murphy…
Now, back to the problem at hand. I believe there is more here than
either of us thought there was.
Libsdl does not allow a user to use Xlib from multiple threads,
because it doesn’t call XLockDisplay() / XUnlockDisplay().
That is correct, it doesn’t. This hasn’t been a problem in the past,
but it is one now. It will become even more of a problem in the
future. The more cores, the more the desire to use them.
If used properly a multithreaded X program can have multiple entities
all updating the screen at the same time. This is something that you
can not do on many other OSes. OTOH, you do pretty much have to have a
single thread reading events coming back from the X server. But, once
they are received they can be distributed to any entities that are
interested in them.
However, it DOES call SDL_Lock_EventThread / SDL_Unlock_EventThread.
So, in order to allow users to use it in a multi-threaded application
you might consider revealing a bit more of this locking to the user
by allowing him to specify two function pointers that will be
called; or even just call XLockDisplay() / XUnlockDisplay() yourself
at all times if they are X11 users… The argument that most people
don’t need it might not be that relevant if the each call only locks
a mutex; that should be totally neglectable.
This is a deeper problem than that. Wrapping the SDL event functions
in a mutex is pretty straight forward and does yield significant
performance improvements. It is well worth doing. (Take a look at
http://gameprogrammer.com/fastevents/fastevents1.html where I did just
that back in '02.) There are very good reasons why this is not a
standard part of SDL 1.2. Not so sure about 1.3.
Otherwise just add this to SDL_Lock_EventThread:
?if (sdl_thread_safe)
? ?XLockDisplay();
(the complement) and allow the user to toggle the global boolean
’sdl_thread_safe’ (checking that boolean probably blends in with
the rest of the assembly instructions and will be executed in
parallel with existing code, and therefore cost 0 cpu cycles
if sdl_thread_safe is false; otherwise it will cost 1 cpu cycle…)
My original request was to add this especially for the case
where SDL_EventThread == NULL. If you want to support thread-safety
also when SDL_EventThread != NULL, you’d have to call
XLockDisplay() / XUnlockDisplay() a lot more often (namely in
the event thread, everywhere where currently SDL_EventLock is
locked). Is this really such a performance hit? Somehow I have
the feeling that sending a message over a socket completely
overshadows the locking of a mutex, not to mention that if
XInitThreads() isn’t called, XLockDisplay probably does the
same as SDL_Lock_EventThread (nothing).
There are two reasons why SDL_EventThread will ever be NULL. The
programmer can say he does not want to use a separate event thread, or
the OS may not support reading events in a separate thread. IIRC
Windows was the main OS that doesn’t support reading events in a
separate thread. It is kind of important that SDL supports Windows.
Multithreaded access to graphics is a different problem. Each X
protocol message contains all the information needed to identify its
context. That means that so long as you set up Xlib to be thread safe
you can send commands from as many different threads as you like. That
is not true for OpenGL. Unless you are talking to a machine other than
the one running the application OpenGL calls do not create X protocol
messages and they do not identify their context. OpenGL is modal and
each thread must create, maintain, and select its own contexts.
To me it seems that we have more than two distinct problems. The
problem of making multithreaded access to Xlib work well with the SDL
event system is not one of the problems. Let me describe the problems
as I see them
SDL is a cross platform library designed to support portable
applications. SDL APIs must work the same way on many different
operating systems and graphics systems. That means that we can not
ever look at a problem on just one system. We have to make sure that
what we do can be made to work on other platforms.
How do we make the SDL event system work nicely with multiple threads
even when there is no separate event thread. I believe Sam has solved
this in 1.3, but I’m not sure. We must be sure that we can have
multiple threads sending events through the event system even if you
do not have, can not have, an event thread. No matter what, you really
can’t have more than one thread reading events. It just doesn’t work.
How do you support multithreaded access to the graphics system even on
systems where the OS or the API do not support that way of using the
graphics system? Well, really, you can’t. At least not without adding
a new layer to the API. But, in the case OpenGL and X we can use a
context (and window) per thread for OpenGL and we can make Xlib
callable from multiple threads. We don’t do that by adding X locking
calls to the SDL event thread. We do that by adding the calls to the
XLib wrappers created by SDL to call into the Xlib dynamic library. We
do have to make sure that the XGL calls used to set up OpenGL are
performed at the right times. But, that can by handled by xsync or
xflush as they already are.
You have raised an interesting issue. Being able to make Xlib calls
from multiple threads would be a nice feature to have.
Bob PendletonOn Wed, Jan 20, 2010 at 7:57 AM, Carlo Wood wrote:
On Tue, Jan 19, 2010 at 07:21:17PM -0600, Bob Pendleton wrote:
On Tue, Jan 19, 2010 at 4:39 PM, Carlo Wood wrote:
On Tue, Jan 19, 2010 at 07:48:42AM -0600, Bob Pendleton wrote:
–
Carlo Wood
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
–
±----------------------------------------------------------