LLVM: lib/CAS/OnDiskCommon.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13#include
14#include
15
16#if __has_include(<sys/file.h>)
17#include <sys/file.h>
18#ifdef LOCK_SH
19#define HAVE_FLOCK 1
20#else
21#define HAVE_FLOCK 0
22#endif
23#endif
24
25#if __has_include(<fcntl.h>)
26#include <fcntl.h>
27#endif
28
29#if __has_include(<sys/mount.h>)
30#include <sys/mount.h>
31#endif
32
33#ifdef __APPLE__
34#if __has_include(<sys/sysctl.h>)
35#include <sys/sysctl.h>
36#endif
37#endif
38
39using namespace llvm;
40
42
44 static std::once_flag Flag;
46 std::call_once(Flag, [&Err] {
48 constexpr const char *EnvVar = "LLVM_CAS_MAX_MAPPING_SIZE";
51 return;
52
56 "invalid value for %s: expected integer", EnvVar);
58 });
59
60 if (Err)
61 return std::move(Err);
62
64 return std::nullopt;
65
67}
68
72
75#if HAVE_FLOCK
77 return std::error_code();
78 return std::error_code(errno, std::generic_category());
79#elif defined(_WIN32)
80
82#else
84#endif
85}
86
88#if HAVE_FLOCK
89 if (flock(FD, LOCK_UN) == 0)
90 return std::error_code();
91 return std::error_code(errno, std::generic_category());
92#elif defined(_WIN32)
93
95#else
97#endif
98}
99
100std::error_code
103#if HAVE_FLOCK
104 auto Start = std::chrono::steady_clock::now();
105 auto End = Start + Timeout;
106 do {
108 LOCK_NB) == 0)
109 return std::error_code();
110 int Error = errno;
111 if (Error == EWOULDBLOCK) {
112
113 std::this_thread::sleep_for(std::chrono::milliseconds(1));
114 continue;
115 }
116 return std::error_code(Error, std::generic_category());
117 } while (std::chrono::steady_clock::now() < End);
119#elif defined(_WIN32)
120
122#else
124#endif
125}
126
128 size_t NewSize) {
129 auto CreateError = [&](std::error_code EC) -> Expected<size_t> {
130 if (EC == std::errc::not_supported)
131
132 return NewSize;
133#if defined(HAVE_POSIX_FALLOCATE)
134 if (EC == std::errc::invalid_argument && CurrentSize < NewSize && // len > 0
135 NewSize < std::numeric_limits<off_t>::max())
136
137
138
139 return NewSize;
140#endif
142 "failed to allocate to CAS file: " + EC.message());
143 };
144#if defined(HAVE_POSIX_FALLOCATE)
145
146 if (int Err = posix_fallocate(FD, CurrentSize, NewSize - CurrentSize))
147 return CreateError(std::error_code(Err, std::generic_category()));
148 return NewSize;
149#elif defined(__APPLE__)
150 fstore_t FAlloc;
151 FAlloc.fst_flags = F_ALLOCATEALL;
152#if defined(F_ALLOCATEPERSIST) && \
153 defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
154 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 130000
155
156 FAlloc.fst_flags |= F_ALLOCATEPERSIST;
157#endif
158 FAlloc.fst_posmode = F_PEOFPOSMODE;
159 FAlloc.fst_offset = 0;
160 FAlloc.fst_length = NewSize - CurrentSize;
161 FAlloc.fst_bytesalloc = 0;
162 if (fcntl(FD, F_PREALLOCATE, &FAlloc))
164 assert(CurrentSize + FAlloc.fst_bytesalloc >= NewSize);
165 return CurrentSize + FAlloc.fst_bytesalloc;
166#else
167 (void)CreateError;
168 return NewSize;
169#endif
170}
171
173
174#if defined(__APPLE__) && __has_include(<sys/mount.h>)
175
177 StringRef Path = P.toNullTerminatedStringRef(PathStorage);
178 struct statfs StatFS;
179 if (statfs(Path.data(), &StatFS) != 0)
180 return false;
181
182 if (strcmp(StatFS.f_fstypename, "tmpfs") == 0)
183 return true;
184#endif
185
186 return false;
187}
188
190#ifdef __APPLE__
191#if __has_include(<sys/sysctl.h>) && defined(KERN_BOOTTIME)
192 struct timeval TV;
193 size_t TVLen = sizeof(TV);
194 int KernBoot[2] = {CTL_KERN, KERN_BOOTTIME};
195 if (sysctl(KernBoot, 2, &TV, &TVLen, nullptr, 0) < 0)
197 "failed to get boottime");
198 if (TVLen != sizeof(TV))
199 return createStringError("sysctl kern.boottime unexpected format");
200 return TV.tv_sec;
201#else
202 return 0;
203#endif
204#elif defined(__linux__)
205
206
210 return Status.getLastModificationTime().time_since_epoch().count();
211#else
212 return 0;
213#endif
214}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint64_t OnDiskCASMaxMappingSize
Definition OnDiskCommon.cpp:41
Provides a library for accessing information about this process and other processes on the operating ...
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
static LLVM_ABI std::optional< std::string > GetEnv(StringRef name)
Represents the result of a call to sys::fs::status().
LLVM_ABI_FOR_TEST void setMaxMappingSize(uint64_t Size)
Set MaxMappingSize for ondisk CAS.
Definition OnDiskCommon.cpp:69
Expected< std::optional< uint64_t > > getOverriddenMaxMappingSize()
Retrieves an overridden maximum mapping size for CAS files, if any, speicified by LLVM_CAS_MAX_MAPPIN...
Definition OnDiskCommon.cpp:43
std::error_code lockFileThreadSafe(int FD, llvm::sys::fs::LockKind Kind)
Thread-safe alternative to sys::fs::lockFile.
Definition OnDiskCommon.cpp:73
std::error_code unlockFileThreadSafe(int FD)
Thread-safe alternative to sys::fs::unlockFile.
Definition OnDiskCommon.cpp:87
std::error_code tryLockFileThreadSafe(int FD, std::chrono::milliseconds Timeout=std::chrono::milliseconds(0), llvm::sys::fs::LockKind Kind=llvm::sys::fs::LockKind::Exclusive)
Thread-safe alternative to sys::fs::tryLockFile.
Definition OnDiskCommon.cpp:101
Expected< uint64_t > getBootTime()
Get boot time for the OS.
Definition OnDiskCommon.cpp:189
Expected< size_t > preallocateFileTail(int FD, size_t CurrentSize, size_t NewSize)
Allocate space for the file FD on disk, if the filesystem supports it.
Definition OnDiskCommon.cpp:127
bool useSmallMappingSize(const Twine &Path)
Whether to use a small file mapping for ondisk databases created in Path.
Definition OnDiskCommon.cpp:172
LLVM_ABI std::error_code lockFile(int FD, LockKind Kind=LockKind::Exclusive)
Lock the file.
LLVM_ABI std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout=std::chrono::milliseconds(0), LockKind Kind=LockKind::Exclusive)
Try to locks the file during the specified time.
LockKind
An enumeration for the lock kind.
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI std::error_code unlockFile(int FD)
Unlock the file.
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::error_code make_error_code(BitcodeError E)
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ Timeout
Reached timeout while waiting for the owner to release the lock.
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.