This commit is contained in:
2025-09-24 10:53:28 +08:00
commit f8e4df77fb
856 changed files with 140098 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
/*
* 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 */

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_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 */

View File

@@ -0,0 +1,94 @@
/*
* 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"
#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. atomic
*/
typedef struct { uint32_t v; } ddsrt_atomic_uint32_t;
typedef struct { uint64_t v; } ddsrt_atomic_uint64_t;
typedef struct { uintptr_t v; } ddsrt_atomic_uintptr_t;
typedef ddsrt_atomic_uintptr_t ddsrt_atomic_voidp_t;
#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) }
#define DDSRT_ATOMIC_UINT64_INIT(v) { (v) }
#define DDSRT_ATOMIC_UINTPTR_INIT(v) { (v) }
#define DDSRT_ATOMIC_VOIDP_INIT(v) { (uintptr_t) (v) }
#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
/* 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. */
DDS_EXPORT uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x);
DDS_EXPORT void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x);
DDS_EXPORT uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x);
DDS_EXPORT void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x);
DDS_EXPORT uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x);
DDS_EXPORT void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);
DDS_EXPORT int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_t des);
#endif
void ddsrt_atomics_init (void);
void ddsrt_atomics_fini (void);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_ATOMICS_H */

View File

@@ -0,0 +1,173 @@
/*
* 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
/* LD, ST */
inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* CAS */
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;
}
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);
}
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 */
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;
}
inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_add32_nv (x, v);
}
inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return ddsrt_atomic_add32_nv (x, v) - v;
}
/* SUB */
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return ddsrt_atomic_add32_nv (x, -v);
}
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
ddsrt_atomic_add32 (x, -v);
}
/* INC */
inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_add32_nv (x, 1) - 1;
}
inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_add32_nv (x, 1);
}
inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
(void) ddsrt_atomic_inc32_nv (x);
}
/* DEC */
inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_sub32_nv (x, 1) + 1;
}
inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return ddsrt_atomic_sub32_nv (x, 1);
}
inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
(void) ddsrt_atomic_dec32_nv (x);
}
/* AND */
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;
}
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;
}
inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_and32_nv (x, v);
}
/* OR */
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;
}
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;
}
inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
(void) ddsrt_atomic_or32_nv (x, v);
}
/* FENCES */
inline void ddsrt_atomic_fence (void) {
__asm volatile ("dmb" : : : "memory");
}
inline void ddsrt_atomic_fence_ldld (void) {
ddsrt_atomic_fence ();
}
inline void ddsrt_atomic_fence_stst (void) {
ddsrt_atomic_fence ();
}
inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}
inline void ddsrt_atomic_fence_rel (void) {
ddsrt_atomic_fence ();
}
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_ATOMICS_ARM_H */

View File

@@ -0,0 +1,309 @@
/*
* 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
/* LD, ST */
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
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
DDS_INLINE_EXPORT ddsrt_attribute_no_sanitize (("thread"))
inline uintptr_t ddsrt_atomic_ldptr(const volatile ddsrt_atomic_uintptr_t *x)
{
return x->v;
}
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);
}
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
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
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;
}
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 */
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
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
__sync_fetch_and_add (&x->v, 1);
}
#endif
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return __sync_fetch_and_add (&x->v, 1);
}
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
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
/* DEC */
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
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
__sync_fetch_and_sub (&x->v, 1);
}
#endif
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
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
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
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
/* ADD */
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
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
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);
}
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
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
/* SUB */
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
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
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);
}
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
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
/* AND */
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
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
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
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
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
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
/* OR */
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
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
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
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
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
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
/* CAS */
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
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
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);
}
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
typedef struct {
ddsrt_atomic_uintptr2_t aba_head;
} ddsrt_atomic_lifo_t;
DDS_EXPORT void ddsrt_atomic_lifo_init(ddsrt_atomic_lifo_t *head);
DDS_EXPORT void ddsrt_atomic_lifo_push(ddsrt_atomic_lifo_t *head, void *elem, size_t linkoff);
DDS_EXPORT void *ddsrt_atomic_lifo_pop(ddsrt_atomic_lifo_t *head, size_t linkoff);
DDS_EXPORT void ddsrt_atomic_lifo_pushmany(ddsrt_atomic_lifo_t *head, void *first, void *last, size_t linkoff);
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 */
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence (void) {
__sync_synchronize ();
}
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
}
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
}
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
}
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 */

View File

