Multithreaded memory crash |
Nathaniel J Fries
|
bug appears to be in your code.
numAliveThreads is initialized to zero, then incremented by each new thread. but you signal all threads are dead when numAliveThreads has been decremented down to 1. this means there is still one thread running, possibly even still waiting in the kernel on a semaphore which the main thread is going to destroy. |
|||||||||||
|
satchmo
|
I'm pretty sure that code is ok. SDL_AtomicAdd() returns the previous value of the variable before the add (hence the variable name prevNumAliveThreads) - when the previous value is 1 it means it was just decremented to 0, so this is the last thread alive.
I believe I've actually identified the issue - it's a bug with SDL's thread management which does memory allocation in a non-thread-safe manner, as SDL_RunThread() itself runs in a separate thread. SDL's memory allocator isn't thread-safe (the dlmalloc implementation doesn't have USE_LOCKS defined), and when I kill the threads manually using a semaphore just before calling the SDL_Quit(), they end up dying at around the same time SDL is cleaning itself up. SDL_RunThread() calls SDL_free() when the thread function exits, and this is probably happening at the same time as some other frees in various SDL subsystems. Another common crash I get is in SDL_free_REAL() when called by SDL_VideoQuit_REAL(), which backs up this theory. Also, if I #define USE_LOCKS 1 in SDL_malloc.c, everything works correctly. Putting locks around every allocation is a very heavy-handed approach to making memory management thread-safe (although some very high-profile game engines unfortunately do exactly that), but in the case of SDL it may be warranted as the alternative is an overhaul of how thread memory management is handled, and in general SDL's memory allocation code is called relatively infrequently. |
|||||||||||
|
Nathaniel J Fries
|
Ah, you're right about AtomicAdd behavior, sorry. Good bug catch. Shouldn't be hard to tweak dlmalloc to use much less locking. The way Hoard does this should work despite any internal allocator differences. |
|||||||||||||
|
Multithreaded memory crash |
Juan Manuel Borges Caño
Guest
|
You wait for dead signal, once the thread sends it, you destroy the system, what the thread still needs to do is clean after itself, that mere return 0..., that could kick some pool job...
Usually the approach is to wait for thread end EXPLICITILY, say WaitThread(), then and that guarantees its destruction. Not discarding core misstakes, but theory is like this . El 07/05/2014 18:47, "satchmo" escribió:
|
|||||||||||||||
|
Re: Multithreaded memory crash |
satchmo
|
That's mostly irrelevant though; the thread local storage implementation also makes thread-unsafe realloc() calls. The real problem here is the memory model used for the threading implementation, not the method of managing the threads themselves. I just went to log a bug about this, but it looks like there's one already that was logged just last month. I'll add a comment. |
|||||||||||||
|