FOLLY_NORETURN
[folly.git] / folly / experimental / io / HugePageUtil.cpp
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sys/mman.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23
24 #include <iostream>
25 #include <stdexcept>
26 #include <system_error>
27
28 #include <gflags/gflags.h>
29
30 #include "folly/Format.h"
31 #include "folly/Portability.h"
32 #include "folly/Range.h"
33 #include "folly/ScopeGuard.h"
34 #include "folly/experimental/io/HugePages.h"
35
36 DEFINE_bool(cp, false, "Copy file");
37
38 using namespace folly;
39
40 namespace {
41
42 void usage(const char* name) FOLLY_NORETURN;
43
44 void usage(const char* name) {
45   std::cerr << folly::format(
46       "Usage: {0}\n"
47       "         list all huge page sizes and their mount points\n"
48       "       {0} -cp <src_file> <dest_nameprefix>\n"
49       "         copy src_file to a huge page file\n",
50       name);
51   exit(1);
52 }
53
54 void copy(const char* srcFile, const char* destPrefix) {
55   int srcfd = open(srcFile, O_RDONLY);
56   if (srcfd == -1) {
57     throw std::system_error(errno, std::system_category(), "open failed");
58   }
59   SCOPE_EXIT {
60     close(srcfd);
61   };
62   struct stat st;
63   if (fstat(srcfd, &st) == -1) {
64     throw std::system_error(errno, std::system_category(), "fstat failed");
65   }
66
67   void* start = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, srcfd, 0);
68   if (start == MAP_FAILED) {
69     throw std::system_error(errno, std::system_category(), "mmap failed");
70   }
71
72   SCOPE_EXIT {
73     munmap(start, st.st_size);
74   };
75
76   HugePages hp;
77   auto f = hp.create(ByteRange(static_cast<const unsigned char*>(start),
78                                st.st_size),
79                      destPrefix);
80   std::cout << f.path << "\n";
81 }
82
83 void list() {
84   HugePages hp;
85   for (auto& p : hp.sizes()) {
86     std::cout << p.size << " " << p.mountPoint << "\n";
87   }
88 }
89
90 }  // namespace
91
92
93 int main(int argc, char *argv[]) {
94   google::ParseCommandLineFlags(&argc, &argv, true);
95   if (FLAGS_cp) {
96     if (argc != 3) usage(argv[0]);
97     copy(argv[1], argv[2]);
98   } else {
99     if (argc != 1) usage(argv[0]);
100     list();
101   }
102   return 0;
103 }
104