Adding support for signed integers
[folly.git] / folly / MemoryMapping.h
1 /*
2  * Copyright 2014 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 #ifndef FOLLY_MEMORYMAPPING_H_
18 #define FOLLY_MEMORYMAPPING_H_
19
20 #include "folly/FBString.h"
21 #include "folly/File.h"
22 #include "folly/Range.h"
23 #include <glog/logging.h>
24 #include <boost/noncopyable.hpp>
25
26 namespace folly {
27
28 /**
29  * Maps files in memory (read-only).
30  *
31  * @author Tudor Bosman (tudorb@fb.com)
32  */
33 class MemoryMapping : boost::noncopyable {
34  public:
35   /**
36    * Lock the pages in memory?
37    * TRY_LOCK  = try to lock, log warning if permission denied
38    * MUST_LOCK = lock, fail assertion if permission denied.
39    */
40   enum class LockMode {
41     TRY_LOCK,
42     MUST_LOCK
43   };
44   /**
45    * Map a portion of the file indicated by filename in memory, causing a CHECK
46    * failure on error.
47    *
48    * By default, map the whole file.  length=-1: map from offset to EOF.
49    * Unlike the mmap() system call, offset and length don't need to be
50    * page-aligned.  length is clipped to the end of the file if it's too large.
51    *
52    * The mapping will be destroyed (and the memory pointed-to by data() will
53    * likely become inaccessible) when the MemoryMapping object is destroyed.
54    */
55   explicit MemoryMapping(File file,
56                          off_t offset=0,
57                          off_t length=-1,
58                          off_t pageSize=0);
59
60   explicit MemoryMapping(const char* name,
61                          off_t offset=0,
62                          off_t length=-1,
63                          off_t pageSize=0);
64
65   explicit MemoryMapping(int fd,
66                          off_t offset=0,
67                          off_t length=-1,
68                          off_t pageSize=0);
69
70   virtual ~MemoryMapping();
71
72   /**
73    * Lock the pages in memory
74    */
75   bool mlock(LockMode lock);
76
77   /**
78    * Unlock the pages.
79    * If dontneed is true, the kernel is instructed to release these pages
80    * (per madvise(MADV_DONTNEED)).
81    */
82   void munlock(bool dontneed=false);
83
84   /**
85    * Hint that these pages will be scanned linearly.
86    * madvise(MADV_SEQUENTIAL)
87    */
88   void hintLinearScan();
89
90   /**
91    * Advise the kernel about memory access.
92    */
93   void advise(int advice) const;
94
95   /**
96    * A bitwise cast of the mapped bytes as range of values. Only intended for
97    * use with POD or in-place usable types.
98    */
99   template<class T>
100   Range<const T*> asRange() const {
101     size_t count = data_.size() / sizeof(T);
102     return Range<const T*>(static_cast<const T*>(
103                              static_cast<const void*>(data_.data())),
104                            count);
105   }
106
107   /**
108    * A range of bytes mapped by this mapping.
109    */
110   Range<const uint8_t*> range() const {
111     return {data_.begin(), data_.end()};
112   }
113
114   /**
115    * Return the memory area where the file was mapped.
116    */
117   StringPiece data() const {
118     return asRange<const char>();
119   }
120
121   bool mlocked() const {
122     return locked_;
123   }
124
125   int fd() const { return file_.fd(); }
126
127  protected:
128   MemoryMapping();
129
130   void init(File file,
131             off_t offset, off_t length,
132             off_t pageSize,
133             int prot,
134             bool grow);
135
136   File file_;
137   void* mapStart_;
138   off_t mapLength_;
139   off_t pageSize_;
140   bool locked_;
141   Range<uint8_t*> data_;
142 };
143
144 /**
145  * Maps files in memory for writing.
146  *
147  * @author Tom Jackson (tjackson@fb.com)
148  */
149 class WritableMemoryMapping : public MemoryMapping {
150  public:
151   explicit WritableMemoryMapping(File file,
152                                  off_t offset = 0,
153                                  off_t length = -1,
154                                  off_t pageSize = 0);
155   /**
156    * A bitwise cast of the mapped bytes as range of mutable values. Only
157    * intended for use with POD or in-place usable types.
158    */
159   template<class T>
160   Range<T*> asWritableRange() const {
161     size_t count = data_.size() / sizeof(T);
162     return Range<T*>(static_cast<T*>(
163                        static_cast<void*>(data_.data())),
164                      count);
165   }
166
167   /**
168    * A range of mutable bytes mapped by this mapping.
169    */
170   Range<uint8_t*> writableRange() const {
171     return data_;
172   }
173 };
174
175 }  // namespace folly
176
177 #endif /* FOLLY_MEMORYMAPPING_H_ */