Port internal functions of concurrent to use the local lock interface.

This commit is contained in:
Patrick Pelissier committed 2018-11-24 12:20:37 +01:00
1 parent d3934dccb9
commit 3640041c47
1 file changed
+124 -92
+124 -92
View File
@@ -90,7 +90,7 @@
)
#define CONCURRENTI_CONTRACT(c) do { \
assert ((c)->self == c); \
assert ((c) != NULL); \
} while (0)
// Deferred evaluation for the concurrent definition.
@@ -113,15 +113,41 @@
\
/* Define the lock strategy (global & shared lock) */ \
static inline void \
M_C(name, _read_lock)(concurrent_t out) \
M_C(name, _internal_init)(concurrent_t out) \
{ \
m_mutex_lock (out->lock); \
m_mutex_init(out->lock); \
m_cond_init(out->there_is_data); \
out->self = out; \
} \
\
static inline void \
M_C(name, _read_unlock)(concurrent_t out) \
M_C(name, _internal_clear)(concurrent_t out) \
{ \
m_mutex_unlock (out->lock); \
assert (out->self == out); \
m_mutex_clear(out->lock); \
m_cond_clear(out->there_is_data); \
out->self = NULL; \
} \
\
static inline void \
M_C(name, _read_lock)(const concurrent_t out) \
{ \
assert (out->self == out); \
m_mutex_lock (out->self->lock); \
} \
\
static inline void \
M_C(name, _read_unlock)(const concurrent_t out) \
{ \
assert (out->self == out); \
m_mutex_unlock (out->self->lock); \
} \
\
static inline void \
M_C(name, _read_wait)(const concurrent_t out) \
{ \
assert (out->self == out); \
m_cond_wait(out->self->there_is_data, out->self->lock); \
} \
\
static inline void \
@@ -136,17 +162,28 @@
m_mutex_unlock (out->lock); \
} \
\
static inline void \
M_C(name, _write_wait)(const concurrent_t out) \
{ \
m_cond_wait(out->self->there_is_data, out->self->lock); \
} \
\
static inline void \
M_C(name, _write_signal)(concurrent_t out) \
{ \
m_cond_broadcast(out->there_is_data); \
} \
\
CONCURRENTI_DEF_FUNC(name, type, oplist, concurrent_t, concurrent_it_t)
// Internal definition of the functions.
#define CONCURRENTI_DEF_FUNC(name, type, oplist, concurrent_t, concurrent_it_t) \
M_IF_METHOD(INIT, oplist)( \
static inline void \
M_C(name, _init)(concurrent_t out) \
{ \
m_mutex_init(out->lock); \
m_cond_init(out->there_is_data); \
out->self = out; \
M_C(name, _internal_init)(out); \
M_CALL_INIT(oplist, out->data); \
CONCURRENTI_CONTRACT(out); \
} \
@@ -158,12 +195,10 @@
{ \
CONCURRENTI_CONTRACT(src); \
assert (out != src); \
m_mutex_init(out->lock); \
m_cond_init(out->there_is_data); \
out->self = out; \
m_mutex_lock (src->self->lock); \
M_C(name, _internal_init)(out); \
M_C(name, _read_lock)(src); \
M_CALL_INIT_SET(oplist, out->data, src->data); \
m_mutex_unlock(src->self->lock); \
M_C(name, _read_unlock)(src); \
CONCURRENTI_CONTRACT(out); \
} \
,) \
@@ -175,19 +210,19 @@
CONCURRENTI_CONTRACT(out); \
if (out == src) return; \
if (out < src) { \
m_mutex_lock (out->lock); \
m_mutex_lock (src->self->lock); \
M_C(name, _write_lock)(out); \
M_C(name, _read_lock)(src); \
} else { \
m_mutex_lock (src->self->lock); \
m_mutex_lock (out->lock); \
M_C(name, _read_lock)(src); \
M_C(name, _write_lock)(out); \
} \
M_CALL_SET(oplist, out->data, src->data); \
if (out < src) { \
m_mutex_unlock (src->self->lock); \
m_mutex_unlock (out->lock); \
M_C(name, _read_lock)(src); \
M_C(name, _write_unlock)(out); \
} else { \
m_mutex_unlock (out->lock); \
m_mutex_unlock (src->self->lock); \
M_C(name, _write_unlock)(out); \
M_C(name, _read_unlock)(src); \
} \
CONCURRENTI_CONTRACT(out); \
} \
@@ -200,8 +235,7 @@
CONCURRENTI_CONTRACT(out); \
/* No need to lock */ \
M_CALL_CLEAR(oplist, out->data); \
m_mutex_clear (out->lock); \
m_cond_clear(out->there_is_data); \
M_C(name, _internal_clear)(out); \
} \
,) \
\
@@ -212,12 +246,9 @@
CONCURRENTI_CONTRACT(src); \
assert (out != src); \
/* No need to lock 'src' ? */ \
m_mutex_init (out->lock); \
m_cond_init (out->there_is_data); \
out->self = out; \
M_C(name, _internal_init)(out); \
M_CALL_INIT_MOVE(oplist, out->data, src->data); \
m_mutex_clear (src->lock); \
m_cond_clear (src->there_is_data); \
M_C(name, _internal_clear)(src); \
CONCURRENTI_CONTRACT(out); \
} \
,) \
@@ -229,11 +260,10 @@
CONCURRENTI_CONTRACT(out); \
CONCURRENTI_CONTRACT(src); \
/* No need to lock 'src' ? */ \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_MOVE(oplist, out->data, src->data); \
m_mutex_unlock (out->lock); \
m_mutex_clear (src->lock); \
m_cond_clear (src->there_is_data); \
M_C(name, _write_unlock)(out); \
M_C(name, _internal_clear)(src); \
CONCURRENTI_CONTRACT(out); \
} \
,) \
@@ -245,19 +275,19 @@
CONCURRENTI_CONTRACT(out); \
CONCURRENTI_CONTRACT(src); \
if (out < src) { \
m_mutex_lock (out->lock); \
m_mutex_lock (src->lock); \
M_C(name, _write_lock)(out); \
M_C(name, _write_lock)(src); \
} else { \
m_mutex_lock (src->lock); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(src); \
M_C(name, _write_lock)(out); \
} \
M_CALL_SWAP(oplist, out->data, src->data); \
if (out < src) { \
m_mutex_unlock (src->lock); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(src); \
M_C(name, _write_unlock)(out); \
} else { \
m_mutex_unlock (out->lock); \
m_mutex_unlock (src->lock); \
M_C(name, _write_unlock)(out); \
M_C(name, _write_unlock)(src); \
} \
} \
,) \
@@ -267,9 +297,9 @@
M_C(name, _clean)(concurrent_t out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_CLEAN(oplist, out->data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -278,9 +308,9 @@
M_C(name, _empty_p)(concurrent_t const out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->self->lock); \
M_C(name, _read_lock)(out); \
bool b = M_CALL_TEST_EMPTY(oplist, out->data); \
m_mutex_unlock (out->self->lock); \
M_C(name, _read_unlock)(out); \
return b; \
} \
,) \
@@ -290,25 +320,25 @@
M_C(name, _set_at)(concurrent_t out, M_GET_KEY_TYPE oplist const key, M_GET_VALUE_TYPE oplist const data) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_SET_KEY(oplist, out->data, key, data); \
m_cond_broadcast(out->there_is_data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(GET_KEY, oplist)( \
static inline bool \
M_C(name, _get_copy)(M_GET_VALUE_TYPE oplist *out_data, concurrent_t out, M_GET_KEY_TYPE oplist const key) \
M_C(name, _get_copy)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key) \
{ \
CONCURRENTI_CONTRACT(out); \
assert (out_data != NULL); \
m_mutex_lock (out->lock); \
M_C(name, _read_lock)(out); \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \
if (p != NULL) { \
M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \
} \
m_mutex_unlock (out->lock); \
M_C(name, _read_unlock)(out); \
return p != NULL; \
} \
,) \
@@ -319,11 +349,11 @@
{ \
CONCURRENTI_CONTRACT(out); \
assert (out_data != NULL); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_SET_KEY(oplist, out->data, key); \
assert (p != NULL); \
M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -332,9 +362,9 @@
M_C(name, _erase)(concurrent_t out, M_GET_KEY_TYPE oplist const key) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
bool b = M_CALL_ERASE_KEY(oplist, out->data, key); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
return b; \
} \
,) \
@@ -344,10 +374,10 @@
M_C(name, _push)(concurrent_t out, M_GET_SUBTYPE oplist const data) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_PUSH(oplist, out->data, data); \
m_cond_broadcast(out->there_is_data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -356,9 +386,9 @@
M_C(name, _pop)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_POP(oplist, p, out->data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -367,10 +397,10 @@
M_C(name, _push_move)(concurrent_t out, M_GET_SUBTYPE oplist *data) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_PUSH_MOVE(oplist, out->data, data); \
m_cond_broadcast(out->there_is_data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -379,9 +409,9 @@
M_C(name, _pop_move)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
M_CALL_POP_MOVE(oplist, p, out->data); \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
} \
,) \
\
@@ -390,9 +420,9 @@
M_C(name, _get_str)(string_t str, concurrent_t const out, bool a) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->self->lock); \
M_C(name, _read_lock)(out); \
M_CALL_GET_STR(oplist, str, out->data, a); \
m_mutex_unlock (out->self->lock); \
M_C(name, _read_unlock)(out); \
} \
,) \
\
@@ -401,9 +431,9 @@
M_C(name, _out_str)(FILE *f, concurrent_t const out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->self->lock); \
M_C(name, _read_lock)(out); \
M_CALL_OUT_STR(oplist, f, out->data); \
m_mutex_unlock (out->self->lock); \
M_C(name, _read_unlock)(out); \
} \
,) \
\
@@ -412,9 +442,10 @@
M_C(name, _parse_str)(concurrent_t out, const char str[], const char **e) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
bool b = M_CALL_PARSE_STR(oplist, out->data, str, e); \
m_mutex_unlock (out->lock); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
return b; \
} \
,) \
@@ -424,9 +455,10 @@
M_C(name, _in_str)(concurrent_t out, FILE *f) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
bool b = M_CALL_IN_STR(oplist, out->data, f); \
m_mutex_unlock (out->lock); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
return b; \
} \
,) \
@@ -439,19 +471,19 @@
CONCURRENTI_CONTRACT(out2); \
if (out1 == out2) return true; \
if (out1 < out2) { \
m_mutex_lock (out1->self->lock); \
m_mutex_lock (out2->self->lock); \
M_C(name, _read_lock)(out1); \
M_C(name, _read_lock)(out2); \
} else { \
m_mutex_lock (out2->self->lock); \
m_mutex_lock (out1->self->lock); \
M_C(name, _read_lock)(out2); \
M_C(name, _read_lock)(out1); \
} \
bool b = M_CALL_EQUAL(oplist, out1->data, out2->data); \
if (out1 < out2) { \
m_mutex_unlock (out2->self->lock); \
m_mutex_unlock (out1->self->lock); \
M_C(name, _read_unlock)(out2); \
M_C(name, _read_unlock)(out1); \
} else { \
m_mutex_unlock (out1->self->lock); \
m_mutex_unlock (out2->self->lock); \
M_C(name, _read_unlock)(out1); \
M_C(name, _read_unlock)(out2); \
} \
return b; \
} \
@@ -459,12 +491,12 @@
\
M_IF_METHOD(GET_KEY, oplist)( \
static inline bool \
M_C(name, _get_blocking)(M_GET_VALUE_TYPE oplist *out_data, concurrent_t out, M_GET_KEY_TYPE oplist const key, bool blocking) \
M_C(name, _get_blocking)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key, bool blocking) \
{ \
CONCURRENTI_CONTRACT(out); \
assert (out_data != NULL); \
bool ret = false; \
m_mutex_lock (out->lock); \
M_C(name, _read_lock)(out); \
while (true) { \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \
if (p != NULL) { \
@@ -473,9 +505,9 @@
break; \
} \
if (blocking == false) break; \
m_cond_wait(out->there_is_data, out->lock); \
M_C(name, _read_wait)(out); \
} \
m_mutex_unlock (out->lock); \
M_C(name, _read_unlock)(out); \
return ret; \
} \
,) \
@@ -487,7 +519,7 @@
CONCURRENTI_CONTRACT(out); \
assert (p != NULL); \
bool ret = false; \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
while (true) { \
if (!M_CALL_TEST_EMPTY(oplist, out->data)) { \
M_CALL_POP(oplist, p, out->data); \
@@ -495,9 +527,9 @@
break; \
} \
if (blocking == false) break; \
m_cond_wait(out->there_is_data, out->lock); \
M_C(name, _write_wait)(out); \
} \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
return ret; \
} \
,) \
@@ -509,7 +541,7 @@
CONCURRENTI_CONTRACT(out); \
assert (p != NULL); \
bool ret = false; \
m_mutex_lock (out->lock); \
M_C(name, _write_lock)(out); \
while (true) { \
if (!M_CALL_TEST_EMPTY(oplist, out->data)) { \
M_CALL_POP_MOVE(oplist, p, out->data); \
@@ -517,9 +549,9 @@
break; \
} \
if (blocking == false) break; \
m_cond_wait(out->there_is_data, out->lock); \
M_C(name, _write_wait)(out); \
} \
m_mutex_unlock (out->lock); \
M_C(name, _write_unlock)(out); \
return ret; \
} \
,) \
@@ -529,9 +561,9 @@
M_C(name, _hash)(concurrent_t const out) \
{ \
CONCURRENTI_CONTRACT(out); \
m_mutex_lock (out->self->lock); \
M_C(name, _read_lock)(out); \
size_t h = M_CALL_HASH(oplist, out->data); \
m_mutex_unlock (out->self->lock); \
M_C(name, _read_unlock)(out); \
return h; \
} \
,) \