summaryrefslogtreecommitdiffstats
path: root/src/fundamental
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@canonical.com>2021-05-19 16:01:59 +0200
committerDan Streetman <ddstreet@canonical.com>2021-05-20 21:39:15 +0200
commitea42da38258ee182201ecc6c9afb18a9ea46021c (patch)
tree0b762dd3b8d684324b5c05813648bbc35819591e /src/fundamental
parentfileio: make return parameters of read_virtual_file() optional (diff)
downloadsystemd-ea42da38258ee182201ecc6c9afb18a9ea46021c.tar.xz
systemd-ea42da38258ee182201ecc6c9afb18a9ea46021c.zip
macro: add ONCE macro that evaluates to 1 one time
Every location that this macro is used, it will be true the first time it's checked, then false each time after that. This can be useful for things such as one-time logging.
Diffstat (limited to 'src/fundamental')
-rw-r--r--src/fundamental/macro-fundamental.h11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
index 6ff8372f3c..967518600d 100644
--- a/src/fundamental/macro-fundamental.h
+++ b/src/fundamental/macro-fundamental.h
@@ -50,6 +50,17 @@
#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
#define UNIQ __COUNTER__
+/* Note that this works differently from pthread_once(): this macro does
+ * not synchronize code execution, i.e. code that is run conditionalized
+ * on this macro will run concurrently to all other code conditionalized
+ * the same way, there's no ordering or completion enforced. */
+#define ONCE __ONCE(UNIQ_T(_once_, UNIQ))
+#define __ONCE(o) \
+ ({ \
+ static bool (o) = false; \
+ __sync_bool_compare_and_swap(&(o), false, true); \
+ })
+
#undef MAX
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
#define __MAX(aq, a, bq, b) \