lhmouse / mcfgthread

Cornerstone of the MOST efficient std::thread on Windows for mingw-w64
https://gcc-mcf.lhmouse.com/
Other
277 stars 28 forks source link

About NtWaitForAlertByThreadId and NtAlertThreadByThreadId #56

Closed CarterLi closed 2 years ago

CarterLi commented 2 years ago

我看到 AcquireSRWLockExclusive 和 SleepConditionVariableSRW 都是用 NtWaitForAlertByThreadId

image

https://github.com/processhacker/processhacker/blob/master/phnt/include/ntpsapi.h#L1656

关于SRWLock不支持timed_mutex的问题,NtWaitForAlertByThreadId 本身支持 timeout,只是 AcquireSRWLockExclusive 没开放出来

NtWaitForAlertByThreadId 比 NtWaitForKeyedEvent 参数更少,功能更专用,性能应该会比后者好

包括 rpcs3 也是优先 NtWaitForAlertByThreadId :https://github.com/valgusk/rpcs3-old-rpcn/blob/f6f12b3b0dfeedc260d44e3be713fcb03c9638eb/rpcs3/util/atomic.cpp#L1192

考虑一下?

lhmouse commented 2 years ago

That is a completely different thing. As there is no longer a 'key', it will be necessary to perform some bookkeeping in user mode.

One possible design for reducing bus pressure is to allocate a structure on the stack and use it to build a wait queue. This answers why SRWLOCK doesn't support timeouts: It is not safe to remove nodes from wait queues without global locking, otherwise a thread that attempts to wake up another one which has timed out would reference destroyed objects and cause unpredictable results.

CarterLi commented 2 years ago

这个东西我是外行。说的有错不要介意。

That is a completely different thing. As there is no longer a 'key', it will be necessary to perform some bookkeeping in user mode.

NtWaitForAlertByThreadId,这里的ThreadId不就是这个key?

lhmouse commented 2 years ago

No there is no thread ID argument. This function suspends the current thread for the timeout specified by its second argument. See https://source.winehq.org/source/dlls/ntdll/sync.c#0931 for example.

CarterLi commented 2 years ago

No there is no thread ID argument. This function suspends the current thread for the timeout specified by its second argument. See https://source.winehq.org/source/dlls/ntdll/sync.c#0931 for example.

You can only suspend the current thread, so you don't need to pass the thread ID argument in ( like what Sleep does ). It's enough, isn't it?

lhmouse commented 2 years ago

Then when a thread attempts to unlock a mutex, how does it know which threads are currently waiting, and which one it should wake up?

CarterLi commented 2 years ago

Isn't it (thread id) stored in the mutex object?

So a mutex object must maintain a wait queue. I understood.

CarterLi commented 2 years ago

What is address used for? According to the implementation of wine, address is completely unused ( only for tracing ).

lhmouse commented 2 years ago

It's unused in Wine. Not sure about Windows.