@@ -0,0 +1,262 @@
/*
* 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
/* LD, ST */
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
#if DDSRT_HAVE_ATOMIC64
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x) { return x->v; }
#endif
DDS_INLINE_EXPORT inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
DDS_INLINE_EXPORT inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
DDS_INLINE_EXPORT inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
#if DDSRT_HAVE_ATOMIC64
DDS_INLINE_EXPORT inline void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { x->v = v; }
#endif
DDS_INLINE_EXPORT inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
DDS_INLINE_EXPORT inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* CAS */
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
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
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;
}
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 */
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
DDSRT_ATOMIC_OP32 (InterlockedIncrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
DDS_INLINE_EXPORT inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
DDSRT_ATOMIC_OP64 (InterlockedIncrement, &x->v);
}
#endif
DDS_INLINE_EXPORT inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) {
return DDSRT_ATOMIC_OP32 (InterlockedIncrement, &x->v) - 1;
}
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
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedIncrement, &x->v);
}
#endif
/* DEC */
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
DDSRT_ATOMIC_OP32 (InterlockedDecrement, &x->v);
}
#if DDSRT_HAVE_ATOMIC64
DDS_INLINE_EXPORT inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
DDSRT_ATOMIC_OP64 (InterlockedDecrement, &x->v);
}
#endif
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
DDS_INLINE_EXPORT inline uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return DDSRT_ATOMIC_OP64 (InterlockedDecrement, &x->v);
}
#endif
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
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
/* ADD */
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
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
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);
}
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
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
/* SUB */
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
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
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)
}
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
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
/* AND */
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
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
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
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
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
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
/* OR */
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
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
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
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
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
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
/* FENCES */
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)
}
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_ldld (void) {
#if !(defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#endif
}
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_stst (void) {
#if !(defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#endif
}
DDS_INLINE_EXPORT inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}
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 */

View File

@@ -0,0 +1,199 @@
/*
* 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
/* LD, ST */
inline uint32_t ddsrt_atomic_ld32 (const volatile ddsrt_atomic_uint32_t *x) { return x->v; }
inline uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x) { return x->v; }
inline uintptr_t ddsrt_atomic_ldptr (const volatile ddsrt_atomic_uintptr_t *x) { return x->v; }
inline void *ddsrt_atomic_ldvoidp (const volatile ddsrt_atomic_voidp_t *x) { return (void *) ddsrt_atomic_ldptr (x); }
inline void ddsrt_atomic_st32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { x->v = v; }
inline void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { x->v = v; }
inline void ddsrt_atomic_stptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { x->v = v; }
inline void ddsrt_atomic_stvoidp (volatile ddsrt_atomic_voidp_t *x, void *v) { ddsrt_atomic_stptr (x, (uintptr_t) v); }
/* INC */
inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x) {
atomic_inc_32 (&x->v);
}
inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
atomic_inc_64 (&x->v);
}
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;
}
inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) {
return atomic_inc_32_nv (&x->v);
}
inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return atomic_inc_64_nv (&x->v);
}
/* DEC */
inline void ddsrt_atomic_dec32 (volatile ddsrt_atomic_uint32_t *x) {
atomic_dec_32 (&x->v);
}
inline void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
atomic_dec_64 (&x->v);
}
inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) {
return atomic_dec_32_nv (&x->v);
}
inline uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return atomic_dec_64_nv (&x->v);
}
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;
}
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 */
inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_add_32 (&x->v, v);
}
inline void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_add_64 (&x->v, v);
}
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;
}
inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, v);
}
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 */
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_add_32 (&x->v, -v);
}
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_add_64 (&x->v, -v);
}
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;
}
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_add_32_nv (&x->v, -v);
}
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 */
inline void ddsrt_atomic_and32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_and_32 (&x->v, v);
}
inline void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_and_64 (&x->v, v);
}
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;
}
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;
}
inline uint32_t ddsrt_atomic_and32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_and_32_nv (&x->v, v);
}
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 */
inline void ddsrt_atomic_or32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
atomic_or_32 (&x->v, v);
}
inline void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
atomic_or_64 (&x->v, v);
}
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;
}
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;
}
inline uint32_t ddsrt_atomic_or32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
return atomic_or_32_nv (&x->v, v);
}
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 */
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;
}
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;
}
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;
}
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 */
inline void ddsrt_atomic_fence (void) {
membar_exit ();
membar_enter ();
}
inline void ddsrt_atomic_fence_ldld (void) {
membar_consumer ();
}
inline void ddsrt_atomic_fence_stst (void) {
membar_producer ();
}
inline void ddsrt_atomic_fence_acq (void) {
membar_enter ();
}
inline void ddsrt_atomic_fence_rel (void) {
membar_exit ();
}
#if defined (__cplusplus)
}
#endif

View File

@@ -0,0 +1,138 @@
/*
* 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(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 */

View File

