summaryrefslogtreecommitdiffstats
path: root/include/zix/ring.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/zix/ring.h')
-rw-r--r--include/zix/ring.h126
1 files changed, 83 insertions, 43 deletions
diff --git a/include/zix/ring.h b/include/zix/ring.h
index db72f41..4431658 100644
--- a/include/zix/ring.h
+++ b/include/zix/ring.h
@@ -4,9 +4,9 @@
#ifndef ZIX_RING_H
#define ZIX_RING_H
-#include "zix/allocator.h"
-#include "zix/attributes.h"
-#include "zix/status.h"
+#include <zix/allocator.h>
+#include <zix/attributes.h>
+#include <zix/status.h>
#include <stdint.h>
@@ -19,7 +19,7 @@ ZIX_BEGIN_DECLS
*/
/**
- @defgroup zix_ring_setup Setup
+ @defgroup zix_ring_types Types
@{
*/
@@ -32,22 +32,30 @@ ZIX_BEGIN_DECLS
typedef struct ZixRingImpl ZixRing;
/**
+ @}
+ @defgroup zix_ring_setup Setup
+ @{
+*/
+
+/**
Create a new ring.
@param allocator Allocator for the ring object and its array.
- @param size Size of the ring in bytes (note this may be rounded up).
+ @param size Minimum size of the ring in bytes (rounded up to a power of 2).
- At most `size` - 1 bytes may be stored in the ring at once.
+ Note that one byte of the ring is reserved, so in order to be able to write
+ `n` bytes to the ring at once, `size` must be `n + 1`.
*/
-ZIX_API
-ZIX_NODISCARD
-ZixRing* ZIX_ALLOCATED
+ZIX_API ZIX_NODISCARD ZixRing* ZIX_ALLOCATED
zix_ring_new(ZixAllocator* ZIX_NULLABLE allocator, uint32_t size);
-/// Destroy a ring
-ZIX_API
-void
+/**
+ Destroy a ring.
+
+ This frees the ring structure and its buffer, discarding its contents.
+*/
+ZIX_API void
zix_ring_free(ZixRing* ZIX_NULLABLE ring);
/**
@@ -57,8 +65,7 @@ zix_ring_free(ZixRing* ZIX_NULLABLE ring);
after zix_ring_new() to lock all ring memory to avoid page faults while
using the ring.
*/
-ZIX_API
-ZixStatus
+ZIX_API ZixStatus
zix_ring_mlock(ZixRing* ZIX_NONNULL ring);
/**
@@ -67,8 +74,7 @@ zix_ring_mlock(ZixRing* ZIX_NONNULL ring);
This function is NOT thread-safe, it may only be called when there is no
reader or writer.
*/
-ZIX_API
-void
+ZIX_API void
zix_ring_reset(ZixRing* ZIX_NONNULL ring);
/**
@@ -77,8 +83,7 @@ zix_ring_reset(ZixRing* ZIX_NONNULL ring);
This function returns a constant for any given ring, and may (but usually
shouldn't) be called anywhere.
*/
-ZIX_PURE_API
-uint32_t
+ZIX_PURE_API uint32_t
zix_ring_capacity(const ZixRing* ZIX_NONNULL ring);
/**
@@ -88,24 +93,47 @@ zix_ring_capacity(const ZixRing* ZIX_NONNULL ring);
@{
*/
-/// Return the number of bytes available for reading
-ZIX_PURE_API
-uint32_t
+/**
+ Return the number of bytes available for reading.
+
+ This function returns at most one less than the ring's buffer size.
+*/
+ZIX_PURE_API uint32_t
zix_ring_read_space(const ZixRing* ZIX_NONNULL ring);
-/// Read from the ring without advancing the read head
-ZIX_API
-uint32_t
+/**
+ Read from the ring without advancing the read head.
+
+ @param ring The ring to read data from.
+ @param dst The buffer to write data to.
+ @param size The number of bytes to read from `ring` and write to `dst`.
+
+ @return The number of bytes read, which is either `size` on success, or zero
+ on failure.
+*/
+ZIX_API uint32_t
zix_ring_peek(ZixRing* ZIX_NONNULL ring, void* ZIX_NONNULL dst, uint32_t size);
-/// Read from the ring and advance the read head
-ZIX_API
-uint32_t
+/**
+ Read from the ring and advance the read head.
+
+ @param ring The ring to read data from.
+ @param dst The buffer to write data to.
+ @param size The number of bytes to read from `ring` and write to `dst`.
+
+ @return The number of bytes read, which is either `size` on success, or zero
+ on failure.
+*/
+ZIX_API uint32_t
zix_ring_read(ZixRing* ZIX_NONNULL ring, void* ZIX_NONNULL dst, uint32_t size);
-/// Advance the read head, ignoring any data
-ZIX_API
-uint32_t
+/**
+ Advance the read head, ignoring any data.
+
+ @return Either `size` on success, or zero if there aren't enough bytes to
+ skip.
+*/
+ZIX_API uint32_t
zix_ring_skip(ZixRing* ZIX_NONNULL ring, uint32_t size);
/**
@@ -123,20 +151,36 @@ zix_ring_skip(ZixRing* ZIX_NONNULL ring, uint32_t size);
written in several chunks before being "committed" and becoming readable.
This can be useful for things like prefixing messages with a header without
needing an allocated buffer to construct the "packet".
+
+ The contents of this structure are an implementation detail and must not be
+ manipulated by the user.
*/
typedef struct {
uint32_t read_head; ///< Read head at the start of the transaction
uint32_t write_head; ///< Write head if the transaction were committed
} ZixRingTransaction;
-/// Return the number of bytes available for writing
-ZIX_PURE_API
-uint32_t
+/**
+ Return the number of bytes available for writing.
+
+ This function returns at most one less than the ring's buffer size.
+*/
+ZIX_PURE_API uint32_t
zix_ring_write_space(const ZixRing* ZIX_NONNULL ring);
-/// Write data to the ring
-ZIX_API
-uint32_t
+/**
+ Write data to the ring.
+
+ This writes a contiguous input buffer of bytes to the ring.
+
+ @param ring The ring to write data to.
+ @param src The buffer to read data from.
+ @param size The number of bytes to read from `src` and write to `ring`.
+
+ @return The number of bytes written, which is either `size` on success, or
+ zero on failure.
+*/
+ZIX_API uint32_t
zix_ring_write(ZixRing* ZIX_NONNULL ring,
const void* ZIX_NONNULL src,
uint32_t size);
@@ -155,9 +199,7 @@ zix_ring_write(ZixRing* ZIX_NONNULL ring,
@param ring The ring to write data to.
@return A new empty transaction.
*/
-ZIX_API
-ZIX_NODISCARD
-ZixRingTransaction
+ZIX_API ZIX_NODISCARD ZixRingTransaction
zix_ring_begin_write(ZixRing* ZIX_NONNULL ring);
/**
@@ -178,8 +220,7 @@ zix_ring_begin_write(ZixRing* ZIX_NONNULL ring);
@param size Length of data to write in bytes.
@return #ZIX_STATUS_NO_MEM or #ZIX_STATUS_SUCCESS.
*/
-ZIX_API
-ZixStatus
+ZIX_API ZixStatus
zix_ring_amend_write(ZixRing* ZIX_NONNULL ring,
ZixRingTransaction* ZIX_NONNULL tx,
const void* ZIX_NONNULL src,
@@ -198,8 +239,7 @@ zix_ring_amend_write(ZixRing* ZIX_NONNULL ring,
@param tx The active transaction, from zix_ring_begin_write().
@return #ZIX_STATUS_SUCCESS.
*/
-ZIX_API
-ZixStatus
+ZIX_API ZixStatus
zix_ring_commit_write(ZixRing* ZIX_NONNULL ring,
const ZixRingTransaction* ZIX_NONNULL tx);