aboutsummaryrefslogtreecommitdiffstats
path: root/src/zix
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-11-15 08:55:55 -0500
committerDavid Robillard <d@drobilla.net>2022-11-16 10:52:09 -0500
commit117391dcf4358e82c85e482340859f5b5dbb2aa8 (patch)
tree372ec8a2e67f4ebddf84e7cf2e55976c9b5e359d /src/zix
parent0d5acf7a614fd1a136ee37cd09f89057d959974b (diff)
downloadjalv-117391dcf4358e82c85e482340859f5b5dbb2aa8.tar.gz
jalv-117391dcf4358e82c85e482340859f5b5dbb2aa8.tar.bz2
jalv-117391dcf4358e82c85e482340859f5b5dbb2aa8.zip
Switch to external zix dependency
Diffstat (limited to 'src/zix')
-rw-r--r--src/zix/allocator.c96
-rw-r--r--src/zix/allocator.h186
-rw-r--r--src/zix/attributes.h81
-rw-r--r--src/zix/common.h55
-rw-r--r--src/zix/ring.c278
-rw-r--r--src/zix/ring.h215
-rw-r--r--src/zix/sem.h229
-rw-r--r--src/zix/thread.h117
8 files changed, 0 insertions, 1257 deletions
diff --git a/src/zix/allocator.c b/src/zix/allocator.c
deleted file mode 100644
index 310ef33..0000000
--- a/src/zix/allocator.c
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2011-2021 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#include "zix/allocator.h"
-
-#include "zix/attributes.h"
-
-#include "jalv_config.h"
-
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN 1
-# include <malloc.h>
-# include <windows.h>
-#endif
-
-#include <stdlib.h>
-
-ZIX_MALLOC_FUNC
-static void*
-zix_default_malloc(ZixAllocator* const allocator, const size_t size)
-{
- (void)allocator;
- return malloc(size);
-}
-
-ZIX_MALLOC_FUNC
-static void*
-zix_default_calloc(ZixAllocator* const allocator,
- const size_t nmemb,
- const size_t size)
-{
- (void)allocator;
- return calloc(nmemb, size);
-}
-
-static void*
-zix_default_realloc(ZixAllocator* const allocator,
- void* const ptr,
- const size_t size)
-{
- (void)allocator;
- return realloc(ptr, size);
-}
-
-static void
-zix_default_free(ZixAllocator* const allocator, void* const ptr)
-{
- (void)allocator;
- free(ptr);
-}
-
-ZIX_MALLOC_FUNC
-static void*
-zix_default_aligned_alloc(ZixAllocator* const allocator,
- const size_t alignment,
- const size_t size)
-{
- (void)allocator;
-
-#if defined(_WIN32)
- return _aligned_malloc(size, alignment);
-#elif USE_POSIX_MEMALIGN
- void* ptr = NULL;
- const int ret = posix_memalign(&ptr, alignment, size);
- return ret ? NULL : ptr;
-#else
- return NULL;
-#endif
-}
-
-static void
-zix_default_aligned_free(ZixAllocator* const allocator, void* const ptr)
-{
- (void)allocator;
-
-#if defined(_WIN32)
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
-}
-
-ZixAllocator*
-zix_default_allocator(void)
-{
- static ZixAllocator default_allocator = {
- zix_default_malloc,
- zix_default_calloc,
- zix_default_realloc,
- zix_default_free,
- zix_default_aligned_alloc,
- zix_default_aligned_free,
- };
-
- return &default_allocator;
-}
diff --git a/src/zix/allocator.h b/src/zix/allocator.h
deleted file mode 100644
index bcffda5..0000000
--- a/src/zix/allocator.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2021 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_ALLOCATOR_H
-#define ZIX_ALLOCATOR_H
-
-#include "zix/attributes.h"
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- @addtogroup zix
- @{
- @name Allocator
- @{
-*/
-
-struct ZixAllocatorImpl;
-
-/**
- A memory allocator.
-
- This object-like structure provides an interface like the standard C
- functions malloc(), calloc(), realloc(), free(), and aligned_alloc(). It
- contains function pointers that differ from their standard counterparts by
- taking a context parameter (a pointer to this struct), which allows the user
- to implement custom stateful allocators.
-*/
-typedef struct ZixAllocatorImpl ZixAllocator;
-
-/**
- General malloc-like memory allocation function.
-
- This works like the standard C malloc(), except has an additional handle
- parameter for implementing stateful allocators without static data.
-*/
-typedef void* ZIX_ALLOCATED (*ZixMallocFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- size_t size);
-
-/**
- General calloc-like memory allocation function.
-
- This works like the standard C calloc(), except has an additional handle
- parameter for implementing stateful allocators without static data.
-*/
-typedef void* ZIX_ALLOCATED (*ZixCallocFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- size_t nmemb,
- size_t size);
-
-/**
- General realloc-like memory reallocation function.
-
- This works like the standard C remalloc(), except has an additional handle
- parameter for implementing stateful allocators without static data.
-*/
-typedef void* ZIX_ALLOCATED (*ZixReallocFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- void* ZIX_NULLABLE ptr,
- size_t size);
-
-/**
- General free-like memory deallocation function.
-
- This works like the standard C remalloc(), except has an additional handle
- parameter for implementing stateful allocators without static data.
-*/
-typedef void (*ZixFreeFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- void* ZIX_NULLABLE ptr);
-
-/**
- General aligned_alloc-like memory deallocation function.
-
- This works like the standard C aligned_alloc(), except has an additional
- handle parameter for implementing stateful allocators without static data.
-*/
-typedef void* ZIX_ALLOCATED (*ZixAlignedAllocFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- size_t alignment,
- size_t size);
-
-/**
- General aligned memory deallocation function.
-
- This works like the standard C free(), but must be used to free memory
- allocated with the aligned_alloc() method of the allocator. This allows
- portability to systems (like Windows) that can not use the same free function
- in these cases.
-*/
-typedef void (*ZixAlignedFreeFunc)( //
- ZixAllocator* ZIX_NULLABLE allocator,
- void* ZIX_NULLABLE ptr);
-
-/// Definition of ZixAllocator
-struct ZixAllocatorImpl {
- ZixMallocFunc ZIX_NONNULL malloc;
- ZixCallocFunc ZIX_NONNULL calloc;
- ZixReallocFunc ZIX_NONNULL realloc;
- ZixFreeFunc ZIX_NONNULL free;
- ZixAlignedAllocFunc ZIX_NONNULL aligned_alloc;
- ZixAlignedFreeFunc ZIX_NONNULL aligned_free;
-};
-
-/// Return the default allocator which simply uses the system allocator
-ZIX_CONST_API
-ZixAllocator* ZIX_NONNULL
-zix_default_allocator(void);
-
-/// Convenience wrapper that defers to malloc() if allocator is null
-static inline void* ZIX_ALLOCATED
-zix_malloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t size)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- return actual->malloc(actual, size);
-}
-
-/// Convenience wrapper that defers to calloc() if allocator is null
-static inline void* ZIX_ALLOCATED
-zix_calloc(ZixAllocator* const ZIX_NULLABLE allocator,
- const size_t nmemb,
- const size_t size)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- return actual->calloc(actual, nmemb, size);
-}
-
-/// Convenience wrapper that defers to realloc() if allocator is null
-static inline void* ZIX_ALLOCATED
-zix_realloc(ZixAllocator* const ZIX_NULLABLE allocator,
- void* const ZIX_NULLABLE ptr,
- const size_t size)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- return actual->realloc(actual, ptr, size);
-}
-
-/// Convenience wrapper that defers to free() if allocator is null
-static inline void
-zix_free(ZixAllocator* const ZIX_NULLABLE allocator,
- void* const ZIX_NULLABLE ptr)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- actual->free(actual, ptr);
-}
-
-/// Convenience wrapper that defers to the system allocator if allocator is null
-static inline void* ZIX_ALLOCATED
-zix_aligned_alloc(ZixAllocator* const ZIX_NULLABLE allocator,
- const size_t alignment,
- const size_t size)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- return actual->aligned_alloc(actual, alignment, size);
-}
-
-/// Convenience wrapper that defers to the system allocator if allocator is null
-static inline void
-zix_aligned_free(ZixAllocator* const ZIX_NULLABLE allocator,
- void* const ZIX_NULLABLE ptr)
-{
- ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
-
- actual->aligned_free(actual, ptr);
-}
-
-/**
- @}
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_ALLOCATOR_H */
diff --git a/src/zix/attributes.h b/src/zix/attributes.h
deleted file mode 100644
index 602fac8..0000000
--- a/src/zix/attributes.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2021 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_ATTRIBUTES_H
-#define ZIX_ATTRIBUTES_H
-
-/**
- @addtogroup zix
- @{
-*/
-
-// ZIX_API must be used to decorate things in the public API
-#ifndef ZIX_API
-# if defined(_WIN32) && !defined(ZIX_STATIC) && defined(ZIX_INTERNAL)
-# define ZIX_API __declspec(dllexport)
-# elif defined(_WIN32) && !defined(ZIX_STATIC)
-# define ZIX_API __declspec(dllimport)
-# elif defined(__GNUC__)
-# define ZIX_API __attribute__((visibility("default")))
-# else
-# define ZIX_API
-# endif
-#endif
-
-// GCC pure/const/malloc attributes
-#ifdef __GNUC__
-# define ZIX_PURE_FUNC __attribute__((pure))
-# define ZIX_CONST_FUNC __attribute__((const))
-# define ZIX_MALLOC_FUNC __attribute__((malloc))
-#else
-# define ZIX_PURE_FUNC
-# define ZIX_CONST_FUNC
-# define ZIX_MALLOC_FUNC
-#endif
-
-#define ZIX_PURE_API \
- ZIX_API \
- ZIX_PURE_FUNC
-
-#define ZIX_CONST_API \
- ZIX_API \
- ZIX_CONST_FUNC
-
-#define ZIX_MALLOC_API \
- ZIX_API \
- ZIX_MALLOC_FUNC
-
-// Printf-like format functions
-#ifdef __GNUC__
-# define ZIX_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1)))
-#else
-# define ZIX_LOG_FUNC(fmt, arg1)
-#endif
-
-// Unused parameter macro to suppresses warnings and make it impossible to use
-#if defined(__cplusplus)
-# define ZIX_UNUSED(name)
-#elif defined(__GNUC__)
-# define ZIX_UNUSED(name) name##_unused __attribute__((__unused__))
-#elif defined(_MSC_VER)
-# define ZIX_UNUSED(name) __pragma(warning(suppress : 4100)) name
-#else
-# define ZIX_UNUSED(name) name
-#endif
-
-// Clang nullability annotations
-#if defined(__clang__) && __clang_major__ >= 7
-# define ZIX_NONNULL _Nonnull
-# define ZIX_NULLABLE _Nullable
-# define ZIX_ALLOCATED _Null_unspecified
-#else
-# define ZIX_NONNULL
-# define ZIX_NULLABLE
-# define ZIX_ALLOCATED
-#endif
-
-/**
- @}
-*/
-
-#endif /* ZIX_ATTRIBUTES_H */
diff --git a/src/zix/common.h b/src/zix/common.h
deleted file mode 100644
index 5919fa9..0000000
--- a/src/zix/common.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016-2020 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_COMMON_H
-#define ZIX_COMMON_H
-
-#include "zix/attributes.h"
-
-#include <stdbool.h>
-
-/**
- @addtogroup zix
- @{
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- ZIX_STATUS_SUCCESS,
- ZIX_STATUS_ERROR,
- ZIX_STATUS_NO_MEM,
- ZIX_STATUS_NOT_FOUND,
- ZIX_STATUS_EXISTS,
- ZIX_STATUS_BAD_ARG,
- ZIX_STATUS_BAD_PERMS,
- ZIX_STATUS_REACHED_END
-} ZixStatus;
-
-/// Return a string describing a status code
-ZIX_CONST_API
-const char*
-zix_strerror(ZixStatus status);
-
-/// Function for comparing two elements
-typedef int (*ZixComparator)(const void* a,
- const void* b,
- const void* user_data);
-
-/// Function for testing equality of two elements
-typedef bool (*ZixEqualFunc)(const void* a, const void* b);
-
-/// Function to destroy an element
-typedef void (*ZixDestroyFunc)(void* ptr, const void* user_data);
-
-/**
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_COMMON_H */
diff --git a/src/zix/ring.c b/src/zix/ring.c
deleted file mode 100644
index d2d3195..0000000
--- a/src/zix/ring.c
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2011-2022 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#include "zix/ring.h"
-#include "zix/common.h"
-
-#include "jalv_config.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#if USE_MLOCK
-# include <sys/mman.h>
-# define ZIX_MLOCK(ptr, size) mlock((ptr), (size))
-#elif defined(_WIN32)
-# include <windows.h>
-# define ZIX_MLOCK(ptr, size) VirtualLock((ptr), (size))
-#else
-# pragma message("warning: No memory locking, possible RT violations")
-# define ZIX_MLOCK(ptr, size)
-#endif
-
-/*
- Note that for simplicity, only x86 and x64 are supported with MSVC. Hopefully
- stdatomic.h support arrives before anyone cares about running this code on
- Windows on ARM.
-*/
-#if defined(_MSC_VER)
-# include <intrin.h>
-#endif
-
-struct ZixRingImpl {
- ZixAllocator* allocator; ///< User allocator
- uint32_t write_head; ///< Read index into buf
- uint32_t read_head; ///< Write index into buf
- uint32_t size; ///< Size (capacity) in bytes
- uint32_t size_mask; ///< Mask for fast modulo
- char* buf; ///< Contents
-};
-
-static inline uint32_t
-zix_atomic_load(const uint32_t* const ptr)
-{
-#if defined(_MSC_VER)
- const uint32_t val = *ptr;
- _ReadBarrier();
- return val;
-#else
- return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
-#endif
-}
-
-static inline void
-zix_atomic_store(uint32_t* const ptr, // NOLINT(readability-non-const-parameter)
- const uint32_t val)
-{
-#if defined(_MSC_VER)
- _WriteBarrier();
- *ptr = val;
-#else
- __atomic_store_n(ptr, val, __ATOMIC_RELEASE);
-#endif
-}
-
-static inline uint32_t
-next_power_of_two(uint32_t size)
-{
- // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
- size--;
- size |= size >> 1U;
- size |= size >> 2U;
- size |= size >> 4U;
- size |= size >> 8U;
- size |= size >> 16U;
- size++;
- return size;
-}
-
-ZixRing*
-zix_ring_new(ZixAllocator* const allocator, const uint32_t size)
-{
- ZixRing* ring = (ZixRing*)zix_malloc(allocator, sizeof(ZixRing));
-
- if (ring) {
- ring->allocator = allocator;
- ring->write_head = 0;
- ring->read_head = 0;
- ring->size = next_power_of_two(size);
- ring->size_mask = ring->size - 1;
-
- if (!(ring->buf = (char*)zix_malloc(allocator, ring->size))) {
- zix_free(allocator, ring);
- return NULL;
- }
- }
-
- return ring;
-}
-
-void
-zix_ring_free(ZixRing* const ring)
-{
- if (ring) {
- zix_free(ring->allocator, ring->buf);
- zix_free(ring->allocator, ring);
- }
-}
-
-void
-zix_ring_mlock(ZixRing* const ring)
-{
- ZIX_MLOCK(ring, sizeof(ZixRing));
- ZIX_MLOCK(ring->buf, ring->size);
-}
-
-void
-zix_ring_reset(ZixRing* const ring)
-{
- ring->write_head = 0;
- ring->read_head = 0;
-}
-
-/*
- General pattern for public thread-safe functions below: start with a single
- atomic load of the "other's" index, then do whatever work, and finally end
- with a single atomic store to "your" index (if it is changed).
-*/
-
-static inline uint32_t
-read_space_internal(const ZixRing* const ring,
- const uint32_t r,
- const uint32_t w)
-{
- return (w - r) & ring->size_mask;
-}
-
-uint32_t
-zix_ring_read_space(const ZixRing* const ring)
-{
- const uint32_t w = zix_atomic_load(&ring->write_head);
-
- return read_space_internal(ring, ring->read_head, w);
-}
-
-static inline uint32_t
-write_space_internal(const ZixRing* const ring,
- const uint32_t r,
- const uint32_t w)
-{
- return (r - w - 1U) & ring->size_mask;
-}
-
-uint32_t
-zix_ring_write_space(const ZixRing* const ring)
-{
- const uint32_t r = zix_atomic_load(&ring->read_head);
-
- return write_space_internal(ring, r, ring->write_head);
-}
-
-uint32_t
-zix_ring_capacity(const ZixRing* const ring)
-{
- return ring->size - 1;
-}
-
-static inline uint32_t
-peek_internal(const ZixRing* const ring,
- const uint32_t r,
- const uint32_t w,
- const uint32_t size,
- void* const dst)
-{
- if (read_space_internal(ring, r, w) < size) {
- return 0;
- }
-
- if (r + size < ring->size) {
- memcpy(dst, &ring->buf[r], size);
- } else {
- const uint32_t first_size = ring->size - r;
- memcpy(dst, &ring->buf[r], first_size);
- memcpy((char*)dst + first_size, &ring->buf[0], size - first_size);
- }
-
- return size;
-}
-
-uint32_t
-zix_ring_peek(ZixRing* const ring, void* const dst, const uint32_t size)
-{
- const uint32_t w = zix_atomic_load(&ring->write_head);
-
- return peek_internal(ring, ring->read_head, w, size, dst);
-}
-
-uint32_t
-zix_ring_read(ZixRing* const ring, void* const dst, const uint32_t size)
-{
- const uint32_t w = zix_atomic_load(&ring->write_head);
- const uint32_t r = ring->read_head;
- if (!peek_internal(ring, r, w, size, dst)) {
- return 0;
- }
-
- zix_atomic_store(&ring->read_head, (r + size) & ring->size_mask);
- return size;
-}
-
-uint32_t
-zix_ring_skip(ZixRing* const ring, const uint32_t size)
-{
- const uint32_t w = zix_atomic_load(&ring->write_head);
- const uint32_t r = ring->read_head;
- if (read_space_internal(ring, r, w) < size) {
- return 0;
- }
-
- zix_atomic_store(&ring->read_head, (r + size) & ring->size_mask);
- return size;
-}
-
-ZixRingTransaction
-zix_ring_begin_write(ZixRing* const ring)
-{
- const uint32_t r = zix_atomic_load(&ring->read_head);
- const uint32_t w = ring->write_head;
-
- const ZixRingTransaction tx = {r, w};
- return tx;
-}
-
-ZixStatus
-zix_ring_amend_write(ZixRing* const ring,
- ZixRingTransaction* const tx,
- const void* const src,
- const uint32_t size)
-{
- const uint32_t r = tx->read_head;
- const uint32_t w = tx->write_head;
- if (write_space_internal(ring, r, w) < size) {
- return ZIX_STATUS_NO_MEM;
- }
-
- const uint32_t end = w + size;
- if (end <= ring->size) {
- memcpy(&ring->buf[w], src, size);
- tx->write_head = end & ring->size_mask;
- } else {
- const uint32_t size1 = ring->size - w;
- const uint32_t size2 = size - size1;
- memcpy(&ring->buf[w], src, size1);
- memcpy(&ring->buf[0], (const char*)src + size1, size2);
- tx->write_head = size2;
- }
-
- return ZIX_STATUS_SUCCESS;
-}
-
-ZixStatus
-zix_ring_commit_write(ZixRing* const ring, const ZixRingTransaction* const tx)
-{
- zix_atomic_store(&ring->write_head, tx->write_head);
- return ZIX_STATUS_SUCCESS;
-}
-
-uint32_t
-zix_ring_write(ZixRing* const ring, const void* src, const uint32_t size)
-{
- ZixRingTransaction tx = zix_ring_begin_write(ring);
-
- if (zix_ring_amend_write(ring, &tx, src, size) ||
- zix_ring_commit_write(ring, &tx)) {
- return 0;
- }
-
- return size;
-}
diff --git a/src/zix/ring.h b/src/zix/ring.h
deleted file mode 100644
index 872f963..0000000
--- a/src/zix/ring.h
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2011-2022 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_RING_H
-#define ZIX_RING_H
-
-#include "zix/allocator.h"
-#include "zix/attributes.h"
-#include "zix/common.h"
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- @addtogroup zix
- @{
- @name Ring
- @{
-*/
-
-/**
- A lock-free ring buffer.
-
- Thread-safe (with a few noted exceptions) for a single reader and single
- writer, and realtime-safe on both ends.
-*/
-typedef struct ZixRingImpl ZixRing;
-
-/**
- A transaction for writing data in multiple parts.
-
- The simple zix_ring_write() can be used to write an atomic message that will
- immediately be visible to the reader, but transactions allow data to be
- 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".
-*/
-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;
-
-/**
- Create a new ring.
- @param size Size in bytes (note this may be rounded up).
-
- At most `size` - 1 bytes may be stored in the ring at once.
-*/
-ZIX_MALLOC_API
-ZixRing* ZIX_ALLOCATED
-zix_ring_new(ZixAllocator* ZIX_NULLABLE allocator, uint32_t size);
-
-/// Destroy a ring
-ZIX_API
-void
-zix_ring_free(ZixRing* ZIX_NULLABLE ring);
-
-/**
- Lock the ring data into physical memory.
-
- This function is NOT thread safe or real-time safe, but it should be called
- after zix_ring_new() to lock all ring memory to avoid page faults while
- using the ring.
-*/
-ZIX_API
-void
-zix_ring_mlock(ZixRing* ZIX_NONNULL ring);
-
-/**
- Reset (empty) a ring.
-
- This function is NOT thread-safe, it may only be called when there is no
- reader or writer.
-*/
-ZIX_API
-void
-zix_ring_reset(ZixRing* ZIX_NONNULL ring);
-
-/**
- Return the number of bytes of space available for reading.
-
- Reader only.
-*/
-ZIX_PURE_API
-uint32_t
-zix_ring_read_space(const ZixRing* ZIX_NONNULL ring);
-
-/**
- Return the number of bytes of space available for writing.
-
- Writer only.
-*/
-ZIX_PURE_API
-uint32_t
-zix_ring_write_space(const ZixRing* ZIX_NONNULL ring);
-
-/**
- Return the capacity (the total write space when empty).
-
- This function returns a constant for any given ring, and may (but usually
- shouldn't) be called anywhere.
-*/
-ZIX_PURE_API
-uint32_t
-zix_ring_capacity(const ZixRing* ZIX_NONNULL ring);
-
-/**
- Read from the ring without advancing the read head.
-
- Reader only.
-*/
-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.
-
- Reader only.
-*/
-ZIX_API
-uint32_t
-zix_ring_read(ZixRing* ZIX_NONNULL ring, void* ZIX_NONNULL dst, uint32_t size);
-
-/**
- Skip data in the ring (advance read head without reading).
-
- Reader only.
-*/
-ZIX_API
-uint32_t
-zix_ring_skip(ZixRing* ZIX_NONNULL ring, uint32_t size);
-
-/**
- Write data to the ring.
-
- Writer only.
-*/
-ZIX_API
-uint32_t
-zix_ring_write(ZixRing* ZIX_NONNULL ring,
- const void* ZIX_NONNULL src,
- uint32_t size);
-
-/**
- Begin a write.
-
- The returned transaction is initially empty. Data can be written to it by
- calling zix_ring_amend_write() one or more times, then finishing with
- zix_ring_commit_write().
-
- Note that the returned "transaction" is not meant to be long-lived: a call
- to this function should be (more or less) immediately followed by calls to
- zix_ring_amend_write() then a call to zix_ring_commit_write().
-
- @param ring The ring to write data to.
- @return A new empty transaction.
-*/
-ZixRingTransaction
-zix_ring_begin_write(ZixRing* ZIX_NONNULL ring);
-
-/**
- Amend the current write with some data.
-
- The data is written immediately after the previously amended data, as if
- they were written contiguously with a single write call. This data is not
- visible to the reader until zix_ring_commit_write() is called.
-
- If any call to this function returns an error, then the transaction is
- invalid and must not be committed. No cleanup is necessary for an invalid
- transaction. Any bytes written while attempting the transaction will remain
- in the free portion of the buffer and be overwritten by subsequent writes.
-
- @param ring The ring this transaction is writing to.
- @param tx The active transaction, from zix_ring_begin_write().
- @param src Pointer to the data to write.
- @param size Length of data to write in bytes.
- @return #ZIX_STATUS_NO_MEM or #ZIX_STATUS_SUCCESS.
-*/
-ZixStatus
-zix_ring_amend_write(ZixRing* ZIX_NONNULL ring,
- ZixRingTransaction* ZIX_NONNULL tx,
- const void* ZIX_NONNULL src,
- uint32_t size);
-
-/**
- Commit the current write.
-
- This atomically updates the state of the ring, so that the reader will
- observe the data written during the transaction.
-
- This function usually shouldn't be called for any transaction which
- zix_ring_amend_write() returned an error for.
-
- @param ring The ring this transaction is writing to.
- @param tx The active transaction, from zix_ring_begin_write().
- @return #ZIX_STATUS_SUCCESS.
-*/
-ZixStatus
-zix_ring_commit_write(ZixRing* ZIX_NONNULL ring,
- const ZixRingTransaction* ZIX_NONNULL tx);
-
-/**
- @}
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_RING_H */
diff --git a/src/zix/sem.h b/src/zix/sem.h
deleted file mode 100644
index 0337f03..0000000
--- a/src/zix/sem.h
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2012-2020 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_SEM_H
-#define ZIX_SEM_H
-
-#include "zix/attributes.h"
-#include "zix/common.h"
-
-#ifdef __APPLE__
-# include <mach/mach.h>
-#elif defined(_WIN32)
-# include <limits.h>
-# include <windows.h>
-#else
-# include <errno.h>
-# include <semaphore.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdbool.h>
-
-/**
- @addtogroup zix
- @{
- @name Semaphore
- @{
-*/
-
-struct ZixSemImpl;
-
-/**
- A counting semaphore.
-
- This is an integer that is always positive, and has two main operations:
- increment (post) and decrement (wait). If a decrement can not be performed
- (i.e. the value is 0) the caller will be blocked until another thread posts
- and the operation can succeed.
-
- Semaphores can be created with any starting value, but typically this will
- be 0 so the semaphore can be used as a simple signal where each post
- corresponds to one wait.
-
- Semaphores are very efficient (much moreso than a mutex/cond pair). In
- particular, at least on Linux, post is async-signal-safe, which means it
- does not block and will not be interrupted. If you need to signal from
- a realtime thread, this is the most appropriate primitive to use.
-*/
-typedef struct ZixSemImpl ZixSem;
-
-/// Create and initialize `sem` to `initial`
-static inline ZixStatus
-zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned initial);
-
-/// Destroy `sem`
-static inline void
-zix_sem_destroy(ZixSem* ZIX_NONNULL sem);
-
-/**
- Increment and signal any waiters.
-
- Realtime safe.
-*/
-static inline void
-zix_sem_post(ZixSem* ZIX_NONNULL sem);
-
-/**
- Wait until count is > 0, then decrement.
-
- Obviously not realtime safe.
-*/
-static inline ZixStatus
-zix_sem_wait(ZixSem* ZIX_NONNULL sem);
-
-/**
- Non-blocking version of wait().
-
- @return true if decrement was successful (lock was acquired).
-*/
-static inline bool
-zix_sem_try_wait(ZixSem* ZIX_NONNULL sem);
-
-/**
- @cond
-*/
-
-#ifdef __APPLE__
-
-struct ZixSemImpl {
- semaphore_t sem;
-};
-
-static inline ZixStatus
-zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned val)
-{
- return semaphore_create(
- mach_task_self(), &sem->sem, SYNC_POLICY_FIFO, (int)val)
- ? ZIX_STATUS_ERROR
- : ZIX_STATUS_SUCCESS;
-}
-
-static inline void
-zix_sem_destroy(ZixSem* ZIX_NONNULL sem)
-{
- semaphore_destroy(mach_task_self(), sem->sem);
-}
-
-static inline void
-zix_sem_post(ZixSem* ZIX_NONNULL sem)
-{
- semaphore_signal(sem->sem);
-}
-
-static inline ZixStatus
-zix_sem_wait(ZixSem* ZIX_NONNULL sem)
-{
- if (semaphore_wait(sem->sem) != KERN_SUCCESS) {
- return ZIX_STATUS_ERROR;
- }
- return ZIX_STATUS_SUCCESS;
-}
-
-static inline bool
-zix_sem_try_wait(ZixSem* ZIX_NONNULL sem)
-{
- const mach_timespec_t zero = {0, 0};
- return semaphore_timedwait(sem->sem, zero) == KERN_SUCCESS;
-}
-
-#elif defined(_WIN32)
-
-struct ZixSemImpl {
- HANDLE sem;
-};
-
-static inline ZixStatus
-zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned initial)
-{
- sem->sem = CreateSemaphore(NULL, (LONG)initial, LONG_MAX, NULL);
- return (sem->sem) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR;
-}
-
-static inline void
-zix_sem_destroy(ZixSem* ZIX_NONNULL sem)
-{
- CloseHandle(sem->sem);
-}
-
-static inline void
-zix_sem_post(ZixSem* ZIX_NONNULL sem)
-{
- ReleaseSemaphore(sem->sem, 1, NULL);
-}
-
-static inline ZixStatus
-zix_sem_wait(ZixSem* ZIX_NONNULL sem)
-{
- if (WaitForSingleObject(sem->sem, INFINITE) != WAIT_OBJECT_0) {
- return ZIX_STATUS_ERROR;
- }
- return ZIX_STATUS_SUCCESS;
-}
-
-static inline bool
-zix_sem_try_wait(ZixSem* ZIX_NONNULL sem)
-{
- return WaitForSingleObject(sem->sem, 0) == WAIT_OBJECT_0;
-}
-
-#else /* !defined(__APPLE__) && !defined(_WIN32) */
-
-struct ZixSemImpl {
- sem_t sem;
-};
-
-static inline ZixStatus
-zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned initial)
-{
- return sem_init(&sem->sem, 0, initial) ? ZIX_STATUS_ERROR
- : ZIX_STATUS_SUCCESS;
-}
-
-static inline void
-zix_sem_destroy(ZixSem* ZIX_NONNULL sem)
-{
- sem_destroy(&sem->sem);
-}
-
-static inline void
-zix_sem_post(ZixSem* ZIX_NONNULL sem)
-{
- sem_post(&sem->sem);
-}
-
-static inline ZixStatus
-zix_sem_wait(ZixSem* ZIX_NONNULL sem)
-{
- while (sem_wait(&sem->sem)) {
- if (errno != EINTR) {
- return ZIX_STATUS_ERROR;
- }
- /* Otherwise, interrupted, so try again. */
- }
-
- return ZIX_STATUS_SUCCESS;
-}
-
-static inline bool
-zix_sem_try_wait(ZixSem* ZIX_NONNULL sem)
-{
- return (sem_trywait(&sem->sem) == 0);
-}
-
-#endif
-
-/**
- @endcond
- @}
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_SEM_H */
diff --git a/src/zix/thread.h b/src/zix/thread.h
deleted file mode 100644
index 74bb19b..0000000
--- a/src/zix/thread.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2012-2020 David Robillard <d@drobilla.net>
-// SPDX-License-Identifier: ISC
-
-#ifndef ZIX_THREAD_H
-#define ZIX_THREAD_H
-
-#include "zix/common.h"
-
-#ifdef _WIN32
-# include <windows.h>
-#else
-# include <errno.h>
-# include <pthread.h>
-#endif
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- @addtogroup zix
- @{
- @name Thread
- @{
-*/
-
-#ifdef _WIN32
-typedef HANDLE ZixThread;
-#else
-typedef pthread_t ZixThread;
-#endif
-
-/**
- Initialize `thread` to a new thread.
-
- The thread will immediately be launched, calling `function` with `arg`
- as the only parameter.
-*/
-static inline ZixStatus
-zix_thread_create(ZixThread* thread,
- size_t stack_size,
- void* (*function)(void*),
- void* arg);
-
-/// Join `thread` (block until `thread` exits)
-static inline ZixStatus
-zix_thread_join(ZixThread thread, void** retval);
-
-#ifdef _WIN32
-
-static inline ZixStatus
-zix_thread_create(ZixThread* thread,
- size_t stack_size,
- void* (*function)(void*),
- void* arg)
-{
- *thread = CreateThread(
- NULL, stack_size, (LPTHREAD_START_ROUTINE)function, arg, 0, NULL);
- return *thread ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR;
-}
-
-static inline ZixStatus
-zix_thread_join(ZixThread thread, void** retval)
-{
- (void)retval;
-
- return WaitForSingleObject(thread, INFINITE) ? ZIX_STATUS_SUCCESS
- : ZIX_STATUS_ERROR;
-}
-
-#else /* !defined(_WIN32) */
-
-static inline ZixStatus
-zix_thread_create(ZixThread* thread,
- size_t stack_size,
- void* (*function)(void*),
- void* arg)
-{
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, stack_size);
-
- const int ret = pthread_create(thread, NULL, function, arg);
- pthread_attr_destroy(&attr);
-
- switch (ret) {
- case EAGAIN:
- return ZIX_STATUS_NO_MEM;
- case EINVAL:
- return ZIX_STATUS_BAD_ARG;
- case EPERM:
- return ZIX_STATUS_BAD_PERMS;
- }
-
- return ret ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS;
-}
-
-static inline ZixStatus
-zix_thread_join(ZixThread thread, void** retval)
-{
- return pthread_join(thread, retval) ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS;
-}
-
-#endif
-
-/**
- @}
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_THREAD_H */