diff options
author | Bhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com> | 2017-07-25 05:14:43 +0100 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2017-08-03 11:31:18 -0700 |
commit | 73e713fc7b69984f75e5947397f9599eb4fb0f83 (patch) | |
tree | f5eca8cb4460c9d68863f5a0d4ec430435b18163 | |
parent | fbe061cbec75d3f22e84532f624aac2d537e6ba3 (diff) | |
download | openvswitch-73e713fc7b69984f75e5947397f9599eb4fb0f83.tar.gz |
util: Add PADDED_MEMBERS_CACHELINE_MARKER macro to mark cachelines.
PADDED_MEMBERS_CACHELINE_MARKER macro introduces a way to mark
cachelines.
This macro expands to an anonymous union containing cacheline marker,
members in nested anonymous structure, followed by array of bytes that
is multiple of UNIT bytes.
Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
-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) { |