I have been looking at the use of the wined3d_mutex_lock and wined3d_mutex_unlock functions in the drawing code. I strongly suspect that it is being badly over-used.
In particular, user call back functions are being called in several places with this mutex held. If the callback starts another thread to do something graphical where the thread needs the mutex, and then waits for the thread to finish, both threads will hang until the mutex times out. There are also places where a function that takes out the mutex is called with the mutex already held.
Switching to another terminal window and back again sometimes breaks these deadlocks. It used to be that I had to do this several times doing a 'make test', but it just takes a long time now. (Yes, years ago I left the test running for several hours when I went out for a few hours and it was still hung when I got back. That does not happen now,)
This shows up running Guild Wars 2. I have a CPU monitor running while I play and I can see the game chomping on both cores, except that the game will sometimes hang for 30-45 seconds and then resume.
I am in the process of annotating the drawing routines use of the mutex, and there is simply a lot of code to go through. Could someone with a good understanding of the drawing part of wine comment please.
In particular, are there places where the lock-like action of the reference counts can be used in place of taking out the mutex?
max
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 2014-02-26 20:13, schrieb Max TenEyck Woodbury:
In particular, user call back functions are being called in several places with this mutex held. If the callback starts another thread to do something graphical where the thread needs the mutex, and then waits for the thread to finish, both threads will hang until the mutex times out. There are also places where a function that takes out the mutex is called with the mutex already held.
ddraw calls application-provided callback functions. A long time ago I did some testing on Windows, and it also uses a dll-global lock for ddraw and keeps it held when calling those callbacks. So we're doing the right thing here.
In case of d3d8/9, there are in theory the Resource's SetPrivateData, GetPrivateData and FreePrivateData functions that can call application code, specificly an IUnknown's AddRef and Release function. I have never tested how those behave wrt the dll lock. This thing can also be used to write a black-box test to see at which granularity Windows does d3d8/9 synchronization.
Switching to another terminal window and back again sometimes breaks these deadlocks.
That seems wrong, unless we're accidentally holding those locks while sending window messages.
On 02/27/2014 03:10 AM, Stefan Dösinger wrote:
Am 2014-02-26 20:13, schrieb Max TenEyck Woodbury:
In particular, user call back functions are being called in several places with this mutex held. If the callback starts another thread to do something graphical where the thread needs the mutex, and then waits for the thread to finish, both threads will hang until the mutex times out. There are also places where a function that takes out the mutex is called with the mutex already held.
ddraw calls application-provided callback functions. A long time ago I did some testing on Windows, and it also uses a dll-global lock for ddraw and keeps it held when calling those callbacks. So we're doing the right thing here.
Thank you for the information. That means I can ignore that issue.
In case of d3d8/9, there are in theory the Resource's SetPrivateData, GetPrivateData and FreePrivateData functions that can call application code, specificly an IUnknown's AddRef and Release function. I have never tested how those behave wrt the dll lock. This thing can also be used to write a black-box test to see at which granularity Windows does d3d8/9 synchronization.
Uh, OK. (More information than I can handle at the moment. Maybe later...)
Switching to another terminal window and back again sometimes breaks these deadlocks.
That seems wrong, unless we're accidentally holding those locks while sending window messages.
With the time-out in place, it is hard to tell if it is still a problem, but it used to happen irregularly. It seemed to be something racy. It showed up with one batch of patches and then disappear after a couple more sets. Whatever it is, it is a really old problem.
IIRC it was more of a problem with ddraw4 and ddraw7 than it was with the earlier interfaces...
max