@@ -0,0 +1,359 @@
/*
* 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
/* 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 ddsi2e, 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 *))
typedef int (*ddsrt_avl_compare_t) (const void *a, const void *b);
typedef int (*ddsrt_avl_compare_r_t) (const void *a, const void *b, void *arg);
typedef void (*ddsrt_avl_augment_t) (void *node, const void *left, const void *right);
typedef void (*ddsrt_avl_walk_t) (void *node, void *arg);
typedef void (*ddsrt_avl_const_walk_t) (const void *node, void *arg);
typedef struct ddsrt_avl_node {
struct ddsrt_avl_node *cs[2]; /* 0 = left, 1 = right */
struct ddsrt_avl_node *parent;
int height;
} ddsrt_avl_node_t;
#define DDSRT_AVL_TREEDEF_FLAG_INDKEY 1
#define DDSRT_AVL_TREEDEF_FLAG_R 2
#define DDSRT_AVL_TREEDEF_FLAG_ALLOWDUPS 4
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;
typedef struct ddsrt_avl_ctreedef {
ddsrt_avl_treedef_t t;
} ddsrt_avl_ctreedef_t;
typedef struct ddsrt_avl_tree {
ddsrt_avl_node_t *root;
} ddsrt_avl_tree_t;
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;
typedef struct ddsrt_avl_ipath {
ddsrt_avl_path_t p;
} ddsrt_avl_ipath_t;
typedef struct ddsrt_avl_dpath {
ddsrt_avl_path_t p;
} ddsrt_avl_dpath_t;
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;
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 */
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));
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));
DDS_EXPORT void ddsrt_avl_init (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_free (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void (*freefun) (void *node)) ddsrt_nonnull((1,2));
DDS_EXPORT void ddsrt_avl_free_arg (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void (*freefun) (void *node, void *arg), void *arg) ddsrt_nonnull((1,2));
DDS_EXPORT void *ddsrt_avl_root (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
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;
DDS_EXPORT void *ddsrt_avl_lookup (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree, const void *key) ddsrt_nonnull_all;
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;
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;
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;
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;
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;
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;
DDS_EXPORT void ddsrt_avl_insert (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *node) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_delete (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *node) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_insert_ipath (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *node, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_delete_dpath (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *node, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_swap_node (const ddsrt_avl_treedef_t *td, ddsrt_avl_tree_t *tree, void *oldn, void *newn) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_augment_update (const ddsrt_avl_treedef_t *td, void *node) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_avl_is_empty (const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_avl_is_singleton (const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_find_min (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_find_max (const ddsrt_avl_treedef_t *td, const ddsrt_avl_tree_t *tree) ddsrt_nonnull_all;
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));
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));
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));
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));
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));
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));
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));
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));
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;
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;
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;
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) }
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));
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));
DDS_EXPORT void ddsrt_avl_cinit (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_cfree (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void (*freefun) (void *node)) ddsrt_nonnull((1,2));
DDS_EXPORT void ddsrt_avl_cfree_arg (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void (*freefun) (void *node, void *arg), void *arg) ddsrt_nonnull((1,2));
DDS_EXPORT void *ddsrt_avl_croot (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_croot_non_empty (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_clookup (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree, const void *key) ddsrt_nonnull_all;
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;
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;
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;
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;
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;
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;
DDS_EXPORT void ddsrt_avl_cinsert (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *node) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_cdelete (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *node) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_cinsert_ipath (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *node, ddsrt_avl_ipath_t *path) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_cdelete_dpath (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *node, ddsrt_avl_dpath_t *path) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_cswap_node (const ddsrt_avl_ctreedef_t *td, ddsrt_avl_ctree_t *tree, void *oldn, void *newn) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_avl_caugment_update (const ddsrt_avl_ctreedef_t *td, void *node) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_avl_cis_empty (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_avl_cis_singleton (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT size_t ddsrt_avl_ccount (const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_cfind_min (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_avl_cfind_max (const ddsrt_avl_ctreedef_t *td, const ddsrt_avl_ctree_t *tree) ddsrt_nonnull_all;
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));
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));
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));
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));
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));
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));
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));
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));
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;
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;
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;
DDS_EXPORT void *ddsrt_avl_citer_next (ddsrt_avl_citer_t *iter) ddsrt_nonnull_all;
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_AVL_H */

View File

