YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/port/port_posix.cc
Line
Count
Source (jump to first uncovered line)
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under the BSD-style license found in the
3
//  LICENSE file in the root directory of this source tree. An additional grant
4
//  of patent rights can be found in the PATENTS file in the same directory.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
21
// Use of this source code is governed by a BSD-style license that can be
22
// found in the LICENSE file. See the AUTHORS file for names of contributors.
23
24
#include "yb/rocksdb/port/port_posix.h"
25
26
#include <assert.h>
27
#if defined(__i386__) || defined(__x86_64__)
28
#include <cpuid.h>
29
#endif
30
#include <signal.h>
31
#include <stdio.h>
32
#include <string.h>
33
34
#include <glog/logging.h>
35
36
#include "yb/rocksdb/util/logging.h"
37
#include "yb/util/status_log.h"
38
39
#if defined(RLIMIT_NOFILE)
40
#include "yb/util/std_util.h"
41
#endif
42
43
namespace rocksdb {
44
namespace port {
45
46
995M
static int PthreadCall(const char* label, int result) {
47
995M
  if (result != 0 && result != ETIMEDOUT) {
48
0
    fprintf(stderr, "pthread %s: %s\n", label, strerror(result));
49
0
    abort();
50
0
  }
51
995M
  return result;
52
995M
}
53
54
116M
Mutex::Mutex(bool adaptive) {
55
#ifdef __linux__
56
  if (!adaptive) {
57
    PthreadCall("init mutex", pthread_mutex_init(&mu_, nullptr));
58
  } else {
59
    pthread_mutexattr_t mutex_attr;
60
    PthreadCall("init mutex attr", pthread_mutexattr_init(&mutex_attr));
61
    PthreadCall("set mutex attr",
62
                pthread_mutexattr_settype(&mutex_attr,
63
                                          PTHREAD_MUTEX_ADAPTIVE_NP));
64
    PthreadCall("init mutex", pthread_mutex_init(&mu_, &mutex_attr));
65
    PthreadCall("destroy mutex attr",
66
                pthread_mutexattr_destroy(&mutex_attr));
67
  }
68
#else // ignore adaptive for non-linux platform
69
116M
  PthreadCall("init mutex", pthread_mutex_init(&mu_, nullptr));
70
116M
#endif // __linux__
71
116M
}
72
73
115M
Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); }
74
75
380M
void Mutex::Lock() {
76
380M
  PthreadCall("lock", pthread_mutex_lock(&mu_));
77
380M
#ifndef NDEBUG
78
380M
  locked_ = true;
79
380M
#endif
80
380M
}
81
82
380M
void Mutex::Unlock() {
83
380M
#ifndef NDEBUG
84
380M
  locked_ = false;
85
380M
#endif
86
380M
  PthreadCall("unlock", pthread_mutex_unlock(&mu_));
87
380M
}
88
89
9.29M
void Mutex::AssertHeld() {
90
9.29M
#ifndef NDEBUG
91
9.29M
  DCHECK(locked_);
92
9.29M
#endif
93
9.29M
}
94
95
CondVar::CondVar(Mutex* mu)
96
1.06M
    : mu_(mu) {
97
1.06M
    PthreadCall("init cv", pthread_cond_init(&cv_, nullptr));
98
1.06M
}
99
100
1.01M
CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); }
101
102
46.2k
void CondVar::Wait() {
103
46.2k
#ifndef NDEBUG
104
46.2k
  mu_->locked_ = false;
105
46.2k
#endif
106
46.2k
  PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_));
107
46.2k
#ifndef NDEBUG
108
46.2k
  mu_->locked_ = true;
109
46.2k
#endif
110
46.2k
}
111
112
2.31k
bool CondVar::TimedWait(uint64_t abs_time_us) {
113
2.31k
  struct timespec ts;
114
2.31k
  ts.tv_sec = static_cast<time_t>(abs_time_us / 1000000);
115
2.31k
  ts.tv_nsec = static_cast<suseconds_t>((abs_time_us % 1000000) * 1000);
116
117
2.31k
#ifndef NDEBUG
118
2.31k
  mu_->locked_ = false;
119
2.31k
#endif
120
2.31k
  int err = pthread_cond_timedwait(&cv_, &mu_->mu_, &ts);
121
2.31k
#ifndef NDEBUG
122
2.31k
  mu_->locked_ = true;
123
2.31k
#endif
124
2.31k
  if (err == ETIMEDOUT) {
125
2.07k
    return true;
126
2.07k
  }
127
232
  if (err != 0) {
128
0
    PthreadCall("timedwait", err);
129
0
  }
130
232
  return false;
131
232
}
132
133
11.6k
void CondVar::Signal() {
134
11.6k
  PthreadCall("signal", pthread_cond_signal(&cv_));
135
11.6k
}
136
137
501k
void CondVar::SignalAll() {
138
501k
  PthreadCall("broadcast", pthread_cond_broadcast(&cv_));
139
501k
}
140
141
900k
RWMutex::RWMutex() {
142
900k
  PthreadCall("init mutex", pthread_rwlock_init(&mu_, nullptr));
143
900k
}
144
145
900k
RWMutex::~RWMutex() { PthreadCall("destroy mutex", pthread_rwlock_destroy(&mu_)); }
146
147
32.1k
void RWMutex::ReadLock() { PthreadCall("read lock", pthread_rwlock_rdlock(&mu_)); }
148
149
45.2k
void RWMutex::WriteLock() { PthreadCall("write lock", pthread_rwlock_wrlock(&mu_)); }
150
151
32.1k
void RWMutex::ReadUnlock() { PthreadCall("read unlock", pthread_rwlock_unlock(&mu_)); }
152
153
45.2k
void RWMutex::WriteUnlock() { PthreadCall("write unlock", pthread_rwlock_unlock(&mu_)); }
154
155
8.03k
int PhysicalCoreID() {
156
#if defined(__i386__) || defined(__x86_64__)
157
  // if you ever find that this function is hot on Linux, you can go from
158
  // ~200 nanos to ~20 nanos by adding the machinery to use __vdso_getcpu
159
  unsigned eax, ebx = 0, ecx, edx;
160
  __get_cpuid(1, &eax, &ebx, &ecx, &edx);
161
  return ebx >> 24;
162
#else
163
  // getcpu or sched_getcpu could work here
164
8.03k
  return -1;
165
8.03k
#endif
166
8.03k
}
167
168
0
void InitOnce(OnceType* once, void (*initializer)()) {
169
0
  PthreadCall("once", pthread_once(once, initializer));
170
0
}
171
172
0
void Crash(const std::string& srcfile, int srcline) {
173
0
  fprintf(stdout, "Crashing at %s:%d\n", srcfile.c_str(), srcline);
174
0
  fflush(stdout);
175
0
  kill(getpid(), SIGTERM);
176
0
}
177
178
688k
int GetMaxOpenFiles() {
179
688k
#if defined(RLIMIT_NOFILE)
180
688k
  struct rlimit no_files_limit;
181
688k
  if (getrlimit(RLIMIT_NOFILE, &no_files_limit) != 0) {
182
0
    return -1;
183
0
  }
184
  // protect against overflow
185
688k
  if (yb::std_util::cmp_greater_equal(no_files_limit.rlim_cur, std::numeric_limits<int>::max())) {
186
0
    return std::numeric_limits<int>::max();
187
0
  }
188
688k
  return static_cast<int>(no_files_limit.rlim_cur);
189
688k
#endif
190
0
  return -1;
191
688k
}
192
193
}  // namespace port
194
}  // namespace rocksdb