From fa79e56bce051e43cbd236c96039b528b1f4ae98 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 26 Sep 2020 09:12:17 +0200 Subject: Merged csptr.h into cptr.h, simpler with one include file and these are very related and short. --- examples/share_ptr.c | 2 +- examples/share_ptr2.c | 2 +- stc/cptr.h | 107 +++++++++++++++++++++++++++++++++++++++++ stc/csptr.h | 131 -------------------------------------------------- 4 files changed, 109 insertions(+), 133 deletions(-) delete mode 100644 stc/csptr.h diff --git a/examples/share_ptr.c b/examples/share_ptr.c index 9b412d93..5f5a0cc7 100644 --- a/examples/share_ptr.c +++ b/examples/share_ptr.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/examples/share_ptr2.c b/examples/share_ptr2.c index 726a9bc0..1b90f49e 100644 --- a/examples/share_ptr2.c +++ b/examples/share_ptr2.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/stc/cptr.h b/stc/cptr.h index f8edb0d4..c4421a37 100644 --- a/stc/cptr.h +++ b/stc/cptr.h @@ -87,5 +87,112 @@ int main() { } \ typedef int cptr_##X##_dud4 + + + +/* csptr: std::shared_ptr -like type: */ +/* +#include +#include + +typedef struct { cstr_t name, last; } Person; + +Person* Person_make(Person* p, const char* name, const char* last) { + p->name = cstr(name), p->last = cstr(last); + return p; +} +void Person_del(Person* p) { + printf("del: %s\n", p->name.str); + c_del(cstr, &p->name, &p->last); +} + +using_csptr(pe, Person, Person_del); + +int main() { + csptr_pe p = csptr_pe_make(Person_make(c_new(Person), "Joe", "Jordan")); + csptr_pe q = csptr_pe_share(p); // share the pointer + + printf("%s %s: %d\n", q.get->name.str, q.get->last.str, *q.use_count); + c_del(csptr_pe, &p, &q); +} +*/ +typedef long atomic_count_t; +#if defined(__GNUC__) || defined(__clang__) + static inline void atomic_increment(atomic_count_t* pw) {__atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);} + static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);} +#elif defined(_MSC_VER) + #include + static inline void atomic_increment(atomic_count_t* pw) {_InterlockedIncrement(pw);} + static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return _InterlockedDecrement(pw);} +#elif defined(__i386__) || defined(__x86_64__) + static inline void atomic_increment(atomic_count_t* pw) { + __asm__ ( + "lock\n\t" + "incl %0": + "=m"( *pw ): // ++*pw // output (%0) + "m"( *pw ): // input (%1) + "cc" // clobbers + ); + } + static inline atomic_count_t atomic_decrement(atomic_count_t* pw) { + int r; + __asm__ __volatile__ ( + "lock\n\t" + "xadd %1, %0": + "=m"( *pw ), "=r"( r ): // int r = *pw; // outputs (%0, %1) + "m"( *pw ), "1"( -1 ): // *pw += -1; // inputs (%2, %3 == %1) + "memory", "cc" // clobbers + ); + return r - 1; + } +#endif + +#define using_csptr(...) c_MACRO_OVERLOAD(using_csptr, __VA_ARGS__) + +#define using_csptr_2(X, Value) \ + using_csptr_3(X, Value, c_default_del) + +#define using_csptr_3(X, Value, valueDestroy) \ + typedef Value csptr_##X##_value_t; \ + typedef struct { csptr_##X##_value_t* get; atomic_count_t* use_count; } csptr_##X; \ +\ + STC_INLINE csptr_##X \ + csptr_##X##_make(csptr_##X##_value_t* p) { \ + csptr_##X ptr = {p}; \ + if (p) *(ptr.use_count = c_new_1(atomic_count_t)) = 1; \ + return ptr; \ + } \ + STC_INLINE csptr_##X \ + csptr_##X##_share(csptr_##X ptr) { \ + if (ptr.use_count) atomic_increment(ptr.use_count); \ + return ptr; \ + } \ +\ + STC_INLINE void \ + csptr_##X##_del(csptr_##X* self) { \ + if (self->use_count && atomic_decrement(self->use_count) == 0) { \ + c_free(self->use_count); \ + valueDestroy(self->get); \ + c_free(self->get); \ + } \ + } \ + STC_INLINE void \ + csptr_##X##_reset(csptr_##X* self, csptr_##X##_value_t* p) { \ + csptr_##X##_del(self); \ + *self = csptr_##X##_make(p); \ + } \ +\ + typedef csptr_##X csptr_##X##_t + + +#define using_csptr_4(X, Value, valueDestroy, valueCompare) \ + using_csptr_3(X, Value, valueDestroy); \ + STC_INLINE int \ + csptr_##X##_compare(csptr_##X* x, csptr_##X* y) { \ + return valueCompare(x->get, y->get); \ + } \ + typedef int csptr_##X##_dud4 + + #endif \ No newline at end of file diff --git a/stc/csptr.h b/stc/csptr.h deleted file mode 100644 index 5089ca36..00000000 --- a/stc/csptr.h +++ /dev/null @@ -1,131 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CSPTR__H__ -#define CSPTR__H__ - -#include "cdefs.h" - -/* csptr: std::shared_ptr -like type: */ -/* -#include -#include - -typedef struct { cstr_t name, last; } Person; - -Person* Person_make(Person* p, const char* name, const char* last) { - p->name = cstr(name), p->last = cstr(last); - return p; -} -void Person_del(Person* p) { - printf("del: %s\n", p->name.str); - c_del(cstr, &p->name, &p->last); -} - -using_csptr(pe, Person, Person_del); - -int main() { - csptr_pe p = csptr_pe_make(Person_make(c_new(Person), "Joe", "Jordan")); - csptr_pe q = csptr_pe_share(p); // share the pointer - - printf("%s %s: %d\n", q.get->name.str, q.get->last.str, *q.use_count); - c_del(csptr_pe, &p, &q); -} -*/ -typedef long atomic_count_t; -#if defined(__GNUC__) || defined(__clang__) - static inline void atomic_increment(atomic_count_t* pw) {__atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);} - static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);} -#elif defined(_MSC_VER) - #include - static inline void atomic_increment(atomic_count_t* pw) {_InterlockedIncrement(pw);} - static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return _InterlockedDecrement(pw);} -#elif defined(__i386__) || defined(__x86_64__) - static inline void atomic_increment(atomic_count_t* pw) { - __asm__ ( - "lock\n\t" - "incl %0": - "=m"( *pw ): // ++*pw // output (%0) - "m"( *pw ): // input (%1) - "cc" // clobbers - ); - } - static inline atomic_count_t atomic_decrement(atomic_count_t* pw) { - int r; - __asm__ __volatile__ ( - "lock\n\t" - "xadd %1, %0": - "=m"( *pw ), "=r"( r ): // int r = *pw; // outputs (%0, %1) - "m"( *pw ), "1"( -1 ): // *pw += -1; // inputs (%2, %3 == %1) - "memory", "cc" // clobbers - ); - return r - 1; - } -#endif - -#define using_csptr(...) c_MACRO_OVERLOAD(using_csptr, __VA_ARGS__) - -#define using_csptr_2(X, Value) \ - using_csptr_3(X, Value, c_default_del) - -#define using_csptr_3(X, Value, valueDestroy) \ - typedef Value csptr_##X##_value_t; \ - typedef struct { csptr_##X##_value_t* get; atomic_count_t* use_count; } csptr_##X; \ -\ - STC_INLINE csptr_##X \ - csptr_##X##_make(csptr_##X##_value_t* p) { \ - csptr_##X ptr = {p}; \ - if (p) *(ptr.use_count = c_new_1(atomic_count_t)) = 1; \ - return ptr; \ - } \ - STC_INLINE csptr_##X \ - csptr_##X##_share(csptr_##X ptr) { \ - if (ptr.use_count) atomic_increment(ptr.use_count); \ - return ptr; \ - } \ -\ - STC_INLINE void \ - csptr_##X##_del(csptr_##X* self) { \ - if (self->use_count && atomic_decrement(self->use_count) == 0) { \ - c_free(self->use_count); \ - valueDestroy(self->get); \ - c_free(self->get); \ - } \ - } \ - STC_INLINE void \ - csptr_##X##_reset(csptr_##X* self, csptr_##X##_value_t* p) { \ - csptr_##X##_del(self); \ - *self = csptr_##X##_make(p); \ - } \ -\ - typedef csptr_##X csptr_##X##_t - - -#define using_csptr_4(X, Value, valueDestroy, valueCompare) \ - using_csptr_3(X, Value, valueDestroy); \ - STC_INLINE int \ - csptr_##X##_compare(csptr_##X* x, csptr_##X* y) { \ - return valueCompare(x->get, y->get); \ - } \ - typedef int csptr_##X##_dud4 - -#endif -- cgit v1.2.3