Adds further ext deps as-is binaries copies from customers env.
Qt6 Migration CI / migrate (push) Canceled after 0s

This commit is contained in:
torsten committed 2026-10-23 16:13:31 +00:00
1 parent 48129fdab2
commit 48d9b9bd49
3700 files changed
+2132394

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
// Copyright(c) 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ALIGN_H
#define DDSRT_ALIGN_H
#if defined (__cplusplus)
extern "C" {
#endif
#define dds_alignof _Alignof
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_ALIGN_H */
+28
View File
@@ -0,0 +1,28 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ARCH_H
#define DDSRT_ARCH_H
#if _WIN32
# if _WIN64
# define DDSRT_64BIT 1
# else
# define DDSRT_64BIT 0
# endif
#else
# if defined(_LP64)
# define DDSRT_64BIT 1
# else
# define DDSRT_64BIT 0
# endif
#endif
#endif /* DDSRT_ARCH_H */
+246
View File
@@ -0,0 +1,246 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ATOMICS_H
#define DDSRT_ATOMICS_H
#include <stddef.h>
#include "dds/export.h"
#include "dds/ddsrt/arch.h"
#include "dds/ddsrt/endian.h"
#include "dds/ddsrt/types.h"
/**
* @file atomics.h
* @brief Contains functions and types for atomic operations on various types
*
* This header file declares functions and types for atomic operations on uint32_t,
* uint64_t, uintptr_t, and void* types.
*
* 64-bit atomics are not supported by all hardware, but it would be a shame not to use them when
* they are available. That necessitates an alternative implementation when they are not, either in
* the form of a different implementation where it is used, or as an emulation using a mutex in
* ddsrt. It seems that the places where they'd be used end up adding a mutex, so an emulation in
* ddsrt while being able to check whether it is supported by hardware is a sensible approach.
*/
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Types on which atomic operations are defined.
*
* @note 64-bit types are defined even if atomic operations on them are not
* really supported.
*/
typedef struct { uint32_t v; } ddsrt_atomic_uint32_t; /**< Type for atomic operations on uint32_t */
typedef struct { uint64_t v; } ddsrt_atomic_uint64_t; /**< Type for atomic operations on uint64_t */
typedef struct { uintptr_t v; } ddsrt_atomic_uintptr_t; /**< Type for atomic operations on uintptr_t */
typedef ddsrt_atomic_uintptr_t ddsrt_atomic_voidp_t; /**< Convenience type for atomic operations on void pointers */
#if DDSRT_64BIT
# define DDSRT_HAVE_ATOMIC64 1
#endif
/**
* @brief Initializers for the types on which atomic operations are defined.
*/
#define DDSRT_ATOMIC_UINT32_INIT(v) { (v) } /**< Initializer for ddsrt_atomic_uint32_t */
#define DDSRT_ATOMIC_UINT64_INIT(v) { (v) } /**< Initializer for ddsrt_atomic_uint64_t */
#define DDSRT_ATOMIC_UINTPTR_INIT(v) { (v) } /**< Initializer for ddsrt_atomic_uintptr_t */
#define DDSRT_ATOMIC_VOIDP_INIT(v) { (uintptr_t) (v) } /**< Initializer for ddsrt_atomic_voidp_t */
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40100
#include "dds/ddsrt/atomics/gcc.h"
#elif defined(_WIN32)
#include "dds/ddsrt/atomics/msvc.h"
#elif defined(__sun)
#include "dds/ddsrt/atomics/sun.h"
#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__)
#include "dds/ddsrt/atomics/arm.h"
#else
#error "Atomic operations are not supported"
#endif
#if ! DDSRT_HAVE_ATOMIC64
/**
* @brief Fetch the value of a 64-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x);
/**
* @brief Assign a 64-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_EXPORT void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_EXPORT void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x);
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x);
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_EXPORT void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x);
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x);
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_EXPORT void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_EXPORT void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_EXPORT void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_EXPORT void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_EXPORT uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
/**
* @brief Compare and swap a 64-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_EXPORT int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_t des);
#endif
/**
* @brief Initialize mutexes for atomics
*/
void ddsrt_atomics_init (void);
/**
* @brief Destroy mutexes for atomics
*/
void ddsrt_atomics_fini (void);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_ATOMICS_H */
+624
View File
@@ -0,0 +1,624 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ATOMICS_ARM_H
#define DDSRT_ATOMICS_ARM_H
#if defined (__cplusplus)
extern "C" {
#endif
#if !defined(__arm__)
#define __arm__
#endif
/* IAR documentation states that __CPU_MODE__ is a predefined preprocessor
symbol reflecting the selected CPU mode and is defined to 1 for Thumb and
2 for ARM. */
#if !defined(__thumb__) && __CPU_MODE__ == 1
#define __thumb__
#endif
/**
* @file arm.h
* @brief Contains functions and types for atomic operations on various types for arm.
*
* This header file defines functions for atomic operations on uint32_t,
* uint64_t, uintptr_t, and void* types.
*/
/* LD, ST */
/**
* @brief Fetch the value of a 32-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
/**
* @brief Fetch the value of an uintptr atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
/**
* @brief Fetch the value of a void pointer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
/**
* @brief Assign a 32-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
/**
* @brief Assign an uintptr atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
/**
* @brief Assign a void pointer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* CAS */
/**
* @brief Compare and swap a 32-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_cas32 (volatile ddsrt_atomic_uint32_t *x, uint32_t exp, uint32_t des) {
register int result;
asm volatile ("ldrex r0, [%1]\n\t" /*exclusive load of ptr */
"cmp r0, %2\n\t" /*compare the oldval == *ptr */
#if defined(__thumb__)
"ite eq\n\t"
#endif
"strexeq %0, %3, [%1]\n\t" /*store if eq, strex+eq*/
#if defined(__thumb__)
"clrexne"
#endif
: "=&r" (result)
: "r"(&x->v), "r"(exp),"r"(des)
: "r0");
return result == 0;
}
/**
* @brief Compare and swap an uintptr atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_casptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t exp, uintptr_t des) {
return ddsrt_atomic_cas32 ((volatile ddsrt_atomic_uint32_t *) x, exp, des);
}
/**
* @brief Compare and swap a void pointer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_casvoidp (volatile ddsrt_atomic_voidp_t *x, void *exp, void *des) {
return ddsrt_atomic_casptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) exp, (uintptr_t) des);
}
/* ADD */
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
register unsigned int result;
asm volatile ("1: ldrex %0, [%1]\n\t"
"add %0, %0, %2\n\t"
"strex r1, %0, [%1]\n\t"
"cmp r1, #0\n\t"
"bne 1b"
: "=&r" (result)
: "r"(&x->v), "r"(v)
: "r1");
return result;
}
/**
* @brief Increment (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
inline uintptr_t ddsrt_atomic_addptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return ddsrt_atomic_add32_nv ((volatile ddsrt_atomic_uint32_t *) x, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_add32_nv (x, v);
}
/**
* @brief Increment (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
(void) ddsrt_atomic_addptr_nv (x, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return ddsrt_atomic_add32_nv (x, v) - v;
}
/**
* @brief Increment (by given amount) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
inline uint32_t ddsrt_atomic_addptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return ddsrt_atomic_addptr_nv (x, v) - v;
}
/* SUB */
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return ddsrt_atomic_add32_nv (x, -v);
}
/**
* @brief Decrement (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return ddsrt_atomic_addptr_nv (x, -v);
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return ddsrt_atomic_add32_ov (x, -v);
}
/**
* @brief Decrement (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_subptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return ddsrt_atomic_addptr_ov (x, -v);
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
ddsrt_atomic_add32 (x, -v);
}
/**
* @brief Decrement (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
ddsrt_atomic_addptr (x, -v);
}
/* INC */
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_add32_ov (x, 1);
}
/**
* @brief Increment (by one) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
inline uintptr_t ddsrt_atomic_incptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return ddsrt_atomic_addptr_ov (x, 1);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_add32_nv (x, 1);
}
/**
* @brief Increment (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
inline uintptr_t ddsrt_atomic_incptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return ddsrt_atomic_addptr_nv (x, 1);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
(void) ddsrt_atomic_inc32_nv (x);
}
/**
* @brief Increment (by one) an uintptr integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) {
(void) ddsrt_atomic_incptr_nv (x);
}
/* DEC */
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_sub32_ov (x, 1);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
inline uintptr_t ddsrt_atomic_decptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return ddsrt_atomic_subptr_ov (x, 1);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_sub32_nv (x, 1);
}
/**
* @brief Decrement (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
inline uintptr_t ddsrt_atomic_decptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return ddsrt_atomic_subptr_nv (x, 1);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
(void) ddsrt_atomic_dec32_nv (x);
}
/**
* @brief Decrement (by one) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
inline void ddsrt_atomic_decptr (volatile ddsrt_atomic_uintptr_t *x) {
(void) ddsrt_atomic_decptr_nv (x);
}
/* AND */
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
inline uint32_t ddsrt_atomic_and32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (!ddsrt_atomic_cas32 (x, oldval, newval));
return oldval;
}
/**
* @brief Bitwise AND an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
inline uintptr_t ddsrt_atomic_andptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
uintptr_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (!ddsrt_atomic_casptr (x, oldval, newval));
return oldval;
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
inline uint32_t ddsrt_atomic_and32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (!ddsrt_atomic_cas32 (x, oldval, newval));
return newval;
}
/**
* @brief Bitwise AND an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
inline uintptr_t ddsrt_atomic_andptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
uintptr_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (!ddsrt_atomic_casptr (x, oldval, newval));
return newval;
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_and32_nv (x, v);
}
/**
* @brief Bitwise AND an uintptr atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
inline void ddsrt_atomic_andptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
(void) ddsrt_atomic_andptr_nv (x, v);
}
/* OR */
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
inline uint32_t ddsrt_atomic_or32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (!ddsrt_atomic_cas32 (x, oldval, newval));
return oldval;
}
/**
* @brief Bitwise OR an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
inline uintptr_t ddsrt_atomic_orptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
uintptr_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (!ddsrt_atomic_casptr (x, oldval, newval));
return oldval;
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
inline uint32_t ddsrt_atomic_or32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (!ddsrt_atomic_cas32 (x, oldval, newval));
return newval;
}
/**
* @brief Bitwise OR an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
inline uintptr_t ddsrt_atomic_orptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
uintptr_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (!ddsrt_atomic_casptr (x, oldval, newval));
return newval;
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_or32_nv (x, v);
}
/**
* @brief Bitwise OR an uintptr atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
inline void ddsrt_atomic_orptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
(void) ddsrt_atomic_orptr_nv (x, v);
}
/* FENCES */
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence (void) {
__asm volatile ("dmb" : : : "memory");
}
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence_ldld (void) {
ddsrt_atomic_fence ();
}
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence_stst (void) {
ddsrt_atomic_fence ();
}
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence_rel (void) {
ddsrt_atomic_fence ();
}
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_ATOMICS_ARM_H */
+984
View File
@@ -0,0 +1,984 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ATOMICS_GCC_H
#define DDSRT_ATOMICS_GCC_H
#include "dds/ddsrt/misc.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
DDSRT_WARNING_GNUC_OFF(old-style-cast)
DDSRT_WARNING_CLANG_OFF(old-style-cast)
#endif
#if ( DDSRT_HAVE_ATOMIC64 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) || \
(!DDSRT_HAVE_ATOMIC64 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
# define DDSRT_HAVE_ATOMIC_LIFO 1
#endif
/**
* @file gcc.h
* @brief Contains functions and types for atomic operations on various types for gcc.
*
* This header file defines functions for atomic operations on uint32_t,
* uint64_t, uintptr_t, and void* types.
*
* It also declares atomic operations for a lifo linked list.
*/
/* LD, ST */
/**
* @brief Fetch the value of a 32-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline uint32_t ddsrt_atomic_ld32(const volatile ddsrt_atomic_uint32_t *x)
{
return x->v;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Fetch the value of a 64-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline uint64_t ddsrt_atomic_ld64(const volatile ddsrt_atomic_uint64_t *x)
{
return x->v;
}
#endif
/**
* @brief Fetch the value of an uintptr atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline uintptr_t ddsrt_atomic_ldptr(const volatile ddsrt_atomic_uintptr_t *x)
{
return x->v;
}
/**
* @brief Fetch the value of a void pointer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline void *ddsrt_atomic_ldvoidp(const volatile ddsrt_atomic_voidp_t *x)
{
return (void *) ddsrt_atomic_ldptr(x);
}
/**
* @brief Assign a 32-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline void ddsrt_atomic_st32(volatile ddsrt_atomic_uint32_t *x, uint32_t v)
{
x->v = v;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Assign a 64-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline void ddsrt_atomic_st64(volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
x->v = v;
}
#endif
/**
* @brief Assign an uintptr atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline void ddsrt_atomic_stptr(volatile ddsrt_atomic_uintptr_t *x, uintptr_t v)
{
x->v = v;
}
/**
* @brief Assign a void pointer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline void ddsrt_atomic_stvoidp(volatile ddsrt_atomic_voidp_t *x, void *v)
{
ddsrt_atomic_stptr(x, (uintptr_t)v);
}
/* INC */
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc32(volatile ddsrt_atomic_uint32_t *x) {
__sync_fetch_and_add (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
__sync_fetch_and_add (&x->v, 1);
}
#endif
/**
* @brief Increment (by one) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_incptr(volatile ddsrt_atomic_uintptr_t *x) {
__sync_fetch_and_add (&x->v, 1);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return __sync_fetch_and_add (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_inc64_ov (volatile ddsrt_atomic_uint64_t *x) {
return __sync_fetch_and_add (&x->v, 1);
}
#endif
/**
* @brief Increment (by one) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_incptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return __sync_fetch_and_add (&x->v, 1);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return __sync_add_and_fetch (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return __sync_add_and_fetch (&x->v, 1);
}
#endif
/**
* @brief Increment (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_incptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return __sync_add_and_fetch (&x->v, 1);
}
/* DEC */
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
__sync_fetch_and_sub (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
__sync_fetch_and_sub (&x->v, 1);
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_decptr (volatile ddsrt_atomic_uintptr_t *x) {
__sync_fetch_and_sub (&x->v, 1);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return __sync_sub_and_fetch (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return __sync_sub_and_fetch (&x->v, 1);
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_decptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return __sync_sub_and_fetch (&x->v, 1);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) {
return __sync_fetch_and_sub (&x->v, 1);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_dec64_ov (volatile ddsrt_atomic_uint64_t *x) {
return __sync_fetch_and_sub (&x->v, 1);
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_decptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return __sync_fetch_and_sub (&x->v, 1);
}
/* ADD */
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
__sync_fetch_and_add (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
__sync_fetch_and_add (&x->v, v);
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
__sync_fetch_and_add (&x->v, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_fetch_and_add (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_add64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_fetch_and_add (&x->v, v);
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_addptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_fetch_and_add (&x->v, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_add_and_fetch (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_add_and_fetch (&x->v, v);
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_addptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_add_and_fetch (&x->v, v);
}
/* SUB */
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
__sync_fetch_and_sub (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
__sync_fetch_and_sub (&x->v, v);
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
__sync_fetch_and_sub (&x->v, v);
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_fetch_and_sub (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_sub64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_fetch_and_sub (&x->v, v);
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_subptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_fetch_and_sub (&x->v, v);
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_sub_and_fetch (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_sub_and_fetch (&x->v, v);
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_sub_and_fetch (&x->v, v);
}
/* AND */
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
__sync_fetch_and_and (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
__sync_fetch_and_and (&x->v, v);
}
#endif
/**
* @brief Bitwise AND an uintptr atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_andptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
__sync_fetch_and_and (&x->v, v);
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_and32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_fetch_and_and (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_fetch_and_and (&x->v, v);
}
#endif
/**
* @brief Bitwise AND an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_andptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_fetch_and_and (&x->v, v);
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_and32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_and_and_fetch (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_and_and_fetch (&x->v, v);
}
#endif
/**
* @brief Bitwise AND an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_andptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_and_and_fetch (&x->v, v);
}
/* OR */
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
__sync_fetch_and_or (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
__sync_fetch_and_or (&x->v, v);
}
#endif
/**
* @brief Bitwise OR an uintptr atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_orptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
__sync_fetch_and_or (&x->v, v);
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_or32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_fetch_and_or (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_fetch_and_or (&x->v, v);
}
#endif
/**
* @brief Bitwise OR an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_orptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_fetch_and_or (&x->v, v);
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_or32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return __sync_or_and_fetch (&x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return __sync_or_and_fetch (&x->v, v);
}
#endif
/**
* @brief Bitwise OR an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_orptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return __sync_or_and_fetch (&x->v, v);
}
/* CAS */
/**
* @brief Compare and swap a 32-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_cas32 (volatile ddsrt_atomic_uint32_t *x, uint32_t exp, uint32_t des) {
return __sync_bool_compare_and_swap (&x->v, exp, des);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Compare and swap a 64-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_t des) {
return __sync_bool_compare_and_swap (&x->v, exp, des);
}
#endif
/**
* @brief Compare and swap an uintptr atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_casptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t exp, uintptr_t des) {
return __sync_bool_compare_and_swap (&x->v, exp, des);
}
/**
* @brief Compare and swap a void pointer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_casvoidp (volatile ddsrt_atomic_voidp_t *x, void *exp, void *des) {
return ddsrt_atomic_casptr (x, (uintptr_t) exp, (uintptr_t) des);
}
#if DDSRT_HAVE_ATOMIC_LIFO
#if DDSRT_HAVE_ATOMIC64
#if defined(__s390__) || defined(__s390x__) || defined(__zarch__)
typedef __int128_t __attribute__((aligned(16))) ddsrt_atomic_int128_t;
#else
typedef __int128_t ddsrt_atomic_int128_t;
#endif
typedef union { ddsrt_atomic_int128_t x; struct { uintptr_t a, b; } s; } ddsrt_atomic_uintptr2_t;
#else
typedef union { uint64_t x; struct { uintptr_t a, b; } s; } ddsrt_atomic_uintptr2_t;
#endif
/**
* @brief A lifo linked list supporting atomic operations
*/
typedef struct {
ddsrt_atomic_uintptr2_t aba_head;
} ddsrt_atomic_lifo_t;
/**
* @brief Initialize the lifo list
*
* @param[out] head the lifo list
*/
DDS_EXPORT void ddsrt_atomic_lifo_init(ddsrt_atomic_lifo_t *head);
/**
* @brief Push to the lifo list
*
* @param[in,out] head the lifo list
* @param[in] elem the element to push to it
* @param[in] linkoff the link offset with respect to elem
*/
DDS_EXPORT void ddsrt_atomic_lifo_push(ddsrt_atomic_lifo_t *head, void *elem, size_t linkoff);
/**
* @brief Pop from the lifo list
*
* @param[in,out] head the lifo list
* @param[in] linkoff the link offset with respect to elem
*
* @return pointer to the popped elem
*/
DDS_EXPORT void *ddsrt_atomic_lifo_pop(ddsrt_atomic_lifo_t *head, size_t linkoff);
/**
* @brief Push a chain of elements to the lifo list
*
* @param[in,out] head the lifo list
* @param[in] first the element that will be at the top of the stack
* @param[in] last the element connected to the existing chain
* @param[in] linkoff the link offset with respect to the element
*/
DDS_EXPORT void ddsrt_atomic_lifo_pushmany(ddsrt_atomic_lifo_t *head, void *first, void *last, size_t linkoff);
/**
* @brief Compare and swap two void pointers atomically
*
* Assigns a1 to x.a and b1 to x.b iff (x.a == a0 && x.b == b0)
*
* @param[in,out] x pointer to two variables whose value to swap
* @param[in] a0 the value to test x.a for
* @param[in] b0 the value to test x.b for
* @param[in] a1 the value to assign to x.a
* @param[in] b1 the value to assign to x.b
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_casvoidp2 (volatile ddsrt_atomic_uintptr2_t *x, uintptr_t a0, uintptr_t b0, uintptr_t a1, uintptr_t b1) {
ddsrt_atomic_uintptr2_t o, n;
o.s.a = a0; o.s.b = b0;
n.s.a = a1; n.s.b = b1;
#if defined(__s390__) || defined(__s390x__) || defined(__zarch__)
return __sync_bool_compare_and_swap ((ddsrt_atomic_int128_t*)__builtin_assume_aligned(&x->x, 16), o.x, n.x);
#else
return __sync_bool_compare_and_swap (&x->x, o.x, n.x);
#endif
}
#endif
/* FENCES */
/**
* @brief insert a memory barrier for store and load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence (void) {
__sync_synchronize ();
}
/**
* @brief insert memory barrier for load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_ldld (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
__sync_synchronize ();
#endif
}
/**
* @brief insert memory barrier for store operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_stst (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
__sync_synchronize ();
#endif
}
/**
* @brief insert memory barrier for load store and load load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_acq (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#else
__asm__ volatile ("" ::: "memory");
#endif
}
/**
* @brief insert memory barrier for load store and store store operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_rel (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#else
__asm__ volatile ("" ::: "memory");
#endif
}
#if defined (__cplusplus)
DDSRT_WARNING_CLANG_ON(old-style-cast)
DDSRT_WARNING_GNUC_ON(old-style-cast)
}
#endif
#endif /* DDSRT_ATOMICS_GCC_H */
+900
View File
@@ -0,0 +1,900 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ATOMICS_MSVC_H
#define DDSRT_ATOMICS_MSVC_H
#include "dds/ddsrt/misc.h"
#if defined (__cplusplus)
extern "C" {
#endif
/* x86 has supported 64-bit CAS for a long time, so Windows ought to
provide all the interlocked operations for 64-bit operands on x86
platforms, but it doesn't. */
#define DDSRT_ATOMIC_OP32(name, ...) name ((volatile long *) __VA_ARGS__)
#if DDSRT_HAVE_ATOMIC64
#define DDSRT_ATOMIC_OP64(name, ...) name##64 ((volatile int64_t *) __VA_ARGS__)
#define DDSRT_ATOMIC_PTROP(name, ...) name##64 ((volatile int64_t *) __VA_ARGS__)
#else
#define DDSRT_ATOMIC_PTROP(name, ...) name ((volatile long *) __VA_ARGS__)
#endif
/**
* @file msvc.h
* @brief Contains functions and types for atomic operations on various types for msvc.
*
* This header file defines functions for atomic operations on uint32_t,
* uint64_t, uintptr_t, and void* types.
*/
/* LD, ST */
/**
* @brief Fetch the value of a 32-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Fetch the value of a 64-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x) { return x->v; }
#endif
/**
* @brief Fetch the value of an uintptr atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
/**
* @brief Fetch the value of a void pointer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
DDS_INLINE_EXPORT inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
/**
* @brief Assign a 32-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Assign a 64-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { x->v = v; }
#endif
/**
* @brief Assign an uintptr atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
/**
* @brief Assign a void pointer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* CAS */
/**
* @brief Compare and swap a 32-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_cas32 (volatile ddsrt_atomic_uint32_t *x, uint32_t exp, uint32_t des) {
return DDSRT_ATOMIC_OP32 (InterlockedCompareExchange, &x->v, des, exp) == exp;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Compare and swap a 64-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_t des) {
return DDSRT_ATOMIC_OP64 (InterlockedCompareExchange, &x->v, des, exp) == exp;
}
#endif
/**
* @brief Compare and swap an uintptr atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_casptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t exp, uintptr_t des) {
return DDSRT_ATOMIC_PTROP (InterlockedCompareExchange, &x->v, des, exp) == exp;
}
/**
* @brief Compare and swap a void pointer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
DDS_INLINE_EXPORT inline int ddsrt_atomic_casvoidp (volatile ddsrt_atomic_voidp_t *x, void *exp, void *des) {
return ddsrt_atomic_casptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) exp, (uintptr_t) des);
}
/* INC */
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
DDSRT_ATOMIC_OP32 (InterlockedIncrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
DDSRT_ATOMIC_OP64 (InterlockedIncrement, &x->v);
}
#endif
/**
* @brief Increment (by one) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) {
DDSRT_ATOMIC_PTROP (InterlockedIncrement, &x->v);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return DDSRT_ATOMIC_OP32 (InterlockedIncrement, &x->v) - 1;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_inc64_ov (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedIncrement, &x->v) - 1;
}
#endif
/**
* @brief Increment (by one) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_incptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return DDSRT_ATOMIC_PTROP (InterlockedIncrement, &x->v) - 1;
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return DDSRT_ATOMIC_OP32 (InterlockedIncrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedIncrement, &x->v);
}
#endif
/**
* @brief Increment (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_incptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return DDSRT_ATOMIC_PTROP (InterlockedIncrement, &x->v);
}
/* DEC */
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
DDSRT_ATOMIC_OP32 (InterlockedDecrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
DDSRT_ATOMIC_OP64 (InterlockedDecrement, &x->v);
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_decptr (volatile ddsrt_atomic_uintptr_t *x) {
DDSRT_ATOMIC_PTROP (InterlockedDecrement, &x->v);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return DDSRT_ATOMIC_OP32 (InterlockedDecrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedDecrement, &x->v);
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_decptr_nv (volatile ddsrt_atomic_uintptr_t *x) {
return DDSRT_ATOMIC_PTROP (InterlockedDecrement, &x->v);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) {
return DDSRT_ATOMIC_OP32 (InterlockedDecrement, &x->v) + 1;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_dec64_ov (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedDecrement, &x->v) + 1;
}
#endif
/**
* @brief Decrement (by one) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_decptr_ov (volatile ddsrt_atomic_uintptr_t *x) {
return DDSRT_ATOMIC_PTROP (InterlockedDecrement, &x->v) + 1;
}
/* ADD */
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, v);
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_add64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, v);
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_addptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, v) + v;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, v) + v;
}
#endif
/**
* @brief Increment (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_addptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, v) + v;
}
/* SUB */
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_sub64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_subptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, -v);
DDSRT_WARNING_MSVC_ON(4146)
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_OP32 (InterlockedExchangeAdd, &x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146)
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_OP64 (InterlockedExchangeAdd, &x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146)
}
#endif
/**
* @brief Decrement (by given amount) an uintptr atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd, &x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146)
}
/* AND */
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
DDSRT_ATOMIC_OP32 (InterlockedAnd, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
DDSRT_ATOMIC_OP64 (InterlockedAnd, &x->v, v);
}
#endif
/**
* @brief Bitwise AND an uintptr atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_andptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
DDSRT_ATOMIC_PTROP (InterlockedAnd, &x->v, v);
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_and32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedAnd, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedAnd, &x->v, v);
}
#endif
/**
* @brief Bitwise AND an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_andptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedAnd, &x->v, v);
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_and32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedAnd, &x->v, v) & v;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedAnd, &x->v, v) & v;
}
#endif
/**
* @brief Bitwise AND an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_andptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedAnd, &x->v, v) & v;
}
/* OR */
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
DDSRT_ATOMIC_OP32 (InterlockedOr, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
DDSRT_ATOMIC_OP64 (InterlockedOr, &x->v, v);
}
#endif
/**
* @brief Bitwise OR an uintptr atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_orptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
DDSRT_ATOMIC_PTROP (InterlockedOr, &x->v, v);
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_or32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedOr, &x->v, v);
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedOr, &x->v, v);
}
#endif
/**
* @brief Bitwise OR an uintptr atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_orptr_ov (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedOr, &x->v, v);
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_or32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return DDSRT_ATOMIC_OP32 (InterlockedOr, &x->v, v) | v;
}
#if DDSRT_HAVE_ATOMIC64
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return DDSRT_ATOMIC_OP64 (InterlockedOr, &x->v, v) | v;
}
#endif
/**
* @brief Bitwise OR an uintptr atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_orptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
return DDSRT_ATOMIC_PTROP (InterlockedOr, &x->v, v) | v;
}
/* FENCES */
/**
* @brief insert a memory barrier for store and load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence (void) {
/* 28113: accessing a local variable tmp via an Interlocked
function: This is an unusual usage which could be reconsidered.
It is too heavyweight, true, but it does the trick. */
DDSRT_WARNING_MSVC_OFF(28113)
volatile LONG tmp = 0;
InterlockedExchange (&tmp, 0);
DDSRT_WARNING_MSVC_ON(28113)
}
/**
* @brief insert memory barrier for load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_ldld (void) {
#if !(defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#endif
}
/**
* @brief insert memory barrier for store operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_stst (void) {
#if !(defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#endif
}
/**
* @brief insert memory barrier for load store and load load operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}
/**
* @brief insert memory barrier for load store and store store operations
*/
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_rel (void) {
ddsrt_atomic_fence ();
}
#undef DDSRT_ATOMIC_PTROP
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_ATOMICS_MSVC_H */
+586
View File
@@ -0,0 +1,586 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#include <atomic.h>
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_ATOMIC64_SUPPORT 1
/**
* @file sun.h
* @brief Contains functions and types for atomic operations on various types for sun.
*
* This header file defines functions for atomic operations on uint32_t,
* uint64_t, uintptr_t, and void* types.
*/
/* LD, ST */
/**
* @brief Fetch the value of a 32-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
/**
* @brief Fetch the value of a 64-bit unsigned integer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x) { return x->v; }
/**
* @brief Fetch the value of an uintptr atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
/**
* @brief Fetch the value of a void pointer atomically
*
* @param[in] x Pointer to the variable to fetch the value of
*
* @return The value of the fetched variable
*/
inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
/**
* @brief Assign a 32-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
/**
* @brief Assign a 64-bit unsigned integer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { x->v = v; }
/**
* @brief Assign an uintptr atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
/**
* @brief Assign a void pointer atomically
*
* @param[out] x Pointer to the variable to update
* @param[in] v The new value to assign to the variable
*/
inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* INC */
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
atomic_inc_32 (&x->v);
}
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
*/
inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
atomic_inc_64 (&x->v);
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the incremented variable
*/
inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval + 1; } while (atomic_cas_32 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Increment (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return atomic_inc_32_nv (&x->v);
}
/**
* @brief Increment (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the incremented variable
*/
inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return atomic_inc_64_nv (&x->v);
}
/* DEC */
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
atomic_dec_32 (&x->v);
}
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
*/
inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
atomic_dec_64 (&x->v);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return atomic_dec_32_nv (&x->v);
}
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The new value of the decremented variable
*/
inline uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return atomic_dec_64_nv (&x->v);
}
/**
* @brief Decrement (by one) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval - 1; } while (atomic_cas_32 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Decrement (by one) a 64-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
*
* @return The old value of the decremented variable
*/
inline uint64_t ddsrt_atomic_dec64_ov (volatile ddsrt_atomic_uint64_t *x) {
uint64_t oldval, newval;
do { oldval = x->v; newval = oldval - 1; } while (atomic_cas_64 (&x->v, oldval, newval) != oldval);
return oldval;
}
/* ADD */
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_add_32 (&x->v, v);
}
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*/
inline void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_add_64 (&x->v, v);
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The old value of the incremented variable
*/
inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, v) - v;
}
/**
* @brief Increment (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, v);
}
/**
* @brief Increment (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to increment
* @param[in] v The value to increment by
*
* @return The new value of the incremented variable
*/
inline uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return atomic_add_64_nv (&x->v, v);
}
/* SUB */
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_add_32 (&x->v, -v);
}
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*/
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_add_64 (&x->v, -v);
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its old value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The old value of the decremented variable
*/
inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, -v) + v;
}
/**
* @brief Decrement (by given amount) a 32-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, -v);
}
/**
* @brief Decrement (by given amount) a 64-bit unsigned integer atomically and return its new value
*
* @param[in,out] x Pointer to the variable to decrement
* @param[in] v The value to decrement by
*
* @return The new value of the decremented variable
*/
inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return atomic_add_64_nv (&x->v, -v);
}
/* AND */
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_and_32 (&x->v, v);
}
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*/
inline void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_and_64 (&x->v, v);
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
inline uint32_t ddsrt_atomic_and32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (atomic_cas_32 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The old value of the ANDed variable
*/
inline uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
uint64_t oldval, newval;
do { oldval = x->v; newval = oldval & v; } while (atomic_cas_64 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Bitwise AND a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
inline uint32_t ddsrt_atomic_and32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_and_32_nv (&x->v, v);
}
/**
* @brief Bitwise AND a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to AND
* @param[in] v The value to AND with the variable
*
* @return The new value of the ANDed variable
*/
inline uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return atomic_and_64_nv (&x->v, v);
}
/* OR */
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_or_32 (&x->v, v);
}
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*/
inline void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_or_64 (&x->v, v);
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
inline uint32_t ddsrt_atomic_or32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
uint32_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (atomic_cas_32 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the old value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The old value of the ORed variable
*/
inline uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
uint64_t oldval, newval;
do { oldval = x->v; newval = oldval | v; } while (atomic_cas_64 (&x->v, oldval, newval) != oldval);
return oldval;
}
/**
* @brief Bitwise OR a 32-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
inline uint32_t ddsrt_atomic_or32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_or_32_nv (&x->v, v);
}
/**
* @brief Bitwise OR a 64-bit unsigned integer atomically and return the new value
*
* @param[in,out] x Pointer to the variable to OR
* @param[in] v The value to OR with the variable
*
* @return The new value of the ORed variable
*/
inline uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
return atomic_or_64_nv (&x->v, v);
}
/* CAS */
/**
* @brief Compare and swap a 32-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_cas32 (volatile ddsrt_atomic_uint32_t *x, uint32_t exp, uint32_t des) {
return atomic_cas_32 (&x->v, exp, des) == exp;
}
/**
* @brief Compare and swap a 64-bit unsigned integer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_t des) {
return atomic_cas_64 (&x->v, exp, des) == exp;
}
/**
* @brief Compare and swap an uintptr atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_casptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t exp, uintptr_t des) {
return atomic_cas_ulong (&x->v, exp, des) == exp;
}
/**
* @brief Compare and swap a void pointer atomically
*
* Assigns des to x iff x == exp
*
* @param[in,out] x Pointer to the variable whose value to swap
* @param[in] exp the value to test x for
* @param[in] des the value to assign to the variable
*
* @return int meant to be interpreted as bool (swapped: 1; not swapped: 0)
*/
inline int ddsrt_atomic_casvoidp (volatile ddsrt_atomic_voidp_t *x, void *exp, void *des) {
return atomic_cas_ptr (&x->v, exp, des) == exp;
}
/* FENCES */
/**
* @brief insert a memory barrier for store and load operations
*/
inline void ddsrt_atomic_fence (void) {
membar_exit ();
membar_enter ();
}
/**
* @brief insert memory barrier only for load operations
*/
inline void ddsrt_atomic_fence_ldld (void) {
membar_consumer ();
}
/**
* @brief insert memory barrier only for store operations
*/
inline void ddsrt_atomic_fence_stst (void) {
membar_producer ();
}
/**
* @brief insert memory barrier for load store and load load operations
*/
inline void ddsrt_atomic_fence_acq (void) {
membar_enter ();
}
/**
* @brief insert memory barrier for load store and store store operations
*/
inline void ddsrt_atomic_fence_rel (void) {
membar_exit ();
}
#if defined (__cplusplus)
}
#endif
+143
View File
@@ -0,0 +1,143 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ATTRIBUTES_H
#define DDSRT_ATTRIBUTES_H
#if __GNUC__
# define ddsrt_gnuc (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#else
# define ddsrt_gnuc (0)
#endif
#if __clang__
# define ddsrt_clang (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#else
# define ddsrt_clang (0)
#endif
#ifdef __SUNPRO_C
# define __attribute__(x)
#endif
#if defined(__has_attribute)
# define ddsrt_has_attribute(params) __has_attribute(params)
#elif ddsrt_gnuc
# define ddsrt_has_attribute(params) (1) /* GCC < 5 */
#else
# define ddsrt_has_attribute(params) (0)
#endif
#if ddsrt_has_attribute(malloc)
# define ddsrt_attribute_malloc __attribute__ ((__malloc__))
#else
# define ddsrt_attribute_malloc
#endif
#if ddsrt_has_attribute(malloc) && ddsrt_gnuc >= 120000
# define ddsrt_attribute_malloc2(params) __attribute__ ((__malloc__ params))
#else
# define ddsrt_attribute_malloc2(params)
#endif
#if ddsrt_has_attribute(unused)
# define ddsrt_attribute_unused __attribute__((__unused__))
#else
# define ddsrt_attribute_unused
#endif
#if ddsrt_has_attribute(noreturn)
# define ddsrt_attribute_noreturn __attribute__ ((__noreturn__))
#else
# define ddsrt_attribute_noreturn
#endif
#if ddsrt_has_attribute(nonnull)
# define ddsrt_nonnull(params) __attribute__ ((__nonnull__ params))
# define ddsrt_nonnull_all __attribute__ ((__nonnull__))
#else
# define ddsrt_nonnull(params)
# define ddsrt_nonnull_all
#endif
#if ddsrt_has_attribute(returns_nonnull) && (ddsrt_clang || ddsrt_gnuc >= 40900)
# define ddsrt_attribute_returns_nonnull __attribute__ ((__returns_nonnull__))
#else
# define ddsrt_attribute_returns_nonnull
#endif
/* GCC <= 4.2.4 has the attribute, but warns that it ignores it. */
#if !ddsrt_has_attribute(alloc_size) || (ddsrt_gnuc <= 40204)
# define ddsrt_attribute_alloc_size(params)
#else
# define ddsrt_attribute_alloc_size(params) __attribute__ ((__alloc_size__ params))
#endif
#if ddsrt_has_attribute(const)
# define ddsrt_attribute_const __attribute__ ((__const__))
#else
# define ddsrt_attribute_const
#endif
#if ddsrt_has_attribute(pure)
# define ddsrt_attribute_pure __attribute__ ((__pure__))
#else
# define ddsrt_attribute_pure
#endif
#if ddsrt_has_attribute(format)
# define ddsrt_attribute_format(params) __attribute__ ((__format__ params))
# if __MINGW32__
# if !defined(__MINGW_PRINTF_FORMAT)
# define __MINGW_PRINTF_FORMAT gnu_printf
# endif
/* GCC assumes printf MS style arguments on Windows */
# define ddsrt_attribute_format_printf(string_index, first_to_check) \
ddsrt_attribute_format((__MINGW_PRINTF_FORMAT, string_index, first_to_check))
# else
# define ddsrt_attribute_format_printf(string_index, first_to_check) \
ddsrt_attribute_format((printf, string_index, first_to_check))
# endif
#else
# define ddsrt_attribute_format(params)
# define ddsrt_attribute_format_printf(string_index, first_to_check)
#endif
#if ddsrt_has_attribute(warn_unused_result)
# define ddsrt_attribute_warn_unused_result __attribute__ ((__warn_unused_result__))
#else
# define ddsrt_attribute_warn_unused_result
#endif
#if ddsrt_has_attribute(assume_aligned)
# define ddsrt_attribute_assume_aligned(params) __attribute__ ((__assume_aligned__ params))
#else
# define ddsrt_attribute_assume_aligned(params)
#endif
#if ddsrt_has_attribute(packed)
# define ddsrt_attribute_packed __attribute__ ((__packed__))
#else
# define ddsrt_attribute_packed
#endif
#if ddsrt_has_attribute(no_sanitize)
# define ddsrt_attribute_no_sanitize(params) __attribute__ ((__no_sanitize__ params))
#else
# define ddsrt_attribute_no_sanitize(params)
#endif
#if defined(__has_feature)
# define ddsrt_has_feature_thread_sanitizer __has_feature(thread_sanitizer)
#else
# define ddsrt_has_feature_thread_sanitizer 0
#endif
#endif /* DDSRT_ATTRIBUTES_H */
+936
View File
@@ -0,0 +1,936 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_AVL_H
#define DDSRT_AVL_H
/** \file avl.h
The tree library never performs memory allocations or deallocations internally.
- Treedef_t: defines the properties of the tree, offsets,
comparison functions, augmented structures, flags -- these are
related to the code/data structure in which the tree is embedded,
and in nearly all cases known at compile time.
- avlTree_t: represents the tree, i.e., pointer to the root.
- avlNode_t: contains the administrative data for a single node in
the tree.
For a tree node:
struct T {
avlNode_t avlnode;
int key;
};
by definition, avlnodeoffset == offsetof(struct T, avlnode) and
keyoffset = offsetof(struct T, key). The user of the library only
ever deals in pointers to (in this case) struct T, never with
pointers to the avlNode_t, and the compare function operations on
pointers to keys, in this case pointers to "int"s. If you wish, you
can also do: keyoffset = 0, in which case the compare function
would be operating on struct T's.
The compare function is assumed to behave just like all compare
functions in the C library: < 0, =0, >0 for left argument less
than, equal to or greater than the right argument.
The "augment" function is automatically called whenever some of the
children of a node change, as well as when the "augment" function
has been called on some of the children. It allows you to maintain
a "summary" of the subtree -- currently only used in DDSI, in one
spot.
Trees come in various "variants", configured through "treedef"
flags:
- direct/indirect key: direct meaning the key value is embedded in
the structure containing the avlNode_t, indirect meaning a
pointer to the key value is. The compare function doesn't deal
with tree nodes, but with key values.
- re-entrant: in the style of the C library, meaning, the
comparison function gets a user-supplied 3rd argument (in
particular used by mmstat).
- unique keys/duplicate keys: when keys must be unique, some
optimizations apply; it is up to the caller to ensure one doesn't
violate the uniqueness of the keys (it'll happily crash in insert
if you don't); when duplicate keys are allowed, a forward scan of
the tree will visit them in the order of insertion.
For a tree node:
struct T {
avlnode_t avlnode;
char *key;
};
you could set the "indirect" flag, and then you simply use
strcmp(), avoiding the need for passing templates in looking up key
values. Much nicer.
There is also an orthogonal variant that is enforced through the
type system -- note that would be possible for all of the above as
well, but the number of cases simply explodes and none of the above
flags affects the dynamically changing data structures (just the
tree definition), unlike this one.
- the "C" variant keeps track of the number of nodes in the tree to
support a "count" operation in O(1) time, but is otherwise
identical.
The various initializer macros and TreedefInit functions should
make sense with this.
All functions for looking up nodes return NULL if there is no node
satisfying the requirements.
- Init: initializes a tree (really just: root = NULL, perhaps count = 0)
- Free: calls "freefun" on each node, which may free the node
- FreeArg: as "Free", but with an extra, user-supplied, argument
- Root: returns the root node
- Lookup: returns a node with key value "key" (ref allowdups flag)
- LookupIPath: like Lookup, but also filling an IPath_t structure
for efficient insertion in case of a failed lookup (or inserting
duplicates)
- LookupDPath: like Lookup, but also filling a DPath_t structure
that helps with deleting a node
- LookupPredEq: locates the node with the greatest key value <= "key"
- LookupSuccEq: similar, but smallest key value >= "key"
- LookupPred: similar, < "key"
- LookupSucc: similar, > "key"
- Insert: convenience function: LookupIPath ; InsertIPath
- Delete: convenience function: LookupDPath ; DeleteDPath
- InsertIPath: insert node based on the "path" obtained from LookupIPath
- DeleteDPath: delete node, using information in "path" to do so efficiently
- SwapNode: replace "oldn" by "newn" without modifying the tree
structure (the key need not be equal, but must be
FindPred(oldn).key < newn.key < FindSucc(oldn).key, where a
non-existing predecessor has key -inf and a non-existing
successor has key +inf, and where it is understood that the <
operator becomes <= if allowdups is set
- AugmentUpdate: to be called when something in "node" changes that
affects the subtree "summary" computed by the configured
"augment" function
- IsEmpty: returns 1 if tree is empty, 0 if not
- IsSingleton: returns 1 if tree contains exactly one node, 0 if not
- FindMin: returns the node with the smallest key value in the tree
- FindMax: similar, largest key value
- FindPred: preceding node in in-order treewalk
- FindSucc: similar, following node
- Walk: calls "f" with user-supplied argument "a" once for each
node, starting at FindMin and ending at FindMax
- ConstWalk: same, but with a const tree
- WalkRange: like Walk, but only visiting nodes with key values in
range [min,max] (that's inclusive)
- ConstWalkRange: same, but with a const tree
- WalkRangeReverse: like WalkRange, but in the reverse direction
- ConstWalkRangeReverse: same, but with a const tree
- IterFirst: starts forward iteration, starting at (and returning) FindMin
- IterSuccEq: similar, starting at LookupSuccEq
- IterSucc: similar, starting at LookupSucc
- IterNext: returns FindSucc(last returned node); may not be called
if preceding IterXXX call on same "iter" returned NULL
That's all there is to it.
Note that all calls to Walk(f,a) can be rewritten as:
for(n=IterFirst(&it); n; n=IterNext(&it)) { f(n,a) }
or as
for(n=FindMin(); n; n=FindSucc(n)) { f(n,a) }
The walk functions and iterators may not alter the tree
structure. If that is desired, the latter can easily be rewritten
as:
n=FindMin() ; while(n) { nn=FindSucc(n); f(n,a); n=nn }
because FindMin/FindSucc doesn't store any information to allow
fast processing. That'll allow every operation, with the obvious
exception of f(n) calling Delete(FindSucc(n)).
Currently, all trees maintain parent pointers, but it may be worth
doing a separate set without it, as it reduces the size of
avlNode_t. But in that case, the FindMin/FindSucc option would no
longer be a reasonable option because it would be prohibitively
expensive, whereas the IterFirst/IterNext option are alway
efficiently. If one were to do a threaded tree variant, the
implemetantion of IterFirst/IterNext would become absolute trivial
and faster still, but at the cost of significantly more overhead in
memory and updates.
*/
#include <stdint.h>
#include <stdlib.h>
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_AVL_MAX_TREEHEIGHT (12 * sizeof (void *))
/**
* @brief User defined compare function.
*
* Input arguments are expected to be pointers to the keys.
* The expected return values are as follows:
* - value < 0 to indicate key a is less than key b
* - value > 0 to indicate key a is greater than key b
* - value == 0 to indicate key a is equal to key b
* @see ddsrt_avl_compare_r_t
*/
typedef int (*ddsrt_avl_compare_t) (const void *a, const void *b);
/** @brief Same as @ref ddsrt_avl_compare_t, but with extra argument for state information. */
typedef int (*ddsrt_avl_compare_r_t) (const void *a, const void *b, void *arg);
/**
* @brief User defined augment function.
*
* If provided, it is called whenever the structure of the tree changes,
* or when explicitly calling @ref ddsrt_avl_augment_update.
* It is called for each node on the path to (and inclusive of) the root.
* It is intended to update user data in nodes when a change occurs in one or both child nodes,
* or when a the change occurs in the node itself.
*/
typedef void (*ddsrt_avl_augment_t) (void *vnode, const void *left, const void *right);
/**
* @brief User defined walk function to perform an action on each node in the tree.
*/
typedef void (*ddsrt_avl_walk_t) (void *vnode, void *arg);
/**
* @brief Like @ref ddsrt_avl_walk_t, but works on const nodes.
*/
typedef void (*ddsrt_avl_const_walk_t) (const void *vnode, void *arg);
/// @brief The avl node is the basic element of the avl tree structure.
///
/// To store user data in the tree, the avl node must be embedded in a user node, which is a struct containing the user data.
/// All API calls with a node as input or output, deal with the user node. Example:
/// @code{.c}
/// typedef struct num_s{ // user node
/// ddsrt_avl_node_t node;
/// uint64_t val; // user data
/// }num_t;
/// @endcode
typedef struct ddsrt_avl_node {
struct ddsrt_avl_node *cs[2]; ///< contains pointers to the left and right child node
struct ddsrt_avl_node *parent; ///< points to the parent node
int height; ///< is the height of the subtree starting at this node
} ddsrt_avl_node_t;
/**
* Save a reference/dereference when using an indirect key. For details, see @ref ddsrt_avl_treedef_init.
*/
#define DDSRT_AVL_TREEDEF_FLAG_INDKEY 1
#define DDSRT_AVL_TREEDEF_FLAG_R 2 /**< Flag used internally by @ref ddsrt_avl_treedef_init_r : compare function has extra argument */
#define DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS 4 /**< Flag for @ref ddsrt_avl_treedef_init : multiple nodes with the same key are allowed */
/**
* @brief The tree definition.
*
* The treedef stores settings for the tree, but does not hold the actual tree itself. This implies that:
* - A single treedef can be used for multiple trees of the same type.
* - Most tree operations require you to provide both the treedef and the @ref ddsrt_avl_tree.
*
* To initialize it, use @ref ddsrt_avl_treedef_init, @ref ddsrt_avl_treedef_init_r,
* or one of the 'DDSRT_AVL_TREEDEF_INITIALIZER' macros.
*/
typedef struct ddsrt_avl_treedef {
#if defined (__cplusplus)
ddsrt_avl_treedef() {}
#endif
size_t avlnodeoffset;
size_t keyoffset;
union {
ddsrt_avl_compare_t comparekk;
ddsrt_avl_compare_r_t comparekk_r;
} u;
ddsrt_avl_augment_t augment;
uint32_t flags;
void *cmp_arg; /* for _r variant */
} ddsrt_avl_treedef_t;
/** @brief Counted version of @ref ddsrt_avl_treedef */
typedef struct ddsrt_avl_ctreedef {
ddsrt_avl_treedef_t t;
} ddsrt_avl_ctreedef_t;
/**
* @brief The avl tree.
*
* The tree only knows the root @ref ddsrt_avl_node. The settings for the tree are stored separately in the @ref ddsrt_avl_treedef.
* As a result, most tree operations require you to provide both the treedef and the tree.
*/
typedef struct ddsrt_avl_tree {
ddsrt_avl_node_t *root; ///< is the root node of the tree
} ddsrt_avl_tree_t;
/** @brief Counted version of @ref ddsrt_avl_tree */
typedef struct ddsrt_avl_ctree {
ddsrt_avl_tree_t t;
size_t count;
} ddsrt_avl_ctree_t;
typedef struct ddsrt_avl_path {
int depth; /* total depth of path */
int pnodeidx;
ddsrt_avl_node_t *parent; /* (nodeidx == 0 ? NULL : *(path[nodeidx-1])) */
ddsrt_avl_node_t **pnode[DDSRT_AVL_MAX_TREEHEIGHT];
} ddsrt_avl_path_t;
/**
* @brief Path for inserting a node.
* @see ddsrt_avl_lookup_ipath
* @see ddsrt_avl_insert_ipath
*/
typedef struct ddsrt_avl_ipath {
ddsrt_avl_path_t p;
} ddsrt_avl_ipath_t;
/**
* @brief Path for removing a node.
* @see ddsrt_avl_lookup_dpath
* @see ddsrt_avl_delete_dpath
*/
typedef struct ddsrt_avl_dpath {
ddsrt_avl_path_t p;
} ddsrt_avl_dpath_t;
/**
* @brief Iter object for the iterator to store its progress and know where to go next.
*/
typedef struct ddsrt_avl_iter {
const ddsrt_avl_treedef_t *td;
ddsrt_avl_node_t *right;
ddsrt_avl_node_t **todop;
ddsrt_avl_node_t *todo[1+DDSRT_AVL_MAX_TREEHEIGHT];
} ddsrt_avl_iter_t;
/** @brief Counted version of @ref ddsrt_avl_iter*/
typedef struct ddsrt_avl_citer {
ddsrt_avl_iter_t t;
} ddsrt_avl_citer_t;
/* avlnodeoffset and keyoffset must both be in [0,2**31-1] */
#define DDSRT_AVL_TREEDEF_INITIALIZER(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), 0, 0 }
#define DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_INDKEY, 0 }
#define DDSRT_AVL_TREEDEF_INITIALIZER_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 }
#define DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_INDKEY|DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 }
#define DDSRT_AVL_TREEDEF_INITIALIZER_R(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_R, (cmparg) }
#define DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_R(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_INDKEY|DDSRT_AVL_TREEDEF_FLAG_R, (cmparg) }
#define DDSRT_AVL_TREEDEF_INITIALIZER_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_R|DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) }
#define DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), DDSRT_AVL_TREEDEF_FLAG_INDKEY|DDSRT_AVL_TREEDEF_FLAG_R|DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) }
/* Not maintaining # nodes */
/// @brief Initialize the @ref ddsrt_avl_treedef
///
/// Different types of trees are supported. This function defines which type to use.
/// Given a node defined as:
/// @code{.c}
/// typedef struct num_s{ // user node
/// ddsrt_avl_node_t node;
/// uint64_t val; // user data
/// }num_t;
/// @endcode
///
/// For a treedef initialized with default settings:
/// @code{.c}
/// ddsrt_avl_treedef_t td;
/// ddsrt_avl_treedef_init(&td, offsetof(num_t, node), offsetof(num_t, val), num_cmp, 0, 0);
/// @endcode
///
/// A lookup is performed as:
/// @code{.c}
/// uint64_t key = 7;
/// num_t* num_lookup = ddsrt_avl_lookup(&td, &tree, &key);
/// @endcode
///
/// By using keyoffset == 0, you can do the lookup using a dummy node:
/// @code{.c}
/// num_t dummy;
/// dummy.val = 7;
/// num_t* num_lookup = ddsrt_avl_lookup(&td, &tree, &dummy);
/// @endcode
///
/// Regarding the flags:
/// - The flag @ref DDSRT_AVL_TREEDEF_FLAG_INDKEY affects functions like @ref ddsrt_avl_compare_t and @ref ddsrt_avl_lookup.
/// These functions expect their 'key' argument to be a pointer, so by default you need to pass a reference to the key.
/// Alternatively, by using @ref DDSRT_AVL_TREEDEF_FLAG_INDKEY you indicate that the key is already a pointer, allowing you to pass the key directly.
/// As an example in the case of a C string, using the INDKEY flag means you can provide the key directly (char*), rather than a reference (char**).
/// @code{.c}
/// typedef struct name_s{ // user node
/// ddsrt_avl_node_t node;
/// char* val; // user data
/// }name_t;
/// @endcode
///
/// If using the default flag:
/// @code{.c}
/// ddsrt_avl_treedef_t td;
/// ddsrt_avl_treedef_init(&td, offsetof(name_t, node), offsetof(name_t, val), name_cmp_default, 0, 0);
/// @endcode
///
/// Then a lookup is done as:
/// @code{.c}
/// char* key = strdup("John");
/// name_t* name_lookup = ddsrt_avl_lookup(&td, &tree, &key); // Using default flag
/// @endcode
///
/// If using the INDKEY flag:
/// @code{.c}
/// ddsrt_avl_treedef_t td;
/// ddsrt_avl_treedef_init(&td, offsetof(name_t, node), offsetof(name_t, val), name_cmp_indkey, 0, DDSRT_AVL_TREEDEF_FLAG_INDKEY);
/// @endcode
///
/// Then a lookup is done as:
/// @code{.c}
/// char* key = strdup("John");
/// name_t* name_lookup = ddsrt_avl_lookup(&td, &tree, key); // Using INDKEY flag
/// @endcode
///
/// - Multiple nodes with the same key are not allowed, unless using @ref DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS.
///
/// To set multiple flags, use the bitwise or.
///
/// @param[out] td the treedef to initialize
/// @param[in] avlnodeoffset offset of @ref ddsrt_avl_node relative to the user node.
/// @param[in] keyoffset offset of the key relative to the user node
/// @param[in] comparekk a key compare function, see @ref ddsrt_avl_compare_t
/// @param[in] augment optional function @ref ddsrt_avl_augment_t, provide NULL if not used
/// @param[in] flags optional flags, use 0 for default
/// @see ddsrt_avl_treedef_init_r
/// @see ddsrt_avl_init
DDS_EXPORT void ddsrt_avl_treedef_init (ddsrt_avl_treedef_t *td, size_t avlnodeoffset, size_t keyoffset, ddsrt_avl_compare_t comparekk, ddsrt_avl_augment_t augment, uint32_t flags) ddsrt_nonnull((1,4));
/**
* @brief Like @ref ddsrt_avl_treedef_init, but there is an extra argument for the compare function.
*
* @param[out] td the treedef to initialize
* @param[in] avlnodeoffset offset of @ref ddsrt_avl_node relative to the user node.
* @param[in] keyoffset offset of the key relative to the user node
* @param[in] comparekk_r a key compare function, see @ref ddsrt_avl_compare_r_t
* @param[in] cmp_arg is fed to the compare function
* @param[in] augment optional function @ref ddsrt_avl_augment_t, provide NULL if not used
* @param[in] flags optional flags, use 0 for default
* @see ddsrt_avl_treedef_init
*/
DDS_EXPORT void ddsrt_avl_treedef_init_r (ddsrt_avl_treedef_t *td, size_t avlnodeoffset, size_t keyoffset, ddsrt_avl_compare_r_t comparekk_r, void *cmp_arg, ddsrt_avl_augment_t augment, uint32_t flags) ddsrt_nonnull((1,4));
/**
* @brief Initialize the tree.
*
* The treedef must have been initialized prior to calling this.
*
* @param[in] td treedef of the tree
* @param[out] tree the avl tree
* @see ddsrt_avl_free
* @see ddsrt_avl_treedef_init
*/
DDS_EXPORT void ddsrt_avl_init (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/**
* @brief Destroy the tree
*
* Applies user defined free function to each node, and initializes the tree again.
* The free function is optional, but if not provided, the user is responsible for freeing the memory.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] freefun optional user defined free function to use on nodes, NULL if not used
* @see ddsrt_avl_init
*/
DDS_EXPORT void ddsrt_avl_free (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void (*freefun) (void *vnode)) ddsrt_nonnull((1,2));
/**
* @brief Same as @ref ddsrt_avl_free, but with an extra argument for the free function.
*
* Extra parameter:
* @param[in] arg is for the user defined free function
*/
DDS_EXPORT void ddsrt_avl_free_arg (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void (*freefun) (void *vnode, void *arg), void *arg) ddsrt_nonnull((1,2));
/**
* @brief Get the root node
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @returns pointer to root node, NULL if tree is empty
*/
DDS_EXPORT void *ddsrt_avl_root (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/** Same as @ref ddsrt_avl_root, but has undefined behavior in case the tree is empty. */
DDS_EXPORT void *ddsrt_avl_root_non_empty (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all ddsrt_attribute_returns_nonnull;
/**
* @brief Lookup a node based on the key
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @return pointer to the node satisfying (node.key == key), NULL if failed
*/
DDS_EXPORT void *ddsrt_avl_lookup (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
/**
* @brief Same as @ref ddsrt_avl_lookup, but also initializes a @ref ddsrt_avl_ipath.
*
* The path initialized is intended for use with @ref ddsrt_avl_insert_ipath.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @param[out] path is the insert path
* @return pointer to the node satisfying (node.key == key), NULL if failed
* @see ddsrt_avl_lookup_dpath
*/
DDS_EXPORT void *ddsrt_avl_lookup_ipath (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
/**
* @brief Same as @ref ddsrt_avl_lookup, but also initializes a @ref ddsrt_avl_dpath.
*
* The path initialized is intended for use with @ref ddsrt_avl_delete_dpath.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @param[out] path is the delete path
* @return pointer to the node satisfying (node.key == key), NULL if failed
* @see ddsrt_avl_lookup_ipath
*/
DDS_EXPORT void *ddsrt_avl_lookup_dpath (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_avl_lookup, but match greatest node satisfying (node.key <= key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @return pointer to the node satisfying (node.key <= key), NULL if failed
*/
DDS_EXPORT void *ddsrt_avl_lookup_pred_eq (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_avl_lookup, but match smallest node satisfying (node.key >= key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @return pointer to the node satisfying (node.key >= key), NULL if failed
*/
DDS_EXPORT void *ddsrt_avl_lookup_succ_eq (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_avl_lookup, but match greatest node satisfying (node.key < key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @return pointer to the node satisfying (node.key < key), NULL if failed
*/
DDS_EXPORT void *ddsrt_avl_lookup_pred (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_avl_lookup, but match smallest node satisfying (node.key > key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] key key to search for
* @return pointer to the node satisfying (node.key > key), NULL if failed
*/
DDS_EXPORT void *ddsrt_avl_lookup_succ (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
/**
* @brief Insert a node into the tree.
*
* There is no protection against duplicates (which causes a crash if the treedef says duplicates are not allowed).
* If you want a safe insert, you should use @ref ddsrt_avl_lookup_ipath to check for existence, then insert using @ref ddsrt_avl_insert_ipath.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] vnode the node to insert
* @see ddsrt_avl_delete
*/
DDS_EXPORT void ddsrt_avl_insert (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *vnode) ddsrt_nonnull_all;
/**
* @brief Remove a node from the tree.
*
* Despite the name 'delete', it only removes the node from the tree. To fully delete it, you still need to free the memory associated with the node.
* There is no protection against a crash due to trying to remove a nonexisting node.
* If you want a safe remove, you should use @ref ddsrt_avl_lookup_dpath to check for existence, then remove using @ref ddsrt_avl_delete_dpath.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] vnode the node to remove
* @see ddsrt_avl_insert
*/
DDS_EXPORT void ddsrt_avl_delete (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *vnode) ddsrt_nonnull_all;
/**
* @brief Same as @ref ddsrt_avl_insert, but also requires a @ref ddsrt_avl_ipath.
*
* The path required can be initialized by @ref ddsrt_avl_lookup_ipath.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] vnode the node to insert
* @param[in] path is the insert path
* @see ddsrt_avl_delete_dpath
*/
DDS_EXPORT void ddsrt_avl_insert_ipath (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *vnode, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
/**
* @brief Same as @ref ddsrt_avl_delete, but also requires a @ref ddsrt_avl_dpath.
*
* The path required can be initialized by @ref ddsrt_avl_lookup_dpath.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] vnode the node to remove
* @param[in] path is the delete path
* @see ddsrt_avl_insert_ipath
*/
DDS_EXPORT void ddsrt_avl_delete_dpath (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *vnode, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
/**
* @brief Replace a node in the tree.
*
* Replace a node in the tree without using @ref ddsrt_avl_delete and @ref ddsrt_avl_insert.
* This operation can invalidate the tree as it doesn't check whether the key of the new node preserves the ordering of the set.
*
* @param[in] td treedef of the tree
* @param[in,out] tree the avl tree
* @param[in] voldn the node to replace
* @param[in] vnewn the node to take the old node's place
* @see ddsrt_avl_insert
* @see ddsrt_avl_delete
*/
DDS_EXPORT void ddsrt_avl_swap_node (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *voldn, void *vnewn) ddsrt_nonnull_all;
/**
* @brief Call the user defined augment function @ref ddsrt_avl_augment_t on a node and its parents up to the root.
*
* It is intended to update user data in nodes when a change occurs in one or both child nodes, or when a the change occurs in the node itself.
* Note that @ref ddsrt_avl_augment_t is called automatically whenever the structure of the tree changes, such as in rotations.
* It is called for each node on the path to (and inclusive of) the root.
*
* @param[in] td treedef of the tree
* @param[in] vnode is the node from which to start the augmentation
*/
DDS_EXPORT void ddsrt_avl_augment_update (const ddsrt_avl_treedef_t *td, void *vnode) ddsrt_nonnull_all;
/**
* @brief Check whether the tree is empty or not.
*
* @param[in] tree the avl tree
* @return int meant to be interpreted as bool (1 is true, 0 is false)
*/
DDS_EXPORT int ddsrt_avl_is_empty (const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/**
* @brief Check whether the tree contains exactly one node.
*
* @param[in] tree the avl tree
* @return int meant to be interpreted as bool (1 is true, 0 is false)
*/
DDS_EXPORT int ddsrt_avl_is_singleton (const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/**
* @brief Lookup node with smallest key.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @return pointer to the node
* @see ddsrt_avl_find_max
*/
DDS_EXPORT void *ddsrt_avl_find_min (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/**
* @brief Lookup node with greatest key.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @return pointer to the node
* @see ddsrt_avl_find_min
*/
DDS_EXPORT void *ddsrt_avl_find_max (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
/**
* @brief Get the previous node in the ordered set.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] vnode the current node
* @return pointer to the node
* @see ddsrt_avl_find_succ
*/
DDS_EXPORT void *ddsrt_avl_find_pred (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *vnode) ddsrt_nonnull((1,2));
/**
* @brief Get the next node in in the ordered set
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] vnode the current node
* @return pointer to the node
* @see ddsrt_avl_find_pred
* @see ddsrt_avl_iter_next
*/
DDS_EXPORT void *ddsrt_avl_find_succ (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *vnode) ddsrt_nonnull((1,2));
/**
* @brief Walk the tree and apply a user defined function @ref ddsrt_avl_walk_t to each node.
*
* Functionally the same as doing a loop using @ref ddsrt_avl_find_succ or @ref ddsrt_avl_iter_next, and calling the function on each node.
* Modifying the tree structure is not allowed when using the walk function. If that is desired, use @ref ddsrt_avl_find_succ
* (or @ref ddsrt_avl_find_pred for the reverse walk).
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
* @see ddsrt_avl_find_succ
* @see ddsrt_avl_iter_next
*/
DDS_EXPORT void ddsrt_avl_walk (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/**
* @brief Like @ref ddsrt_avl_walk, but the user defined function @ref ddsrt_avl_const_walk_t works on const nodes.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
*/
DDS_EXPORT void ddsrt_avl_const_walk (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/**
* @brief Like @ref ddsrt_avl_walk, but walk within a restricted range defined by [min, max].
*
* - If min is smaller than the smallest value, it starts at the smallest value.
* - If max is larger than the largest value, it finishes at the largest value.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] min The smallest value to start at
* @param[in] max The largest value to finish at (inclusive)
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
*/
DDS_EXPORT void ddsrt_avl_walk_range (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, const void *min, const void *max, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/**
* @brief Like @ref ddsrt_avl_walk_range, but the user defined function @ref ddsrt_avl_const_walk_t works on const nodes.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] min The smallest value to start at
* @param[in] max The largest value to finish at (inclusive)
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
*/
DDS_EXPORT void ddsrt_avl_const_walk_range (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *min, const void *max, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/**
* @brief Like @ref ddsrt_avl_walk_range, but walks in the reverse direction.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] min The smallest value to finish at (inclusive)
* @param[in] max The largest value to start at
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
*/
DDS_EXPORT void ddsrt_avl_walk_range_reverse (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, const void *min, const void *max, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/**
* @brief Like @ref ddsrt_avl_walk_range_reverse, but the user defined function @ref ddsrt_avl_const_walk_t works on const nodes.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[in] min The smallest value to finish at (inclusive)
* @param[in] max The largest value to start at
* @param[in] f is the user defined walk function
* @param[in,out] a is an argument for the user defined function
*/
DDS_EXPORT void ddsrt_avl_const_walk_range_reverse (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *min, const void *max, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/**
* @brief Get the first node in in the ordered set, and initialize the iterator @ref ddsrt_avl_iter_t.
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[out] iter the iterator
* @return pointer to the node
* @see ddsrt_avl_iter_next
* @see ddsrt_avl_find_min
*/
DDS_EXPORT void *ddsrt_avl_iter_first (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, ddsrt_avl_iter_t *iter) ddsrt_nonnull_all;
/**
* @brief Similar to @ref ddsrt_avl_iter_first, but start at smallest node satisfying (node.key >= key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[out] iter the iterator
* @param[in] key the key with which to do the lookup
* @return pointer to the node
*/
DDS_EXPORT void *ddsrt_avl_iter_succ_eq (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, ddsrt_avl_iter_t *iter, const void *key) ddsrt_nonnull_all;
/**
* @brief Similar to @ref ddsrt_avl_iter_first, but start at smallest node satisfying (node.key > key)
*
* @param[in] td treedef of the tree
* @param[in] tree the avl tree
* @param[out] iter the iterator
* @param[in] key the key with which to do the lookup
* @return pointer to the node
*/
DDS_EXPORT void *ddsrt_avl_iter_succ (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, ddsrt_avl_iter_t *iter, const void *key) ddsrt_nonnull_all;
/**
* @brief Get the next node in in the ordered set.
*
* Modifying the tree structure is not allowed when using the iterator. If that is desired, use @ref ddsrt_avl_find_succ.
*
* @param[in,out] iter the iterator
* @return pointer to the node
* @see ddsrt_avl_iter_first
* @see ddsrt_avl_find_succ
*/
DDS_EXPORT void *ddsrt_avl_iter_next (ddsrt_avl_iter_t *iter) ddsrt_nonnull_all;
/* Maintaining # nodes */
#define DDSRT_AVL_CTREEDEF_INITIALIZER(avlnodeoffset, keyoffset, comparekk, augment) { DDSRT_AVL_TREEDEF_INITIALIZER (avlnodeoffset, keyoffset, comparekk, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_INDKEY(avlnodeoffset, keyoffset, comparekk, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY (avlnodeoffset, keyoffset, comparekk, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_ALLOWDUPS (avlnodeoffset, keyoffset, comparekk, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_INDKEY_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_ALLOWDUPS (avlnodeoffset, keyoffset, comparekk, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_R(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_R (avlnodeoffset, keyoffset, comparekk, cmparg, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_INDKEY_R(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_R (avlnodeoffset, keyoffset, comparekk, cmparg, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_R_ALLOWDUPS (avlnodeoffset, keyoffset, comparekk, cmparg, augment) }
#define DDSRT_AVL_CTREEDEF_INITIALIZER_INDKEY_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY_R_ALLOWDUPS (avlnodeoffset, keyoffset, comparekk, cmparg, augment) }
/** @brief Counted version of @ref ddsrt_avl_treedef_init*/
DDS_EXPORT void ddsrt_avl_ctreedef_init (ddsrt_avl_ctreedef_t *td, size_t avlnodeoffset, size_t keyoffset, ddsrt_avl_compare_t comparekk, ddsrt_avl_augment_t augment, uint32_t flags) ddsrt_nonnull((1,4));
/** @brief Counted version of @ref ddsrt_avl_treedef_init_r*/
DDS_EXPORT void ddsrt_avl_ctreedef_init_r (ddsrt_avl_ctreedef_t *td, size_t avlnodeoffset, size_t keyoffset, ddsrt_avl_compare_r_t comparekk_r, void *cmp_arg, ddsrt_avl_augment_t augment, uint32_t flags) ddsrt_nonnull((1,4));
/** @brief Counted version of @ref ddsrt_avl_init*/
DDS_EXPORT void ddsrt_avl_cinit (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_free*/
DDS_EXPORT void ddsrt_avl_cfree (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void (*freefun) (void *vnode)) ddsrt_nonnull((1,2));
/** @brief Counted version of @ref ddsrt_avl_free_arg*/
DDS_EXPORT void ddsrt_avl_cfree_arg (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void (*freefun) (void *vnode, void *arg), void *arg) ddsrt_nonnull((1,2));
/** @brief Counted version of @ref ddsrt_avl_root*/
DDS_EXPORT void *ddsrt_avl_croot (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_root_non_empty*/
DDS_EXPORT void *ddsrt_avl_croot_non_empty (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup*/
DDS_EXPORT void *ddsrt_avl_clookup (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_ipath*/
DDS_EXPORT void *ddsrt_avl_clookup_ipath (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_dpath*/
DDS_EXPORT void *ddsrt_avl_clookup_dpath (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_pred_eq*/
DDS_EXPORT void *ddsrt_avl_clookup_pred_eq (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_succ_eq*/
DDS_EXPORT void *ddsrt_avl_clookup_succ_eq (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_pred*/
DDS_EXPORT void *ddsrt_avl_clookup_pred (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_lookup_succ*/
DDS_EXPORT void *ddsrt_avl_clookup_succ (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_insert*/
DDS_EXPORT void ddsrt_avl_cinsert (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *vnode) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_delete*/
DDS_EXPORT void ddsrt_avl_cdelete (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *vnode) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_insert_ipath*/
DDS_EXPORT void ddsrt_avl_cinsert_ipath (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *vnode, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_delete_dpath*/
DDS_EXPORT void ddsrt_avl_cdelete_dpath (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *vnode, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_swap_node*/
DDS_EXPORT void ddsrt_avl_cswap_node (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *voldn, void *vnewn) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_augment_update*/
DDS_EXPORT void ddsrt_avl_caugment_update (const ddsrt_avl_ctreedef_t *td, void *vnode) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_is_empty*/
DDS_EXPORT int ddsrt_avl_cis_empty (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_is_singleton*/
DDS_EXPORT int ddsrt_avl_cis_singleton (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_count*/
DDS_EXPORT size_t ddsrt_avl_ccount (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_find_min*/
DDS_EXPORT void *ddsrt_avl_cfind_min (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_find_max*/
DDS_EXPORT void *ddsrt_avl_cfind_max (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_find_pred*/
DDS_EXPORT void *ddsrt_avl_cfind_pred (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *vnode) ddsrt_nonnull((1,2));
/** @brief Counted version of @ref ddsrt_avl_find_succ*/
DDS_EXPORT void *ddsrt_avl_cfind_succ (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *vnode) ddsrt_nonnull((1,2));
/** @brief Counted version of @ref ddsrt_avl_walk*/
DDS_EXPORT void ddsrt_avl_cwalk (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/** @brief Counted version of @ref ddsrt_avl_const_walk*/
DDS_EXPORT void ddsrt_avl_cconst_walk (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3));
/** @brief Counted version of @ref ddsrt_avl_walk_range*/
DDS_EXPORT void ddsrt_avl_cwalk_range (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, const void *min, const void *max, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/** @brief Counted version of @ref ddsrt_avl_const_walk_range*/
DDS_EXPORT void ddsrt_avl_cconst_walk_range (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *min, const void *max, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/** @brief Counted version of @ref ddsrt_avl_walk_range_reverse*/
DDS_EXPORT void ddsrt_avl_cwalk_range_reverse (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, const void *min, const void *max, ddsrt_avl_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/** @brief Counted version of @ref ddsrt_avl_const_walk_range_reverse*/
DDS_EXPORT void ddsrt_avl_cconst_walk_range_reverse (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *min, const void *max, ddsrt_avl_const_walk_t f, void *a) ddsrt_nonnull((1,2,3,4,5));
/** @brief Counted version of @ref ddsrt_avl_iter_first*/
DDS_EXPORT void *ddsrt_avl_citer_first (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, ddsrt_avl_citer_t *iter) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_iter_succ_eq*/
DDS_EXPORT void *ddsrt_avl_citer_succ_eq (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, ddsrt_avl_citer_t *iter, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_iter_succ*/
DDS_EXPORT void *ddsrt_avl_citer_succ (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, ddsrt_avl_citer_t *iter, const void *key) ddsrt_nonnull_all;
/** @brief Counted version of @ref ddsrt_avl_iter_next*/
DDS_EXPORT void *ddsrt_avl_citer_next (ddsrt_avl_citer_t *iter) ddsrt_nonnull_all;
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_AVL_H */
+60
View File
@@ -0,0 +1,60 @@
// Copyright(c) 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_BITS_H
#define DDSRT_BITS_H
#include <stdint.h>
#include <stdlib.h>
#include "dds/export.h"
#include "dds/ddsrt/static_assert.h"
#if defined (__cplusplus)
extern "C" {
#endif
/** \brief Find first set (POSIX style): returns index of least significant bit set in input
@param[in] x input, may be 0
@return position of least significant bit set in x (LSB is 1, MSB is 32), returns 0 if x == 0
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_ffs32u (uint32_t x)
{
// Compiler support checks based on https://en.wikipedia.org/wiki/Find_first_set
#if defined __clang__ && __clang_major__ >= 5
DDSRT_STATIC_ASSERT (sizeof (int) == sizeof (uint32_t));
return (uint32_t) __builtin_ffs ((int) x);
#elif defined __GNUC__ && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
DDSRT_STATIC_ASSERT (sizeof (int) == sizeof (uint32_t));
return (uint32_t) __builtin_ffs ((int) x);
#elif defined _MSC_VER && _MSC_VER >= 1400 // Visual Studio 2005
DDSRT_STATIC_ASSERT (sizeof (unsigned long) == sizeof (uint32_t));
unsigned long index;
return _BitScanForward (&index, x) ? (index + 1) : 0;
#else
if (x == 0)
return 0;
uint32_t n = 1;
if ((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; };
if ((x & 0x000000FF) == 0) { n += 8; x >>= 8; };
if ((x & 0x0000000F) == 0) { n += 4; x >>= 4; };
if ((x & 0x00000003) == 0) { n += 2; x >>= 2; };
if ((x & 0x00000001) == 0) { n += 1; };
return n;
#endif
}
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_BITS_H */
+176
View File
@@ -0,0 +1,176 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_BSWAP_H
#define DDSRT_BSWAP_H
/** @file bswap.h
This header implements byteswapping (between big endian and little endian) for different integer types.
*/
#include <stdint.h>
#include <stdlib.h>
#include "dds/export.h"
#include "dds/ddsrt/endian.h"
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Defines the byte order options: native, big endian, and little endian
*/
enum ddsrt_byte_order_selector {
DDSRT_BOSEL_NATIVE,
DDSRT_BOSEL_BE,
DDSRT_BOSEL_LE,
};
/**
* @brief Byteswap uint16_t
*
* @param[in] x the uint16_t to byteswap
* @return the byteswapped uint16_t
*/
DDS_INLINE_EXPORT inline uint16_t ddsrt_bswap2u (uint16_t x)
{
return (uint16_t) ((x >> 8) | (x << 8));
}
/**
* @brief Byteswap int16_t
*
* @param[in] x the int16_t to byteswap
* @return the byteswapped int16_t
*/
DDS_INLINE_EXPORT inline int16_t ddsrt_bswap2 (int16_t x)
{
return (int16_t) ddsrt_bswap2u ((uint16_t) x);
}
/**
* @brief Byteswap uint32_t
*
* @param[in] x the uint32_t to byteswap
* @return the byteswapped uint32_t
*/
DDS_INLINE_EXPORT inline uint32_t ddsrt_bswap4u (uint32_t x)
{
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
}
/**
* @brief Byteswap int32_t
*
* @param[in] x the int32_t to byteswap
* @return the byteswapped int32_t
*/
DDS_INLINE_EXPORT inline int32_t ddsrt_bswap4 (int32_t x)
{
return (int32_t) ddsrt_bswap4u ((uint32_t) x);
}
/**
* @brief Byteswap uint64_t
*
* @param[in] x the uint64_t to byteswap
* @return the byteswapped uint64_t
*/
DDS_INLINE_EXPORT inline uint64_t ddsrt_bswap8u (uint64_t x)
{
const uint32_t newhi = ddsrt_bswap4u ((uint32_t) x);
const uint32_t newlo = ddsrt_bswap4u ((uint32_t) (x >> 32));
return ((uint64_t) newhi << 32) | (uint64_t) newlo;
}
/**
* @brief Byteswap int64_t
*
* @param[in] x the int64_t to byteswap
* @return the byteswapped int64_t
*/
DDS_INLINE_EXPORT inline int64_t ddsrt_bswap8 (int64_t x)
{
return (int64_t) ddsrt_bswap8u ((uint64_t) x);
}
/**
* @brief Macros for byteswapping
*
* These macros are for converting integer types from and to big endian or little endian.
* They abstract from the endianness of your system by providing a different implementation based on the value of DDSRT_ENDIAN
* (for example if you want to convert to big endian, it converts if your system is little endian,
* but if your system is already big endian, the conversion is skipped).
* Postfix numbers indicate the number of bytes of the integer (2,4,8 for 16-bit, 32-bit, 64-bit respectively),
* whilst an 'u' postfix indicates an unsigned integer type.
*
* - ddsrt_toBE: convert from native to big endian
* - ddsrt_toLE: convert from native to little endian
* - ddsrt_toBO: convert from native to byte order 'bo', @see ddsrt_byte_order_selector
* - ddsrt_fromBE: convert from big endian to native endianness (DDSRT_ENDIAN)
*/
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
#define ddsrt_toBE2(x) ddsrt_bswap2 (x)
#define ddsrt_toBE2u(x) ddsrt_bswap2u (x)
#define ddsrt_toBE4(x) ddsrt_bswap4 (x)
#define ddsrt_toBE4u(x) ddsrt_bswap4u (x)
#define ddsrt_toBE8(x) ddsrt_bswap8 (x)
#define ddsrt_toBE8u(x) ddsrt_bswap8u (x)
#define ddsrt_toLE2(x) (x)
#define ddsrt_toLE2u(x) (x)
#define ddsrt_toLE4(x) (x)
#define ddsrt_toLE4u(x) (x)
#define ddsrt_toLE8(x) (x)
#define ddsrt_toLE8u(x) (x)
#define ddsrt_toBO2(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap2 (x) : (x))
#define ddsrt_toBO2u(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap2u (x) : (x))
#define ddsrt_toBO4(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap4 (x) : (x))
#define ddsrt_toBO4u(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap4u (x) : (x))
#define ddsrt_toBO8(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap8 (x) : (x))
#define ddsrt_toBO8u(bo, x) ((bo) == DDSRT_BOSEL_BE ? ddsrt_bswap8u (x) : (x))
#define ddsrt_fromBE2(x) ddsrt_bswap2 (x)
#define ddsrt_fromBE2u(x) ddsrt_bswap2u (x)
#define ddsrt_fromBE4(x) ddsrt_bswap4 (x)
#define ddsrt_fromBE4u(x) ddsrt_bswap4u (x)
#define ddsrt_fromBE8(x) ddsrt_bswap8 (x)
#define ddsrt_fromBE8u(x) ddsrt_bswap8u (x)
#else
#define ddsrt_toBE2u(x) (x)
#define ddsrt_toBE4(x) (x)
#define ddsrt_toBE4u(x) (x)
#define ddsrt_toBE8(x) (x)
#define ddsrt_toBE8u(x) (x)
#define ddsrt_toLE2(x) ddsrt_bswap2 (x)
#define ddsrt_toLE2u(x) ddsrt_bswap2u (x)
#define ddsrt_toLE4(x) ddsrt_bswap4 (x)
#define ddsrt_toLE4u(x) ddsrt_bswap4u (x)
#define ddsrt_toLE8(x) ddsrt_bswap8 (x)
#define ddsrt_toLE8u(x) ddsrt_bswap8u (x)
#define ddsrt_toBO2(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap2 (x) : (x))
#define ddsrt_toBO2u(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap2u (x) : (x))
#define ddsrt_toBO4(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap4 (x) : (x))
#define ddsrt_toBO4u(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap4u (x) : (x))
#define ddsrt_toBO8(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap8 (x) : (x))
#define ddsrt_toBO8u(bo, x) ((bo) == DDSRT_BOSEL_LE ? ddsrt_bswap8u (x) : (x))
#define ddsrt_fromBE2(x) (x)
#define ddsrt_fromBE2u(x) (x)
#define ddsrt_fromBE4(x) (x)
#define ddsrt_fromBE4u(x) (x)
#define ddsrt_fromBE8(x) (x)
#define ddsrt_fromBE8u(x) (x)
#endif
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_BSWAP_H */
+64
View File
@@ -0,0 +1,64 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_CDTORS_H
#define DDSRT_CDTORS_H
#include "dds/export.h"
#include "dds/ddsrt/sync.h"
/**
* @file cdtors.h
* @brief Contains initializing and finalizing functions for some ddsrt units, and provides a singleton mutex and cond.
*
* Initializes and finalizes mutexes of ddsrt/random and ddsrt/atomics, and for Windows also the ddsrt/socket
* (not necessary for other platforms).
*/
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Initialize ddsrt units
*
* This doesn't need to be done more than once per process. It keeps track of the number of invocations,
* and if the current call isn't the first one, it just waits for initializing (by the first one) to finish.
* Note calling @ref ddsrt_init in parallel to the last invocation of @ref ddsrt_fini results in undefined behavior.
*/
void ddsrt_init(void);
/**
* @brief Finalize ddsrt units
*
* Since @ref ddsrt_init increments the reference count, it is decremented here. Only the last invocation
* (when the reference count is 1) actually finalizes it.
*/
void ddsrt_fini(void);
/**
* @brief Get a pointer to the global 'init_mutex'
*
* @return ddsrt_mutex_t* pointer to the mutex
*/
ddsrt_mutex_t *ddsrt_get_singleton_mutex(void);
/**
* @brief Get a pointer to the global 'init_cond'
*
* @return ddsrt_cond_t* pointer to the condition
*/
ddsrt_cond_t *ddsrt_get_singleton_cond(void);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_CDTORS_H */
+119
View File
@@ -0,0 +1,119 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_CIRCLIST_H
#define DDSRT_CIRCLIST_H
/**
* @file circlist.h
*
* Circular doubly linked list implementation.
*/
#include <stdbool.h>
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Macro to get the pointer to the user node, see @ref ddsrt_circlist_elem for an example.
*/
#define DDSRT_FROM_CIRCLIST(typ_, member_, cle_) ((typ_ *) ((char *) (cle_) - offsetof (typ_, member_)))
/** @brief the circular doubly linked list */
struct ddsrt_circlist {
struct ddsrt_circlist_elem *latest; /**< pointer to latest inserted element */
};
/// @brief The circlist element is the basic element of circular doubly linked list structure.
///
/// To store user data in the list, the element must be embedded in a user element, which is a struct containing the user data.
/// All API calls with an element as input or output, deal with the circlist element. Example:
/// @code{.c}
/// typedef struct num_s{ // user element
/// uint64_t val; // user data
/// ddsrt_circlist_elem elem;
/// }num_t;
/// @endcode
///
/// For functions like @ref ddsrt_circlist_latest, this means that to get a pointer to the user element, you can use the macro @ref DDSRT_FROM_CIRCLIST :
/// @code{.c}
/// num_t* num = DDSRT_FROM_CIRCLIST(num_t, elem, ddsrt_circlist_latest(listptr));
/// @endcode
struct ddsrt_circlist_elem {
struct ddsrt_circlist_elem *next;
struct ddsrt_circlist_elem *prev;
};
/**
* @brief initialize the list
*
* @param[out] list the circular list
*/
void ddsrt_circlist_init (struct ddsrt_circlist *list);
/**
* @brief check whether the list is empty
*
* @param[in] list the circular list
* @return true if empty, false if not empty
*/
bool ddsrt_circlist_isempty (const struct ddsrt_circlist *list);
/**
* @brief append an element to the list
*
* @param[in,out] list the circular list
* @param[in] elem the element to append
*
* See @ref ddsrt_circlist_remove
*/
void ddsrt_circlist_append (struct ddsrt_circlist *list, struct ddsrt_circlist_elem *elem);
/**
* @brief remove an element from the list
*
* The user is still responsible for freeing the memory associated with the element.
*
* @param[in,out] list the circular list
* @param[in] elem the element to append
*
* See @ref ddsrt_circlist_append
*/
void ddsrt_circlist_remove (struct ddsrt_circlist *list, struct ddsrt_circlist_elem *elem);
/**
* @brief get the oldest (earliest appended) element
*
* @param[in] list the circular list
* @return pointer to the oldest element
*
* See @ref ddsrt_circlist_latest, @ref ddsrt_circlist_elem
*/
struct ddsrt_circlist_elem *ddsrt_circlist_oldest (const struct ddsrt_circlist *list);
/**
* @brief get the latest (most recently appended) element
*
* @param[in] list the circular list
* @return pointer to the latest element
*
* See @ref ddsrt_circlist_oldest, @ref ddsrt_circlist_elem
*/
struct ddsrt_circlist_elem *ddsrt_circlist_latest (const struct ddsrt_circlist *list);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_CIRCLIST_H */
+26
View File
@@ -0,0 +1,26 @@
// Copyright(c) 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_COUNTARGS_H
#define DDSRT_COUNTARGS_H
/** @file countargs.h
@brief This header provides a macro @ref DDSRT_COUNT_ARGS that returns the number of arguments provided
(the other macros are just helper macros for @ref DDSRT_COUNT_ARGS)
*/
#define DDSRT_COUNT_ARGS_MSVC_WORKAROUND(x) x
/** @brief Returns the number of arguments provided (at most 20) */
#define DDSRT_COUNT_ARGS(...) DDSRT_COUNT_ARGS1 (__VA_ARGS__, 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define DDSRT_COUNT_ARGS1(...) DDSRT_COUNT_ARGS_MSVC_WORKAROUND (DDSRT_COUNT_ARGS_ARGN (__VA_ARGS__))
#define DDSRT_COUNT_ARGS_ARGN(a,b,c,d,e,f,g,h,i,j, k,l,m,n,o,p,q,r,s,t, N,...) N
#endif
+172
View File
@@ -0,0 +1,172 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_DYNLIB_H
#define DDSRT_DYNLIB_H
#include "dds/export.h"
#include "dds/config.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
#endif
//typedef void *ddsrt_dynlib_t;
typedef struct ddsrt_dynlib *ddsrt_dynlib_t;
/**
* @brief Load a dynamic shared library.
*
* The function ddsrt_dlopen() loads the dynamic shared object (shared library)
* file, identified by 'name', sets the handle parameter for the loaded library and
* returns the result with dds return code.
*
* If the 'translate' boolean is true, this function will first try to open the
* library with a translated 'name'. Translated in this context means that if
* "mylibrary" is provided, it will be translated into libmylibrary.so,
* libmylibrary.dylib or mylibrary.dll depending on the platform.
* This translation only happens when the given name does not contain
* a directory.
* If the function isn't able to load the library with the translated name, it
* will still try the given name.
*
* @param[in] name Library file name.
* @param[in] translate Automatic name translation on/off.
* @param[out] handle Library handle that will be assigned after successfull operation. It is assigned to NULL if loading fails.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Library handle was successfully loaded.
* @retval DDS_RETCODE_BAD_PARAM
* There is an invalid input in the parameter list
* @retval DDS_RETCODE_ERROR
* Loading failed.
* Use ddsrt_dlerror() to diagnose the failure.
*/
dds_return_t
ddsrt_dlopen(
const char *name,
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;
#if DDSRT_HAVE_DYNLIB
dds_return_t
ddsrt_platform_dlopen(
const char *name,
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;
#endif
/**
* @brief Close the library.
*
* The function ddsrt_dlclose() informs the system that the
* library, identified by 'handle', is no longer needed.
* will get the memory address of a symbol,
* identified by 'symbol', from a loaded library 'handle'.
*
* @param[in] handle Library handle.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Library handle was successfully closed.
* @retval DDS_RETCODE_ERROR
* Library closing failed.
* Use ddsrt_dlerror() to diagnose the failure.
*/
dds_return_t
ddsrt_dlclose(
ddsrt_dynlib_t handle);
#if DDSRT_HAVE_DYNLIB
dds_return_t
ddsrt_platform_dlclose(
ddsrt_dynlib_t handle);
#endif
/**
* @brief Get the memory address of a symbol.
*
* The function ddsrt_dlsym() will get the memory address of a symbol,
* identified by 'symbol', from a loaded library 'handle'.
*
* @param[in] handle Library handle.
* @param[in] symbol Symbol name.
* @param[out] address The memory address of the loaded symbol (void*).
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Symbol was found in the loaded library.
* Address parameter is ready to use.
* @retval DDS_RETCODE_ERROR
* Symbol was not found.
* Use ddsrt_dlerror() to diagnose the failure.
*/
dds_return_t
ddsrt_dlsym(
ddsrt_dynlib_t handle,
const char *symbol,
void **address);
#if DDSRT_HAVE_DYNLIB
dds_return_t
ddsrt_platform_dlsym(
ddsrt_dynlib_t handle,
const char *symbol,
void **address);
#endif
/**
* @brief Get the most recent library related error.
*
* The function ddsrt_dlerror() will return the most recent error of a
* call to ddsrt_dlopen, ddsrt_dlclose, ddsrt_dlsym in human readable form.
*
* If no error was found, it's either due to the fact that there
* actually was no error since init or last ddsrt_dlerror() call,
* or due to an unknown unrelated error.
*
* @param[out] buf Buffer to store the error message
* @param[in] buflen The length of the provided buffer (must be > 0).
*
* @returns A dds_return_t indicating success (>0) or failure.
*
* @retval >0
* The length of the returned error message
* @retval 0
* No dynamic library loading related error present
* @retval DDS_RETCODE_NOT_ENOUGH_SPACE
* Buffer is not large enough to hold the error message
*/
dds_return_t
ddsrt_dlerror(
char *buf,
size_t buflen);
#if DDSRT_HAVE_DYNLIB
dds_return_t
ddsrt_platform_dlerror(
char *buf,
size_t buflen);
#endif
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_DYNLIB_H */
+61
View File
@@ -0,0 +1,61 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ENDIAN_H
#define DDSRT_ENDIAN_H
#if defined(__cplusplus)
extern "C" {
#endif
#define DDSRT_LITTLE_ENDIAN 1
#define DDSRT_BIG_ENDIAN 2
#if _WIN32
# if defined(__BIG_ENDIAN)
# define DDSRT_ENDIAN DDSRT_BIG_ENDIAN
# else
# define DDSRT_ENDIAN DDSRT_LITTLE_ENDIAN
# endif
/* _WIN32 */
#elif defined(__IAR_SYSTEMS_ICC__)
# if __LITTLE_ENDIAN__ == 1
# define DDSRT_ENDIAN DDSRT_LITTLE_ENDIAN
# else
# define DDSRT_ENDIAN DDSRT_BIG_ENDIAN
# endif
/* __IAR_SYSTEMS_ICC__ */
#else
# if defined(__BYTE_ORDER__)
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define DDSRT_ENDIAN DDSRT_BIG_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define DDSRT_ENDIAN DDSRT_LITTLE_ENDIAN
# endif
# elif defined(__sun)
# include <sys/isa_defs.h>
# if defined(_BIG_ENDIAN)
# define DDSRT_ENDIAN DDSRT_BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN)
# define DDSRT_ENDIAN DDSRT_LITTLE_ENDIAN
# endif
# endif
#endif /* _WIN32 */
#if (DDSRT_ENDIAN != DDSRT_LITTLE_ENDIAN) && \
(DDSRT_ENDIAN != DDSRT_BIG_ENDIAN)
# error "Endianness cannot be determined"
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_ENDIAN_H */
+149
View File
@@ -0,0 +1,149 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_ENVIRON_H
#define DDSRT_ENVIRON_H
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/expand_vars.h"
#include "dds/ddsrt/retcode.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Get value for environment variable.
*
* @param[in] name Environment variable name.
* @param[out] value Alias to value of environment variable - must not be modified
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Environment variable written to @buf.
* @retval DDS_RETCODE_NOT_FOUND
* Environment variable not found.
* @retval DDS_RETCODE_BAD_PARAMETER
* FIXME: document
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* FIXME: document
* @retval DDS_RETCODE_ERROR
* Unspecified error.
*/
DDS_EXPORT dds_return_t
ddsrt_getenv(
const char *name,
const char **value)
ddsrt_nonnull_all;
/**
* @brief Set environment variable value.
*
* Sets the environment variable to the value specified in value, or
* alternatively, unsets the environment variable if value is an empty string.
*
* @param[in] name Environment variable name.
* @param[in] value Value to set environment variable to.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Environment variable successfully set to @value.
* @retval DDS_RETCODE_BAD_PARAMETER
* Invalid environment variable name.
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* Not enough system resources to set environment variable.
* @retval DDS_RETCODE_ERROR
* Unspecified system error.
*/
DDS_EXPORT dds_return_t
ddsrt_setenv(
const char *name,
const char *value)
ddsrt_nonnull_all;
/**
* @brief Unset environment variable value.
*
* @param[in] name Environment variable name.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Environment variable successfully unset.
* @retval DDS_RETCODE_BAD_PARAMETER
* Invalid environment variable name.
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* Not enough system resources to unset environment variable.
* @retval DDS_RETCODE_ERROR
* Unspecified system error.
*/
DDS_EXPORT dds_return_t
ddsrt_unsetenv(
const char *name)
ddsrt_nonnull_all;
/**
* @brief Expand environment variables within string.
*
* Expands ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, but not $X.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
* @param[in] domid Domain id that this is relevant to
* UINT32_MAX means none (see logging)
* also made available as
* ${CYCLONEDDS_DOMAIN_ID}
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the environment
* variables expanded.
*/
DDS_EXPORT char*
ddsrt_expand_envvars(
const char *string,
uint32_t domid);
/**
* @brief Expand environment variables within string.
*
* Expands $X, ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, $ and \
* can be escaped with \.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the environment
* variables expanded.
*/
DDS_EXPORT char*
ddsrt_expand_envvars_sh(
const char *string,
uint32_t domid);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_ENVIRON_H */
+77
View File
@@ -0,0 +1,77 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_EXPAND_VARS_H
#define DDSRT_EXPAND_VARS_H
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef const char * (*expand_lookup_fn)(const char *name, void *data);
/**
* @brief Expand variables within string.
*
* Expands ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, but not $X.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
* @param[in] lookup Lookup function to retrieve replacement value
* @param[in] data Data passed to lookup function
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the variables expanded.
*/
char*
ddsrt_expand_vars(
const char *string,
expand_lookup_fn lookup,
void * data);
/**
* @brief Expand variables within string.
*
* Expands $X, ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, $ and \
* can be escaped with \.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
* @param[in] lookup Lookup function to retrieve replacement value
* @param[in] data Data passed to lookup function
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the variables expanded.
*/
char*
ddsrt_expand_vars_sh(
const char *string,
expand_lookup_fn lookup,
void * data);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_EXPAND_VARS_H */
+189
View File
@@ -0,0 +1,189 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_FIBHEAP_H
#define DDSRT_FIBHEAP_H
/** @file fibheap.h
The main purpose of a fibonacci heap is for use as a priority queue i.e. repeatedly extracting the minimum of the set.
Certain operations i.e. insert, merge, decrease_key are very efficient in that they have O(1) time complexity,
but they they degrade the shape of the heap, which requires rebalancing to fix.
The necessary rebalancing is delayed until the next call to extract_min.
For example, after lots of calls to insert and/or decrease_key, the next call to extract_min is very expensive
since it has to rebalance, and this could take as much as O(N) in the worst case. This is where you pay off the debt
for procrastinating on rebalancing. Once balanced, following calls to extract_min will be O(log(N)).
*/
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
/// @brief The fibheap node is the basic element of the fibonacci heap.
///
/// - children: Rather than have a pointer to each child, it has one pointer to a representative child.
/// The other children can then be reached through the child's prev/next.
/// - prev/next: Siblings form a circular doubly linked list, so all can be reached going either direction.
/// A node without siblings will point prev/next to itself.
/// - mark: Is either 0 (unmarked) or 1 (marked). It is marked to indicate the node has lost a child since the last time
/// it was made the child of another node. Newly created nodes are unmarked.
/// A node becomes unmarked whenever it is made the child of another node.
/// The mark flag is of importance for @ref ddsrt_fibheap_decrease_key and @ref ddsrt_fibheap_delete.
///
/// To store user data in the heap, the node must be embedded in a user node, which is a struct containing the user data e.g.:
/// @code{.c}
/// typedef struct num_s{ // user node
/// uint64_t val; // user data
/// ddsrt_fibheap_node node;
/// }num_t;
/// @endcode
///
/// The offset obtained as 'offsetof(num_t, node)' is needed for @ref ddsrt_fibheap_def_init
typedef struct ddsrt_fibheap_node {
struct ddsrt_fibheap_node *parent; ///< The node's parent
struct ddsrt_fibheap_node *children; ///< The node's representative child.
struct ddsrt_fibheap_node *prev; ///< The node's left sibling.
struct ddsrt_fibheap_node *next; ///< The node’s right sibling.
unsigned mark: 1; ///< Indicates whether the node has lost a child since the last time it was made the child of another node.
unsigned degree: 31; ///< The number of children the node has
} ddsrt_fibheap_node_t;
/**
* @brief The fibonacci heap definition for the @ref ddsrt_fibheap
*
* Regarding the compare function, input arguments are pointers to the user nodes.
* The expected return values are as follows:
* - value < 0 to indicate va is less than vb
* - value > 0 to indicate va is greater than vb
* - value == 0 to indicate va is equal to vb
*
* See @ref ddsrt_fibheap_def_init, @ref DDSRT_FIBHEAPDEF_INITIALIZER
*/
typedef struct ddsrt_fibheap_def {
uintptr_t offset; ///< The offset of the @ref ddsrt_fibheap_node with respect to the user node
int (*cmp) (const void *va, const void *vb); ///< compare function for user nodes
} ddsrt_fibheap_def_t;
/** @brief The fibonacci heap */
typedef struct ddsrt_fibheap {
ddsrt_fibheap_node_t *roots; ///< points to root node with minimum key value
} ddsrt_fibheap_t;
/**
* @brief Macro to initialize @ref ddsrt_fibheap_def
*
* See @ref ddsrt_fibheap_def_init
*/
#define DDSRT_FIBHEAPDEF_INITIALIZER(offset, cmp) { (offset), (cmp) }
/**
* @brief Initialize the @ref ddsrt_fibheap_def
*
* @param[out] fhdef the fibonacci heap definition to initialize
* @param[in] offset the offset
* @param[in] cmp the compare function
*
* See @ref ddsrt_fibheap_init, @ref DDSRT_FIBHEAPDEF_INITIALIZER
*/
DDS_EXPORT void ddsrt_fibheap_def_init (ddsrt_fibheap_def_t *fhdef, uintptr_t offset, int (*cmp) (const void *va, const void *vb));
/**
* @brief Initialize the @ref ddsrt_fibheap
*
* @param[in] fhdef the fibonacci heap definition
* @param[out] fh the fibonacci heap
*
* See @ref ddsrt_fibheap_def_init
*/
DDS_EXPORT void ddsrt_fibheap_init (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh);
/**
* @brief Access the minimum node
*
* @param[in] fhdef the fibonacci heap definition
* @param[in] fh the fibonacci heap
* @return pointer to the minimum user node, NULL if empty
*
* See @ref ddsrt_fibheap_extract_min
*/
DDS_EXPORT void *ddsrt_fibheap_min (const ddsrt_fibheap_def_t *fhdef, const ddsrt_fibheap_t *fh);
/**
* @brief Merge two fibonacci heaps
*
* Contents of heap b are merged into heap a, emptying heap b.
*
* @param[in] fhdef the fibonacci heap definition
* @param[in,out] a target fibonacci heap
* @param[in,out] b source fibonacci heap
*
* See @ref ddsrt_fibheap_insert
*/
DDS_EXPORT void ddsrt_fibheap_merge (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *a, ddsrt_fibheap_t *b);
/**
* @brief Insert a node into a fibonacci heap
*
* @param[in] fhdef the fibonacci heap definition
* @param[in,out] fh the fibonacci heap
* @param[in] vnode user node to insert
*
* See @ref ddsrt_fibheap_extract_min, @ref ddsrt_fibheap_delete, @ref ddsrt_fibheap_merge
*/
DDS_EXPORT void ddsrt_fibheap_insert (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode);
/**
* @brief Remove a node from a fibonacci heap
*
* Despite the name 'delete', it only removes the node from the heap.
* To fully delete it, you still need to free the memory associated with the node.
*
* @param[in] fhdef the fibonacci heap definition
* @param[in,out] fh the fibonacci heap
* @param[in] vnode user node to delete
*
* See @ref ddsrt_fibheap_extract_min, @ref ddsrt_fibheap_insert
*/
DDS_EXPORT void ddsrt_fibheap_delete (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode);
/**
* @brief Take the minimum node from a fibonacci heap
*
* The user is responsible for freeing the memory associated with the node.
*
* @param[in] fhdef the fibonacci heap definition
* @param[in,out] fh the fibonacci heap
* @return pointer to the minimum user node, NULL if empty
*
* See @ref ddsrt_fibheap_min, @ref ddsrt_fibheap_delete, @ref ddsrt_fibheap_insert
*/
DDS_EXPORT void *ddsrt_fibheap_extract_min (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh);
/**
* @brief Reposition a node in the fibonacci heap to account for a decrease of its key
*
* Despite the name 'decrease_key', the function doesn't decrease the key.
* It assumes the key has already been decreased, and repositions the node such as to maintain a valid heap structure.
*
* @param[in] fhdef the fibonacci heap definition
* @param[in,out] fh the fibonacci heap
* @param[in] vnode user node to reposition
*/
DDS_EXPORT void ddsrt_fibheap_decrease_key (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_FIBHEAP_H */
+126
View File
@@ -0,0 +1,126 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_FILESYSTEM_H
#define DDSRT_FILESYSTEM_H
#include <stddef.h>
#include "dds/export.h"
#include "dds/config.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/time.h"
#if DDSRT_HAVE_FILESYSTEM
#if _WIN32
#include "dds/ddsrt/filesystem/windows.h"
#else
#include "dds/ddsrt/filesystem/posix.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
struct ddsrt_stat {
ddsrt_mode_t stat_mode;
size_t stat_size;
dds_time_t stat_mtime;
};
struct ddsrt_dirent {
char d_name[DDSRT_PATH_MAX + 1];
};
/** \brief opendir wrapper
*
* Open the directory conform opendir
*
* Precondition:
* none
*
* Possible results:
* - return DDS_RETCODE_OK if directory 'name' is opened
* - DDS_RETCODE_ERROR if 'name' could not
* be found or is not a directory.
*/
DDS_EXPORT dds_return_t ddsrt_opendir(const char *name, ddsrt_dir_handle_t *dir);
/** \brief closedir wrapper
*
* Close the directory conform closdir
*
* Precondition:
* none
*
* Possible results:
* - return DDS_RETCODE_OK if directory identified by the handle
* is succesfully closed
* - return DDS_RETCODE_ERROR if the handle is invalid.
*/
DDS_EXPORT dds_return_t ddsrt_closedir(ddsrt_dir_handle_t d);
/** \brief readdir wrapper
*
* Read the directory conform readdir.
*
* Precondition:
* none
*
* Possible results:
* - return DDS_RETCODE_OK if next directory is found
* - return DDS_RETCODE_ERROR if no more directories are found.
*/
DDS_EXPORT dds_return_t ddsrt_readdir(ddsrt_dir_handle_t d, struct ddsrt_dirent *direntp);
/** \brief stat wrapper
*
* Gets directory status conform stat.
*
* Precondition:
* none
*
* Possible results:
* - return DDS_RETCODE_OK if stat is successful
* - return DDS_RETCODE_ERROR if stat fails.
*/
DDS_EXPORT dds_return_t ddsrt_stat(const char *path, struct ddsrt_stat *buf);
/** \brief Transforms the given filepath into a platform specific filepath.
*
* This translation function will replace any platform file seperator into
* the fileseperator of the current platform. Doulbe quotes are removed
* as well.
*
* Precondition:
* none
*
* Possible results:
* - returns normalized filepath conform current platform
* - return NULL if out of memory.
*/
DDS_EXPORT char* ddsrt_file_normalize(const char *filepath);
/** \brief Get file seperator
*
* Possible Results:
* - "<file-seperator-string>"
*/
DDS_EXPORT const char* ddsrt_file_sep(void);
#if defined (__cplusplus)
}
#endif
#endif // DDRT_HAVE_FILESYSTEM
#endif // DDSRT_FILESYSTEM_H
+37
View File
@@ -0,0 +1,37 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_FILESYSTEM_POSIX_H
#define DDSRT_FILESYSTEM_POSIX_H
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
typedef DIR *ddsrt_dir_handle_t;
typedef mode_t ddsrt_mode_t;
#ifdef PATH_MAX
#define DDSRT_PATH_MAX PATH_MAX
#else
#define DDSRT_PATH_MAX FILENAME_MAX
#endif
#define DDSRT_FILESEPCHAR '/'
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_FILESYSTEM_POSIX_H */
+33
View File
@@ -0,0 +1,33 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_FILESYSTEM_WINDOWS_H
#define DDSRT_FILESYSTEM_WINDOWS_H
#include <sys/types.h>
#include <sys/stat.h>
#include "dds/ddsrt/types.h"
typedef HANDLE ddsrt_dir_handle_t;
typedef unsigned short ddsrt_mode_t;
#define DDSRT_PATH_MAX MAX_PATH
#define DDSRT_FILESEPCHAR '\\'
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_FILESYSTEM_WINDOWS_H */
+106
View File
@@ -0,0 +1,106 @@
// Copyright(c) 2024 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_FOREACH_H
#define DDSRT_FOREACH_H
/** @file foreach.h
@brief This header provides macros for operating on each argument provided
*/
#include "dds/ddsrt/countargs.h"
#define DDSRT_FOREACH_3_MSVC_WORKAROUND(x) x
#define DDSRT_FOREACH_3_1(f, sep, x) f(x)
#define DDSRT_FOREACH_3_2(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_1(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_3(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_2(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_4(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_3(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_5(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_4(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_6(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_5(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_7(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_6(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_8(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_7(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_9(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_8(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_10(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_9(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_11(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_10(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_12(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_11(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_13(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_12(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_14(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_13(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_15(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_14(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_16(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_15(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_17(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_16(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_18(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_17(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_19(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_18(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_3_20(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_19(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_2(n, f, sep, ...) DDSRT_FOREACH_3_MSVC_WORKAROUND(DDSRT_FOREACH_3_##n(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_1(n, f, sep, ...) DDSRT_FOREACH_2(n, f, sep, __VA_ARGS__)
#define DDSRT_FOREACH(f, sep, ...) DDSRT_FOREACH_1(DDSRT_COUNT_ARGS(__VA_ARGS__), f, sep, __VA_ARGS__)
#define DDSRT_FOREACH_WRAP(f, sep, ...) DDSRT_FOREACH(f, sep, __VA_ARGS__)
// 2nd set of DDSRT_FOREACH macros because we need two levels of DDSRT_FOREACH's but the
// C preprocessor doesn't allow recursive macro expansion
#define DDSRT_FOREACH_B_3_MSVC_WORKAROUND(x) x
#define DDSRT_FOREACH_B_3_1(f, sep, x) f(x)
#define DDSRT_FOREACH_B_3_2(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_1(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_3(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_2(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_4(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_3(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_5(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_4(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_6(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_5(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_7(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_6(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_8(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_7(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_9(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_8(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_10(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_9(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_11(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_10(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_12(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_11(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_13(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_12(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_14(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_13(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_15(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_14(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_16(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_15(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_17(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_16(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_18(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_17(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_19(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_18(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_3_20(f, sep, x, ...) f(x) sep() DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_19(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_2(n, f, sep, ...) DDSRT_FOREACH_B_3_MSVC_WORKAROUND(DDSRT_FOREACH_B_3_##n(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_B_1(n, f, sep, ...) DDSRT_FOREACH_B_2(n, f, sep, __VA_ARGS__)
#define DDSRT_FOREACH_B(f, sep, ...) DDSRT_FOREACH_B_1(DDSRT_COUNT_ARGS(__VA_ARGS__), f, sep, __VA_ARGS__)
#define DDSRT_FOREACH_B_WRAP(f, sep, ...) DDSRT_FOREACH_B(f, sep, __VA_ARGS__)
/* Operating on pairs of arguments */
#define DDSRT_COUNT_PAIRS_MSVC_WORKAROUND(x) x
#define DDSRT_COUNT_PAIRS(...) DDSRT_COUNT_PAIRS1 (__VA_ARGS__, 20,20,19,19,18,18,17,17,16,16,15,15,14,14,13,13,12,12,11,11,10,10,9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0)
#define DDSRT_COUNT_PAIRS1(...) DDSRT_COUNT_PAIRS_MSVC_WORKAROUND (DDSRT_COUNT_PAIRS_ARGN (__VA_ARGS__))
#define DDSRT_COUNT_PAIRS_ARGN(a,a1,b,b1,c,c1,d,d1,e,e1,f,f1,g,g1,h,h1,i,i1,j,j1, k,k1,l,l1,m,m1,n,n1,o,o1,p,p1,q,q1,r,r1,s,s1,t,t1, N,...) N
#define DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(x) x
#define DDSRT_FOREACH_PAIR_3_1(f, sep, x,y) f(x,y)
#define DDSRT_FOREACH_PAIR_3_2(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_1(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_3(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_2(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_4(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_3(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_5(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_4(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_6(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_5(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_7(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_6(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_8(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_7(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_9(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_8(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_10(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_9(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_11(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_10(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_12(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_11(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_13(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_12(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_14(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_13(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_15(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_14(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_16(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_15(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_17(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_16(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_18(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_17(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_19(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_18(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_3_20(f, sep, x,y, ...) f(x,y) sep() DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_19(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_2(n, f, sep, ...) DDSRT_FOREACH_PAIR_3_MSVC_WORKAROUND(DDSRT_FOREACH_PAIR_3_##n(f, sep, __VA_ARGS__))
#define DDSRT_FOREACH_PAIR_1(n, f, sep, ...) DDSRT_FOREACH_PAIR_2(n, f, sep, __VA_ARGS__)
#define DDSRT_FOREACH_PAIR(f, sep, ...) DDSRT_FOREACH_PAIR_1(DDSRT_COUNT_PAIRS(__VA_ARGS__), f, sep, __VA_ARGS__)
#define DDSRT_FOREACH_PAIR_WRAP(f, sep, ...) DDSRT_FOREACH_PAIR(f, sep, __VA_ARGS__)
#endif
+169
View File
@@ -0,0 +1,169 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
/**
* @file heap.h
* @brief Heap memory management.
*
* Platform independent interface to heap memory management.
*/
#ifndef DDSRT_HEAP_H
#define DDSRT_HEAP_H
#include <stddef.h>
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct ddsrt_allocation_ops {
void* (*malloc) (size_t size);
void* (*calloc) (size_t count, size_t size);
void* (*realloc) (void *memblk, size_t size);
void (*free) (void *ptr);
} ddsrt_allocation_ops_t;
/// @brief Set the memory allocators
///
/// Set the functions to malloc, calloc, realloc, and free memory. By default
/// the functions of `stdlib` will be used.
DDS_EXPORT void
ddsrt_set_allocator(
ddsrt_allocation_ops_t custom_ops);
/**
* @brief Allocate memory from heap.
*
* The allocated block of memory must be freed by calling @ddsrt_free when no
* longer used.
*
* @param[in] size The size, in bytes, of the block of memory to allocate.
*
* @returns A pointer to the allocated block of memory. abort() is called if
* not enough free memory was available.
*/
DDS_EXPORT void *
ddsrt_malloc(
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((1));
/**
* @brief Allocate memory from heap.
*
* Allocate a block of memory from heap with the given size. The allocated
* block of memory must be freed by calling @ddsrt_free when no longer used.
*
* @param[in] size The size, in bytes, of memory to allocate.
*
* @returns A pointer to the allocated block of memory, NULL if not enough
* memory was available.
*/
DDS_EXPORT void *
ddsrt_malloc_s(
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((1));
/**
* @brief Allocate memory from heap for an array of @count elements of @size
* bytes.
*
* The allocated memory is initialized to zero. The allocated memory must be
* freed by calling @ddsrt_free when no longer used.
*
* A non-NULL pointer, that must be freed is always returned, even if the sum
* @count and @size equals zero.
*
* @returns A pointer to the allocated memory. abort() is called if not enough
* free memory was available.
*/
DDS_EXPORT void *
ddsrt_calloc(
size_t count,
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((1,2));
/**
* @brief Allocate memory from heap for an array of @count elements of @size
* bytes.
*
* The allocated memory is initialized to zero. The allocated memory must be
* freed by calling @ddsrt_free when no longer used.
*
* A non-NULL pointer, that must be freed is always returned, even if the sum
* @count and @size equals zero.
*
* @returns A pointer to the allocated memory, or NULL if not enough memory was
* available.
*/
DDS_EXPORT void *
ddsrt_calloc_s(
size_t count,
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((1,2));
/**
* @brief Reallocate memory from heap.
*
* Reallocate memory from heap. If memblk is NULL the function returns
* ddsrt_malloc_s(size). If size is 0, ddsrt_realloc_s free's the memory
* pointed to by memblk and returns a pointer as if ddsrt_malloc_s(0) was
* invoked. The returned pointer must be free'd with ddsrt_free.
*
* @returns A pointer to reallocated memory. Calls abort() if not enough free
* memory was available.
*/
DDS_EXPORT void *
ddsrt_realloc(
void *memblk,
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((2));
/**
* @brief Reallocate memory from heap.
*
* Reallocate memory from heap. If memblk is NULL the function returns
* ddsrt_malloc_s(size). If size is 0, ddsrt_realloc_s free's the memory
* pointed to by memblk and returns a pointer as if ddsrt_malloc_s(0) was
* invoked. The returned pointer must be free'd with ddsrt_free.
*
* @returns A pointer to reallocated memory, or NULL if not enough free memory
* was available.
*/
DDS_EXPORT void *
ddsrt_realloc_s(
void *memblk,
size_t size)
ddsrt_attribute_malloc
ddsrt_attribute_alloc_size((2));
/**
* @brief Free a previously allocated block of memory and return it to heap.
*
* Free the allocated memory pointed to by @ptr and release it to the heap. No
* action will be taken if @ptr is NULL.
*
* @param[in] ptr Pointer to previously allocated block of memory.
*/
DDS_EXPORT void
ddsrt_free(void *ptr);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_HEAP_H */
+432
View File
@@ -0,0 +1,432 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_HOPSCOTCH_H
#define DDSRT_HOPSCOTCH_H
#include <stdint.h>
#include <stdbool.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
/** \file hopscotch.h
* The hopscotch hash table is implemented in three versions:
* - Standard version
* - Concurrent version (for shared use by multiple threads)
* - Embedded data version (stores a copy of the data)
*
* With exception of the embedded data version, the hash table stores pointers to user data,
* but doesn't manage the memory of the data itself.
*
* Note that elements in a hash table are unordered. If an ordered set is desired,
* then a different data structure such as a tree should be used.
*/
/**
* @brief User defined hash function.
*
* The hopscotch hash table is dependent on a proper functioning hash.
* If the hash function generates a lot of hash collisions, then it will
* not be able to handle that by design.
* It is capable of handling some collisions, but not more than 32 per
* bucket (less, when other hash values are clustered around the
* collision value).
* When proper distributed hash values are generated, then hopscotch
* works nice and quickly.
*/
typedef uint32_t (*ddsrt_hh_hash_fn) (const void *a);
/**
* @brief User defined equals function.
*
* Hopscotch needs to be able to compare two elements to confirm it has found the correct one
* (equal hashes doesn't guarantee that the keys are equal).
* The input arguments are pointers to the user data objects to compare.
* Returns int meant to be interpreted as bool (1 is match, 0 is no match)
*/
typedef bool (*ddsrt_hh_equals_fn) (const void *a, const void *b);
/**
* @brief User defined garbage collection function for buckets (only used for concurrent version).
*
* Hopscotch will resize its internal buckets list when needed. It will
* call this garbage collection function with the old buckets list. The
* caller has to delete the list when it deems it safe to do so.
*/
typedef void (*ddsrt_hh_buckets_gc_fn) (void *bs, void *arg);
/* Sequential version */
/**
* @brief The hopscotch hash table.
* @see ddsrt_hh_new
* @see ddsrt_hh_free
*/
struct ddsrt_hh;
/**
* @brief Iter object for the iterator to store its progress and know where to go next.
* @see ddsrt_hh_iter_first
*/
struct ddsrt_hh_iter {
struct ddsrt_hh *hh;
uint32_t cursor;
};
/**
* @brief Create a hopscotch hash table.
*
* @param[in] init_size the minimum initial size
* @param[in] hash the hash function, see @ref ddsrt_hh_hash_fn
* @param[in] equals the equals function, see @ref ddsrt_hh_equals_fn
* @return pointer to the hopscotch hash table
* @see ddsrt_hh_free
*/
DDS_EXPORT struct ddsrt_hh *ddsrt_hh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals) ddsrt_nonnull_all;
/**
* @brief Destroy a hopscotch hash table.
*
* It destroys the hash table and its buckets, but not the user data in the buckets.
* The user data in the table must be deleted prior to calling this,
* which can be done by using @ref ddsrt_hh_enum with a free function.
*
* @param[in,out] hh the hash table to destroy
* @see ddsrt_hh_new
*/
DDS_EXPORT void ddsrt_hh_free (struct ddsrt_hh *hh) ddsrt_nonnull_all;
/**
* @brief Lookup an element in the hash table.
*
* Despite the name, the parameter 'keyobject' is a pointer to the whole user data object, not just the key,
* so you need a dummy object to do the lookup. However, if the user data object is defined such that the key is its first element,
* then it is also possible to do the lookup by making just a key object and passing a pointer to that key.
*
* @param[in] rt the hash table
* @param[in] keyobject is the object with which to do the lookup
* @return pointer to the matching element, NULL if failed
*/
DDS_EXPORT void *ddsrt_hh_lookup (const struct ddsrt_hh *rt, const void *keyobject) ddsrt_nonnull_all;
/**
* @brief Add an element to the hash table.
*
* Attempting to add a duplicate to the hash table results in failure i.e. the element is not added,
* and the function returns with failure.
*
* @param[in,out] rt the hash table
* @param[in] data user data to add
* @return false iff key already present
* @see ddsrt_hh_remove
*/
DDS_EXPORT bool ddsrt_hh_add (struct ddsrt_hh *rt, void *data) ddsrt_nonnull_all;
/**
* @brief Remove an element from the hash table.
*
* It only uses the key of the passed object and as such it will also work if you pass a dummy object.
* However, you still need to free the memory of the object after removing it from the hash table.
* Since this means you need to have the pointer to the actual object anyway, you might as well use that.
*
* @param[in,out] rt the hash table
* @param[in] keyobject user data to remove
* @return false iff key not present
* @see ddsrt_hh_add
*/
DDS_EXPORT bool ddsrt_hh_remove (struct ddsrt_hh *rt, const void *keyobject) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_hh_add, but without returning success/failure result.
*
* Only use if you're certain that the element doesn't already exist.
*
* @param[in,out] rt the hash table
* @param[in] data user data to add
* @see ddsrt_hh_remove
*/
DDS_EXPORT void ddsrt_hh_add_absent (struct ddsrt_hh *rt, void *data) ddsrt_nonnull_all;
/**
* @brief Like @ref ddsrt_hh_remove, but without returning success/failure result.
*
* Only use if you're certain that the element exists.
*
* @param[in,out] rt the hash table
* @param[in] keyobject user data to remove
* @see ddsrt_hh_add_absent
*/
DDS_EXPORT void ddsrt_hh_remove_present (struct ddsrt_hh *rt, void *keyobject) ddsrt_nonnull_all;
/**
* @brief Walk the hash table and apply a user defined function to each node.
*
* The walk function 'f' receives in parameter 'a' the pointer to user data, and has 'f_arg' as an optional extra argument.
* It is allowed to modify the user data. The @ref ddsrt_hh_enum is useful to free user data
* (by passing a function 'f' that frees memory pointed to by 'a') prior to calling @ref ddsrt_hh_free.
*
* @param[in,out] rt the hash table
* @param[in] f user defined walk function to apply to each element
* @param[in] f_arg extra argument for walk function
* @see ddsrt_hh_iter_next
*/
DDS_EXPORT void ddsrt_hh_enum (struct ddsrt_hh *rt, void (*f) (void *a, void *f_arg), void *f_arg) ddsrt_nonnull ((1, 2));
/**
* @brief Initialize the iterator and get the first element.
*
* @param[in] rt the hash table
* @param[out] iter iterator object
* @return pointer to first element
* @see ddsrt_hh_iter_next
*/
DDS_EXPORT void *ddsrt_hh_iter_first (struct ddsrt_hh *rt, struct ddsrt_hh_iter *iter) ddsrt_nonnull_all;
/**
* @brief Use the iterator to get the next element
*
* @param[in,out] iter iterator object
* @return pointer to next element
* @see ddsrt_hh_iter_first
* @see ddsrt_hh_enum
*/
DDS_EXPORT void *ddsrt_hh_iter_next (struct ddsrt_hh_iter *iter) ddsrt_nonnull_all;
/* Concurrent version */
/**
* @brief The concurrent hopscotch hash table.
* @see ddsrt_chh_new
* @see ddsrt_chh_free
*/
struct ddsrt_chh;
struct ddsrt_chh_bucket;
/**
* @brief Embedded data version of @ref ddsrt_hh_iter.
* @see ddsrt_chh_iter_first
*/
struct ddsrt_chh_iter {
struct ddsrt_chh_bucket *bs;
uint32_t size;
uint32_t cursor;
};
/**
* @brief Concurrent version of @ref ddsrt_hh_new
*
* @param[in] init_size the minimum initial size
* @param[in] hash the hash function, see @ref ddsrt_hh_hash_fn
* @param[in] equals the equals function, see @ref ddsrt_hh_equals_fn
* @param[in] gc_buckets user defined garbage collection function, see @ref ddsrt_hh_buckets_gc_fn
* @param[in] gc_buckets_arg extra argument for @ref ddsrt_hh_buckets_gc_fn
* @return pointer to the hopscotch hash table
* @see ddsrt_chh_free
*/
struct ddsrt_chh *ddsrt_chh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets, void *gc_buckets_arg);
/**
* @brief Concurrent version of @ref ddsrt_hh_free
*
* @param[in,out] hh the hash table to destroy
* @see ddsrt_chh_new
*/
void ddsrt_chh_free (struct ddsrt_chh *hh);
/**
* @brief Concurrent version of @ref ddsrt_hh_lookup
*
* The lookup is lock-free and wait-free, and an element that exists in the hash table is guaranteed to be found.
* Note that wait-free doesn't mean the operation is unimpeded by actions of other threads,
* but rather it means that the operation will complete within a bounded number of steps.
*
* It can work in parallel to @ref ddsrt_chh_remove,
* but a successful lookup doesn't guarantee that the element hasn't been removed in the mean time.
*
* @param[in] rt the hash table
* @param[in] keyobject is the object with which to do the lookup
* @return pointer to the matching element, NULL if failed
*/
void *ddsrt_chh_lookup (struct ddsrt_chh *rt, const void *keyobject);
/**
* @brief Concurrent version of @ref ddsrt_hh_add
*
* @param[in,out] rt the hash table
* @param[in] data user data to add
* @return false iff key already present
* @see ddsrt_chh_remove
*/
bool ddsrt_chh_add (struct ddsrt_chh *rt, void *data);
/**
* @brief Concurrent version of @ref ddsrt_hh_remove
*
* It can work in parallel to @ref ddsrt_chh_lookup, but in that case the looked up element may not be
* part of the hash table anymore by the time the caller of @ref ddsrt_chh_lookup accesses the element.
*
* @param[in,out] rt the hash table
* @param[in] keyobject user data to remove
* @return false iff key not present
* @see ddsrt_chh_add
*/
bool ddsrt_chh_remove (struct ddsrt_chh *rt, const void *keyobject);
/**
* @brief Concurrent version of @ref ddsrt_hh_enum
*
* Called unsafe because:
* - if another thread is removing an element, then there is no guarantee that the element for which 'f' is invoked
* is still in the table at the time of invocation (similar to a @ref ddsrt_chh_remove and @ref ddsrt_chh_lookup)
* - if another thread is adding an element, there is no guarantee whether that new element will, or will not, be visited
* - if another thread is adding an element, there is no guarantee that an element won't be visited multiple times
*
* @param[in,out] rt the hash table
* @param[in] f user defined walk function to apply to each element
* @param[in] f_arg extra argument for walk function
* @see ddsrt_chh_iter_next
*/
void ddsrt_chh_enum_unsafe (struct ddsrt_chh *rt, void (*f) (void *a, void *f_arg), void *f_arg); /* may delete a */
/**
* @brief Concurrent version of @ref ddsrt_hh_iter_first
*
* @param[in] rt the hash table
* @param[out] it iterator object
* @return pointer to first element
* @see ddsrt_chh_iter_next
*/
void *ddsrt_chh_iter_first (struct ddsrt_chh *rt, struct ddsrt_chh_iter *it);
/**
* @brief Concurrent version of @ref ddsrt_hh_iter_next
*
* @param[in,out] it iterator object
* @return pointer to next element
* @see ddsrt_chh_iter_first
* @see ddsrt_chh_enum_unsafe
*/
void *ddsrt_chh_iter_next (struct ddsrt_chh_iter *it);
/* Sequential version, embedded data */
/**
* @brief The embedded data hopscotch hash table.
* @see ddsrt_ehh_new
* @see ddsrt_ehh_free
*/
struct ddsrt_ehh;
/**
* @brief Embedded data version of @ref ddsrt_hh_iter.
* @see ddsrt_ehh_iter_first
*/
struct ddsrt_ehh_iter {
struct ddsrt_ehh *hh;
uint32_t cursor;
};
/**
* @brief Embedded data version of @ref ddsrt_hh_new.
*
* Each element will use the same fixed size of embedded data. This means that for data that can vary in size (such as strings),
* you'll have to use the worst case size and thus waste memory. It is also not recommended to use the embedded data version
* with a large data size: It will hurt performance because each time the hash table is resized, all of the data is copied.
*
* @param[in] elemsz size (in bytes) of the embedded data element
* @param[in] init_size the minimum initial size
* @param[in] hash the hash function, see @ref ddsrt_hh_hash_fn
* @param[in] equals the equals function, see @ref ddsrt_hh_equals_fn
* @return pointer to the hopscotch hash table
* @see ddsrt_ehh_free
*/
struct ddsrt_ehh *ddsrt_ehh_new (size_t elemsz, uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals);
/**
* @brief Embedded data version of @ref ddsrt_hh_free
*
* Since the memory of the data is part of the bucket, it is also freed.
*
* @param[in,out] hh the hash table to destroy
* @see ddsrt_ehh_new
*/
void ddsrt_ehh_free (struct ddsrt_ehh *hh);
/**
* @brief Embedded data version of @ref ddsrt_hh_lookup
*
* @param[in] rt the hash table
* @param[in] keyobject is the object with which to do the lookup
* @return pointer to the matching element, NULL if failed
*/
void *ddsrt_ehh_lookup (const struct ddsrt_ehh *rt, const void *keyobject);
/**
* @brief Embedded data version of @ref ddsrt_hh_add
*
* The data is copied into a bucket of the hash table.
*
* @param[in,out] rt the hash table
* @param[in] data user data to add
* @return false iff key already present
* @see ddsrt_ehh_remove
*/
bool ddsrt_ehh_add (struct ddsrt_ehh *rt, const void *data);
/**
* @brief Embedded data version of @ref ddsrt_hh_remove
*
* There is no issue with memory management here. The bucket is simply tagged as not in use.
*
* @param[in,out] rt the hash table
* @param[in] keyobject user data to remove
* @return false iff key not present
* @see ddsrt_ehh_add
*/
bool ddsrt_ehh_remove (struct ddsrt_ehh *rt, const void *keyobject);
/**
* @brief Embedded data version of @ref ddsrt_hh_enum
*
* @param[in,out] rt the hash table
* @param[in] f user defined walk function to apply to each element
* @param[in] f_arg extra argument for walk function
* @see ddsrt_ehh_iter_next
*/
void ddsrt_ehh_enum (struct ddsrt_ehh *rt, void (*f) (void *a, void *f_arg), void *f_arg); /* may delete a */
/**
* @brief Embedded data version of @ref ddsrt_hh_iter_first
*
* @param[in] rt the hash table
* @param[out] iter iterator object
* @return pointer to first element
* @see ddsrt_ehh_iter_next
*/
void *ddsrt_ehh_iter_first (struct ddsrt_ehh *rt, struct ddsrt_ehh_iter *iter); /* may delete nodes */
/**
* @brief Embedded data version of @ref ddsrt_hh_iter_next
*
* @param[in,out] iter iterator object
* @return pointer to next element
* @see ddsrt_ehh_iter_first
* @see ddsrt_ehh_enum
*/
void *ddsrt_ehh_iter_next (struct ddsrt_ehh_iter *iter);
#if defined (__cplusplus)
}
#endif
#endif
+96
View File
@@ -0,0 +1,96 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_IFADDRS_H
#define DDSRT_IFADDRS_H
#include "dds/ddsrt/sockets.h"
/**
@file ifaddrs.h
@brief This header deals with interface addresses
*/
#if defined (__cplusplus)
extern "C" {
#endif
/** @brief The interface type */
enum ddsrt_iftype {
DDSRT_IFTYPE_UNKNOWN, ///< An unknown interface type
DDSRT_IFTYPE_WIRED, ///< A wired interface (e.g. ethernet)
DDSRT_IFTYPE_WIFI ///< A wifi (IEEE 802.11) interface
};
/** @brief Linked list of interface addresses */
struct ddsrt_ifaddrs {
struct ddsrt_ifaddrs *next; ///< pointer to the next interface in the returned list of interfaces
char *name; ///< name of the interface
uint32_t index; ///< a unique integer associated with the interface
uint32_t flags; ///< interface flags e.g. IFF_LOOPBACK, IFF_MASTER, IFF_MULTICAST
enum ddsrt_iftype type; ///< @see ddsrt_iftype
struct sockaddr *addr; ///< network address of this interface
struct sockaddr *netmask; ///< netmask of this interface (or NULL if it doesn't have one)
struct sockaddr *broadaddr; ///< broadcast address of this interface (or NULL if it doesn't have one)
};
typedef struct ddsrt_ifaddrs ddsrt_ifaddrs_t;
/**
* @brief Get the interface addresses (@ref ddsrt_ifaddrs) (and interface information) for specific address families
*
* A few points worth mentioning:
* - Array 'afs' must be terminated with an element 'DDSRT_AF_TERM'.
* - Only the interface addresses matching an address family in 'afs' are returned.
* - In case of any error, '*ifap' is left untouched.
* - In case of success, a new linked list @ref ddsrt_ifaddrs is allocated, and '*ifap' points to the first element.
* The user is responsible for freeing the memory at a later time using @ref ddsrt_freeifaddrs.
* - Multiple calls are allowed (with different 'afs' or not).
*
* @param[out] ifap interface address pointer
* @param[in] afs an array of address families
* @return a DDS_RETCODE (OK, ERROR, OUT_OF_RESOURCES, NOT_ALLOWED)
*/
DDS_EXPORT dds_return_t
ddsrt_getifaddrs(
ddsrt_ifaddrs_t **ifap,
const int *afs);
/**
* @brief Free the interface addresses returned by @ref ddsrt_getifaddrs
*
* @param[in] ifa the interface addresses to free
*/
DDS_EXPORT void
ddsrt_freeifaddrs(
ddsrt_ifaddrs_t *ifa);
/**
* @brief Get the mac address for a given interface name
*
* Copies the first 6 bytes of the mac address into the buffer 'mac_addr'.
* Specifying an unknown interface results in DDS_RETCODE_ERROR.
* If the interface exists and doesn't actually have a MAC address, like a loopback interface,
* the behaviour is platform-dependent. (On Linux, you get all 0, but that may not be universally true.)
*
* @param[in] interface_name the name of the interface
* @param[out] mac_addr a buffer to copy the mac address into
* @return a DDS_RETCODE (OK, ERROR)
*/
dds_return_t
ddsrt_eth_get_mac_addr(
char *interface_name,
unsigned char *mac_addr);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_IFADDRS_H */
+50
View File
@@ -0,0 +1,50 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_IO_H
#define DDSRT_IO_H
#include <stdarg.h>
#include <stdio.h>
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Write a formatted string to a newly allocated buffer.
*/
DDS_EXPORT int
ddsrt_vasprintf(
char **strp,
const char *fmt,
va_list ap);
/**
* @brief Write a formatted string to a newly allocated buffer.
*/
DDS_EXPORT int
ddsrt_asprintf(
char **strp,
const char *fmt,
...) ddsrt_attribute_format ((printf, 2, 3));
#if defined(_MSC_VER) && (_MSC_VER < 1900)
extern int snprintf(char *s, size_t n, const char *format, ...);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_IO_H */
+44
View File
@@ -0,0 +1,44 @@
// Copyright(c) 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_IOVEC_H
#define DDSRT_IOVEC_H
#if _WIN32
typedef unsigned ddsrt_iov_len_t;
typedef struct ddsrt_iovec {
ddsrt_iov_len_t iov_len;
void *iov_base;
} ddsrt_iovec_t;
// Equivalent to a DWORD
typedef unsigned long ddsrt_msg_iovlen_t;
#else // _WIN32
#if DDSRT_WITH_LWIP
#include <lwip/sockets.h>
#else
#include <stddef.h>
#include <sys/socket.h>
#endif
typedef struct iovec ddsrt_iovec_t;
typedef size_t ddsrt_iov_len_t;
#if defined(__linux) && !LWIP_SOCKET
typedef size_t ddsrt_msg_iovlen_t;
#else /* POSIX says int (which macOS, FreeBSD, Solaris do) */
typedef int ddsrt_msg_iovlen_t;
#endif
#endif // _WIN32
#endif
+465
View File
@@ -0,0 +1,465 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
/** @file
*
* @brief DDS C Logging API
*
* This header file defines the public API for logging and controlling logging
* in the DDS C language binding.
*/
#ifndef DDS_LOG_H
#define DDS_LOG_H
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
#endif
/** @defgroup log_categories Convenience log category definitions.
*
* These defines expand into numeric values that can be ORed together to
* specify messages of which categories must be passed to the respective sinks.
*
* Every category other than DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING and
* DDS_LC_INFO automatically falls into the trace category.
*
* @{
*/
/** Fatal error condition. Immediate abort on sink return. */
#define DDS_LC_FATAL (1u)
/** Error condition. */
#define DDS_LC_ERROR (2u)
/** Warning condition. */
#define DDS_LC_WARNING (4u)
/** Informational message. */
#define DDS_LC_INFO (8u)
/** Debug/trace messages related to configuration settings. */
#define DDS_LC_CONFIG (16u)
/** Debug/trace messages related to node discovery. */
#define DDS_LC_DISCOVERY (32u)
/** Currently unused. */
#define DDS_LC_DATA (64u)
/** Debug/trace messages for which no specialized category exists (yet). */
#define DDS_LC_TRACE (128u)
/** Debug/trace messages related to receive administration. */
#define DDS_LC_RADMIN (256u)
/** Debug/trace messages related to timing. */
#define DDS_LC_TIMING (512u)
/** Debug/trace messages related to send administration. */
#define DDS_LC_TRAFFIC (1024u)
/** Currently unused. */
#define DDS_LC_TOPIC (2048u)
/** Debug/trace messages related to TCP communication. */
#define DDS_LC_TCP (4096u)
/** Debug/trace messages related to parameter list processing. */
#define DDS_LC_PLIST (8192u)
/** Debug/trace messages related to the writer history cache. */
#define DDS_LC_WHC (16384u)
/** Debug/trace messages related to throttling. */
#define DDS_LC_THROTTLE (32768u)
/** Reader history cache. */
#define DDS_LC_RHC (65536u)
/** Include content in traces. */
#define DDS_LC_CONTENT (131072u)
/** Output full dump of malformed messages as warnings */
#define DDS_LC_MALFORMED (262144u)
/** Debug/trace messages related to sysdef parser. */
#define DDS_LC_SYSDEF (524288u)
/** Debug/trace messages related to qos provider. */
#define DDS_LC_QOSPROV (1048576u)
/** Reserved for user defined log categories (e.g. user application that uses Cyclone logger) */
#define DDS_LC_USER1 (1u << 29)
#define DDS_LC_USER2 (1u << 30)
#define DDS_LC_USER3 (1u << 31)
#define DDS_LC_USER (DDS_LC_USER1 | DDS_LC_USER2 | DDS_LC_USER3)
/** All common trace categories. */
#define DDS_LC_ALL \
(DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \
DDS_LC_CONFIG | DDS_LC_DISCOVERY | DDS_LC_DATA | DDS_LC_TRACE | \
DDS_LC_TIMING | DDS_LC_TRAFFIC | DDS_LC_TCP | DDS_LC_THROTTLE | \
DDS_LC_CONTENT | DDS_LC_USER)
/** @}*/
#define DDS_LOG_MASK \
(DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO)
#define DDS_TRACE_MASK \
(~DDS_LOG_MASK)
/** Structure with log message and meta data passed to callbacks. */
typedef struct {
/** Log category the message falls into. */
uint32_t priority;
/** Log domain id, UINT32_MAX is global. */
uint32_t domid;
/** Filename where message was generated. */
const char *file;
/** Line number in file where message was generated. */
uint32_t line;
/** Name of function message where message was generated. */
const char *function;
/** Log message. */
const char *message;
/** Size of log message. */
size_t size;
/** Default log message header length */
size_t hdrsize;
} dds_log_data_t;
/** Function signature that log and trace callbacks must adhere too. */
typedef void (*dds_log_write_fn_t) (void * p, const dds_log_data_t * d);
/** Semi-opaque type for log/trace configuration. */
struct ddsrt_log_cfg_common {
/** Mask for testing whether the xLOG macro should forward to the
function (and so incur the cost of constructing the parameters).
Messages in DDS_LOG_MASK are rare, so the overhead of calling
the function and then dropping the message is not an issue, unlike
for messages in DDS_TRACE_MASK. */
uint32_t mask;
/** The actual configured trace mask */
uint32_t tracemask;
/** Domain id for reporting; UINT32_MAX = no domain */
uint32_t domid;
};
typedef struct ddsrt_log_cfg {
struct ddsrt_log_cfg_common c;
union {
dds_log_write_fn_t fnptr;
void *ptr;
uint32_t u32;
unsigned char pad[72];
} u;
} ddsrt_log_cfg_t;
DDS_EXPORT extern uint32_t *const dds_log_mask;
/**
* @brief Get currently enabled log and trace categories.
*
* @returns A uint32_t with enabled categories set.
*/
DDS_INLINE_EXPORT inline uint32_t
dds_get_log_mask(void)
{
return *dds_log_mask;
}
/**
* @brief Set enabled log and trace categories.
*
* @param[in] cats Log and trace categories to enable.
*/
DDS_EXPORT void
dds_set_log_mask(
uint32_t cats);
/**
* @private
*/
void
dds_set_log_file(
FILE *file);
/**
* @private
*/
void
dds_set_trace_file(
FILE *file);
/**
* @brief Register callback to receive log messages
*
* Callbacks registered to handle log messages will receive messages of type
* info, warning, error and fatal. Messages that fall into the trace category
* will never be delivered to the callback.
*
* This operation is synchronous and only returns once the operation is
* registered with all threads. Meaning that neither callback or userdata will
* be referenced by the DDS stack on return.
*
* @param[in] callback Function pointer matching dds_log_write_fn signature
* or a null pointer to restore the default sink.
* @param[in] userdata User specified data passed along with each invocation
* of callback.
*/
void
dds_set_log_sink(
dds_log_write_fn_t callback,
void *userdata);
/**
* @brief Register callback to receive trace messages
*
* Callbacks registered to handle trace messages will receive messages of type
* info, warning, error and fatal as well as all message types that fall into
* the trace category depending on the log mask.
*
* This operation is synchronous and only returns once the operation is
* registered with all threads. Meaning that neither callback or
* userdata will be referenced by the DDS stack on return.
*
* @param[in] callback Function pointer matching dds_log_write_fn_t signature
* or a null pointer to restore the default sink.
* @param[in] userdata User specified data passed along with each invocation
* of callback.
*/
void
dds_set_trace_sink(
dds_log_write_fn_t callback,
void *userdata);
/**
* @brief Initialize a struct ddsrt_log_cfg for use with dds_log_cfg
*
* Callbacks registered to handle log messages will receive messages of type
* info, warning, error and fatal. Messages that fall into the trace category
* will never be delivered to the callback.
*
* Callbacks registered to handle trace messages will receive messages of type
* info, warning, error and fatal as well as all message types that fall into
* the trace category depending on the log mask.
*
* This operation is synchronous and only returns once the operation is
* registered with all threads. Meaning that neither callback or
* userdata will be referenced by the DDS stack on return.
*
* @param[out] cfg On return, initialised to make dds_log_cfg invoked
* with this config object behave as specified by the
* other parameters.
* @param[in] domid Numerical identifier in log/trace, UINT32_MAX is
* reserved for global logging.
* @param[in] tracemask Mask determining which traces should be written.
* @param[in] log_fp File for default sink.
* @param[in] trace_fp File for default sink.
*/
void
dds_log_cfg_init(
struct ddsrt_log_cfg *cfg,
uint32_t domid,
uint32_t tracemask,
FILE *log_fp,
FILE *trace_fp);
/**
* @brief Write a log or trace message for a specific logging configuraiton
* (categories, id, sinks).
*
* Direct use of #dds_log is discouraged. Use #DDS_CINFO, #DDS_CWARNING,
* #DDS_CERROR, #DDS_CTRACE or #DDS_CLOG instead.
*/
void
dds_log_cfg(
const struct ddsrt_log_cfg *cfg,
uint32_t cat,
const char *file,
uint32_t line,
const char *func,
const char *fmt,
...)
ddsrt_attribute_format_printf(6, 7);
/**
* @brief Write a log or trace message to the global configuration but with
* specific domain (intended solely for use during domain start-up, while
* the domain-specific logging/tracing hasn't been set yet).
*
* Write a log or trace message to one (or both) of the currently active sinks.
*
* Direct use of #dds_log_id is discouraged. Use #DDS_ILOG instead.
*/
void
dds_log_id(
uint32_t cat,
uint32_t domid,
const char *file,
uint32_t line,
const char *func,
const char *fmt,
...)
ddsrt_attribute_format_printf(6, 7);
/**
* @brief Write a log or trace message to the global log/trace.
*
* Write a log or trace message to one (or both) of the currently active sinks.
*
* Direct use of #dds_log is discouraged. Use #DDS_INFO, #DDS_WARNING,
* #DDS_ERROR, #DDS_FATAL or #DDS_LOG instead.
*/
DDS_EXPORT void
dds_log(
uint32_t cat,
const char *file,
uint32_t line,
const char *func,
const char *fmt,
...)
ddsrt_attribute_format_printf(5, 6);
/**
* @brief Undecorated function name of the current function.
*
* Behavior of DDS_FUNCTION outside a function is undefined. Note that
* implementations differ across compilers and compiler versions. It might be
* implemented as either a string literal or a constant variable.
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define DDS_FUNCTION __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
# define DDS_FUNCTION __func__
#elif defined(__GNUC__)
# define DDS_FUNCTION __FUNCTION__
#elif defined(__clang__)
# define DDS_FUNCTION __FUNCTION__
#elif defined(__ghs__)
# define DDS_FUNCTION __FUNCTION__
#elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
/* Solaris Studio had support for __func__ before it supported __FUNCTION__.
Compiler flag -features=extensions is required on older versions. */
# define DDS_FUNCTION __func__
#elif defined(__FUNCTION__)
/* Visual Studio */
# define DDS_FUNCTION __FUNCTION__
#elif defined(__vxworks)
/* At least versions 2.9.6 and 3.3.4 of the GNU C Preprocessor only define
__GNUC__ if the entire GNU C compiler is in use. VxWorks 5.5 targets invoke
the preprocessor separately resulting in __GNUC__ not being defined. */
# define DDS_FUNCTION __FUNCTION__
#else
# warning "DDS_FUNCTION is not supported"
# define DDS_FUNCTION ""
#endif
/**
* @brief Function signature of the current function.
*
* See comments on DDS_FUNCTION for details.
*/
#if defined(__GNUC__)
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif defined(__clang__)
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif defined(__ghs__)
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x5100)
/* Solaris Studio supports __PRETTY_FUNCTION__ in C since version 12.1 */
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5120)
/* Solaris Studio supports __PRETTY_FUNCTION__ in C++ since version 12.3 */
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
/* Visual Studio */
# define DDS_PRETTY_FUNCTION __FUNCSIG__
#elif defined(__vxworks)
/* See comments on __vxworks macro above. */
# define DDS_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
/* Fall back to DDS_FUNCTION. */
# define DDS_PRETTY_FUNCTION DDS_FUNCTION
#endif
/**
* @brief Write a log message.
*
* Write a log or trace message to the currently active log and/or trace sinks
* if the log category is enabled. Whether or not the category is enabled is
* checked before any dds_log-related activities to save a couple of % CPU.
*
* Only messages that fall into one of the log categories are passed onto
* dds_log. While messages that fall into a trace category could have been
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
#define DDS_LOG(cat, ...) \
((dds_get_log_mask() & (cat)) ? \
dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
/**
* @brief Write a log message with a domain id override.
*
* Write a log or trace message to the currently active log and/or trace sinks
* if the log category is enabled. Whether or not the category is enabled is
* checked before any dds_log-related activities to save a couple of % CPU.
*
* Only messages that fall into one of the log categories are passed onto
* dds_log. While messages that fall into a trace category could have been
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
#define DDS_ILOG(cat, domid, ...) \
((dds_get_log_mask() & (cat)) ? \
dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
/**
* @brief Write a log message using a specific config.
*
* Write a log or trace message to the currently active log and/or trace sinks
* if the log category is enabled. Whether or not the category is enabled is
* checked before any dds_log-related activities to save a couple of % CPU.
*
* Only messages that fall into one of the log categories are passed onto
* dds_log. While messages that fall into a trace category could have been
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
#define DDS_CLOG(cat, cfg, ...) \
(((cfg)->c.mask & (cat)) ? \
dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
/** Write a log message of type #DDS_LC_INFO into global log. */
#define DDS_INFO(...) \
DDS_LOG(DDS_LC_INFO, __VA_ARGS__)
/** Write a log message of type #DDS_LC_WARNING into global log. */
#define DDS_WARNING(...) \
DDS_LOG(DDS_LC_WARNING, __VA_ARGS__)
/** Write a log message of type #DDS_LC_ERROR into global log. */
#define DDS_ERROR(...) \
DDS_LOG(DDS_LC_ERROR, __VA_ARGS__)
/** Write a log message of type #DDS_LC_ERROR into global log and abort. */
#define DDS_FATAL(...) \
dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__)
/* MSVC mishandles __VA_ARGS__ while claiming to be conforming -- and even
if they have a defensible implement, they still differ from every other
compiler out there. An extra layer of macro expansion works around it. */
#define DDS_CLOG_MSVC_WORKAROUND(x) x
/** Write a log message of type #DDS_LC_INFO using specific logging config. */
#define DDS_CINFO(...) \
DDS_CLOG_MSVC_WORKAROUND(DDS_CLOG(DDS_LC_INFO, __VA_ARGS__))
/** Write a log message of type #DDS_LC_WARNING using specific logging config. */
#define DDS_CWARNING(...) \
DDS_CLOG_MSVC_WORKAROUND(DDS_CLOG(DDS_LC_WARNING, __VA_ARGS__))
/** Write a log message of type #DDS_LC_ERROR using specific logging config. */
#define DDS_CERROR(...) \
DDS_CLOG_MSVC_WORKAROUND(DDS_CLOG(DDS_LC_ERROR, __VA_ARGS__))
/** Write a #DDS_LC_TRACE message using specific logging config. */
#define DDS_CTRACE(...) \
DDS_CLOG_MSVC_WORKAROUND(DDS_CLOG(DDS_LC_TRACE, __VA_ARGS__))
#if defined (__cplusplus)
}
#endif
#endif /* DDS_LOG_H */
+119
View File
@@ -0,0 +1,119 @@
// Minimal changes introduced, for which:
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
// Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// L. Peter Deutsch
// ghost@aladdin.com
// $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $
// Independent implementation of MD5 (RFC 1321).
//
// This code implements the MD5 Algorithm defined in RFC 1321, whose
// text is available at
// http://www.ietf.org/rfc/rfc1321.txt
// The code is derived from the text of the RFC, including the test suite
// (section A.5) but excluding the rest of Appendix A. It does not include
// any code or documentation that is identified in the RFC as being
// copyrighted.
//
// The original and principal author of md5.h is L. Peter Deutsch
// <ghost@aladdin.com>. Other authors are noted in the change history
// that follows (in reverse chronological order):
//
// 2002-04-13 lpd Removed support for non-ANSI compilers; removed
// references to Ghostscript; clarified derivation from RFC 1321;
// now handles byte order either statically or dynamically.
// 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
// 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
// added conditionalization for C++ compilation from Martin
// Purschke <purschke@bnl.gov>.
// 1999-05-03 lpd Original version.
#ifndef DDSRT_MD5_H
#define DDSRT_MD5_H
#include <stddef.h>
#include "dds/export.h"
/** @file md5.h
* The MD5 hash (a 128-bit hash, still suitable for detecting unintentional corruption,
* but no longer to be used where a cryptographic hash is needed)
*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
typedef unsigned char ddsrt_md5_byte_t; /* 8-bit byte */
typedef unsigned int ddsrt_md5_word_t; /* 32-bit word */
/** @brief The state object for the MD5 Algorithm. */
typedef struct ddsrt_md5_state_s {
ddsrt_md5_word_t count[2]; /* message length in bits, lsw first */
ddsrt_md5_word_t abcd[4]; /* digest buffer */
ddsrt_md5_byte_t buf[64]; /* accumulate block */
} ddsrt_md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Initialize the @ref ddsrt_md5_state_s
*
* @param[out] pms the state object to initialize
*/
DDS_EXPORT void ddsrt_md5_init(ddsrt_md5_state_t *pms);
/**
* @brief Add bytes to the message
*
* @param[in,out] pms the state object
* @param[in] data pointer to data from which to compute the hash
* @param[in] nbytes size of the data in bytes
*/
DDS_EXPORT void ddsrt_md5_append(ddsrt_md5_state_t *pms, const ddsrt_md5_byte_t *data, unsigned nbytes);
/**
* @brief Finish the message and return the hash
*
* @param[in,out] pms the state object
* @param[out] digest the 128-bit hash
*/
DDS_EXPORT void ddsrt_md5_finish(ddsrt_md5_state_t *pms, ddsrt_md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* DDSRT_MD5_H */
+46
View File
@@ -0,0 +1,46 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_MH3_H
#define DDSRT_MH3_H
/** @file mh3.h
* The Murmur hash is designed to be fast and is intended for use in hash based lookups.
* It is not suitable for cryptographic purposes.
*/
#include <stdint.h>
#include <stddef.h>
#include "dds/export.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Generate a 32-bit hash
*
* @param[in] key pointer to key from which to compute the hash
* @param[in] len size of the key in bytes
* @param[in] seed a 32-bit seed to use for computing the hash
* @return the hash
*/
DDS_EXPORT uint32_t
ddsrt_mh3(
const void *key,
size_t len,
uint32_t seed);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_MH3_H */
+98
View File
@@ -0,0 +1,98 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_MISC_H
#define DDSRT_MISC_H
#include <limits.h>
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_STRINGIFY(x) DDSRT_STRINGIFY1(x)
#define DDSRT_STRINGIFY1(x) #x
#if defined(__clang__) || \
defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
# define DDSRT_STR(s) #s
# define DDSRT_JOINSTR(x,y) DDSRT_STR(x ## y)
# define DDSRT_DO_PRAGMA(x) _Pragma(#x)
# define DDSRT_PRAGMA(x) DDSRT_DO_PRAGMA(GCC diagnostic x)
# if defined(__clang__)
# define DDSRT_WARNING_CLANG_OFF(x) \
DDSRT_PRAGMA(push) \
DDSRT_PRAGMA(ignored DDSRT_JOINSTR(-W,x))
# define DDSRT_WARNING_CLANG_ON(x) \
DDSRT_PRAGMA(pop)
# elif ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define DDSRT_WARNING_GNUC_OFF(x) \
DDSRT_PRAGMA(push) \
DDSRT_PRAGMA(ignored DDSRT_JOINSTR(-W,x))
# define DDSRT_WARNING_GNUC_ON(x) \
DDSRT_PRAGMA(pop)
# else
# define DDSRT_WARNING_GNUC_OFF(x) \
DDSRT_PRAGMA(ignored DDSRT_JOINSTR(-W,x))
# define DDSRT_WARNING_GNUC_ON(x) \
DDSRT_PRAGMA(warning DDSRT_JOINSTR(-W,x))
# endif
#endif
#if !defined(DDSRT_WARNING_CLANG_OFF) && \
!defined(DDSRT_WARNING_CLANG_ON)
# define DDSRT_WARNING_CLANG_OFF(x)
# define DDSRT_WARNING_CLANG_ON(x)
#endif
#if !defined(DDSRT_WARNING_GNUC_OFF) && \
!defined(DDSRT_WARNING_GNUC_ON)
# define DDSRT_WARNING_GNUC_OFF(x)
# define DDSRT_WARNING_GNUC_ON(x)
#endif
#if defined(_MSC_VER)
# define DDSRT_WARNING_MSVC_OFF(x) \
__pragma (warning(push)) \
__pragma (warning(disable: ## x))
# define DDSRT_WARNING_MSVC_ON(x) \
__pragma (warning(pop))
#else
# define DDSRT_WARNING_MSVC_OFF(x)
# define DDSRT_WARNING_MSVC_ON(x)
#endif
/**
* @brief Macro to disable unused argument warnings
*/
#define DDSRT_UNUSED_ARG(a) (void)(a)
/**
* @brief Macro to disable warnings for calling deprecated interfaces
*/
#define DDSRT_WARNING_DEPRECATED_OFF \
DDSRT_WARNING_CLANG_OFF(deprecated-declarations) \
DDSRT_WARNING_GNUC_OFF(deprecated-declarations) \
DDSRT_WARNING_MSVC_OFF(4996)
/**
* @brief Macro to enable warnings for calling deprecated interfaces
*/
#define DDSRT_WARNING_DEPRECATED_ON \
DDSRT_WARNING_CLANG_ON(deprecated-declarations) \
DDSRT_WARNING_GNUC_ON(deprecated-declarations) \
DDSRT_WARNING_MSVC_ON(4996)
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_MISC_H */
+67
View File
@@ -0,0 +1,67 @@
// Copyright(c) 2019 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_NETSTAT_H
#define DDSRT_NETSTAT_H
#include <stdint.h>
#include "dds/export.h"
#include "dds/config.h"
#include "dds/ddsrt/retcode.h"
#if DDSRT_HAVE_NETSTAT
#if defined(__cplusplus)
extern "C" {
#endif
struct ddsrt_netstat {
uint64_t ipkt;
uint64_t opkt;
uint64_t ibytes;
uint64_t obytes;
};
/**
* @brief Platform dependent control structure for network statistics
*/
struct ddsrt_netstat_control;
/**
* @brief Prepare for gathering network statistics for specified interface.
*/
DDS_EXPORT dds_return_t
ddsrt_netstat_new (
struct ddsrt_netstat_control **control,
const char *device);
/**
* @brief Release resources for gathering network statistics.
*/
DDS_EXPORT dds_return_t
ddsrt_netstat_free (
struct ddsrt_netstat_control *control);
/**
* @brief Get network statistics.
*/
DDS_EXPORT dds_return_t
ddsrt_netstat_get (
struct ddsrt_netstat_control *control,
struct ddsrt_netstat *stats);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_HAVE_NETSTAT */
#endif /* DDSRT_NETSTAT_H */
+77
View File
@@ -0,0 +1,77 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_PROCESS_H
#define DDSRT_PROCESS_H
#include "dds/export.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/retcode.h"
#if DDSRT_WITH_FREERTOS
#include <FreeRTOS.h>
#include <task.h>
typedef TaskHandle_t ddsrt_pid_t; /* typedef void *TaskHandle_t */
#define PRIdPID "p"
#define DDSRT_HAVE_MULTI_PROCESS 0
/* DDSRT_WITH_FREERTOS */
#elif defined(_WIN32)
typedef uint32_t ddsrt_pid_t;
#define PRIdPID PRIu32
#define DDSRT_HAVE_MULTI_PROCESS 1
/* _WIN32 */
#else
#include <unistd.h>
#if defined(_WRS_KERNEL)
typedef RTP_ID ddsrt_pid_t; /* typedef struct wind_rtp *RTP_ID */
#define PRIdPID PRIuPTR
#define DDSRT_HAVE_MULTI_PROCESS 0
#elif defined(__ZEPHYR__)
typedef int ddsrt_pid_t;
#define PRIdPID "d"
#define DDSRT_HAVE_MULTI_PROCESS 0
#else
typedef pid_t ddsrt_pid_t;
#define PRIdPID "d"
#define DDSRT_HAVE_MULTI_PROCESS 1
#endif
#endif
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Return process ID (PID) of the calling process.
*
* @returns The process ID of the calling process.
*/
DDS_EXPORT ddsrt_pid_t
ddsrt_getpid(void);
/**
* @brief Return process name of the calling process.
*
* On linux maps to /proc/self/cmdline's first entry (argv[0]),
* on mac/windows maps to relevant API calls. Falls back to process-{pid}
* on failure.
*
* @returns The process name of the calling process.
*/
DDS_EXPORT char *
ddsrt_getprocessname(void);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_PROCESS_H */
+48
View File
@@ -0,0 +1,48 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_RANDOM_H
#define DDSRT_RANDOM_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_MT19937_N 624
typedef struct ddsrt_prng_seed {
uint32_t key[8];
} ddsrt_prng_seed_t;
typedef struct ddsrt_prng {
uint32_t mt[DDSRT_MT19937_N];
uint32_t mti;
} ddsrt_prng_t;
void ddsrt_random_init (void);
void ddsrt_random_fini (void);
void ddsrt_prng_init_simple (ddsrt_prng_t *prng, uint32_t seed);
bool ddsrt_prng_makeseed (struct ddsrt_prng_seed *seed);
void ddsrt_prng_init (ddsrt_prng_t *prng, const struct ddsrt_prng_seed *seed);
uint32_t ddsrt_prng_random (ddsrt_prng_t *prng);
size_t ddsrt_prng_random_name(ddsrt_prng_t *prng, char* output, size_t output_size);
DDS_EXPORT uint32_t ddsrt_random (void);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_RANDOM_H */
+98
View File
@@ -0,0 +1,98 @@
#ifndef DDS_RETCODE_H
#define DDS_RETCODE_H
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
typedef int32_t dds_return_t;
/*
State is unchanged following a function call returning an error
other than UNSPECIFIED, OUT_OF_RESOURCES and ALREADY_DELETED.
Error handling functions. Three components to returned int status value.
1 - The DDS_ERR_xxx error number
2 - The file identifier
3 - The line number
All functions return >= 0 on success, < 0 on error
*/
/**
* @defgroup retcode (Return Codes)
* @ingroup dds
* @{
*/
#define DDS_RETCODE_OK (0) /**< Success */
#define DDS_RETCODE_ERROR (-1) /**< Non specific error */
#define DDS_RETCODE_UNSUPPORTED (-2) /**< Feature unsupported */
#define DDS_RETCODE_BAD_PARAMETER (-3) /**< Bad parameter value */
#define DDS_RETCODE_PRECONDITION_NOT_MET (-4) /**< Precondition for operation not met */
#define DDS_RETCODE_OUT_OF_RESOURCES (-5) /**< When an operation fails because of a lack of resources */
#define DDS_RETCODE_NOT_ENABLED (-6) /**< When a configurable feature is not enabled */
#define DDS_RETCODE_IMMUTABLE_POLICY (-7) /**< When an attempt is made to modify an immutable policy */
#define DDS_RETCODE_INCONSISTENT_POLICY (-8) /**< When a policy is used with inconsistent values */
#define DDS_RETCODE_ALREADY_DELETED (-9) /**< When an attempt is made to delete something more than once */
#define DDS_RETCODE_TIMEOUT (-10) /**< When a timeout has occurred */
#define DDS_RETCODE_NO_DATA (-11) /**< When expected data is not provided */
#define DDS_RETCODE_ILLEGAL_OPERATION (-12) /**< When a function is called when it should not be */
#define DDS_RETCODE_NOT_ALLOWED_BY_SECURITY (-13) /**< When credentials are not enough to use the function */
/* Extended return codes are not in the DDS specification and are meant
exclusively for internal use and must not be returned by the C API. */
#define DDS_XRETCODE_BASE (-50) /**< Base offset for extended return codes */
#define DDS_XRETCODE(x) (DDS_XRETCODE_BASE - (x)) /**< Extended return code generator */
/** Requested resource is busy */
#define DDS_RETCODE_IN_PROGRESS DDS_XRETCODE(1)
/** Resource unavailable, try again */
#define DDS_RETCODE_TRY_AGAIN DDS_XRETCODE(2)
/** Operation was interrupted */
#define DDS_RETCODE_INTERRUPTED DDS_XRETCODE(3)
/** Permission denied */
#define DDS_RETCODE_NOT_ALLOWED DDS_XRETCODE(4)
/** Host not found */
#define DDS_RETCODE_HOST_NOT_FOUND DDS_XRETCODE(5)
/** Network is not available */
#define DDS_RETCODE_NO_NETWORK DDS_XRETCODE(6)
/** Connection is not available */
#define DDS_RETCODE_NO_CONNECTION DDS_XRETCODE(7)
/* Host not reachable is used to indicate that a connection was refused
(ECONNREFUSED), reset by peer (ECONNRESET) or that a host or network cannot
be reached (EHOSTUNREACH, ENETUNREACH). Generally all system errors that
indicate a connection cannot be made or that a message cannot be delivered,
map onto host not reachable. */
/** Not enough space available */
#define DDS_RETCODE_NOT_ENOUGH_SPACE DDS_XRETCODE(8)
/* Not enough space is used to indicate there is not enough buffer space to
read a message from the network (i.e. EMSGSIZE), but is also used to
indicate there is not enough space left on a device, etc. */
/** Result too large */
#define DDS_RETCODE_OUT_OF_RANGE DDS_XRETCODE(9)
/** Not found */
#define DDS_RETCODE_NOT_FOUND DDS_XRETCODE(10)
/**
* @brief Takes the error value and outputs a string corresponding to it.
*
* @param[in] ret Error value to be converted to a string
*
* @returns String corresponding to the error value
*/
DDS_EXPORT const char *dds_strretcode(dds_return_t ret);
/**
* @}
*/
#if defined (__cplusplus)
}
#endif
#endif /* DDS_RETCODE_H */
+85
View File
@@ -0,0 +1,85 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_RUSAGE_H
#define DDSRT_RUSAGE_H
#include <stddef.h>
#include "dds/config.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/threads.h"
#if DDSRT_HAVE_RUSAGE
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
dds_time_t utime; /* User CPU time used. */
dds_time_t stime; /* System CPU time used. */
size_t maxrss; /* Maximum resident set size in bytes. */
size_t idrss; /* Integral unshared data size. Not maintained on (at least)
Linux and Windows. */
size_t nvcsw; /* Voluntary context switches. Not maintained on Windows. */
size_t nivcsw; /* Involuntary context switches. Not maintained on Windows. */
} ddsrt_rusage_t;
enum ddsrt_getrusage_who {
DDSRT_RUSAGE_SELF,
DDSRT_RUSAGE_THREAD
};
/**
* @brief Get resource usage for the current thread or process.
*
* @param[in] who DDSRT_RUSAGE_SELF or DDSRT_RUSAGE_THREAD.
* @param[in] usage Structure where resource usage is returned.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Resource usage successfully returned in @usage.
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* There were not enough resources to get resource usage.
* @retval DDS_RETCODE_ERROR
* An unidentified error occurred.
*/
DDS_EXPORT dds_return_t ddsrt_getrusage(enum ddsrt_getrusage_who who, ddsrt_rusage_t *usage);
#if DDSRT_HAVE_THREAD_LIST
/**
* @brief Get resource usage for some thread.
*
* @param[in] tid id of the thread of to get the resource usage for
* @param[in] usage Structure where resource usage is returned.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Resource usage successfully returned in @usage.
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* There were not enough resources to get resource usage.
* @retval DDS_RETCODE_ERROR
* An unidentified error occurred.
*/
DDS_EXPORT dds_return_t ddsrt_getrusage_anythread (ddsrt_thread_list_id_t tid, ddsrt_rusage_t *usage);
#endif
#if defined (__cplusplus)
}
#endif
#endif // DDSRT_HAVE_RUSAGE
#endif // DDSRT_RUSAGE_H
+48
View File
@@ -0,0 +1,48 @@
// Copyright(c) 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_SCHED_H
#define DDSRT_SCHED_H
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Thread scheduling classes
* @{
*/
typedef enum {
/** Schedule processes and threads according a platform default.
* DDSRT_SCHED_REALTIME for timesharing platforms and
* DDSRT_SCHED_TIMESHARE for realtime platforms
*/
DDSRT_SCHED_DEFAULT,
/** Schedule processes and threads on realtime basis,
* on most platforms implying:
* - Fixed Priority
* - Preemption
* - Either "First In First Out" or "Round Robin"
*/
DDSRT_SCHED_REALTIME,
/** Schedule processes and threads on timesharing basis,
* on most platforms implying:
* - Dynamic Priority to guarantee fair share
* - Preemption
*/
DDSRT_SCHED_TIMESHARE
} ddsrt_sched_t;
/** @} */
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_SCHED_H */
+578
View File
@@ -0,0 +1,578 @@
#ifndef DDSRT_SOCKETS_H
#define DDSRT_SOCKETS_H
#include <stdbool.h>
#include "dds/export.h"
#include "dds/config.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/misc.h"
#if _WIN32
#include "dds/ddsrt/sockets/windows.h"
#else
#include "dds/ddsrt/sockets/posix.h"
#endif
/** @file sockets.h
*
* This provides the interface for sockets. Most of the functions declared here, map directly onto the corresponding
* OS functions. Therefore the nitty gritty details are omitted as they should be available in the OS documentation.
*/
#if defined (__cplusplus)
extern "C" {
#endif
#define INET_ADDRSTRLEN_EXTENDED (INET_ADDRSTRLEN + 6) /* ":12345" */
#if DDSRT_HAVE_IPV6
#define INET6_ADDRSTRLEN_EXTENDED (INET6_ADDRSTRLEN + 8) /* "[]:12345" */
extern const struct in6_addr ddsrt_in6addr_any;
extern const struct in6_addr ddsrt_in6addr_loopback;
#endif /* DDSRT_HAVE_IPV6 */
#define DDSRT_AF_TERM (-1)
#if DDSRT_HAVE_GETHOSTNAME
/**
* @brief Get the hostname
*
* The buffer needs to be large enough to hold the name including null terminator.
* On success, the buffer will include the null terminator.
*
* @param[out] hostname a buffer to copy the name into
* @param[in] buffersize the space (in bytes) that may be used
* @return a DDS_RETCODE (OK, ERROR, NOT_ENOUGH_SPACE)
*/
DDS_EXPORT dds_return_t
ddsrt_gethostname(
char *hostname,
size_t buffersize);
#endif
/**
* @brief Creates a socket
*
* @param[out] sockptr a pointer to the socket (file descriptor) created
* @param[in] domain the communication domain, selects the protocol family e.g. PF_INET, PF_PACKET
* @param[in] type specifies communication semantics e.g. SOCK_STREAM, SOCK_RAW
* @param[in] protocol specifies a particular protocol to be used with the socket e.g. IPPROTO_TCP, IPPROTO_UDP.
* Normally only a single protocol exists to support a particular socket type within a given protocol family,
* in which case protocol can be specified as 0.
* @return a DDS_RETCODE (OK, ERROR, NOT_ALLOWED, BAD_PARAMETER, OUT_OF_RESOURCES)
*
* See @ddsrt_bind, @ddsrt_close
*/
dds_return_t
ddsrt_socket(
ddsrt_socket_t *sockptr,
int domain,
int type,
int protocol);
/**
* @brief Initialize an "extended socket" based on a normal socket
*
* @note The "extended socket" currently only serves as a holder for the WSARecvMsg
* pointer on Windows.
*
* @param[out] sockext the extended socket
* @param[in] sock the socket (file descriptor) created by @ref ddsrt_socket
*/
void
ddsrt_socket_ext_init(
ddsrt_socket_ext_t *sockext,
ddsrt_socket_t sock);
/**
* @brief Undo the work of @ref ddsrt_socket_ext_init
*
* @note Does not close the socket (it is not opened by @ref ddsrt_socket_ext_init, so it
* is not closed here)
*
* @param[in] sockext the extended socket
*/
void
ddsrt_socket_ext_fini(
ddsrt_socket_ext_t *sockext);
/**
* @brief Close the socket
*
* @param[in,out] sock the socket (file descriptor) created by @ref ddsrt_socket
* @return a DDS_RETCODE (OK, ERROR, INTERRUPTED, BAD_PARAMETER)
*/
dds_return_t
ddsrt_close(
ddsrt_socket_t sock);
/**
* @brief Connects the socket to the address specified by 'addr'.
*
* @param[in,out] sock the socket
* @param[in] addr a socket address
* @param[in] addrlen the size of 'addr'
* @return a DDS_RETCODE (OK, ERROR, TIMEOUT, and more)
*
* See @ref ddsrt_accept
*/
dds_return_t
ddsrt_connect(
ddsrt_socket_t sock,
const struct sockaddr *addr,
socklen_t addrlen);
/**
* @brief Accept a connect (@ref ddsrt_connect) request and create a new connected socket for it.
*
* Is used with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET).
* - 'addrlen' must contain the size of the structure pointed to by 'addr' before the operation,
* and afterwards will contain the the size of the peer address.
* - when not used, 'addr' and 'addrlen' must be NULL
*
* @param[in,out] sock socket with which to wait for a connection
* @param[out] addr address of the connecting peer
* @param[in,out] addrlen the size (in bytes) of the structure pointed to by 'addr'
* @param[out] connptr pointer to the new connected socket.
* @return a DDS_RETCODE (OK, ERROR, and more)
*
* See @ref ddsrt_bind, ddsrt_listen
*/
dds_return_t
ddsrt_accept(
ddsrt_socket_t sock,
struct sockaddr *addr,
socklen_t *addrlen,
ddsrt_socket_t *connptr);
/**
* @brief Marks the socket referred to by 'sock' as a passive socket.
*
* A passive socket will be used to accept incoming connection requests using @ref ddsrt_accept.
*
* @param[in,out] sock file descriptor of the socket
* @param[in] backlog maximum number of pending connections
* @return a DDS_RETCODE (OK, ERROR, PRECONDITION_NOT_MET, BAD_PARAMETER, ILLEGAL_OPERATION)
*/
dds_return_t
ddsrt_listen(
ddsrt_socket_t sock,
int backlog);
/**
* @brief Assign an address to the socket.
*
* When a socket is created with @ref ddsrt_socket, it exists in a name space (address family) but has no address assigned to it.
* @ref ddsrt_bind assigns the address specified by 'addr' to the socket referred to by the file descriptor 'sock'.
*
* @param[in,out] sock the socket
* @param[in] addr address to assign to the socket
* @param[in] addrlen specifies the size, in bytes, of the address structure pointed to by 'addr'
* @return a DDS_RETCODE (OK, ERROR, NOT_ALLOWED, PRECONDITION_NOT_MET, BAD_PARAMETER)
*/
dds_return_t
ddsrt_bind(
ddsrt_socket_t sock,
const struct sockaddr *addr,
socklen_t addrlen);
/**
* @brief Get the current address to which the socket is bound (@ref ddsrt_bind).
*
* The 'addrlen' argument should be initialized to indicate the amount of space (in bytes)
* pointed to by 'addr'. On return it contains the actual size of the socket address.
* The returned address is truncated if the buffer provided is too small; in this case, 'addrlen' will return a value greater than was supplied to the call.
*
* @param[in] sock the socket
* @param[out] addr the address of the socket
* @param[in,out] addrlen specifies the size, in bytes, of the address structure pointed to by 'addr'
* @return a DDS_RETCODE (OK, ERROR, BAD_PARAMETER, OUT_OF_RESOURCES)
*/
dds_return_t
ddsrt_getsockname(
ddsrt_socket_t sock,
struct sockaddr *addr,
socklen_t *addrlen);
/**
* @brief Send data from a buffer
*
* - Sends 'len' bytes of 'buf'
* - The 'flags' can be 0, or the bitwise OR of one or more of:
* {MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_MORE, MSG_NOSIGNAL, MSG_OOB}
*
* @param[in] sock the socket
* @param[in] buf buffer containing the data to send
* @param[in] len size (in bytes) of 'buf'
* @param[in] flags flags for special options
* @param[out] sent the number of bytes sent
* @return a DDS_RETCODE (OK, ERROR, and more)
*
* See @ref ddsrt_recv
*/
dds_return_t
ddsrt_send(
ddsrt_socket_t sock,
const void *buf,
size_t len,
int flags,
ssize_t *sent);
/**
* @brief Send a message
*
* - The 'flags' can be 0, or the bitwise OR of one or more of:
* {MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_MORE, MSG_NOSIGNAL, MSG_OOB}
*
* @param[in] sock the socket
* @param[in] msg the message to send
* @param[in] flags flags for special options
* @param[out] sent the number of bytes sent
* @return a DDS_RETCODE (OK, ERROR, and more)
*
* See @ref ddsrt_recvmsg
*/
dds_return_t
ddsrt_sendmsg(
ddsrt_socket_t sock,
const ddsrt_msghdr_t *msg,
int flags,
ssize_t *sent);
/**
* @brief Receive data into a buffer
*
* - If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on
* the type of socket the message is received from.
* - If no data is available at the socket, the call waits for a message to arrive, unless the socket is nonblocking (MSG_DONTWAIT).
* - The 'flags' can be 0, or the bitwise OR of one or more of:
* {MSG_CMSG_CLOEXEC, MSG_DONTWAIT, MSG_ERRQUEUE, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL}
*
* @param[in] sock the socket
* @param[out] buf buffer in which to receive the data
* @param[in] len the size available in the buffer
* @param[in] flags flags for special options
* @param[out] rcvd number of bytes received
* @return a DDS_RETCODE (OK, ERROR, TRY_AGAIN, BAD_PARAMETER, NO_CONNECTION, INTERRUPTED, OUT_OF_RESOURCES, ILLEGAL_OPERATION)
*
* See @ref ddsrt_send
*/
dds_return_t
ddsrt_recv(
ddsrt_socket_t sock,
void *buf,
size_t len,
int flags,
ssize_t *rcvd);
/**
* @brief Receive a message
*
* - If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on
* the type of socket the message is received from.
* - If no data is available at the socket, the call waits for a message to arrive, unless the socket is nonblocking (MSG_DONTWAIT).
* - The 'flags' can be 0, or the bitwise OR of one or more of:
* {MSG_CMSG_CLOEXEC, MSG_DONTWAIT, MSG_ERRQUEUE, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL}
*
* @param[in] sockext the socket
* @param[out] msg the message received
* @param[in] flags flags for special options
* @param[out] rcvd number of bytes received (>= 0 if return == OK, undefined if return != OK)
* @return a DDS_RETCODE (OK, ERROR, TRY_AGAIN, BAD_PARAMETER, NO_CONNECTION, INTERRUPTED, OUT_OF_RESOURCES, ILLEGAL_OPERATION)
*
* See @ref ddsrt_sendmsg
*/
dds_return_t
ddsrt_recvmsg(
const ddsrt_socket_ext_t *sockext,
ddsrt_msghdr_t *msg,
int flags,
ssize_t *rcvd);
/**
* @brief Get options from the socket.
*
* Argument 'optlen' is a value-result argument, initially containing the size
* of the buffer pointed to by 'optval', and modified on return to indicate the
* actual size of the value returned.
*
* @param[in] sock the socket
* @param[in] level the level at which the option resides. For socket API use SOL_SOCKET
* @param[in] optname the name of the option (SO_REUSEADDR, SO_DONTROUTE, SO_BROADCAST, SO_SNDBUF, SO_RCVBUF, ...)
* @param[out] optval buffer into which to receive the option value
* @param[in,out] optlen size of buffer 'optval'
* @return a DDS_RETCODE (OK, ERROR, BAD_PARAMETER, UNSUPPORTED)
*
* See @ref ddsrt_setsockopt
*/
dds_return_t
ddsrt_getsockopt(
ddsrt_socket_t sock,
int32_t level,
int32_t optname,
void *optval,
socklen_t *optlen);
/**
* @brief Set options on the socket
*
* Most socket-level options utilize an int argument for 'optval'.
* The argument should be nonzero to enable a boolean option,
* or zero if the option is to be disabled.
*
* @param[in,out] sock the socket
* @param[in] level the level at which the option resides. For socket API use SOL_SOCKET
* @param[in] optname the name of the option (SO_REUSEADDR, SO_DONTROUTE, SO_BROADCAST, SO_SNDBUF, SO_RCVBUF, ...)
* @param[in] optval buffer containing the option value
* @param[in] optlen size of buffer 'optval'
* @return a DDS_RETCODE (OK, ERROR, BAD_PARAMETER, UNSUPPORTED)
*
* See @ref ddsrt_getsockopt
*/
dds_return_t
ddsrt_setsockopt(
ddsrt_socket_t sock,
int32_t level,
int32_t optname,
const void *optval,
socklen_t optlen);
/**
* @brief Set the I/O on the socket to blocking or non-nonblocking.
*
* @param[in] sock Socket to set I/O mode for.
* @param[in] nonblock true for nonblocking, or false for blocking I/O.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* I/O mode successfully set to (non)blocking.
* @retval DDS_RETCODE_TRY_AGAIN
* A blocking call is in progress.
* @retval DDS_RETCODE_BAD_PARAMETER
* @sock is not a valid socket.
* @retval DDS_RETCODE_ERROR
* An unknown error error occurred.
*/
dds_return_t
ddsrt_setsocknonblocking(
ddsrt_socket_t sock,
bool nonblock);
/**
* @brief Set whether a port may be shared with other sockets
*
* Maps to SO_REUSEPORT (if defined) followed by SO_REUSEADDR
*
* @param[in] sock Socket to set reusability for.
* @param[in] reuse Whether to allow sharing the address/port.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* SO_REUSEPORT successfully set, or not defined,
* or returned ENOPROTOOPT
* SO_REUSEADDR successfully set
* @retval DDS_RETCODE_UNSUPPORTED
* Network stack doesn't support SO_REUSEADDR and
* returned ENOPROTOOPT
* @retval DDS_RETCODE_BAD_PARAMETER
* Bad things happened (e.g., not a socket)
* @retval DDS_RETCODE_ERROR
* An unknown error occurred.
*/
dds_return_t
ddsrt_setsockreuse(
ddsrt_socket_t sock,
bool reuse);
/**
* @brief Monitor multiple sockets, waiting until one or more become ready.
*
* @param[in] nfds Highest-numbered file descriptor in any of the sets.
* @param[in] readfds Set of sockets to monitor for read ready status.
* @param[in] writefds Set of sockets to monitor for write ready status.
* @param[in] errorfds Set of sockets to monitor for exceptional conditions.
* @param[in] reltime Interval to block for sockets to become ready.
*
* @returns The number of sockets ready in the sets or a return code.
*/
dds_return_t
ddsrt_select(
int32_t nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *errorfds,
dds_duration_t reltime);
enum ddsrt_shutdown_how {
DDSRT_SHUTDOWN_READ,
DDSRT_SHUTDOWN_WRITE,
DDSRT_SHUTDOWN_READ_WRITE
};
/**
* @brief Shutdown all or part of a full-duplex connection
*
* @param[in] sock Socket to operate on
* @param[in] how What to shut down
* */
dds_return_t
ddsrt_shutdown(
ddsrt_socket_t sock,
enum ddsrt_shutdown_how how);
#if _WIN32
/* SOCKETs on Windows are NOT integers. The nfds parameter is only there for
compatibility, the implementation ignores it. Implicit casts will generate
warnings though, therefore ddsrt_select is redefined to discard the
parameter on Windows. */
#define ddsrt_select(nfds, readfds, writefds, errorfds, timeout) \
ddsrt_select(-1, readfds, writefds, errorfds, timeout)
#endif /* _WIN32 */
/**
* @brief Get the size of a socket address.
*
* @param[in] sa Socket address to return the size for.
*
* @returns Size of the socket address based on the address family, or 0 if
* the address family is unknown.
*/
socklen_t
ddsrt_sockaddr_get_size(
const struct sockaddr *const sa) ddsrt_nonnull_all;
/**
* @brief Get the port number from a socket address.
*
* @param[in] sa Socket address to retrieve the port from.
*
* @return Port number in host order.
*/
uint16_t
ddsrt_sockaddr_get_port(
const struct sockaddr *const sa) ddsrt_nonnull_all;
/**
* @brief Check if the given address is unspecified.
*
* @param[in] sa Socket address to check.
*
* @return true if the address is unspecified, false otherwise.
*/
bool
ddsrt_sockaddr_isunspecified(
const struct sockaddr *sa) ddsrt_nonnull_all;
/**
* @brief Check if the given address is a loopback address.
*
* @param[in] sa Socket address to check.
*
* @return true if the address is a loopback address, false otherwise.
*/
bool
ddsrt_sockaddr_isloopback(
const struct sockaddr *sa) ddsrt_nonnull_all;
/**
* @brief Check if given socket IP addresses reside in the same subnet.
*
* Checks if two socket IP addresses reside in the same subnet, considering the
* given subnetmask. IPv6 mapped IPv4 addresses are not taken in account.
*
* @param[in] sa1 First address
* @param[in] sa2 Second address.
* @param[in] mask Subnetmask.
*
* @returns true if both addresses reside in the same subnet, false otherwise.
*/
bool
ddsrt_sockaddr_insamesubnet(
const struct sockaddr *sa1,
const struct sockaddr *sa2,
const struct sockaddr *mask)
ddsrt_nonnull_all;
/**
* @brief Convert a string to a socket address
*
* The socket address 'sa' can be any of type:
* (struct sockaddr_in*, struct sockaddr_in6*, struct sockaddr_storage*)
* Note that the data is copied into the existing socket address (does not allocate memory).
*
* @param[in] af the address family (AF_INET, AF_INET6)
* @param[in] str the string input e.g. "192.0.2.0"
* @param[out] sa the socket address to overwrite
* @return a DDS_RETCODE (OK, BAD_PARAMETER)
*
* See @ref ddsrt_sockaddrtostr
*/
DDS_EXPORT dds_return_t
ddsrt_sockaddrfromstr(
int af, const char *str, void *sa);
/**
* @brief Convert a socket address to a string
*
* The socket address 'sa' can be any of type:
* (const struct sockaddr_in*, const struct sockaddr_in6*, const struct sockaddr_storage*)
*
* @param[in] sa the socket address to convert into a string
* @param[out] buf a string buffer for the output
* @param[in] size the size (in bytes) of 'buf'
* @return a DDS_RETCODE (OK, BAD_PARAMETER, NOT_ENOUGH_SPACE)
*
* See @ref ddsrt_sockaddrfromstr
*/
dds_return_t
ddsrt_sockaddrtostr(
const void *sa, char *buf, size_t size);
#if DDSRT_HAVE_DNS
DDSRT_WARNING_MSVC_OFF(4200)
/**
* @brief A vector of socket addresses
*/
typedef struct {
size_t naddrs; ///< Number of addresses
struct sockaddr_storage addrs[]; ///< Array containing socket addresses
} ddsrt_hostent_t;
DDSRT_WARNING_MSVC_ON(4200)
/**
* @brief Lookup addresses for given host name.
*
* @param[in] name Host name to resolve.
* @param[in] af Address family, either AF_INET, AF_INET6 or AF_UNSPEC.
* @param[out] hentp Structure of type ddsrt_hostent_t.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Host name successfully resolved to address(es).
* @retval DDS_RETCODE_HOST_NOT_FOUND
* Host not found.
* @retval DDS_RETCODE_NO_DATA
* Valid name, no data record of requested type.
* @retval DDS_RETCODE_ERROR
* Nonrecoverable error.
* @retval DDS_RETCODE_TRY_AGAIN
* Nonauthoratitative host not found.
*/
dds_return_t
ddsrt_gethostbyname(
const char *name,
int af,
ddsrt_hostent_t **hentp);
#endif
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_SOCKETS_H */
+103
View File
@@ -0,0 +1,103 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_SOCKETS_POSIX_H
#define DDSRT_SOCKETS_POSIX_H
#if DDSRT_WITH_LWIP
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#else
#if __ZEPHYR__
#include <netdb.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/select.h>
#endif
#include "dds/ddsrt/iovec.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef int ddsrt_socket_t;
#define DDSRT_INVALID_SOCKET (-1)
#define PRIdSOCK "d"
typedef struct ddsrt_socket_ext {
ddsrt_socket_t sock;
} ddsrt_socket_ext_t;
#if LWIP_SOCKET
# define IFF_UP 0x1
# define IFF_BROADCAST 0x2
# define IFF_LOOPBACK 0x8
# define IFF_POINTOPOINT 0x10
# define IFF_MULTICAST 0x1000
#elif __SunOS_5_6
// nothing needed so far
#elif __ZEPHYR__
/* In Zephyr, a network interface can join a multi-cast group only once.
So setsockopt is called only for the first socket to join a group, other sockets
for the same group will be skipped */
#define DDSRT_MCGROUP_JOIN_ONCE 1
# define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
# define IN_MULTICAST(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
/* Ignored socket options */
# define IP_MULTICAST_IF 32
# define IP_MULTICAST_TTL 33
# define IP_MULTICAST_LOOP 34
/* for ddsrt_getifaddrs */
# define IFF_UP 0x1
# define IFF_BROADCAST 0x2
# define IFF_LOOPBACK 0x8
# define IFF_POINTOPOINT 0x10
# define IFF_MULTICAST 0x1000
#if DDSRT_HAVE_IPV6
# define IN6_IS_ADDR_UNSPECIFIED(a) (!((a)->s6_addr32[0] | (a)->s6_addr32[1] | (a)->s6_addr32[2] | (a)->s6_addr32[3]))
# define IN6_IS_ADDR_LOOPBACK(a) (((a)->s6_addr[15]) == 1 && !memcmp((a)->s6_addr, &in6addr_loopback, sizeof(struct in6_addr)))
# define IN6_IS_ADDR_LINKLOCAL(a) (((a)->s6_addr[0] & 0xff) == 0xfe && ((a)->s6_addr[1] & 0xc0) == 0x80)
# define IN6_IS_ADDR_MULTICAST(a) (((a)->s6_addr[0] & 0xff) == 0xff)
/* socket options */
# define IPV6_JOIN_GROUP 91
# define IPV6_LEAVE_GROUP 92
# define IPV6_MULTICAST_IF 95
# define IPV6_MULTICAST_LOOP 96
#endif
#else // Unix/Windows/...
// nothing needed so far
#endif /* LWIP_SOCKET */
typedef struct msghdr ddsrt_msghdr_t;
#if (defined(__sun) && !defined(_XPG4_2)) || \
(defined(LWIP_SOCKET))
# define DDSRT_MSGHDR_FLAGS 0
#else
# define DDSRT_MSGHDR_FLAGS 1
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_SOCKETS_POSIX_H */
+48
View File
@@ -0,0 +1,48 @@
#ifndef DDSRT_WINDOWS_SOCKET_H
#define DDSRT_WINDOWS_SOCKET_H
#include <winsock2.h>
#include <mswsock.h> // Required for MSG_TRUNC when compiling with mingw-w64.
#include <ws2tcpip.h>
#include "dds/ddsrt/iovec.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef SOCKET ddsrt_socket_t;
#define DDSRT_INVALID_SOCKET (INVALID_SOCKET)
#define PRIdSOCK PRIuPTR
typedef struct ddsrt_socket_ext_t {
ddsrt_socket_t sock;
LPFN_WSARECVMSG wsarecvmsg;
} ddsrt_socket_ext_t;
#define IFF_POINTOPOINT IFF_POINTTOPOINT
// Required when compiling with mingw-w64.
#ifndef MCAST_JOIN_SOURCE_GROUP
#define MCAST_JOIN_SOURCE_GROUP 45
#endif
#ifndef MCAST_LEAVE_SOURCE_GROUP
#define MCAST_LEAVE_SOURCE_GROUP 46
#endif
typedef struct ddsrt_msghdr {
void *msg_name;
socklen_t msg_namelen;
ddsrt_iovec_t *msg_iov;
ddsrt_msg_iovlen_t msg_iovlen;
void *msg_control;
size_t msg_controllen;
int msg_flags;
} ddsrt_msghdr_t;
#define DDSRT_MSGHDR_FLAGS 1
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_WINDOWS_SOCKET_H */
+60
View File
@@ -0,0 +1,60 @@
// Copyright(c) 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_STATIC_ASSERT_H
#define DDSRT_STATIC_ASSERT_H
/* There are many tricks to use a constant expression to yield an
illegal type or expression at compile time, such as zero-sized
arrays and duplicate case or enum labels. So this is but one of the
many tricks. */
#define DDSRT_STATIC_ASSERT2(line, pred) \
struct static_assert_##line { \
char cond[(pred) ? 1 : -1]; \
}
#define DDSRT_STATIC_ASSERT1(line, pred) \
DDSRT_STATIC_ASSERT2 (line, pred)
#define DDSRT_STATIC_ASSERT(pred) \
DDSRT_STATIC_ASSERT1 (__LINE__, pred)
#ifndef _MSC_VER
#define DDSRT_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case (pred): ; } } while (0)
#else
/* Temporarily disabling warning C6326: Potential comparison of a
constant with another constant. */
#define DDSRT_STATIC_ASSERT_CODE(pred) do { \
__pragma (warning (push)) \
__pragma (warning (disable : 6326)) \
switch(0) { case 0: case (pred): ; } \
__pragma (warning (pop)) \
} while (0)
#endif
// _Generic is C11, gcc and clang have supported it for a long time already
// and will happily do it also when compiling C99 code. Microsoft did add
// it eventually, but only when compiling with /std:c11 according to the
// docs.
//
// Skipping the test for non-whitelisted cases means this should work on
// all Linux and macOS builds without breaking other platforms. That is
// a reasonable compromise.
#if (__STDC__ == 1 && __STDC_VERSION__ >= 201112L) || \
(__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) >= 40900 || \
(__clang_major__*10000 + __clang_minor__*100 + __clang_patchlevel__) >= 30000
#define DDSRT_STATIC_ASSERT_IS_UNSIGNED(v_) \
DDSRT_STATIC_ASSERT(_Generic(v_, \
uint8_t: 1, uint16_t: 1, uint32_t: 1, uint64_t: 1, \
default: 0))
#else
#define DDSRT_STATIC_ASSERT_IS_UNSIGNED(v_) DDSRT_STATIC_ASSERT(1)
#endif
#endif
+209
View File
@@ -0,0 +1,209 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_STRING_H
#define DDSRT_STRING_H
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Compare two strings ignoring case.
*
* @param[in] s1 String to compare.
* @param[in] s2 String to compare.
*
* @returns Zero if @s1 and @s2 match, a negative integer if @s1 is less than
* @s2 or a positive integer if @s1 is greater than @s2.
*/
DDS_EXPORT int
ddsrt_strcasecmp(
const char *s1,
const char *s2)
ddsrt_nonnull_all;
/**
* @brief Compare two strings ignoring case, but no more than @n bytes.
*
* @param[in] s1 String to compare.
* @param[in] s2 String to compare.
* @param[in] n Maximum number of bytes to compare.
*
* @returns Zero if @s1 and @s2 match, a negative integer if @s1 is less than
* @s2 or a positive integer if @s1 is greater than @s2.
*/
DDS_EXPORT int
ddsrt_strncasecmp(
const char *s1,
const char *s2,
size_t n)
ddsrt_nonnull((1,2));
/**
* @brief Extract token from string.
*
* Finds the first token in @stringp delimited by one of the characters in
* @delim. The delimiter is overwritten with a null byte, terminating the
* token and @stringp is updated to point past the delimiter.
*
* @param[in,out] stringp String to extract token from.
* @param[in] delim Characters that delimit a token.
*
* @returns The original value of @stringp.
*/
DDS_EXPORT char *
ddsrt_strsep(
char **stringp,
const char *delim);
/**
* @brief Duplicate block of memory.
*
* Copy a block of memory into a newly allocated block of memory. The memory
* is obtained with @ddsrt_malloc and must be freed with @ddsrt_free when it
* is no longer used.
*
* @param[in] src Pointer to block of memory to duplicate.
* @param[in] n Number of bytes to copy into newly allocated buffer.
*
* @returns A new block of memory that is a duplicate of the block pointed to
* by @ptr or NULL if not enough memory was available.
*/
DDS_EXPORT void *
ddsrt_memdup(
const void *src,
size_t n)
ddsrt_nonnull((1))
ddsrt_attribute_malloc;
/**
* @brief Duplicate string.
*
* Copy string into a newly allocated block of memory. The memory is obtained
* with @ddsrt_malloc and must be freed with @ddsrt_free when it is no longer
* used.
*
* @param[in] str String to duplicate.
*
* @returns A new string that is a duplicate of @str or NULL if not enough
* memory was available.
*/
DDS_EXPORT char *
ddsrt_strdup(
const char *str)
ddsrt_nonnull_all
ddsrt_attribute_malloc;
/**
* @brief Duplicate at most @len bytes of string @str.
*
* Copy at most @len number of bytes into a newly allocated block of memory.
* The memory is obtained with @ddsrt_malloc and must be freed with
* @ddsrt_free when it is no longer used.
*
* @param[in] str String to duplicate.
* @param[in] len Maximum number of bytes to copy.
*
* @returns A new string that is a duplicate of @str up to @len bytes or NULL
* if not enough memory was available.
*/
DDS_EXPORT char *
ddsrt_strndup(
const char *str,
size_t len)
ddsrt_nonnull((1))
ddsrt_attribute_malloc;
/**
* @brief Copy string.
*
* Copy string to buffer with specified size. The string is truncated if there
* is not enough space. The resulting string is guaranteed to be null
* terminated if there is space.
*
* @param[out] dest Destination buffer.
* @param[in] src Null terminated string to copy to dest.
* @param[in] size Number of bytes available in dest.
*
* @returns Number of characters copied to dest (excluding the null byte), or
* the number of characters that would have been copied if dest is not
* sufficiently large enough.
*/
DDS_EXPORT size_t
ddsrt_strlcpy(
char *dest,
const char *src,
size_t size)
ddsrt_nonnull((1,2));
/**
* @brief Concatenate strings.
*
* Append the string specified by src to the string specified by dest. The
* terminating null byte at the end of dest is overwritten. The resulting
* string is truncated if there is not enough space. The resulting string
* guaranteed to be null terminated if there is space.
*
* @param[in,out] dest Destination buffer.
* @param[in] src Null terminated string to append to dest.
* @param[in] size Number of bytes available in dest.
*
* @returns Number of characters copied to dest (excluding the null byte), or
* the number of characters that would have been copied if dest is not
* sufficiently large enough.
*/
DDS_EXPORT size_t
ddsrt_strlcat(
char *dest,
const char *src,
size_t size)
ddsrt_nonnull((1,2));
/**
* @brief Replace substring of null terminated string
*
* @param[in] str pointer to string
* @param[in] srch non-empty string to replace
* @param[in] subst string to substitute character "srch" with
* @param[in] max maximum number of times to replace search, or 0 for unlimited
*
* @returns Pointer to newly allocated string with max occurrences of srch replaced, or
* NULL on allocation failure or if srch is an empty string.
*/
DDS_EXPORT char *
ddsrt_str_replace(
const char *str,
const char *srch,
const char *subst,
size_t max)
ddsrt_nonnull_all;
/**
* @brief Trim leading and trailing ordinary space character (' ' ascii 32) from string.
*
* @param[in] str pointer to string.
*
* @returns Pointer to original trimed string
* without leading and trailing ordinary space character
*/
DDS_EXPORT char *
ddsrt_str_trim_ord_space(
char *str);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_STRING_H */
+78
View File
@@ -0,0 +1,78 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
/**
* @file strtod.h
* @brief Floating-point number to/from string conversion functions.
*
* Locale independent versions of the floating-point number conversion
* functions found in the standard library.
*/
#ifndef DDSRT_STRTOD_H
#define DDSRT_STRTOD_H
#include "dds/export.h"
#include "dds/ddsrt/retcode.h"
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Convert a string to a double precision floating point number.
*
* This operation handles locale specific manipulation of the floating point
* string and then sets the output double based on the parsing via `strtod`
* from the standard library. The function returns a failure iff:
* - the string to be parsed represents a value that is too large to store in a double.
* - the string contains junk.
* - the string parses to either `-nan` or `nan`.
* - the string parses to either `-inf` or `inf`.
* It is otherwise successful.
*
* @param[in] nptr A string to convert into a double.
* @param[out] endptr If not NULL, a char* where the address of first invalid
* character is stored.
* @param[out] dblptr A double where the result is stored.
*
* @returns A dds_return_t indicating success or failure.
*/
dds_return_t
ddsrt_strtod(const char *nptr, char **endptr, double *dblptr);
/**
* @brief Convert a double-precision floating-point number to a string.
*
* @param[in] src Double-precision floating-point number to convert.
* @param[in] str Buffer where string representation is written.
* @param[in] size Number of bytes available in @str.
*
* @returns The number of bytes written (excluding the null terminating byte).
*/
int
ddsrt_dtostr(double src, char *str, size_t size);
/**
* @brief convert a floating-point number to a string.
*
* @param[in] src Floating-point number to conver.
* @param[in] str Buffer where string representation is written.
* @param[in] size Number of bytes available in @str.
*
* @returns The number of bytes written (exluding the null terminating byte).
*/
int
ddsrt_ftostr(float src, char *str, size_t size);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_STRTOD_H */
+181
View File
@@ -0,0 +1,181 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_STRTOL_H
#define DDSRT_STRTOL_H
#include <stdint.h>
#include "dds/export.h"
#include "dds/ddsrt/retcode.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Convert a character to an integer value
*
* Translates the numeric value of the provided character. For characters in range
* '0' to '9' the returned integer value is 0-9. For the range 'a' to 'z' and 'A'
* to 'Z', the numeric return value is 10-36.
*
* @param[in] chr The character
*
* @returns The integer value for the character, or -1 in case @chr cannot be translated to a numeric value
*/
DDS_EXPORT int32_t
ddsrt_todigit(const int chr);
/**
* @brief Convert a string to a long long integer.
*
* Translate @str to a long long integer considering base, and sign. If @base
* is 0, base is determined from @str. A prefix of "0x" or "0X" will cause the
* number be read in base 16 (hexadecimal), otherwise base 10 (decimal) is
* used, unless the first character is '0', in which case the number will be
* read in base 8 (octal).
*
* @param[in] str String to convert into a number.
* @param[out] endptr If not NULL, a char* where the address of first invalid
* character is stored.
* @param[in] base Base to use. Must be a base between 2 and 36, or 0 to
* determine from @str.
* @param[out] llng A long long integer where the number is stored.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* String successfully converted to an integer.
* @retval DDS_RETCODE_BAD_PARAMETER
* Base is invalid.
* @retval DDS_RETCODE_OUT_OF_RANGE
* String converted to an integer, but was out of range.
*/
DDS_EXPORT dds_return_t
ddsrt_strtoll(
const char *str,
char **endptr,
int32_t base,
long long *llng);
/**
* @brief Convert a string to an unsigned long long integer.
*
* Translate @str to an unsigned long long integer considering base, and sign.
* If @base is 0, base is determined from @str. A prefix of "0x" or "0X" will
* cause the number be read in base 16 (hexadecimal), otherwise base 10
* (decimal) is used, unless the first character is '0', in which case the
* number will be read in base 8 (octal).
*
* @param[in] str String to convert into a number.
* @param[out] endptr If not NULL, a char* where the address of first invalid
* character is stored.
* @param[in] base Base to use. Must be a base between 2 and 36, or 0 to
* determine from @str.
* @param[out] ullng A long long integer where the number is stored.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* String successfully converted to an integer.
* @retval DDS_RETCODE_BAD_PARAMETER
* Base is invalid.
* @retval DDS_RETCODE_OUT_OF_RANGE
* String converted to an integer, but was out of range.
*/
DDS_EXPORT dds_return_t
ddsrt_strtoull(
const char *str,
char **endptr,
int32_t base,
unsigned long long *ullng);
/**
* @brief Convert a string to a long long integer.
*
* @param[in] str String to convert into a long long integer.
* @param[in] llng A long long integer where the number is stored.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* String successfully converted to an integer.
* @retval DDS_RETCODE_BAD_PARAMETER
* Base is invalid.
* @retval DDS_RETCODE_OUT_OF_RANGE
* String converted to an integer, but was out of range.
*/
DDS_EXPORT dds_return_t
ddsrt_atoll(
const char *str,
long long *llng);
/**
* @brief Convert a string to an unsigned long long integer.
*
* @param[in] str String to conver into an unsigned long long integer.
* @param[out] ullng An unsigned long long integer where the number is stored.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* String successfully converted to an integer.
* @retval DDS_RETCODE_BAD_PARAMETER
* Base is invalid.
* @retval DDS_RETCODE_OUT_OF_RANGE
* String converted to an integer, but was out of range.
*/
DDS_EXPORT dds_return_t
ddsrt_atoull(
const char *str,
unsigned long long *ullng);
/**
* @brief Convert a long long integer into a string.
*
* @param[in] num Long long integer to convert into a string.
* @param[in] str Buffer where string representation is written.
* @param[in] len Number of bytes available in buffer.
* @param[out] endptr A char* where the address of the null terminating byte
* is stored.
*
* @returns The value of @str on success, otherwise NULL.
*/
DDS_EXPORT char *
ddsrt_lltostr(
long long num,
char *str,
size_t len,
char **endptr);
/**
* @brief Convert an unsigned long long integer into a string.
*
* @param[in] num Unsigned long long integer to covert into a string.
* @param[in] str Buffer where string representation is stored.
* @param[in] len Number of bytes available in buffer.
* @param[out] endptr A char* where the adress of the null terminating byte
* is stored.
*
* @returns The value of @str on success, otherwise NULL.
*/
DDS_EXPORT char *
ddsrt_ulltostr(
unsigned long long num,
char *str,
size_t len,
char **endptr);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_STRTOL_H */
+301
View File
@@ -0,0 +1,301 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_SYNC_H
#define DDSRT_SYNC_H
#include <stdbool.h>
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/attributes.h"
#if DDSRT_WITH_FREERTOS
#include "dds/ddsrt/sync/freertos.h"
#elif _WIN32
#include "dds/ddsrt/sync/windows.h"
#elif __SunOS_5_6
#include "dds/ddsrt/sync/solaris2.6.h"
#else
#include "dds/ddsrt/sync/posix.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
/**
* @brief Initialize a mutex.
*
* @param[in] mutex Mutex to itialize.
*/
DDS_EXPORT void
ddsrt_mutex_init(
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all;
/**
* @brief Destroy a mutex.
*
* @param[in] mutex Mutex to destroy.
*/
DDS_EXPORT void
ddsrt_mutex_destroy(
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all;
/**
* @brief Acquire a mutex.
*
* @param[in] mutex Mutex to acquire.
*/
DDS_EXPORT void
ddsrt_mutex_lock(
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all;
/**
* @brief Acquire a mutex if it is not already acquired.
*
* @param[in] mutex Mutex to acquire.
*
* @returns true if the mutex was acquired, false otherwise.
*/
DDS_EXPORT bool
ddsrt_mutex_trylock(
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all
ddsrt_attribute_warn_unused_result;
/**
* @brief Release an acquired mutex.
*
* @param[in] mutex Mutex to release.
*/
DDS_EXPORT void
ddsrt_mutex_unlock (
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all;
/**
* @brief Initialize a condition variable.
*
* @param[in] cond Condition variable to initialize.
*/
DDS_EXPORT void
ddsrt_cond_init(
ddsrt_cond_t *cond)
ddsrt_nonnull_all;
/**
* @brief Destroy a condition variable.
*
* @param[in] cond Condition variable to destroy.
*/
DDS_EXPORT void
ddsrt_cond_destroy(
ddsrt_cond_t *cond)
ddsrt_nonnull_all;
/**
* @brief Wait for a condition variable to be signalled.
*
* @param[in] cond Condition variable to block on.
* @param[in] mutex Mutex to associate with condition variable.
*
* @pre The calling thread must hold the mutex specified by @mutex.
*
* @post The calling thread will hold the mutex specified by @mutex.
*/
DDS_EXPORT void
ddsrt_cond_wait(
ddsrt_cond_t *cond,
ddsrt_mutex_t *mutex)
ddsrt_nonnull_all;
/**
* @brief Wait until @abstime for a condition variable to be signalled.
*
* @param[in] cond Condition variable to block on.
* @param[in] mutex Mutex to associate with condition variable.
* @param[in] abstime Time in nanoseconds since UNIX Epoch.
*
* @pre The calling thread must hold the mutex specified by @mutex.
*
* @post The calling thread will hold the mutex specified by @mutex.
*
* @returns false if the condition variable was not signalled before the
* absolute time specified by @abstime passed, otherwise true.
*/
DDS_EXPORT bool
ddsrt_cond_waituntil(
ddsrt_cond_t *cond,
ddsrt_mutex_t *mutex,
dds_time_t abstime)
ddsrt_nonnull((1,2));
/**
* @brief Wait for @reltime for a condition variable to be signalled.
*
* @param[in] cond Condition variable to block on.
* @param[in] mutex Mutex to associate with condition variable.
* @param[in] reltime Time in nanoseconds since UNIX Epoch.
*
* @pre The calling thread must hold the mutex specified by @mutex.
*
* @post The calling thread will hold the mutex specified by @mutex.
*
* @returns false if the condition variable was not signalled before the
* relative time specified by @reltime passed, otherwise true.
*/
DDS_EXPORT bool
ddsrt_cond_waitfor(
ddsrt_cond_t *cond,
ddsrt_mutex_t *mutex,
dds_duration_t reltime)
ddsrt_nonnull((1,2));
/**
* @brief Signal a condition variable and unblock at least one thread.
*
* @param[in] cond Condition variable to signal.
*
* @pre The mutex associated with the condition in general should be acquired
* by the calling thread before setting the condition state and
* signalling.
*/
DDS_EXPORT void
ddsrt_cond_signal(
ddsrt_cond_t *cond)
ddsrt_nonnull_all;
/**
* @brief Signal a condition variable and unblock all threads.
*
* @param[in] cond Condition variable to signal.
*
* @pre The mutex associated with the condition in general should be acquired
* by the calling thread before setting the condition state and
* signalling
*/
DDS_EXPORT void
ddsrt_cond_broadcast(
ddsrt_cond_t *cond)
ddsrt_nonnull_all;
/**
* @brief Initialize a read-write lock.
*
* @param[in] rwlock Read-write lock to initialize.
*/
DDS_EXPORT void
ddsrt_rwlock_init(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all;
/**
* @brief Destroy a read-write lock.
*
* @param[in] rwlock Read-write lock to destroy.
*/
DDS_EXPORT void
ddsrt_rwlock_destroy(
ddsrt_rwlock_t *rwlock);
/**
* @brief Acquire a read-write lock for reading.
*
* @param[in] rwlock Read-write lock to acquire.
*
* @post Data related to the critical section must not be changed by the
* calling thread.
*/
DDS_EXPORT void
ddsrt_rwlock_read(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all;
/**
* @brief Acquire a read-write lock for writing.
*
* @param[in] rwlock Read-write lock to acquire.
*/
DDS_EXPORT void
ddsrt_rwlock_write(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all;
/**
* @brief Try to acquire a read-write lock for reading.
*
* Try to acquire a read-write lock while for reading, immediately return if
* the lock is already exclusively acquired by another thread.
*
* @param[in] rwlock Read-write lock to aqcuire.
*
* @post Data related to the critical section must not changed by the
* calling thread.
*
* @returns true if the lock was acquired, otherwise false.
*/
DDS_EXPORT bool
ddsrt_rwlock_tryread(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all
ddsrt_attribute_warn_unused_result;
/**
* @brief Try to acquire a read-write lock for writing.
*
* Try to acquire a read-write lock for writing, immediately return if the
* lock is already acquired, either for reading or writing, by another thread.
*
* @param[in] rwlock Read-write lock to acquire.
*
* @returns true if the lock was acquired, otherwise false.
*/
DDS_EXPORT bool
ddsrt_rwlock_trywrite(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all
ddsrt_attribute_warn_unused_result;
/**
* @brief Release a previously acquired read-write lock.
*
* @param[in] rwlock Read-write lock to release.
*/
DDS_EXPORT void
ddsrt_rwlock_unlock(
ddsrt_rwlock_t *rwlock)
ddsrt_nonnull_all;
/* Initialization callback used by ddsrt_once */
typedef void (*ddsrt_once_fn)(void);
/**
* @brief Invoke init_fn exactly once for a given control.
*
* The first thread to call this function with a given control will call the
* function specified by @init_fn with no arguments. All following calls with
* the same control will not call the specified function.
*
* @pre The control parameter is properly initialized with DDSRT_ONCE_INIT.
*/
DDS_EXPORT void
ddsrt_once(
ddsrt_once_t *control,
ddsrt_once_fn init_fn);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_SYNC_H */
+92
View File
@@ -0,0 +1,92 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_SYNC_FREERTOS_H
#define DDSRT_SYNC_FREERTOS_H
#include <FreeRTOS.h>
#include <semphr.h>
#include <task.h>
#include <stddef.h>
#include "dds/ddsrt/atomics.h"
#if (INCLUDE_vTaskSuspend != 1)
/* INCLUDE_vTaskSuspend must be set to 1 to make xSemaphoreTake wait
indefinitely when passed portMAX_DELAY. See reference manual. */
#error "INCLUDE_vTaskSuspend != 1 in FreeRTOSConfig.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
SemaphoreHandle_t sem;
} ddsrt_mutex_t;
typedef struct {
size_t len;
size_t cnt;
size_t off;
size_t end;
TaskHandle_t *tasks;
} ddsrt_tasklist_t;
typedef struct {
SemaphoreHandle_t sem;
ddsrt_tasklist_t tasks;
} ddsrt_cond_t;
/* This readers-writer lock implementation does not prefer writers over readers
or vice versa. Multiple readers are allowed to hold the lock simultaneously
and can acquire it directly if no writers are queued. However, if a writer
is queued, new readers and writers are queued behind it in order. Any reader
that acquires the lock after a writer frees it, notifies the next task. If
that task tries to acquire a write lock it waits until the reader frees the
lock. However, if the task tries to acquire a read lock it will succeed, and
notify the next task, etc. */
typedef struct {
SemaphoreHandle_t sem;
ddsrt_tasklist_t tasks;
int32_t state;
uint32_t cnt;
uint32_t rdcnt;
uint32_t wrcnt;
} ddsrt_rwlock_t;
typedef ddsrt_atomic_uint32_t ddsrt_once_t;
#define DDSRT_ONCE_INIT { .v = (1<<0) /* ONCE_NOT_STARTED */ }
/* The declarations below are here for tests and must be considered private. */
/* Number of buckets to grow buffer by. */
#define DDSRT_TASKLIST_CHUNK (5)
/* Number of buckets to allocate initially. */
#define DDSRT_TASKLIST_INITIAL (DDSRT_TASKLIST_CHUNK * 2)
int ddsrt_tasklist_init(ddsrt_tasklist_t *list);
void ddsrt_tasklist_fini(ddsrt_tasklist_t *list);
void ddsrt_tasklist_ltrim(ddsrt_tasklist_t *list);
void ddsrt_tasklist_rtrim(ddsrt_tasklist_t *list);
void ddsrt_tasklist_pack(ddsrt_tasklist_t *list);
int ddsrt_tasklist_shrink(ddsrt_tasklist_t *list);
int ddsrt_tasklist_grow(ddsrt_tasklist_t *list);
ssize_t ddsrt_tasklist_find(ddsrt_tasklist_t *list, TaskHandle_t task);
TaskHandle_t ddsrt_tasklist_peek(ddsrt_tasklist_t *list, TaskHandle_t task);
TaskHandle_t ddsrt_tasklist_pop(ddsrt_tasklist_t *list, TaskHandle_t task);
int ddsrt_tasklist_push(ddsrt_tasklist_t *list, TaskHandle_t task);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_SYNC_FREERTOS_H */
+48
View File
@@ -0,0 +1,48 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_POSIX_SYNC_H
#define DDSRT_POSIX_SYNC_H
#include <stdint.h>
#include <pthread.h>
#if HAVE_LKST
#include "lkst.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
pthread_cond_t cond;
bool is_monotonic;
} ddsrt_cond_t;
typedef struct {
pthread_mutex_t mutex;
} ddsrt_mutex_t;
typedef struct {
#if __SunOS_5_6
pthread_mutex_t rwlock;
#else
pthread_rwlock_t rwlock;
#endif
} ddsrt_rwlock_t;
typedef pthread_once_t ddsrt_once_t;
#define DDSRT_ONCE_INIT PTHREAD_ONCE_INIT
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_POSIX_SYNC_H */
+38
View File
@@ -0,0 +1,38 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_WINDOWS_SYNC_H
#define DDSRT_WINDOWS_SYNC_H
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
CONDITION_VARIABLE cond;
} ddsrt_cond_t;
typedef struct {
SRWLOCK lock;
} ddsrt_mutex_t;
typedef struct os_rwlock {
SRWLOCK lock;
int state; /* -1: exclusive, 0: free, 1: shared */
} ddsrt_rwlock_t;
typedef INIT_ONCE ddsrt_once_t;
#define DDSRT_ONCE_INIT INIT_ONCE_STATIC_INIT
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_WINDOWS_SYNC_H */
+300
View File
@@ -0,0 +1,300 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
/**
* @file threads.h
* @brief Thread management and creation.
*
* Platform independent interface for managing and creating execution threads.
*/
#ifndef DDSRT_THREADS_H
#define DDSRT_THREADS_H
#include <stdbool.h>
#include <stdint.h>
#include "dds/config.h"
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/sched.h"
#if DDSRT_WITH_FREERTOS
#include "dds/ddsrt/threads/freertos.h"
#elif _WIN32
#include "dds/ddsrt/threads/windows.h"
#else
#include "dds/ddsrt/threads/posix.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
#if defined(_MSC_VER) || __MINGW__
/* Thread-local storage using __declspec(thread) on Windows versions before
Vista and Server 2008 works in DLLs if they are bound to the executable,
it does not work if the library is loaded using LoadLibrary. */
#define ddsrt_thread_local __declspec(thread)
#elif defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 2)
/* GCC supports Thread-local storage for x86 since version 3.3. Clang
supports Thread-local storage since version 2.0. */
/* VxWorks 7 supports __thread for both GCC and DIAB, older versions may
support it as well, but that is not verified. */
#define ddsrt_thread_local __thread
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#define ddsrt_thread_local __thread
#else
#error "Thread-local storage is not supported"
#endif
/**
* @brief Definition for a thread routine invoked on thread create.
*/
typedef uint32_t (*ddsrt_thread_routine_t)(void* p);
/**
* @brief Definition of the thread attributes
*/
typedef struct {
/** Specifies the scheduling class */
ddsrt_sched_t schedClass;
/** Specifies the thread priority */
int32_t schedPriority;
/** Specifies thread affinity, N = 0, Set = NULL or N > 0 and Set[0..N-1] contains N CPU ids */
uint32_t schedAffinityN;
uint32_t *schedAffinitySet;
/** Specifies the thread stack size */
uint32_t stackSize;
} ddsrt_threadattr_t;
/**
* @brief Initialize thread attributes to platform defaults.
*/
DDS_EXPORT void
ddsrt_threadattr_init(
ddsrt_threadattr_t *attr)
ddsrt_nonnull_all;
/**
* @brief Create a new thread.
*
* Creates a new thread of control that executes concurrently with
* the calling thread. The new thread applies the function start_routine
* passing it arg as first argument.
*
* The new thread terminates by returning from the start_routine function.
* The created thread is identified by the returned threadId.
*
* @param[out] thread Location where thread id is stored.
* @param[in] name Name assigned to created thread.
* @param[in] attr Attributes to create thread with.
* @param[in] start_routine Function to execute in created thread.
* @param[in] arg Argument passed to @start_routine.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Thread successfully created.
* @retval DDS_RETCODE_ERROR
* Thread could not be created.
*/
DDS_EXPORT dds_return_t
ddsrt_thread_create(
ddsrt_thread_t *thread,
const char *name,
const ddsrt_threadattr_t *attr,
ddsrt_thread_routine_t start_routine,
void *arg)
ddsrt_nonnull((1,2,3,4));
/**
* @brief Retrieve integer representation of the given thread id.
*
* @returns The integer representation of the current thread.
*/
DDS_EXPORT ddsrt_tid_t
ddsrt_gettid(void);
/**
* @brief Retrieve integer representation of the given thread id.
*
* @returns The integer representation of the given thread.
*/
DDS_EXPORT ddsrt_tid_t
ddsrt_gettid_for_thread( ddsrt_thread_t thread);
/**
* @brief Return thread ID of the calling thread.
*
* @returns Thread ID of the calling thread.
*/
DDS_EXPORT ddsrt_thread_t
ddsrt_thread_self(void);
/**
* @brief Compare thread identifiers.
*
* @returns true if thread ids match, otherwise false.
*/
DDS_EXPORT bool
ddsrt_thread_equal(ddsrt_thread_t t1, ddsrt_thread_t t2);
/**
* @brief Wait for termination of the specified thread.
*
* If the specified thread is still running, wait for its termination
* else return immediately. In thread_result it returns the exit status
* of the thread. If NULL is passed for @thread_result, no exit status is
* returned, but ddsrt_thread_join still waits for the thread to terminate.
*
* @param[in] thread Id of thread to wait for.
* @param[out] thread_result Location where thread result is stored.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Target thread terminated.
* @retval DDS_RETCODE_ERROR
* An error occurred while waiting for the thread to terminate.
*/
DDS_EXPORT dds_return_t
ddsrt_thread_join(
ddsrt_thread_t thread,
uint32_t *thread_result);
/**
* @brief Get name of current thread.
*
* @param[in] name Buffer where the name is copied to.
* @param[in] size Number of bytes available in the buffer.
*
* @returns The number of bytes (excluding the null terminating bytes) that
* are written. If the buffer is not sufficiently large enough, the
* name is truncated and the number of bytes that would have been
* written is returned.
*/
DDS_EXPORT size_t
ddsrt_thread_getname(
char *name,
size_t size);
/**
* @brief Set name of current thread.
*
* Set name of the current thread to @name. If the name is longer than the
* platform maximum, it is silently truncated.
*
* @param[in] name Name for current thread.
*/
#if DDSRT_HAVE_THREAD_SETNAME
DDS_EXPORT void
ddsrt_thread_setname(
const char *name);
#endif
#if DDSRT_HAVE_THREAD_LIST
/**
* @brief Get a list of threads in the calling process
*
* @param[out] tids Array of size elements to be filled with thread
* identifiers, may be NULL if size is 0
* @param[in] size The size of the tids array; 0 is allowed
*
* @returns A dds_return_t indicating the number of threads in the process
* or an error code on failure.
*
* @retval > 0
* Number of threads in the process, may be larger than size
* tids[0 .. (return - 1)] are valid
* @retval DDS_RETCODE_ERROR
* Something went wrong, contents of tids is undefined
* @retval DDS_RETCODE_UNSUPPORTED
* Not supported on the platform
*/
DDS_EXPORT dds_return_t ddsrt_thread_list (ddsrt_thread_list_id_t *tids, size_t size);
/**
* @brief Get the name of the specified thread (in the calling process)
*
* @param[in] tid Thread identifier for which the name is sought
* @param[out] name Filled with the thread name (or a synthesized one)
* on successful return; name is silently truncated
* if the actual name is longer than name can hold;
* always 0-terminated if size > 0
* @param[in] size Number of bytes of name that may be assigned, size
* is 0 is allowed, though somewhat useless
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Possibly truncated name is returned as a null-terminated
* string in name (provided size > 0).
* @retval DDS_RETCODE_NOT_FOUND
* Thread not found; the contents of name is unchanged
* @retval DDS_RETCODE_ERROR
* Unspecified failure, the contents of name is undefined
* @retval DDS_RETCODE_UNSUPPORTED
* Not supported on the platform
*/
DDS_EXPORT dds_return_t ddsrt_thread_getname_anythread (ddsrt_thread_list_id_t tid, char *name, size_t size);
#endif
/**
* @brief Push cleanup handler onto the cleanup stack
*
* Push a cleanup handler onto the top of the calling thread's cleanup
* stack. The cleanup handler will be popped of the thread's cleanup stack
* and invoked with the specified argument when the thread exits.
*
* @param[in] routine Cleanup handler to push onto the thread cleanup stack.
* @param[in] arg Argument that will be passed to the cleanup handler.
*/
DDS_EXPORT dds_return_t
ddsrt_thread_cleanup_push(
void (*routine)(void* p),
void *arg);
/**
* @brief Pop cleanup handler from the top of the cleanup stack
*
* Remove routine at the top of the calling thread's cleanup stack and
* optionally invoke it (if execute is non-zero).
*/
DDS_EXPORT dds_return_t
ddsrt_thread_cleanup_pop(
int execute);
/**
* @brief Initialize thread internals.
*
* Initialize internals for threads not created with @ddsrt_create_thread. By
* default initialization is done automatically.
*/
DDS_EXPORT void
ddsrt_thread_init(uint32_t reason);
/**
* @brief Free thread resources and execute cleanup handlers.
*
* Platforms that support it, automatically free resources claimed by the
* current thread and call any registered cleanup routines. This function only
* needs to be called on platforms that do not support thread destructors and
* only for threads that were not created with @ddsrt_thread_create.
*/
DDS_EXPORT void
ddsrt_thread_fini(uint32_t reason);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_THREADS_H */
+36
View File
@@ -0,0 +1,36 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_THREADS_FREERTOS_H
#define DDSRT_THREADS_FREERTOS_H
#include <FreeRTOS.h>
#include <task.h>
#define DDSRT_HAVE_THREAD_SETNAME (0)
#define DDSRT_HAVE_THREAD_LIST (0)
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct {
TaskHandle_t task;
} ddsrt_thread_t;
typedef UBaseType_t ddsrt_tid_t;
typedef TaskHandle_t ddsrt_thread_list_id_t;
#define PRIdTID "lu"
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_THREADS_FREERTOS_H */
+68
View File
@@ -0,0 +1,68 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_POSIX_THREAD_H
#define DDSRT_POSIX_THREAD_H
#include <pthread.h>
#define DDSRT_HAVE_THREAD_SETNAME (1)
#if defined (__linux) || defined (__APPLE__)
#define DDSRT_HAVE_THREAD_LIST (1)
#else
#define DDSRT_HAVE_THREAD_LIST (0)
#endif
#if defined (__cplusplus)
extern "C" {
#endif
#if defined(__linux)
typedef long int ddsrt_tid_t;
#define PRIdTID "ld"
typedef long int ddsrt_thread_list_id_t;
/* __linux */
#elif defined(__FreeBSD__) && (__FreeBSD__ >= 9)
/* FreeBSD >= 9.0 */
typedef int ddsrt_tid_t;
#define PRIdTID "d"
/* __FreeBSD__ */
#elif defined(__APPLE__) && !(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
__MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
/* macOS X >= 10.6 */
typedef uint64_t ddsrt_tid_t;
#define PRIdTID PRIu64
/* ddsrt_thread_list_id_t is actually a mach_port_t */
typedef uint32_t ddsrt_thread_list_id_t;
/* __APPLE__ */
#elif defined(__VXWORKS__)
/* TODO: Verify taskIdSelf is the right function to use on VxWorks */
typedef TASK_ID ddsrt_tid_t;
# if defined(_WRS_CONFIG_LP64)
# define PRIdTID PRIuPTR /* typedef struct windTcb *TASK_ID */
# else
# define PRIdTID "d" /* typedef int TASK_ID */
# endif
/* __VXWORKS__ */
#else
typedef uintptr_t ddsrt_tid_t;
#define PRIdTID PRIuPTR
#endif
/* Wrapped in a struct to force conformation to abstraction. */
typedef struct {
pthread_t v;
} ddsrt_thread_t;
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_POSIX_THREAD_H */
+37
View File
@@ -0,0 +1,37 @@
// Copyright(c) 2006 to 2021 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_WINDOWS_THREADS_H
#define DDSRT_WINDOWS_THREADS_H
#include "dds/ddsrt/types.h"
#define DDSRT_HAVE_THREAD_SETNAME (1)
#define DDSRT_HAVE_THREAD_LIST (1)
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
DWORD tid;
HANDLE handle;
} ddsrt_thread_t;
typedef uint32_t ddsrt_tid_t;
#define PRIdTID PRIu32
typedef HANDLE ddsrt_thread_list_id_t;
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_WINDOWS_THREADS_H */
+307
View File
@@ -0,0 +1,307 @@
// Copyright(c) 2006 to 2022 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
/**
* @file
* @brief DDS C Time support API
*
* This header file defines the public API of the in the
* CycloneDDS C language binding.
*/
#ifndef DDS_TIME_H
#define DDS_TIME_H
#include <stdint.h>
#include <assert.h>
#include <stddef.h>
#include "dds/export.h"
#include "dds/config.h"
#include "dds/ddsrt/types.h"
#if defined (__cplusplus)
extern "C" {
#endif
/*
Times are represented using a 64-bit signed integer, encoding
nanoseconds since the epoch. Considering the nature of these
systems, one would best use TAI, International Atomic Time, rather
than something UTC, but availability may be limited.
Valid times are non-negative and times up to 2**63-2 can be
represented. 2**63-1 is defined to represent, essentially, "never".
This is good enough for a couple of centuries.
*/
/** Absolute Time definition */
typedef int64_t dds_time_t;
/** Relative Time definition in nanoseconds */
typedef int64_t dds_duration_t;
/** @name Macro definition for time units in nanoseconds.
@{**/
#define DDS_NSECS_IN_SEC INT64_C(1000000000)
#define DDS_NSECS_IN_MSEC INT64_C(1000000)
#define DDS_NSECS_IN_USEC INT64_C(1000)
/** @}*/
/** @name Infinite timeout for indicate absolute time */
#define DDS_NEVER ((dds_time_t) INT64_MAX)
/** @name Infinite timeout for relative time */
#define DDS_INFINITY ((dds_duration_t) INT64_MAX)
/** @name Invalid time value for assigning to time output when something goes wrong */
#define DDS_TIME_INVALID ((dds_time_t) INT64_MIN)
/** @name Invalid duration value */
#define DDS_DURATION_INVALID ((dds_duration_t) INT64_MIN)
/** @name Macro definition for time conversion to nanoseconds
@{**/
#define DDS_SECS(n) ((n) * DDS_NSECS_IN_SEC)
#define DDS_MSECS(n) ((n) * DDS_NSECS_IN_MSEC)
#define DDS_USECS(n) ((n) * DDS_NSECS_IN_USEC)
/** @}*/
typedef struct {
dds_time_t v;
} ddsrt_mtime_t;
typedef struct {
dds_time_t v;
} ddsrt_wctime_t;
typedef struct {
dds_time_t v;
} ddsrt_etime_t;
#define DDSRT_MTIME_NEVER ((ddsrt_mtime_t) { DDS_NEVER })
#define DDSRT_WCTIME_NEVER ((ddsrt_wctime_t) { DDS_NEVER })
#define DDSRT_ETIME_NEVER ((ddsrt_etime_t) { DDS_NEVER })
#define DDSRT_WCTIME_INVALID ((ddsrt_wctime_t) { INT64_MIN })
/**
* @brief Get the current time in nanoseconds since the UNIX Epoch.
*
* @returns Current time.
*/
DDS_EXPORT dds_time_t dds_time(void);
/**
* @brief Suspend execution of calling thread until relative time n elapsed.
*
* Execution is suspended for n nanoseconds. Should the call be interrupted,
* the call is re-entered with the remaining time.
*
* @param[in] reltime Relative time in nanoseconds.
*/
DDS_EXPORT void dds_sleepfor (dds_duration_t reltime);
/**
* @brief Get the current time in nanoseconds since the UNIX Epoch. Identical
* to (ddsrt_wctime_t){dds_time()}
*
* @returns Curren time.
*/
DDS_EXPORT ddsrt_wctime_t ddsrt_time_wallclock(void);
/**
* @brief Get high resolution, monotonic time.
*
* The monotonic clock is a clock with near real-time progression and can be
* used when a high-resolution time is needed without the need for it to be
* related to the wall-clock. The resolution of the clock is typically the
* highest available on the platform.
*
* The clock is not guaranteed to be strictly monotonic, but on most common
* platforms it will be (based on performance-counters or HPET's).
*
* @returns Monotonic time if available, otherwise real time.
*/
DDS_EXPORT ddsrt_mtime_t ddsrt_time_monotonic(void);
/**
* @brief Get high resolution, elapsed (and thus monotonic) time since some
* fixed unspecified past time.
*
* The elapsed time clock is a clock with near real-time progression and can be
* used when a high-resolution suspend-aware monotonic clock is needed, without
* having to deal with the complications of discontinuities if for example the
* time is changed. The fixed point from which the elapsed time is returned is
* not guaranteed to be fixed over reboots of the system.
*
* @returns Elapsed time if available, otherwise return monotonic time.
*/
DDS_EXPORT ddsrt_etime_t ddsrt_time_elapsed(void);
/**
* @brief Convert time into a human readable string in RFC 3339 format.
*
* Converts the calender time into a null-terminated string in RFC 3339 format.
* e.g. "2014-10-24 15:32:27-04:00".
*
* UTC offset is omitted if time-zone information is unknown.
*
* @param[in] abstime Time in nanoseconds since UNIX Epoch.
* @param[in] str String to write human readable timestamp to.
* @param[in] size Number of bytes available in @str.
*
* @returns Number of bytes written (excluding terminating null byte). The
* string is truncated if str is not sufficiently large enough. Thus,
* a return value of size or more means the output was truncated.
*/
#define DDSRT_RFC3339STRLEN (25)
DDS_EXPORT size_t ddsrt_ctime(dds_time_t abstime, char *str, size_t size);
/**
* @brief Calculate a time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
DDS_INLINE_EXPORT inline dds_time_t ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime)
{
assert(abstime >= 0);
assert(reltime >= 0);
return (reltime >= DDS_NEVER - abstime ? DDS_NEVER : abstime + reltime);
}
/**
* @brief Calculate a monotonic time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
DDS_INLINE_EXPORT inline ddsrt_mtime_t ddsrt_mtime_add_duration(ddsrt_mtime_t abstime, dds_duration_t reltime) {
ddsrt_mtime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
/**
* @brief Calculate a wall-clock time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
DDS_INLINE_EXPORT inline ddsrt_wctime_t ddsrt_wctime_add_duration(ddsrt_wctime_t abstime, dds_duration_t reltime) {
ddsrt_wctime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
/**
* @brief Calculate an elapsed time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
DDS_INLINE_EXPORT inline ddsrt_etime_t ddsrt_etime_add_duration(ddsrt_etime_t abstime, dds_duration_t reltime) {
ddsrt_etime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
#if _WIN32
/**
* @brief Convert a relative time to microseconds rounding up.
*
* @param[in] reltime Relative time to convert.
*
* @returns INFINITE if @reltime was @DDS_INIFINITY, relative time converted to
* microseconds otherwise.
*/
inline DWORD
ddsrt_duration_to_msecs_ceil(dds_duration_t reltime)
{
if (reltime == DDS_INFINITY) {
return INFINITE;
} else if (reltime > 0) {
assert(INFINITE < (DDS_INFINITY / DDS_NSECS_IN_MSEC));
dds_duration_t max_nsecs = (INFINITE - 1) * DDS_NSECS_IN_MSEC;
if (reltime < (max_nsecs - (DDS_NSECS_IN_MSEC - 1))) {
reltime += (DDS_NSECS_IN_MSEC - 1);
} else {
reltime = max_nsecs;
}
return (DWORD)(reltime / DDS_NSECS_IN_MSEC);
}
return 0;
}
#endif
/**
* @brief Convert monotonic time seconds & microseconds
*
* @param[in] t Monotonic time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_mtime_to_sec_usec (int32_t *sec, int32_t *usec, ddsrt_mtime_t t);
/**
* @brief Convert wall-clock time seconds & microseconds
*
* @param[in] t Wall-clock time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_wctime_to_sec_usec (int32_t *sec, int32_t *usec, ddsrt_wctime_t t);
/**
* @brief Convert elapsed time seconds & microseconds
*
* @param[in] t Elasped time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_etime_to_sec_usec (int32_t *sec, int32_t *usec, ddsrt_etime_t t);
#if defined(__cplusplus)
}
#endif
#if DDSRT_WITH_FREERTOS
#include "dds/ddsrt/time/freertos.h"
#endif
#endif /* DDSRT_TIME_H */
+52
View File
@@ -0,0 +1,52 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_TIME_FREERTOS_H
#define DDSRT_TIME_FREERTOS_H
#include <assert.h>
#include <FreeRTOS.h>
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ)
inline TickType_t
ddsrt_duration_to_ticks_ceil(
dds_duration_t reltime)
{
TickType_t ticks = 0;
assert(portMAX_DELAY > configTICK_RATE_HZ);
if (reltime == DDS_INFINITY) {
ticks = portMAX_DELAY;
} else if (reltime > 0) {
dds_duration_t max_nsecs =
(DDS_INFINITY / DDSRT_NSECS_PER_TICK < portMAX_DELAY
? DDS_INFINITY - 1 : portMAX_DELAY * DDSRT_NSECS_PER_TICK);
if (reltime > max_nsecs - (DDSRT_NSECS_PER_TICK - 1)) {
ticks = portMAX_DELAY;
} else {
ticks = (TickType_t)((reltime + (DDSRT_NSECS_PER_TICK - 1)) / DDSRT_NSECS_PER_TICK);
}
}
return ticks;
}
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_TIME_FREERTOS_H */
+29
View File
@@ -0,0 +1,29 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_TYPES_H
#define DDSRT_TYPES_H
#include <stdbool.h>
#include <stdint.h>
#if _WIN32
# include "dds/ddsrt/types/windows.h"
#elif __VXWORKS__
# include "dds/ddsrt/types/vxworks.h"
#else
# include "dds/ddsrt/types/posix.h"
#endif
#define PRIdSIZE "zd"
#define PRIuSIZE "zu"
#define PRIxSIZE "zx"
#endif /* DDSRT_TYPES_H */
+22
View File
@@ -0,0 +1,22 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_TYPES_POSIX_H
#define DDSRT_TYPES_POSIX_H
#include <stdint.h>
#include <inttypes.h>
#if defined(__IAR_SYSTEMS_ICC__)
typedef long int ssize_t;
#else
#include <unistd.h>
#endif
#endif /* DDSRT_TYPES_POSIX_H */
+73
View File
@@ -0,0 +1,73 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_TYPES_VXWORKS_H
#define DDSRT_TYPES_VXWORKS_H
#if defined(_WRS_KERNEL)
/* inttypes.h does not exist in VxWorks DKM. */
#include <st_inttypes.h>
#include <cafe/inttypes.h>
/* The above inttypes includes don't seem to define uintmax_t &c. */
#ifdef _WRS_CONFIG_LP64 /* Used in cafe/inttypes.h too. */
#define _PFX_64 "l"
typedef unsigned long int uintmax_t;
#else
#define _PFX_64 "ll"
typedef unsigned long long int uintmax_t;
#endif
/* Not a complete replacement for inttypes.h (yet); No SCN/PRI?LEAST/FAST/etc. */
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 _PFX_64 "d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 _PFX_64 "i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 _PFX_64 "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 _PFX_64 "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 _PFX_64 "X"
#define PRIdMAX _PFX_64 "d"
#define PRIiMAX _PFX_64 "i"
#define PRIoMAX _PFX_64 "o"
#define PRIuMAX _PFX_64 "u"
#define PRIxMAX _PFX_64 "x"
#define PRIXMAX _PFX_64 "X"
#define PRIdPTR _PFX_64 "d"
#define PRIiPTR _PFX_64 "i"
#define PRIoPTR _PFX_64 "o"
#define PRIXPTR _PFX_64 "X"
#else /* _WRS_KERNEL */
#include <inttypes.h>
#endif /* _WRS_KERNEL */
#endif /* DDSRT_TYPES_VXWORKS_H */
+32
View File
@@ -0,0 +1,32 @@
// Copyright(c) 2006 to 2019 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_TYPES_WINDOWS_H
#define DDSRT_TYPES_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <versionhelpers.h>
#include <stdint.h>
#include <inttypes.h>
#include <wchar.h>
#ifdef _MSC_VER
typedef SSIZE_T ssize_t;
#endif
#endif /* DDSRT_TYPES_WINDOWS_H */
+169
View File
@@ -0,0 +1,169 @@
// Copyright(c) 2006 to 2020 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#ifndef DDSRT_XMLPARSER_H
#define DDSRT_XMLPARSER_H
#include <stdio.h>
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
/** @file xmlparser.h
*
* This is provides a parser for an XML-like language (close enough to a subset of XML to
* treat it as XML).
*
* It is configured with a set of callbacks for handling elements and attributes, to be
* called at appropriate times during parsing. Each of these can return a negative value
* to signal an error. A separate callback exists for reporting syntactic errors.
*
* The parser carries an arbitrary state pointer around that is passed as the first
* argument to all callback functions. It also allows the element open function to
* associate it with an arbitrary `uintptr_t` that is passed to all other callbacks
* related to the same element (so attributes, data), and also as the `parentinfo` to the
* element open callbacks for any children.
*/
/** @brief Type of callback function for processing an element open tag
*
* @param[in] varg arbitrary object pointer for tracking state during parsing
* @param[in] parentinfo is 0 for the root element, otherwise the value stored into `*eleminfo` by the element open callback for the parent
* @param[out] eleminfo arbitrary value passed to all other callbacks related to this element
* @param[in] name name of the element (i.e., "abc" in `<abc def="ghi">jkl</abc>`)
* @param[in] line line number at which the token starts
*
* @return < 0 on failure, >= 0 on success
*/
typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line);
/** @brief Type of callback function for processing an attribute
*
* @param[in] varg arbitrary object pointer for tracking state during parsing
* @param[in] eleminfo whatever was stored in `*eleminfo` by the element open tag callback
* @param[in] name name of the attribute (i.e., "def" in the above`)
* @param[in] value value of the attribute (i.e., "ghi" in the above)
* @param[in] line line number at which the token starts
*
* @return < 0 on failure, >= 0 on success
*/
typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line);
/** @brief Type of callback function for processing the element body
*
* @param[in] varg arbitrary object pointer for tracking state during parsing
* @param[in] eleminfo whatever was stored in `*eleminfo` by the element open tag callback
* @param[in] data element body text (i.e., "jkl" in the above)
* @param[in] line line number at which body token starts
*
* @return < 0 on failure, >= 0 on success
*/
typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data, int line);
/** @brief Type of callback function for processing the element close tag
*
* @param[in] varg arbitrary object pointer for tracking state during parsing
* @param[in] eleminfo whatever was stored in `*eleminfo` by the element open tag callback
* @param[in] line line number at which element close token starts
*
* @return < 0 on failure, >= 0 on success
*/
typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo, int line);
/** @brief Type of callback function for reporting a syntactic error
*
* @param[in] varg arbitrary object pointer for tracking state during parsing
* @param[in] msg error message generated by the parser
* @param[in] line line number at which the error was detected
*/
typedef void (*ddsrt_xmlp_error) (void *varg, const char *msg, int line);
/** Struct defining the callbacks, see the type definitions for information */
struct ddsrt_xmlp_callbacks {
ddsrt_xmlp_proc_elem_open_t elem_open;
ddsrt_xmlp_proc_attr_t attr;
ddsrt_xmlp_proc_elem_data_t elem_data;
ddsrt_xmlp_proc_elem_close_t elem_close;
ddsrt_xmlp_error error;
};
/** Opaque parser state */
struct ddsrt_xmlp_state;
/** Parser option: if not set, junk may follow top-level closing tag. Set by default. */
#define DDSRT_XMLP_REQUIRE_EOF 1u
/** Parser option: if set allow closing an element with </> instead of </name>. Clear by default. */
#define DDSRT_XMLP_ANONYMOUS_CLOSE_TAG 2u
/** Parser option: if set, treat missing close tag as EOF and synthesise any missing close tags. Clear by default. */
#define DDSRT_XMLP_MISSING_CLOSE_AS_EOF 4u
/** @brief Construct a new XML parser for a file
*
* @param[in] fp file to read from, cached in returned `ddsrt_xmlp_state` state object
* @param[in] varg argument pointer to passed to all callback functions
* @param[in] cb callbacks for interpreting the contents of the file, functions pointers may be 0
*
* @return a newly allocated state object with default options
*/
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_file (FILE *fp, void *varg, const struct ddsrt_xmlp_callbacks *cb);
/** @brief Construct a new XML parser taking a string as input
*
* @param[in] string string to read from, cached in returned `ddsrt_xmlp_state` state object
* @param[in] varg argument pointer to passed to all callback functions
* @param[in] cb callbacks for interpreting the contents of the file, functions pointers may be 0
*
* @return a newly allocated state object with default options
*/
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_string (const char *string, void *varg, const struct ddsrt_xmlp_callbacks *cb);
/** @brief Modify the options of a XML parser state object
*
* @param[in] st state object obtained from @ref ddsrt_xmlp_new_file or @ref ddsrt_xmlp_new_string
* @param[in] options bitwise or of desired options
*/
DDS_EXPORT void ddsrt_xmlp_set_options (struct ddsrt_xmlp_state *st, uint32_t options);
/** @brief Get the current buffer position
*
* @note While there is a "current buffer position" in all cases, it is meaningless when reading from a file.
*
* @param[in] st state object obtained from @ref ddsrt_xmlp_new_file or @ref ddsrt_xmlp_new_string
* @return When parsing a string, the offset in the input string
*/
DDS_EXPORT size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st);
/** @brief Free the XML parser state object
*
* @param[in] st state object obtained from @ref ddsrt_xmlp_new_file or @ref ddsrt_xmlp_new_string
*/
DDS_EXPORT void ddsrt_xmlp_free (struct ddsrt_xmlp_state *st);
/** @brief Parse an XML file or string
*
* This calls the callbacks specified when creating the parser for interpretation of the contents.
*
* @param[in] st state object obtained from @ref ddsrt_xmlp_new_file or @ref ddsrt_xmlp_new_string
*
* @return The result of the last call to the element close callback, or -1 on syntax error.
*/
DDS_EXPORT int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st);
#if defined (__cplusplus)
}
#endif
#endif