xref: /llvm-project/bolt/runtime/common.h (revision 87e9c42495aa4d290b04fa2866ec0e627a54842a)
12f09f445SMaksim Panchenko //===- bolt/runtime/common.h ------------------------------------*- C++ -*-===//
276d346caSVladislav Khmelevsky //
376d346caSVladislav Khmelevsky // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476d346caSVladislav Khmelevsky // See https://llvm.org/LICENSE.txt for license information.
576d346caSVladislav Khmelevsky // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676d346caSVladislav Khmelevsky //
776d346caSVladislav Khmelevsky //===----------------------------------------------------------------------===//
876d346caSVladislav Khmelevsky 
91c3653dfSNathan Sidwell #if defined(__linux__)
101cf23e5eSAlexander Shaposhnikov 
119bd71615SXun Li #include <cstddef>
129bd71615SXun Li #include <cstdint>
131cf23e5eSAlexander Shaposhnikov 
14823ebcc7SVladislav Khmelevsky #include "config.h"
15823ebcc7SVladislav Khmelevsky 
16823ebcc7SVladislav Khmelevsky #ifdef HAVE_ELF_H
17823ebcc7SVladislav Khmelevsky #include <elf.h>
18823ebcc7SVladislav Khmelevsky #endif
19823ebcc7SVladislav Khmelevsky 
201c3653dfSNathan Sidwell #elif defined(__APPLE__)
211cf23e5eSAlexander Shaposhnikov 
221cf23e5eSAlexander Shaposhnikov typedef __SIZE_TYPE__ size_t;
231cf23e5eSAlexander Shaposhnikov #define __SSIZE_TYPE__                                                         \
241cf23e5eSAlexander Shaposhnikov   __typeof__(_Generic((__SIZE_TYPE__)0, unsigned long long int                 \
251cf23e5eSAlexander Shaposhnikov                       : (long long int)0, unsigned long int                    \
261cf23e5eSAlexander Shaposhnikov                       : (long int)0, unsigned int                              \
271cf23e5eSAlexander Shaposhnikov                       : (int)0, unsigned short                                 \
281cf23e5eSAlexander Shaposhnikov                       : (short)0, unsigned char                                \
291cf23e5eSAlexander Shaposhnikov                       : (signed char)0))
301cf23e5eSAlexander Shaposhnikov typedef __SSIZE_TYPE__ ssize_t;
311cf23e5eSAlexander Shaposhnikov 
321cf23e5eSAlexander Shaposhnikov typedef unsigned long long uint64_t;
33d6e60c5bSAlexander Shaposhnikov typedef unsigned uint32_t;
34a0dd5b05SAlexander Shaposhnikov typedef unsigned char uint8_t;
35d6e60c5bSAlexander Shaposhnikov 
36d6e60c5bSAlexander Shaposhnikov typedef long long int64_t;
37d6e60c5bSAlexander Shaposhnikov typedef int int32_t;
381cf23e5eSAlexander Shaposhnikov 
391c3653dfSNathan Sidwell #else
401c3653dfSNathan Sidwell #error "For Linux or MacOS only"
41bbd9d610SAlexander Shaposhnikov #endif
429bd71615SXun Li 
438b23a853SDenis Revunov #define PROT_READ 0x1  /* Page can be read.  */
448b23a853SDenis Revunov #define PROT_WRITE 0x2 /* Page can be written.  */
458b23a853SDenis Revunov #define PROT_EXEC 0x4  /* Page can be executed.  */
468b23a853SDenis Revunov #define PROT_NONE 0x0  /* Page can not be accessed.  */
478b23a853SDenis Revunov #define PROT_GROWSDOWN                                                         \
488b23a853SDenis Revunov   0x01000000 /* Extend change to start of                                      \
498b23a853SDenis Revunov                 growsdown vma (mprotect only).  */
508b23a853SDenis Revunov #define PROT_GROWSUP                                                           \
518b23a853SDenis Revunov   0x02000000 /* Extend change to start of                                      \
528b23a853SDenis Revunov                 growsup vma (mprotect only).  */
538b23a853SDenis Revunov 
548b23a853SDenis Revunov /* Sharing types (must choose one and only one of these).  */
558b23a853SDenis Revunov #define MAP_SHARED 0x01  /* Share changes.  */
568b23a853SDenis Revunov #define MAP_PRIVATE 0x02 /* Changes are private.  */
578b23a853SDenis Revunov #define MAP_FIXED 0x10   /* Interpret addr exactly.  */
588b23a853SDenis Revunov 
598b23a853SDenis Revunov #if defined(__APPLE__)
608b23a853SDenis Revunov #define MAP_ANONYMOUS 0x1000
618b23a853SDenis Revunov #else
628b23a853SDenis Revunov #define MAP_ANONYMOUS 0x20
638b23a853SDenis Revunov #endif
648b23a853SDenis Revunov 
658b23a853SDenis Revunov #define MAP_FAILED ((void *)-1)
668b23a853SDenis Revunov 
6760bbddf3SDenis Revunov #define SEEK_SET 0 /* Seek from beginning of file.  */
6860bbddf3SDenis Revunov #define SEEK_CUR 1 /* Seek from current position.  */
6960bbddf3SDenis Revunov #define SEEK_END 2 /* Seek from end of file.  */
7060bbddf3SDenis Revunov 
7160bbddf3SDenis Revunov #define O_RDONLY 0
7260bbddf3SDenis Revunov #define O_WRONLY 1
7360bbddf3SDenis Revunov #define O_RDWR 2
7460bbddf3SDenis Revunov #define O_CREAT 64
7560bbddf3SDenis Revunov #define O_TRUNC 512
7660bbddf3SDenis Revunov #define O_APPEND 1024
7760bbddf3SDenis Revunov 
78ea2182feSMaksim Panchenko // Functions that are required by freestanding environment. Compiler may
79ea2182feSMaksim Panchenko // generate calls to these implicitly.
80ea2182feSMaksim Panchenko extern "C" {
memcpy(void * Dest,const void * Src,size_t Len)81ea2182feSMaksim Panchenko void *memcpy(void *Dest, const void *Src, size_t Len) {
82ea2182feSMaksim Panchenko   uint8_t *d = static_cast<uint8_t *>(Dest);
83ea2182feSMaksim Panchenko   const uint8_t *s = static_cast<const uint8_t *>(Src);
84ea2182feSMaksim Panchenko   while (Len--)
85ea2182feSMaksim Panchenko     *d++ = *s++;
86ea2182feSMaksim Panchenko   return Dest;
87ea2182feSMaksim Panchenko }
88ea2182feSMaksim Panchenko 
memmove(void * Dest,const void * Src,size_t Len)89ea2182feSMaksim Panchenko void *memmove(void *Dest, const void *Src, size_t Len) {
90ea2182feSMaksim Panchenko   uint8_t *d = static_cast<uint8_t *>(Dest);
91ea2182feSMaksim Panchenko   const uint8_t *s = static_cast<const uint8_t *>(Src);
92ea2182feSMaksim Panchenko   if (d < s) {
93ea2182feSMaksim Panchenko     while (Len--)
94ea2182feSMaksim Panchenko       *d++ = *s++;
95ea2182feSMaksim Panchenko   } else {
96ea2182feSMaksim Panchenko     s += Len - 1;
97ea2182feSMaksim Panchenko     d += Len - 1;
98ea2182feSMaksim Panchenko     while (Len--)
99ea2182feSMaksim Panchenko       *d-- = *s--;
100ea2182feSMaksim Panchenko   }
101ea2182feSMaksim Panchenko 
102ea2182feSMaksim Panchenko   return Dest;
103ea2182feSMaksim Panchenko }
104ea2182feSMaksim Panchenko 
memset(void * Buf,int C,size_t Size)105e10e120cSVladislav Khmelevsky void *memset(void *Buf, int C, size_t Size) {
106e10e120cSVladislav Khmelevsky   char *S = (char *)Buf;
107e10e120cSVladislav Khmelevsky   for (size_t I = 0; I < Size; ++I)
108e10e120cSVladislav Khmelevsky     *S++ = C;
109e10e120cSVladislav Khmelevsky   return Buf;
110ea2182feSMaksim Panchenko }
111ea2182feSMaksim Panchenko 
memcmp(const void * s1,const void * s2,size_t n)112ea2182feSMaksim Panchenko int memcmp(const void *s1, const void *s2, size_t n) {
113ea2182feSMaksim Panchenko   const uint8_t *c1 = static_cast<const uint8_t *>(s1);
114ea2182feSMaksim Panchenko   const uint8_t *c2 = static_cast<const uint8_t *>(s2);
115ea2182feSMaksim Panchenko   for (; n--; c1++, c2++) {
116ea2182feSMaksim Panchenko     if (*c1 != *c2)
117ea2182feSMaksim Panchenko       return *c1 < *c2 ? -1 : 1;
118ea2182feSMaksim Panchenko   }
119ea2182feSMaksim Panchenko   return 0;
120ea2182feSMaksim Panchenko }
121ea2182feSMaksim Panchenko } // extern "C"
122ea2182feSMaksim Panchenko 
1239bd71615SXun Li // Anonymous namespace covering everything but our library entry point
1249bd71615SXun Li namespace {
1259bd71615SXun Li 
126*87e9c424SElvina Yakubova struct dirent64 {
127*87e9c424SElvina Yakubova   uint64_t d_ino;          /* Inode number */
128*87e9c424SElvina Yakubova   int64_t d_off;           /* Offset to next linux_dirent */
129*87e9c424SElvina Yakubova   unsigned short d_reclen; /* Length of this linux_dirent */
130*87e9c424SElvina Yakubova   unsigned char d_type;
131*87e9c424SElvina Yakubova   char d_name[]; /* Filename (null-terminated) */
132*87e9c424SElvina Yakubova                  /* length is actually (d_reclen - 2 -
133*87e9c424SElvina Yakubova                    offsetof(struct linux_dirent, d_name)) */
134*87e9c424SElvina Yakubova };
135*87e9c424SElvina Yakubova 
136*87e9c424SElvina Yakubova /* Length of the entries in `struct utsname' is 65.  */
137*87e9c424SElvina Yakubova #define _UTSNAME_LENGTH 65
138*87e9c424SElvina Yakubova 
139*87e9c424SElvina Yakubova struct UtsNameTy {
140*87e9c424SElvina Yakubova   char sysname[_UTSNAME_LENGTH];  /* Operating system name (e.g., "Linux") */
141*87e9c424SElvina Yakubova   char nodename[_UTSNAME_LENGTH]; /* Name within "some implementation-defined
142*87e9c424SElvina Yakubova                       network" */
143*87e9c424SElvina Yakubova   char release[_UTSNAME_LENGTH]; /* Operating system release (e.g., "2.6.28") */
144*87e9c424SElvina Yakubova   char version[_UTSNAME_LENGTH]; /* Operating system version */
145*87e9c424SElvina Yakubova   char machine[_UTSNAME_LENGTH]; /* Hardware identifier */
146*87e9c424SElvina Yakubova   char domainname[_UTSNAME_LENGTH]; /* NIS or YP domain name */
147*87e9c424SElvina Yakubova };
148*87e9c424SElvina Yakubova 
149*87e9c424SElvina Yakubova struct timespec {
150*87e9c424SElvina Yakubova   uint64_t tv_sec;  /* seconds */
151*87e9c424SElvina Yakubova   uint64_t tv_nsec; /* nanoseconds */
152*87e9c424SElvina Yakubova };
153*87e9c424SElvina Yakubova 
154*87e9c424SElvina Yakubova #if defined(__aarch64__)
155*87e9c424SElvina Yakubova #include "sys_aarch64.h"
156*87e9c424SElvina Yakubova #else
157*87e9c424SElvina Yakubova #include "sys_x86_64.h"
158*87e9c424SElvina Yakubova #endif
159a86dd9aeSDenis Revunov 
160d6e60c5bSAlexander Shaposhnikov constexpr uint32_t BufSize = 10240;
161d6e60c5bSAlexander Shaposhnikov 
162d6e60c5bSAlexander Shaposhnikov // Helper functions for writing strings to the .fdata file. We intentionally
163ea2182feSMaksim Panchenko // avoid using libc names to make it clear it is our impl.
164d6e60c5bSAlexander Shaposhnikov 
165d6e60c5bSAlexander Shaposhnikov /// Write number Num using Base to the buffer in OutBuf, returns a pointer to
166d6e60c5bSAlexander Shaposhnikov /// the end of the string.
intToStr(char * OutBuf,uint64_t Num,uint32_t Base)167d6e60c5bSAlexander Shaposhnikov char *intToStr(char *OutBuf, uint64_t Num, uint32_t Base) {
168d6e60c5bSAlexander Shaposhnikov   const char *Chars = "0123456789abcdef";
169d6e60c5bSAlexander Shaposhnikov   char Buf[21];
170d6e60c5bSAlexander Shaposhnikov   char *Ptr = Buf;
171d6e60c5bSAlexander Shaposhnikov   while (Num) {
172d6e60c5bSAlexander Shaposhnikov     *Ptr++ = *(Chars + (Num % Base));
173d6e60c5bSAlexander Shaposhnikov     Num /= Base;
174d6e60c5bSAlexander Shaposhnikov   }
175d6e60c5bSAlexander Shaposhnikov   if (Ptr == Buf) {
176d6e60c5bSAlexander Shaposhnikov     *OutBuf++ = '0';
177d6e60c5bSAlexander Shaposhnikov     return OutBuf;
178d6e60c5bSAlexander Shaposhnikov   }
179883bf0e8SAmir Ayupov   while (Ptr != Buf)
180d6e60c5bSAlexander Shaposhnikov     *OutBuf++ = *--Ptr;
181883bf0e8SAmir Ayupov 
182d6e60c5bSAlexander Shaposhnikov   return OutBuf;
183d6e60c5bSAlexander Shaposhnikov }
184d6e60c5bSAlexander Shaposhnikov 
185d6e60c5bSAlexander Shaposhnikov /// Copy Str to OutBuf, returns a pointer to the end of the copied string
186d6e60c5bSAlexander Shaposhnikov char *strCopy(char *OutBuf, const char *Str, int32_t Size = BufSize) {
187d6e60c5bSAlexander Shaposhnikov   while (*Str) {
188d6e60c5bSAlexander Shaposhnikov     *OutBuf++ = *Str++;
189d6e60c5bSAlexander Shaposhnikov     if (--Size <= 0)
190d6e60c5bSAlexander Shaposhnikov       return OutBuf;
191d6e60c5bSAlexander Shaposhnikov   }
192d6e60c5bSAlexander Shaposhnikov   return OutBuf;
193d6e60c5bSAlexander Shaposhnikov }
194d6e60c5bSAlexander Shaposhnikov 
1952da5b12aSAmir Ayupov /// Compare two strings, at most Num bytes.
strnCmp(const char * Str1,const char * Str2,size_t Num)1962da5b12aSAmir Ayupov int strnCmp(const char *Str1, const char *Str2, size_t Num) {
1972da5b12aSAmir Ayupov   while (Num && *Str1 && (*Str1 == *Str2)) {
1982da5b12aSAmir Ayupov     Num--;
1992da5b12aSAmir Ayupov     Str1++;
2002da5b12aSAmir Ayupov     Str2++;
2012da5b12aSAmir Ayupov   }
2022da5b12aSAmir Ayupov   if (Num == 0)
2032da5b12aSAmir Ayupov     return 0;
2042da5b12aSAmir Ayupov   return *(unsigned char *)Str1 - *(unsigned char *)Str2;
2052da5b12aSAmir Ayupov }
2062da5b12aSAmir Ayupov 
strLen(const char * Str)207d6e60c5bSAlexander Shaposhnikov uint32_t strLen(const char *Str) {
208d6e60c5bSAlexander Shaposhnikov   uint32_t Size = 0;
209d6e60c5bSAlexander Shaposhnikov   while (*Str++)
210d6e60c5bSAlexander Shaposhnikov     ++Size;
211d6e60c5bSAlexander Shaposhnikov   return Size;
212d6e60c5bSAlexander Shaposhnikov }
213d6e60c5bSAlexander Shaposhnikov 
strStr(const char * const Haystack,const char * const Needle)2141fb18619SAlexey Moksyakov void *strStr(const char *const Haystack, const char *const Needle) {
2151fb18619SAlexey Moksyakov   int j = 0;
2161fb18619SAlexey Moksyakov 
2171fb18619SAlexey Moksyakov   for (int i = 0; i < strLen(Haystack); i++) {
2181fb18619SAlexey Moksyakov     if (Haystack[i] == Needle[0]) {
2191fb18619SAlexey Moksyakov       for (j = 1; j < strLen(Needle); j++) {
2201fb18619SAlexey Moksyakov         if (Haystack[i + j] != Needle[j])
2211fb18619SAlexey Moksyakov           break;
2221fb18619SAlexey Moksyakov       }
2231fb18619SAlexey Moksyakov       if (j == strLen(Needle))
2241fb18619SAlexey Moksyakov         return (void *)&Haystack[i];
2251fb18619SAlexey Moksyakov     }
2261fb18619SAlexey Moksyakov   }
2271fb18619SAlexey Moksyakov   return nullptr;
2281fb18619SAlexey Moksyakov }
2291fb18619SAlexey Moksyakov 
reportNumber(const char * Msg,uint64_t Num,uint32_t Base)2303b876cc3SAlexander Shaposhnikov void reportNumber(const char *Msg, uint64_t Num, uint32_t Base) {
2313b876cc3SAlexander Shaposhnikov   char Buf[BufSize];
2323b876cc3SAlexander Shaposhnikov   char *Ptr = Buf;
2333b876cc3SAlexander Shaposhnikov   Ptr = strCopy(Ptr, Msg, BufSize - 23);
2343b876cc3SAlexander Shaposhnikov   Ptr = intToStr(Ptr, Num, Base);
2353b876cc3SAlexander Shaposhnikov   Ptr = strCopy(Ptr, "\n");
2363b876cc3SAlexander Shaposhnikov   __write(2, Buf, Ptr - Buf);
2373b876cc3SAlexander Shaposhnikov }
2383b876cc3SAlexander Shaposhnikov 
report(const char * Msg)2393b876cc3SAlexander Shaposhnikov void report(const char *Msg) { __write(2, Msg, strLen(Msg)); }
2403b876cc3SAlexander Shaposhnikov 
2412ffd6e2bSElvina Yakubova unsigned long hexToLong(const char *Str, char Terminator = '\0') {
2422ffd6e2bSElvina Yakubova   unsigned long Res = 0;
2432ffd6e2bSElvina Yakubova   while (*Str != Terminator) {
2442ffd6e2bSElvina Yakubova     Res <<= 4;
2452ffd6e2bSElvina Yakubova     if ('0' <= *Str && *Str <= '9')
2462ffd6e2bSElvina Yakubova       Res += *Str++ - '0';
2472ffd6e2bSElvina Yakubova     else if ('a' <= *Str && *Str <= 'f')
2482ffd6e2bSElvina Yakubova       Res += *Str++ - 'a' + 10;
2492ffd6e2bSElvina Yakubova     else if ('A' <= *Str && *Str <= 'F')
2502ffd6e2bSElvina Yakubova       Res += *Str++ - 'A' + 10;
251883bf0e8SAmir Ayupov     else
2522ffd6e2bSElvina Yakubova       return 0;
2532ffd6e2bSElvina Yakubova   }
2542ffd6e2bSElvina Yakubova   return Res;
2552ffd6e2bSElvina Yakubova }
2562ffd6e2bSElvina Yakubova 
2571fb18619SAlexey Moksyakov /// Starting from character at \p buf, find the longest consecutive sequence
2581fb18619SAlexey Moksyakov /// of digits (0-9) and convert it to uint32_t. The converted value
2591fb18619SAlexey Moksyakov /// is put into \p ret. \p end marks the end of the buffer to avoid buffer
2601fb18619SAlexey Moksyakov /// overflow. The function \returns whether a valid uint32_t value is found.
2611fb18619SAlexey Moksyakov /// \p buf will be updated to the next character right after the digits.
scanUInt32(const char * & Buf,const char * End,uint32_t & Ret)2621fb18619SAlexey Moksyakov static bool scanUInt32(const char *&Buf, const char *End, uint32_t &Ret) {
2631fb18619SAlexey Moksyakov   uint64_t Result = 0;
2641fb18619SAlexey Moksyakov   const char *OldBuf = Buf;
2651fb18619SAlexey Moksyakov   while (Buf < End && ((*Buf) >= '0' && (*Buf) <= '9')) {
2661fb18619SAlexey Moksyakov     Result = Result * 10 + (*Buf) - '0';
2671fb18619SAlexey Moksyakov     ++Buf;
2681fb18619SAlexey Moksyakov   }
2691fb18619SAlexey Moksyakov   if (OldBuf != Buf && Result <= 0xFFFFFFFFu) {
2701fb18619SAlexey Moksyakov     Ret = static_cast<uint32_t>(Result);
2711fb18619SAlexey Moksyakov     return true;
2721fb18619SAlexey Moksyakov   }
2731fb18619SAlexey Moksyakov   return false;
2741fb18619SAlexey Moksyakov }
2751fb18619SAlexey Moksyakov 
reportError(const char * Msg,uint64_t Size)2769bd71615SXun Li void reportError(const char *Msg, uint64_t Size) {
2779bd71615SXun Li   __write(2, Msg, Size);
2789bd71615SXun Li   __exit(1);
2799bd71615SXun Li }
2809bd71615SXun Li 
assert(bool Assertion,const char * Msg)2819bd71615SXun Li void assert(bool Assertion, const char *Msg) {
2829bd71615SXun Li   if (Assertion)
2839bd71615SXun Li     return;
2849bd71615SXun Li   char Buf[BufSize];
2859bd71615SXun Li   char *Ptr = Buf;
2869bd71615SXun Li   Ptr = strCopy(Ptr, "Assertion failed: ");
2879bd71615SXun Li   Ptr = strCopy(Ptr, Msg, BufSize - 40);
2889bd71615SXun Li   Ptr = strCopy(Ptr, "\n");
2899bd71615SXun Li   reportError(Buf, Ptr - Buf);
2909bd71615SXun Li }
2919bd71615SXun Li 
292*87e9c424SElvina Yakubova #define SIG_BLOCK 0
293*87e9c424SElvina Yakubova #define SIG_UNBLOCK 1
294*87e9c424SElvina Yakubova #define SIG_SETMASK 2
295*87e9c424SElvina Yakubova 
296*87e9c424SElvina Yakubova static const uint64_t MaskAllSignals[] = {-1ULL};
297*87e9c424SElvina Yakubova 
2989bd71615SXun Li class Mutex {
2999bd71615SXun Li   volatile bool InUse{false};
3009bd71615SXun Li 
3019bd71615SXun Li public:
acquire()30235155a07SElvina Yakubova   bool acquire() { return !__atomic_test_and_set(&InUse, __ATOMIC_ACQUIRE); }
release()30335155a07SElvina Yakubova   void release() { __atomic_clear(&InUse, __ATOMIC_RELEASE); }
3049bd71615SXun Li };
3059bd71615SXun Li 
3069bd71615SXun Li /// RAII wrapper for Mutex
3079bd71615SXun Li class Lock {
3089bd71615SXun Li   Mutex &M;
3092cf9008aSVladislav Khmelevsky   uint64_t SignalMask[1] = {};
3109bd71615SXun Li 
3119bd71615SXun Li public:
Lock(Mutex & M)3129bd71615SXun Li   Lock(Mutex &M) : M(M) {
3132cf9008aSVladislav Khmelevsky     __sigprocmask(SIG_BLOCK, MaskAllSignals, SignalMask);
3149bd71615SXun Li     while (!M.acquire()) {
3159bd71615SXun Li     }
3169bd71615SXun Li   }
3172cf9008aSVladislav Khmelevsky 
~Lock()3182cf9008aSVladislav Khmelevsky   ~Lock() {
3192cf9008aSVladislav Khmelevsky     M.release();
3202cf9008aSVladislav Khmelevsky     __sigprocmask(SIG_SETMASK, SignalMask, nullptr);
3212cf9008aSVladislav Khmelevsky   }
3229bd71615SXun Li };
3239bd71615SXun Li 
3249aa134dcSVasily Leonenko /// RAII wrapper for Mutex
3259aa134dcSVasily Leonenko class TryLock {
3269aa134dcSVasily Leonenko   Mutex &M;
3279aa134dcSVasily Leonenko   bool Locked = false;
3289aa134dcSVasily Leonenko 
3299aa134dcSVasily Leonenko public:
TryLock(Mutex & M)3309aa134dcSVasily Leonenko   TryLock(Mutex &M) : M(M) {
3319aa134dcSVasily Leonenko     int Retry = 100;
3329aa134dcSVasily Leonenko     while (--Retry && !M.acquire())
3339aa134dcSVasily Leonenko       ;
3349aa134dcSVasily Leonenko     if (Retry)
3359aa134dcSVasily Leonenko       Locked = true;
3369aa134dcSVasily Leonenko   }
isLocked()3379aa134dcSVasily Leonenko   bool isLocked() { return Locked; }
3389aa134dcSVasily Leonenko 
~TryLock()3399aa134dcSVasily Leonenko   ~TryLock() {
3409aa134dcSVasily Leonenko     if (isLocked())
3419aa134dcSVasily Leonenko       M.release();
3429aa134dcSVasily Leonenko   }
3439aa134dcSVasily Leonenko };
3449aa134dcSVasily Leonenko 
alignTo(uint64_t Value,uint64_t Align)3459bd71615SXun Li inline uint64_t alignTo(uint64_t Value, uint64_t Align) {
3469bd71615SXun Li   return (Value + Align - 1) / Align * Align;
3479bd71615SXun Li }
348bbd9d610SAlexander Shaposhnikov 
3491cf23e5eSAlexander Shaposhnikov } // anonymous namespace
350