I don't know explicitly what "triple checked locking" is but since almost a decade ago when the compiler writers and hardware engineers started to take control away from the programmers my lazy init has had 3 states:
enum eINITIALIZATION_STATE {FIRST_INITIALIZER=0,INITIALIZING,INITIALIZED} ;
( Just imagine if you sent out library software that was totally incompatible with important multi threaded algorithms in the field! But I have been writing code for SMP machines for over 30 years and the multi-core "revolution" (HA!) just really got rolling in the last decade. The compiler writers and HW engineers either didn't know what they were breaking or they decided it did not matter... But enough editorializing! )
Sooo...
enum eINITIALIZATION_STATE {FIRST_INITIALIZER=0,INITIALIZING,INITIALIZED} ;
then you have an initialization control variable:
static int init_state; //its 0 initialized 'cause static
then the idiom is:
IF(init_state == INITIALIZED)
return your pointer or what ever;//the "normal" post initialization path
ENDIF
IF(init_state == FIRST_INITIALIZER)
IF(compare_and_swap(&init_state,
INITIALIZING,
FIRST_INITIALIZER)==FIRST_INITIALIZER)
//first initializer race resolved - I'm first.
do your initialization here;
//And now resolve the race induced by the compiler writers and the HW guys
COMPILER_FENCE();//needs macro for portability
HARDWARE_FENCE();//needs macro for portability
//on intel using cas here supplies the HARDWARE_FENCE();
compare_and_swap(&init_state,INITIALIZER,INITIALIZING);
//now you can return your pointer or what ever or just fall through
ENDIF
ENDIF
DOWHILE(*const_cast<volatile const int*>(&init_state)!=INITIALIZED)
relinquish or spin;
ENDDO
return your pointer or what ever;
I am not sure if this is what was meant but because of the 3 states I suspect this may be equivalent (or at least similar) to whatever was meant by "triple checked locking" .