The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
Typedefs | Functions
atomic_queue.h File Reference

Thread-safe queues. More...

#include <freeradius-devel/util/stdatomic.h>
#include <freeradius-devel/util/talloc.h>
+ Include dependency graph for atomic_queue.h:

Go to the source code of this file.

Typedefs

typedef struct fr_atomic_queue_s fr_atomic_queue_t
 
typedef struct fr_atomic_ring_s fr_atomic_ring_t
 Unbounded segmented single-producer / single-consumer queue.
 

Functions

void fr_atomic_queue_debug (FILE *fp, fr_atomic_queue_t *aq)
 Dump an atomic queue.
 
void fr_atomic_queue_free (fr_atomic_queue_t **aq)
 Free an atomic queue if it's not freed by ctx.
 
fr_atomic_queue_t * fr_atomic_queue_malloc (TALLOC_CTX *ctx, size_t size)
 Create fixed-size atomic queue outside the talloc hierarchy, owned by a talloc context.
 
bool fr_atomic_queue_pop (fr_atomic_queue_t *aq, void **p_data)
 Pop a pointer from the atomic queue.
 
bool fr_atomic_queue_push (fr_atomic_queue_t *aq, void *data)
 Push a pointer into the atomic queue.
 
size_t fr_atomic_queue_size (fr_atomic_queue_t *aq)
 
fr_atomic_queue_t * fr_atomic_queue_talloc (TALLOC_CTX *ctx, size_t size)
 Create fixed-size atomic queue.
 
fr_atomic_ring_t * fr_atomic_ring_alloc (TALLOC_CTX *ctx, size_t seg_size)
 Allocate an empty SPSC ring.
 
void fr_atomic_ring_free (fr_atomic_ring_t **ring)
 Free the ring and all remaining segments.
 
bool fr_atomic_ring_pop (fr_atomic_ring_t *ring, void **p_data)
 Pop a pointer from the ring, advancing past drained segments.
 
bool fr_atomic_ring_push (fr_atomic_ring_t *ring, void *data)
 Push a pointer into the ring; allocate a new segment on overflow.
 

Detailed Description

Thread-safe queues.

Id
b98262973a8e27fcfcfee244045609af37750857

Definition in file atomic_queue.h.

Typedef Documentation

◆ fr_atomic_queue_t

Definition at line 40 of file atomic_queue.h.

◆ fr_atomic_ring_t

Unbounded segmented single-producer / single-consumer queue.

Internally a linked list of fixed-size fr_atomic_queue_t segments. When the producer's current segment fills, a new segment is malloc'd and linked in; the consumer drains segments in order and frees them as it advances. Allocation on the producer side uses raw malloc (not talloc), so the producer thread is free to be one that cannot safely use talloc (e.g. a library-owned callback thread).

Exactly one producer and one consumer. Not safe for MPMC use.

Definition at line 60 of file atomic_queue.h.

Function Documentation

◆ fr_atomic_queue_debug()

void fr_atomic_queue_debug ( FILE *  fp,
fr_atomic_queue_t *  aq 
)

Dump an atomic queue.

Absolutely NOT thread-safe.

Parameters
[in]aqThe atomic queue to debug.
[in]fpwhere the debugging information will be printed.

Definition at line 841 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_queue_free()

void fr_atomic_queue_free ( fr_atomic_queue_t **  aq)

Free an atomic queue if it's not freed by ctx.

The queue memory must be cache line aligned, so it lives in one of three places: a talloc aligned array (chunk is the array), a raw allocation owned by a talloc handle (chunk is the handle, whose destructor frees the queue), or a raw allocation with no owner (chunk is NULL).

Definition at line 388 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_queue_malloc()

fr_atomic_queue_t * fr_atomic_queue_malloc ( TALLOC_CTX *  ctx,
size_t  size 
)

Create fixed-size atomic queue outside the talloc hierarchy, owned by a talloc context.

The queue itself is a raw posix_memalign allocation, so it can be pushed to and popped from by threads where talloc is not safe, and can later be placed in memory talloc does not manage. A small owner handle allocated in ctx frees the queue when ctx is freed, or when the caller calls fr_atomic_queue_free.

Parameters
[in]ctxThe talloc ctx which owns the queue.
[in]sizeThe number of entries in the queue.
Returns
  • NULL on error.
  • fr_atomic_queue_t *, a pointer to the allocated and initialized queue.

Definition at line 360 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_queue_pop()

bool fr_atomic_queue_pop ( fr_atomic_queue_t *  aq,
void **  p_data 
)

Pop a pointer from the atomic queue.

Parameters
[in]aqthe atomic queue to retrieve data from.
[out]p_datawhere to write the data.
Returns
  • true on successful pop
  • false on queue empty

Definition at line 531 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_queue_push()

bool fr_atomic_queue_push ( fr_atomic_queue_t *  aq,
void *  data 
)

Push a pointer into the atomic queue.

Parameters
[in]aqThe atomic queue to add data to.
[in]datato push.
Returns
  • true on successful push
  • false on queue full

Definition at line 408 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_queue_size()

size_t fr_atomic_queue_size ( fr_atomic_queue_t *  aq)

Definition at line 593 of file atomic_queue.c.

+ Here is the caller graph for this function:

◆ fr_atomic_queue_talloc()

fr_atomic_queue_t * fr_atomic_queue_talloc ( TALLOC_CTX *  ctx,
size_t  size 
)

Create fixed-size atomic queue.

Note
the queue must be freed explicitly by the ctx being freed, or by using the fr_atomic_queue_free function.
Parameters
[in]ctxThe talloc ctx to allocate the queue in.
[in]sizeThe number of entries in the queue.
Returns
  • NULL on error.
  • fr_atomic_queue_t *, a pointer to the allocated and initialized queue.

Definition at line 270 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_ring_alloc()

fr_atomic_ring_t * fr_atomic_ring_alloc ( TALLOC_CTX *  ctx,
size_t  seg_size 
)

Allocate an empty SPSC ring.

Parameters
[in]ctxtalloc ctx that owns the ring handle (segments live outside talloc; they are freed by the ring's destructor).
[in]seg_sizePer-segment capacity. Rounded up to a power of 2.
Returns
  • NULL on error.
  • A ring containing one initial (empty) segment.

Definition at line 680 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_ring_free()

void fr_atomic_ring_free ( fr_atomic_ring_t **  ring_p)

Free the ring and all remaining segments.

Equivalent to talloc_free() on the ring, but nulls the caller's handle in the style of fr_atomic_queue_free.

Definition at line 709 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_ring_pop()

bool fr_atomic_ring_pop ( fr_atomic_ring_t *  ring,
void **  p_data 
)

Pop a pointer from the ring, advancing past drained segments.

Single-consumer only. Must not be called concurrently with itself.

Parameters
[in]ringRing to pop from.
[out]p_dataWhere to write the popped value on success.
Returns
  • true if a value was popped.
  • false if the ring is currently empty.

Definition at line 775 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_atomic_ring_push()

bool fr_atomic_ring_push ( fr_atomic_ring_t *  ring,
void *  data 
)

Push a pointer into the ring; allocate a new segment on overflow.

Single-producer only. Must not be called concurrently with itself.

Parameters
[in]ringRing to push into.
[in]dataValue to push (must be non-NULL).
Returns
  • true on success.
  • false if both the current segment is full and a new segment could not be allocated.

Definition at line 748 of file atomic_queue.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function: