Update comment

This commit is contained in:
Patrick Pelissier committed 2024-10-28 17:46:48 +01:00
1 parent f43db93791
commit c5692e7e9f
1 file changed
+59 -39
+59 -39
View File
@@ -29,19 +29,23 @@
#include "m-atomic.h"
#include "m-thread.h"
/* Declare a shared weak pointer (not atomic). oplist is mandatory */
/* Declare a shared weak pointer (not atomic, single thread) for use in header file.
oplist is mandatory but is only used to test if a function has to be declared */
#define M_SHARED_WEAK_PTR_DECL(name, oplist) \
M_SHAR3D_PTR_DECL_P2(name, M_F(name, _t), oplist)
/* Declare a shared weak pointer (not atomic). oplist is mandatory */
/* Declare a shared weak pointer (not atomic, single thread) for use in header file.
oplist is mandatory but is only used to test if a function has to be declared */
#define M_SHARED_WEAK_PTR_DECL_AS(name, shared_t, oplist) \
M_SHAR3D_PTR_DECL_P2(name, shared_t, oplist)
/* Declare a shared strong pointer (atomic & lock). oplist is mandatory */
/* Declare a shared strong pointer (atomic & lock) for use in header file.
oplist is mandatory but is only used to test if a function has to be declared */
#define M_SHARED_PTR_DECL(name, oplist) \
M_SHAR3D_PTR_DECL_P2(name, M_F(name, _t), oplist)
/* Declare a shared strong pointer (atomic & lock). oplist is mandatory */
/* Declare a shared strong pointer (atomic & lock) for use in header file.
oplist is mandatory but is only used to test if a function has to be declared */
#define M_SHARED_PTR_DECL_AS(name, shared_t, oplist) \
M_SHAR3D_PTR_DECL_P2(name, shared_t, oplist)
@@ -73,6 +77,7 @@
/* Define a static inline a shared weak pointer (not atomic). oplist is optional */
#define M_SHARED_WEAK_PTR_DEF_AS(name, shared_t, ...) \
M_SHARED_PTR_DECL_TYPE(name, shared_t, ) \
M_SHAR3D_WEAK_PTR_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
((name, shared_t, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), static inline ), \
(name, shared_t, __VA_ARGS__, static inline )))
@@ -83,6 +88,7 @@
/* Define a static inline a shared strong pointer (atomic & lock). oplist is optional */
#define M_SHARED_PTR_DEF_AS(name, shared_t, ...) \
M_SHARED_PTR_DECL_TYPE(name, shared_t, ) \
M_SHAR3D_PTR_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
((name, shared_t, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), static inline ), \
(name, shared_t, __VA_ARGS__, static inline )))
@@ -101,6 +107,7 @@
#define M_SHAR3D_PTR_DECL_FAILURE(name, shared_t, oplist) \
((M_LIB_ERROR(ARGUMENT_OF_DECL_SHARED_POINTER_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
/* Declare all functions assiated to the shared pointer */
#define M_SHAR3D_PTR_DECL_P3(name, shared_t, oplist) \
M_BEGIN_PROTECTED_CODE \
M_SHARED_PTR_DECL_TYPE(name, shared_t, oplist) \
@@ -125,8 +132,9 @@
/* Prepare a clean compilation failure */
#define M_SHAR3D_WEAK_PTR_DEF_FAILURE(name, shared_t, type, oplist, fattr) \
((M_LIB_ERROR(ARGUMENT_OF_DECL_SHARED_POINTER_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
((M_LIB_ERROR(ARGUMENT_OF_WEAK_DEF_SHARED_POINTER_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
/* Define all functions assiated to the weak shared pointer as 'fattr' (can be static inline or extern) */
#define M_SHAR3D_WEAK_PTR_DEF_P3(name, shared_t, type, oplist, fattr) \
M_BEGIN_PROTECTED_CODE \
M_SHARED_PTR_NO_THRD_DEF_TYPE(name, shared_t, type, oplist) \
@@ -152,8 +160,9 @@
/* Prepare a clean compilation failure */
#define M_SHAR3D_PTR_DEF_FAILURE(name, shared_t, type, oplist, fattr) \
((M_LIB_ERROR(ARGUMENT_OF_DECL_SHARED_POINTER_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
((M_LIB_ERROR(ARGUMENT_OF_DEF_SHARED_POINTER_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
/* Define all functions assiated to the shared pointer as 'fattr' (can be static inline or extern) */
#define M_SHAR3D_PTR_DEF_P3(name, shared_t, type, oplist, fattr) \
M_BEGIN_PROTECTED_CODE \
M_SHARED_PTR_DEF_TYPE(name, shared_t, type, oplist) \
@@ -169,101 +178,98 @@
M_END_PROTECTED_CODE
/* Declare the type of shared pointer. Opaque structure */
/* Declare the type of shared pointer. Opaque structure for encapsulation */
#define M_SHARED_PTR_DECL_TYPE(name, shared_t, oplist) \
typedef struct M_C(name, _s) shared_t;
// Definition of the type with no thread safety.
/* Definition of the type with no thread safety (single thread) */
#define M_SHARED_PTR_NO_THRD_DEF_TYPE(name, shared_t, type, oplist) \
struct M_C(name, _s) { \
type data; /* Allow safe casting from shared_t* to type* */ \
unsigned cpt; /* Owner counter that acquire the data */ \
unsigned cpt; /* Owner counter that acquire the data */ \
};
// Define the core functions without any thread safety
/* Define the core functions without any thread safety */
#define M_SHARED_PTR_NO_THRD_DEF_CORE(name, shared_t, type, oplist, fattr) \
\
/* Increment the number of owner (acquire the resource) */ \
fattr void M_F(name, _inc_owner)(shared_t *out) \
{ \
out->cpt ++; \
} \
\
/* Decrement the number of owner (release the resource). Return true if it was the last owner */ \
fattr bool M_F(name, _dec_owner)(shared_t *out) \
{ \
out->cpt --; \
return 0 == out->cpt; \
} \
\
/* Init the lock */ \
fattr void M_F(name, _init_lock)(shared_t *out) \
{ \
out->cpt = 0; \
} \
\
/* Clear the lock */ \
fattr void M_F(name, _clear_lock)(shared_t *out) \
{ \
M_ASSERT(out->cpt == 0); \
(void) out; \
} \
\
/* Enter the lock for reading the data */ \
fattr void M_F(name, _read_lock)(const shared_t *out) \
{ \
(void) out; \
} \
\
/* wait for some data to be read */ \
/* wait for some new data to be available (within read_lock) */ \
fattr void M_F(name, _read_wait)(const shared_t *out) \
{ \
(void) out; \
} \
\
/* Leave the lock for reading the data (within read_lock) */ \
fattr void M_F(name, _read_unlock)(const shared_t *out) \
{ \
(void) out; \
} \
\
/* Enter the lock for writing/updating the data */ \
fattr void M_F(name, _write_lock)(shared_t *out) \
{ \
(void) out; \
} \
\
/* wait to be able to write in the data */ \
/* wait to be able to write new data (within write_lock) */ \
fattr void M_F(name, _write_wait)(shared_t *out) \
{ \
(void) out; \
} \
\
/* signal some write in the data */ \
/* signal some new data are available (within write_lock) */ \
fattr void M_F(name, _write_signal)(shared_t *out) \
{ \
(void) out; \
} \
\
/* signal some free slot in the data */ \
/* signal some free slot are available (within write_lock) */ \
fattr void M_F(name, _free_signal)(shared_t *out) \
{ \
(void) out; \
} \
\
/* Leaver the lock for writing/updating the data (within write_lock) */ \
fattr void M_F(name, _write_unlock)(shared_t *out) \
{ \
(void) out; \
} \
\
/* Return a pointer to the data */ \
fattr type *M_F(name, _ref)(shared_t *out) \
{ \
return &out->data; \
} \
\
/* Return a const pointer to the data */ \
fattr type const *M_F(name, _cref)(const shared_t *out) \
{ \
return &out->data; \
} \
\
/* Perform a write lock on out and a read lock on src */ \
fattr void M_F(name, _write_read_lock)(shared_t *out, const shared_t *src) \
{ \
(void) out; \
(void) src; \
} \
\
/* Leave the write lock on out and the read lock on src */ \
fattr void M_F(name, _write_read_unlock)(shared_t *out, const shared_t *src) \
{ \
(void) out; \
@@ -271,8 +277,7 @@ fattr void M_F(name, _write_read_unlock)(shared_t *out, const shared_t *src) \
} \
// Definition of the type with thread safety.
/* Definition of the type with thread safety. */
//TODO: If PROPERTIES.THREADSAFE, disable the global lock as the container handles it itself.
#define M_SHARED_PTR_DEF_TYPE(name, shared_t, type, oplist) \
struct M_C(name, _s) { \
@@ -287,7 +292,8 @@ fattr void M_F(name, _write_read_unlock)(shared_t *out, const shared_t *src) \
, ) \
};
// NOTE: lock are exception free.
/* Define the core functions with thread safety
NOTE: lock are exception free. */
#define M_SHARED_PTR_DEF_CORE(name, shared_t, type, oplist, fattr) \
\
fattr void M_F(name, _inc_owner)(shared_t *out) \
@@ -344,7 +350,6 @@ fattr void M_F(name, _read_lock)(const shared_t *out) \
m_core_backoff_clear(backoff); \
} \
\
/* wait for some data to be read */ \
fattr void M_F(name, _read_wait)(const shared_t *out) \
{ \
shared_t *self = (shared_t *)out; \
@@ -369,7 +374,6 @@ fattr void M_F(name, _write_lock)(shared_t *out) \
M_ASSERT(atomic_load(&out->num_reader) == 0); \
} \
\
/* wait to be able to write in the data */ \
fattr void M_F(name, _write_wait)(shared_t *out) \
{ \
M_ASSERT(atomic_load(&out->num_reader) == 0); \
@@ -378,14 +382,12 @@ fattr void M_F(name, _write_wait)(shared_t *out) \
,) \
} \
\
/* signal some write in the data */ \
fattr void M_F(name, _write_signal)(shared_t *out) \
{ \
M_ASSERT(atomic_load(&out->num_reader) == 0); \
m_cond_broadcast(out->there_is_data); \
} \
\
/* signal some free slot in the data */ \
fattr void M_F(name, _free_signal)(shared_t *out) \
{ \
M_ASSERT(atomic_load(&out->num_reader) == 0); \
@@ -440,6 +442,7 @@ fattr void M_F(name, _write_read_unlock)(shared_t *out, const shared_t *src) \
} \
/* Define the basic function of a shared pointer */
#define M_SHARED_PTR_DECL_BASIC(name, shared_t, oplist) \
M_IF_METHOD(INIT, oplist)( extern shared_t *M_F(name, _new)(void); , ) \
M_IF_METHOD(INIT_SET, oplist)( extern shared_t *M_F(name, _new_copy)(const shared_t *); , ) \
@@ -459,7 +462,7 @@ M_IF_METHOD(INIT, oplist)( \
shared_t *out = M_CALL_NEW(oplist, shared_t); \
if (M_UNLIKELY_NOMEM( out == NULL)) { \
M_MEMORY_FULL(sizeof (shared_t)); \
M_ASSERT (0); \
abort(); \
} \
M_ON_EXCEPTION( M_CALL_FREE(oplist, out) ) \
M_CALL_INIT(oplist, out->data); \
@@ -529,7 +532,7 @@ M_PAIR_2 name_attr shared_t *function_name(M_EMPLACE_LIST_TYPE_VAR_ALTER(a, exp_
shared_t *out = M_CALL_NEW(oplist, shared_t); \
if (M_UNLIKELY_NOMEM( out == NULL)) { \
M_MEMORY_FULL(sizeof (shared_t)); \
M_ASSERT (0); \
abort(); \
} \
M_ON_EXCEPTION( M_CALL_FREE(oplist, out) ) \
M_EMPLACE_CALL_FUNC(a, init_func, oplist, out->data, exp_emplace_type); \
@@ -537,6 +540,8 @@ M_PAIR_2 name_attr shared_t *function_name(M_EMPLACE_LIST_TYPE_VAR_ALTER(a, exp_
return out; \
} \
/* Define the extra function of a shared pointer */
#define M_SHARED_PTR_DECL_EXTRA(name, shared_t, oplist) \
M_IF_METHOD(SWAP, oplist)( extern void M_F(name, _swap)(shared_t *, shared_t *); , ) \
M_IF_METHOD(RESET, oplist)( extern void M_F(name, _reset)(shared_t *); , ) \
@@ -560,6 +565,7 @@ M_IF_METHOD(SWAP, oplist)( \
M_F(name, _write_lock)(o2); \
/* SWAP cannot throw exception */ \
M_CALL_SWAP(oplist, o1->data, o2->data); \
/* It doesn't make sense to signal new data or new slot, Right? */ \
M_F(name, _write_unlock)(o1); \
M_F(name, _write_unlock)(o2); \
} \
@@ -621,6 +627,7 @@ M_IF_METHOD(EQUAL, oplist)( \
if (o1 > o2) { \
M_SWAP(const shared_t *, o1, o2); \
} \
/* FIXME: OOR compare and constraint on OOR argument? */ \
M_F(name, _read_lock)(o1); \
M_F(name, _read_lock)(o2); \
/* EQUAL cannot throw exception */ \
@@ -664,6 +671,8 @@ M_IF_METHOD(HASH, oplist)( \
} \
, ) \
/* Define the arithmetic operators */
#define M_SHARED_PTR_DECL_ARITH(name, shared_t, oplist) \
M_IF_METHOD(ADD, oplist)( extern void M_F(name, _add)(shared_t *, const shared_t *); , ) \
M_IF_METHOD(SUB, oplist)( extern void M_F(name, _sub)(shared_t *, const shared_t *); , ) \
@@ -736,6 +745,7 @@ M_IF_METHOD(SPLICE, oplist)( \
, ) \
/* Define the key based operators */
#define M_SHARED_PTR_DECL_KEY(name, shared_t, oplist, key_type, value_type) \
M_IF_METHOD(GET_KEY, oplist)( extern bool M_F(name, _get)(value_type *, const shared_t *, key_type const); , ) \
M_IF_METHOD(SAFE_GET_KEY, oplist)( extern void M_F(name, _safe_get)(value_type *, shared_t *, key_type const); , ) \
@@ -800,6 +810,8 @@ M_IF_METHOD(ERASE_KEY, oplist)( \
} \
, ) \
/* Define the push based operators */
#define M_SHARED_PTR_DECL_PUSH(name, shared_t, oplist, sub_type) \
M_IF_METHOD(PUSH, oplist)( extern void M_F(name, _push)(shared_t *, sub_type const); , ) \
M_IF_METHOD(PUSH_MOVE, oplist)( extern void M_F(name, _push_move)(shared_t *, sub_type *); , ) \
@@ -922,6 +934,8 @@ M_TRIPLE_2 name_attr bool function_name(shared_t *out, M_EMPLACE_LIST_TYPE_VAR_A
return ret; \
} \
/* Define the pop based operators */
#define M_SHARED_PTR_DECL_POP(name, shared_t, oplist, sub_type) \
M_IF_METHOD(POP, oplist)( extern void M_F(name, _pop)(sub_type *const, shared_t *); , ) \
M_IF_METHOD(POP_MOVE, oplist)( extern void M_F(name, _pop_move)(sub_type *, shared_t *); , ) \
@@ -994,6 +1008,10 @@ M_IF_METHOD(POP_MOVE, oplist)( \
} \
, ) \
/* Define the iterator based operators
We cannot provide directly the iterator due to concenrency API,
so we produce an encapsulation of the major usage of them */
#define M_SHARED_PTR_DECL_IT(name, shared_t, oplist, sub_type) \
M_IF_METHOD2(IT_FIRST, IT_REF, oplist)( extern int M_F(name, _apply)(shared_t *, int (*callback)(void *, sub_type*), void*); , ) \
M_IF_METHOD2(IT_FIRST, IT_CREF, oplist)( extern int M_F(name, _for_each)(const shared_t *, int (*callback)(void *, const sub_type*), void*); , ) \
@@ -1080,6 +1098,8 @@ M_IF_METHOD2(IT_LAST, IT_CREF, oplist)( \
} \
, ) \
/* Define the I/O based operators */
#define M_SHARED_PTR_DECL_IO(name, shared_t, oplist) \
M_IF_METHOD(OUT_STR, oplist)( extern void M_F(name, _out_str)(FILE *, const shared_t *); , ) \
M_IF_METHOD(IN_STR, oplist)( extern bool M_F(name, _in_str)(shared_t *, FILE *); , ) \