summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-09-23 22:18:51 +0200
committerTyge Løvset <[email protected]>2020-09-23 22:18:51 +0200
commit31ec9ba3359864a780ac64f53acee33fb5cb2b5a (patch)
treef54bbfad5196301457c5b4324c6b9780f489611d
parenta0b1659baa898cd124a15b5f7c86670ca08277e5 (diff)
downloadSTC-modified-31ec9ba3359864a780ac64f53acee33fb5cb2b5a.tar.gz
STC-modified-31ec9ba3359864a780ac64f53acee33fb5cb2b5a.zip
Some internal restructuring. Added shared_ptr like struct type: csptr.h
-rw-r--r--examples/benchmark.c25
-rw-r--r--stc/carray.h12
-rw-r--r--stc/cdefs.h3
-rw-r--r--stc/clist.h4
-rw-r--r--stc/cmap.h4
-rw-r--r--stc/cpqueue.h2
-rw-r--r--stc/cqueue.h2
-rw-r--r--stc/csptr.h113
-rw-r--r--stc/cstack.h2
-rw-r--r--stc/cvec.h4
10 files changed, 143 insertions, 28 deletions
diff --git a/examples/benchmark.c b/examples/benchmark.c
index 691d585b..d1167eb4 100644
--- a/examples/benchmark.c
+++ b/examples/benchmark.c
@@ -151,8 +151,8 @@ int rr = RR;
erased += M##_ERASE(X, RAND(rr)); \
} \
difference = clock() - before; \
- printf(#M ": size: %zu, buckets: %8zu, time: %5.02f, sum: %zu, erased %zu\n", \
- (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X), (float) difference / CLOCKS_PER_SEC, checksum, erased); \
+ printf(#M ": time: %5.02f, sum: %zu, erased %zu, size: %zu, buckets: %8zu\n", \
+ (float) difference / CLOCKS_PER_SEC, checksum, erased, (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X)); \
M##_CLEAR(X); \
}
@@ -166,8 +166,8 @@ int rr = RR;
for (size_t i = 0; i < N2; ++i) \
erased += M##_ERASE(X, i); \
difference = clock() - before; \
- printf(#M ": size: %zu, buckets: %8zu, time: %5.02f, erased %zu\n", \
- (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X), (float) difference / CLOCKS_PER_SEC, erased); \
+ printf(#M ": time: %5.02f, erased %zu, size: %zu, buckets: %8zu\n", \
+ (float) difference / CLOCKS_PER_SEC, erased, (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X)); \
M##_CLEAR(X); \
}
@@ -183,8 +183,8 @@ int rr = RR;
for (size_t i = 0; i < N3; ++i) \
erased += M##_ERASE(X, RAND(rr)); \
difference = clock() - before; \
- printf(#M ": size: %zu, buckets: %8zu, time: %5.02f, erased %zu\n", \
- (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X), (float) difference / CLOCKS_PER_SEC, erased); \
+ printf(#M ": time: %5.02f, erased %zu, size: %zu, buckets: %8zu\n", \
+ (float) difference / CLOCKS_PER_SEC, erased, (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X)); \
M##_CLEAR(X); \
}
@@ -199,21 +199,22 @@ int rr = RR;
for (int k=0; k<5; k++) M##_FOR (X, i) \
sum += M##_ITEM(X, i); \
difference = clock() - before; \
- printf(#M ": size: %zu, buckets: %8zu, time: %5.02f, sum %zu\n", \
- (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X), (float) difference / CLOCKS_PER_SEC, sum); \
+ printf(#M ": time: %5.02f, sum %zu, size: %zu, buckets: %8zu\n", \
+ (float) difference / CLOCKS_PER_SEC, sum, (size_t) M##_SIZE(X), (size_t) M##_BUCKETS(X)); \
M##_CLEAR(X); \
}
-
-#ifndef __cplusplus
-#define RUN_TEST(n) MAP_TEST##n(CMAP, ii) /*MAP_TEST##n(KMAP, ii)*/
-#else
+#ifdef __cplusplus
#define RUN_TEST(n) MAP_TEST##n(CMAP, ii) MAP_TEST##n(KMAP, ii) MAP_TEST##n(UMAP, ii) MAP_TEST##n(SMAP, ii) \
MAP_TEST##n(BMAP, ii) MAP_TEST##n(FMAP, ii) MAP_TEST##n(RMAP, ii) MAP_TEST##n(HMAP, ii)
#define RUNX_TEST(n) MAP_TEST##n(CMAP, ii) /*MAP_TEST##n(KMAP, ii)*/ MAP_TEST##n(UMAP, ii) MAP_TEST##n(SMAP, ii) \
MAP_TEST##n(BMAP, ii) MAP_TEST##n(FMAP, ii) /*MAP_TEST##n(RMAP, ii)*/ MAP_TEST##n(HMAP, ii)
+#else
+#define RUN_TEST(n) MAP_TEST##n(CMAP, ii) MAP_TEST##n(KMAP, ii)
+#define RUNX_TEST(n) MAP_TEST##n(CMAP, ii)
#endif
+
int main(int argc, char* argv[])
{
rr = argc == 2 ? atoi(argv[1]) : RR;
diff --git a/stc/carray.h b/stc/carray.h
index 4e164f42..3fd7f532 100644
--- a/stc/carray.h
+++ b/stc/carray.h
@@ -101,20 +101,20 @@ STC_INLINE size_t _carray3_size(const size_t* zdim) {
typedef Value carray1##X##_value_t; \
typedef carray1##X##_value_t carray2##X##_value_t, carray3##X##_value_t; \
\
- typedef struct carray1##X { \
+ typedef struct { \
Value *data; \
size_t _xdim; \
- } carray1##X; \
+ } carray1##X, carray1##X##_t; \
\
- typedef struct carray2##X { \
+ typedef struct { \
Value *data; \
size_t _xdim, _yxdim; \
- } carray2##X; \
+ } carray2##X, carray2##X##_t; \
\
- typedef struct carray3##X { \
+ typedef struct { \
Value *data; \
size_t _xdim, _yxdim, _zdim; \
- } carray3##X; \
+ } carray3##X, carray3##X##_t; \
\
using_carray_common(1, X, Value, valueDestroy) \
using_carray_common(2, X, Value, valueDestroy) \
diff --git a/stc/cdefs.h b/stc/cdefs.h
index 7b06f74d..7034f304 100644
--- a/stc/cdefs.h
+++ b/stc/cdefs.h
@@ -77,6 +77,7 @@ enum {_c_max_buffer = 512};
#define c_default_from_raw(x) (x)
#define c_default_to_raw(ptr) (*(ptr))
#define c_default_del(ptr) ((void) (ptr))
+#define c_pointer_del(pptr) free(*(pptr))
#define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__)
#define c_foreach_3(it, ctype, cnt) \
@@ -98,7 +99,7 @@ enum {_c_max_buffer = 512};
} while (0)
#define c_del(ctype, ...) do { \
- struct ctype* __arr[] = {__VA_ARGS__}; \
+ ctype##_t* __arr[] = {__VA_ARGS__}; \
for (size_t i=0; i<sizeof(__arr)/sizeof(__arr[0]); ++i) \
ctype##_del(__arr[i]); \
} while (0)
diff --git a/stc/clist.h b/stc/clist.h
index 9aa83437..69523dc0 100644
--- a/stc/clist.h
+++ b/stc/clist.h
@@ -75,9 +75,9 @@
clist_##X##_value_t value; \
} clist_##X##_node_t; \
\
- typedef struct clist_##X { \
+ typedef struct { \
clist_##X##_node_t* last; \
- } clist_##X; \
+ } clist_##X, clist_##X##_t; \
\
typedef struct { \
clist_##X##_node_t* const* _last; \
diff --git a/stc/cmap.h b/stc/cmap.h
index fa427a6e..f7241a06 100644
--- a/stc/cmap.h
+++ b/stc/cmap.h
@@ -189,13 +189,13 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
bool second; /* inserted */ \
} ctype##_##X##_result_t; \
\
- typedef struct ctype##_##X { \
+ typedef struct { \
ctype##_##X##_value_t* table; \
uint8_t* _hashx; \
uint32_t size, bucket_count; \
float max_load_factor; \
float shrink_limit_factor; \
- } ctype##_##X; \
+ } ctype##_##X, ctype##_##X##_t; \
\
typedef struct { \
ctype##_##X##_value_t *get; \
diff --git a/stc/cpqueue.h b/stc/cpqueue.h
index 4241cc32..e1c13d57 100644
--- a/stc/cpqueue.h
+++ b/stc/cpqueue.h
@@ -52,7 +52,7 @@
#define using_cpqueue(X, ctype, cmpOpr) /* cmpOpr: < or > */ \
\
- typedef struct ctype cpqueue_##X; \
+ typedef ctype##_t cpqueue_##X, cpqueue_##X##_t; \
typedef ctype##_value_t cpqueue_##X##_value_t; \
typedef ctype##_rawvalue_t cpqueue_##X##_rawvalue_t; \
typedef ctype##_input_t cpqueue_##X##_input_t; \
diff --git a/stc/cqueue.h b/stc/cqueue.h
index 27346de6..9ccb69f1 100644
--- a/stc/cqueue.h
+++ b/stc/cqueue.h
@@ -60,7 +60,7 @@
#define using_cqueue(X, ctype) \
\
- typedef struct ctype cqueue_##X; \
+ typedef ctype##_t cqueue_##X, cqueue_##X##_t; \
typedef ctype##_value_t cqueue_##X##_value_t; \
typedef ctype##_rawvalue_t cqueue_##X##_rawvalue_t; \
typedef ctype##_input_t cqueue_##X##_input_t; \
diff --git a/stc/csptr.h b/stc/csptr.h
new file mode 100644
index 00000000..8e09f36e
--- /dev/null
+++ b/stc/csptr.h
@@ -0,0 +1,113 @@
+/* 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 <stc/csptr.h>
+#include <stc/cstr.h>
+
+typedef struct { cstr_t name, last; } Person;
+
+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(c_new(Person));
+ p.get->name = cstr("Joe");
+ p.get->last = cstr("Jordan");
+
+ 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;
+ }
+ 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) {
+ return atomic_exchange_and_add(pw, -1) - 1; // (pw, 1) + 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
+
+
+#define using_csptr(X, Value, valueDestroy) \
+ typedef Value csptr_##X##_value_t; \
+ typedef struct { csptr_##X##_value_t* get; atomic_count_t* use_count; } csptr_##X, csptr_##X##_t; \
+\
+ STC_INLINE csptr_##X \
+ csptr_##X##_make(csptr_##X##_value_t* p) { \
+ csptr_##X ptr = {p}; \
+ if (p) *(ptr.use_count = c_new(atomic_count_t)) = 1; \
+ return ptr; \
+ } \
+\
+ STC_INLINE csptr_##X \
+ csptr_##X##_ref(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); \
+ } \
+ } \
+\
+ STC_INLINE void \
+ csptr_##X##_reset(csptr_##X* self, csptr_##X##_value_t* p) { \
+ csptr_##X##_del(self); \
+ *self = csptr_##X##_make(p); \
+ } \
+\
+ typedef int csptr_##X##_dud
+
+#endif
diff --git a/stc/cstack.h b/stc/cstack.h
index 0351a545..37e8f3f3 100644
--- a/stc/cstack.h
+++ b/stc/cstack.h
@@ -49,7 +49,7 @@
#define using_cstack(X, ctype) \
\
- typedef struct ctype cstack_##X; \
+ typedef ctype##_t cstack_##X, cstack_##X##_t; \
typedef ctype##_value_t cstack_##X##_value_t; \
typedef ctype##_rawvalue_t cstack_##X##_rawvalue_t; \
typedef ctype##_input_t cstack_##X##_input_t; \
diff --git a/stc/cvec.h b/stc/cvec.h
index 3754732d..082909fc 100644
--- a/stc/cvec.h
+++ b/stc/cvec.h
@@ -50,9 +50,9 @@
typedef cvec_##X##_rawvalue_t cvec_##X##_input_t; \
typedef struct { cvec_##X##_value_t *get; } cvec_##X##_iter_t; \
\
- typedef struct cvec_##X { \
+ typedef struct { \
cvec_##X##_value_t* data; \
- } cvec_##X; \
+ } cvec_##X, cvec_##X##_t; \
\
STC_INLINE cvec_##X \
cvec_##X##_init(void) {cvec_##X v = cvec_INIT; return v;} \