@@ -0,0 +1,119 @@
/*
* 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
#include <stdint.h>
#include <stdlib.h>
#include "dds/export.h"
#include "dds/ddsrt/endian.h"
#if defined (__cplusplus)
extern "C" {
#endif
enum ddsrt_byte_order_selector {
DDSRT_BOSEL_NATIVE,
DDSRT_BOSEL_BE,
DDSRT_BOSEL_LE,
};
DDS_INLINE_EXPORT inline uint16_t ddsrt_bswap2u (uint16_t x)
{
return (uint16_t) ((x >> 8) | (x << 8));
}
DDS_INLINE_EXPORT inline int16_t ddsrt_bswap2 (int16_t x)
{
return (int16_t) ddsrt_bswap2u ((uint16_t) x);
}
DDS_INLINE_EXPORT inline uint32_t ddsrt_bswap4u (uint32_t x)
{
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
}
DDS_INLINE_EXPORT inline int32_t ddsrt_bswap4 (int32_t x)
{
return (int32_t) ddsrt_bswap4u ((uint32_t) x);
}
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;
}
DDS_INLINE_EXPORT inline int64_t ddsrt_bswap8 (int64_t x)
{
return (int64_t) ddsrt_bswap8u ((uint64_t) x);
}
#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 */

View File

@@ -0,0 +1,34 @@
/*
* 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"
#if defined (__cplusplus)
extern "C" {
#endif
DDS_EXPORT void ddsrt_init(void);
DDS_EXPORT void ddsrt_fini(void);
DDS_EXPORT ddsrt_mutex_t *ddsrt_get_singleton_mutex(void);
DDS_EXPORT ddsrt_cond_t *ddsrt_get_singleton_cond(void);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_CDTORS_H */

View File

@@ -0,0 +1,43 @@
/*
* 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
/* Circular doubly linked list implementation */
#include <stdbool.h>
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define DDSRT_FROM_CIRCLIST(typ_, member_, cle_) ((typ_ *) ((char *) (cle_) - offsetof (typ_, member_)))
struct ddsrt_circlist {
struct ddsrt_circlist_elem *latest; /* pointer to latest inserted element */
};
struct ddsrt_circlist_elem {
struct ddsrt_circlist_elem *next;
struct ddsrt_circlist_elem *prev;
};
DDS_EXPORT void ddsrt_circlist_init (struct ddsrt_circlist *list);
DDS_EXPORT bool ddsrt_circlist_isempty (const struct ddsrt_circlist *list);
DDS_EXPORT void ddsrt_circlist_append (struct ddsrt_circlist *list, struct ddsrt_circlist_elem *elem);
DDS_EXPORT void ddsrt_circlist_remove (struct ddsrt_circlist *list, struct ddsrt_circlist_elem *elem);
DDS_EXPORT struct ddsrt_circlist_elem *ddsrt_circlist_oldest (const struct ddsrt_circlist *list);
DDS_EXPORT struct ddsrt_circlist_elem *ddsrt_circlist_latest (const struct ddsrt_circlist *list);
#endif /* DDSRT_CIRCLIST_H */

View File

@@ -0,0 +1,20 @@
/*
* 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
#define DDSRT_COUNT_ARGS_MSVC_WORKAROUND(x) x
#define DDSRT_COUNT_ARGS(...) DDSRT_COUNT_ARGS1 (__VA_ARGS__, 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,n,...) n
#endif

View File

@@ -0,0 +1,149 @@
/*
* 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 DDSRT_HAVE_DYNLIB
#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_EXPORT dds_return_t
ddsrt_dlopen(
const char *name,
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;
/**
* @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_EXPORT dds_return_t
ddsrt_dlclose(
ddsrt_dynlib_t handle);
/**
* @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_EXPORT dds_return_t
ddsrt_dlsym(
ddsrt_dynlib_t handle,
const char *symbol,
void **address);
/**
* @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_EXPORT dds_return_t
ddsrt_dlerror(
char *buf,
size_t buflen);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_HAVE_DYNLIB */
#endif /* DDSRT_DYNLIB_H */

View File

@@ -0,0 +1,62 @@
/*
* 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 */

View File

@@ -0,0 +1,150 @@
/*
* 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 */

View File

@@ -0,0 +1,78 @@
/*
* 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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT char*
ddsrt_expand_vars_sh(
const char *string,
expand_lookup_fn lookup,
void * data);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_EXPAND_VARS_H */

View File

@@ -0,0 +1,54 @@
/*
* 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
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct ddsrt_fibheap_node {
struct ddsrt_fibheap_node *parent, *children;
struct ddsrt_fibheap_node *prev, *next;
unsigned mark: 1;
unsigned degree: 31;
} ddsrt_fibheap_node_t;
typedef struct ddsrt_fibheap_def {
uintptr_t offset;
int (*cmp) (const void *va, const void *vb);
} ddsrt_fibheap_def_t;
typedef struct ddsrt_fibheap {
ddsrt_fibheap_node_t *roots; /* points to root with min key value */
} ddsrt_fibheap_t;
#define DDSRT_FIBHEAPDEF_INITIALIZER(offset, cmp) { (offset), (cmp) }
DDS_EXPORT void ddsrt_fibheap_def_init (ddsrt_fibheap_def_t *fhdef, uintptr_t offset, int (*cmp) (const void *va, const void *vb));
DDS_EXPORT void ddsrt_fibheap_init (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh);
DDS_EXPORT void *ddsrt_fibheap_min (const ddsrt_fibheap_def_t *fhdef, const ddsrt_fibheap_t *fh);
DDS_EXPORT void ddsrt_fibheap_merge (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *a, ddsrt_fibheap_t *b);
DDS_EXPORT void ddsrt_fibheap_insert (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode);
DDS_EXPORT void ddsrt_fibheap_delete (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode);
DDS_EXPORT void *ddsrt_fibheap_extract_min (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh);
DDS_EXPORT void ddsrt_fibheap_decrease_key (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode); /* to be called AFTER decreasing the key */
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_FIBHEAP_H */

