casacore
Loading...
Searching...
No Matches
casacore::aocommon::Lane< Tp > Class Template Reference

The Lane is an efficient cyclic buffer that is synchronized. More...

#include <Lane.h>

Public Types

typedef std::size_t size_type
 Integer type used to store size types.
typedef Tp value_type
 Type of elements stored in the Lane.

Public Member Functions

 Lane () noexcept
 Construct a Lane with zero elements.
 Lane (size_t capacity)
 Construct a Lane with the given capacity.
 Lane (const Lane< Tp > &source)=delete
 Lane (Lane< Tp > &&source) noexcept
 Move construct a Lane.
 ~Lane ()
 Destructor.
Lane< Tp > & operator= (const Lane< Tp > &source)=delete
Lane< Tp > & operator= (Lane< Tp > &&source) noexcept
 Move assignment.
void swap (Lane< Tp > &other) noexcept
 Swap the contents of this Lane with another.
void clear () noexcept
 Clear the contents and reset the state of the Lane.
void write (const value_type &element)
 Write a single element.
template<typename... Args>
void emplace (Args &&... args)
 Write a single element by constructing it.
void write (value_type &&element)
 Write a single element by moving it in.
void write (const value_type *elements, size_t n)
void move_write (value_type *elements, size_t n)
bool read (value_type &destination)
size_t read (value_type *destinations, size_t n)
size_t discard (size_t n)
 This method does the same thing as read(buffer, n) but discards the data.
void write_end ()
size_t capacity () const noexcept
size_t size () const
bool empty () const
bool is_end () const
 True when write_end() was called.
bool is_end_and_empty () const
 True when write_end() and the lane does not contain items.
void resize (size_t new_capacity)
 Change the capacity of the Lane.
void wait_for_empty ()
 Wait until this Lane is empty.

Private Types

enum  {
  status_normal ,
  status_end
}

Private Member Functions

size_t read_position () const noexcept
size_t free_read_space () const noexcept
template<typename T>
void write_generic (T *elements, size_t n)
 This is a template to allow const and non-const (to be able to move).
template<typename T>
void immediate_write (T *elements, size_t n) noexcept
 This is a template to allow const and non-const (to be able to move).
void immediate_read (value_type *elements, size_t n) noexcept
void immediate_discard (size_t n) noexcept

Private Attributes

Tp * _buffer
size_t _capacity
size_t _write_position
size_t _free_write_space
enum casacore::aocommon::Lane:: { ... }  _status
std::mutex _mutex
std::condition_variable _writing_possible_condition
std::condition_variable _reading_possible_condition

Detailed Description

template<typename Tp>
class casacore::aocommon::Lane< Tp >

The Lane is an efficient cyclic buffer that is synchronized.

A Lane can typically be used in a multi-threaded producer-consumer situation. The Lane also holds a state which allows for an ellegant way of communicating from producer(s) to consumer(s) that all data has been produced.

A simple example:

void producer(Lane<Task>* taskLane)
{
while(moreTasks)
taskLane->write(nextTask());
taskLane->write_end();
}
void consumer(Lane<Task>* taskLane)
{
Task task;
while(taskLane->read(task))
processTask(task);
}
void run()
{
Lane<Task> taskLane;
std::thread consumerThread(&consumer(), &taskLane);
producer(&taskLane);
consumerThread.join();
}
The Lane is an efficient cyclic buffer that is synchronized.
Definition Lane.h:100
void write(const value_type &element)
Write a single element.
Definition Lane.h:206
bool read(value_type &destination)
Definition Lane.h:289
Lane() noexcept
Construct a Lane with zero elements.
Definition Lane.h:116

The various read and write methods, as well as the empty(), capacity() and size() methods are always thread safe. The other methods are not: assignment, swap(), clear() and resize() can not be called from a different thread while another thread is also accessing the Lane. The same holds obviously for the constructors and destructor. This is chosen because these methods should almost never be called in parallel with other methods, and hence it is not worth to increase every call with extra locks to make this possible.

With one reader and one writer, the order is guaranteed to be consistent. With multiple readers or writers in combination with multi-element write or read functions, a sequence of symbols might be interrupted. For example, if a multi-element write() won't fit completely in the buffer, the thread will wait for free space. Another thread might get now write access first, causing the single call to the multi-element write to be "split up".

