[libc-commits] [libc] 78f172e - [libc] Implement gettimeofday

Raman Tenneti via libc-commits libc-commits at lists.llvm.org
Fri Nov 11 18:11:39 PST 2022


Author: Raman Tenneti
Date: 2022-11-11T18:02:33-08:00
New Revision: 78f172e45ad95bb9cac907486af968a9e41d9570

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

LOG: [libc] Implement gettimeofday

Implement gettimeofday per
.../onlinepubs/9699919799/functions/gettimeofday.html.
This call clock_gettime to implement gettimeofday function.

Tested:
Limited unit test: This makes a call and checks that no error was
returned. Used nanosleep for 100 microseconds and verfified it
returns a value that elapses more than 100 microseconds and less
than 300 microseconds.

Co-authored-by: Jeff Bailey <jeffbailey at google.com>

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

Added: 
    libc/src/time/gettimeofday.cpp
    libc/src/time/gettimeofday.h
    libc/test/src/time/gettimeofday_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/date_and_time.rst
    libc/include/CMakeLists.txt
    libc/spec/posix.td
    libc/src/time/CMakeLists.txt
    libc/test/src/time/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 4accc1443b49d..8db3b795a83b6 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -425,6 +425,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.clock_gettime
     libc.src.time.clock
     libc.src.time.
diff time
+    libc.src.time.gettimeofday
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime

diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index a84ab387bb8fe..f4d32a22510c6 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -173,7 +173,14 @@ def StdlibAPI : PublicAPI<"stdlib.h"> {
 }
 
 def TimeAPI : PublicAPI<"time.h"> {
-  let Types = ["clock_t", "time_t", "struct tm", "struct timespec", "clockid_t",];
+  let Types = [
+    "clock_t",
+    "time_t",
+    "struct tm",
+    "struct timespec",
+    "struct timeval",
+    "clockid_t",
+  ];
 }
 
 def ErrnoAPI : PublicAPI<"errno.h"> {
@@ -287,7 +294,8 @@ def SysResourceAPI : PublicAPI<"sys/resource.h"> {
 
 def SysStatAPI : PublicAPI<"sys/stat.h"> {
   let Types = ["mode_t", "dev_t", "ino_t", "nlink_t", "uid_t", "gid_t", "off_t",
-               "struct timespec", "blksize_t", "blkcnt_t", "struct stat"];
+               "struct timespec", "struct timeval", "blksize_t", "blkcnt_t",
+	       "struct stat"];
 }
 
 def SysWaitAPI : PublicAPI<"sys/wait.h"> {

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 2544ff2a5e40a..5b34636dc5fbf 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -459,6 +459,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.clock_gettime
     libc.src.time.clock
     libc.src.time.
diff time
+    libc.src.time.gettimeofday
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime

diff  --git a/libc/docs/date_and_time.rst b/libc/docs/date_and_time.rst
index cadeabcb49478..c91bffb32bb3d 100644
--- a/libc/docs/date_and_time.rst
+++ b/libc/docs/date_and_time.rst
@@ -42,6 +42,7 @@ ctime
 ctime_r
 
diff time              |check|
 getdate
+gettimeofday          |check|
 gmtime                |check|
 gmtime_r              |check|
 localtime

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index f9d3ee5164f95..f32c8e30902fb 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -106,6 +106,7 @@ add_gen_header(
     .llvm-libc-types.clockid_t
     .llvm-libc-types.struct_tm
     .llvm-libc-types.struct_timespec
+    .llvm-libc-types.struct_timeval
 )
 
 add_gen_header(

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 0333c6e47c4d3..eaf4f3a5b4fd2 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -45,6 +45,9 @@ def ConstStructDirentPtrPtr : ConstType<StructDirentPtrPtr>;
 def StructTimeSpec : NamedType<"struct timespec">;
 def StructTimeSpecPtr : PtrType<StructTimeSpec>;
 
+def StructTimeVal : NamedType<"struct timeval">;
+def StructTimeValPtr : PtrType<StructTimeVal>;
+
 def ExecArgvT : NamedType<"__exec_argv_t">;
 def ExecEnvpT : NamedType<"__exec_envp_t">;
 
@@ -723,7 +726,20 @@ def POSIX : StandardSpec<"POSIX"> {
   HeaderSpec SysStat = HeaderSpec<
     "sys/stat.h",
     [], // Macros
-    [ModeTType, DevT, InoT, UidT, GidT, StructTimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
+    [
+        ModeTType,
+	DevT,
+	InoT,
+	UidT,
+	GidT,
+	StructTimeSpec,
+	StructTimeVal,
+	BlkSizeT,
+	BlkCntT,
+	OffTType,
+	NLinkT,
+	StatType,
+    ], // Types
     [], // Enumerations
     [
         FunctionSpec<
@@ -1061,21 +1077,26 @@ def POSIX : StandardSpec<"POSIX"> {
   HeaderSpec Time = HeaderSpec<
       "time.h",
       [], // Macros
-      [ClockIdT, StructTimeSpec], // Types
+      [ClockIdT, StructTimeSpec, StructTimeVal], // Types
       [], // Enumerations
       [
           FunctionSpec<
-              "nanosleep",
+              "clock_gettime",
               RetValSpec<IntType>,
-              [
-	      	      ArgSpec<StructTimeSpecPtr>,
-	      	      ArgSpec<StructTimeSpecPtr>,
-	            ]
+              [ArgSpec<ClockIdT>, ArgSpec<StructTimeSpecPtr>]
           >,
           FunctionSpec<
-              "clock_gettime",
+              "gettimeofday",
+              RetValSpec<IntType>,
+              [ArgSpec<StructTimeValPtr>, ArgSpec<VoidPtr>]
+          >,
+          FunctionSpec<
+              "nanosleep",
               RetValSpec<IntType>,
-              [ArgSpec<ClockIdT>,ArgSpec<StructTimeSpecPtr>]
+              [
+	      	   ArgSpec<StructTimeSpecPtr>,
+	      	   ArgSpec<StructTimeSpecPtr>,
+	      ]
           >,
       ]
   >;

diff  --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 8a8a30bf34d6b..8f953e4c9b132 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -59,6 +59,21 @@ add_entrypoint_object(
     libc.include.time
 )
 
+add_entrypoint_object(
+  gettimeofday
+  SRCS
+    gettimeofday.cpp
+  HDRS
+    gettimeofday.h
+  DEPENDS
+    .clock_gettime
+    libc.include.errno
+    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/gettimeofday.cpp b/libc/src/time/gettimeofday.cpp
new file mode 100644
index 0000000000000..911e587caf99b
--- /dev/null
+++ b/libc/src/time/gettimeofday.cpp
@@ -0,0 +1,34 @@
+//===-- Implementation of gettimeofday 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/gettimeofday.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/time/clock_gettime.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, gettimeofday,
+                   (struct timeval * tv, [[maybe_unused]] void *unused)) {
+  if (tv == nullptr)
+    return 0;
+  clockid_t clockid = CLOCK_REALTIME;
+  struct timespec tp;
+  long ret_val = __llvm_libc::clock_gettime(clockid, &tp);
+  if (ret_val < 0)
+    return -1;
+  tv->tv_sec = tp.tv_sec;
+  tv->tv_usec = tp.tv_nsec / 1000;
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/time/gettimeofday.h b/libc/src/time/gettimeofday.h
new file mode 100644
index 0000000000000..42182ee28e2a9
--- /dev/null
+++ b/libc/src/time/gettimeofday.h
@@ -0,0 +1,22 @@
+//===-- Implementation header of gettimeofday -------------------*- 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_GETTIMEOFDAY_H
+#define LLVM_LIBC_SRC_TIME_GETTIMEOFDAY_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+int gettimeofday(struct timeval *tv, void *tz);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_GETTIMEOFDAY_H
+
+#include "include/time.h"

diff  --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 5903333c665fb..d059f5640dd65 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -50,6 +50,24 @@ add_libc_unittest(
     libc.src.time.
diff time
 )
 
+add_libc_unittest(
+  gettimeofday
+  SUITE
+    libc_time_unittests
+  SRCS
+    gettimeofday_test.cpp
+  HDRS
+    TmHelper.h
+    TmMatcher.h
+  CXX_STANDARD
+    20
+  DEPENDS
+    libc.include.errno
+    libc.include.time
+    libc.src.time.gettimeofday
+    libc.src.time.nanosleep
+)
+
 add_libc_unittest(
   gmtime
   SUITE

diff  --git a/libc/test/src/time/gettimeofday_test.cpp b/libc/test/src/time/gettimeofday_test.cpp
new file mode 100644
index 0000000000000..2cd8d51670635
--- /dev/null
+++ b/libc/test/src/time/gettimeofday_test.cpp
@@ -0,0 +1,38 @@
+//===-- Unittests for gettimeofday ----------------------------------------===//
+//
+// 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 <errno.h>
+#include <time.h>
+
+#include "src/time/gettimeofday.h"
+#include "src/time/nanosleep.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+namespace cpp = __llvm_libc::cpp;
+
+TEST(LlvmLibcGettimeofday, SmokeTest) {
+  using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+  void *tz = nullptr;
+  struct timeval tv;
+  int ret = __llvm_libc::gettimeofday(&tv, tz);
+  ASSERT_EQ(ret, 0);
+
+  // Sleep for 200 microsceconds.
+  struct timespec tim = {0, 200 * 1000};
+  struct timespec tim2 = {0, 0};
+  ret = __llvm_libc::nanosleep(&tim, &tim2);
+
+  // Call gettimeofday again and verify that it is more 100 microscecods and
+  // less than 300 microseconds,
+  struct timeval tv1;
+  ret = __llvm_libc::gettimeofday(&tv1, tz);
+  ASSERT_EQ(ret, 0);
+  ASSERT_GT(tv1.tv_usec - tv.tv_usec, 100);
+  ASSERT_LT(tv1.tv_usec - tv.tv_usec, 300);
+}


        


More information about the libc-commits mailing list