From 453dc0ba1d2cc376029cbec6a92192d75175529f Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Thu, 7 Dec 2023 16:58:50 +0100 Subject: [PATCH 1/9] fix: set private z_atomic --- include/zenoh-pico/collections/pointer.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index 8e1fd54e0..cfdb82f50 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -22,7 +22,7 @@ #ifndef __cplusplus #include -#define z_atomic(X) _Atomic X +#define _z_atomic(X) _Atomic X #define _z_atomic_store_explicit atomic_store_explicit #define _z_atomic_fetch_add_explicit atomic_fetch_add_explicit #define _z_atomic_fetch_sub_explicit atomic_fetch_sub_explicit @@ -31,26 +31,26 @@ #define _z_memory_order_relaxed memory_order_relaxed #else #include -#define z_atomic(X) std::atomic +#define _z_atomic(X) std::atomic #define _z_atomic_store_explicit std::atomic_store_explicit #define _z_atomic_fetch_add_explicit std::atomic_fetch_add_explicit #define _z_atomic_fetch_sub_explicit std::atomic_fetch_sub_explicit #define _z_memory_order_acquire std::memory_order_acquire #define _z_memory_order_release std::memory_order_release #define _z_memory_order_relaxed std::memory_order_relaxed -#endif +#endif // __cplusplus /*------------------ Internal Array Macros ------------------*/ #define _Z_POINTER_DEFINE(name, type) \ typedef struct { \ type##_t *ptr; \ - z_atomic(unsigned int) * _cnt; \ + _z_atomic(unsigned int) * _cnt; \ } name##_sptr_t; \ static inline name##_sptr_t name##_sptr_new(type##_t val) { \ name##_sptr_t p; \ p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ if (p.ptr != NULL) { \ - p._cnt = (z_atomic(unsigned int) *)z_malloc(sizeof(z_atomic(unsigned int) *)); \ + p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ if (p._cnt != NULL) { \ *p.ptr = val; \ _z_atomic_store_explicit(p._cnt, 1, _z_memory_order_relaxed); \ @@ -150,6 +150,6 @@ } \ return dropped; \ } -#endif +#endif // ZENOH_C_STANDARD != 99 && !defined(ZENOH_NO_STDATOMIC) #endif /* ZENOH_PICO_COLLECTIONS_POINTER_H */ From e68987f11bf768b9c5d860214e146ad0264a0596 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Thu, 7 Dec 2023 16:59:02 +0100 Subject: [PATCH 2/9] feat: add refcount type (wip) --- include/zenoh-pico/collections/refcount.h | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 include/zenoh-pico/collections/refcount.h diff --git a/include/zenoh-pico/collections/refcount.h b/include/zenoh-pico/collections/refcount.h new file mode 100644 index 000000000..07b302b34 --- /dev/null +++ b/include/zenoh-pico/collections/refcount.h @@ -0,0 +1,67 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#ifndef ZENOH_PICO_COLLECTIONS_REFCOUNT_H +#define ZENOH_PICO_COLLECTIONS_REFCOUNT_H + +#include +#include + +#include "zenoh-pico/collections/pointer.h" + +typedef struct ref { + void (*free)(const struct ref *); + int count; +} _z_rc_t; + +#if Z_FEATURE_MULTI_THREAD == 1 +#if ZENOH_C_STANDARD != 99 +#if !defined(ZENOH_NO_STDATOMIC) + +#else +#error "Implement Windows atomics" +#endif // !defined(ZENOH_NO_STDATOMIC) + +static inline void ref_inc(const struct ref *ref) { + _z_atomic_fetch_add_explicit((int *)&ref->count, 1, _z_memory_order_relaxed); +} + +static inline void ref_dec(const struct ref *ref) { + if (_z_atomic_fetch_sub_explicit((int *)&ref->count, 1, _z_memory_order_relaxed) == 1) { + ref->free(ref); + } +} + +#else +// FIXME Check for Windows +static inline void ref_inc(const struct ref *ref) { __sync_add_and_fetch((int *)&ref->count, 1); } + +static inline void ref_dec(const struct ref *ref) { + if (__sync_sub_and_fetch((int *)&ref->count, 1) == 0) { + ref->free(ref); + } +} +#endif // ZENOH_C_STANDARD != 99 + +#else +static inline void ref_inc(const struct ref *ref) { ((struct ref *)ref)->count++; } + +static inline void ref_dec(const struct ref *ref) { + if (--((struct ref *)ref)->count == 0) { + ref->free(ref); + } +} +#endif // Z_FEATURE_MULTI_THREAD == 1 + +#endif // ZENOH_PICO_COLLECTIONS_REFCOUNT_H From 2d501ae19b4975cffee102d396a968723bf199a9 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Thu, 21 Dec 2023 09:36:52 +0100 Subject: [PATCH 3/9] fix: clang-format --- include/zenoh-pico/collections/pointer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index cfdb82f50..b4d66cd98 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -38,19 +38,19 @@ #define _z_memory_order_acquire std::memory_order_acquire #define _z_memory_order_release std::memory_order_release #define _z_memory_order_relaxed std::memory_order_relaxed -#endif // __cplusplus +#endif // __cplusplus /*------------------ Internal Array Macros ------------------*/ #define _Z_POINTER_DEFINE(name, type) \ typedef struct { \ type##_t *ptr; \ - _z_atomic(unsigned int) * _cnt; \ + _z_atomic(unsigned int) * _cnt; \ } name##_sptr_t; \ static inline name##_sptr_t name##_sptr_new(type##_t val) { \ name##_sptr_t p; \ p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ if (p.ptr != NULL) { \ - p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ + p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ if (p._cnt != NULL) { \ *p.ptr = val; \ _z_atomic_store_explicit(p._cnt, 1, _z_memory_order_relaxed); \ @@ -150,6 +150,6 @@ } \ return dropped; \ } -#endif // ZENOH_C_STANDARD != 99 && !defined(ZENOH_NO_STDATOMIC) +#endif // ZENOH_C_STANDARD != 99 && !defined(ZENOH_NO_STDATOMIC) #endif /* ZENOH_PICO_COLLECTIONS_POINTER_H */ From 04f2e918399bc91a71e468f4eda993ac44a2d7a9 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Thu, 21 Dec 2023 09:59:09 +0100 Subject: [PATCH 4/9] feat: supposedly, windows has c11 atomics now --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 426f85cc6..7a050f4be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten") add_definition(ZENOH_EMSCRIPTEN) elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") add_definition(ZENOH_WINDOWS) + # add_definition(ZENOH_NO_STDATOMIC) add_definition(_CRT_SECURE_NO_WARNINGS) - add_definition(ZENOH_NO_STDATOMIC) elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") if(WITH_ZEPHYR) add_definition(ZENOH_ZEPHYR) @@ -158,7 +158,10 @@ if(CMAKE_BUILD_TYPE MATCHES "DEBUG") if(UNIX) add_compile_options(-c -Wall -Wextra -Werror -Wshadow -Wpedantic -Wunused -Wstrict-prototypes -pipe -g -O0) elseif(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /std:c11 /experimental:c11atomics") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest /experimental:c11atomics") add_compile_options(/W4 /WX /Od) + message("C Flags: ${CMAKE_C_FLAGS}") elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -pipe -g -O0) endif() @@ -166,7 +169,8 @@ elseif(CMAKE_BUILD_TYPE MATCHES "RELEASE") if(UNIX) add_compile_options(-pipe -O3) elseif(MSVC) - # add_compile_options(/O2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /std:c11 /experimental:c11atomics") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest /experimental:c11atomics") elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") add_compile_options(-pipe -O3) endif() From d6c7a368f15a6558b39ca893dfbb2603f38d8445 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 22 Dec 2023 09:58:45 +0100 Subject: [PATCH 5/9] fix: add explicit type casting --- include/zenoh-pico/collections/pointer.h | 107 ++++++++++++----------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index b4d66cd98..90c2bbe8b 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -41,59 +41,60 @@ #endif // __cplusplus /*------------------ Internal Array Macros ------------------*/ -#define _Z_POINTER_DEFINE(name, type) \ - typedef struct { \ - type##_t *ptr; \ - _z_atomic(unsigned int) * _cnt; \ - } name##_sptr_t; \ - static inline name##_sptr_t name##_sptr_new(type##_t val) { \ - name##_sptr_t p; \ - p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ - if (p.ptr != NULL) { \ - p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ - if (p._cnt != NULL) { \ - *p.ptr = val; \ - _z_atomic_store_explicit(p._cnt, 1, _z_memory_order_relaxed); \ - } else { \ - z_free(p.ptr); \ - } \ - } \ - return p; \ - } \ - static inline name##_sptr_t name##_sptr_clone(name##_sptr_t *p) { \ - name##_sptr_t c; \ - c._cnt = p->_cnt; \ - c.ptr = p->ptr; \ - _z_atomic_fetch_add_explicit(p->_cnt, 1, _z_memory_order_relaxed); \ - return c; \ - } \ - static inline name##_sptr_t *name##_sptr_clone_as_ptr(name##_sptr_t *p) { \ - name##_sptr_t *c = (name##_sptr_t *)z_malloc(sizeof(name##_sptr_t)); \ - if (c != NULL) { \ - c->_cnt = p->_cnt; \ - c->ptr = p->ptr; \ - _z_atomic_fetch_add_explicit(p->_cnt, 1, _z_memory_order_relaxed); \ - } \ - return c; \ - } \ - static inline _Bool name##_sptr_eq(const name##_sptr_t *left, const name##_sptr_t *right) { \ - return (left->ptr == right->ptr); \ - } \ - static inline _Bool name##_sptr_drop(name##_sptr_t *p) { \ - _Bool dropped = false; \ - if (p->_cnt != NULL) { \ - unsigned int c = _z_atomic_fetch_sub_explicit(p->_cnt, 1, _z_memory_order_release); \ - dropped = c == 1; \ - if (dropped == true) { \ - atomic_thread_fence(_z_memory_order_acquire); \ - if (p->ptr != NULL) { \ - type##_clear(p->ptr); \ - z_free(p->ptr); \ - z_free(p->_cnt); \ - } \ - } \ - } \ - return dropped; \ +#define _Z_POINTER_DEFINE(name, type) \ + typedef struct { \ + type##_t *ptr; \ + _z_atomic(unsigned int) * _cnt; \ + } name##_sptr_t; \ + static inline name##_sptr_t name##_sptr_new(type##_t val) { \ + name##_sptr_t p; \ + p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ + if (p.ptr != NULL) { \ + p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ + if (p._cnt != NULL) { \ + *p.ptr = val; \ + _z_atomic_store_explicit((volatile unsigned int *)p._cnt, 1, _z_memory_order_relaxed); \ + } else { \ + z_free(p.ptr); \ + } \ + } \ + return p; \ + } \ + static inline name##_sptr_t name##_sptr_clone(name##_sptr_t *p) { \ + name##_sptr_t c; \ + c._cnt = p->_cnt; \ + c.ptr = p->ptr; \ + _z_atomic_fetch_add_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_relaxed); \ + return c; \ + } \ + static inline name##_sptr_t *name##_sptr_clone_as_ptr(name##_sptr_t *p) { \ + name##_sptr_t *c = (name##_sptr_t *)z_malloc(sizeof(name##_sptr_t)); \ + if (c != NULL) { \ + c->_cnt = p->_cnt; \ + c->ptr = p->ptr; \ + _z_atomic_fetch_add_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_relaxed); \ + } \ + return c; \ + } \ + static inline _Bool name##_sptr_eq(const name##_sptr_t *left, const name##_sptr_t *right) { \ + return (left->ptr == right->ptr); \ + } \ + static inline _Bool name##_sptr_drop(name##_sptr_t *p) { \ + _Bool dropped = false; \ + if (p->_cnt != NULL) { \ + unsigned int c = \ + _z_atomic_fetch_sub_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_release); \ + dropped = c == 1; \ + if (dropped == true) { \ + atomic_thread_fence(_z_memory_order_acquire); \ + if (p->ptr != NULL) { \ + type##_clear(p->ptr); \ + z_free(p->ptr); \ + z_free((void *)p->_cnt); \ + } \ + } \ + } \ + return dropped; \ } #else /*------------------ Internal Array Macros ------------------*/ From a802b2c5cfd9188560f9cc6a486eb3337259e952 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 22 Dec 2023 10:02:12 +0100 Subject: [PATCH 6/9] Revert "feat: add refcount type (wip)" This reverts commit e68987f11bf768b9c5d860214e146ad0264a0596. --- include/zenoh-pico/collections/refcount.h | 67 ----------------------- 1 file changed, 67 deletions(-) delete mode 100644 include/zenoh-pico/collections/refcount.h diff --git a/include/zenoh-pico/collections/refcount.h b/include/zenoh-pico/collections/refcount.h deleted file mode 100644 index 07b302b34..000000000 --- a/include/zenoh-pico/collections/refcount.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -#ifndef ZENOH_PICO_COLLECTIONS_REFCOUNT_H -#define ZENOH_PICO_COLLECTIONS_REFCOUNT_H - -#include -#include - -#include "zenoh-pico/collections/pointer.h" - -typedef struct ref { - void (*free)(const struct ref *); - int count; -} _z_rc_t; - -#if Z_FEATURE_MULTI_THREAD == 1 -#if ZENOH_C_STANDARD != 99 -#if !defined(ZENOH_NO_STDATOMIC) - -#else -#error "Implement Windows atomics" -#endif // !defined(ZENOH_NO_STDATOMIC) - -static inline void ref_inc(const struct ref *ref) { - _z_atomic_fetch_add_explicit((int *)&ref->count, 1, _z_memory_order_relaxed); -} - -static inline void ref_dec(const struct ref *ref) { - if (_z_atomic_fetch_sub_explicit((int *)&ref->count, 1, _z_memory_order_relaxed) == 1) { - ref->free(ref); - } -} - -#else -// FIXME Check for Windows -static inline void ref_inc(const struct ref *ref) { __sync_add_and_fetch((int *)&ref->count, 1); } - -static inline void ref_dec(const struct ref *ref) { - if (__sync_sub_and_fetch((int *)&ref->count, 1) == 0) { - ref->free(ref); - } -} -#endif // ZENOH_C_STANDARD != 99 - -#else -static inline void ref_inc(const struct ref *ref) { ((struct ref *)ref)->count++; } - -static inline void ref_dec(const struct ref *ref) { - if (--((struct ref *)ref)->count == 0) { - ref->free(ref); - } -} -#endif // Z_FEATURE_MULTI_THREAD == 1 - -#endif // ZENOH_PICO_COLLECTIONS_REFCOUNT_H From 5c18a75ab2d63683d37e56baae253c56967c0db0 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 22 Dec 2023 10:05:17 +0100 Subject: [PATCH 7/9] build: remove print --- CMakeLists.txt | 2 -- include/zenoh-pico/collections/pointer.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a050f4be..030a8020d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,6 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten") add_definition(ZENOH_EMSCRIPTEN) elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") add_definition(ZENOH_WINDOWS) - # add_definition(ZENOH_NO_STDATOMIC) add_definition(_CRT_SECURE_NO_WARNINGS) elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") if(WITH_ZEPHYR) @@ -161,7 +160,6 @@ if(CMAKE_BUILD_TYPE MATCHES "DEBUG") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /std:c11 /experimental:c11atomics") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest /experimental:c11atomics") add_compile_options(/W4 /WX /Od) - message("C Flags: ${CMAKE_C_FLAGS}") elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -pipe -g -O0) endif() diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index 90c2bbe8b..b0627831f 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -90,7 +90,7 @@ if (p->ptr != NULL) { \ type##_clear(p->ptr); \ z_free(p->ptr); \ - z_free((void *)p->_cnt); \ + z_free((void *)p->_cnt); \ } \ } \ } \ From e6e8798860381cb3eb1e08c6c3312dc159ab95b3 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 22 Dec 2023 10:07:35 +0100 Subject: [PATCH 8/9] fix: remove obsolete compile symbol --- include/zenoh-pico/collections/pointer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index b0627831f..e63fc01d6 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -18,7 +18,7 @@ #include #include -#if ZENOH_C_STANDARD != 99 && !defined(ZENOH_NO_STDATOMIC) +#if ZENOH_C_STANDARD != 99 #ifndef __cplusplus #include @@ -151,6 +151,6 @@ } \ return dropped; \ } -#endif // ZENOH_C_STANDARD != 99 && !defined(ZENOH_NO_STDATOMIC) +#endif // ZENOH_C_STANDARD != 99 #endif /* ZENOH_PICO_COLLECTIONS_POINTER_H */ From 342fcce82ea167406bc57d651b62b4179833d84a Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 22 Dec 2023 10:15:27 +0100 Subject: [PATCH 9/9] fix: revert type casting --- include/zenoh-pico/collections/pointer.h | 107 +++++++++++------------ 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/include/zenoh-pico/collections/pointer.h b/include/zenoh-pico/collections/pointer.h index e63fc01d6..9dc4c4859 100644 --- a/include/zenoh-pico/collections/pointer.h +++ b/include/zenoh-pico/collections/pointer.h @@ -41,60 +41,59 @@ #endif // __cplusplus /*------------------ Internal Array Macros ------------------*/ -#define _Z_POINTER_DEFINE(name, type) \ - typedef struct { \ - type##_t *ptr; \ - _z_atomic(unsigned int) * _cnt; \ - } name##_sptr_t; \ - static inline name##_sptr_t name##_sptr_new(type##_t val) { \ - name##_sptr_t p; \ - p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ - if (p.ptr != NULL) { \ - p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ - if (p._cnt != NULL) { \ - *p.ptr = val; \ - _z_atomic_store_explicit((volatile unsigned int *)p._cnt, 1, _z_memory_order_relaxed); \ - } else { \ - z_free(p.ptr); \ - } \ - } \ - return p; \ - } \ - static inline name##_sptr_t name##_sptr_clone(name##_sptr_t *p) { \ - name##_sptr_t c; \ - c._cnt = p->_cnt; \ - c.ptr = p->ptr; \ - _z_atomic_fetch_add_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_relaxed); \ - return c; \ - } \ - static inline name##_sptr_t *name##_sptr_clone_as_ptr(name##_sptr_t *p) { \ - name##_sptr_t *c = (name##_sptr_t *)z_malloc(sizeof(name##_sptr_t)); \ - if (c != NULL) { \ - c->_cnt = p->_cnt; \ - c->ptr = p->ptr; \ - _z_atomic_fetch_add_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_relaxed); \ - } \ - return c; \ - } \ - static inline _Bool name##_sptr_eq(const name##_sptr_t *left, const name##_sptr_t *right) { \ - return (left->ptr == right->ptr); \ - } \ - static inline _Bool name##_sptr_drop(name##_sptr_t *p) { \ - _Bool dropped = false; \ - if (p->_cnt != NULL) { \ - unsigned int c = \ - _z_atomic_fetch_sub_explicit((volatile unsigned int *)p->_cnt, 1, _z_memory_order_release); \ - dropped = c == 1; \ - if (dropped == true) { \ - atomic_thread_fence(_z_memory_order_acquire); \ - if (p->ptr != NULL) { \ - type##_clear(p->ptr); \ - z_free(p->ptr); \ - z_free((void *)p->_cnt); \ - } \ - } \ - } \ - return dropped; \ +#define _Z_POINTER_DEFINE(name, type) \ + typedef struct { \ + type##_t *ptr; \ + _z_atomic(unsigned int) * _cnt; \ + } name##_sptr_t; \ + static inline name##_sptr_t name##_sptr_new(type##_t val) { \ + name##_sptr_t p; \ + p.ptr = (type##_t *)z_malloc(sizeof(type##_t)); \ + if (p.ptr != NULL) { \ + p._cnt = (_z_atomic(unsigned int) *)z_malloc(sizeof(_z_atomic(unsigned int) *)); \ + if (p._cnt != NULL) { \ + *p.ptr = val; \ + _z_atomic_store_explicit(p._cnt, 1, _z_memory_order_relaxed); \ + } else { \ + z_free(p.ptr); \ + } \ + } \ + return p; \ + } \ + static inline name##_sptr_t name##_sptr_clone(name##_sptr_t *p) { \ + name##_sptr_t c; \ + c._cnt = p->_cnt; \ + c.ptr = p->ptr; \ + _z_atomic_fetch_add_explicit(p->_cnt, 1, _z_memory_order_relaxed); \ + return c; \ + } \ + static inline name##_sptr_t *name##_sptr_clone_as_ptr(name##_sptr_t *p) { \ + name##_sptr_t *c = (name##_sptr_t *)z_malloc(sizeof(name##_sptr_t)); \ + if (c != NULL) { \ + c->_cnt = p->_cnt; \ + c->ptr = p->ptr; \ + _z_atomic_fetch_add_explicit(p->_cnt, 1, _z_memory_order_relaxed); \ + } \ + return c; \ + } \ + static inline _Bool name##_sptr_eq(const name##_sptr_t *left, const name##_sptr_t *right) { \ + return (left->ptr == right->ptr); \ + } \ + static inline _Bool name##_sptr_drop(name##_sptr_t *p) { \ + _Bool dropped = false; \ + if (p->_cnt != NULL) { \ + unsigned int c = _z_atomic_fetch_sub_explicit(p->_cnt, 1, _z_memory_order_release); \ + dropped = c == 1; \ + if (dropped == true) { \ + atomic_thread_fence(_z_memory_order_acquire); \ + if (p->ptr != NULL) { \ + type##_clear(p->ptr); \ + z_free(p->ptr); \ + z_free((void *)p->_cnt); \ + } \ + } \ + } \ + return dropped; \ } #else /*------------------ Internal Array Macros ------------------*/