[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