Lely core libraries  2.2.5
spscring.h File Reference

This header file is part of the utilities library; it contains the single-producer, single-consumer ring buffer declarations. More...

#include <lely/features.h>
#include <lely/libc/stdatomic.h>
#include <stddef.h>
Include dependency graph for spscring.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  spscring
 A single-producer, single-consumer ring buffer. More...
 

Macros

#define SPSCRING_INIT(size)
 The static initializer for spscring.
 

Functions

void spscring_init (struct spscring *ring, size_t size)
 Initializes a single-producer, single-consumer ring buffer with the specified size.
 
size_t spscring_size (const struct spscring *ring)
 Returns the size of a single-producer, single-consumer ring buffer.
 
size_t spscring_p_capacity (struct spscring *ring)
 Returns the total capacity available for a producer in a single-producer single-consumer ring buffer, including wrapping. More...
 
size_t spscring_p_capacity_no_wrap (struct spscring *ring)
 Returns the total capacity available for a producer in a single-producer single-consumer ring buffer, without wrapping. More...
 
size_t spscring_p_alloc (struct spscring *ring, size_t *psize)
 Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for writing. More...
 
size_t spscring_p_alloc_no_wrap (struct spscring *ring, size_t *psize)
 Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer ring buffer for writing. More...
 
size_t spscring_p_commit (struct spscring *ring, size_t size)
 Makes the specified number of indices available to a consumer and, if this satisfies a wait operation registered by the consumer, invokes the consumer signal function . More...
 
int spscring_p_submit_wait (struct spscring *ring, size_t size, void(*func)(struct spscring *ring, void *arg), void *arg)
 Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for writing and, if not, registers a signal function to be invoked once the requested range becomes available. More...
 
int spscring_p_abort_wait (struct spscring *ring)
 Aborts a wait operation previously registered with spscring_p_submit_wait(). More...
 
size_t spscring_c_capacity (struct spscring *ring)
 Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer, including wrapping. More...
 
size_t spscring_c_capacity_no_wrap (struct spscring *ring)
 Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer, without wrapping. More...
 
size_t spscring_c_alloc (struct spscring *ring, size_t *psize)
 Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for reading. More...
 
size_t spscring_c_alloc_no_wrap (struct spscring *ring, size_t *psize)
 Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer ring buffer for reading. More...
 
size_t spscring_c_commit (struct spscring *ring, size_t size)
 Makes the specified number of indices available to a producer and, if this satisfies a wait operation registered by the producer, invokes the producer signal function . More...
 
int spscring_c_submit_wait (struct spscring *ring, size_t size, void(*func)(struct spscring *ring, void *arg), void *arg)
 Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for reading and, if not, registers a signal function to be invoked once the requested range becomes available. More...
 
int spscring_c_abort_wait (struct spscring *ring)
 Aborts a wait operation previously registered with spscring_c_submit_wait(). More...
 

Detailed Description

This header file is part of the utilities library; it contains the single-producer, single-consumer ring buffer declarations.

To make the ring buffer generic, a low-level interface is provided which only operates on buffer indices. The user is responsible for reading or writing values to an actual memory buffer (or file).

The implementation allows both the producer and consumer to register a signal function which is invoked once a requested number of indices becomes available for reading or writing. This enables the user to implement blocking read or write operations.

All ring buffer operations are lock-free, provided the user-defined signal functions are lock-free. If no signal functions are registered, the operations are also wait-free.

Author
J. S. Seldenthuis jseld.nosp@m.enth.nosp@m.uis@l.nosp@m.ely..nosp@m.com

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Definition in file spscring.h.

Function Documentation

◆ spscring_p_capacity()

size_t spscring_p_capacity ( struct spscring ring)

Returns the total capacity available for a producer in a single-producer single-consumer ring buffer, including wrapping.

A subsequent call to spscring_p_alloc() with a size smaller than or equal to the reported capacity is guaranteed to succeed.

This function is wait-free. It MUST NOT be invoked by a consumer or by more than one concurrent producer.

Returns
the total number of indices available for writing.

Definition at line 65 of file spscring.c.

◆ spscring_p_capacity_no_wrap()

