YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
1.63G
static int PthreadCall(const char* label, int result) {
47
1.63G
  if (result != 0 && 
result != ETIMEDOUT0
) {
48
0
    fprintf(stderr, "pthread %s: %s\n", label, strerror(result));
49
0
    abort();
50
0
  }
51
1.63G
  return result;
52
1.63G
}
53
54
143M
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
143M
  PthreadCall("init mutex", pthread_mutex_init(&mu_, nullptr));
70
143M
#endif // __linux__
71
143M
}
72
73
141M
Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); }
74
75
675M
void Mutex::Lock() {
76
675M
  PthreadCall("lock", pthread_mutex_lock(&mu_));
77
675M
#ifndef NDEBUG
78
675M
  locked_ = true;
79
675M
#endif
80
675M
}
81
82
675M
void Mutex::Unlock() {
83
675M
#ifndef NDEBUG
84
675M
  locked_ = false;
85
675M
#endif
86
675M
  PthreadCall("unlock", pthread_mutex_unlock(&mu_));
87
675M
}
88
89
11.7M
void Mutex::AssertHeld() {
90
11.7M
#ifndef NDEBUG
91
11.7M
  DCHECK(locked_);
92
11.7M
#endif
93
11.7M
}
94
95
CondVar::CondVar(Mutex* mu)
96
1.31M
    : mu_(mu) {
97
1.31M
    PthreadCall("init cv", pthread_cond_init(&cv_, nullptr));
98
1.31M
}
99
100
1.21M
CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); }
101
102
50.4k
void CondVar::Wait() {
103
50.4k
#ifndef NDEBUG
104
50.4k
  mu_->locked_ = false;
105
50.4k
#endif
106
50.4k
  PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_));
107
50.4k
#ifndef NDEBUG
108
50.4k
  mu_->locked_ = true;
109
50.4k
#endif
110
50.4k
}
111
112
2.53k
bool CondVar::TimedWait(uint64_t abs_time_us) {
113
2.53k
  struct timespec ts;
114
2.53k
  ts.tv_sec = static_cast<time_t>(abs_time_us / 1000000);
115
2.53k
  ts.tv_nsec = static_cast<suseconds_t>((abs_time_us % 1000000) * 1000);
116
117
2.53k
#ifndef NDEBUG
118
2.53k
  mu_->locked_ = false;
119
2.53k
#endif
120
2.53k
  int err = pthread_cond_timedwait(&cv_, &mu_->mu_, &ts);
121
2.53k
#ifndef NDEBUG
122
2.53k
  mu_->locked_ = true;
123
2.53k
#endif
124
2.53k
  if (err == ETIMEDOUT) {
125
2.27k
    return true;
126
2.27k
  }
127
252
  if (err != 0) {
128
0
    PthreadCall("timedwait", err);
129
0
  }
130
252
  return false;
131
2.53k
}
132
133
11.4k
void CondVar::Signal() {
134
11.4k
  PthreadCall("signal", pthread_cond_signal(&cv_));
135
11.4k
}
136
137
602k
void CondVar::SignalAll() {
138
602k
  PthreadCall("broadcast", pthread_cond_broadcast(&cv_));
139
602k
}
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
33.0k
void RWMutex::ReadLock() { PthreadCall("read lock", pthread_rwlock_rdlock(&mu_)); }
148
149
46.4k
void RWMutex::WriteLock() { PthreadCall("write lock", pthread_rwlock_wrlock(&mu_)); }
150
151
33.0k
void RWMutex::ReadUnlock() { PthreadCall("read unlock", pthread_rwlock_unlock(&mu_)); }
152
153
46.4k
void RWMutex::WriteUnlock() { PthreadCall("write unlock", pthread_rwlock_unlock(&mu_)); }
154
155
7.25k
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
7.25k
  return -1;
165
7.25k
#endif
166
7.25k
}
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
857k
int GetMaxOpenFiles() {
179
857k
#if defined(RLIMIT_NOFILE)
180
857k
  struct rlimit no_files_limit;
181
857k
  if (getrlimit(RLIMIT_NOFILE, &no_files_limit) != 0) {
182
0
    return -1;
183
0
  }
184
  // protect against overflow
185
857k
  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
857k
  return static_cast<int>(no_files_limit.rlim_cur);
189
0
#endif
190
0
  return -1;
191
857k
}
192
193
}  // namespace port
194
}  // namespace rocksdb