<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Is this safe?  Double-check pattern is often not fully safe.  I haven't looked at your code but will do so ASAP.<div><br></div><div>PS Why are you optimizing initialization -- seems premature to me.<br><div><div><div><br><div> <span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div><font class="Apple-style-span" color="#0000FF"><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Antony Hosking</span></span></font></font><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; "> | </span></span><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; ">Associate Professor</span></span><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; "> | Computer Science | Purdue University</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; ">305 N. University Street | West Lafayette | IN 47907 | USA</span></font></div><div><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Office</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "> +1 765 494 6001 | </span></span></font><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Mobile</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "> +1 765 427 5484</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><br class="khtml-block-placeholder"></font></div></span></span></span></span></span></span></span><br class="Apple-interchange-newline"></span></div></span> </div><br><div><div>On 4 May 2009, at 13:19, Jay Krell wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>CVSROOT:<span class="Apple-tab-span" style="white-space:pre">        </span>/usr/cvs<br>Changes by:<span class="Apple-tab-span" style="white-space:pre">       </span>jkrell@birch.<span class="Apple-tab-span" style="white-space:pre">       </span>09/05/04 13:19:07<br><br>Modified files:<br><span class="Apple-tab-span" style="white-space:pre">      </span>cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 <br><br>Log message:<br><span class="Apple-tab-span" style="white-space:pre"> </span>move expensive calloc+pthread_mutex_init outside lock, using a double<br><span class="Apple-tab-span" style="white-space:pre">     </span>check pattern:<br><span class="Apple-tab-span" style="white-space:pre">    </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>if it appears work is needed (but with taking lock to be sure)<br><span class="Apple-tab-span" style="white-space:pre">    </span>do the work, into temp<br><span class="Apple-tab-span" style="white-space:pre">    </span>take lock<br><span class="Apple-tab-span" style="white-space:pre"> </span>if work not actually needed, ok<br><span class="Apple-tab-span" style="white-space:pre">   </span>release lock<br><span class="Apple-tab-span" style="white-space:pre">      </span>free the temp (don't care if it succeeded)<br><span class="Apple-tab-span" style="white-space:pre">        </span>else<br><span class="Apple-tab-span" style="white-space:pre">      </span>if attempt to do the work failed<br><span class="Apple-tab-span" style="white-space:pre">  </span>release lock<br><span class="Apple-tab-span" style="white-space:pre">      </span>raise exception<br><span class="Apple-tab-span" style="white-space:pre">   </span>else<br><span class="Apple-tab-span" style="white-space:pre">      </span>commit the work<br><span class="Apple-tab-span" style="white-space:pre">   </span>release lock<br><span class="Apple-tab-span" style="white-space:pre">      </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>It is ugly perhaps to repeat "release lock" three times instead<br><span class="Apple-tab-span" style="white-space:pre"> </span>of once, but time holding the lock is minimized.<br><span class="Apple-tab-span" style="white-space:pre">  </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>As long as "temp" is a pointer, which it is here,<br><span class="Apple-tab-span" style="white-space:pre">       </span>this can use InterlockedCompareExchangePointer and not a full blown lock.<br><span class="Apple-tab-span" style="white-space:pre"> </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>Something like:<br><span class="Apple-tab-span" style="white-space:pre">   </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>if pointer == null<br><span class="Apple-tab-span" style="white-space:pre">        </span>temp = new ...<br><span class="Apple-tab-span" style="white-space:pre">    </span>if InterlockedCompareExchange(&pointer, NULL, temp) != NULL)<br><span class="Apple-tab-span" style="white-space:pre">  </span>delete temp (* lost the race, ok *)<br><span class="Apple-tab-span" style="white-space:pre">       </span>else<br><span class="Apple-tab-span" style="white-space:pre">      </span>if temp == NULL (* won the race but failed *)<br><span class="Apple-tab-span" style="white-space:pre">     </span>raise exception<br><span class="Apple-tab-span" style="white-space:pre">   </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span>end<br><span class="Apple-tab-span" style="white-space:pre">       </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>This pattern is bad if the temp work is particularly expensive or<br><span class="Apple-tab-span" style="white-space:pre"> </span>must not be executed more than once. That leaves<br><span class="Apple-tab-span" style="white-space:pre">  </span>many instances in which it is ok.<br><span class="Apple-tab-span" style="white-space:pre"> </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>Also here eliminate PushFrame, but the point is more to eliminate<br><span class="Apple-tab-span" style="white-space:pre"> </span>calloc from inside a lock. Therefore, if calloc is well tuned for<br><span class="Apple-tab-span" style="white-space:pre"> </span>multiprocessor systems, and many locks are used for the first<br><span class="Apple-tab-span" style="white-space:pre">     </span>time at about the same time on multiple threads, scale better.<br><span class="Apple-tab-span" style="white-space:pre">    </span>("hold locks for minimal time, even at the risk of doing more work<br><span class="Apple-tab-span" style="white-space:pre">   </span>in the event of a race" is a good scalability principle; as well as "replace lock<br><span class="Apple-tab-span" style="white-space:pre">       </span>with interlocked/atomic/cas/etc., also at the risk of doing<br><span class="Apple-tab-span" style="white-space:pre">       </span>more work when there is a race")<br><span class="Apple-tab-span" style="white-space:pre">     </span><br><span class="Apple-tab-span" style="white-space:pre">  </span>Factor InitMutex and InitCondition into one function InitMutexHelper.<br><span class="Apple-tab-span" style="white-space:pre">     </span>It is tempting to rewrite InitMutexHelper in C, thereby removing<br><span class="Apple-tab-span" style="white-space:pre">  </span>the exposure of the init lock, however as I understand this is a<br><span class="Apple-tab-span" style="white-space:pre">  </span>bad move due to interior gc pointers or such.<br></div></blockquote></div><br></div></div></div></div></body></html>