summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-09-24 07:56:47 +0200
committerTyge Løvset <[email protected]>2020-09-24 07:56:47 +0200
commit0ca173d91a5d75b3f4939766085129d394085d0b (patch)
treecc79e3f769cbe9d9989bc07c12c16c5e47a928d8
parent31ec9ba3359864a780ac64f53acee33fb5cb2b5a (diff)
downloadSTC-modified-0ca173d91a5d75b3f4939766085129d394085d0b.tar.gz
STC-modified-0ca173d91a5d75b3f4939766085129d394085d0b.zip
Improved csptr.h
-rw-r--r--stc/csptr.h55
1 files 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 <intrin.h>
+ 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); \
} \
} \
\