From 0ca173d91a5d75b3f4939766085129d394085d0b Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 24 Sep 2020 07:56:47 +0200 Subject: Improved csptr.h --- stc/csptr.h | 55 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/stc/csptr.h b/stc/csptr.h index 8e09f36e..13c6b3ad 100644 --- a/stc/csptr.h +++ b/stc/csptr.h @@ -32,6 +32,10 @@ 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); @@ -40,29 +44,22 @@ void Person_del(Person* p) { using_csptr(pe, Person, Person_del); int main() { - csptr_pe p = csptr_pe_make(c_new(Person)); - p.get->name = cstr("Joe"); - p.get->last = cstr("Jordan"); + csptr_pe p = csptr_pe_make(Person_make(c_new(Person), "Joe", "Jordan")); + csptr_pe q = csptr_pe_share(p); // share the pointer - csptr_pe q = csptr_pe_ref(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 int atomic_count_t; -#if defined(__i386__) || defined(__x86_64__) - static inline atomic_count_t atomic_exchange_and_add(atomic_count_t* pw, int dv) { - int r; - __asm__ __volatile__ ( - "lock\n\t" - "xadd %1, %0": - "=m"( *pw ), "=r"( r ): // int r = *pw; // outputs (%0, %1) - "m"( *pw ), "1"( dv ): // *pw += dv; // inputs (%2, %3 == %1) - "memory", "cc" // clobbers - ); - return r; - } +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" @@ -73,11 +70,16 @@ typedef int atomic_count_t; ); } static inline atomic_count_t atomic_decrement(atomic_count_t* pw) { - return atomic_exchange_and_add(pw, -1) - 1; // (pw, 1) + 1; + 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; } -#else - static inline void atomic_increment(atomic_count_t* pw) {++*pw;} - static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return --*pw;} #endif @@ -93,12 +95,17 @@ typedef int atomic_count_t; } \ \ STC_INLINE csptr_##X \ - csptr_##X##_ref(csptr_##X ptr) {if (ptr.get) atomic_increment(ptr.use_count); return ptr;} \ + csptr_##X##_share(csptr_##X ptr) { \ + if (ptr.get) 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); \ + c_free(self->use_count); \ + valueDestroy(self->get); \ + c_free(self->get); \ } \ } \ \ -- cgit v1.2.3