forked from max0x7ba/atomic_queue
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhuge_pages.cc
More file actions
72 lines (56 loc) · 2.32 KB
/
huge_pages.cc
File metadata and controls
72 lines (56 loc) · 2.32 KB
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
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
#include "huge_pages.h"
#include <system_error>
#include <unistd.h>
#include <sys/mman.h>
#ifndef MAP_HUGE_SHIFT
#define MAP_HUGE_SHIFT 26
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
size_t const default_page_size = ::sysconf(_SC_PAGESIZE);
atomic_queue::HugePages::WarnFn* atomic_queue::HugePages::warn_no_1GB_pages = 0;
atomic_queue::HugePages::WarnFn* atomic_queue::HugePages::warn_no_2MB_pages = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
atomic_queue::HugePages::HugePages(Type t, size_t size) {
void* p;
size_t total_size;
for(;;) {
unsigned flags = 0;
size_t page_size = default_page_size;
if(t != PAGE_DEFAULT) {
page_size = 1u << t;
flags = (t << MAP_HUGE_SHIFT) | MAP_HUGETLB;
}
total_size = (size + (page_size - 1)) & ~(page_size - 1); // Round up to the page size.
p = ::mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED | flags, -1, 0);
if(p != MAP_FAILED)
break;
// Try using smaller page sizes.
if(t == PAGE_1GB) {
t = PAGE_2MB;
if(warn_no_1GB_pages) {
warn_no_1GB_pages();
warn_no_1GB_pages = 0; // Warn once.
}
}
else if(t == PAGE_2MB) {
t = PAGE_DEFAULT;
if(warn_no_2MB_pages) {
warn_no_2MB_pages();
warn_no_2MB_pages = 0; // Warn once.
}
}
else
throw std::system_error(errno, std::system_category(), "mmap");
}
beg_ = static_cast<unsigned char*>(p);
cur_ = beg_;
end_ = beg_ + total_size;
}
atomic_queue::HugePages::~HugePages() noexcept {
if(beg_)
::munmap(beg_, end_ - beg_);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
atomic_queue::HugePages* atomic_queue::HugePageAllocatorBase::hp = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////