[M3commit] CVS Update: cm3

Jay Krell jkrell at elego.de
Mon May 4 13:19:07 CEST 2009

CVSROOT:	/usr/cvs
Changes by:	jkrell at birch.	09/05/04 13:19:07

Modified files:
	cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 

Log message:
	move expensive calloc+pthread_mutex_init outside lock, using a double
	check pattern:
	if it appears work is needed (but with taking lock to be sure)
	do the work, into temp
	take lock
	if work not actually needed, ok
	release lock
	free the temp (don't care if it succeeded)
	if attempt to do the work failed
	release lock
	raise exception
	commit the work
	release lock
	It is ugly perhaps to repeat "release lock" three times instead
	of once, but time holding the lock is minimized.
	As long as "temp" is a pointer, which it is here,
	this can use InterlockedCompareExchangePointer and not a full blown lock.
	Something like:
	if pointer == null
	temp = new ...
	if InterlockedCompareExchange(&pointer, NULL, temp) != NULL)
	delete temp (* lost the race, ok *)
	if temp == NULL (* won the race but failed *)
	raise exception
	This pattern is bad if the temp work is particularly expensive or
	must not be executed more than once. That leaves
	many instances in which it is ok.
	Also here eliminate PushFrame, but the point is more to eliminate
	calloc from inside a lock. Therefore, if calloc is well tuned for
	multiprocessor systems, and many locks are used for the first
	time at about the same time on multiple threads, scale better.
	("hold locks for minimal time, even at the risk of doing more work
	in the event of a race" is a good scalability principle; as well as "replace lock
	with interlocked/atomic/cas/etc., also at the risk of doing
	more work when there is a race")
	Factor InitMutex and InitCondition into one function InitMutexHelper.
	It is tempting to rewrite InitMutexHelper in C, thereby removing
	the exposure of the init lock, however as I understand this is a
	bad move due to interior gc pointers or such.

More information about the M3commit mailing list