size_t spscring_p_capacity_no_wrap ( struct spscring ring)

Returns the total capacity available for a producer in a single-producer single-consumer ring buffer, without wrapping.

A subsequent call to spscring_p_alloc_no_wrap() with a size smaller than or equal to the reported capacity is guaranteed to succeed.

This function is wait-free. It MUST NOT be invoked by a consumer or by more than one concurrent producer.

Returns
the total number of indices available for writing.

Definition at line 83 of file spscring.c.

◆ spscring_p_alloc()

size_t spscring_p_alloc ( struct spscring ring,
size_t *  psize 
)

Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for writing.

The indices are not made available to the consumer until a call to spscring_p_commit(). Without an intervening call to spscring_p_commit(), this function is idempotent.

This function is wait-free. It MUST NOT be invoked by a consumer or by more than one concurrent producer.

Parameters
ringa pointer to a ring buffer.
psizea pointer to a value which, on input, contains the requested number of indices. If fewer indices are available, *psize is updated on output to contain the actual number of indices available for writing.
Returns
the first index available for writing.

Definition at line 98 of file spscring.c.

◆ spscring_p_alloc_no_wrap()

size_t spscring_p_alloc_no_wrap ( struct spscring ring,
size_t *  psize 
)

Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer ring buffer for writing.

The indices are not made available to the consumer until a call to spscring_p_commit(). Without an intervening call to spscring_p_commit(), this function is idempotent.

This function is wait-free. It MUST NOT be invoked by a consumer or by more than one concurrent producer.

Parameters
ringa pointer to a ring buffer.
psizea pointer to a value which, on input, contains the requested number of indices. If fewer indices are available, *psize is updated on output to contain the actual number of indices available for writing.
Returns
the first index available for writing.

Definition at line 118 of file spscring.c.

◆ spscring_p_commit()

size_t spscring_p_commit ( struct spscring ring,
size_t  size 
)

Makes the specified number of indices available to a consumer and, if this satisfies a wait operation registered by the consumer, invokes the consumer signal function .

size MUST not exceed the range obtained from a preceding call to spscring_p_alloc() or spscring_p_alloc_no_wrap(). However, it is possible to incrementally commit a range of indices without invoking spscring_p_alloc() or spscring_p_alloc_no_wrap() again.

This function is wait-free, unless the consumer has registered a wait, in which case it is lock-free if, and only if, the consumer signal function is lock-free. This function MUST NOT be invoked by a consumer or by more than one concurrent producer.

Returns
the first index available for writing.

Definition at line 138 of file spscring.c.

◆ spscring_p_submit_wait()

int spscring_p_submit_wait ( struct spscring ring,
size_t  size,
void(*)(struct spscring *ring, void *arg)  func,
void *  arg 
)

Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for writing and, if not, registers a signal function to be invoked once the requested range becomes available.

This function is lock-free. It MAY busy-wait while aborting a previous wait operation with spscring_p_abort_wait(). This function MUST NOT be invoked by a consumer or by more than one concurrent producer.

Parameters
ringa pointer to a ring buffer.
sizethe number of indices available for writing before the wait condition is satisfied.
functhe signal function to be invoked when the wait condition is satisfied.
argthe user-specific value to be passed as the second argument to func.
Returns
1 if the wait operation was submitted, and 0 if the wait condition was already satisfied and requested number of indices are available. In the latter case, the signal function is not invoked.

Definition at line 163 of file spscring.c.

◆ spscring_p_abort_wait()

int spscring_p_abort_wait ( struct spscring ring)

Aborts a wait operation previously registered with spscring_p_submit_wait().

This function is lock-free. It MAY busy-wait while spscring_c_commit() is reading the function pointer and argument of an ongoing wait. This function MUST NOT be invoked by a consumer or by more than one concurrent producer.

Returns
1 if a wait operation was canceled, and 0 if no wait operation was registered.

Definition at line 204 of file spscring.c.

◆ spscring_c_capacity()

size_t spscring_c_capacity ( struct spscring ring)

Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer, including wrapping.

A subsequent call to spscring_c_alloc() with a size smaller than or equal to the reported capacity is guaranteed to succeed.

