[SDL] What are threads allowed to do?
bob at pendleton.com
Mon Jan 24 07:03:42 PST 2005
On Sun, 2005-01-23 at 12:38 -0500, Albert Cahalan wrote:
> On Sun, 2005-01-23 at 12:05, Stephane Marchesin wrote:
> > Albert Cahalan wrote:
> > >>>I tried using threads, hit memory corruption problems, and...
> > >>>
> > >>Well, show us a small program demonstrating memory corruption with SDL
> > >>threads, and we'll have a chance to find the reason for this problem.
> > >>
> > >
> > >That's a tough order to fill I think.
> > >
> > >I saw the problem in Tux Paint, which is one 15469-line file.
> > >(yes, yes, we know -- it grew over time)
> > >
> > We usually ask this because it works.
> > That said, if you happen to have a test case demonstrating a precise
> > problem, don't hesitate.
> > >
> > >One thread was using libSDL_ttf. It scanned through about 200
> > >font files. The thread would open a file, render some test text,
> > >and close the file.
> > >
> > >Meanwhile, the main app thread was mostly loading PNG images.
> > >It would load a few hundred perhaps, along with a couple fonts
> > >and perhaps dozens of *.wav files. The main thread has video
> > >and sound going.
> > >
> > I quickly looked at the file and I think you'll really have a hard time
> > getting it to work, there are too many global variables, whereas I
> > couldn't spot any mutex. Threaded programming must be thought about at
> > the beggining...
> What, the tuxpaint.c file? The font thread was supposed to do
> a very isolated task. The globals in use by the font thread
> would not be touched by the main thread while the font thread
> was running, except for reading one "volatile long" that the
> font thread sets to indicate completion. The main thread would
> do other stuff for a while, then display a progress bar while
> waiting for font thread completion. When the font thread is done,
> the main thread joins with it before using the global data.
> That all worked pretty well, except for memory corruption.
> Since the threads don't race on shared globals, there should
> not be any need for a mutex. (where would you put it?)
> Well, there is a known memory corruption bug in libSDL_ttf
> involving italic fonts. It normally doesn't cause trouble,
> but maybe the altered memory layout of the threaded solution
> (different stack location, etc.) made the problem worse.
> Perhaps Tux Paint even has a similar problem, though it
> tolerates linking with Electric Fence (a malloc bounds checker)
> just fine.
> It's looking now like I will use fork(), with a socket to
> send back the list of font files. Windows is without fork(),
> so the Windows users will just have to wait 20 seconds for
> Tux Paint to start. (nothing unusual for them I think)
Taking a shot in the dark here... Since no one can know what you know we
have to take shots in the dark.
On linux, the C/C++ standard libraries may or may not be thread safe, it
all depends on the version you use. If you are on 3.0 or better then the
standard libraries are thread safe (at least that is what the docs I
have found say and it seems to work). For Windows help ask someone else.
OTOH, SDL is not thread safe. All graphics must be done in the main
thread and all keyboard, mouse, and joystick input must be done in the
main thread. You can do anything you want in other threads.
But, like I said, SDL is not thread safe, neither are any of the SDL add
on libraries. If you want to use them in threads you have to build
wrappers for the code you want to use. The wrappers must enforce serial
access to each function call. The libraries have there own global
variables and are coded assuming that only a single thread will run in
them at a time.
What does that mean to an SDL programmer? It means that you can have 10
threads reading 10 files, but only one thread can be decoding a ttf font
at a time.
Now, the thing to consider is that unless you have a hyperthreading or
multicore CPU you can't actually have more than one thread active at a
time anyway. And, having multiple threads reading from a single disk may
or may not improve disk reading performance. After all, there is only
one disk to perform the reads. So, this month you might not see the
performance improvement you expect to see. Next month you might see a
dramatic performance improvement :-)
For an example of a thread safe wrapper library used with SDL take a
look at Net2 and Fast Events at
http://gameprogrammer.com/programming.html I had to solve this problem
to do multithreaded network I/O handling in SDL.
Just and editorial comment or two if you don't mind: Thread programming
in user space is very different from thread programming in system space.
The main difference is that in system space everything has been coded
assuming multiple threads because of interrupt processing. In use space
almost no code is written assuming multiple threads. Most libraries will
turn there toes up and die if you try to use them in a multithreaded
application without writing a serializing wrapper library.
One last editorial comment: A funny thing happened a couple or three
years ago. Processors aren't getting a lot faster any more. Starting in
about 2001 the rate at which processors get faster dropped dramatically.
OTOH, Moore's law has been cranking right a long giveing us more and
more transistors on a chip. The processor manufactures have been forced
to redirect the benefits of Moore's law into things like hyperthreading
and multicore processors rather than into faster processors. Unless
there is a breakthrough that allows CPUs to start getting faster we are
facing a world where all performance increases are going to come from
multithreading on parallel processors and not from faster processors.
We're going to need thread safe versions of all the libraries we use.
> SDL mailing list
> SDL at libsdl.org
More information about the SDL