Skip to content

Commit

Permalink
arch,lib/seqlock: implement seqlock with C++ atomic if compiled with C++
Browse files Browse the repository at this point in the history
because some functions declared by <stdatomic.h> share the same names
with those declared by <atomic>, for instance `kill_dependency()` is
defined as a macro by <stdatomic.h>, while it is defined as a template
function in <atomic>.

this renders it impossible to compile an ioengine written in C++ if
its source file includes both <atomic> and <fio.h>. the latter includes
<stdatomic.h> via arch/arch.h. the compile error would look like:

In file included from ../src/test/fio/fio_ceph_objectstore.cc:26:
In file included from src/fio/fio.h:18:
In file included from src/fio/thread_options.h:8:
In file included from src/fio/gettime.h:7:
src/fio/lib/seqlock.h:21:9: error: expected ')'
                seq = atomic_load_acquire(&s->sequence);
                      ^
src/fio/arch/../lib/../arch/arch.h:47:32: note: expanded from macro 'atomic_load_acquire'
        atomic_load_explicit((_Atomic typeof(*(p)) *)(p),       \
                                      ^
src/fio/lib/seqlock.h:21:9: note: to match this '('

to address this issue, instead of using the functions in <stdatomic.h> to
implement seqlock, use the primitives offered by C++ standard library
if the source code is compiled using a C++ compiler.

Signed-off-by: Kefu Chai <[email protected]>
  • Loading branch information
tchaikov committed Aug 25, 2021
1 parent 15ce99b commit 33ab690
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
20 changes: 20 additions & 0 deletions arch/arch.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#ifndef ARCH_H
#define ARCH_H

#ifdef __cplusplus
#include <atomic>
#else
#include <stdatomic.h>
#endif

#include "../lib/types.h"

Expand Down Expand Up @@ -36,6 +40,21 @@ extern unsigned long arch_flags;

#define ARCH_CPU_CLOCK_WRAPS

#ifdef __cplusplus
#define atomic_add(p, v) \
std::atomic_fetch_add(p, (v))
#define atomic_sub(p, v) \
std::atomic_fetch_sub(p, (v))
#define atomic_load_relaxed(p) \
std::atomic_load_explicit(p, \
std::memory_order_relaxed)
#define atomic_load_acquire(p) \
std::atomic_load_explicit(p, \
std::memory_order_acquire)
#define atomic_store_release(p, v) \
std::atomic_store_explicit(p, (v), \
std::memory_order_release)
#else
#define atomic_add(p, v) \
atomic_fetch_add((_Atomic typeof(*(p)) *)(p), v)
#define atomic_sub(p, v) \
Expand All @@ -49,6 +68,7 @@ extern unsigned long arch_flags;
#define atomic_store_release(p, v) \
atomic_store_explicit((_Atomic typeof(*(p)) *)(p), (v), \
memory_order_release)
#endif

/* IWYU pragma: begin_exports */
#if defined(__i386__)
Expand Down
4 changes: 4 additions & 0 deletions lib/seqlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
#include "../arch/arch.h"

struct seqlock {
#ifdef __cplusplus
std::atomic<unsigned int> sequence;
#else
volatile unsigned int sequence;
#endif
};

static inline void seqlock_init(struct seqlock *s)
Expand Down

0 comments on commit 33ab690

Please sign in to comment.