View File

@@ -0,0 +1,127 @@
/*
* 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

View File

@@ -0,0 +1,34 @@
/*
* 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;
#define DDSRT_PATH_MAX PATH_MAX
#define DDSRT_FILESEPCHAR '/'
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_FILESYSTEM_POSIX_H */

View File

@@ -0,0 +1,34 @@
/*
* 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 */

View File

@@ -0,0 +1,155 @@
/*
* 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
/**
* @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 */

View File

@@ -0,0 +1,113 @@
/*
* 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 "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
/*
* 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);
/*
* Hopscotch needs to be able to compare two elements.
* Returns 0 when not equal.
*/
typedef int (*ddsrt_hh_equals_fn) (const void *a, const void *b);
/*
* Hopscotch is 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 */
struct ddsrt_hh;
struct ddsrt_hh_iter {
struct ddsrt_hh *hh;
uint32_t cursor;
};
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;
DDS_EXPORT void ddsrt_hh_free (struct ddsrt_hh * __restrict hh) ddsrt_nonnull_all;
DDS_EXPORT void *ddsrt_hh_lookup (const struct ddsrt_hh * __restrict rt, const void * __restrict keyobject) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_hh_add (struct ddsrt_hh * __restrict rt, void * __restrict data) ddsrt_nonnull_all;
DDS_EXPORT int ddsrt_hh_remove (struct ddsrt_hh * __restrict rt, const void * __restrict keyobject) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_hh_add_absent (struct ddsrt_hh * __restrict rt, void * __restrict data) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_hh_remove_present (struct ddsrt_hh * __restrict rt, void * __restrict keyobject) ddsrt_nonnull_all;
DDS_EXPORT void ddsrt_hh_enum (struct ddsrt_hh * __restrict rt, void (*f) (void *a, void *f_arg), void *f_arg) ddsrt_nonnull ((1, 2)); /* may delete a */
DDS_EXPORT void *ddsrt_hh_iter_first (struct ddsrt_hh * __restrict rt, struct ddsrt_hh_iter * __restrict iter) ddsrt_nonnull_all; /* may delete nodes */
DDS_EXPORT void *ddsrt_hh_iter_next (struct ddsrt_hh_iter * __restrict iter) ddsrt_nonnull_all;
/* Concurrent version */
struct ddsrt_chh;
struct ddsrt_chh_bucket;
#if ! ddsrt_has_feature_thread_sanitizer
struct ddsrt_chh_iter {
struct ddsrt_chh_bucket *bs;
uint32_t size;
uint32_t cursor;
};
#else
struct ddsrt_chh_iter {
struct ddsrt_chh *chh;
struct ddsrt_hh_iter it;
};
#endif
DDS_EXPORT 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);
DDS_EXPORT void ddsrt_chh_free (struct ddsrt_chh * __restrict hh);
DDS_EXPORT void *ddsrt_chh_lookup (struct ddsrt_chh * __restrict rt, const void * __restrict keyobject);
DDS_EXPORT int ddsrt_chh_add (struct ddsrt_chh * __restrict rt, void * __restrict data);
DDS_EXPORT int ddsrt_chh_remove (struct ddsrt_chh * __restrict rt, const void * __restrict keyobject);
DDS_EXPORT void ddsrt_chh_enum_unsafe (struct ddsrt_chh * __restrict rt, void (*f) (void *a, void *f_arg), void *f_arg); /* may delete a */
DDS_EXPORT void *ddsrt_chh_iter_first (struct ddsrt_chh * __restrict rt, struct ddsrt_chh_iter *it);
DDS_EXPORT void *ddsrt_chh_iter_next (struct ddsrt_chh_iter *it);
/* Sequential version, embedded data */
struct ddsrt_ehh;
struct ddsrt_ehh_iter {
struct ddsrt_ehh *hh;
uint32_t cursor;
};
DDS_EXPORT struct ddsrt_ehh *ddsrt_ehh_new (size_t elemsz, uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals);
DDS_EXPORT void ddsrt_ehh_free (struct ddsrt_ehh * __restrict hh);
DDS_EXPORT void *ddsrt_ehh_lookup (const struct ddsrt_ehh * __restrict rt, const void * __restrict keyobject);
DDS_EXPORT int ddsrt_ehh_add (struct ddsrt_ehh * __restrict rt, const void * __restrict data);
DDS_EXPORT int ddsrt_ehh_remove (struct ddsrt_ehh * __restrict rt, const void * __restrict keyobject);
DDS_EXPORT void ddsrt_ehh_enum (struct ddsrt_ehh * __restrict rt, void (*f) (void *a, void *f_arg), void *f_arg); /* may delete a */
DDS_EXPORT void *ddsrt_ehh_iter_first (struct ddsrt_ehh * __restrict rt, struct ddsrt_ehh_iter * __restrict iter); /* may delete nodes */
DDS_EXPORT void *ddsrt_ehh_iter_next (struct ddsrt_ehh_iter * __restrict iter);
#if defined (__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,58 @@
/*
* 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"
#if defined (__cplusplus)
extern "C" {
#endif
enum ddsrt_iftype {
DDSRT_IFTYPE_UNKNOWN,
DDSRT_IFTYPE_WIRED,
DDSRT_IFTYPE_WIFI
};
struct ddsrt_ifaddrs {
struct ddsrt_ifaddrs *next;
char *name;
uint32_t index;
uint32_t flags;
enum ddsrt_iftype type;
struct sockaddr *addr;
struct sockaddr *netmask;
struct sockaddr *broadaddr;
};
typedef struct ddsrt_ifaddrs ddsrt_ifaddrs_t;
DDS_EXPORT dds_return_t
ddsrt_getifaddrs(
ddsrt_ifaddrs_t **ifap,
const int *afs);
DDS_EXPORT void
ddsrt_freeifaddrs(
ddsrt_ifaddrs_t *ifa);
DDS_EXPORT dds_return_t
ddsrt_eth_get_mac_addr(
char *interface_name,
unsigned char *mac_addr);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_IFADDRS_H */

