On Tue, Jun 8, 2021 at 4:22 PM Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: > On 6/8/21 3:14 PM, Andy Shevchenko wrote: > > On Tue, Jun 8, 2021 at 3:44 PM Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: > >> On 6/8/21 2:35 PM, Andy Shevchenko wrote: > >>> Hi! > >>> > >>> Can anybody explain this code [1] in terms of atomicity? > >>> > >>> if (!atomic_read(&trig->use_count)) { > >>> atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER); > >>> ... > >>> } > >>> > >>> AFAIU how atomics are supposed to work the above doesn't do anything > >>> atomically. I.o.w. use_count may be simple int with the same effect. > >>> > >> The operations here do not require atomic access, it is just operating > >> on a atomic type. The atomic access is the atomic_dec_and_test() in > >> iio_trigger_notify_done(). > > So, between atomic_read and atomic_set somebody can call > > atomic_dec_and_test(), for example. Is it a problem to actually lose > > the value? > > Why are atomic types being used here when there is no atomicity guaranteed? > > We know that if the value is zero that there are no more active > consumers. Then we set the value to the number of consumers, and then > launch the consumers, which will decrement the counter once they are done. So, why atomic type? I can see various races with this code. For example, we have two CPUs calling the same function (because it's hardware driven model) Imagine that one goes into counter 0 (just after the last notify done) followed by the atomic_set to something non-zero followed by a skipping trigger notification. Next time the loop won't be called, because nobody will reduce atomic to 0, right? Is it a possible scenario? -- With Best Regards, Andy Shevchenko