The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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_tfr_atomic_queue_malloc (size_t size)
 Create fixed-size atomic queue outside any talloc hierarchy.
 
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_tfr_atomic_queue_talloc (TALLOC_CTX *ctx, size_t size)
 Create fixed-size atomic queue.
 
fr_atomic_ring_tfr_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
3a566defb63f15aa51287e250b83ac3320ddca85

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 661 of file atomic_queue.c.

+ 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.

This function is needed because the atomic queue memory must be cache line aligned, and may live either in a talloc chunk or a raw posix_memalign allocation (aq->chunk == NULL).

Definition at line 212 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 ( size_t  size)

Create fixed-size atomic queue outside any talloc hierarchy.

Backed by posix_memalign; the resulting queue is released with fr_atomic_queue_free (which detects the raw allocation via a NULL chunk field) or plain free() on the queue pointer.

Intended for callers that push or pop from threads where talloc is not safe (for example, library-owned callback threads).

Parameters
[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 188 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 355 of file atomic_queue.c.

+ 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 232 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 417 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 143 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 504 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 533 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 595 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 552 of file atomic_queue.c.

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