Zero  0.1.0
latch.h
Go to the documentation of this file.
1 // -*- mode:c++; c-basic-offset:4 -*-
2 /*
3  * (c) Copyright 2014, Hewlett-Packard Development Company, LP
4  */
5 
6 /* -*- mode:C++; c-basic-offset:4 -*-
7  Shore-MT -- Multi-threaded port of the SHORE storage manager
8 
9  Copyright (c) 2007-2009
10  Data Intensive Applications and Systems Labaratory (DIAS)
11  Ecole Polytechnique Federale de Lausanne
12 
13  All Rights Reserved.
14 
15  Permission to use, copy, modify and distribute this software and
16  its documentation is hereby granted, provided that both the
17  copyright notice and this permission notice appear in all copies of
18  the software, derivative works or modified versions, and any
19  portions thereof, and that both notices appear in supporting
20  documentation.
21 
22  This code is distributed in the hope that it will be useful, but
23  WITHOUT ANY WARRANTY; without even the implied warranty of
24  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
25  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
26  RESULTING FROM THE USE OF THIS SOFTWARE.
27 */
28 
29 /*<std-header orig-src='shore' incl-file-exclusion='LATCH_H'>
30 
31  $Id: latch.h,v 1.35 2010/07/07 20:50:11 nhall Exp $
32 
33 SHORE -- Scalable Heterogeneous Object REpository
34 
35 Copyright (c) 1994-99 Computer Sciences Department, University of
36  Wisconsin -- Madison
37 All Rights Reserved.
38 
39 Permission to use, copy, modify and distribute this software and its
40 documentation is hereby granted, provided that both the copyright
41 notice and this permission notice appear in all copies of the
42 software, derivative works or modified versions, and any portions
43 thereof, and that both notices appear in supporting documentation.
44 
45 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
46 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
47 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
48 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
49 
50 This software was developed with support by the Advanced Research
51 Project Agency, ARPA order number 018 (formerly 8230), monitored by
52 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
53 Further funding for this work was provided by DARPA through
54 Rome Research Laboratory Contract No. F30602-97-2-0247.
55 
56 */
57 
58 #ifndef __LATCH_H
59 #define __LATCH_H
60 
61 #include "w_defines.h"
62 
63 /* -- do not edit anything above this line -- </std-header>*/
64 
65 #include "smthread.h"
66 #include "latches.h"
67 #include <list>
68 #include <thread>
69 
80  LATCH_NL = 0,
81  LATCH_SH = 2,
83 };
84 
86 typedef int64_t q_ticket_t;
87 
88 class latch_t;
89 
90 extern ostream& operator<<(ostream&, const latch_t&);
91 
106 public:
107 
109 
111 
113 
115 
116  int _count;
117 
118 private:
119  std::thread::id _threadid; // REMOVE ME (for debuging)
120 
121  // disabled
122  latch_holder_t& operator=(latch_holder_t const& other);
123 
124 public:
125  // internal freelist use only!
127 
129 
131  : _latch(nullptr),
132  _mode(LATCH_NL),
133  _count(0) {
134  _threadid = std::this_thread::get_id();
135  }
136 
137  bool operator==(latch_holder_t const& other) const {
138  if (_threadid != other._threadid) {
139  return false;
140  }
141  return _latch == other._latch &&
142  _mode == other._mode && _count == other._count;
143  }
144 
145  void print(ostream& o) const;
146 };
147 
148 #include <iosfwd>
149 
159 class latch_t /*: public sthread_named_base_t*/ {
160 
161 public:
163  latch_t();
164 
165  ~latch_t();
166 
168  static void on_thread_destroy();
169 
170  // Dump latch info to the ostream. Not thread-safe.
171  ostream& print(ostream&) const;
172 
173  // Return a unique id for the latch.For debugging.
174  inline const void* id() const {
175  return &_lock;
176  }
177 
179  inline void setname(const char* const desc);
180 
182  w_rc_t latch_acquire(
183  latch_mode_t m,
184  int timeout = timeout_t::WAIT_FOREVER);
185 
192  w_rc_t upgrade_if_not_block(bool& would_block);
193 
198  void downgrade();
199 
206  int latch_release();
207 
210  bool is_latched() const;
211 
212  /*
213  * GNATS 30 fix: changes lock_cnt name to latch_cnt,
214  * and adds _total_cnt to the latch structure itself so it can
215  * keep track of the total #holders
216  * This is an additional cost, but it is a great debugging aid.
217  * \todo TODO: get rid of BUG_LATCH_SEMANTICS_FIX: replace with gnats #
218  */
219 
221  int latch_cnt() const {
222  return _total_count;
223  }
224 
226  int num_holders() const;
227 
229  bool is_mine() const; // only if ex
231  //latch count (# times this thread holds the latch).
232  int held_by_me() const; // sh or ex
234  latch_mode_t mode() const;
235 
237  static const char* const latch_mode_str[4];
238 
239 private:
240  // found, iterator
241  w_rc_t _acquire(latch_mode_t m,
242  int timeout_in_ms,
243  latch_holder_t* me);
244 
245  // return #times this thread holds the latch after this release
246  int _release(latch_holder_t* me);
247 
248  void _downgrade(latch_holder_t* me);
249 
250 /*
251  * Note: the problem with #threads and #cpus and os preemption is real.
252  * And it causes things to hang; and it's hard to debug, in the sense that
253  * using pthread facilities gives thread-analysis tools and debuggers
254  * understood-things with which to work.
255  * Consequently, we use w_pthread_rwlock for our lock.
256  */
257  mutable srwlock_t _lock;
258 
259  // disabled
260  latch_t(const latch_t&);
261 
262  latch_t& operator=(const latch_t&);
263 
264  uint32_t _total_count;
265 };
266 
267 inline bool
269  /* NOTE: Benign race -- this function is naturally unreliable, as
270  * its return value may become invalid as soon as it is
271  * generated. The only way to reliably know if the lock is held at
272  * a particular moment is to hold it yourself, which defeats the
273  * purpose of asking in the first place...
274  * ... except for assertions / debugging... since there are bugs
275  * in acquire/release of latches
276  */
277  return _lock.is_locked();
278 }
279 
280 inline int
282  return _lock.num_holders();
283 }
284 
285 inline latch_mode_t
286 latch_t::mode() const {
287  switch (_lock.mode()) {
288  case mcs_rwlock::NONE:
289  return LATCH_NL;
290  case mcs_rwlock::WRITER:
291  return LATCH_EX;
292  case mcs_rwlock::READER:
293  return LATCH_SH;
294  default:
295  w_assert1(0); // shouldn't ever happen
296  return LATCH_SH; // keep compiler happy
297  }
298 }
299 
300 // unsafe: for use in debugger:
301 extern "C" void print_my_latches();
302 extern "C" void print_all_latches();
303 extern "C" void print_latch(const latch_t* l);
304 
305 /*<std-footer incl-file-exclusion='LATCH_H'> -- do not edit anything below this line -- */
306 
307 #endif // __LATCH_H /*</std-footer>*/
bool operator==(latch_holder_t const &other) const
Definition: latch.h:137
Definition: latch.h:82
void print(ostream &o) const
Definition: latch.cpp:556
int64_t q_ticket_t
type of a Q mode ticket; exact type and location of definition TBD
Definition: latch.h:86
static __thread latch_holder_t * thread_local_holders
Linked list of all latches held by this thread.
Definition: latch.h:108
#define w_assert1(x)
Level 1 should not add significant extra time.
Definition: w_base.h:198
latch_holder_t * _prev
Definition: latch.h:126
latch_holder_t & operator=(latch_holder_t const &other)
Indicates a latch is held by this thread.
Definition: latch.h:105
Definition: latches.h:372
Definition: latch.h:80
int _count
Definition: latch.h:116
latch_holder_t()
Definition: latch.h:130
bool is_latched() const
Unreliable, but helpful for some debugging.
Definition: latch.h:268
static constexpr int WAIT_FOREVER
Definition: timeout.h:28
void print_latch(const latch_t *l)
Definition: latch.cpp:610
Definition: latches.h:374
A short-term hold (exclusive or shared) on a page.
Definition: latch.h:159
static __thread latch_holder_t * thread_local_freelist
Pool of unused latch_holder_t instances.
Definition: latch.h:110
Return code for most functions and methods.
Definition: w_rc.h:87
uint32_t _total_count
Definition: latch.h:264
ostream & operator<<(ostream &, const latch_t &)
Definition: latch.cpp:605
Definition: latches.h:373
latch_holder_t * _next
Definition: latch.h:128
Definition: latch.h:81
latch_mode_t mode() const
EX, SH, or NL (if not held at all).
Definition: latch.h:286
const void * id() const
Definition: latch.h:174
void print_my_latches()
Definition: latch.cpp:617
void print_all_latches()
int num_holders() const
How many threads hold the R/W lock.
Definition: latch.h:281
latch_mode_t
Definition: latch.h:79
latch_t * _latch
Definition: latch.h:112
latch_mode_t _mode
Definition: latch.h:114
srwlock_t _lock
Definition: latch.h:257
std::thread::id _threadid
Definition: latch.h:119
Shore read-write lock:: many-reader/one-writer spin lock.
Definition: latches.h:350
int latch_cnt() const
Number of acquires. A thread may hold more than once.
Definition: latch.h:221