OmniSciDB  cde582ebc3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
heavyai_fs.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, 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 "OSDependent/heavyai_fs.h"
18 
19 #include <fcntl.h>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include "Logger/Logger.h"
26 
27 namespace heavyai {
28 
30  return getpagesize();
31 }
32 
33 size_t file_size(const int fd) {
34  struct stat buf;
35  int err = fstat(fd, &buf);
36  CHECK_EQ(0, err);
37  return buf.st_size;
38 }
39 
40 void* checked_mmap(const int fd, const size_t sz) {
41  auto ptr = mmap(nullptr, sz, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
42  CHECK(ptr != reinterpret_cast<void*>(-1));
43 #ifdef __linux__
44 #ifdef MADV_HUGEPAGE
45  madvise(ptr, sz, MADV_RANDOM | MADV_WILLNEED | MADV_HUGEPAGE);
46 #else
47  madvise(ptr, sz, MADV_RANDOM | MADV_WILLNEED);
48 #endif
49 #endif
50  return ptr;
51 }
52 
53 void checked_munmap(void* addr, size_t length) {
54  CHECK_EQ(0, munmap(addr, length));
55 }
56 
57 int msync(void* addr, size_t length, bool async) {
58  // TODO: support MS_INVALIDATE?
59  return ::msync(addr, length, async ? MS_ASYNC : MS_SYNC);
60 }
61 
62 int fsync(int fd) {
63  return ::fsync(fd);
64 }
65 
66 int open(const char* path, int flags, int mode) {
67  return ::open(path, flags, mode);
68 }
69 
70 void close(const int fd) {
71  ::close(fd);
72 }
73 
74 ::FILE* fopen(const char* filename, const char* mode) {
75  return ::fopen(filename, mode);
76 }
77 
78 ::FILE* popen(const char* command, const char* type) {
79  return ::popen(command, type);
80 }
81 
82 int32_t pclose(::FILE* fh) {
83  return ::pclose(fh);
84 }
85 
86 int32_t ftruncate(const int32_t fd, int64_t length) {
87  return ::ftruncate(fd, length);
88 }
89 
90 int safe_open(const char* path, int flags, mode_t mode) noexcept {
91  for (int ret;;) {
92  ret = ::open(path, flags, mode);
93  if (ret == -1 && errno == EINTR) { // interrupted by signal
94  continue;
95  }
96  return ret;
97  }
98  UNREACHABLE();
99 }
100 
101 int safe_close(int fd) noexcept {
102  for (int ret;;) {
103  ret = ::close(fd);
104  if (ret == -1 && errno == EINTR) { // interrupted by signal
105  continue;
106  }
107  return ret;
108  }
109  UNREACHABLE();
110 }
111 
112 int safe_fcntl(int fd, int cmd, struct flock* fl) noexcept {
113  for (int ret;;) {
114  ret = ::fcntl(fd, cmd, fl);
115  if (ret == -1 && errno == EINTR) { // interrupted by signal
116  continue;
117  }
118  return ret;
119  }
120  UNREACHABLE();
121 }
122 
123 ssize_t safe_read(const int fd, void* buffer, const size_t buffer_size) noexcept {
124  for (ssize_t ret, sz = 0;;) {
125  ret = ::read(fd, &static_cast<char*>(buffer)[sz], buffer_size - sz);
126  if (ret == -1) {
127  if (errno == EINTR) { // interrupted by signal
128  continue;
129  }
130  return -1;
131  }
132  if (ret == 0) { // EOF
133  return sz;
134  }
135  sz += ret;
136  if (sz == static_cast<ssize_t>(buffer_size)) {
137  return sz;
138  }
139  // either an EOF is coming or interrupted by signal
140  }
141  UNREACHABLE();
142 }
143 
144 ssize_t safe_write(const int fd, const void* buffer, const size_t buffer_size) noexcept {
145  for (ssize_t ret, sz = 0;;) {
146  ret = ::write(fd, &static_cast<char const*>(buffer)[sz], buffer_size - sz);
147  if (ret == -1) {
148  if (errno == EINTR) { // interrupted by signal
149  continue;
150  }
151  return -1;
152  }
153  sz += ret;
154  if (sz == static_cast<ssize_t>(buffer_size)) {
155  return sz;
156  }
157  // either an error is coming (such as disk full) or interrupted by signal
158  }
159  UNREACHABLE();
160 }
161 
162 int32_t safe_ftruncate(const int32_t fd, int64_t length) noexcept {
163  for (int ret;;) {
164  ret = ::ftruncate(fd, length);
165  if (ret == -1 && errno == EINTR) { // interrupted by signal
166  continue;
167  }
168  return ret;
169  }
170  UNREACHABLE();
171 }
172 
173 } // namespace heavyai
#define CHECK_EQ(x, y)
Definition: Logger.h:230
int safe_open(const char *path, int flags, mode_t mode) noexcept
Definition: heavyai_fs.cpp:90
#define UNREACHABLE()
Definition: Logger.h:266
int32_t pclose(::FILE *fh)
Definition: heavyai_fs.cpp:82
::FILE * popen(const char *command, const char *type)
Definition: heavyai_fs.cpp:78
ssize_t safe_read(const int fd, void *buffer, const size_t buffer_size) noexcept
Definition: heavyai_fs.cpp:123
size_t write(FILE *f, const size_t offset, const size_t size, const int8_t *buf)
Writes the specified number of bytes to the offset position in file f from buf.
Definition: File.cpp:150
ssize_t safe_write(const int fd, const void *buffer, const size_t buffer_size) noexcept
Definition: heavyai_fs.cpp:144
future< Result > async(Fn &&fn, Args &&...args)
size_t read(FILE *f, const size_t offset, const size_t size, int8_t *buf)
Reads the specified number of bytes from the offset position in file f into buf.
Definition: File.cpp:142
int open(const char *path, int flags, int mode)
Definition: heavyai_fs.cpp:66
::FILE * fopen(const char *filename, const char *mode)
Definition: heavyai_fs.cpp:74
int msync(void *addr, size_t length, bool async)
Definition: heavyai_fs.cpp:57
int32_t safe_ftruncate(const int32_t fd, int64_t length) noexcept
Definition: heavyai_fs.cpp:162
int fsync(int fd)
Definition: heavyai_fs.cpp:62
#define CHECK(condition)
Definition: Logger.h:222
void checked_munmap(void *addr, size_t length)
Definition: heavyai_fs.cpp:53
int32_t ftruncate(const int32_t fd, int64_t length)
Definition: heavyai_fs.cpp:86
void close(const int fd)
Definition: heavyai_fs.cpp:70
int safe_fcntl(int fd, int cmd, struct flock *fl) noexcept
Definition: heavyai_fs.cpp:112
int safe_close(int fd) noexcept
Definition: heavyai_fs.cpp:101
int get_page_size()
Definition: heavyai_fs.cpp:29
size_t file_size(const int fd)
Definition: heavyai_fs.cpp:33
void * checked_mmap(const int fd, const size_t sz)
Definition: heavyai_fs.cpp:40