diff --git a/include/haproxy/thread.h b/include/haproxy/thread.h index c5a485797..9d13ed952 100644 --- a/include/haproxy/thread.h +++ b/include/haproxy/thread.h @@ -368,17 +368,31 @@ static inline unsigned long thread_isolated() lock_start = now_mono_time(); \ } \ (void)(expr); \ - if (_LK_ == _LK_UN) \ + if (_LK_ == _LK_UN) { \ th_ctx->lock_level += bal; \ - else if (unlikely(lock_start)) \ - th_ctx->lock_wait_total += now_mono_time() - lock_start; \ + if (th_ctx->lock_level == 0 && unlikely(th_ctx->flags & TH_FL_TASK_PROFILING)) \ + th_ctx->locked_total += now_mono_time() - th_ctx->lock_start_date; \ + } else if (unlikely(th_ctx->flags & TH_FL_TASK_PROFILING)) { \ + uint64_t now = now_mono_time(); \ + if (lock_start) \ + th_ctx->lock_wait_total += now - lock_start; \ + if (th_ctx->lock_level == 1) \ + th_ctx->lock_start_date = now; \ + } \ if (lbl != OTHER_LOCK) \ _lock_wait_common(_LK_, lbl); \ } while (0) #define _lock_cond(_LK_, bal, lbl, expr) ({ \ typeof(expr) _expr = (expr); \ - if (_expr == 0) \ + if (_expr == 0) { \ th_ctx->lock_level += bal; \ + if (unlikely(th_ctx->flags & TH_FL_TASK_PROFILING)) { \ + if (_LK_ == _LK_UN && th_ctx->lock_level == 0) \ + th_ctx->locked_total += now_mono_time() - th_ctx->lock_start_date; \ + else if (_LK_ != _LK_UN && th_ctx->lock_level == 1) \ + th_ctx->lock_start_date = now_mono_time(); \ + } \ + } \ if (lbl != OTHER_LOCK && !_expr) \ _lock_wait_common(_LK_, lbl); \ _expr; \ diff --git a/include/haproxy/tinfo-t.h b/include/haproxy/tinfo-t.h index 8ea5898fd..7d550e7e6 100644 --- a/include/haproxy/tinfo-t.h +++ b/include/haproxy/tinfo-t.h @@ -161,6 +161,8 @@ struct thread_ctx { uint32_t sched_wake_date; /* current task/tasklet's wake date in 32-bit ns or 0 if not supported */ uint64_t sched_call_date; /* current task/tasklet's call date in ns */ uint64_t lock_wait_total; /* total time in ns spent waiting for a lock (task prof) */ + uint64_t lock_start_date; /* date when first locked was obtained (task prof) */ + uint64_t locked_total; /* total time in ns spent with at least one lock held (task prof) */ uint64_t prev_mono_time; /* previous system wide monotonic time (leaving poll) */ uint64_t curr_mono_time; /* latest system wide monotonic time (leaving poll) */ diff --git a/src/task.c b/src/task.c index fdd2775ba..0de5a588d 100644 --- a/src/task.c +++ b/src/task.c @@ -570,6 +570,7 @@ unsigned int run_tasks_from_lists(unsigned int budgets[]) t->calls++; th_ctx->lock_wait_total = 0; + th_ctx->locked_total = 0; th_ctx->sched_wake_date = t->wake_date; if (th_ctx->sched_wake_date || (t->state & TASK_F_WANTS_TIME)) { /* take the most accurate clock we have, either @@ -683,6 +684,8 @@ unsigned int run_tasks_from_lists(unsigned int budgets[]) HA_ATOMIC_ADD(&profile_entry->cpu_time, (uint32_t)(now_mono_time() - th_ctx->sched_call_date)); if (th_ctx->lock_wait_total) HA_ATOMIC_ADD(&profile_entry->lkw_time, th_ctx->lock_wait_total); + if (th_ctx->locked_total) + HA_ATOMIC_ADD(&profile_entry->lkd_time, th_ctx->locked_total); } } th_ctx->current_queue = -1;