diff options
Diffstat (limited to 'src/zix')
-rw-r--r-- | src/zix/common.h | 135 | ||||
-rw-r--r-- | src/zix/ring.c | 217 | ||||
-rw-r--r-- | src/zix/ring.h | 141 | ||||
-rw-r--r-- | src/zix/sem.h | 241 | ||||
-rw-r--r-- | src/zix/thread.h | 131 |
5 files changed, 0 insertions, 865 deletions
diff --git a/src/zix/common.h b/src/zix/common.h deleted file mode 100644 index cf07451..0000000 --- a/src/zix/common.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright 2016 David Robillard <d@drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef ZIX_COMMON_H -#define ZIX_COMMON_H - -#include <stdbool.h> - -/** - @addtogroup zix - @{ -*/ - -/** @cond */ -#ifdef ZIX_SHARED -# ifdef _WIN32 -# define ZIX_LIB_IMPORT __declspec(dllimport) -# define ZIX_LIB_EXPORT __declspec(dllexport) -# else -# define ZIX_LIB_IMPORT __attribute__((visibility("default"))) -# define ZIX_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef ZIX_INTERNAL -# define ZIX_API ZIX_LIB_EXPORT -# else -# define ZIX_API ZIX_LIB_IMPORT -# endif -# define ZIX_PRIVATE static -#elif defined(ZIX_INLINE) -# define ZIX_API static inline -# define ZIX_PRIVATE static inline -#else -# define ZIX_API -# define ZIX_PRIVATE static -#endif - -#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 - -/** @endcond */ - -#ifdef __cplusplus -extern "C" { -#endif - -#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__)) -#else -# define ZIX_UNUSED(name) name -#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 -} ZixStatus; - -static inline const char* -zix_strerror(const ZixStatus status) -{ - switch (status) { - case ZIX_STATUS_SUCCESS: return "Success"; - case ZIX_STATUS_ERROR: return "Unknown error"; - case ZIX_STATUS_NO_MEM: return "Out of memory"; - case ZIX_STATUS_NOT_FOUND: return "Not found"; - case ZIX_STATUS_EXISTS: return "Exists"; - case ZIX_STATUS_BAD_ARG: return "Bad argument"; - case ZIX_STATUS_BAD_PERMS: return "Bad permissions"; - } - return "Unknown error"; -} - -/** - 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); - -/** - @} -*/ - -#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 e728a3f..0000000 --- a/src/zix/ring.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - Copyright 2011 David Robillard <d@drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "zix/ring.h" - -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_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 - -#if defined(_MSC_VER) -# include <windows.h> -# define ZIX_READ_BARRIER() MemoryBarrier() -# define ZIX_WRITE_BARRIER() MemoryBarrier() -#elif defined(__GNUC__) -# define ZIX_READ_BARRIER() __atomic_thread_fence(__ATOMIC_ACQUIRE) -# define ZIX_WRITE_BARRIER() __atomic_thread_fence(__ATOMIC_RELEASE) -#else -# pragma message("warning: No memory barriers, possible SMP bugs") -# define ZIX_READ_BARRIER() -# define ZIX_WRITE_BARRIER() -#endif - -struct ZixRingImpl { - 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 -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(uint32_t size) -{ - ZixRing* ring = (ZixRing*)malloc(sizeof(ZixRing)); - ring->write_head = 0; - ring->read_head = 0; - ring->size = next_power_of_two(size); - ring->size_mask = ring->size - 1; - ring->buf = (char*)malloc(ring->size); - return ring; -} - -void -zix_ring_free(ZixRing* ring) -{ - free(ring->buf); - free(ring); -} - -void -zix_ring_mlock(ZixRing* ring) -{ - ZIX_MLOCK(ring, sizeof(ZixRing)); - ZIX_MLOCK(ring->buf, ring->size); -} - -void -zix_ring_reset(ZixRing* ring) -{ - ring->write_head = 0; - ring->read_head = 0; -} - -static inline uint32_t -read_space_internal(const ZixRing* ring, uint32_t r, uint32_t w) -{ - if (r < w) { - return w - r; - } else { - return (w - r + ring->size) & ring->size_mask; - } -} - -uint32_t -zix_ring_read_space(const ZixRing* ring) -{ - return read_space_internal(ring, ring->read_head, ring->write_head); -} - -static inline uint32_t -write_space_internal(const ZixRing* ring, uint32_t r, uint32_t w) -{ - if (r == w) { - return ring->size - 1; - } else if (r < w) { - return ((r - w + ring->size) & ring->size_mask) - 1; - } else { - return (r - w) - 1; - } -} - -uint32_t -zix_ring_write_space(const ZixRing* ring) -{ - return write_space_internal(ring, ring->read_head, ring->write_head); -} - -uint32_t -zix_ring_capacity(const ZixRing* ring) -{ - return ring->size - 1; -} - -static inline uint32_t -peek_internal(const ZixRing* ring, uint32_t r, uint32_t w, - uint32_t size, void* 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* ring, void* dst, uint32_t size) -{ - return peek_internal(ring, ring->read_head, ring->write_head, size, dst); -} - -uint32_t -zix_ring_read(ZixRing* ring, void* dst, uint32_t size) -{ - const uint32_t r = ring->read_head; - const uint32_t w = ring->write_head; - - if (peek_internal(ring, r, w, size, dst)) { - ZIX_READ_BARRIER(); - ring->read_head = (r + size) & ring->size_mask; - return size; - } - - return 0; -} - -uint32_t -zix_ring_skip(ZixRing* ring, uint32_t size) -{ - const uint32_t r = ring->read_head; - const uint32_t w = ring->write_head; - if (read_space_internal(ring, r, w) < size) { - return 0; - } - - ZIX_READ_BARRIER(); - ring->read_head = (r + size) & ring->size_mask; - return size; -} - -uint32_t -zix_ring_write(ZixRing* ring, const void* src, uint32_t size) -{ - const uint32_t r = ring->read_head; - const uint32_t w = ring->write_head; - if (write_space_internal(ring, r, w) < size) { - return 0; - } - - if (w + size <= ring->size) { - memcpy(&ring->buf[w], src, size); - ZIX_WRITE_BARRIER(); - ring->write_head = (w + size) & ring->size_mask; - } else { - const uint32_t this_size = ring->size - w; - memcpy(&ring->buf[w], src, this_size); - memcpy(&ring->buf[0], (const char*)src + this_size, size - this_size); - ZIX_WRITE_BARRIER(); - ring->write_head = size - this_size; - } - - return size; -} diff --git a/src/zix/ring.h b/src/zix/ring.h deleted file mode 100644 index 99437f8..0000000 --- a/src/zix/ring.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright 2011-2014 David Robillard <d@drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef ZIX_RING_H -#define ZIX_RING_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 single reader and single writer, and realtime safe - on both ends. -*/ -typedef struct ZixRingImpl ZixRing; - -/** - 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_ring_new(uint32_t size); - -/** - Destroy a ring. -*/ -ZIX_API -void -zix_ring_free(ZixRing* 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 (i.e. this function MUST be called first in order for the - ring to be truly real-time safe). - -*/ -ZIX_API -void -zix_ring_mlock(ZixRing* ring); - -/** - Reset (empty) a ring. - - This function is NOT thread-safe, it may only be called when there are no - readers or writers. -*/ -ZIX_API -void -zix_ring_reset(ZixRing* ring); - -/** - Return the number of bytes of space available for reading. -*/ -ZIX_CONST_API -uint32_t -zix_ring_read_space(const ZixRing* ring); - -/** - Return the number of bytes of space available for writing. -*/ -ZIX_CONST_API -uint32_t -zix_ring_write_space(const ZixRing* ring); - -/** - Return the capacity (i.e. total write space when empty). -*/ -ZIX_CONST_API -uint32_t -zix_ring_capacity(const ZixRing* ring); - -/** - Read from the ring without advancing the read head. -*/ -ZIX_API -uint32_t -zix_ring_peek(ZixRing* ring, void* dst, uint32_t size); - -/** - Read from the ring and advance the read head. -*/ -ZIX_API -uint32_t -zix_ring_read(ZixRing* ring, void* dst, uint32_t size); - -/** - Skip data in the ring (advance read head without reading). -*/ -ZIX_API -uint32_t -zix_ring_skip(ZixRing* ring, uint32_t size); - -/** - Write data to the ring. -*/ -ZIX_API -uint32_t -zix_ring_write(ZixRing* ring, const void* src, uint32_t size); - -/** - @} - @} -*/ - -#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 7ced8dc..0000000 --- a/src/zix/sem.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - Copyright 2012-2014 David Robillard <d@drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef ZIX_SEM_H -#define ZIX_SEM_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* sem, unsigned initial); - -/** - Destroy `sem`. -*/ -static inline void -zix_sem_destroy(ZixSem* sem); - -/** - Increment (and signal any waiters). - Realtime safe. -*/ -static inline void -zix_sem_post(ZixSem* sem); - -/** - Wait until count is > 0, then decrement. - Obviously not realtime safe. -*/ -static inline ZixStatus -zix_sem_wait(ZixSem* sem); - -/** - Non-blocking version of wait(). - - @return true if decrement was successful (lock was acquired). -*/ -static inline bool -zix_sem_try_wait(ZixSem* sem); - -/** - @cond -*/ - -#ifdef __APPLE__ - -struct ZixSemImpl { - semaphore_t sem; -}; - -static inline ZixStatus -zix_sem_init(ZixSem* sem, unsigned val) -{ - return semaphore_create(mach_task_self(), &sem->sem, SYNC_POLICY_FIFO, val) - ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; -} - -static inline void -zix_sem_destroy(ZixSem* sem) -{ - semaphore_destroy(mach_task_self(), sem->sem); -} - -static inline void -zix_sem_post(ZixSem* sem) -{ - semaphore_signal(sem->sem); -} - -static inline ZixStatus -zix_sem_wait(ZixSem* sem) -{ - if (semaphore_wait(sem->sem) != KERN_SUCCESS) { - return ZIX_STATUS_ERROR; - } - return ZIX_STATUS_SUCCESS; -} - -static inline bool -zix_sem_try_wait(ZixSem* 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* sem, unsigned initial) -{ - sem->sem = CreateSemaphore(NULL, initial, LONG_MAX, NULL); - return (sem->sem) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; -} - -static inline void -zix_sem_destroy(ZixSem* sem) -{ - CloseHandle(sem->sem); -} - -static inline void -zix_sem_post(ZixSem* sem) -{ - ReleaseSemaphore(sem->sem, 1, NULL); -} - -static inline ZixStatus -zix_sem_wait(ZixSem* 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* 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* sem, unsigned initial) -{ - return sem_init(&sem->sem, 0, initial) - ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; -} - -static inline void -zix_sem_destroy(ZixSem* sem) -{ - sem_destroy(&sem->sem); -} - -static inline void -zix_sem_post(ZixSem* sem) -{ - sem_post(&sem->sem); -} - -static inline ZixStatus -zix_sem_wait(ZixSem* 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* 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 dbfdf36..0000000 --- a/src/zix/thread.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright 2012-2014 David Robillard <d@drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#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 */ |