From cde7c39de3492f8b701038af6563a6c4e01ff558 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 26 Nov 2021 11:08:57 +0100 Subject: Bugfix of c_atomic_decrement() asm version in csptr.h. Some cleanup --- examples/random.c | 4 ++-- examples/read.c | 6 +++--- examples/sptr_pthread.c | 8 ++++---- include/stc/csptr.h | 9 +++------ 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/examples/random.c b/examples/random.c index d4a12a27..81fe71c5 100644 --- a/examples/random.c +++ b/examples/random.c @@ -4,7 +4,7 @@ int main() { - const size_t N = 5000000000; + const size_t N = 1000000000; const uint64_t seed = time(NULL), range = 1000000; stc64_t rng = stc64_init(seed); @@ -39,4 +39,4 @@ int main() diff = clock() - before; printf("biased 0-%zu \t: %f secs, %zu, avg: %f\n", range, (float) diff / CLOCKS_PER_SEC, N, (double) sum / N); -} \ No newline at end of file +} diff --git a/examples/read.c b/examples/read.c index 728bf579..4e670a10 100644 --- a/examples/read.c +++ b/examples/read.c @@ -6,9 +6,9 @@ cvec_str read_file(const char* name) { cvec_str vec = cvec_str_init(); c_autovar (FILE* f = fopen(name, "r"), fclose(f)) - c_auto (cstr, line) - while (cstr_getline(&line, f)) - cvec_str_emplace_back(&vec, line.str); + c_autovar (cstr line = cstr_init(), cstr_del(&line)) + while (cstr_getline(&line, f)) + cvec_str_emplace_back(&vec, line.str); return vec; } diff --git a/examples/sptr_pthread.c b/examples/sptr_pthread.c index 63b9a7a4..cffafd3d 100644 --- a/examples/sptr_pthread.c +++ b/examples/sptr_pthread.c @@ -25,7 +25,7 @@ void* thr(csptr_base* lp) c_autoscope (pthread_mutex_lock(&mtx), pthread_mutex_unlock(&mtx)) { printf("local pointer in a thread:\n" - " p.get() = %p, p.use_count() = %zu\n", (void*)lp->get, *lp->use_count); + " p.get() = %p, p.use_count() = %ld\n", (void*)lp->get, *lp->use_count); } /* atomically decrease ref. */ csptr_base_del(lp); @@ -37,7 +37,7 @@ int main() csptr_base p = csptr_base_make((Base){42}); printf("Created a Base\n" - " p.get() = %p, p.use_count() = %zu\n", (void*)p.get, *p.use_count); + " p.get() = %p, p.use_count() = %ld\n", (void*)p.get, *p.use_count); enum {N = 3}; pthread_t t[N]; csptr_base c[N]; @@ -48,7 +48,7 @@ int main() printf("Shared ownership between %d threads and released\n" "ownership from main:\n" - " p.get() = %p, p.use_count() = %zu\n", N, (void*)p.get, *p.use_count); + " p.get() = %p, p.use_count() = %ld\n", N, (void*)p.get, *p.use_count); csptr_base_reset(&p); c_forrange (i, N) pthread_join(t[i], NULL); @@ -57,4 +57,4 @@ int main() #else int main() {} -#endif \ No newline at end of file +#endif diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 7415c20a..b702f461 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -65,11 +65,8 @@ typedef long atomic_count_t; #elif defined(__i386__) || defined(__x86_64__) STC_INLINE void c_atomic_increment(atomic_count_t* v) { __asm__ __volatile__("lock; incq %0" :"=m"(*v) :"m"(*v)); } - STC_INLINE atomic_count_t c_atomic_decrement(atomic_count_t* v) { - atomic_count_t r; - __asm__ __volatile__("lock; xadd %0, %1" :"=r"(r) :"m"(*v), "0"(-1)); - return r - 1; - } + STC_INLINE atomic_count_t c_atomic_decrement(atomic_count_t* v) + { __asm__ __volatile__("lock; decq %0" :"=m"(*v) :"m"(*v)); return *v; } #endif #define csptr_null {NULL, NULL} @@ -181,4 +178,4 @@ _cx_memb(_compare)(const _cx_self* x, const _cx_self* y) { #undef cx_increment #undef cx_decrement #undef i_nonatomic -#include "template.h" \ No newline at end of file +#include "template.h" -- cgit v1.2.3 From 30f6b34e1d1451f08a652b940d3ff3e1b9adc1e4 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 26 Nov 2021 11:57:10 +0100 Subject: Fixed atomic_decrement final. --- include/stc/csptr.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/stc/csptr.h b/include/stc/csptr.h index b702f461..10063bcd 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -57,16 +57,19 @@ int main() { typedef long atomic_count_t; #if defined(__GNUC__) || defined(__clang__) #define c_atomic_increment(v) (void)__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST) - #define c_atomic_decrement(v) __atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST) + #define c_atomic_decrement(v) (bool)__atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST) #elif defined(_MSC_VER) #include #define c_atomic_increment(v) (void)_InterlockedIncrement(v) - #define c_atomic_decrement(v) _InterlockedDecrement(v) + #define c_atomic_decrement(v) (bool)_InterlockedDecrement(v) #elif defined(__i386__) || defined(__x86_64__) STC_INLINE void c_atomic_increment(atomic_count_t* v) - { __asm__ __volatile__("lock; incq %0" :"=m"(*v) :"m"(*v)); } - STC_INLINE atomic_count_t c_atomic_decrement(atomic_count_t* v) - { __asm__ __volatile__("lock; decq %0" :"=m"(*v) :"m"(*v)); return *v; } + { asm volatile("lock; incq %0" :"=m"(*v) :"m"(*v)); } + STC_INLINE bool c_atomic_decrement(atomic_count_t* v) { + unsigned char c; + asm volatile("lock; decq %0; sete %1" :"=m"(*v), "=qm"(c) :"m"(*v) :"memory"); + return !c; + } #endif #define csptr_null {NULL, NULL} -- cgit v1.2.3 From 8d871133ee563faca037f7d3b13f81153ee340a8 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 26 Nov 2021 14:16:37 +0100 Subject: internal renamings --- include/stc/cmap.h | 60 ++++++++++++++++++++++----------------------- include/stc/csmap.h | 70 ++++++++++++++++++++++++++--------------------------- include/stc/csptr.h | 39 +++++++++++++++-------------- 3 files changed, 84 insertions(+), 85 deletions(-) diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 979f1b44..e0d132ba 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -62,28 +62,28 @@ typedef struct { MAP_SIZE_T idx; uint_fast8_t hx; } chash_bucket_t; #define i_prefix cmap_ #endif #ifdef i_isset - #define cx_MAP_ONLY c_false - #define cx_SET_ONLY c_true - #define cx_keyref(vp) (vp) + #define _i_MAP_ONLY c_false + #define _i_SET_ONLY c_true + #define _i_keyref(vp) (vp) #else - #define cx_MAP_ONLY c_true - #define cx_SET_ONLY c_false - #define cx_keyref(vp) (&(vp)->first) + #define _i_MAP_ONLY c_true + #define _i_SET_ONLY c_false + #define _i_keyref(vp) (&(vp)->first) #endif #include "template.h" #ifndef i_fwd -_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, cx_MAP_ONLY, cx_SET_ONLY); +_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY); #endif -cx_MAP_ONLY( struct _cx_value { +_i_MAP_ONLY( struct _cx_value { _cx_key first; _cx_mapped second; }; ) typedef i_keyraw _cx_rawkey; typedef i_valraw _cx_memb(_rawmapped); -typedef cx_SET_ONLY( i_keyraw ) - cx_MAP_ONLY( struct { i_keyraw first; +typedef _i_SET_ONLY( i_keyraw ) + _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) _cx_rawvalue; @@ -108,7 +108,7 @@ STC_INLINE void _cx_memb(_swap)(_cx_self *map1, _cx_self *map2) {c_swap( STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) { return self->size && self->_hashx[_cx_memb(_bucket_)(self, &rkey).idx]; } -cx_MAP_ONLY( +_i_MAP_ONLY( STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped); STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); @@ -127,37 +127,37 @@ cx_MAP_ONLY( STC_INLINE void _cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) { - *cx_keyref(_dst) = i_keyfrom(i_keyto(cx_keyref(_val))); - cx_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); ) + *_i_keyref(_dst) = i_keyfrom(i_keyto(_i_keyref(_val))); + _i_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); ) } STC_INLINE _cx_rawvalue _cx_memb(_value_toraw)(_cx_value* val) { - return cx_SET_ONLY( i_keyto(val) ) - cx_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} ); + return _i_SET_ONLY( i_keyto(val) ) + _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} ); } STC_INLINE void _cx_memb(_value_del)(_cx_value* _val) { - i_keydel(cx_keyref(_val)); - cx_MAP_ONLY( i_valdel(&_val->second); ) + i_keydel(_i_keyref(_val)); + _i_MAP_ONLY( i_valdel(&_val->second); ) } STC_INLINE _cx_result -_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) { +_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { _cx_result _res = _cx_memb(_insert_entry_)(self, rkey); if (_res.inserted) { - *cx_keyref(_res.ref) = i_keyfrom(rkey); - cx_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); ) + *_i_keyref(_res.ref) = i_keyfrom(rkey); + _i_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); ) } return _res; } STC_INLINE _cx_result -_cx_memb(_insert)(_cx_self* self, i_key _key cx_MAP_ONLY(, i_val _mapped)) { +_cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) { _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key)); - if (_res.inserted) { *cx_keyref(_res.ref) = _key; cx_MAP_ONLY( _res.ref->second = _mapped; )} - else { i_keydel(&_key); cx_MAP_ONLY( i_valdel(&_mapped); )} + if (_res.inserted) { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )} + else { i_keydel(&_key); _i_MAP_ONLY( i_valdel(&_mapped); )} return _res; } @@ -258,7 +258,7 @@ STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); } -cx_MAP_ONLY( +_i_MAP_ONLY( STC_DEF _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) { _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key)); @@ -284,7 +284,7 @@ _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) { const uint8_t* _hashx = self->_hashx; while ((_hx = _hashx[b.idx])) { if (_hx == b.hx) { - _cx_rawkey _raw = i_keyto(cx_keyref(self->table + b.idx)); + _cx_rawkey _raw = i_keyto(_i_keyref(self->table + b.idx)); if (i_equ(&_raw, rkeyptr)) break; } if (++b.idx == _cap) b.idx = 0; @@ -337,7 +337,7 @@ _cx_memb(_reserve)(_cx_self* self, const size_t _newcap) { _cx_value* e = _tmp.table, *_slot = self->table; uint8_t* _hashx = self->_hashx; for (size_t i = 0; i < _oldbuckets; ++i, ++e) if (_tmp._hashx[i]) { - _cx_rawkey _raw = i_keyto(cx_keyref(e)); + _cx_rawkey _raw = i_keyto(_i_keyref(e)); chash_bucket_t b = _cx_memb(_bucket_)(self, &_raw); _slot[b.idx] = *e; _hashx[b.idx] = (uint8_t) b.hx; @@ -359,7 +359,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { if (++j == _cap) j = 0; if (! _hashx[j]) break; - _cx_rawkey _raw = i_keyto(cx_keyref(_slot + j)); + _cx_rawkey _raw = i_keyto(_i_keyref(_slot + j)); k = c_PASTE(fastrange_,MAP_SIZE_T)(i_hash(&_raw, sizeof _raw), _cap); if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ _slot[i] = _slot[j], _hashx[i] = _hashx[j], i = j; @@ -370,8 +370,8 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { #endif // TEMPLATED IMPLEMENTATION #undef i_isset -#undef cx_keyref -#undef cx_MAP_ONLY -#undef cx_SET_ONLY +#undef _i_keyref +#undef _i_MAP_ONLY +#undef _i_SET_ONLY #include "template.h" #define CMAP_H_INCLUDED diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 279bdf6d..99c4c97a 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -63,21 +63,21 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #define i_prefix csmap_ #endif #ifdef i_isset - #define cx_MAP_ONLY c_false - #define cx_SET_ONLY c_true - #define cx_keyref(vp) (vp) + #define _i_MAP_ONLY c_false + #define _i_SET_ONLY c_true + #define _i_keyref(vp) (vp) #else - #define cx_MAP_ONLY c_true - #define cx_SET_ONLY c_false - #define cx_keyref(vp) (&(vp)->first) + #define _i_MAP_ONLY c_true + #define _i_SET_ONLY c_false + #define _i_keyref(vp) (&(vp)->first) #endif #include "template.h" #ifndef i_fwd -_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, cx_MAP_ONLY, cx_SET_ONLY); +_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY); #endif -cx_MAP_ONLY( struct _cx_value { +_i_MAP_ONLY( struct _cx_value { _cx_key first; _cx_mapped second; }; ) @@ -89,8 +89,8 @@ struct _cx_node { typedef i_keyraw _cx_rawkey; typedef i_valraw _cx_memb(_rawmapped); -typedef cx_SET_ONLY( i_keyraw ) - cx_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) +typedef _i_SET_ONLY( i_keyraw ) + _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) _cx_rawvalue; STC_API _cx_self _cx_memb(_init)(void); @@ -134,23 +134,23 @@ _cx_memb(_copy)(_cx_self *self, _cx_self other) { STC_INLINE _cx_rawvalue _cx_memb(_value_toraw)(_cx_value* val) { - return cx_SET_ONLY( i_keyto(val) ) - cx_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} ); + return _i_SET_ONLY( i_keyto(val) ) + _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} ); } STC_INLINE void _cx_memb(_value_del)(_cx_value* val) { - i_keydel(cx_keyref(val)); - cx_MAP_ONLY( i_valdel(&val->second); ) + i_keydel(_i_keyref(val)); + _i_MAP_ONLY( i_valdel(&val->second); ) } STC_INLINE void _cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) { - *cx_keyref(dst) = i_keyfrom(i_keyto(cx_keyref(val))); - cx_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); ) + *_i_keyref(dst) = i_keyfrom(i_keyto(_i_keyref(val))); + _i_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); ) } -cx_MAP_ONLY( +_i_MAP_ONLY( STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped); STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); @@ -171,20 +171,20 @@ _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) { } STC_INLINE _cx_result -_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) { +_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { _cx_result res = _cx_memb(_insert_entry_)(self, rkey); if (res.inserted) { - *cx_keyref(res.ref) = i_keyfrom(rkey); - cx_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) + *_i_keyref(res.ref) = i_keyfrom(rkey); + _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) } return res; } STC_INLINE _cx_result -_cx_memb(_insert)(_cx_self* self, i_key key cx_MAP_ONLY(, i_val mapped)) { +_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); - if (res.inserted) { *cx_keyref(res.ref) = key; cx_MAP_ONLY( res.ref->second = mapped; )} - else { i_keydel(&key); cx_MAP_ONLY( i_valdel(&mapped); )} + if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} + else { i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )} return res; } @@ -268,7 +268,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { return (_cx_size) tn; } -cx_MAP_ONLY( +_i_MAP_ONLY( STC_DEF _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); @@ -292,7 +292,7 @@ _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out) { _cx_node *d = out->_d = self->nodes; out->_top = 0; while (tn) { - int c; _cx_rawkey raw = i_keyto(cx_keyref(&d[tn].value)); + int c; _cx_rawkey raw = i_keyto(_i_keyref(&d[tn].value)); if ((c = i_cmp(&raw, &rkey)) < 0) tn = d[tn].link[1]; else if (c > 0) @@ -360,7 +360,7 @@ _cx_memb(_insert_entry_i_)(_cx_self* self, _cx_size tn, const _cx_rawkey* rkey, int c, top = 0, dir = 0; while (tx) { up[top++] = tx; - i_keyraw raw = i_keyto(cx_keyref(&d[tx].value)); + i_keyraw raw = i_keyto(_i_keyref(&d[tx].value)); if ((c = i_cmp(&raw, rkey)) == 0) {res->ref = &d[tx].value; return tn; } dir = (c < 0); tx = d[tx].link[dir]; @@ -391,7 +391,7 @@ STC_DEF _cx_size _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erased) { if (tn == 0) return 0; - i_keyraw raw = i_keyto(cx_keyref(&d[tn].value)); + i_keyraw raw = i_keyto(_i_keyref(&d[tn].value)); _cx_size tx; int c = i_cmp(&raw, rkey); if (c != 0) d[tn].link[c < 0] = _cx_memb(_erase_r_)(d, d[tn].link[c < 0], rkey, erased); @@ -403,7 +403,7 @@ _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erase while (d[tx].link[1]) tx = d[tx].link[1]; d[tn].value = d[tx].value; /* move */ - raw = i_keyto(cx_keyref(&d[tn].value)); + raw = i_keyto(_i_keyref(&d[tn].value)); d[tn].link[0] = _cx_memb(_erase_r_)(d, d[tn].link[0], &raw, erased); } else { /* unlink node */ tx = tn; @@ -436,9 +436,9 @@ _cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { STC_DEF _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { - _cx_rawkey raw = i_keyto(cx_keyref(it.ref)), nxt; + _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; _cx_memb(_next)(&it); - if (it.ref) nxt = i_keyto(cx_keyref(it.ref)); + if (it.ref) nxt = i_keyto(_i_keyref(it.ref)); _cx_memb(_erase)(self, raw); if (it.ref) _cx_memb(_find_it)(self, nxt, &it); return it; @@ -448,11 +448,11 @@ STC_DEF _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { if (!it2.ref) { while (it1.ref) it1 = _cx_memb(_erase_at)(self, it1); return it1; } - _cx_key k1 = *cx_keyref(it1.ref), k2 = *cx_keyref(it2.ref); + _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); _cx_rawkey r1 = i_keyto(&k1); for (;;) { if (memcmp(&k1, &k2, sizeof k1) == 0) return it1; - _cx_memb(_next)(&it1); k1 = *cx_keyref(it1.ref); + _cx_memb(_next)(&it1); k1 = *_i_keyref(it1.ref); _cx_memb(_erase)(self, r1); _cx_memb(_find_it)(self, (r1 = i_keyto(&k1)), &it1); } @@ -496,8 +496,8 @@ _cx_memb(_del)(_cx_self* self) { #endif // IMPLEMENTATION #undef i_isset -#undef cx_keyref -#undef cx_MAP_ONLY -#undef cx_SET_ONLY +#undef _i_keyref +#undef _i_MAP_ONLY +#undef _i_SET_ONLY #include "template.h" #define CSMAP_H_INCLUDED diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 10063bcd..d503c94f 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -56,16 +56,16 @@ int main() { typedef long atomic_count_t; #if defined(__GNUC__) || defined(__clang__) - #define c_atomic_increment(v) (void)__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST) - #define c_atomic_decrement(v) (bool)__atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST) + #define c_atomic_inc(v) (void)__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST) + #define c_atomic_dec_and_test(v) !__atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST) #elif defined(_MSC_VER) #include - #define c_atomic_increment(v) (void)_InterlockedIncrement(v) - #define c_atomic_decrement(v) (bool)_InterlockedDecrement(v) + #define c_atomic_inc(v) (void)_InterlockedIncrement(v) + #define c_atomic_dec_and_test(v) !_InterlockedDecrement(v) #elif defined(__i386__) || defined(__x86_64__) - STC_INLINE void c_atomic_increment(atomic_count_t* v) + STC_INLINE void c_atomic_inc(atomic_count_t* v) { asm volatile("lock; incq %0" :"=m"(*v) :"m"(*v)); } - STC_INLINE bool c_atomic_decrement(atomic_count_t* v) { + STC_INLINE bool c_atomic_dec_and_test(atomic_count_t* v) { unsigned char c; asm volatile("lock; decq %0; sete %1" :"=m"(*v), "=qm"(c) :"m"(*v) :"memory"); return !c; @@ -73,6 +73,7 @@ typedef long atomic_count_t; #endif #define csptr_null {NULL, NULL} +#define _cx_csptr_rep struct _cx_memb(_rep_) #endif // CSPTR_H_INCLUDED #ifndef i_prefix @@ -81,17 +82,16 @@ typedef long atomic_count_t; #include "template.h" #ifdef i_nonatomic - #define cx_increment(v) (++*(v)) - #define cx_decrement(v) (--*(v)) + #define _i_atomic_inc(v) (void)(++*(v)) + #define _i_atomic_dec_and_test(v) !(--*(v)) #else - #define cx_increment(v) c_atomic_increment(v) - #define cx_decrement(v) c_atomic_decrement(v) + #define _i_atomic_inc(v) c_atomic_inc(v) + #define _i_atomic_dec_and_test(v) c_atomic_dec_and_test(v) #endif #ifndef i_fwd _cx_deftypes(_c_csptr_types, _cx_self, i_val); #endif -#define cx_csptr_rep struct _cx_memb(_rep_) -cx_csptr_rep { atomic_count_t counter; _cx_value value; }; +_cx_csptr_rep { atomic_count_t counter; _cx_value value; }; STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL, NULL}; } @@ -108,7 +108,7 @@ _cx_memb(_from)(_cx_value* p) { STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) { - _cx_self ptr; cx_csptr_rep *rep = c_alloc(cx_csptr_rep); + _cx_self ptr; _cx_csptr_rep *rep = c_alloc(_cx_csptr_rep); *(ptr.use_count = &rep->counter) = 1; *(ptr.get = &rep->value) = val; return ptr; @@ -116,7 +116,7 @@ _cx_memb(_make)(_cx_value val) { STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) { - if (ptr.use_count) cx_increment(ptr.use_count); + if (ptr.use_count) _i_atomic_inc(ptr.use_count); return ptr; } @@ -129,9 +129,9 @@ _cx_memb(_move)(_cx_self* self) { STC_INLINE void _cx_memb(_del)(_cx_self* self) { - if (self->use_count && cx_decrement(self->use_count) == 0) { + if (self->use_count && _i_atomic_dec_and_test(self->use_count)) { i_valdel(self->get); - if (self->get != &((cx_csptr_rep *)self->use_count)->value) + if (self->get != &((_cx_csptr_rep *)self->use_count)->value) c_free(self->get); c_free(self->use_count); } @@ -157,7 +157,7 @@ _cx_memb(_reset_with)(_cx_self* self, _cx_value val) { STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) { - if (ptr.use_count) cx_increment(ptr.use_count); + if (ptr.use_count) _i_atomic_inc(ptr.use_count); _cx_memb(_del)(self); *self = ptr; } @@ -177,8 +177,7 @@ _cx_memb(_compare)(const _cx_self* x, const _cx_self* y) { #endif } #endif -#undef cx_csptr_rep -#undef cx_increment -#undef cx_decrement #undef i_nonatomic +#undef _i_atomic_inc +#undef _i_atomic_dec_and_test #include "template.h" -- cgit v1.2.3