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

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

#include "claim.h"
#include "err.h"

Go to the source code of this file.

Macros

#define make_mpmc(N, T)
 Convenience macro for allocating a new mpmc.
#define sizeof_mpmc(N, T)
 Convenience macro for calculating the size of a mpmc with certain parameters.
#define mpmc_send1(C, SRC)
 Convenience macro for sending a single item to a channel.
#define mpmc_nbsend1(C, SRC)
 Convenience macro for sending a single item to a channel.
#define mpmc_recv1(C, DST)
 Convenience macro for receiving a single item from a channel.
#define mpmc_nbrecv1(C, DST)
 Convenience macro for receiving a single item from a channel.

Functions

size_t mpmc_open (void *c, size_t nel, size_t elsize)
 Constructs a mpmc in-place, or calculates the needed allocation size for one.
struct mpmcmpmc_alloc (size_t nel, size_t elsize)
 Allocates a new mpmc using malloc() and opens it.
enum chic_err mpmc_close (struct mpmc *c)
 Closes a channel, forbidding any future send operations on it.
size_t mpmc_nel (struct mpmc *c)
 Gets the maximim number of elements a channel is capable of holding at once.
enum chic_err mpmc_send_init (struct mpmc *c, size_t n, struct claim *s)
 Claims space in the channel to be manually written into.
enum chic_err mpmc_send_nbinit (struct mpmc *c, size_t n, struct claim *s)
 Claims up to an amount of space in the channel to be manually written into.
void mpmc_send_fini (struct mpmc *c, struct claim *s)
 Commits a claim, indicating the item slots within are finished being written to and are ready to be received.
enum chic_err mpmc_send_nbfini (struct mpmc *c, struct claim *s)
 Tries to commit a claim, indicating the item slots within have been written to and are ready to be received.
enum chic_err mpmc_send (struct mpmc *restrict c, size_t n, void *restrict src)
 Sends items to a channel.
enum chic_err mpmc_nbsend (struct mpmc *restrict c, size_t n, size_t *restrict n2, void *restrict src)
 Sends whatever items will fit to a channel.
enum chic_err mpmc_sendv (struct mpmc *restrict c, size_t n,...)
 Sends items to a channel.
enum chic_err mpmc_nbsendv (struct mpmc *restrict c, size_t n, size_t *restrict n2,...)
 Sends whatever items will fit to a channel.
enum chic_err mpmc_recv_init (struct mpmc *c, size_t n, struct claim *r)
 Claims space in the channel to be manually read from.
enum chic_err mpmc_recv_nbinit (struct mpmc *c, size_t n, struct claim *r)
 Claims up to an amount of space in the channel to be manually read from.
void mpmc_recv_fini (struct mpmc *c, struct claim *r)
 Commits a claim, indicating the item slots within have been read from and are ready to be overwritten.
enum chic_err mpmc_recv_nbfini (struct mpmc *c, struct claim *r)
 Tries to commit a claim, indicating the item slots within have been read from and are safe to be overwritten.
enum chic_err mpmc_recv (struct mpmc *restrict c, size_t n, void *restrict dst)
 Receives items from a channel.
enum chic_err mpmc_nbrecv (struct mpmc *restrict c, size_t n, size_t *restrict n2, void *restrict dst)
 Receives whatever items are available from a channel.
enum chic_err mpmc_recvv (struct mpmc *restrict c, size_t n,...)
 Receives items from a channel.
enum chic_err mpmc_nbrecvv (struct mpmc *restrict c, size_t n, size_t *restrict n2,...)
 Receives whatever items are available from a channel.

Detailed Description

Multiple-producer, multiple-consumer channel.

Author
Fawn rubie.nosp@m.fawn.nosp@m.@prot.nosp@m.on.m.nosp@m.e
Date
2026

Macro Definition Documentation

◆ make_mpmc

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

Convenience macro for allocating a new mpmc.

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

◆ mpmc_nbrecv1

#define mpmc_nbrecv1 ( C,
DST )
Value:
mpmc_nbrecv((C), 1, NULL, (DST))
enum chic_err mpmc_nbrecv(struct mpmc *restrict c, size_t n, size_t *restrict n2, void *restrict dst)
Receives whatever items are available from a channel.

Convenience macro for receiving a single item from a channel.

See also
mpmc_nbrecv

◆ mpmc_nbsend1

#define mpmc_nbsend1 ( C,
SRC )
Value:
mpmc_nbsend((C), 1, NULL, (SRC))
enum chic_err mpmc_nbsend(struct mpmc *restrict c, size_t n, size_t *restrict n2, void *restrict src)
Sends whatever items will fit to a channel.

Convenience macro for sending a single item to a channel.

See also
mpmc_nbsend

◆ mpmc_recv1

