Make the liburing header files again compatible with C++

Include <atomic> instead of <stdatomic.h> if built with a C++ compiler.

Fixes: b9c0bf79aa87 ("src/include/liburing/barrier.h: Use C11 atomics")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/src/include/liburing.h b/src/include/liburing.h
index c9034fc..76e2b85 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -2,10 +2,6 @@
 #ifndef LIB_URING_H
 #define LIB_URING_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include <sys/stat.h>
@@ -19,6 +15,10 @@
 #include "liburing/io_uring.h"
 #include "liburing/barrier.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Library interface to io_uring
  */
diff --git a/src/include/liburing/barrier.h b/src/include/liburing/barrier.h
index 5732434..a4a59fb 100644
--- a/src/include/liburing/barrier.h
+++ b/src/include/liburing/barrier.h
@@ -2,8 +2,6 @@
 #ifndef LIBURING_BARRIER_H
 #define LIBURING_BARRIER_H
 
-#include <stdatomic.h>
-
 /*
 From the kernel documentation file refcount-vs-atomic.rst:
 
@@ -23,6 +21,40 @@
 :c:func:`smp_acquire__after_ctrl_dep`.
 */
 
+#ifdef __cplusplus
+#include <atomic>
+
+template <typename T>
+static inline void IO_URING_WRITE_ONCE(T &var, T val)
+{
+	std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(&var),
+				   val, std::memory_order_relaxed);
+}
+template <typename T>
+static inline T IO_URING_READ_ONCE(const T &var)
+{
+	return std::atomic_load_explicit(
+		reinterpret_cast<const std::atomic<T> *>(&var),
+		std::memory_order_relaxed);
+}
+
+template <typename T>
+static inline void io_uring_smp_store_release(T *p, T v)
+{
+	std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(p), v,
+				   std::memory_order_release);
+}
+
+template <typename T>
+static inline T io_uring_smp_load_acquire(const T *p)
+{
+	return std::atomic_load_explicit(
+		reinterpret_cast<const std::atomic<T> *>(p),
+		std::memory_order_acquire);
+}
+#else
+#include <stdatomic.h>
+
 #define IO_URING_WRITE_ONCE(var, val)				\
 	atomic_store_explicit((_Atomic typeof(var) *)&(var),	\
 			      (val), memory_order_relaxed)
@@ -36,5 +68,6 @@
 #define io_uring_smp_load_acquire(p)				\
 	atomic_load_explicit((_Atomic typeof(*(p)) *)(p),	\
 			     memory_order_acquire)
+#endif
 
 #endif /* defined(LIBURING_BARRIER_H) */
diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h
index 785a6a4..6a73522 100644
--- a/src/include/liburing/io_uring.h
+++ b/src/include/liburing/io_uring.h
@@ -11,6 +11,10 @@
 #include <linux/fs.h>
 #include <linux/types.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * IO submission data structure (Submission Queue Entry)
  */
@@ -289,4 +293,8 @@
 	struct io_uring_probe_op ops[0];
 };
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif