2 * Copyright 2014 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <gtest/gtest.h>
19 #include "folly/MemoryMapping.h"
23 TEST(MemoryMapping, Basic) {
24 File f = File::temporary();
26 WritableMemoryMapping m(File(f.fd()), 0, sizeof(double));
27 double volatile* d = m.asWritableRange<double>().data();
31 MemoryMapping m(File(f.fd()), 0, 3);
32 EXPECT_EQ(0, m.asRange<int>().size()); //not big enough
35 MemoryMapping m(File(f.fd()), 0, sizeof(double));
36 const double volatile* d = m.asRange<double>().data();
37 EXPECT_EQ(*d, 37 * M_PI);
41 TEST(MemoryMapping, Move) {
42 File f = File::temporary();
44 WritableMemoryMapping m(File(f.fd()), 0, sizeof(double) * 2);
45 double volatile* d = m.asWritableRange<double>().data();
47 WritableMemoryMapping m2(std::move(m));
48 double volatile* d2 = m2.asWritableRange<double>().data();
52 MemoryMapping m(File(f.fd()), 0, sizeof(double));
53 const double volatile* d = m.asRange<double>().data();
54 EXPECT_EQ(d[0], 37 * M_PI);
55 MemoryMapping m2(std::move(m));
56 const double volatile* d2 = m2.asRange<double>().data();
57 EXPECT_EQ(d2[1], 39 * M_PI);
61 TEST(MemoryMapping, DoublyMapped) {
62 File f = File::temporary();
63 // two mappings of the same memory, different addresses.
64 WritableMemoryMapping mw(File(f.fd()), 0, sizeof(double));
65 MemoryMapping mr(File(f.fd()), 0, sizeof(double));
67 double volatile* dw = mw.asWritableRange<double>().data();
68 const double volatile* dr = mr.asRange<double>().data();
70 // Show that it's truly the same value, even though the pointers differ
73 EXPECT_EQ(*dr, 42 * M_PI);
75 EXPECT_EQ(*dr, 43 * M_PI);
80 void writeStringToFileOrDie(const std::string& str, int fd) {
81 const char* b = str.c_str();
82 size_t count = str.size();
83 ssize_t total_bytes = 0;
86 r = write(fd, b, count);
97 } while (r != 0 && count);
100 } // anonymous namespace
102 TEST(MemoryMapping, Simple) {
103 File f = File::temporary();
104 writeStringToFileOrDie("hello", f.fd());
107 MemoryMapping m(File(f.fd()));
108 EXPECT_EQ("hello", m.data());
111 MemoryMapping m(File(f.fd()), 1, 2);
112 EXPECT_EQ("el", m.data());
116 TEST(MemoryMapping, LargeFile) {
117 std::string fileData;
118 size_t fileSize = sysconf(_SC_PAGESIZE) * 3 + 10;
119 fileData.reserve(fileSize);
120 for (size_t i = 0; i < fileSize; i++) {
121 fileData.push_back(0xff & random());
124 File f = File::temporary();
125 writeStringToFileOrDie(fileData, f.fd());
128 MemoryMapping m(File(f.fd()));
129 EXPECT_EQ(fileData, m.data());
132 size_t size = sysconf(_SC_PAGESIZE) * 2;
133 StringPiece s(fileData.data() + 9, size - 9);
134 MemoryMapping m(File(f.fd()), 9, size - 9);
135 EXPECT_EQ(s.toString(), m.data());
139 TEST(MemoryMapping, ZeroLength) {
140 File f = File::temporary();
141 MemoryMapping m(File(f.fd()));
142 EXPECT_TRUE(m.mlock(MemoryMapping::LockMode::MUST_LOCK));
143 EXPECT_TRUE(m.mlocked());
144 EXPECT_EQ(0, m.data().size());