For a scenario with multiple reader threads and a single writer thread, where the readers are allowed to read slightly outdated data, I've concocted a lockless control flow as shown below in its most basic form in pseudocode:
GLOBAL_ATOMIC_POINTER shared_pointer
// Only called by the reader threads.
read()
THREAD_LOCAL_POINTER read_pointer := shared_pointer
return read_data_at(read_pointer)
// Only called by the writer thread.
write(input)
THREAD_LOCAL_ARRAY array
THREAD_LOCAL_POINTER write_pointer := shared_pointer
if write_pointer == location_of_last_element(array)
write_pointer := location_of_first_element(array)
else
write_pointer := location_of_next_element(array, write_pointer)
write_data_at(write_pointer, input)
shared_pointer := write_pointer
Let's call MAX_READING_DURATION
the maximum period of time that a call to read()
can take to complete, and MIN_WRITING_DURATION
the minimum period of time that a call to write()
can take to complete.
Now, with shared_pointer
guaranteed to be atomic, as long as MAX_READING_DURATION < ELEMENT_COUNT(ARRAY) * MIN_WRITING_DURATION
, this scheme should be perfectly safe.
Or have I overlooked something? If not, I'm sure this is a well known thing, and I'd like to know the proper terminology is, so I can use that when I explain/advocate this approach to others.