| 857 | #endif |
| 858 | |
| 859 | void |
| 860 | thread_lock_flags_(struct thread *td, int opts, const char *file, int line) |
| 861 | { |
| 862 | struct mtx *m; |
| 863 | uintptr_t tid, v; |
| 864 | struct lock_delay_arg lda; |
| 865 | #ifdef LOCK_PROFILING |
| 866 | int contested = 0; |
| 867 | uint64_t waittime = 0; |
| 868 | #endif |
| 869 | #ifdef KDTRACE_HOOKS |
| 870 | int64_t spin_time = 0; |
| 871 | #endif |
| 872 | #if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING) |
| 873 | int doing_lockprof = 1; |
| 874 | #endif |
| 875 | |
| 876 | tid = (uintptr_t)curthread; |
| 877 | |
| 878 | if (SCHEDULER_STOPPED()) { |
| 879 | /* |
| 880 | * Ensure that spinlock sections are balanced even when the |
| 881 | * scheduler is stopped, since we may otherwise inadvertently |
| 882 | * re-enable interrupts while dumping core. |
| 883 | */ |
| 884 | spinlock_enter(); |
| 885 | return; |
| 886 | } |
| 887 | |
| 888 | lock_delay_arg_init(&lda, &mtx_spin_delay); |
| 889 | |
| 890 | #ifdef HWPMC_HOOKS |
| 891 | PMC_SOFT_CALL( , , lock, failed); |
| 892 | #endif |
| 893 | |
| 894 | #ifdef LOCK_PROFILING |
| 895 | doing_lockprof = 1; |
| 896 | #elif defined(KDTRACE_HOOKS) |
| 897 | doing_lockprof = lockstat_enabled; |
| 898 | if (__predict_false(doing_lockprof)) |
| 899 | spin_time -= lockstat_nsecs(&td->td_lock->lock_object); |
| 900 | #endif |
| 901 | spinlock_enter(); |
| 902 | |
| 903 | for (;;) { |
| 904 | retry: |
| 905 | m = td->td_lock; |
| 906 | thread_lock_validate(m, opts, file, line); |
| 907 | v = MTX_READ_VALUE(m); |
| 908 | for (;;) { |
| 909 | if (v == MTX_UNOWNED) { |
| 910 | if (_mtx_obtain_lock_fetch(m, &v, tid)) |
| 911 | break; |
| 912 | continue; |
| 913 | } |
| 914 | MPASS(v != tid); |
| 915 | lock_profile_obtain_lock_failed(&m->lock_object, |
| 916 | &contested, &waittime); |
no test coverage detected