Author
Andre Offringa
Template Parameters
TpType of elements to be stored in the Lane.

Definition at line 100 of file Lane.h.

Member Typedef Documentation

◆ size_type

template<typename Tp>
typedef std::size_t casacore::aocommon::Lane< Tp >::size_type

Integer type used to store size types.

Definition at line 103 of file Lane.h.

◆ value_type

template<typename Tp>
typedef Tp casacore::aocommon::Lane< Tp >::value_type

Type of elements stored in the Lane.

Definition at line 106 of file Lane.h.

Member Enumeration Documentation

◆ anonymous enum

template<typename Tp>
anonymous enum
private
Enumerator
status_normal 
status_end 

Definition at line 443 of file Lane.h.

Constructor & Destructor Documentation

◆ Lane() [1/4]

template<typename Tp>
casacore::aocommon::Lane< Tp >::Lane ( )
inlinenoexcept

Construct a Lane with zero elements.

A Lane with zero elements can not be written to or read to (both operations will wait forever).

This constructor makes it easy to construct e.g. a container of Lanes. After the container is created, the Lanes can be resized with resize().

Definition at line 116 of file Lane.h.

References _buffer, _capacity, _free_write_space, _status, _write_position, and status_normal.

Referenced by Lane(), Lane(), operator=(), operator=(), and swap().

◆ Lane() [2/4]

template<typename Tp>
casacore::aocommon::Lane< Tp >::Lane ( size_t capacity)
inlineexplicit

Construct a Lane with the given capacity.

After construction, the Lane is ready for writing to and reading from.

Parameters
capacityNumber of elements that the Lane can hold at once.

Definition at line 128 of file Lane.h.

References _buffer, _capacity, _free_write_space, _status, _write_position, capacity(), and status_normal.

◆ Lane() [3/4]

template<typename Tp>
casacore::aocommon::Lane< Tp >::Lane ( const Lane< Tp > & source)
delete

References Lane().

◆ Lane() [4/4]

template<typename Tp>
casacore::aocommon::Lane< Tp >::Lane ( Lane< Tp > && source)
inlinenoexcept

Move construct a Lane.

This operation is not thread safe: the behaviour is undefined when other threads access the source Lane.

Parameters
sourceOriginal Lane to be moved from.

Definition at line 142 of file Lane.h.

References Lane(), status_normal, and swap().

◆ ~Lane()

template<typename Tp>
casacore::aocommon::Lane< Tp >::~Lane ( )
inline

Destructor.

The destructor is not synchronized.

Definition at line 154 of file Lane.h.

References _buffer, and LANE_REPORT_DEBUG_INFO.

Member Function Documentation

◆ capacity()

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::capacity ( ) const
inlinenoexcept

Definition at line 372 of file Lane.h.

References _capacity.

Referenced by Lane().

◆ clear()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::clear ( )
inlinenoexcept

Clear the contents and reset the state of the Lane.

After calling clear(), the Lane is in the same state as after construction. This also means that after clearing the Lane, it is as if write_end() has not been called yet.

This method is not thread safe.

Definition at line 191 of file Lane.h.

References _capacity, _free_write_space, _status, _write_position, and status_normal.

◆ discard()

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::discard ( size_t n)
inline

This method does the same thing as read(buffer, n) but discards the data.

This eliminates the requirement to specify a buffer if the data is not necessary anyway, and avoids a copy of the data.

Definition at line 339 of file Lane.h.

References _mutex, _reading_possible_condition, _status, free_read_space(), immediate_discard(), LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_READ_WAIT, and status_normal.

◆ emplace()

template<typename Tp>
template<typename... Args>
void casacore::aocommon::Lane< Tp >::emplace ( Args &&... args)
inline

Write a single element by constructing it.

This method is thread safe, and can be called together with other write and read methods from different threads.

If this call comes after a call to write_end(), the call will be ignored. The implementation does not construct the value in place, but rather constructs the value and then move assigns it. This is because the value that it is moved into has already been constructed (in the current implementation).

Parameters
elementObject to be moved into the cyclic buffer.

Now that there is less free write space, there is more free read space and thus readers can possibly continue.

