Fix case of the same variable is passed as 2/3 arguments of a function.
This commit is contained in:
1 parent
ae55ccfc40
commit
27b0850af4
1 file changed
+47
-2
+47
-2
@@ -508,6 +508,8 @@ static inline type const *M_F(name, _cref)(const shared_t *out) \
|
||||
\
|
||||
static inline void M_F(name, _write_read_lock)(shared_t *out, const shared_t *src) \
|
||||
{ \
|
||||
/* We cannot perform a write_lock and a read_lock on the same variable at the same time */ \
|
||||
M_ASSERT(out != src); \
|
||||
/* Need to order the locks in a total way to avoid lock deadlock. \
|
||||
Indeed, two call to _set can be done in two threads with : \
|
||||
T1: A := B \
|
||||
@@ -530,13 +532,39 @@ static inline void M_F(name, _write_read_lock)(shared_t *out, const shared_t *sr
|
||||
\
|
||||
static inline void M_F(name, _write_read_unlock)(shared_t *out, const shared_t *src) \
|
||||
{ \
|
||||
M_ASSERT(out != src); \
|
||||
/* NOTE: No need to order the unlock */ \
|
||||
M_F(name, _read_unlock)(src); \
|
||||
M_F(name, _write_unlock)(out); \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _write_read2_lock)(shared_t *out, const shared_t *src1, const shared_t *src2) \
|
||||
fattr void M_F(name, _write_read2_lock)(shared_t *out, const shared_t *src1, const shared_t *src2); \
|
||||
fattr void M_F(name, _write_read2_lock)(shared_t *out, const shared_t *src1, const shared_t *src2) \
|
||||
{ \
|
||||
/* We can have out == src1 or out == src2 or src1 == src2 */ \
|
||||
/* if src1 == src2, nothing special to do (read_lock are compatible each other )*/ \
|
||||
if (out == src1) { \
|
||||
if (out == src2) { \
|
||||
M_F(name, _write_lock)(out); \
|
||||
} else if (out < src2) { \
|
||||
M_F(name, _write_lock)(out); \
|
||||
M_F(name, _read_lock)(src2); \
|
||||
} else { \
|
||||
M_F(name, _read_lock)(src2); \
|
||||
M_F(name, _write_lock)(out); \
|
||||
} \
|
||||
return; \
|
||||
} else if (out == src2) { \
|
||||
M_ASSERT(out != src1); \
|
||||
if (out < src1) { \
|
||||
M_F(name, _write_lock)(out); \
|
||||
M_F(name, _read_lock)(src1); \
|
||||
} else { \
|
||||
M_F(name, _read_lock)(src1); \
|
||||
M_F(name, _write_lock)(out); \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
/* See above */ \
|
||||
if (src1 > src2) { \
|
||||
M_SWAP(const shared_t *, src1, src2); \
|
||||
@@ -560,8 +588,25 @@ static inline void M_F(name, _write_read2_lock)(shared_t *out, const shared_t *s
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _write_read2_unlock)(shared_t *out, const shared_t *src1, const shared_t *src2) \
|
||||
fattr void M_F(name, _write_read2_unlock)(shared_t *out, const shared_t *src1, const shared_t *src2); \
|
||||
fattr void M_F(name, _write_read2_unlock)(shared_t *out, const shared_t *src1, const shared_t *src2) \
|
||||
{ \
|
||||
/* We can have out == src1 or out == src2 or src1 == src2 */ \
|
||||
/* if src1 == src2, nothing special to do (read_lock are compatible each other )*/ \
|
||||
if (out == src1) { \
|
||||
if (out == src2) { \
|
||||
M_F(name, _write_unlock)(out); \
|
||||
} else { \
|
||||
M_F(name, _read_unlock)(src2); \
|
||||
M_F(name, _write_unlock)(out); \
|
||||
} \
|
||||
return; \
|
||||
} else if (out == src2) { \
|
||||
M_ASSERT(out != src1); \
|
||||
M_F(name, _read_unlock)(src1); \
|
||||
M_F(name, _write_unlock)(out); \
|
||||
return; \
|
||||
} \
|
||||
/* NOTE: No need to order the unlock */ \
|
||||
M_F(name, _read_unlock)(src1); \
|
||||
M_F(name, _read_unlock)(src2); \
|
||||
|
||||
Reference in new issue
Block a user