16 #ifndef __STDC_FORMAT_MACROS 17 #define __STDC_FORMAT_MACROS 25 #include <sys/types.h> 27 #include <sys/utsname.h> 40 #include <glog/logging.h> 48 auto dot1 = release.
find(
'.');
49 if (dot1 == StringPiece::npos) {
50 throw std::invalid_argument(
"could not find first dot");
52 auto v1 = folly::to<int>(release.
subpiece(0, dot1));
54 auto dot2 = release.
find(
'.', dot1 + 1);
55 if (dot2 == StringPiece::npos) {
56 throw std::invalid_argument(
"could not find second dot");
58 auto v2 = folly::to<int>(release.
subpiece(dot1 + 1, dot2 - (dot1 + 1)));
60 int dash = release.
find(
'-', dot2 + 1);
61 auto v3 = folly::to<int>(release.
subpiece(dot2 + 1, dash - (dot2 + 1)));
63 return ((v1 * 1000 + v2) * 1000) + v3;
73 static int64_t determineSchedstatUnits() {
74 struct utsname unameInfo;
75 if (uname(&unameInfo) != 0) {
76 LOG(ERROR) <<
"unable to determine jiffies/second: uname failed: %s" 92 }
catch (
const std::exception&) {
93 LOG(ERROR) <<
"unable to determine jiffies/second: failed to parse " 94 <<
"kernel release string \"" << unameInfo.release <<
"\"";
97 if (linuxVersion >= 2006023) {
110 char configPath[256];
112 configPath,
sizeof(configPath),
"/boot/config-%s", unameInfo.release);
114 FILE*
f = fopen(configPath,
"r");
116 LOG(ERROR) <<
"unable to determine jiffies/second: " 117 "cannot open kernel config file %s" 127 while (fgets(buf,
sizeof(buf), f) !=
nullptr) {
128 if (strcmp(buf,
"CONFIG_NO_HZ=y\n") == 0) {
129 LOG(ERROR) <<
"unable to determine jiffies/second: tickless kernel";
131 }
else if (strcmp(buf,
"CONFIG_HZ=1000\n") == 0) {
133 }
else if (strcmp(buf,
"CONFIG_HZ=300\n") == 0) {
135 }
else if (strcmp(buf,
"CONFIG_HZ=250\n") == 0) {
137 }
else if (strcmp(buf,
"CONFIG_HZ=100\n") == 0) {
143 LOG(ERROR) <<
"unable to determine jiffies/second: no CONFIG_HZ setting " 163 return nanoseconds(0);
165 static int64_t timeUnits = determineSchedstatUnits();
169 return nanoseconds(0);
174 char schedstatFile[256];
175 snprintf(schedstatFile,
sizeof(schedstatFile),
"/proc/%d/schedstat", tid);
176 fd = open(schedstatFile, O_RDONLY);
178 throw std::runtime_error(
179 folly::to<string>(
"failed to open process schedstat file", errno));
183 ssize_t bytesReadRet =
read(fd, buf,
sizeof(buf) - 1);
184 if (bytesReadRet <= 0) {
185 throw std::runtime_error(
186 folly::to<string>(
"failed to read process schedstat file", errno));
188 size_t bytesRead = size_t(bytesReadRet);
190 if (buf[bytesRead - 1] !=
'\n') {
191 throw std::runtime_error(
"expected newline at end of schedstat data");
193 assert(bytesRead <
sizeof(buf));
194 buf[bytesRead] =
'\0';
201 "%" PRIu64
" %" PRIu64
" %" PRIu64
"\n",
206 throw std::runtime_error(
"failed to parse schedstat data");
210 return nanoseconds(waitingJiffies * timeUnits);
211 }
catch (
const std::runtime_error& e) {
215 LOG(ERROR) <<
"error determining process wait time: %s" << e.what();
216 return nanoseconds(0);
221 void TimePoint::reset() {
235 os <<
"TimePoint(" << timePoint.
getTimeStart().time_since_epoch().count()
236 <<
", " << timePoint.
getTimeEnd().time_since_epoch().count() <<
", " 244 nanoseconds expected,
246 nanoseconds tolerance) {
252 if (elapsedTime < (expected - milliseconds(1))) {
262 nanoseconds timeExcluded;
266 timeExcluded = nanoseconds(0);
271 assert((elapsedTime + tolerance) >= timeExcluded);
274 nanoseconds effectiveElapsedTime(0);
275 if (elapsedTime > timeExcluded) {
276 effectiveElapsedTime = elapsedTime - timeExcluded;
281 auto overrun = effectiveElapsedTime - expected;
282 if (overrun > tolerance) {
std::chrono::nanoseconds getTimeWaiting() const
static nanoseconds getSchedTimeWaiting(pid_t tid)
std::chrono::steady_clock::time_point now()
size_type find(const_range_type str) const
bool checkTimeout(const TimePoint &start, const TimePoint &end, nanoseconds expected, bool allowSmaller, nanoseconds tolerance)
—— Concurrent Priority Queue Implementation ——
std::ostream & operator<<(std::ostream &os, const TimePoint &timePoint)
size_t read(T &out, folly::io::Cursor &cursor)
auto end(TestAdlIterable &instance)
Range subpiece(size_type first, size_type length=npos) const
std::chrono::steady_clock::time_point getTimeStart() const
fbstring errnoStr(int err)
static int getLinuxVersion(StringPiece release)
int close(NetworkSocket s)
GMockOutputTest ExpectedCall FILE
static FOLLY_TLS uint32_t tid_
std::chrono::steady_clock::time_point getTimeEnd() const