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.