Definition at line 236 of file Lane.h.

References _buffer, _capacity, _free_write_space, _mutex, _reading_possible_condition, _status, _write_position, _writing_possible_condition, LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_WRITE_WAIT, and status_normal.

◆ empty()

template<typename Tp>
bool casacore::aocommon::Lane< Tp >::empty ( ) const
inline

Definition at line 379 of file Lane.h.

References _capacity, _free_write_space, and _mutex.

◆ free_read_space()

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::free_read_space ( ) const
inlineprivatenoexcept

Definition at line 454 of file Lane.h.

References _capacity, and _free_write_space.

Referenced by discard(), read(), and read().

◆ immediate_discard()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::immediate_discard ( size_t n)
inlineprivatenoexcept

Now that there is more free write space, writers can possibly continue.

Definition at line 543 of file Lane.h.

References _free_write_space, and _writing_possible_condition.

Referenced by discard().

◆ immediate_read()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::immediate_read ( value_type * elements,
size_t n )
inlineprivatenoexcept

As with write, split in two ranges if needed. The first range fits in [read_position(), _capacity), the second range in [0, end).

Now that there is more free write space, writers can possibly continue.

Definition at line 515 of file Lane.h.

References _buffer, _capacity, _free_write_space, _writing_possible_condition, and read_position().

Referenced by read().

◆ immediate_write()

template<typename Tp>
template<typename T>
void casacore::aocommon::Lane< Tp >::immediate_write ( T * elements,
size_t n )
inlineprivatenoexcept

This is a template to allow const and non-const (to be able to move).

Split the writing in two ranges if needed. The first range fits in [_write_position, _capacity), the second range in [0, end). By doing so, we only have to calculate the modulo in the write position once.

Now that there is less free write space, there is more free read space and thus readers may continue.

Definition at line 486 of file Lane.h.

References _buffer, _capacity, _free_write_space, _reading_possible_condition, and _write_position.

Referenced by write_generic().

◆ is_end()

template<typename Tp>
bool casacore::aocommon::Lane< Tp >::is_end ( ) const
inline

True when write_end() was called.

Even when end, the lane may still contain items.

Definition at line 388 of file Lane.h.

References _mutex, _status, and status_end.

◆ is_end_and_empty()

template<typename Tp>
bool casacore::aocommon::Lane< Tp >::is_end_and_empty ( ) const
inline

True when write_end() and the lane does not contain items.

Definition at line 396 of file Lane.h.

References _capacity, _free_write_space, _mutex, _status, and status_end.

◆ move_write()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::move_write ( value_type * elements,
size_t n )
inline

Definition at line 285 of file Lane.h.

References write_generic().

◆ operator=() [1/2]

template<typename Tp>
Lane< Tp > & casacore::aocommon::Lane< Tp >::operator= ( const Lane< Tp > & source)
delete

References Lane().

◆ operator=() [2/2]

template<typename Tp>
Lane< Tp > & casacore::aocommon::Lane< Tp >::operator= ( Lane< Tp > && source)
inlinenoexcept

Move assignment.

This operation is not thread safe: the behaviour is undefined when other threads access the source Lane.

Parameters
sourceOriginal Lane to be moved from.
Returns
This Lane.

Definition at line 167 of file Lane.h.

References Lane(), and swap().

◆ read() [1/2]

template<typename Tp>
bool casacore::aocommon::Lane< Tp >::read ( value_type & destination)
inline

Now that there is more free write space, writers can possibly continue.

Definition at line 289 of file Lane.h.

References _buffer, _free_write_space, _mutex, _reading_possible_condition, _status, _writing_possible_condition, free_read_space(), LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_READ_WAIT, read_position(), and status_normal.

◆ read() [2/2]

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::read ( value_type * destinations,
size_t n )
inline

◆ read_position()

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::read_position ( ) const
inlineprivatenoexcept

Definition at line 450 of file Lane.h.

References _capacity, _free_write_space, and _write_position.

Referenced by immediate_read(), and read().

◆ resize()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::resize ( size_t new_capacity)
inline

Change the capacity of the Lane.

This will erase all data in the Lane, and clear the state.

Definition at line 405 of file Lane.h.

References _buffer, _capacity, _free_write_space, _status, _write_position, and status_normal.

