MINOR: global: declare a read_mostly section
Some variables are mostly read (mostly pointers) but they tend to be
merged with other ones in the same cache line, slowing their access down
in multi-thread setups. This patch declares an empty, aligned variable
in a section called "read_mostly". This will force a cache-line alignment
on this section so that any variable declared in it will be certain to
avoid false sharing with other ones. The section will be eliminated at
link time if not used.
A __read_mostly attribute was added to compiler.h to ease use of this
section.
diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h
index c183319..7255767 100644
--- a/include/haproxy/compiler.h
+++ b/include/haproxy/compiler.h
@@ -88,6 +88,9 @@
#endif // USE_OBSOLETE_LINKER
+/* use this attribute on a variable to move it to the read_mostly section */
+#define __read_mostly HA_SECTION("read_mostly")
+
/* This allows gcc to know that some locations are never reached, for example
* after a longjmp() in the Lua code, hence that some errors caught by such
* methods cannot propagate further. This is important with gcc versions 6 and
diff --git a/src/haproxy.c b/src/haproxy.c
index 407ce42..3d5e85f 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -135,6 +135,16 @@
/* array of init calls for older platforms */
DECLARE_INIT_STAGES;
+/* create a read_mostly section to hold variables which are accessed a lot
+ * but which almost never change. The purpose is to isolate them in their
+ * own cache lines where they don't risk to be perturbated by write accesses
+ * to neighbor variables. We need to create an empty aligned variable for
+ * this. The fact that the variable is of size zero means that it will be
+ * eliminated at link time if no other variable uses it, but alignment will
+ * be respected.
+ */
+empty_t __read_mostly_align HA_SECTION("read_mostly") ALIGNED(64);
+
/* list of config files */
static struct list cfg_cfgfiles = LIST_HEAD_INIT(cfg_cfgfiles);
int pid; /* current process id */