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 <toku_portability.h> |
42 | #include <toku_pthread.h> |
43 | #include <stdbool.h> |
44 | #include <stdint.h> |
45 | #include <util/context.h> |
46 | |
47 | //TODO: update comment, this is from rwlock.h |
48 | |
49 | namespace toku { |
50 | |
51 | class frwlock { |
52 | public: |
53 | void init(toku_mutex_t *const mutex |
54 | #if defined(TOKU_MYSQL_WITH_PFS) |
55 | , |
56 | const toku_instr_key &rwlock_instr_key |
57 | #endif |
58 | ); |
59 | void deinit(void); |
60 | |
61 | void write_lock(bool expensive); |
62 | bool try_write_lock(bool expensive); |
63 | void write_unlock(void); |
64 | // returns true if acquiring a write lock will be expensive |
65 | bool write_lock_is_expensive(void); |
66 | |
67 | void read_lock(void); |
68 | bool try_read_lock(void); |
69 | void read_unlock(void); |
70 | // returns true if acquiring a read lock will be expensive |
71 | bool read_lock_is_expensive(void); |
72 | |
73 | uint32_t users(void) const; |
74 | uint32_t blocked_users(void) const; |
75 | uint32_t writers(void) const; |
76 | uint32_t blocked_writers(void) const; |
77 | uint32_t readers(void) const; |
78 | uint32_t blocked_readers(void) const; |
79 | |
80 | private: |
81 | struct queue_item { |
82 | toku_cond_t *cond; |
83 | struct queue_item *next; |
84 | }; |
85 | |
86 | bool queue_is_empty(void) const; |
87 | void enq_item(queue_item *const item); |
88 | toku_cond_t *deq_item(void); |
89 | void maybe_signal_or_broadcast_next(void); |
90 | void maybe_signal_next_writer(void); |
91 | |
92 | toku_mutex_t *m_mutex; |
93 | |
94 | uint32_t m_num_readers; |
95 | uint32_t m_num_writers; |
96 | uint32_t m_num_want_write; |
97 | uint32_t m_num_want_read; |
98 | uint32_t m_num_signaled_readers; |
99 | // number of writers waiting that are expensive |
100 | // MUST be < m_num_want_write |
101 | uint32_t m_num_expensive_want_write; |
102 | // bool that states if the current writer is expensive |
103 | // if there is no current writer, then is false |
104 | bool m_current_writer_expensive; |
105 | // bool that states if waiting for a read |
106 | // is expensive |
107 | // if there are currently no waiting readers, then set to false |
108 | bool m_read_wait_expensive; |
109 | // thread-id of the current writer |
110 | int m_current_writer_tid; |
111 | // context id describing the context of the current writer blocking |
112 | // new readers (either because this writer holds the write lock or |
113 | // is the first to want the write lock). |
114 | context_id m_blocking_writer_context_id; |
115 | queue_item m_queue_item_read; |
116 | bool m_wait_read_is_in_queue; |
117 | |
118 | toku_cond_t m_wait_read; |
119 | #if defined(TOKU_MYSQL_WITH_PFS) |
120 | toku_pthread_rwlock_t m_rwlock; |
121 | #endif |
122 | queue_item *m_wait_head; |
123 | queue_item *m_wait_tail; |
124 | }; |
125 | |
126 | ENSURE_POD(frwlock); |
127 | |
128 | } // namespace toku |
129 | |
130 | // include the implementation here |
131 | // #include "frwlock.cc" |
132 | |