-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathutils.h
130 lines (104 loc) · 3.33 KB
/
utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2015, the scalloc Project Authors. All rights reserved.
// Please see the AUTHORS file for details. Use of this source code is governed
// by a BSD license that can be found in the LICENSE file.
#ifndef SCALLOC_UTILS_H_
#define SCALLOC_UTILS_H_
#include <sys/mman.h>
#include "globals.h"
#include "platform/globals.h"
#include "log.h"
namespace scalloc {
always_inline size_t PadSize(size_t size, size_t multiple) {
return (size + multiple - 1) / multiple * multiple;
}
always_inline void* SystemMmapGuided(void* hint, size_t size) {
const int flags = MAP_PRIVATE | MAP_ANONYMOUS;
const int prot = PROT_READ | PROT_WRITE;
void* p = mmap(hint, size, prot, flags, -1, 0);
if (UNLIKELY(reinterpret_cast<void*>(p) == MAP_FAILED)) {
return nullptr;
}
if (hint != p) {
munmap(p, size);
return nullptr;
}
#if defined(SCALLOC_DISABLE_TRANSPARENT_HUGEPAGES) && defined(MADV_NOHUGEPAGE)
if (madvise(p, size, MADV_NOHUGEPAGE) != 0) {
Fatal("madvise MADV_NOHUGEPAGE failed");
}
#endif // SCALLOC_DISABLE_TRANSPARENT_HUGEPAGES && MADV_NOHUGEPAGE
return p;
}
always_inline void* SystemMmap(size_t size) {
const int flags = MAP_PRIVATE | MAP_ANONYMOUS;
const int prot = PROT_READ | PROT_WRITE;
void* p = mmap(0, size, prot, flags, -1, 0);
if (UNLIKELY(reinterpret_cast<void*>(p) == MAP_FAILED)) {
return nullptr;
}
#if defined(SCALLOC_DISABLE_TRANSPARENT_HUGEPAGES) && defined(MADV_NOHUGEPAGE)
if (madvise(p, size, MADV_NOHUGEPAGE) != 0) {
Fatal("madvise MADV_NOHUGEPAGE failed");
}
#endif // SCALLOC_DISABLE_TRANSPARENT_HUGEPAGES && MADV_NOHUGEPAGE
return p;
}
always_inline void* SystemMmapFail(size_t size) {
void* p = SystemMmap(size);
if (UNLIKELY(p == nullptr)) { Fatal("mmap failed"); }
return p;
}
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
static const char log_table[256] = {
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
};
// base-2 logarithm of 32-bit integers
always_inline int Log2(size_t v) {
unsigned int t, tt, r; // temp vars
if ((tt = (v >> 16))) {
r = (t = (tt >> 8)) ? 24 + log_table[t] : 16 + log_table[tt];
} else {
r = (t = (v >> 8)) ? 8 + log_table[t] : log_table[v];
}
return r;
}
always_inline int32_t CpusOnline() {
static __attribute__((aligned(64))) int32_t cpus_online = -1;
if (cpus_online == -1) {
cpus_online = static_cast<int32_t>(sysconf(_SC_NPROCESSORS_ONLN));
if ((cpus_online == - 1) || /* sysconf failed */
(cpus_online == 0)) { /* this should not happen */
Fatal("CpusOnline failed");
}
}
return cpus_online;
}
always_inline uint_fast64_t rdtsc(void) {
unsigned int hi, lo;
__asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint_fast64_t) lo) | (((uint_fast64_t) hi) << 32);
}
always_inline uint_fast64_t hwrand() {
return (rdtsc() >> 6);
}
// Used for pseudorand
const uint32_t kA = 16807;
const uint32_t kM = 2147483647;
const uint32_t kQ = 127773;
const uint32_t kR = 2836;
always_inline uint64_t pseudorand() {
static int32_t s = 1237;
int32_t seed = s;
uint32_t hi = seed / kQ;
uint32_t lo = seed % kQ;
seed = kA * lo - kR * hi;
if (seed < 0) {
seed += kM;
}
s = seed;
return seed;
}
} // namespace scalloc
#endif // SCALLOC_UTILS_H_