Avoid false sharing for snapshot by aligning properly the
data of the triple buffer to a cache boundary.
This commit is contained in:
1 parent
c71de15cb0
commit
67856a98af
1 file changed
+18
-12
+18
-12
@@ -99,8 +99,14 @@
|
||||
|
||||
#define SNAPSHOTI_DEF2(name, type, oplist) \
|
||||
\
|
||||
/* Create an aligned type to avoid false sharing between threads */ \
|
||||
typedef struct M_C(name, _aligned_type_s) { \
|
||||
type x; \
|
||||
char align[M_ALIGN_FOR_CACHELINE_EXCLUSION > sizeof(type) ? M_ALIGN_FOR_CACHELINE_EXCLUSION - - sizeof(type) : 1]; \
|
||||
} M_C(name, _aligned_type_t); \
|
||||
\
|
||||
typedef struct M_C(name, _s) { \
|
||||
type data[SNAPSHOTI_MAX_BUFFER]; \
|
||||
M_C(name, _aligned_type_t) data[SNAPSHOTI_MAX_BUFFER]; \
|
||||
atomic_uchar flags; \
|
||||
} M_C(name, _t)[1]; \
|
||||
\
|
||||
@@ -110,7 +116,7 @@
|
||||
{ \
|
||||
assert(snap != NULL); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_INIT oplist(snap->data[i]); \
|
||||
M_GET_INIT oplist(snap->data[i].x); \
|
||||
} \
|
||||
atomic_init (&snap->flags, SNAPSHOTI_FLAG(0, 1, 2, 0)); \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
@@ -120,17 +126,17 @@
|
||||
{ \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_CLEAR oplist(snap->data[i]); \
|
||||
M_GET_CLEAR oplist(snap->data[i].x); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void M_C(name, _init_set)(M_C(name, _t) snap, \
|
||||
M_C(name, _t) org) \
|
||||
{ \
|
||||
SNAPSHOTI_CONTRACT(org); \
|
||||
assert(snap != NULL && snap != org); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_INIT_SET oplist(snap->data[i], org->data[i]); \
|
||||
M_GET_INIT_SET oplist(snap->data[i].x, org->data[i].x); \
|
||||
} \
|
||||
atomic_init (&snap->flags, atomic_load(&org->flags)); \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
@@ -142,7 +148,7 @@
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
SNAPSHOTI_CONTRACT(org); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_SET oplist(snap->data[i], org->data[i]); \
|
||||
M_GET_SET oplist(snap->data[i].x, org->data[i].x); \
|
||||
} \
|
||||
atomic_init (&snap->flags, atomic_load(&org->flags)); \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
@@ -155,7 +161,7 @@
|
||||
SNAPSHOTI_CONTRACT(org); \
|
||||
assert(snap != NULL && snap != org); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_INIT_MOVE oplist(snap->data[i], org->data[i]); \
|
||||
M_GET_INIT_MOVE oplist(snap->data[i].x, org->data[i].x); \
|
||||
} \
|
||||
atomic_store (&snap->flags, atomic_load(&org->flags)); \
|
||||
atomic_store (&org->flags, SNAPSHOTI_FLAG(0,0,0,0) ); \
|
||||
@@ -171,7 +177,7 @@
|
||||
SNAPSHOTI_CONTRACT(org); \
|
||||
assert(snap != org); \
|
||||
for(int i = 0; i < SNAPSHOTI_MAX_BUFFER; i++) { \
|
||||
M_GET_MOVE oplist(snap->data[i], org->data[i]); \
|
||||
M_GET_MOVE oplist(snap->data[i].x, org->data[i].x); \
|
||||
} \
|
||||
atomic_store (&snap->flags, atomic_load(&org->flags)); \
|
||||
atomic_store (&org->flags, SNAPSHOTI_FLAG(0,0,0,0) ); \
|
||||
@@ -194,7 +200,7 @@
|
||||
} while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \
|
||||
nextFlags)); \
|
||||
/* Return new write buffer for new updating */ \
|
||||
return &snap->data[SNAPSHOTI_W(nextFlags)]; \
|
||||
return &snap->data[SNAPSHOTI_W(nextFlags)].x; \
|
||||
} \
|
||||
\
|
||||
static inline const type *M_C(name, _read)(M_C(name, _t) snap) \
|
||||
@@ -216,7 +222,7 @@
|
||||
} while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \
|
||||
nextFlags)); \
|
||||
/* Return current read buffer */ \
|
||||
return M_CONST_CAST(type, &snap->data[SNAPSHOTI_R(nextFlags)]); \
|
||||
return M_CONST_CAST(type, &snap->data[SNAPSHOTI_R(nextFlags)].x); \
|
||||
} \
|
||||
\
|
||||
static inline bool M_C(name, _updated_p)(M_C(name, _t) snap) \
|
||||
@@ -230,14 +236,14 @@
|
||||
{ \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
unsigned char flags = atomic_load(&snap->flags); \
|
||||
return &snap->data[SNAPSHOTI_W(flags)]; \
|
||||
return &snap->data[SNAPSHOTI_W(flags)].x; \
|
||||
} \
|
||||
\
|
||||
static inline const type *M_C(name, _get_read_buffer)(M_C(name, _t) snap) \
|
||||
{ \
|
||||
SNAPSHOTI_CONTRACT(snap); \
|
||||
unsigned char flags = atomic_load(&snap->flags); \
|
||||
return M_CONST_CAST(type, &snap->data[SNAPSHOTI_R(flags)]); \
|
||||
return M_CONST_CAST(type, &snap->data[SNAPSHOTI_R(flags)].x); \
|
||||
} \
|
||||
|
||||
// FIXME: Method SWAP ?
|
||||
|
||||
Reference in new issue
Block a user