Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a lock-free shared flag in C?

Tags:

c

sync

lock-free

I have one-producer-one-consumer model, in which I need for the producer to set a flag when data is available. I suspect I can get away without a lock on the shared flag because:

  • The producer never checks the value before setting
  • Missing an update to the flag occasionally is not a problem (though I could probably also avoid this using atomic operations?).

So my question is, how do I implement this? My understanding of the volatile keyword, and things like __sync_synchronize() are tenuous at best, so assume I know very little. Specifically, I'm looking to be able to make sure that a change to the flag is visible in the other thread in a timely fashion.

Edit: I'm using GCC on Linux.

like image 229
brooks94 Avatar asked Nov 25 '22 15:11

brooks94


1 Answers

Use two variables:

volatile size_t elements_produced; // producer increments it when data is available
volatile size_t elements_consumed; // consumer increments it

new data is available exactly when elements_produced != elements_consumed. If you need an infinite amount then in addition mod it on updating.

produce(...) {
    elements_produced = (elements_produced + 1) % (max_elements_in_queue + 1);
}

consume(...) {
    elements_consumed = (elements_consumed + 1) % (max_elements_in_queue + 1);
}

no need for locks or atomics.

This is the standard implementation of single-producer, single-consumer circular ring buffers.

like image 106
Sergey L. Avatar answered Dec 20 '22 12:12

Sergey L.