#define mpmc_recv1 ( C,
DST )
Value:
mpmc_recv((C), 1, (DST))
enum chic_err mpmc_recv(struct mpmc *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
mpmc_recv

◆ mpmc_send1

#define mpmc_send1 ( C,
SRC )
Value:
mpmc_send((C), 1, (SRC))
enum chic_err mpmc_send(struct mpmc *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
mpmc_send

◆ sizeof_mpmc

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

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

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

Function Documentation

◆ mpmc_alloc()

struct mpmc * mpmc_alloc ( size_t nel,
size_t elsize )

Allocates a new mpmc 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 mpmc allocated using malloc(), or nil if nel is 0, or if elsize is 0 or not a power of 2, or if the memory allocation could not be made.
Exceptions
ENOMEMif out of memory, as set by malloc()
See also
mpmc_open

◆ mpmc_close()

enum chic_err mpmc_close ( struct mpmc * c)

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

Parameters
cThe channel to close; must be non-nil
Returns
CHIC_OK if c is ready to be deallocated
CHIC_CHAN_UNREAD if c has unreceived items

◆ mpmc_nbrecv()

enum chic_err mpmc_nbrecv ( struct mpmc *restrict c,
size_t n,
size_t *restrict n2,
void *restrict dst )

Receives whatever items are available from a channel.

Parameters
[in]cThe channel to receive items from; must be non-nil
[in]nThe number of items to receive
[out]n2If non-nil, will be incremented by the number of items that were actually received
[out]dstWhere to receive the items into
Returns
CHIC_OK if one or more items were successfully received
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c, or if dst is nil
CHIC_CHAN_EMPTY if there is nothing to receive from the channel
CHIC_CHAN_CLOSED if chan is closed and there are no more items to receive

◆ mpmc_nbrecvv()

enum chic_err mpmc_nbrecvv ( struct mpmc *restrict c,
size_t n,
size_t *restrict n2,
... )

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
[out]n2If non-nil, will be incremented by the number of items that were actually received
...Where to receive the items into
Returns
CHIC_OK if one or more items were successfully received
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c
CHIC_CHAN_EMPTY if there is nothing to receive from the channel
CHIC_CHAN_CLOSED if chan is closed and there are no more items to receive

◆ mpmc_nbsend()

enum chic_err mpmc_nbsend ( struct mpmc *restrict c,
size_t n,
size_t *restrict n2,
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
[in]cThe channel to try to send items to; must be non-nil
[in]nThe maximum number of items to try to send
[out]n2If non-nil, will be incremented by the number of items that were actually sent
[in]srcWhere to send the items from
Returns
CHIC_OK if one or more items were successfully sent
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c, or if src is nil
CHIC_CHAN_FULL if there is no room in the channel
CHIC_CHAN_CLOSED if chan is closed and can no longer be sent to

◆ mpmc_nbsendv()

enum chic_err mpmc_nbsendv ( struct mpmc *restrict c,
size_t n,
size_t *restrict n2,
... )

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
[out]n2If non-nil, will be incremented by the number of items that were actually sent
...Pointers to the items to send
Returns
CHIC_OK if one or more items were successfully sent
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c
CHIC_CHAN_FULL if there is no room in the channel
CHIC_CHAN_CLOSED if chan is closed and can no longer be sent to

◆ mpmc_nel()

size_t mpmc_nel ( struct mpmc * 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

◆ mpmc_open()

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

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

Parameters
[out]cThe address at which to construct a mpmc; 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 mpmc with these parameters (if c was not nil, the size of the constructed mpmc), or 0 if nel is 0, or if elsize is 0 or not a power of 2.

◆ mpmc_recv()

enum chic_err mpmc_recv ( struct mpmc *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
[in]cThe channel to receive items from; must be non-nil
[in]nThe number of items to receive
[out]dstWhere to receive the items into
Returns
CHIC_OK if the items were successfully received
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c, or if dst is nil
CHIC_CHAN_CLOSED if chan is closed and there are less than n items remaining to receive

◆ mpmc_recvv()

enum chic_err mpmc_recvv ( struct mpmc *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
CHIC_OK if the items were successfully received
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c
CHIC_CHAN_CLOSED if chan is closed and there are less than n items remaining to receive

◆ mpmc_send()

enum chic_err mpmc_send ( struct mpmc *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
CHIC_OK if the items were successfully sent
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c, or if src is nil
CHIC_CHAN_CLOSED if chan is closed and can no longer be sent to

◆ mpmc_sendv()

enum chic_err mpmc_sendv ( struct mpmc *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
CHIC_OK if the items were successfully sent
CHIC_ARGS_INVAL if n is not within the range [0, nel], where nel is the capacity of c
CHIC_CHAN_CLOSED if chan is closed and can no longer be sent to