diff mbox series

[v1,08/12] thread: add tsan annotations to QemuSpin

Message ID 20200529132341.755-8-robert.foley@linaro.org
State Superseded
Headers show
Series Add Thread Sanitizer support to QEMU | expand

Commit Message

Robert Foley May 29, 2020, 1:23 p.m. UTC
From: "Emilio G. Cota" <cota@braap.org>


Signed-off-by: Emilio G. Cota <cota@braap.org>

Signed-off-by: Robert Foley <robert.foley@linaro.org>

---
 include/qemu/thread.h | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

-- 
2.17.1

Comments

Alex Bennée June 2, 2020, 8:14 p.m. UTC | #1
Robert Foley <robert.foley@linaro.org> writes:

> From: "Emilio G. Cota" <cota@braap.org>

>

> Signed-off-by: Emilio G. Cota <cota@braap.org>

> Signed-off-by: Robert Foley <robert.foley@linaro.org>


Reviewed-by: Alex Bennée <alex.bennee@linaro.org>


> ---

>  include/qemu/thread.h | 39 ++++++++++++++++++++++++++++++++++++---

>  1 file changed, 36 insertions(+), 3 deletions(-)

>

> diff --git a/include/qemu/thread.h b/include/qemu/thread.h

> index e50a073889..43fc094b96 100644

> --- a/include/qemu/thread.h

> +++ b/include/qemu/thread.h

> @@ -206,6 +206,10 @@ void qemu_thread_atexit_add(struct Notifier *notifier);

>   */

>  void qemu_thread_atexit_remove(struct Notifier *notifier);

>  

> +#ifdef CONFIG_TSAN

> +#include <sanitizer/tsan_interface.h>

> +#endif

> +

>  struct QemuSpin {

>      int value;

>  };

> @@ -213,23 +217,46 @@ struct QemuSpin {

>  static inline void qemu_spin_init(QemuSpin *spin)

>  {

>      __sync_lock_release(&spin->value);

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_create(spin, __tsan_mutex_not_static);

> +#endif

>  }

>  

> -static inline void qemu_spin_destroy(QemuSpin *spin)

> -{ }

> +/* const parameter because the only purpose here is the TSAN annotation */

> +static inline void qemu_spin_destroy(const QemuSpin *spin)

> +{

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_destroy((void *)spin, __tsan_mutex_not_static);

> +#endif

> +}

>  

>  static inline void qemu_spin_lock(QemuSpin *spin)

>  {

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_pre_lock(spin, 0);

> +#endif

>      while (unlikely(__sync_lock_test_and_set(&spin->value, true))) {

>          while (atomic_read(&spin->value)) {

>              cpu_relax();

>          }

>      }

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_post_lock(spin, 0, 0);

> +#endif

>  }

>  

>  static inline bool qemu_spin_trylock(QemuSpin *spin)

>  {

> -    return __sync_lock_test_and_set(&spin->value, true);

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_pre_lock(spin, __tsan_mutex_try_lock);

> +#endif

> +    bool busy = __sync_lock_test_and_set(&spin->value, true);

> +#ifdef CONFIG_TSAN

> +    unsigned flags = __tsan_mutex_try_lock;

> +    flags |= busy ? __tsan_mutex_try_lock_failed : 0;

> +    __tsan_mutex_post_lock(spin, flags, 0);

> +#endif

> +    return busy;

>  }

>  

>  static inline bool qemu_spin_locked(QemuSpin *spin)

> @@ -239,7 +266,13 @@ static inline bool qemu_spin_locked(QemuSpin *spin)

>  

>  static inline void qemu_spin_unlock(QemuSpin *spin)

>  {

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_pre_unlock(spin, 0);

> +#endif

>      __sync_lock_release(&spin->value);

> +#ifdef CONFIG_TSAN

> +    __tsan_mutex_post_unlock(spin, 0);

> +#endif

>  }

>  

>  struct QemuLockCnt {



-- 
Alex Bennée
diff mbox series

Patch

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index e50a073889..43fc094b96 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -206,6 +206,10 @@  void qemu_thread_atexit_add(struct Notifier *notifier);
  */
 void qemu_thread_atexit_remove(struct Notifier *notifier);
 
+#ifdef CONFIG_TSAN
+#include <sanitizer/tsan_interface.h>
+#endif
+
 struct QemuSpin {
     int value;
 };
@@ -213,23 +217,46 @@  struct QemuSpin {
 static inline void qemu_spin_init(QemuSpin *spin)
 {
     __sync_lock_release(&spin->value);
+#ifdef CONFIG_TSAN
+    __tsan_mutex_create(spin, __tsan_mutex_not_static);
+#endif
 }
 
-static inline void qemu_spin_destroy(QemuSpin *spin)
-{ }
+/* const parameter because the only purpose here is the TSAN annotation */
+static inline void qemu_spin_destroy(const QemuSpin *spin)
+{
+#ifdef CONFIG_TSAN
+    __tsan_mutex_destroy((void *)spin, __tsan_mutex_not_static);
+#endif
+}
 
 static inline void qemu_spin_lock(QemuSpin *spin)
 {
+#ifdef CONFIG_TSAN
+    __tsan_mutex_pre_lock(spin, 0);
+#endif
     while (unlikely(__sync_lock_test_and_set(&spin->value, true))) {
         while (atomic_read(&spin->value)) {
             cpu_relax();
         }
     }
+#ifdef CONFIG_TSAN
+    __tsan_mutex_post_lock(spin, 0, 0);
+#endif
 }
 
 static inline bool qemu_spin_trylock(QemuSpin *spin)
 {
-    return __sync_lock_test_and_set(&spin->value, true);
+#ifdef CONFIG_TSAN
+    __tsan_mutex_pre_lock(spin, __tsan_mutex_try_lock);
+#endif
+    bool busy = __sync_lock_test_and_set(&spin->value, true);
+#ifdef CONFIG_TSAN
+    unsigned flags = __tsan_mutex_try_lock;
+    flags |= busy ? __tsan_mutex_try_lock_failed : 0;
+    __tsan_mutex_post_lock(spin, flags, 0);
+#endif
+    return busy;
 }
 
 static inline bool qemu_spin_locked(QemuSpin *spin)
@@ -239,7 +266,13 @@  static inline bool qemu_spin_locked(QemuSpin *spin)
 
 static inline void qemu_spin_unlock(QemuSpin *spin)
 {
+#ifdef CONFIG_TSAN
+    __tsan_mutex_pre_unlock(spin, 0);
+#endif
     __sync_lock_release(&spin->value);
+#ifdef CONFIG_TSAN
+    __tsan_mutex_post_unlock(spin, 0);
+#endif
 }
 
 struct QemuLockCnt {