Copyright 2012 -> 2013
[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/experimental/io/HugePages.h"
31 #include "folly/Format.h"
32 #include "folly/Range.h"
33 #include "folly/ScopeGuard.h"
34
35 DEFINE_bool(cp, false, "Copy file");
36
37 using namespace folly;
38
39 namespace {
40
41 void usage(const char* name) __attribute__((noreturn));
42
43 void usage(const char* name) {
44   std::cerr << folly::format(
45       "Usage: {0}\n"
46       "         list all huge page sizes and their mount points\n"
47       "       {0} -cp <src_file> <dest_nameprefix>\n"
48       "         copy src_file to a huge page file\n",
49       name);
50   exit(1);
51 }
52
53 void copy(const char* srcFile, const char* destPrefix) {
54   int srcfd = open(srcFile, O_RDONLY);
55   if (srcfd == -1) {
56     throw std::system_error(errno, std::system_category(), "open failed");
57   }
58   SCOPE_EXIT {
59     close(srcfd);
60   };
61   struct stat st;
62   if (fstat(srcfd, &st) == -1) {
63     throw std::system_error(errno, std::system_category(), "fstat failed");
64   }
65
66   void* start = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, srcfd, 0);
67   if (start == MAP_FAILED) {
68     throw std::system_error(errno, std::system_category(), "mmap failed");
69   }
70
71   SCOPE_EXIT {
72     munmap(start, st.st_size);
73   };
74
75   HugePages hp;
76   auto f = hp.create(ByteRange(static_cast<const unsigned char*>(start),
77                                st.st_size),
78                      destPrefix);
79   std::cout << f.path << "\n";
80 }
81
82 void list() {
83   HugePages hp;
84   for (auto& p : hp.sizes()) {
85     std::cout << p.size << " " << p.mountPoint << "\n";
86   }
87 }
88
89 }  // namespace
90
91
92 int main(int argc, char *argv[]) {
93   google::ParseCommandLineFlags(&argc, &argv, true);
94   if (FLAGS_cp) {
95     if (argc != 3) usage(argv[0]);
96     copy(argv[1], argv[2]);
97   } else {
98     if (argc != 1) usage(argv[0]);
99     list();
100   }
101   return 0;
102 }
103