]> git.proxmox.com Git - mirror_qemu.git/blobdiff - util/qsp.c
bsd-user: Implement host_to_target_waitstatus conversion.
[mirror_qemu.git] / util / qsp.c
index 5264c973420bfb5a6aabc9f50862a2baba639aa1..2fe3764906c53c53ec08572fc165c6f441241e19 100644 (file)
@@ -83,8 +83,8 @@ typedef struct QSPCallSite QSPCallSite;
 struct QSPEntry {
     void *thread_ptr;
     const QSPCallSite *callsite;
-    uint64_t n_acqs;
-    uint64_t ns;
+    aligned_uint64_t n_acqs;
+    aligned_uint64_t ns;
     unsigned int n_objs; /* count of coalesced objs; only used for reporting */
 };
 typedef struct QSPEntry QSPEntry;
@@ -131,6 +131,7 @@ QemuRecMutexLockFunc qemu_rec_mutex_lock_func = qemu_rec_mutex_lock_impl;
 QemuRecMutexTrylockFunc qemu_rec_mutex_trylock_func =
     qemu_rec_mutex_trylock_impl;
 QemuCondWaitFunc qemu_cond_wait_func = qemu_cond_wait_impl;
+QemuCondTimedWaitFunc qemu_cond_timedwait_func = qemu_cond_timedwait_impl;
 
 /*
  * It pays off to _not_ hash callsite->file; hashing a string is slow, and
@@ -143,7 +144,7 @@ uint32_t do_qsp_callsite_hash(const QSPCallSite *callsite, uint64_t ab)
     uint32_t e = callsite->line;
     uint32_t f = callsite->type;
 
-    return qemu_xxhash6(ab, cd, e, f);
+    return qemu_xxhash8(ab, cd, 0, e, f);
 }
 
 static inline
@@ -244,11 +245,11 @@ static void qsp_do_init(void)
 
 static __attribute__((noinline)) void qsp_init__slowpath(void)
 {
-    if (atomic_cmpxchg(&qsp_initializing, false, true) == false) {
+    if (qatomic_cmpxchg(&qsp_initializing, false, true) == false) {
         qsp_do_init();
-        atomic_set(&qsp_initialized, true);
+        qatomic_set(&qsp_initialized, true);
     } else {
-        while (!atomic_read(&qsp_initialized)) {
+        while (!qatomic_read(&qsp_initialized)) {
             cpu_relax();
         }
     }
@@ -257,7 +258,7 @@ static __attribute__((noinline)) void qsp_init__slowpath(void)
 /* qsp_init() must be called from _all_ exported functions */
 static inline void qsp_init(void)
 {
-    if (likely(atomic_read(&qsp_initialized))) {
+    if (likely(qatomic_read(&qsp_initialized))) {
         return;
     }
     qsp_init__slowpath();
@@ -345,9 +346,9 @@ static QSPEntry *qsp_entry_get(const void *obj, const char *file, int line,
  */
 static inline void do_qsp_entry_record(QSPEntry *e, int64_t delta, bool acq)
 {
-    atomic_set_u64(&e->ns, e->ns + delta);
+    qatomic_set_u64(&e->ns, e->ns + delta);
     if (acq) {
-        atomic_set_u64(&e->n_acqs, e->n_acqs + 1);
+        qatomic_set_u64(&e->n_acqs, e->n_acqs + 1);
     }
 }
 
@@ -412,29 +413,48 @@ qsp_cond_wait(QemuCond *cond, QemuMutex *mutex, const char *file, int line)
     qsp_entry_record(e, t1 - t0);
 }
 
+static bool
+qsp_cond_timedwait(QemuCond *cond, QemuMutex *mutex, int ms,
+                   const char *file, int line)
+{
+    QSPEntry *e;
+    int64_t t0, t1;
+    bool ret;
+
+    t0 = get_clock();
+    ret = qemu_cond_timedwait_impl(cond, mutex, ms, file, line);
+    t1 = get_clock();
+
+    e = qsp_entry_get(cond, file, line, QSP_CONDVAR);
+    qsp_entry_record(e, t1 - t0);
+    return ret;
+}
+
 bool qsp_is_enabled(void)
 {
-    return atomic_read(&qemu_mutex_lock_func) == qsp_mutex_lock;
+    return qatomic_read(&qemu_mutex_lock_func) == qsp_mutex_lock;
 }
 
 void qsp_enable(void)
 {
-    atomic_set(&qemu_mutex_lock_func, qsp_mutex_lock);
-    atomic_set(&qemu_mutex_trylock_func, qsp_mutex_trylock);
-    atomic_set(&qemu_bql_mutex_lock_func, qsp_bql_mutex_lock);
-    atomic_set(&qemu_rec_mutex_lock_func, qsp_rec_mutex_lock);
-    atomic_set(&qemu_rec_mutex_trylock_func, qsp_rec_mutex_trylock);
-    atomic_set(&qemu_cond_wait_func, qsp_cond_wait);
+    qatomic_set(&qemu_mutex_lock_func, qsp_mutex_lock);
+    qatomic_set(&qemu_mutex_trylock_func, qsp_mutex_trylock);
+    qatomic_set(&qemu_bql_mutex_lock_func, qsp_bql_mutex_lock);
+    qatomic_set(&qemu_rec_mutex_lock_func, qsp_rec_mutex_lock);
+    qatomic_set(&qemu_rec_mutex_trylock_func, qsp_rec_mutex_trylock);
+    qatomic_set(&qemu_cond_wait_func, qsp_cond_wait);
+    qatomic_set(&qemu_cond_timedwait_func, qsp_cond_timedwait);
 }
 
 void qsp_disable(void)
 {
-    atomic_set(&qemu_mutex_lock_func, qemu_mutex_lock_impl);
-    atomic_set(&qemu_mutex_trylock_func, qemu_mutex_trylock_impl);
-    atomic_set(&qemu_bql_mutex_lock_func, qemu_mutex_lock_impl);
-    atomic_set(&qemu_rec_mutex_lock_func, qemu_rec_mutex_lock_impl);
-    atomic_set(&qemu_rec_mutex_trylock_func, qemu_rec_mutex_trylock_impl);
-    atomic_set(&qemu_cond_wait_func, qemu_cond_wait_impl);
+    qatomic_set(&qemu_mutex_lock_func, qemu_mutex_lock_impl);
+    qatomic_set(&qemu_mutex_trylock_func, qemu_mutex_trylock_impl);
+    qatomic_set(&qemu_bql_mutex_lock_func, qemu_mutex_lock_impl);
+    qatomic_set(&qemu_rec_mutex_lock_func, qemu_rec_mutex_lock_impl);
+    qatomic_set(&qemu_rec_mutex_trylock_func, qemu_rec_mutex_trylock_impl);
+    qatomic_set(&qemu_cond_wait_func, qemu_cond_wait_impl);
+    qatomic_set(&qemu_cond_timedwait_func, qemu_cond_timedwait_impl);
 }
 
 static gint qsp_tree_cmp(gconstpointer ap, gconstpointer bp, gpointer up)
@@ -518,8 +538,8 @@ static void qsp_aggregate(void *p, uint32_t h, void *up)
      * The entry is in the global hash table; read from it atomically (as in
      * "read once").
      */
-    agg->ns += atomic_read_u64(&e->ns);
-    agg->n_acqs += atomic_read_u64(&e->n_acqs);
+    agg->ns += qatomic_read_u64(&e->ns);
+    agg->n_acqs += qatomic_read_u64(&e->n_acqs);
 }
 
 static void qsp_iter_diff(void *p, uint32_t hash, void *htp)
@@ -578,7 +598,6 @@ static void qsp_ht_delete(void *p, uint32_t h, void *htp)
 
 static void qsp_mktree(GTree *tree, bool callsite_coalesce)
 {
-    QSPSnapshot *snap;
     struct qht ht, coalesce_ht;
     struct qht *htp;
 
@@ -590,20 +609,19 @@ static void qsp_mktree(GTree *tree, bool callsite_coalesce)
      * We must remain in an RCU read-side critical section until we're done
      * with the snapshot.
      */
-    rcu_read_lock();
-    snap = atomic_rcu_read(&qsp_snapshot);
+    WITH_RCU_READ_LOCK_GUARD() {
+        QSPSnapshot *snap = qatomic_rcu_read(&qsp_snapshot);
 
-    /* Aggregate all results from the global hash table into a local one */
-    qht_init(&ht, qsp_entry_no_thread_cmp, QSP_INITIAL_SIZE,
-             QHT_MODE_AUTO_RESIZE | QHT_MODE_RAW_MUTEXES);
-    qht_iter(&qsp_ht, qsp_aggregate, &ht);
+        /* Aggregate all results from the global hash table into a local one */
+        qht_init(&ht, qsp_entry_no_thread_cmp, QSP_INITIAL_SIZE,
+                 QHT_MODE_AUTO_RESIZE | QHT_MODE_RAW_MUTEXES);
+        qht_iter(&qsp_ht, qsp_aggregate, &ht);
 
-    /* compute the difference wrt the snapshot, if any */
-    if (snap) {
-        qsp_diff(&snap->ht, &ht);
+        /* compute the difference wrt the snapshot, if any */
+        if (snap) {
+            qsp_diff(&snap->ht, &ht);
+        }
     }
-    /* done with the snapshot; RCU can reclaim it */
-    rcu_read_unlock();
 
     htp = &ht;
     if (callsite_coalesce) {
@@ -788,7 +806,7 @@ void qsp_reset(void)
     qht_iter(&qsp_ht, qsp_aggregate, &new->ht);
 
     /* replace the previous snapshot, if any */
-    old = atomic_xchg(&qsp_snapshot, new);
+    old = qatomic_xchg(&qsp_snapshot, new);
     if (old) {
         call_rcu(old, qsp_snapshot_destroy, rcu);
     }