[libc-commits] [libc] b49d626 - [libc] add clock_gettime

Michael Jones via libc-commits libc-commits at lists.llvm.org
Thu Sep 29 10:23:30 PDT 2022


Author: Michael Jones
Date: 2022-09-29T10:23:21-07:00
New Revision: b49d626cb4b43fcd96cb5c0d6a36c3f16213022c

URL: https://github.com/llvm/llvm-project/commit/b49d626cb4b43fcd96cb5c0d6a36c3f16213022c
DIFF: https://github.com/llvm/llvm-project/commit/b49d626cb4b43fcd96cb5c0d6a36c3f16213022c.diff

LOG: [libc] add clock_gettime

Add the clock_gettime syscall wrapper and tests.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D134773

Added: 
    libc/include/llvm-libc-macros/linux/time-macros.h
    libc/include/llvm-libc-macros/time-macros.h
    libc/include/llvm-libc-types/clockid_t.h
    libc/src/time/clock_gettime.cpp
    libc/src/time/clock_gettime.h
    libc/test/src/time/clock_gettime_test.cpp

Modified: 
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-macros/CMakeLists.txt
    libc/include/llvm-libc-macros/linux/CMakeLists.txt
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/include/time.h.def
    libc/spec/posix.td
    libc/src/time/CMakeLists.txt
    libc/test/src/time/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 50baea0157c53..28c86241d0a2b 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -171,7 +171,7 @@ def StdlibAPI : PublicAPI<"stdlib.h"> {
 }
 
 def TimeAPI : PublicAPI<"time.h"> {
-  let Types = ["time_t", "struct tm", "struct timespec"];
+  let Types = ["time_t", "struct tm", "struct timespec", "clockid_t",];
 }
 
 def ErrnoAPI : PublicAPI<"errno.h"> {

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index b7d122b60d6f4..529779ee26491 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -395,6 +395,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.gmtime_r
     libc.src.time.mktime
     libc.src.time.nanosleep
+    libc.src.time.clock_gettime
   )
 endif()
 

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index e8db6b72df706..544dccc52d7d5 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -91,7 +91,9 @@ add_gen_header(
   GEN_HDR time.h
   DEPENDS
     .llvm_libc_common_h
+    .llvm-libc-macros.time_macros
     .llvm-libc-types.time_t
+    .llvm-libc-types.clockid_t
     .llvm-libc-types.struct_tm
     .llvm-libc-types.struct_timespec
 )

diff  --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 380cb288ed971..f7490e813ea86 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -38,6 +38,14 @@ add_header(
     .linux.sys_resource_macros
 )
 
