aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-06-17 10:42:57 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-06-17 10:42:57 +0100
commit18e53dff939898c6dd00d206a3c2f5cd3d6669db (patch)
tree612ff698fdf3d3032f8aecfe98b35abd870cb27f /include
parent38848ce565849e5b867a5e08022b3c755039c11a (diff)
parentc7a7cb5692690ad621b6eb2d1c7256907ff45d67 (diff)
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-c11-20210615' into staging
Change to -std=gnu11. Replace QEMU_GENERIC with _Generic. Remove configure detect of _Static_assert. # gpg: Signature made Wed 16 Jun 2021 02:32:32 BST # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * remotes/rth-gitlab/tags/pull-c11-20210615: configure: Remove probe for _Static_assert qemu/compiler: Remove QEMU_GENERIC include/qemu/lockable: Use _Generic instead of QEMU_GENERIC util: Use unique type for QemuRecMutex in thread-posix.h util: Pass file+line to qemu_rec_mutex_unlock_impl util: Use real functions for thread-posix QemuRecMutex softfloat: Use _Generic instead of QEMU_GENERIC configure: Use -std=gnu11 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/qemu/compiler.h51
-rw-r--r--include/qemu/lockable.h88
-rw-r--r--include/qemu/thread-posix.h14
-rw-r--r--include/qemu/thread-win32.h6
-rw-r--r--include/qemu/thread.h15
5 files changed, 61 insertions, 113 deletions
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 091c45248b..3baa5e3790 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -72,18 +72,7 @@
int:(x) ? -1 : 1; \
}
-/* QEMU_BUILD_BUG_MSG() emits the message given if _Static_assert is
- * supported; otherwise, it will be omitted from the compiler error
- * message (but as it remains present in the source code, it can still
- * be useful when debugging). */
-#if defined(CONFIG_STATIC_ASSERT)
#define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg)
-#elif defined(__COUNTER__)
-#define QEMU_BUILD_BUG_MSG(x, msg) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \
- glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused))
-#else
-#define QEMU_BUILD_BUG_MSG(x, msg)
-#endif
#define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x)
@@ -173,46 +162,6 @@
#define QEMU_ALWAYS_INLINE
#endif
-/* Implement C11 _Generic via GCC builtins. Example:
- *
- * QEMU_GENERIC(x, (float, sinf), (long double, sinl), sin) (x)
- *
- * The first argument is the discriminator. The last is the default value.
- * The middle ones are tuples in "(type, expansion)" format.
- */
-
-/* First, find out the number of generic cases. */
-#define QEMU_GENERIC(x, ...) \
- QEMU_GENERIC_(typeof(x), __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
-
-/* There will be extra arguments, but they are not used. */
-#define QEMU_GENERIC_(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, count, ...) \
- QEMU_GENERIC##count(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
-
-/* Two more helper macros, this time to extract items from a parenthesized
- * list.
- */
-#define QEMU_FIRST_(a, b) a
-#define QEMU_SECOND_(a, b) b
-
-/* ... and a final one for the common part of the "recursion". */
-#define QEMU_GENERIC_IF(x, type_then, else_) \
- __builtin_choose_expr(__builtin_types_compatible_p(x, \
- QEMU_FIRST_ type_then), \
- QEMU_SECOND_ type_then, else_)
-
-/* CPP poor man's "recursion". */
-#define QEMU_GENERIC1(x, a0, ...) (a0)
-#define QEMU_GENERIC2(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC1(x, __VA_ARGS__))
-#define QEMU_GENERIC3(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC2(x, __VA_ARGS__))
-#define QEMU_GENERIC4(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC3(x, __VA_ARGS__))
-#define QEMU_GENERIC5(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC4(x, __VA_ARGS__))
-#define QEMU_GENERIC6(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC5(x, __VA_ARGS__))
-#define QEMU_GENERIC7(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC6(x, __VA_ARGS__))
-#define QEMU_GENERIC8(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC7(x, __VA_ARGS__))
-#define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__))
-#define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__))
-
/**
* qemu_build_not_reached()
*
diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h
index b620023141..86db7cb04c 100644
--- a/include/qemu/lockable.h
+++ b/include/qemu/lockable.h
@@ -24,79 +24,71 @@ struct QemuLockable {
QemuLockUnlockFunc *unlock;
};
-/* This function gives an error if an invalid, non-NULL pointer type is passed
- * to QEMU_MAKE_LOCKABLE. For optimized builds, we can rely on dead-code elimination
- * from the compiler, and give the errors already at link time.
- */
-#if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__)
-void unknown_lock_type(void *);
-#else
-static inline void unknown_lock_type(void *unused)
-{
- abort();
-}
-#endif
-
static inline __attribute__((__always_inline__)) QemuLockable *
qemu_make_lockable(void *x, QemuLockable *lockable)
{
- /* We cannot test this in a macro, otherwise we get compiler
+ /*
+ * We cannot test this in a macro, otherwise we get compiler
* warnings like "the address of 'm' will always evaluate as 'true'".
*/
return x ? lockable : NULL;
}
-/* Auxiliary macros to simplify QEMU_MAKE_LOCABLE. */
-#define QEMU_LOCK_FUNC(x) ((QemuLockUnlockFunc *) \
- QEMU_GENERIC(x, \
- (QemuMutex *, qemu_mutex_lock), \
- (QemuRecMutex *, qemu_rec_mutex_lock), \
- (CoMutex *, qemu_co_mutex_lock), \
- (QemuSpin *, qemu_spin_lock), \
- unknown_lock_type))
-
-#define QEMU_UNLOCK_FUNC(x) ((QemuLockUnlockFunc *) \
- QEMU_GENERIC(x, \
- (QemuMutex *, qemu_mutex_unlock), \
- (QemuRecMutex *, qemu_rec_mutex_unlock), \
- (CoMutex *, qemu_co_mutex_unlock), \
- (QemuSpin *, qemu_spin_unlock), \
- unknown_lock_type))
-
-/* In C, compound literals have the lifetime of an automatic variable.
+static inline __attribute__((__always_inline__)) QemuLockable *
+qemu_null_lockable(void *x)
+{
+ if (x != NULL) {
+ qemu_build_not_reached();
+ }
+ return NULL;
+}
+
+/*
+ * In C, compound literals have the lifetime of an automatic variable.
* In C++ it would be different, but then C++ wouldn't need QemuLockable
* either...
*/
-#define QEMU_MAKE_LOCKABLE_(x) (&(QemuLockable) { \
- .object = (x), \
- .lock = QEMU_LOCK_FUNC(x), \
- .unlock = QEMU_UNLOCK_FUNC(x), \
+#define QML_OBJ_(x, name) (&(QemuLockable) { \
+ .object = (x), \
+ .lock = (QemuLockUnlockFunc *) qemu_ ## name ## _lock, \
+ .unlock = (QemuLockUnlockFunc *) qemu_ ## name ## _unlock \
})
-/* QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable
+/**
+ * QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable
*
- * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin).
+ * @x: a lock object (currently one of QemuMutex, QemuRecMutex,
+ * CoMutex, QemuSpin).
*
* Returns a QemuLockable object that can be passed around
* to a function that can operate with locks of any kind, or
* NULL if @x is %NULL.
+ *
+ * Note the special case for void *, so that we may pass "NULL".
*/
-#define QEMU_MAKE_LOCKABLE(x) \
- QEMU_GENERIC(x, \
- (QemuLockable *, (x)), \
- qemu_make_lockable((x), QEMU_MAKE_LOCKABLE_(x)))
+#define QEMU_MAKE_LOCKABLE(x) \
+ _Generic((x), QemuLockable *: (x), \
+ void *: qemu_null_lockable(x), \
+ QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)), \
+ QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x, rec_mutex)), \
+ CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)), \
+ QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))
-/* QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
+/**
+ * QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
*
- * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin).
+ * @x: a lock object (currently one of QemuMutex, QemuRecMutex,
+ * CoMutex, QemuSpin).
*
* Returns a QemuLockable object that can be passed around
* to a function that can operate with locks of any kind.
*/
-#define QEMU_MAKE_LOCKABLE_NONNULL(x) \
- QEMU_GENERIC(x, \
- (QemuLockable *, (x)), \
- QEMU_MAKE_LOCKABLE_(x))
+#define QEMU_MAKE_LOCKABLE_NONNULL(x) \
+ _Generic((x), QemuLockable *: (x), \
+ QemuMutex *: QML_OBJ_(x, mutex), \
+ QemuRecMutex *: QML_OBJ_(x, rec_mutex), \
+ CoMutex *: QML_OBJ_(x, co_mutex), \
+ QemuSpin *: QML_OBJ_(x, spin))
static inline void qemu_lockable_lock(QemuLockable *x)
{
diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index c903525062..b792e6ef37 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -4,12 +4,6 @@
#include <pthread.h>
#include <semaphore.h>
-typedef QemuMutex QemuRecMutex;
-#define qemu_rec_mutex_destroy qemu_mutex_destroy
-#define qemu_rec_mutex_lock_impl qemu_mutex_lock_impl
-#define qemu_rec_mutex_trylock_impl qemu_mutex_trylock_impl
-#define qemu_rec_mutex_unlock qemu_mutex_unlock
-
struct QemuMutex {
pthread_mutex_t lock;
#ifdef CONFIG_DEBUG_MUTEX
@@ -19,6 +13,14 @@ struct QemuMutex {
bool initialized;
};
+/*
+ * QemuRecMutex cannot be a typedef of QemuMutex lest we have two
+ * compatible cases in _Generic. See qemu/lockable.h.
+ */
+typedef struct QemuRecMutex {
+ QemuMutex m;
+} QemuRecMutex;
+
struct QemuCond {
pthread_cond_t cond;
bool initialized;
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
index d0a1a9597e..d95af4498f 100644
--- a/include/qemu/thread-win32.h
+++ b/include/qemu/thread-win32.h
@@ -18,12 +18,6 @@ struct QemuRecMutex {
bool initialized;
};
-void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
-void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line);
-int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file,
- int line);
-void qemu_rec_mutex_unlock(QemuRecMutex *mutex);
-
struct QemuCond {
CONDITION_VARIABLE var;
bool initialized;
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 5435763184..460568d67d 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -28,6 +28,12 @@ int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line);
+void qemu_rec_mutex_init(QemuRecMutex *mutex);
+void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
+void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line);
+int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line);
+void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line);
+
typedef void (*QemuMutexLockFunc)(QemuMutex *m, const char *f, int l);
typedef int (*QemuMutexTrylockFunc)(QemuMutex *m, const char *f, int l);
typedef void (*QemuRecMutexLockFunc)(QemuRecMutex *m, const char *f, int l);
@@ -104,6 +110,9 @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
#define qemu_mutex_unlock(mutex) \
qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__)
+#define qemu_rec_mutex_unlock(mutex) \
+ qemu_rec_mutex_unlock_impl(mutex, __FILE__, __LINE__)
+
static inline void (qemu_mutex_lock)(QemuMutex *mutex)
{
qemu_mutex_lock(mutex);
@@ -129,8 +138,10 @@ static inline int (qemu_rec_mutex_trylock)(QemuRecMutex *mutex)
return qemu_rec_mutex_trylock(mutex);
}
-/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */
-void qemu_rec_mutex_init(QemuRecMutex *mutex);
+static inline void (qemu_rec_mutex_unlock)(QemuRecMutex *mutex)
+{
+ qemu_rec_mutex_unlock(mutex);
+}
void qemu_cond_init(QemuCond *cond);
void qemu_cond_destroy(QemuCond *cond);