View File

@@ -0,0 +1,51 @@
/*
* 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 */

View File

@@ -0,0 +1,45 @@
/*
* 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

View File

@@ -0,0 +1,456 @@
/*
* 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)
/** Debug/trace messages related to SHMEM */
#define DDS_LC_SHM (262144u)
/** 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_SHM)
/** @}*/
#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 *, const dds_log_data_t *);
/** 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
*/
DDS_EXPORT void
dds_set_log_file(
FILE *file);
/**
* @private
*/
DDS_EXPORT 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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT void
dds_log_cfg(
const struct ddsrt_log_cfg *cfg,
uint32_t prio,
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.
*/
DDS_EXPORT void
dds_log_id(
uint32_t prio,
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 prio,
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 */

View File

@@ -0,0 +1,106 @@
/* 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"
/*
* 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 */
/* Define the state of 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
/* Initialize the algorithm. */
DDS_EXPORT void ddsrt_md5_init(ddsrt_md5_state_t *pms);
/* Append a string to the message. */
DDS_EXPORT void ddsrt_md5_append(ddsrt_md5_state_t *pms, const ddsrt_md5_byte_t *data, unsigned nbytes);
/* Finish the message and return the digest. */
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 */

View File

@@ -0,0 +1,34 @@
/*
* 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
#include <stdint.h>
#include <stddef.h>
#include "dds/export.h"
#if defined(__cplusplus)
extern "C" {
#endif
DDS_EXPORT uint32_t
ddsrt_mh3(
const void *key,
size_t len,
uint32_t seed);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_MH3_H */

View File

@@ -0,0 +1,99 @@
/*
* 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 */

View File

@@ -0,0 +1,68 @@
/*
* 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 */

View File

@@ -0,0 +1,74 @@
/*
* 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
#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 */

View File

@@ -0,0 +1,50 @@
/*
* 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;
DDS_EXPORT void ddsrt_random_init (void);
DDS_EXPORT void ddsrt_random_fini (void);
DDS_EXPORT void ddsrt_prng_init_simple (ddsrt_prng_t *prng, uint32_t seed);
DDS_EXPORT bool ddsrt_prng_makeseed (struct ddsrt_prng_seed *seed);
DDS_EXPORT void ddsrt_prng_init (ddsrt_prng_t *prng, const struct ddsrt_prng_seed *seed);
DDS_EXPORT uint32_t ddsrt_prng_random (ddsrt_prng_t *prng);
DDS_EXPORT 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 */

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 */

View File

@@ -0,0 +1,86 @@
/*
* 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 * __restrict usage);
#endif
#if defined (__cplusplus)
}
#endif
#endif // DDSRT_HAVE_RUSAGE
#endif // DDSRT_RUSAGE_H

View File

@@ -0,0 +1,49 @@
/*
* 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 */

View File

@@ -0,0 +1,315 @@
#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
#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
DDS_EXPORT dds_return_t
ddsrt_gethostname(
char *hostname,
size_t buffersize);
#endif
DDS_EXPORT dds_return_t
ddsrt_socket(
ddsrt_socket_t *sockptr,
int domain,
int type,
int protocol);
DDS_EXPORT dds_return_t
ddsrt_close(
ddsrt_socket_t sock);
DDS_EXPORT dds_return_t
ddsrt_connect(
ddsrt_socket_t sock,
const struct sockaddr *addr,
socklen_t addrlen);
DDS_EXPORT dds_return_t
ddsrt_accept(
ddsrt_socket_t sock,
struct sockaddr *addr,
socklen_t *addrlen,
ddsrt_socket_t *connptr);
DDS_EXPORT dds_return_t
ddsrt_listen(
ddsrt_socket_t sock,
int backlog);
DDS_EXPORT dds_return_t
ddsrt_bind(
ddsrt_socket_t sock,
const struct sockaddr *addr,
socklen_t addrlen);
DDS_EXPORT dds_return_t
ddsrt_getsockname(
ddsrt_socket_t sock,
struct sockaddr *addr,
socklen_t *addrlen);
DDS_EXPORT dds_return_t
ddsrt_send(
ddsrt_socket_t sock,
const void *buf,
size_t len,
int flags,
ssize_t *sent);
DDS_EXPORT dds_return_t
ddsrt_sendmsg(
ddsrt_socket_t sock,
const ddsrt_msghdr_t *msg,
int flags,
ssize_t *sent);
DDS_EXPORT dds_return_t
ddsrt_recv(
ddsrt_socket_t sock,
void *buf,
size_t len,
int flags,
ssize_t *rcvd);
DDS_EXPORT dds_return_t
ddsrt_recvmsg(
ddsrt_socket_t sock,
ddsrt_msghdr_t *msg,
int flags,
ssize_t *rcvd);
DDS_EXPORT dds_return_t
ddsrt_getsockopt(
ddsrt_socket_t sock,
int32_t level, /* SOL_SOCKET */
int32_t optname, /* SO_REUSEADDR, SO_DONTROUTE, SO_BROADCAST, SO_SNDBUF, SO_RCVBUF, ... */
void *optval,
socklen_t *optlen);
DDS_EXPORT dds_return_t
ddsrt_setsockopt(
ddsrt_socket_t sock,
int32_t level, /* SOL_SOCKET */
int32_t optname, /* SO_REUSEADDR, SO_DONTROUTE, SO_BROADCAST, SO_SNDBUF, SO_RCVBUF, ... */
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_EXPORT 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_EXPORT 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_EXPORT dds_return_t
ddsrt_select(
int32_t nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *errorfds,
dds_duration_t reltime);
#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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT 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.
*/
DDS_EXPORT bool
ddsrt_sockaddr_isunspecified(
const struct sockaddr *__restrict 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.
*/
DDS_EXPORT bool
ddsrt_sockaddr_isloopback(
const struct sockaddr *__restrict 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.
*/
DDS_EXPORT bool
ddsrt_sockaddr_insamesubnet(
const struct sockaddr *sa1,
const struct sockaddr *sa2,
const struct sockaddr *mask)
ddsrt_nonnull_all;
DDS_EXPORT dds_return_t
ddsrt_sockaddrfromstr(
int af, const char *str, void *sa);
DDS_EXPORT dds_return_t
ddsrt_sockaddrtostr(
const void *sa, char *buf, size_t size);
#if DDSRT_HAVE_DNS
DDSRT_WARNING_MSVC_OFF(4200)
typedef struct {
size_t naddrs;
struct sockaddr_storage addrs[];
} 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_EXPORT dds_return_t
ddsrt_gethostbyname(
const char *name,
int af,
ddsrt_hostent_t **hentp);
#endif
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_SOCKETS_H */

View File

@@ -0,0 +1,63 @@
/*
* 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
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.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"
#if LWIP_SOCKET
# define DDSRT_HAVE_SSM 0
# define IFF_UP 0x1
# define IFF_BROADCAST 0x2
# define IFF_LOOPBACK 0x8
# define IFF_POINTOPOINT 0x10
# define IFF_MULTICAST 0x1000
#elif __SunOS_5_6
# define DDSRT_HAVE_SSM 0
#else /* LWIP_SOCKET */
# define DDSRT_HAVE_SSM 1
#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 */

View File

@@ -0,0 +1,51 @@
#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
#if defined(NTDDI_VERSION) && \
defined(_WIN32_WINNT_WS03) && \
(NTDDI_VERSION >= _WIN32_WINNT_WS03)
#define DDSRT_HAVE_SSM 1
#else
#define DDSRT_HAVE_SSM 0
#endif
#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 */

View File

@@ -0,0 +1,42 @@
/*
* 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
#endif

View File

@@ -0,0 +1,200 @@
/*
* 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] ptr Pointer to block of memory to duplicate.
* @param[in] len 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 *ptr,
size_t len)
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 * __restrict dest,
const char * __restrict 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 * __restrict dest,
const char * __restrict 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;
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_STRING_H */

View File

@@ -0,0 +1,83 @@
/*
* 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.
*
* @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_EXPORT dds_return_t
ddsrt_strtod(const char *nptr, char **endptr, double *dblptr);
/**
* @brief Convert a string to a floating point number.
*
* @param[in] nptr A string to convert into a float.
* @param[in] endptr If not NULL, a char* where the address of first invalid
* character is stored.
* @param[out] fltptr A float where the floating-point number is stored.
*
* @returns A dds_return_t indicating success or failure.
*/
DDS_EXPORT dds_return_t
ddsrt_strtof(const char *nptr, char **endptr, float *fltptr);
/**
* @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).
*/
DDS_EXPORT 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).
*/
DDS_EXPORT int
ddsrt_ftostr(float src, char *str, size_t size);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_STRTOD_H */

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 */

View File

@@ -0,0 +1,302 @@
/*
* 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 */

View File

@@ -0,0 +1,93 @@
/*
* 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 */

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;
} 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 */

View File

@@ -0,0 +1,39 @@
/*
* 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 */

View File

@@ -0,0 +1,298 @@
/*
* 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*);
/**
* @brief Definition of the thread attributes
*/
typedef struct {
/** Specifies the scheduling class */
ddsrt_sched_t schedClass;
/** Specifies the thread priority */
int32_t schedPriority;
/** 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 *__restrict 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 *__restrict 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 * __restrict 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 *__restrict 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*),
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 */

View File

@@ -0,0 +1,37 @@
/*
* 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 */

View File

@@ -0,0 +1,73 @@
/*
* 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>
#if defined(__VXWORKS__)
#define DDSRT_HAVE_THREAD_SETNAME (0)
#else
#define DDSRT_HAVE_THREAD_SETNAME (1)
#endif
#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 PRIdPID PRIuPTR /* typedef struct windTcb *TASK_ID */
# else
# define PRIdPID "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 */

View File

@@ -0,0 +1,38 @@
/*
* 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 */

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 "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.
*/
DDS_INLINE_EXPORT 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 * __restrict sec, int32_t * __restrict 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 * __restrict sec, int32_t * __restrict 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 * __restrict sec, int32_t * __restrict usec, ddsrt_etime_t t);
#if defined(__cplusplus)
}
#endif
#if DDSRT_WITH_FREERTOS
#include "dds/ddsrt/time/freertos.h"
#endif
#endif /* DDSRT_TIME_H */

View File

@@ -0,0 +1,53 @@
/*
* 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 */

View File

@@ -0,0 +1,30 @@
/*
* 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 */

View File

@@ -0,0 +1,23 @@
/*
* 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 */

View File

@@ -0,0 +1,74 @@
/*
* 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 */

View File

@@ -0,0 +1,31 @@
/*
* 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>
typedef SSIZE_T ssize_t;
#endif /* DDSRT_TYPES_WINDOWS_H */

View File

@@ -0,0 +1,54 @@
/*
* 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
typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line);
typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line);
typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data, int line);
typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo, int line);
typedef void (*ddsrt_xmlp_error) (void *varg, const char *msg, int line);
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;
};
struct ddsrt_xmlp_state;
#define DDSRT_XMLP_REQUIRE_EOF 1u /* set by default; if not set, junk may follow top-level closing tag */
#define DDSRT_XMLP_ANONYMOUS_CLOSE_TAG 2u /* clear by default; if set allow closing an element with </> instead of </name> */
#define DDSRT_XMLP_MISSING_CLOSE_AS_EOF 4u /* clear by default; if set, treat missing close tag as EOF */
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_file (FILE *fp, void *varg, const struct ddsrt_xmlp_callbacks *cb);
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_string (const char *string, void *varg, const struct ddsrt_xmlp_callbacks *cb);
DDS_EXPORT void ddsrt_xmlp_set_options (struct ddsrt_xmlp_state *st, unsigned options);
DDS_EXPORT size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st);
DDS_EXPORT void ddsrt_xmlp_free (struct ddsrt_xmlp_state *st);
DDS_EXPORT int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st);
#if defined (__cplusplus)
}
#endif
#endif