On Mon, Mar 2, 2009 at 5:28 AM, Paul TBBle Hampson Paul.Hampson@pobox.com wrote:
On Mon, Mar 02, 2009 at 12:29:14AM +0200, Pauli Nieminen wrote:
Msdn sayes: "The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means that the following restrictions hold:
* During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process. * Only one thread in a process can be in a DLL initialization or detach routine at a time. * ExitProcess does not complete until there are no threads in their DLL initialization or detach routines."
So maybe this hidden synchronization is causing also newly created thread not to run until CreateThread has exited.
How would I know if one of these was the case? 'cause if that's what's going on, it'd explain the problem quite neatly.
I should mention that the actual code being run here is inside a dll file (libpatchui.dll) not the main warpatch.bin.
There seems to be at least partial synchronization for dll loading but threading part doesn't include this lock. It seems like wine doesn't need it so maybe it is enough to just simulate windows with following small patch.
For me above restriction just sounds like performance bottleneck for future CPUs with x cores where X>100 cores :)
Pauli
disclaimer: I didn't test this so might not be complete solution. If it isn't enough then you could try add lock calls to create thread and exit thread paths too.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 87b9d57..88acc3e 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -466,7 +466,9 @@ static void start_thread( struct startup_info *info ) PRTL_THREAD_START_ROUTINE func = info->entry_point; void *arg = info->entry_arg; struct debug_info debug_info; - + ULONG magic; + + LdrLockLoaderLock(0, NULL, &magic); debug_info.str_pos = debug_info.strings; debug_info.out_pos = debug_info.output; thread_data->debug_info = &debug_info; @@ -480,6 +482,7 @@ static void start_thread( struct startup_info *info ) InsertHeadList( &tls_links, &teb->TlsLinks ); RtlReleasePebLock();
+ LdrUnlockLoaderLock(0, &magic); /* NOTE: Windows does not have an exception handler around the call to * the thread attach. We do for ease of debugging */ if (unhandled_exception_filter)