| 593 | } |
| 594 | |
| 595 | void |
| 596 | lock_profile_obtain_lock_success(struct lock_object *lo, int contested, |
| 597 | uint64_t waittime, const char *file, int line) |
| 598 | { |
| 599 | static int lock_prof_count; |
| 600 | struct lock_profile_object *l; |
| 601 | int spin; |
| 602 | |
| 603 | if (SCHEDULER_STOPPED()) |
| 604 | return; |
| 605 | |
| 606 | /* don't reset the timer when/if recursing */ |
| 607 | if (!lock_prof_enable || (lo->lo_flags & LO_NOPROFILE)) |
| 608 | return; |
| 609 | if (lock_prof_skipcount && |
| 610 | (++lock_prof_count % lock_prof_skipcount) != 0) |
| 611 | return; |
| 612 | spin = (LOCK_CLASS(lo)->lc_flags & LC_SPINLOCK) ? 1 : 0; |
| 613 | if (spin && lock_prof_skipspin == 1) |
| 614 | return; |
| 615 | critical_enter(); |
| 616 | /* Recheck enabled now that we're in a critical section. */ |
| 617 | if (lock_prof_enable == 0) |
| 618 | goto out; |
| 619 | l = lock_profile_object_lookup(lo, spin, file, line); |
| 620 | if (l == NULL) |
| 621 | goto out; |
| 622 | l->lpo_cnt++; |
| 623 | if (++l->lpo_ref > 1) |
| 624 | goto out; |
| 625 | l->lpo_contest_locking = contested; |
| 626 | l->lpo_acqtime = nanoseconds(); |
| 627 | if (waittime && (l->lpo_acqtime > waittime)) |
| 628 | l->lpo_waittime = l->lpo_acqtime - waittime; |
| 629 | else |
| 630 | l->lpo_waittime = 0; |
| 631 | out: |
| 632 | /* |
| 633 | * Paired with cpus_fence_seq_cst(). |
| 634 | */ |
| 635 | atomic_thread_fence_rel(); |
| 636 | critical_exit(); |
| 637 | } |
| 638 | |
| 639 | void |
| 640 | lock_profile_thread_exit(struct thread *td) |
no test coverage detected