[vlc-devel] [PATCH 1/6] os2: implement vlc_once()

Rémi Denis-Courmont remi at remlab.net
Tue Mar 27 17:49:54 CEST 2018


Le tiistaina 27. maaliskuuta 2018, 18.48.59 EEST Kamil Rytarowski a écrit :
> On 27.03.2018 17:43, Rémi Denis-Courmont wrote:
> > Le tiistaina 27. maaliskuuta 2018, 18.36.32 EEST Kamil Rytarowski a écrit 
:
> >> On 26.03.2018 13:16, KO Myung-Hun wrote:
> >>> Rémi Denis-Courmont wrote:
> >>>> POSIX model is simpler here, but it wouldn't work with C11 either.
> >>> 
> >>> How about this ?
> >> 
> >> There is no need for a mutex.
> > 
> > How do you handle the case that another thread is doing the initialization
> > without a mutex?
> > 
> >> An algorithm like follows should work better:
> >> 
> >> static atomic_uint32_t bg_thread = {};
> >> if (atomic_load(&bg_thread, memory_order_relaxed) == 0 &&
> >> 
> >>     atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) {
> >>   
> >>   cb();
> >> 
> >> }
> > 
> > That can be equivalent reduced to:
> > 
> > static atomic_uint32_t bg_thread = {};
> > if (atomic_compare_exchange_strong_explicit(&bg_thread, &{0}, 1,
> > memory_order_relaxed, memory_order_relaxed) == 0)
> > 
> >   cb();
> > 
> > This obviously lacks memory synchronization in the simple non-racy case,
> > and utterly fails in the racy corner case. In other words, it does not
> > work at all.
> 
> If we want to go for CAS:
> 
>   static atomic_uint32_t bg_thread = {};
>   u32 cond = atomic_load(&bg_thread, memory_order_acquire);
>   if (cond == 0) {
>     if (atomic_compare_exchange_strong(&bg_thread, &cond, 1,
>                                        memory_order_acq_rel)) {
>       cb();
>     }
>   }

No. The memory release needs to occur *after* the callback, so this is still 
nto working in non-racy case. And it fails to wait for callback completion in 
racy case.

-- 
雷米‧德尼-库尔蒙
https://www.remlab.net/



More information about the vlc-devel mailing list