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/*======
5This file is part of PerconaFT.
6
7
8Copyright (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
47enum 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
63void toku_context_note_frwlock_contention(const context_id blocking, const context_id blocked);
64
65namespace 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
119const toku::context *toku_thread_get_context();
120
121enum 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
144struct context_status {
145 bool initialized;
146 TOKU_ENGINE_STATUS_ROW_S status[CTX_STATUS_NUM_ROWS];
147};
148
149void toku_context_get_status(struct context_status *status);
150
151void toku_context_status_init(void);
152void toku_context_status_destroy(void);
153