14 #if defined(__SYCL_RT_OS_LINUX)
26 #include <linux/limits.h>
28 #include <sys/sysinfo.h>
30 #elif defined(__SYCL_RT_OS_WINDOWS)
37 #elif defined(__SYCL_RT_OS_DARWIN)
40 #include <sys/sysctl.h>
41 #include <sys/types.h>
43 #endif // __SYCL_RT_OS
49 #if defined(__SYCL_RT_OS_LINUX)
60 static int callback(
struct dl_phdr_info *Info,
size_t,
void *Data) {
61 auto Base =
reinterpret_cast<unsigned char *
>(Info->dlpi_addr);
62 auto MI =
reinterpret_cast<ModuleInfo *
>(Data);
63 auto TestAddr =
reinterpret_cast<const unsigned char *
>(MI->VirtAddr);
65 for (
int i = 0; i < Info->dlpi_phnum; ++i) {
66 unsigned char *SegStart = Base + Info->dlpi_phdr[i].p_vaddr;
67 unsigned char *SegEnd = SegStart + Info->dlpi_phdr[i].p_memsz;
70 if (TestAddr >= SegStart && TestAddr < SegEnd) {
73 auto H =
reinterpret_cast<void *
>(Info->dlpi_addr);
74 MI->Handle = H ? H :
reinterpret_cast<void *
>(OSUtil::ExeModuleHandle);
75 MI->Name = Info->dlpi_name;
83 ModuleInfo Res = {VirtAddr,
nullptr,
nullptr};
84 dl_iterate_phdr(callback, &Res);
89 bool procMapsAddressInRange(std::istream &Stream, uintptr_t Addr) {
90 uintptr_t Start = 0, End = 0;
92 assert(!Stream.fail() && Stream.peek() ==
'-' &&
93 "Couldn't read /proc/self/maps correctly");
97 assert(!Stream.fail() && Stream.peek() ==
' ' &&
98 "Couldn't read /proc/self/maps correctly");
101 return Addr >= Start && Addr < End;
105 std::string OSUtil::getCurrentDSODir() {
126 uintptr_t CurrentFunc = (uintptr_t)&getCurrentDSODir;
127 std::ifstream Stream(
"/proc/self/maps");
129 while (!Stream.eof()) {
130 if (!procMapsAddressInRange(Stream, CurrentFunc)) {
137 Stream.readsome(Perm,
sizeof(Perm));
138 assert(Perm[0] ==
'r' && Perm[2] ==
'x' &&
139 "Invalid flags in /proc/self/maps");
140 assert(Stream.peek() ==
' ');
159 while (Stream.peek() ==
' ') {
163 Stream.getline(Path, PATH_MAX - 1);
164 Path[PATH_MAX - 1] =
'\0';
167 assert(
false &&
"Unable to find the current function in /proc/self/maps");
172 std::string Tmp(Path);
175 size_t TruncatedSize = strlen(dirname(
const_cast<char *
>(Tmp.c_str())));
176 Tmp.resize(TruncatedSize);
180 #elif defined(__SYCL_RT_OS_WINDOWS)
183 DWORD Flag = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
184 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
185 auto LpModuleAddr =
reinterpret_cast<LPCSTR
>(VirtAddr);
186 if (!GetModuleHandleExA(Flag, LpModuleAddr, &PhModule)) {
191 if (PhModule == GetModuleHandleA(
nullptr))
192 return OSUtil::ExeModuleHandle;
199 std::string OSUtil::getCurrentDSODir() {
202 Path[
sizeof(Path) - 1] =
'\0';
203 auto Handle = getOSModuleHandle(
reinterpret_cast<void *
>(&getCurrentDSODir));
204 DWORD Ret = GetModuleFileNameA(
205 reinterpret_cast<HMODULE
>(OSUtil::ExeModuleHandle == Handle ? 0 : Handle),
206 reinterpret_cast<LPSTR
>(&Path),
sizeof(Path));
207 assert(Ret <
sizeof(Path) &&
"Path is longer than PATH_MAX?");
208 assert(Ret > 0 &&
"GetModuleFileNameA failed");
211 BOOL RetCode = PathRemoveFileSpecA(
reinterpret_cast<LPSTR
>(&Path));
212 assert(RetCode &&
"PathRemoveFileSpecA failed");
219 std::string Tmp(Path);
221 Tmp.erase(Tmp.find_last_not_of(
"/\\") + 1, std::string::npos);
223 size_t pos = Tmp.find_last_of(
"/\\");
224 if (pos != std::string::npos)
225 return Tmp.substr(0, pos);
231 #elif defined(__SYCL_RT_OS_DARWIN)
234 dladdr(VirtAddr, &Res);
238 std::string OSUtil::getCurrentDSODir() {
239 auto CurrentFunc =
reinterpret_cast<const void *
>(&getCurrentDSODir);
241 int RetCode = dladdr(CurrentFunc, &Info);
247 auto Path = std::string(Info.dli_fname);
248 auto LastSlashPos = Path.find_last_of(
'/');
250 return Path.substr(0, LastSlashPos);
253 #endif // __SYCL_RT_OS
255 size_t OSUtil::getOSMemSize() {
256 #if defined(__SYCL_RT_OS_LINUX)
257 struct sysinfo MemInfo;
259 return static_cast<size_t>(MemInfo.totalram * MemInfo.mem_unit);
260 #elif defined(__SYCL_RT_OS_WINDOWS)
261 MEMORYSTATUSEX MemInfo;
262 MemInfo.dwLength =
sizeof(MemInfo);
263 GlobalMemoryStatusEx(&MemInfo);
264 return static_cast<size_t>(MemInfo.ullTotalPhys);
265 #elif defined(__SYCL_RT_OS_DARWIN)
267 sysctlbyname(
"hw.memsize", &Size,
nullptr,
nullptr, 0);
268 return static_cast<size_t>(Size);
269 #endif // __SYCL_RT_OS
273 #if defined(__SYCL_RT_OS_LINUX) && (defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) || \
274 defined(_LIBCPP_HAS_C11_FEATURES))
276 #elif defined(__SYCL_RT_OS_POSIX_SUPPORT)
277 void *Addr =
nullptr;
278 int ReturnCode = posix_memalign(&Addr,
Alignment, NumBytes);
279 return (ReturnCode == 0) ? Addr :
nullptr;
280 #elif defined(__SYCL_RT_OS_WINDOWS)
281 return _aligned_malloc(NumBytes,
Alignment);
285 void OSUtil::alignedFree(
void *Ptr) {
286 #if defined(__SYCL_RT_OS_LINUX) || defined(__SYCL_RT_OS_POSIX_SUPPORT)
288 #elif defined(__SYCL_RT_OS_WINDOWS)
297 int OSUtil::makeDir(
const char *Dir) {
298 assert((Dir !=
nullptr) &&
"Passed null-pointer as directory name.");
299 if (isPathPresent(Dir))
302 std::string Path{Dir}, CurPath;
306 pos = Path.find_first_of(
"/\\", ++pos);
307 CurPath = Path.substr(0, pos);
308 #if defined(__SYCL_RT_OS_POSIX_SUPPORT)
309 auto Res = mkdir(CurPath.c_str(), 0777);
311 auto Res = _mkdir(CurPath.c_str());
313 if (Res && errno != EEXIST)
315 }
while (pos != std::string::npos);