◆ size()

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::size ( ) const
inline

Definition at line 374 of file Lane.h.

References _capacity, _free_write_space, and _mutex.

◆ swap()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::swap ( Lane< Tp > & other)
inlinenoexcept

Swap the contents of this Lane with another.

This operation is not thread safe: the behaviour is undefined when other threads access either Lane.

Definition at line 176 of file Lane.h.

References _buffer, _capacity, _free_write_space, _status, _write_position, and Lane().

Referenced by Lane(), and operator=().

◆ wait_for_empty()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::wait_for_empty ( )
inline

Wait until this Lane is empty.

Definition at line 418 of file Lane.h.

References _capacity, _free_write_space, _mutex, and _writing_possible_condition.

◆ write() [1/3]

template<typename Tp>
void casacore::aocommon::Lane< Tp >::write ( const value_type & element)
inline

Write a single element.

This method is thread safe, and can be called together with other write and read methods from different threads.

If this call comes after a call to write_end(), the call will be ignored. If a write_end() call comes during write(), the write() call is aborted and returns immediately.

Parameters
elementObject to be copied into the cyclic buffer.

Now that there is less free write space, there is more free read space and thus readers may continue.

Definition at line 206 of file Lane.h.

References _buffer, _capacity, _free_write_space, _mutex, _reading_possible_condition, _status, _write_position, _writing_possible_condition, LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_WRITE_WAIT, and status_normal.

◆ write() [2/3]

template<typename Tp>
void casacore::aocommon::Lane< Tp >::write ( const value_type * elements,
size_t n )
inline

Definition at line 281 of file Lane.h.

References write_generic().

◆ write() [3/3]

template<typename Tp>
void casacore::aocommon::Lane< Tp >::write ( value_type && element)
inline

Write a single element by moving it in.

This method is thread safe, and can be called together with other write and read methods from different threads.

If this call comes after a call to write_end(), the call will be ignored.

Parameters
elementObject to be moved into the cyclic buffer.

Now that there is less free write space, there is more free read space and thus readers can possibly continue.

Definition at line 263 of file Lane.h.

References _buffer, _capacity, _free_write_space, _mutex, _reading_possible_condition, _status, _write_position, _writing_possible_condition, LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_WRITE_WAIT, and status_normal.

◆ write_end()

template<typename Tp>
void casacore::aocommon::Lane< Tp >::write_end ( )
inline

◆ write_generic()

template<typename Tp>
template<typename T>
void casacore::aocommon::Lane< Tp >::write_generic ( T * elements,
size_t n )
inlineprivate

This is a template to allow const and non-const (to be able to move).

Definition at line 460 of file Lane.h.

References _free_write_space, _mutex, _status, _writing_possible_condition, immediate_write(), LANE_REGISTER_DEBUG_INFO, LANE_REGISTER_DEBUG_WRITE_WAIT, and status_normal.

Referenced by move_write(), and write().

Member Data Documentation

◆ _buffer

template<typename Tp>
Tp* casacore::aocommon::Lane< Tp >::_buffer
private

Definition at line 435 of file Lane.h.

Referenced by emplace(), immediate_read(), immediate_write(), Lane(), Lane(), read(), resize(), swap(), write(), write(), and ~Lane().

◆ _capacity

◆ _free_write_space

◆ _mutex

template<typename Tp>
std::mutex casacore::aocommon::Lane< Tp >::_mutex
mutableprivate

◆ _reading_possible_condition

template<typename Tp>
std::condition_variable casacore::aocommon::Lane< Tp >::_reading_possible_condition
private

Definition at line 448 of file Lane.h.

Referenced by discard(), emplace(), immediate_write(), read(), read(), write(), write(), and write_end().

◆ []

◆ _write_position

template<typename Tp>
size_t casacore::aocommon::Lane< Tp >::_write_position
private

Definition at line 439 of file Lane.h.

Referenced by clear(), emplace(), immediate_write(), Lane(), Lane(), read_position(), resize(), swap(), write(), and write().

◆ _writing_possible_condition

template<typename Tp>
std::condition_variable casacore::aocommon::Lane< Tp >::_writing_possible_condition
private

The documentation for this class was generated from the following file: