diff options
-rw-r--r-- | include/openvswitch/util.h | 48 | ||||
-rw-r--r-- | lib/util.h | 6 |
2 files changed, 54 insertions, 0 deletions
diff --git a/include/openvswitch/util.h b/include/openvswitch/util.h index 5d6d453f7..abebf96fa 100644 --- a/include/openvswitch/util.h +++ b/include/openvswitch/util.h @@ -193,6 +193,54 @@ OVS_NO_RETURN void ovs_assert_failure(const char *, const char *, const char *); } #endif +/* Similar to PADDED_MEMBERS with additional cacheline marker: + * + * - OVS_CACHE_LINE_MARKER is a cacheline marker + * - MEMBERS in a nested anonymous struct. + * - An array as large as MEMBERS plus padding to a multiple of UNIT bytes. + * + * The effect is to add cacheline marker and pad MEMBERS to a multiple of + * UNIT bytes. + * + * Example: + * struct padded_struct { + * PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, + * uint8_t x; + * uint8_t y; + * ); + * }; + * + * The PADDED_MEMBERS_CACHELINE_MARKER macro in above structure expands as: + * + * struct padded_struct { + * union { + * OVS_CACHE_LINE_MARKER cacheline0; + * struct { + * uint8_t x; + * uint8_t y; + * }; + * uint8_t pad0[64]; + * }; + * *--- cacheline 1 boundary (64 bytes) ---* + * }; + */ +#ifndef __cplusplus +#define PADDED_MEMBERS_CACHELINE_MARKER(UNIT, CACHELINE, MEMBERS) \ + union { \ + OVS_CACHE_LINE_MARKER CACHELINE; \ + struct { MEMBERS }; \ + uint8_t PAD_ID[ROUND_UP(sizeof(struct { MEMBERS }), UNIT)]; \ + } +#else +#define PADDED_MEMBERS_CACHELINE_MARKER(UNIT, CACHELINE, MEMBERS) \ + union { \ + OVS_CACHE_LINE_MARKER CACHELINE; \ + struct { MEMBERS }; \ + struct { MEMBERS } named_member__; \ + uint8_t PAD_ID[ROUND_UP(sizeof named_member__, UNIT)]; \ + } +#endif + static inline bool is_pow2(uintmax_t x) { diff --git a/lib/util.h b/lib/util.h index c45e6ebdb..764e0a08a 100644 --- a/lib/util.h +++ b/lib/util.h @@ -51,6 +51,12 @@ extern char *program_name; #define CACHE_LINE_SIZE 64 BUILD_ASSERT_DECL(IS_POW2(CACHE_LINE_SIZE)); +/* Cacheline marking is typically done using zero-sized array. + * However MSVC doesn't like zero-sized array in struct/union. + * C4200: https://msdn.microsoft.com/en-us/library/79wf64bc.aspx + */ +typedef uint8_t OVS_CACHE_LINE_MARKER[1]; + static inline void ovs_prefetch_range(const void *start, size_t size) { |