xref: /llvm-project/libcxx/src/filesystem/filesystem_clock.cpp (revision edf9439e00971b55bae19e40ef6a8e132645a56a)
1c7d3c844SLouis Dionne //===----------------------------------------------------------------------===//
2c7d3c844SLouis Dionne //
3c7d3c844SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c7d3c844SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5c7d3c844SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c7d3c844SLouis Dionne //
7c7d3c844SLouis Dionne //===----------------------------------------------------------------------===//
8c7d3c844SLouis Dionne 
9c7d3c844SLouis Dionne #include <__config>
10dedc5159SNikolas Klauser #include <__system_error/throw_system_error.h>
11c7d3c844SLouis Dionne #include <chrono>
12c7d3c844SLouis Dionne #include <filesystem>
13c7d3c844SLouis Dionne #include <time.h>
14c7d3c844SLouis Dionne 
15dab5f56eSLouis Dionne #if defined(_LIBCPP_WIN32API)
16ba3619b9SLouis Dionne #  include "time_utils.h"
17dab5f56eSLouis Dionne #endif
18c7d3c844SLouis Dionne 
19c7d3c844SLouis Dionne #if defined(_LIBCPP_WIN32API)
20c7d3c844SLouis Dionne #  define WIN32_LEAN_AND_MEAN
21c7d3c844SLouis Dionne #  define NOMINMAX
22c7d3c844SLouis Dionne #  include <windows.h>
23c7d3c844SLouis Dionne #endif
24c7d3c844SLouis Dionne 
255f1ba3a5SLouis Dionne #if __has_include(<unistd.h>)
265f1ba3a5SLouis Dionne #  include <unistd.h> // _POSIX_TIMERS
275f1ba3a5SLouis Dionne #endif
285f1ba3a5SLouis Dionne 
295f1ba3a5SLouis Dionne #if __has_include(<sys/time.h>)
30c7d3c844SLouis Dionne #  include <sys/time.h> // for gettimeofday and timeval
31c7d3c844SLouis Dionne #endif
32c7d3c844SLouis Dionne 
33*edf9439eSPetr Hosek #if defined(__LLVM_LIBC__)
34*edf9439eSPetr Hosek #  define _LIBCPP_HAS_TIMESPEC_GET
35*edf9439eSPetr Hosek #endif
36*edf9439eSPetr Hosek 
370eb1fc88SJoseph Huber #if defined(__APPLE__) || defined(__gnu_hurd__) || defined(__AMDGPU__) || defined(__NVPTX__) ||                        \
380eb1fc88SJoseph Huber     (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
397e6f2b74SLouis Dionne #  define _LIBCPP_HAS_CLOCK_GETTIME
405f1ba3a5SLouis Dionne #endif
415f1ba3a5SLouis Dionne 
42c7d3c844SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
43c7d3c844SLouis Dionne 
44b69ddbc6SNikolas Klauser _LIBCPP_DIAGNOSTIC_PUSH
45b69ddbc6SNikolas Klauser _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated")
46c7d3c844SLouis Dionne const bool _FilesystemClock::is_steady;
47b69ddbc6SNikolas Klauser _LIBCPP_DIAGNOSTIC_POP
48c7d3c844SLouis Dionne 
49c7d3c844SLouis Dionne _FilesystemClock::time_point _FilesystemClock::now() noexcept {
50c7d3c844SLouis Dionne   typedef chrono::duration<rep> __secs;
51c7d3c844SLouis Dionne #if defined(_LIBCPP_WIN32API)
52c7d3c844SLouis Dionne   typedef chrono::duration<rep, nano> __nsecs;
53c7d3c844SLouis Dionne   FILETIME time;
54c7d3c844SLouis Dionne   GetSystemTimeAsFileTime(&time);
55c7d3c844SLouis Dionne   detail::TimeSpec tp = detail::filetime_to_timespec(time);
569783f28cSLouis Dionne   return time_point(__secs(tp.tv_sec) + chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
57*edf9439eSPetr Hosek #elif defined(_LIBCPP_HAS_TIMESPEC_GET)
58*edf9439eSPetr Hosek   typedef chrono::duration<rep, nano> __nsecs;
59*edf9439eSPetr Hosek   struct timespec ts;
60*edf9439eSPetr Hosek   if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
61*edf9439eSPetr Hosek     __throw_system_error(errno, "timespec_get(TIME_UTC) failed");
62*edf9439eSPetr Hosek   return time_point(__secs(ts.tv_sec) + chrono::duration_cast<duration>(__nsecs(ts.tv_nsec)));
637e6f2b74SLouis Dionne #elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
64c7d3c844SLouis Dionne   typedef chrono::duration<rep, nano> __nsecs;
65c7d3c844SLouis Dionne   struct timespec tp;
66c7d3c844SLouis Dionne   if (0 != clock_gettime(CLOCK_REALTIME, &tp))
67c7d3c844SLouis Dionne     __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
689783f28cSLouis Dionne   return time_point(__secs(tp.tv_sec) + chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
69c7d3c844SLouis Dionne #else
70c7d3c844SLouis Dionne   typedef chrono::duration<rep, micro> __microsecs;
71c7d3c844SLouis Dionne   timeval tv;
72c7d3c844SLouis Dionne   gettimeofday(&tv, 0);
73c7d3c844SLouis Dionne   return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
747e6f2b74SLouis Dionne #endif
75c7d3c844SLouis Dionne }
76c7d3c844SLouis Dionne 
77c7d3c844SLouis Dionne _LIBCPP_END_NAMESPACE_FILESYSTEM
78