This function is wait-free. It MUST NOT be invoked by a producer or by more than one concurrent consumer.

Returns
the total number of indices available for writing.

Definition at line 229 of file spscring.c.

◆ spscring_c_capacity_no_wrap()

size_t spscring_c_capacity_no_wrap ( struct spscring ring)

Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer, without wrapping.

A subsequent call to spscring_c_alloc_no_wrap() with a size smaller than or equal to the reported capacity is guaranteed to succeed.

This function is wait-free. It MUST NOT be invoked by a producer or by more than one concurrent consumer.

Returns
the total number of indices available for writing.

Definition at line 247 of file spscring.c.

◆ spscring_c_alloc()

size_t spscring_c_alloc ( struct spscring ring,
size_t *  psize 
)

Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for reading.

The indices are not made available to the producer until a call to spscring_c_commit(). Without an intervening call to spscring_c_commit(), this function is idempotent.

This function is wait-free. It MUST NOT be invoked by a producer or by more than one concurrent consumer.

Parameters
ringa pointer to a ring buffer.
psizea pointer to a value which, on input, contains the requested number of indices. If fewer indices are available, *psize is updated on output to contain the actual number of indices available for reading.
Returns
the first index available for reading.

Definition at line 262 of file spscring.c.

◆ spscring_c_alloc_no_wrap()

size_t spscring_c_alloc_no_wrap ( struct spscring ring,
size_t *  psize 
)

Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer ring buffer for reading.

The indices are not made available to the producer until a call to spscring_c_commit(). Without an intervening call to spscring_c_commit(), this function is idempotent.

This function is wait-free. It MUST NOT be invoked by a producer or by more than one concurrent consumer.

Parameters
ringa pointer to a ring buffer.
psizea pointer to a value which, on input, contains the requested number of indices. If fewer indices are available, *psize is updated on output to contain the actual number of indices available for reading.
Returns
the first index available for reading.

Definition at line 282 of file spscring.c.

◆ spscring_c_commit()

size_t spscring_c_commit ( struct spscring ring,
size_t  size 
)

Makes the specified number of indices available to a producer and, if this satisfies a wait operation registered by the producer, invokes the producer signal function .

size MUST not exceed the range obtained from a preceding call to spscring_c_alloc() or spscring_c_alloc_no_wrap(). However, it is possible to incrementally commit a range of indices without invoking spscring_c_alloc() or spscring_c_alloc_no_wrap() again.

This function is wait-free, unless the producer has registered a wait, in which case it is lock-free if, and only if, the producer signal function is lock-free. This function MUST NOT be invoked by a producer or by more than one concurrent consumer.

Returns
the first index available for reading.

Definition at line 302 of file spscring.c.

◆ spscring_c_submit_wait()

int spscring_c_submit_wait ( struct spscring ring,
size_t  size,
void(*)(struct spscring *ring, void *arg)  func,
void *  arg 
)

Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for reading and, if not, registers a signal function to be invoked once the requested range becomes available.

This function is lock-free. It MAY busy-wait while aborting a previous wait operation with spscring_c_abort_wait(). This function MUST NOT be invoked by a producer or by more than one concurrent consumer.

Parameters
ringa pointer to a ring buffer.
sizethe number of indices available for reading before the wait condition is satisfied.
functhe signal function to be invoked when the wait condition is satisfied.
argthe user-specific value to be passed as the second argument to func.
Returns
1 if the wait operation was submitted, and 0 if the wait condition was already satisfied and requested number of indices are available. In the latter case, the signal function is not invoked.

Definition at line 327 of file spscring.c.

◆ spscring_c_abort_wait()

int spscring_c_abort_wait ( struct spscring ring)

Aborts a wait operation previously registered with spscring_c_submit_wait().

This function is lock-free. It MAY busy-wait while spscring_p_commit() is reading the function pointer and argument of an ongoing wait. This function MUST NOT be invoked by a producer or by more than one concurrent consumer.

Returns
1 if a wait operation was canceled, and 0 if no wait operation was registered.

Definition at line 368 of file spscring.c.