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 <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
49namespace 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