MongoDB  2.7.0
race.h
1 
29 #pragma once
30 
31 #include "mongo/util/concurrency/mutexdebugger.h"
32 #include "mongo/util/debug_util.h"
33 #include "mongo/util/goodies.h" // printStackTrace
34 #include "mongo/util/stacktrace.h"
35 
36 namespace mongo {
37 
38  namespace race {
39 
40 #ifdef _WIN32
41  typedef unsigned threadId_t;
42 #else
43  typedef pthread_t threadId_t;
44 #endif
45 
46 #if defined(_DEBUG)
47 
48  class Block {
49  volatile int n;
50  unsigned ncalls;
51  const string file;
52  const unsigned line;
53  void fail() {
54  log() << "\n\n\nrace: synchronization (race condition) failure\ncurrent locks this thread (" << getThreadName() << "):" << std::endl
55  << mutexDebugger.currentlyLocked() << std::endl;
57  ::abort();
58  }
59  void enter() {
60  if( ++n != 1 ) fail();
61  ncalls++;
62  if( ncalls < 100 ) {
63  sleepmillis(0);
64  }
65  else {
66  RARELY {
67  sleepmillis(0);
68  if( ncalls < 128 * 20 ) {
69  OCCASIONALLY {
70  sleepmillis(3);
71  }
72  }
73  }
74  }
75  }
76  void leave() {
77  if( --n != 0 ) fail();
78  }
79  public:
80  Block(const std::string& f, unsigned l) : n(0), ncalls(0), file(f), line(l) { }
81  ~Block() {
82  if( ncalls > 1000000 ) {
83  // just so we know if we are slowing things down
84  log() << "race::Block lots of calls " << file << ' ' << line << " n:" << ncalls;
85  }
86  }
87  class Within {
88  Block& _s;
89  public:
90  Within(Block& s) : _s(s) { _s.enter(); }
91  ~Within() { _s.leave(); }
92  };
93  };
94 
95  /* in a rwlock situation this will fail, so not appropriate for things like that. */
96 # define RACECHECK \
97  static race::Block __cp(__FILE__, __LINE__); \
98  race::Block::Within __ck(__cp);
99 
100 #else
101  /* !_DEBUG */
102 # define RACECHECK
103 
104 #endif
105 
106  }
107 }
const std::string & getThreadName()
Retrieves the name of the current thread, as previously set, or "" if no name was previously set...
Definition: thread_name.cpp:69
LogstreamBuilder log()
Returns a LogstreamBuilder for logging a message with LogSeverity::Log().
Definition: log.h:69
void printStackTrace(std::ostream &os)
Print a stack backtrace for the current thread to the specified ostream.
Definition: stacktrace.cpp:302