]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
7c673cae FG |
14 | |
15 | #include "common/mutex_debug.h" | |
16 | #include "common/perf_counters.h" | |
17 | #include "common/ceph_context.h" | |
18 | #include "common/config.h" | |
7c673cae FG |
19 | |
20 | namespace ceph { | |
21 | namespace mutex_debug_detail { | |
22 | enum { | |
23 | l_mutex_first = 999082, | |
24 | l_mutex_wait, | |
25 | l_mutex_last | |
26 | }; | |
27 | ||
28 | mutex_debugging_base::mutex_debugging_base(const std::string &n, bool bt, | |
29 | CephContext *cct) : | |
30 | id(-1), backtrace(bt), nlock(0), locked_by(thread::id()), | |
31 | cct(cct), logger(0) { | |
32 | if (n.empty()) { | |
33 | uuid_d uu; | |
34 | uu.generate_random(); | |
35 | name = string("Unnamed-Mutex-") + uu.to_string(); | |
36 | } else { | |
37 | name = n; | |
38 | } | |
39 | if (cct) { | |
40 | PerfCountersBuilder b(cct, string("mutex-") + name, | |
41 | l_mutex_first, l_mutex_last); | |
42 | b.add_time_avg(l_mutex_wait, "wait", | |
43 | "Average time of mutex in locked state"); | |
44 | logger = b.create_perf_counters(); | |
45 | cct->get_perfcounters_collection()->add(logger); | |
46 | logger->set(l_mutex_wait, 0); | |
47 | } | |
48 | if (g_lockdep) | |
49 | _register(); | |
50 | } | |
51 | ||
52 | mutex_debugging_base::~mutex_debugging_base() { | |
53 | assert(nlock == 0); | |
54 | if (cct && logger) { | |
55 | cct->get_perfcounters_collection()->remove(logger); | |
56 | delete logger; | |
57 | } | |
58 | if (g_lockdep) { | |
59 | lockdep_unregister(id); | |
60 | } | |
61 | } | |
62 | ||
63 | void mutex_debugging_base::_register() { | |
64 | id = lockdep_register(name.c_str()); | |
65 | } | |
66 | void mutex_debugging_base::_will_lock() { // about to lock | |
67 | id = lockdep_will_lock(name.c_str(), id, backtrace); | |
68 | } | |
69 | void mutex_debugging_base::_locked() { // just locked | |
70 | id = lockdep_locked(name.c_str(), id, backtrace); | |
71 | } | |
72 | void mutex_debugging_base::_will_unlock() { // about to unlock | |
73 | id = lockdep_will_unlock(name.c_str(), id); | |
74 | } | |
75 | ||
76 | ceph::mono_time mutex_debugging_base::before_lock_blocks() { | |
77 | if (logger && cct && cct->_conf->mutex_perf_counter) | |
78 | return ceph::mono_clock::now(); | |
79 | return ceph::mono_time::min(); | |
80 | } | |
81 | ||
82 | void mutex_debugging_base::after_lock_blocks(ceph::mono_time start, | |
83 | bool no_lockdep) { | |
84 | if (logger && cct && cct->_conf->mutex_perf_counter) | |
85 | logger->tinc(l_mutex_wait, | |
86 | ceph::mono_clock::now() - start); | |
87 | if (!no_lockdep && g_lockdep) | |
88 | _locked(); | |
89 | } | |
90 | } // namespace mutex_debug_detail | |
91 | } // namespace ceph |