YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/condition_variable.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
//
5
// The following only applies to changes made to this file as part of YugaByte development.
6
//
7
// Portions Copyright (c) YugaByte, Inc.
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
10
// in compliance with the License.  You may obtain a copy of the License at
11
//
12
// http://www.apache.org/licenses/LICENSE-2.0
13
//
14
// Unless required by applicable law or agreed to in writing, software distributed under the License
15
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16
// or implied.  See the License for the specific language governing permissions and limitations
17
// under the License.
18
//
19
#include "yb/util/condition_variable.h"
20
21
#include <glog/logging.h>
22
23
#include "yb/util/errno.h"
24
#include "yb/util/monotime.h"
25
#include "yb/util/thread_restrictions.h"
26
27
using std::string;
28
29
namespace yb {
30
31
ConditionVariable::ConditionVariable(Mutex* user_lock)
32
    : user_mutex_(&user_lock->native_handle_)
33
#if !defined(NDEBUG)
34
    , user_lock_(user_lock)
35
#endif
36
12.6M
{
37
12.6M
  int rv = 0;
38
  // http://crbug.com/293736
39
  // NaCl doesn't support monotonic clock based absolute deadlines.
40
  // On older Android platform versions, it's supported through the
41
  // non-standard pthread_cond_timedwait_monotonic_np. Newer platform
42
  // versions have pthread_condattr_setclock.
43
  // Mac can use relative time deadlines.
44
#if !defined(__APPLE__) && !defined(OS_NACL) && \
45
      !(defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
46
  pthread_condattr_t attrs;
47
  rv = pthread_condattr_init(&attrs);
48
  DCHECK_EQ(0, rv);
49
  pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC);
50
  rv = pthread_cond_init(&condition_, &attrs);
51
  pthread_condattr_destroy(&attrs);
52
#else
53
12.6M
  rv = pthread_cond_init(&condition_, nullptr);
54
12.6M
#endif
55
12.6M
  DCHECK_EQ
(0, rv) << ErrnoToString(rv)0
;
56
12.6M
}
57
58
8.78M
ConditionVariable::~ConditionVariable() {
59
8.78M
#if defined(OS_MACOSX)
60
  // This hack is necessary to avoid a fatal pthreads subsystem bug in the
61
  // Darwin kernel. https://codereview.chromium.org/1323293005/
62
8.78M
  {
63
8.78M
    Mutex lock;
64
8.78M
    MutexLock l(lock);
65
8.78M
    struct timespec ts;
66
8.78M
    ts.tv_sec = 0;
67
8.78M
    ts.tv_nsec = 1;
68
8.78M
    pthread_cond_timedwait_relative_np(&condition_, &lock.native_handle_, &ts);
69
8.78M
  }
70
8.78M
#endif
71
8.78M
  int rv = pthread_cond_destroy(&condition_);
72
8.78M
  DCHECK_EQ
(0, rv) << ErrnoToString(rv)0
;
73
8.78M
}
74
75
31.8M
void ConditionVariable::Wait() const {
76
31.8M
  ThreadRestrictions::AssertWaitAllowed();
77
31.8M
#if !defined(NDEBUG)
78
31.8M
  user_lock_->CheckHeldAndUnmark();
79
31.8M
#endif
80
31.8M
  int rv = pthread_cond_wait(&condition_, user_mutex_);
81
31.8M
  DCHECK_EQ
(0, rv) << ErrnoToString(rv)0
;
82
31.8M
#if !defined(NDEBUG)
83
31.8M
  user_lock_->CheckUnheldAndMark();
84
31.8M
#endif
85
31.8M
}
86
87
25.4M
bool ConditionVariable::WaitUntil(const MonoTime& wait_timeout_deadline) const {
88
25.4M
  return TimedWait(wait_timeout_deadline - MonoTime::Now());
89
25.4M
}
90
91
102M
bool ConditionVariable::TimedWait(const MonoDelta& max_time) const {
92
102M
  ThreadRestrictions::AssertWaitAllowed();
93
94
  // Negative delta means we've already timed out.
95
102M
  int64 nsecs = max_time.ToNanoseconds();
96
102M
  if (nsecs < 0) {
97
1
    return false;
98
1
  }
99
100
102M
  struct timespec relative_time;
101
102M
  max_time.ToTimeSpec(&relative_time);
102
103
102M
#if !defined(NDEBUG)
104
102M
  user_lock_->CheckHeldAndUnmark();
105
102M
#endif
106
107
102M
#if defined(__APPLE__)
108
102M
  int rv = pthread_cond_timedwait_relative_np(
109
102M
      &condition_, user_mutex_, &relative_time);
110
#else
111
  // The timeout argument to pthread_cond_timedwait is in absolute time.
112
  struct timespec absolute_time;
113
#if defined(OS_NACL)
114
  // See comment in constructor for why this is different in NaCl.
115
  struct timeval now;
116
  gettimeofday(&now, NULL);
117
  absolute_time.tv_sec = now.tv_sec;
118
  absolute_time.tv_nsec = now.tv_usec * MonoTime::kNanosecondsPerMicrosecond;
119
#else
120
  struct timespec now;
121
  clock_gettime(CLOCK_MONOTONIC, &now);
122
  absolute_time.tv_sec = now.tv_sec;
123
  absolute_time.tv_nsec = now.tv_nsec;
124
#endif
125
126
  absolute_time.tv_sec += relative_time.tv_sec;
127
  absolute_time.tv_nsec += relative_time.tv_nsec;
128
  absolute_time.tv_sec += absolute_time.tv_nsec / MonoTime::kNanosecondsPerSecond;
129
  absolute_time.tv_nsec %= MonoTime::kNanosecondsPerSecond;
130
  DCHECK_GE(absolute_time.tv_sec, now.tv_sec);  // Overflow paranoia
131
132
#if defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
133
  int rv = pthread_cond_timedwait_monotonic_np(
134
      &condition_, user_mutex_, &absolute_time);
135
#else
136
  int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time);
137
#endif  // OS_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
138
#endif  // __APPLE__
139
140
102M
  DCHECK(rv == 0 || rv == ETIMEDOUT)
141
149k
    << "unexpected pthread_cond_timedwait return value: " << rv;
142
102M
#if !defined(NDEBUG)
143
102M
  user_lock_->CheckUnheldAndMark();
144
102M
#endif
145
102M
  return rv == 0;
146
102M
}
147
148
167M
void ConditionVariable::Broadcast() {
149
167M
  int rv = pthread_cond_broadcast(&condition_);
150
167M
  DCHECK_EQ
(0, rv) << ErrnoToString(rv)0
;
151
167M
}
152
153
1.15G
void ConditionVariable::Signal() {
154
1.15G
  int rv = pthread_cond_signal(&condition_);
155
1.15G
  DCHECK_EQ
(0, rv) << ErrnoToString(rv)0
;
156
1.15G
}
157
158
}  // namespace yb