Submit the contention along with the callsite('s stacktrace)
| 625 | |
| 626 | // Submit the contention along with the callsite('s stacktrace) |
| 627 | void submit_contention(const bthread_contention_site_t& csite, int64_t now_ns) { |
| 628 | tls_inside_lock = true; |
| 629 | BRPC_SCOPE_EXIT { |
| 630 | tls_inside_lock = false; |
| 631 | }; |
| 632 | |
| 633 | butil::debug::StackTrace stack(true); // May lock. |
| 634 | if (0 == stack.FrameCount()) { |
| 635 | return; |
| 636 | } |
| 637 | // There are two situations where we need to check whether in the |
| 638 | // malloc call stack: |
| 639 | // 1. Warn up some singleton objects used in `submit_contention' |
| 640 | // to avoid deadlock in malloc call stack. |
| 641 | // 2. LocalPool is empty, GlobalPool may allocate memory by malloc. |
| 642 | if (!tls_warn_up || butil::local_pool_free_empty<SampledContention>()) { |
| 643 | // In malloc call stack, can not submit contention. |
| 644 | if (stack.FindSymbol((void*)malloc)) { |
| 645 | return; |
| 646 | } |
| 647 | } |
| 648 | |
| 649 | auto sc = butil::get_object<SampledContention>(); |
| 650 | // Normalize duration_us and count so that they're addable in later |
| 651 | // processings. Notice that sampling_range is adjusted periodically by |
| 652 | // collecting thread. |
| 653 | sc->duration_ns = csite.duration_ns * bvar::COLLECTOR_SAMPLING_BASE |
| 654 | / csite.sampling_range; |
| 655 | sc->count = bvar::COLLECTOR_SAMPLING_BASE / (double)csite.sampling_range; |
| 656 | sc->nframes = stack.CopyAddressTo(sc->stack, arraysize(sc->stack)); |
| 657 | sc->submit(now_ns / 1000); // may lock |
| 658 | // Once submit a contention, complete warn up. |
| 659 | tls_warn_up = true; |
| 660 | } |
| 661 | |
| 662 | #if BRPC_DEBUG_LOCK |
| 663 | #define MUTEX_RESET_OWNER_COMMON(owner) \ |
no test coverage detected