+add_header(
+  time_macros
+  HDR
+    time-macros.h
+  DEPENDS
+    .linux.time_macros
+)
+
 add_header(
   unistd_macros
   HDR

diff  --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index aac9e9768d924..2018d041987f7 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -16,6 +16,12 @@ add_header(
     sys-stat-macros.h
 )
 
+add_header(
+  time_macros
+  HDR
+    time-macros.h
+)
+
 add_header(
   sys_resource_macros
   HDR

diff  --git a/libc/include/llvm-libc-macros/linux/time-macros.h b/libc/include/llvm-libc-macros/linux/time-macros.h
new file mode 100644
index 0000000000000..c2dea4d5796af
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/time-macros.h
@@ -0,0 +1,24 @@
+//===-- Definition of macros from time.h ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+#define __LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+
+// clock type macros
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+#define CLOCK_MONOTONIC_RAW 4
+#define CLOCK_REALTIME_COARSE 5
+#define CLOCK_MONOTONIC_COARSE 6
+#define CLOCK_BOOTTIME 7
+#define CLOCK_REALTIME_ALARM 8
+#define CLOCK_BOOTTIME_ALARM 9
+
+#endif //__LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H

diff  --git a/libc/include/llvm-libc-macros/time-macros.h b/libc/include/llvm-libc-macros/time-macros.h
new file mode 100644
index 0000000000000..9d5fad5ea86e1
--- /dev/null
+++ b/libc/include/llvm-libc-macros/time-macros.h
@@ -0,0 +1,8 @@
+#ifndef __LLVM_LIBC_MACROS_TIME_MACROS_H
+#define __LLVM_LIBC_MACROS_TIME_MACROS_H
+
+#ifdef __unix__
+#include "linux/time-macros.h"
+#endif
+
+#endif // __LLVM_LIBC_MACROS_TIME_MACROS_H

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 5f0a5796042ce..78f54380e38f3 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -12,6 +12,7 @@ add_header(__sighandler_t HDR __sighandler_t.h)
 add_header(__thread_type HDR __thread_type.h)
 add_header(blkcnt_t HDR blkcnt_t.h)
 add_header(blksize_t HDR blksize_t.h)
+add_header(clockid_t HDR clockid_t.h)
 add_header(cnd_t HDR cnd_t.h)
 add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t)
 add_header(double_t HDR double_t.h)

diff  --git a/libc/include/llvm-libc-types/clockid_t.h b/libc/include/llvm-libc-types/clockid_t.h
new file mode 100644
index 0000000000000..ddaceb664ec12
--- /dev/null
+++ b/libc/include/llvm-libc-types/clockid_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of the type clockid_t ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_TYPES_CLOCKID_T_H__
+#define __LLVM_LIBC_TYPES_CLOCKID_T_H__
+
+typedef int clockid_t;
+
+#endif // __LLVM_LIBC_TYPES_CLOCKID_T_H__

diff  --git a/libc/include/time.h.def b/libc/include/time.h.def
index 0c90f9b76c2eb..d8988329a372b 100644
--- a/libc/include/time.h.def
+++ b/libc/include/time.h.def
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_TIME_H
 
 #include <__llvm-libc-common.h>
+#include <llvm-libc-macros/time-macros.h>
 
 %%public_api()
 

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 131adf96da930..f691001b3ce94 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -22,10 +22,10 @@ def InoT : NamedType<"ino_t">;
 def UidT : NamedType<"uid_t">;
 def GidT : NamedType<"gid_t">;
 def DevT : NamedType<"dev_t">;
+def ClockIdT : NamedType<"clockid_t">;
 def BlkSizeT : NamedType<"blksize_t">;
 def BlkCntT : NamedType<"blkcnt_t">;
 def NLinkT : NamedType<"nlink_t">;
-def TimeSpec : NamedType<"struct timespec">;
 def PidT : NamedType<"pid_t">;
 
 def StatType : NamedType<"struct stat">;
@@ -608,7 +608,7 @@ def POSIX : StandardSpec<"POSIX"> {
   HeaderSpec SysStat = HeaderSpec<
     "sys/stat.h",
     [], // Macros
-    [ModeTType, DevT, InoT, UidT, GidT, TimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
+    [ModeTType, DevT, InoT, UidT, GidT, StructTimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
     [], // Enumerations
     [
         FunctionSpec<
@@ -935,7 +935,7 @@ def POSIX : StandardSpec<"POSIX"> {
   HeaderSpec Time = HeaderSpec<
       "time.h",
       [], // Macros
-      [StructTimeSpec], // Types
+      [ClockIdT, StructTimeSpec], // Types
       [], // Enumerations
       [
           FunctionSpec<
@@ -946,6 +946,11 @@ def POSIX : StandardSpec<"POSIX"> {
 	      	      ArgSpec<StructTimeSpecPtr>,
 	            ]
           >,
+          FunctionSpec<
+              "clock_gettime",
+              RetValSpec<IntType>,
+              [ArgSpec<ClockIdT>,ArgSpec<StructTimeSpecPtr>]
+          >,
       ]
   >;
 

diff  --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 880e7ed956acb..660b79678b524 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -32,6 +32,19 @@ add_entrypoint_object(
     libc.include.time
 )
 
+add_entrypoint_object(
+  clock_gettime
+  SRCS
+    clock_gettime.cpp
+  HDRS
+    clock_gettime.h
+  DEPENDS
+    libc.include.time
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   gmtime
   SRCS

diff  --git a/libc/src/time/clock_gettime.cpp b/libc/src/time/clock_gettime.cpp
new file mode 100644
index 0000000000000..420dc367e571e
--- /dev/null
+++ b/libc/src/time/clock_gettime.cpp
@@ -0,0 +1,36 @@
+//===---------- Linux implementation of the POSIX clock_gettime function
+//--------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock_gettime.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+#include <time.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, clock_gettime,
+                   (clockid_t clockid, struct timespec *tp)) {
+  long ret_val =
+      __llvm_libc::syscall(SYS_clock_gettime, static_cast<long>(clockid),
+                           reinterpret_cast<long>(tp));
+  // A negative return value indicates an error with the magnitude of the
+  // value being the error code.
+  if (ret_val < 0) {
+    errno = -ret_val;
+    return -1;
+  }
+
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/time/clock_gettime.h b/libc/src/time/clock_gettime.h
new file mode 100644
index 0000000000000..a131251bac973
--- /dev/null
+++ b/libc/src/time/clock_gettime.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for clock_gettime function --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_TIME_CLOCK_GETTIME_H
+#define LLVM_LIBC_SRC_TIME_CLOCK_GETTIME_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+int clock_gettime(clockid_t clockid, struct timespec *tp);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_CLOCK_GETTIME_H

diff  --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 0fe964ca4333b..91c9cdc38e057 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -30,6 +30,16 @@ add_libc_unittest(
     libc.src.time.asctime_r
 )
 
+add_libc_unittest(
+  clock_gettime
+  SUITE
+    libc_time_unittests
+  SRCS
+  clock_gettime_test.cpp
+  DEPENDS
+    libc.src.time.clock_gettime
+)
+
 add_libc_unittest(
   gmtime
   SUITE

diff  --git a/libc/test/src/time/clock_gettime_test.cpp b/libc/test/src/time/clock_gettime_test.cpp
new file mode 100644
index 0000000000000..3214ca19c72ae
--- /dev/null
+++ b/libc/test/src/time/clock_gettime_test.cpp
@@ -0,0 +1,36 @@
+//===-- Unittests for clock_gettime ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock_gettime.h"
+#include "utils/UnitTest/Test.h"
+
+#include <time.h>
+
+TEST(LlvmLibcClockGetTime, RealTime) {
+  struct timespec tp;
+  int result;
+  result = clock_gettime(CLOCK_REALTIME, &tp);
+  ASSERT_EQ(result, 0);
+  ASSERT_GT(tp.tv_sec, time_t(0));
+}
+
+#ifdef CLOCK_MONOTONIC
+TEST(LlvmLibcClockGetTime, MonotonicTime) {
+  struct timespec tp1, tp2;
+  int result;
+  result = clock_gettime(CLOCK_MONOTONIC, &tp1);
+  ASSERT_EQ(result, 0);
+  ASSERT_GT(tp1.tv_sec, time_t(0));
+  result = clock_gettime(CLOCK_MONOTONIC, &tp2);
+  ASSERT_EQ(result, 0);
+  ASSERT_GE(tp2.tv_sec, tp1.tv_sec); // The monotonic clock should increase.
+  if (tp2.tv_sec == tp1.tv_sec) {
+    ASSERT_GE(tp2.tv_nsec, tp1.tv_nsec);
+  }
+}
+#endif // CLOCK_MONOTONIC


        


More information about the libc-commits mailing list