CreateThread timing behaviour (Bug 15323 affecting Warhammer Online)

Pauli Nieminen suokkos at gmail.com
Sun Mar 1 22:51:06 CST 2009


On Mon, Mar 2, 2009 at 5:28 AM, Paul TBBle Hampson
<Paul.Hampson at 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)



More information about the wine-devel mailing list