Compute Library
 21.11
MMappedFile.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #if !defined(BARE_METAL)
25 
27 
28 #include <cstdio>
29 #include <cstring>
30 #include <tuple>
31 
32 #include <fcntl.h>
33 #include <sys/mman.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 
38 namespace arm_compute
39 {
40 namespace utils
41 {
42 namespace mmap_io
43 {
44 namespace
45 {
46 /** File size accessor
47  *
48  * @param[in] filename File to extract its size
49  *
50  * @return A pair of size and status.
51  */
52 std::pair<size_t, bool> get_file_size(const std::string &filename)
53 {
54  struct stat st; // NOLINT
55  memset(&st, 0, sizeof(struct stat));
56  if(stat(filename.c_str(), &st) == 0)
57  {
58  return std::make_pair(st.st_size, true);
59  }
60  else
61  {
62  return std::make_pair(0, false);
63  }
64 }
65 
66 /** Get OS page size
67  *
68  * @return Page size
69  */
70 size_t get_page_size()
71 {
72  return sysconf(_SC_PAGESIZE);
73 }
74 } // namespace
75 
77  : _filename(), _file_size(0), _map_size(0), _map_offset(0), _fp(nullptr), _data(nullptr)
78 {
79 }
80 
81 MMappedFile::MMappedFile(std::string filename, size_t size, size_t offset)
82  : _filename(std::move(filename)), _file_size(0), _map_size(size), _map_offset(offset), _fp(nullptr), _data(nullptr)
83 {
84  map(_filename, _map_size, _map_offset);
85 }
86 
88 {
89  release();
90 }
91 
92 bool MMappedFile::map(const std::string &filename, size_t size, size_t offset)
93 {
94  // Check if file is mapped
95  if(is_mapped())
96  {
97  return false;
98  }
99 
100  // Open file
101  _fp = fopen(filename.c_str(), "a+be");
102  if(_fp == nullptr)
103  {
104  return false;
105  }
106 
107  // Extract file descriptor
108  int fd = fileno(_fp);
109  bool status = fd >= 0;
110  if(status)
111  {
112  // Get file size
113  std::tie(_file_size, status) = get_file_size(_filename);
114 
115  if(status)
116  {
117  // Map all file from offset if map size is 0
118  _map_size = (size == 0) ? _file_size : size;
119  _map_offset = offset;
120 
121  // Check offset mapping
122  if((_map_offset > _file_size) || (_map_offset % get_page_size() != 0))
123  {
124  status = false;
125  }
126  else
127  {
128  // Truncate to file size
129  if(_map_offset + _map_size > _file_size)
130  {
131  _map_size = _file_size - _map_offset;
132  }
133 
134  // Perform mapping
135  _data = ::mmap(nullptr, _map_size, PROT_WRITE, MAP_SHARED, fd, _map_offset);
136  }
137  }
138  }
139 
140  if(!status)
141  {
142  fclose(_fp);
143  }
144 
145  return status;
146 }
147 
149 {
150  // Unmap file
151  if(_data != nullptr)
152  {
153  ::munmap(_data, _file_size);
154  _data = nullptr;
155  }
156 
157  // Close file
158  if(_fp != nullptr)
159  {
160  fclose(_fp);
161  _fp = nullptr;
162  }
163 
164  // Clear variables
165  _file_size = 0;
166  _map_size = 0;
167  _map_offset = 0;
168 }
169 
170 unsigned char *MMappedFile::data()
171 {
172  return static_cast<unsigned char *>(_data);
173 }
174 
176 {
177  return _file_size;
178 }
179 
180 size_t MMappedFile::map_size() const
181 {
182  return _map_size;
183 }
184 
186 {
187  return _data != nullptr;
188 }
189 } // namespace mmap_io
190 } // namespace utils
191 } // namespace arm_compute
192 #endif // !defined(BARE_METAL)
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
Definition: helpers.h:1069
size_t map_size() const
Map size accessor.
bool map(const std::string &filename, size_t size, size_t offset)
Opens and maps a file.
Definition: MMappedFile.cpp:92
void release()
Unmaps and closes file.
Copyright (c) 2017-2021 Arm Limited.
bool is_mapped() const
Checks if file mapped.
unsigned char * data()
Mapped data accessor.
size_t file_size() const
File size accessor.