Low (and high)-level TMonitor improvements.
-
Change
SetMonitorData
toInterlockedTrySetMonitorData
(can be named less Java EE style...)InterlockedCompareExchangeMonitorData
(this style is probably required overTrySet... : boolean
to be able to freeTMonitorData
early, should the urge ever arise) and remove global_MemLock
. -
LockCount
does not require atomic operations, they are already performed under the lock, and the checkGetCurrentThreadId = LockOwnerThreadID
passes if and only if current thread holds the lock. If current thread does not hold the lock,LockOwnerThreadID
can only visibly change from one value not equal toGetCurrentThreadId
to another value not equal toGetCurrentThreadId
. (While we at it:TryEnter
is incorrect, it does not incrementLockCount
on succesful recursive acquisitions.) -
Since
TPulseData
-related structures are “transient” in their nature (TPulseData
exists only during correspondingWait
call), they can be assembled into a linked list of structures allocated inWait
stack frames of waiting threads. This may sound exotic and dangerous, but is in practice simpler and more reliable (does not require any kind of search andTPulseData.Match
, and cannot throw OOM in the middle ofWait
) than current implementation. -
TMonitor.Wait
must temporarily unlock through any amount of recursive acquisitions!
Two Three more notes:
-
I just hope this entire thing is not going to be compiled into every application at any point in the future, right? (Right now it is not, but eg threading is, because of
TThreadManager
; cfTMonitorManager
). -
Starting from Windows Vista, there are SRW locks and condition variables (and starting from Windows 8, there are
WaitOnAddress
,WakeByAddressSingle
, andWakeByAddressAll
, but not sure about their usage here). They implement most ofTMonitor
(with no guarantees about fairness or FIFO, but, ugh...) and are well worth a separate far simpler and far more efficientTMonitor
implementation chosen at runtime. -
Timeouted
Enter
must be implemented with an event, but I don’t want to think how exactly. For now, spin-wait a while,ThreadSwitch
a while, and then progressivelySleep
.