[libc-commits] [libc] 8f1e362 - Implement nanosleep per https://pubs.opengroup.org/onlinepubs/009695399/basedefs/time.h.html

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Fri Sep 23 17:14:05 PDT 2022


Author: Raman Tenneti
Date: 2022-09-24T00:13:58Z
New Revision: 8f1e362ee9275a687693448bd975194ee9b984f2

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

LOG: Implement nanosleep per https://pubs.opengroup.org/onlinepubs/009695399/basedefs/time.h.html

Tested:
Limited unit test: This makes a call and checks that no error was
returned, but we currently don't have the ability to ensure that
time has elapsed as expected.

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

Reviewed By: sivachandra, jeffbailey

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

Added: 
    libc/src/time/nanosleep.cpp
    libc/src/time/nanosleep.h
    libc/test/src/time/nanosleep_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-types/struct_timespec.h
    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 b506663a04b60..e05012391beaa 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -353,6 +353,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.nanosleep
   )
 endif()
 

diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 508ef3721a64e..03559879b353d 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"];
+  let Types = ["time_t", "struct tm", "struct timespec"];
 }
 
 def ErrnoAPI : PublicAPI<"errno.h"> {

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index cf8c2c2d7746f..2a48c90b967d5 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -393,6 +393,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.nanosleep
   )
 endif()
 

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 63eb88247de04..a8aac4cfbd31d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -93,6 +93,7 @@ add_gen_header(
     .llvm_libc_common_h
     .llvm-libc-types.time_t
     .llvm-libc-types.struct_tm
+    .llvm-libc-types.struct_timespec
 )
 
 add_gen_header(

diff  --git a/libc/include/llvm-libc-types/struct_timespec.h b/libc/include/llvm-libc-types/struct_timespec.h
index eb6e70bb578a4..1fa6272d3df92 100644
--- a/libc/include/llvm-libc-types/struct_timespec.h
+++ b/libc/include/llvm-libc-types/struct_timespec.h
@@ -12,8 +12,9 @@
 #include <llvm-libc-types/time_t.h>
 
 struct timespec {
-  time_t tv_sec;
-  long tv_nsec;
+  time_t tv_sec; /* Seconds.  */
+  /* TODO: BIG_ENDIAN may require padding. */
+  long tv_nsec; /* Nanoseconds.  */
 };
 
 #endif // __LLVM_LIBC_TYPES_TIMESPEC_H__

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 8f8cad426ef59..d93ba16de9faf 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -37,6 +37,9 @@ def StructDirentPtr : PtrType<StructDirent>;
 def StructDirentPtrPtr : PtrType<StructDirentPtr>;
 def ConstStructDirentPtrPtr : ConstType<StructDirentPtrPtr>;
 
+def StructTimeSpec : NamedType<"struct timespec">;
+def StructTimeSpecPtr : PtrType<StructTimeSpec>;
+
 def POSIX : StandardSpec<"POSIX"> {
   PtrType CharPtr = PtrType<CharType>;
   RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@@ -919,6 +922,23 @@ def POSIX : StandardSpec<"POSIX"> {
       ]
   >;
 
+  HeaderSpec Time = HeaderSpec<
+      "time.h",
+      [], // Macros
+      [StructTimeSpec], // Types
+      [], // Enumerations
+      [
+          FunctionSpec<
+              "nanosleep",
+              RetValSpec<IntType>,
+              [
+	      	      ArgSpec<StructTimeSpecPtr>,
+	      	      ArgSpec<StructTimeSpecPtr>,
+	            ]
+          >,
+      ]
+  >;
+
   let Headers = [
     CType,
     Dirent,
@@ -932,6 +952,7 @@ def POSIX : StandardSpec<"POSIX"> {
     SysResource,
     SysStat,
     SysUtsName,
+    Time,
     UniStd,
     String
   ];

diff  --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 514b36cd852ac..880e7ed956acb 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -66,3 +66,17 @@ add_entrypoint_object(
     libc.include.time
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  nanosleep
+  SRCS
+    nanosleep.cpp
+  HDRS
+    nanosleep.h
+  DEPENDS
+    libc.include.errno
+    libc.include.time
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)

diff  --git a/libc/src/time/nanosleep.cpp b/libc/src/time/nanosleep.cpp
new file mode 100644
index 0000000000000..2eb5e97aff090
--- /dev/null
+++ b/libc/src/time/nanosleep.cpp
@@ -0,0 +1,29 @@
+//===-- Implementation of nanosleep 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/nanosleep.h"
+#include "include/sys/syscall.h"          // For syscall numbers.
+#include "src/__support/OSUtil/syscall.h" // For syscall functions.
+#include "src/__support/common.h"
+
+#include <errno.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, nanosleep,
+                   (const struct timespec *req, struct timespec *rem)) {
+  int ret = __llvm_libc::syscall(SYS_nanosleep, req, rem);
+  if (ret < 0) {
+    errno = -ret;
+    return -1;
+  }
+  return ret;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/time/nanosleep.h b/libc/src/time/nanosleep.h
new file mode 100644
index 0000000000000..5177ef0f63acd
--- /dev/null
+++ b/libc/src/time/nanosleep.h
@@ -0,0 +1,23 @@
+//===-- Implementation header of nanosleep -------------------------*- 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_NANOSLEEP_H
+#define LLVM_LIBC_SRC_TIME_NANOSLEEP_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+int nanosleep(const struct timespec *req, struct timespec *rem);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_NANOSLEEP_H
+
+#include "include/time.h"

diff  --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 9fe06e3a22974..0fe964ca4333b 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -68,3 +68,20 @@ add_libc_unittest(
   DEPENDS
     libc.src.time.mktime
 )
+
+add_libc_unittest(
+  nanosleep
+  SUITE
+    libc_time_unittests
+  SRCS
+    nanosleep_test.cpp
+  HDRS
+    TmHelper.h
+    TmMatcher.h
+  CXX_STANDARD
+    20
+  DEPENDS
+    libc.include.errno
+    libc.include.time
+    libc.src.time.nanosleep
+)

diff  --git a/libc/test/src/time/nanosleep_test.cpp b/libc/test/src/time/nanosleep_test.cpp
new file mode 100644
index 0000000000000..2b2c90710e1a3
--- /dev/null
+++ b/libc/test/src/time/nanosleep_test.cpp
@@ -0,0 +1,29 @@
+//===-- Unittests for nanosleep
+//---------------------------------------------===//
+//
+// 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/nanosleep.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+namespace cpp = __llvm_libc::cpp;
+
+TEST(LlvmLibcNanosleep, SmokeTest) {
+  // TODO: When we have the code to read clocks, test that time has passed.
+  using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+  errno = 0;
+
+  struct timespec tim = {1, 500};
+  struct timespec tim2 = {0, 0};
+  int ret = __llvm_libc::nanosleep(&tim, &tim2);
+  ASSERT_EQ(errno, 0);
+  ASSERT_EQ(ret, 0);
+}


        


More information about the libc-commits mailing list