diff options
Diffstat (limited to 'plugins/eg-sampler.lv2/zix')
-rw-r--r-- | plugins/eg-sampler.lv2/zix/common.h | 83 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/zix/ring.c | 231 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/zix/ring.h | 136 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/zix/sem.h | 236 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/zix/thread.h | 133 |
5 files changed, 0 insertions, 819 deletions
diff --git a/plugins/eg-sampler.lv2/zix/common.h b/plugins/eg-sampler.lv2/zix/common.h deleted file mode 100644 index f113cfe..0000000 --- a/plugins/eg-sampler.lv2/zix/common.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright 2011-2012 David Robillard <http://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 - -/** - @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 -#else -# define ZIX_API -#endif -/** @endcond */ - -#ifdef __cplusplus -extern "C" { -#else -# include <stdbool.h> -#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; - -/** - Function for comparing two elements. -*/ -typedef int (*ZixComparator)(const void* a, const void* b, 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/plugins/eg-sampler.lv2/zix/ring.c b/plugins/eg-sampler.lv2/zix/ring.c deleted file mode 100644 index 29d415c..0000000 --- a/plugins/eg-sampler.lv2/zix/ring.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - Copyright 2011-2012 David Robillard <http://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 <stdint.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(__APPLE__) -# include <libkern/OSAtomic.h> -# define ZIX_FULL_BARRIER() OSMemoryBarrier() -#elif defined(_WIN32) -# include <windows.h> -# define ZIX_FULL_BARRIER() MemoryBarrier() -#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) -# define ZIX_FULL_BARRIER() __sync_synchronize() -#else -# pragma message("warning: No memory barriers, possible SMP bugs") -# define ZIX_FULL_BARRIER() -#endif - -/* No support for any systems with separate read and write barriers */ -#define ZIX_READ_BARRIER() ZIX_FULL_BARRIER() -#define ZIX_WRITE_BARRIER() ZIX_FULL_BARRIER() - -#include "zix/ring.h" - -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 >> 1; - size |= size >> 2; - size |= size >> 4; - size |= size >> 8; - size |= size >> 16; - 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) -{ - const uint32_t r = ring->read_head; - const uint32_t w = ring->write_head; - - return peek_internal(ring, r, w, 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; - } else { - 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], (char*)src + this_size, size - this_size); - ZIX_WRITE_BARRIER(); - ring->write_head = size - this_size; - } - - return size; -} - -void* -zix_ring_write_head(ZixRing* ring) -{ - return &ring->buf[ring->write_head]; -} diff --git a/plugins/eg-sampler.lv2/zix/ring.h b/plugins/eg-sampler.lv2/zix/ring.h deleted file mode 100644 index dd45769..0000000 --- a/plugins/eg-sampler.lv2/zix/ring.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright 2011-2012 David Robillard <http://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 <stdint.h> - -#include "zix/common.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 @c size - 1 bytes may be stored in the ring at once. -*/ -ZixRing* -zix_ring_new(uint32_t size); - -/** - Destroy a ring. -*/ -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). - -*/ -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. -*/ -void -zix_ring_reset(ZixRing* ring); - -/** - Return the number of bytes of space available for reading. -*/ -uint32_t -zix_ring_read_space(const ZixRing* ring); - -/** - Return the number of bytes of space available for writing. -*/ -uint32_t -zix_ring_write_space(const ZixRing* ring); - -/** - Return the capacity (i.e. total write space when empty). -*/ -uint32_t -zix_ring_capacity(const ZixRing* ring); - -/** - Read from the ring without advancing the read head. -*/ -uint32_t -zix_ring_peek(ZixRing* ring, void* dst, uint32_t size); - -/** - Read from the ring and advance the read head. -*/ -uint32_t -zix_ring_read(ZixRing* ring, void* dst, uint32_t size); - -/** - Skip data in the ring (advance read head without reading). -*/ -uint32_t -zix_ring_skip(ZixRing* ring, uint32_t size); - -/** - Write data to the ring. -*/ -uint32_t -zix_ring_write(ZixRing* ring, const void* src, uint32_t size); - -/** - Return a pointer to the current position of the write head. -*/ -void* -zix_ring_write_head(ZixRing* ring); - -/** - @} - @} -*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ZIX_RING_H */ diff --git a/plugins/eg-sampler.lv2/zix/sem.h b/plugins/eg-sampler.lv2/zix/sem.h deleted file mode 100644 index d536c99..0000000 --- a/plugins/eg-sampler.lv2/zix/sem.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - Copyright 2012-2012 David Robillard <http://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 - -#ifdef __APPLE__ -# include <mach/mach.h> -#elif defined(_WIN32) -# include <windows.h> -#else -# include <semaphore.h> -# include <errno.h> -#endif - -#include "zix/common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - @addtogroup zix - @{ - @name Semaphore - @{ -*/ - -/** - 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 @c sem to @c initial. -*/ -static inline ZixStatus -zix_sem_init(ZixSem* sem, unsigned initial); - -/** - Destroy @c 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 initial) -{ - return semaphore_create(mach_task_self(), &sem->sem, SYNC_POLICY_FIFO, 0) - ? 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_ERROR : ZIX_STATUS_SUCCESS; -} - -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) -{ - WaitForSingleObject(sem->sem, 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/plugins/eg-sampler.lv2/zix/thread.h b/plugins/eg-sampler.lv2/zix/thread.h deleted file mode 100644 index 602b701..0000000 --- a/plugins/eg-sampler.lv2/zix/thread.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright 2012-2012 David Robillard <http://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 - -#ifdef _WIN32 -# include <windows.h> -#else -# include <errno.h> -# include <pthread.h> -#endif - -#include "zix/common.h" - -#ifdef __cplusplus -extern "C" { -#else -# include <stdbool.h> -#endif - -/** - @addtogroup zix - @{ - @name Thread - @{ -*/ - -#ifdef _WIN32 -typedef HANDLE ZixThread; -#else -typedef pthread_t ZixThread; -#endif - -/** - Initialize @c thread to a new thread. - - The thread will immediately be launched, calling @c function with @c arg - as the only parameter. -*/ -static inline ZixStatus -zix_thread_create(ZixThread* thread, - size_t stack_size, - void* (*function)(void*), - void* arg); - -/** - Join @c thread (block until @c 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) -{ - 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); - - if (ret == EAGAIN) { - return ZIX_STATUS_NO_MEM; - } else if (ret == EINVAL) { - return ZIX_STATUS_BAD_ARG; - } else if (ret == EPERM) { - return ZIX_STATUS_BAD_PERMS; - } else if (ret) { - return ZIX_STATUS_ERROR; - } - - return 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 */ |