@@ -16,6 +16,9 @@ ABSL_FLAG(uint32_t, fiber_safety_margin, 1024,
16
16
" If > 0, ensures the stack each fiber has at least this margin. "
17
17
" The check is done at fiber destruction time." );
18
18
19
+ ABSL_FLAG (uint32_t , fiber_run_warning_threshold_ms, 0 ,
20
+ " If greater than 0, will warn if a fiber runs longer than this threshold. " );
21
+
19
22
namespace util {
20
23
namespace fb2 {
21
24
using namespace std ;
@@ -61,14 +64,13 @@ class MainFiberImpl final : public FiberInterface {
61
64
mutex g_scheduler_lock;
62
65
63
66
TL_FiberInitializer* g_fiber_thread_list = nullptr ;
64
- uint64_t g_tsc_cycles_per_ms = 0 ;
67
+ uint64_t g_tsc_cycles_per_ms = 0 , g_ts_cycles_warn_threshold = - 1 ;
65
68
66
69
} // namespace
67
70
68
71
PMR_NS::memory_resource* default_stack_resource = nullptr ;
69
72
size_t default_stack_size = 64 * 1024 ;
70
73
71
-
72
74
__thread FiberInterface::TL FiberInterface::tl;
73
75
74
76
// Per thread initialization structure.
@@ -111,6 +113,9 @@ TL_FiberInitializer::TL_FiberInitializer() noexcept : sched(nullptr) {
111
113
g_fiber_thread_list = this ;
112
114
if (g_tsc_cycles_per_ms == 0 ) {
113
115
g_tsc_cycles_per_ms = CycleClock::Frequency () / 1000 ;
116
+ uint32_t warn_ms = absl::GetFlag (FLAGS_fiber_run_warning_threshold_ms);
117
+ if (warn_ms)
118
+ g_ts_cycles_warn_threshold = g_tsc_cycles_per_ms * warn_ms;
114
119
VLOG (1 ) << " TSC Frequency : " << g_tsc_cycles_per_ms << " /ms" ;
115
120
}
116
121
}
@@ -401,12 +406,16 @@ FiberInterface* FiberInterface::SwitchSetup() {
401
406
fb_initializer.switch_delay_cycles += (tsc - cpu_tsc_);
402
407
403
408
// to_suspend points to the fiber that is active and is going to be suspended.
404
- uint64_t delta_cycles = tsc - to_suspend->cpu_tsc_ ;
405
- if (delta_cycles > g_tsc_cycles_per_ms) {
409
+ uint64_t active_cycles = tsc - to_suspend->cpu_tsc_ ;
410
+ if (active_cycles > g_tsc_cycles_per_ms) {
406
411
fb_initializer.long_runtime_cnt ++;
407
412
408
- // improves precision, instead of "delta_cycles / (g_tsc_cycles_per_ms / 1000)"
409
- fb_initializer.long_runtime_usec += (delta_cycles * 1000 ) / g_tsc_cycles_per_ms;
413
+ // improves precision, instead of "active_cycles / (g_tsc_cycles_per_ms / 1000)"
414
+ fb_initializer.long_runtime_usec += (active_cycles * 1000 ) / g_tsc_cycles_per_ms;
415
+ if (active_cycles >= g_ts_cycles_warn_threshold && to_suspend->type () == WORKER) {
416
+ LOG_EVERY_T (WARNING, 1 ) << " Fiber " << to_suspend->name () << " ran for "
417
+ << (active_cycles / g_tsc_cycles_per_ms) << " ms" ;
418
+ }
410
419
}
411
420
}
412
421
@@ -473,6 +482,10 @@ uint64_t FiberLongRunSumUsec() noexcept {
473
482
return detail::FbInitializer ().long_runtime_usec ;
474
483
}
475
484
485
+ void SetFiberLongRunWarningThreshold (uint32_t warn_ms) {
486
+ detail::g_ts_cycles_warn_threshold = warn_ms == 0 ? -1 : detail::g_tsc_cycles_per_ms * warn_ms;
487
+ }
488
+
476
489
size_t WorkerFibersStackSize () {
477
490
return detail::FbInitializer ().sched ->worker_stack_size ();
478
491
}
0 commit comments