1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
3 | #ident "$Id$" |
4 | /*====== |
5 | This file is part of PerconaFT. |
6 | |
7 | |
8 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
9 | |
10 | PerconaFT is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License, version 2, |
12 | as published by the Free Software Foundation. |
13 | |
14 | PerconaFT is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
21 | |
22 | ---------------------------------------- |
23 | |
24 | PerconaFT is free software: you can redistribute it and/or modify |
25 | it under the terms of the GNU Affero General Public License, version 3, |
26 | as published by the Free Software Foundation. |
27 | |
28 | PerconaFT is distributed in the hope that it will be useful, |
29 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | GNU Affero General Public License for more details. |
32 | |
33 | You should have received a copy of the GNU Affero General Public License |
34 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
35 | ======= */ |
36 | |
37 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
38 | |
39 | #pragma once |
40 | |
41 | #include <portability/toku_portability.h> |
42 | |
43 | #include <db.h> |
44 | |
45 | #include <util/status.h> |
46 | |
47 | enum context_id { |
48 | CTX_INVALID = -1, |
49 | CTX_DEFAULT = 0, // default context for when no context is set |
50 | CTX_SEARCH, // searching for a key at the bottom of the tree |
51 | CTX_PROMO, // promoting a message down the tree |
52 | CTX_FULL_FETCH, // performing full fetch (pivots + some partial fetch) |
53 | CTX_PARTIAL_FETCH, // performing partial fetch |
54 | CTX_FULL_EVICTION, // running partial eviction |
55 | CTX_PARTIAL_EVICTION, // running partial eviction |
56 | CTX_MESSAGE_INJECTION, // injecting a message into a buffer |
57 | CTX_MESSAGE_APPLICATION, // applying ancestor's messages to a basement node |
58 | CTX_FLUSH, // flushing a buffer |
59 | CTX_CLEANER // doing work as the cleaner thread |
60 | }; |
61 | |
62 | // Note a contention event in engine status |
63 | void toku_context_note_frwlock_contention(const context_id blocking, const context_id blocked); |
64 | |
65 | namespace toku { |
66 | |
67 | // class for tracking what a thread is doing |
68 | // |
69 | // usage: |
70 | // |
71 | // // automatically tag and document what you're doing |
72 | // void my_interesting_function(void) { |
73 | // toku::context ctx("doing something interesting", INTERESTING_FN_1); |
74 | // ... |
75 | // { |
76 | // toku::context inner_ctx("doing something expensive", EXPENSIVE_FN_1); |
77 | // my_rwlock.wrlock(); |
78 | // expensive(); |
79 | // my_rwlock.wrunlock(); |
80 | // } |
81 | // ... |
82 | // } |
83 | // |
84 | // // ... so later you can write code like this. |
85 | // // here, we save some info to help determine why a lock could not be acquired |
86 | // void my_rwlock::wrlock() { |
87 | // r = try_acquire_write_lock(); |
88 | // if (r == 0) { |
89 | // m_write_locked_context_id = get_thread_local_context()->get_id(); |
90 | // ... |
91 | // } else { |
92 | // if (m_write_locked_context_id == EXPENSIVE_FN_1) { |
93 | // status.blocked_because_of_expensive_fn_1++; |
94 | // } else if (...) { |
95 | // ... |
96 | // } |
97 | // ... |
98 | // } |
99 | // } |
100 | class context { |
101 | public: |
102 | context(const context_id id); |
103 | |
104 | ~context(); |
105 | |
106 | context_id get_id() const { |
107 | return m_id; |
108 | } |
109 | |
110 | private: |
111 | // each thread has a stack of contexts, rooted at the trivial "root context" |
112 | const context *m_old_ctx; |
113 | const context_id m_id; |
114 | }; |
115 | |
116 | } // namespace toku |
117 | |
118 | // Get the current context of this thread |
119 | const toku::context *toku_thread_get_context(); |
120 | |
121 | enum context_status_entry { |
122 | CTX_SEARCH_BLOCKED_BY_FULL_FETCH = 0, |
123 | CTX_SEARCH_BLOCKED_BY_PARTIAL_FETCH, |
124 | CTX_SEARCH_BLOCKED_BY_FULL_EVICTION, |
125 | CTX_SEARCH_BLOCKED_BY_PARTIAL_EVICTION, |
126 | CTX_SEARCH_BLOCKED_BY_MESSAGE_INJECTION, |
127 | CTX_SEARCH_BLOCKED_BY_MESSAGE_APPLICATION, |
128 | CTX_SEARCH_BLOCKED_BY_FLUSH, |
129 | CTX_SEARCH_BLOCKED_BY_CLEANER, |
130 | CTX_SEARCH_BLOCKED_OTHER, |
131 | CTX_PROMO_BLOCKED_BY_FULL_FETCH, |
132 | CTX_PROMO_BLOCKED_BY_PARTIAL_FETCH, |
133 | CTX_PROMO_BLOCKED_BY_FULL_EVICTION, |
134 | CTX_PROMO_BLOCKED_BY_PARTIAL_EVICTION, |
135 | CTX_PROMO_BLOCKED_BY_MESSAGE_INJECTION, |
136 | CTX_PROMO_BLOCKED_BY_MESSAGE_APPLICATION, |
137 | CTX_PROMO_BLOCKED_BY_FLUSH, |
138 | CTX_PROMO_BLOCKED_BY_CLEANER, |
139 | CTX_PROMO_BLOCKED_OTHER, |
140 | CTX_BLOCKED_OTHER, |
141 | CTX_STATUS_NUM_ROWS |
142 | }; |
143 | |
144 | struct context_status { |
145 | bool initialized; |
146 | TOKU_ENGINE_STATUS_ROW_S status[CTX_STATUS_NUM_ROWS]; |
147 | }; |
148 | |
149 | void toku_context_get_status(struct context_status *status); |
150 | |
151 | void toku_context_status_init(void); |
152 | void toku_context_status_destroy(void); |
153 | |