summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com>2017-07-25 05:14:43 +0100
committerBen Pfaff <blp@ovn.org>2017-08-03 11:31:18 -0700
commit73e713fc7b69984f75e5947397f9599eb4fb0f83 (patch)
treef5eca8cb4460c9d68863f5a0d4ec430435b18163
parentfbe061cbec75d3f22e84532f624aac2d537e6ba3 (diff)
downloadopenvswitch-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.h48
-rw-r--r--lib/util.h6
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)
{