On Sun, 02 Jun 2024 15:14:51 +0200 Bruno Haible wrote: > Hi Takashi Yano, > > > The result is as follows (submitted as v4 patch). > > > > int > > pthread::once (pthread_once_t *once_control, void (*init_routine) (void)) > > { > > /* Sign bit of once_control->state is used as done flag. > > Similary, the next significant bit is used as destroyed flag. */ > > const int done = INT_MIN; /* 0b1000000000000000 */ > > const int destroyed = INT_MIN >> 1; /* 0b1100000000000000 */ > > if (once_control->state & done) > > return 0; > > > > /* The type of &once_control->state is int *, which is compatible with > > LONG * (the type of the pointer argument of InterlockedXxx()). */ > > if ((InterlockedIncrement (&once_control->state) & done) == 0) > > { > > pthread_mutex_lock (&once_control->mutex); > > if (!(once_control->state & done)) > > { > > init_routine (); > > InterlockedOr (&once_control->state, done); > > } > > pthread_mutex_unlock (&once_control->mutex); > > } > > InterlockedDecrement (&once_control->state); > > if (InterlockedCompareExchange (&once_control->state, > > destroyed, done) == done) > > pthread_mutex_destroy (&once_control->mutex); > > return 0; > > } > > ... > > I believe both codes are equivalent. Could you please check? > > Yes, they are equivalent. This code is free of race conditions. (Let's > hope I am not making a mistake again.) > > For legibility I would write the constant values as bit masks: > 0x80000000 > 0xc0000000 > and - following the habit that constant integers should have names in > upper case - I would rename > done → DONE > destroyed → DESTROYED
Thanks for checking. I'll push the patch after the modification. -- Takashi Yano <takashi.y...@nifty.ne.jp> -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple