📨 chic 0.0.0
Realtime-safe channels in C
Loading...
Searching...
No Matches
spmc.h File Reference

Single-producer, multiple-consumer channel. More...

#include "claim.h"

Go to the source code of this file.

Macros

#define make_spmc(N, T)
 Convenience macro for allocating a new spmc.
#define sizeof_spmc(N, T)
 Convenience macro for calculating the size of a spmc with certain parameters.
#define spmc_send1(C, SRC)
 Convenience macro for sending a single item to a channel.
#define spmc_nbsend1(C, SRC)
 Convenience macro for sending a single item to a channel.
#define spmc_recv1(C, DST)
 Convenience macro for receiving a single item from a channel.
#define spmc_nbrecv1(C, DST)
 Convenience macro for receiving a single item from a channel.

Functions

size_t spmc_open (void *c, size_t nel, size_t elsize)
 Constructs a spmc in-place, or calculates the needed allocation size for one.
struct spmcspmc_alloc (size_t nel, size_t elsize)
 Allocates a new spmc using malloc() and opens it.
bool spmc_close (struct spmc *c)
 Closes a channel, forbidding any future send operations on it.
size_t spmc_nel (struct spmc *c)
 Gets the maximim number of elements a channel is capable of holding at once.
bool spmc_send_init (struct spmc *c, size_t n, struct claim *s)
 Claims space in the channel to be manually written into.
size_t spmc_send_nbinit (struct spmc *c, size_t n, struct claim *s)
 Claims up to an amount of space in the channel to be manually written into.
bool spmc_send_fini (struct spmc *c, struct claim *s)
 Commits a claim, indicating the item slots within have been written to and are ready to be received.
bool spmc_send (struct spmc *restrict c, size_t n, void *restrict src)
 Sends items to a channel.
size_t spmc_nbsend (struct spmc *restrict c, size_t n, void *restrict src)
 Sends whatever items will fit to a channel.
bool spmc_sendv (struct spmc *restrict c, size_t n,...)
 Sends items to a channel.
size_t spmc_nbsendv (struct spmc *restrict c, size_t n,...)
 Sends whatever items will fit to a channel.
bool spmc_recv_init (struct spmc *c, size_t n, struct claim *r)
 Claims space in the channel to be manually read from.
size_t spmc_recv_nbinit (struct spmc *c, size_t n, struct claim *r)
 Claims up to an amount of space in the channel to be manually read from.
bool spmc_recv_fini (struct spmc *c, struct claim *r)
 Commits a claim, indicating the item slots within have been read from and are ready to be overwritten.
bool spmc_recv_nbfini (struct spmc *c, struct claim *r)
 Tries to commit a claim, indicating the item slots within have been read from and are safe to be overwritten.
bool spmc_recv (struct spmc *restrict c, size_t n, void *restrict dst)
 Receives items from a channel.
size_t spmc_nbrecv (struct spmc *restrict c, size_t n, void *restrict dst)
 Receives whatever items are available from a channel.
bool spmc_recvv (struct spmc *restrict c, size_t n,...)
 Receives items from a channel.
size_t spmc_nbrecvv (struct spmc *restrict c, size_t n,...)
 Receives whatever items are available from a channel.

Detailed Description

Single-producer, multiple-consumer channel.

Author
Fawn rubie.nosp@m.fawn.nosp@m.@gmai.nosp@m.l.co.nosp@m.m
Date
2026

Macro Definition Documentation

◆ make_spmc

#define make_spmc ( N,
T )
Value:
spmc_alloc((N), sizeof(T))
struct spmc * spmc_alloc(size_t nel, size_t elsize)
Allocates a new spmc using malloc() and opens it.

Convenience macro for allocating a new spmc.

Parameters
NThe capacity of the channel; must be a nonzero power of 2
TThe type of a channel element
See also
spmc_alloc

◆ sizeof_spmc

#define sizeof_spmc ( N,
T )
Value:
spmc_open(NULL, (N), sizeof(T))
size_t spmc_open(void *c, size_t nel, size_t elsize)
Constructs a spmc in-place, or calculates the needed allocation size for one.

Convenience macro for calculating the size of a spmc with certain parameters.

Parameters
NThe capacity of the channel; must be a nonzero power of 2
TThe type of a channel element
See also
spmc_open

◆ spmc_nbrecv1

#define spmc_nbrecv1 ( C,
DST )
Value:
spmc_nbrecv((C), 1, (DST))
size_t spmc_nbrecv(struct spmc *restrict c, size_t n, void *restrict dst)
Receives whatever items are available from a channel.

Convenience macro for receiving a single item from a channel.

See also
spmc_nbrecv

◆ spmc_nbsend1

#define spmc_nbsend1 ( C,
SRC )
Value:
spmc_nbsend((C), 1, (SRC))
size_t spmc_nbsend(struct spmc *restrict c, size_t n, void *restrict src)
Sends whatever items will fit to a channel.

Convenience macro for sending a single item to a channel.

See also
spmc_nbsend

◆ spmc_recv1

#define spmc_recv1 ( C,
DST )
Value:
spmc_recv((C), 1, (DST))
bool spmc_recv(struct spmc *restrict c, size_t n, void *restrict dst)
Receives items from a channel.

Convenience macro for receiving a single item from a channel.

See also
spmc_recv

◆ spmc_send1

#define spmc_send1 ( C,
SRC )
Value:
spmc_send((C), 1, (SRC))
bool spmc_send(struct spmc *restrict c, size_t n, void *restrict src)
Sends items to a channel.

Convenience macro for sending a single item to a channel.

See also
spmc_send

Function Documentation

◆ spmc_alloc()

struct spmc * spmc_alloc ( size_t nel,
size_t elsize )

Allocates a new spmc using malloc() and opens it.

Parameters
nelThe minimum number of elements the channel should be able to hold; must be a nonzero power of 2
elsizeThe sizeof the type of a channel element
Returns
An owning pointer to a new spmc allocated using malloc(), or nil if there was an error. If nil is returned, errno is set to indicate the reason why.
Exceptions
EINVALif nel is 0, or if elsize is 0 or not a power of 2
ENOMEMif out of memory
See also
spmc_open

◆ spmc_close()

bool spmc_close ( struct spmc * c)

Closes a channel, forbidding any future send operations on it.

Parameters
cThe channel to close; must be non-nil
Returns
Whether or not the channel is ready to be deallocated. If false is returned, errno is set to indicate the reason why.
Exceptions
EBUSYif chan has unreceived items
Warning
Calling this function on any other thread other than the sole producer risks interrupting a pending send operation.

◆ spmc_nbrecv()

size_t spmc_nbrecv ( struct spmc *restrict c,
size_t n,
void *restrict dst )

Receives whatever items are available from a channel.

Parameters
cThe channel to receive items from; must be non-nil
nThe number of items to receive
dstWhere to receive the items into
Returns
How many items were received. If 0, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c, or if dst is nil
ENOMSGif there is nothing to receive from the channel
EPIPEif chan is closed and there are no more items to receive

◆ spmc_nbrecvv()

size_t spmc_nbrecvv ( struct spmc *restrict c,
size_t n,
... )

Receives whatever items are available from a channel.

Parameters
cThe channel to receive items from; must be non-nil
nThe number of items to receive
...Where to receive the items into
Returns
How many items were received. If 0, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c
ENOMSGif there is nothing to receive from the channel
EPIPEif chan is closed and there are no more items to receive

◆ spmc_nbsend()

size_t spmc_nbsend ( struct spmc *restrict c,
size_t n,
void *restrict src )

Sends whatever items will fit to a channel.

If the channel has less than n available item slots for writing, this function will send whatever items will fit. If there is no space available, this function will return 0.

Parameters
cThe channel to try to send items to; must be non-nil
nThe maximum number of items to try to send
srcWhere to send the items from
Returns
How many items were sent. If 0, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c, or if src is nil
ENOBUFSif there is no room in the channel
EPIPEif chan is closed and can no longer be sent to

◆ spmc_nbsendv()

size_t spmc_nbsendv ( struct spmc *restrict c,
size_t n,
... )

Sends whatever items will fit to a channel.

If the channel has less than n available item slots for writing, this function will send whatever items will fit. If there is no space available, this function will return 0.

Parameters
cThe channel to try to send items to; must be non-nil
nThe maximum number of items to try to send
...Pointers to the items to send
Returns
How many items were sent. If 0, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c
ENOBUFSif there is no room in the channel
EPIPEif chan is closed and can no longer be sent to

◆ spmc_nel()

size_t spmc_nel ( struct spmc * c)

Gets the maximim number of elements a channel is capable of holding at once.

Parameters
cThe channel to get the capacity of; must be non-nil
Returns
The capacity of c

◆ spmc_open()

size_t spmc_open ( void * c,
size_t nel,
size_t elsize )

Constructs a spmc in-place, or calculates the needed allocation size for one.

Parameters
[out]cThe address at which to construct a spmc; may be nil
[in]nelThe number of elements the channel can hold; must be a nonzero power of 2
[in]elsizeThe sizeof the type of an element
Returns
The allocation size necessary to construct a spmc with these parameters (if c was not nil, the size of the constructed spmc). If there was an error, returns 0. If 0 is returned, errno is set to indicate the reason why.
Exceptions
EINVALif nel is 0, or if elsize is 0 or not a power of 2

◆ spmc_recv()

bool spmc_recv ( struct spmc *restrict c,
size_t n,
void *restrict dst )

Receives items from a channel.

If the channel does not have n or more available items ready to be received, this function will busy-wait until there are.

Parameters
cThe channel to receive items from; must be non-nil
nThe number of items to receive
dstWhere to receive the items into
Returns
Whether or not the items were received. If false, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c, or if dst is nil
EPIPEif chan is closed and there are less than n items remaining to receive

◆ spmc_recvv()

bool spmc_recvv ( struct spmc *restrict c,
size_t n,
... )

Receives items from a channel.

If the channel does not have n or more available items ready to be received, this function will busy-wait until there are.

Parameters
cThe channel to receive items from; must be non-nil
nThe number of items to receive
...Where to receive the items into
Returns
Whether or not the items were received. If false, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c
EPIPEif chan is closed and there are less than n items remaining to receive

◆ spmc_send()

bool spmc_send ( struct spmc *restrict c,
size_t n,
void *restrict src )

Sends items to a channel.

If the channel does not have enough free space to send all n items, this function will busy-wait until there are.

Parameters
cThe channel to send items to; must be non-nil
nThe number of items to send
srcWhere to send the items from
Returns
Whether or not the items were sent. If false, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c, or if src is nil
EPIPEif chan is closed and can no longer be sent to

◆ spmc_sendv()

bool spmc_sendv ( struct spmc *restrict c,
size_t n,
... )

Sends items to a channel.

If the channel does not have enough free space to send all n items, this function will busy-wait until there are.

Parameters
cThe channel to send items to; must be non-nil
nThe number of items to send
...Pointers to the items to send
Returns
Whether or not the items were sent. If false, errno is set to indicate the reason why.
Exceptions
EINVALif n is not within the range [0, nel], where nel is the capacity of c
EPIPEif chan is closed and can no longer be sent to