is core Mutex lock "fast"?

IGotD- nise at nise.com
Tue Jan 26 20:56:21 UTC 2021


On Tuesday, 26 January 2021 at 18:07:06 UTC, ludo wrote:
> Hi guys,
>
> still working on old D1 code, to be updated to D2. At some 
> point the previous dev wrote a FastLock class. The top comment 
> is from the dev himself, not me. My question is after the code.
>
> ---
>
> class FastLock
> {
> 	protected Mutex mutex;
> 	protected int lockCount;
> 	protected Thread owner;
>
> 	///
> 	this()
> 	{	mutex = new Mutex();
> 	}
>
> 	/**
> 	 * This works the same as Tango's Mutex's lock()/unlock except 
> provides extra performance in the special case where
> 	 * a thread calls lock()/unlock() multiple times while it 
> already has ownership from a previous call to lock().
> 	 * This is a common case in Yage.
> 	 *
> 	 * For convenience, lock() and unlock() calls may be nested.  
> Subsequent lock() calls will still maintain the lock,
> 	 * but unlocking will only occur after unlock() has been 
> called an equal number of times.
> 	 *
> 	 * On Windows, Tango's lock() is always faster than D's 
> synchronized statement.  */
> 	void lock()
> 	{	auto self = Thread.getThis();
> 		if (self !is owner)
> 		{	mutex.lock();
> 			owner = self;
> 		}
> 		lockCount++;
> 	}
> 	void unlock() /// ditto
> 	{	assert(Thread.getThis() is owner);
> 		lockCount--;
> 		if (!lockCount)
> 		{	owner = null;
> 			mutex.unlock();
> 		}
> 	}
> }
>
> ---
>
> Now if I look at the doc , in particular Class 
> core.sync.mutex.Mutex, I see:
> ---
>  lock () 	If this lock is not already held by the caller, the 
> lock is acquired, then the internal counter is incremented by 
> one.
> --
> Which looks exactly like the behavior of "fastLock". Is it so 
> that the old Tango's mutex lock was not keeping count and would 
> lock the same object several time? Do we agree that the 
> FastLock class is obsolete considering current D core?
>
> cheers

That code isn't thread safe at all (assuming FastLock is used 
from several threads). lockCount isn't atomic which means the 
code will not work with several threads. Also the assignment of 
the variable owner isn't thread safe. As soon you start to 
include more that one supposedly atomic assignment in 
synchronization primitives, things quickly get out of hand.

Normal D Mutex uses pthread_mutex on Linux and the usual 
CriticalSection stuff on Windows. Neither is particularly fast. 
Futex on Linux isn't exactly super fast either. Synchronization 
primitives aren't exactly fast on any system because that's how 
it is. There are ways to makes things faster but adding stuff 
like timeouts and the complexity goes exponential. There so many 
pitfalls with synchronization primitives that it is hardly worth 
it making your own.


More information about the Digitalmars-d-learn mailing list