[libc-commits] [libc] [libc] implement quick exit function (PR #93621)
via libc-commits
libc-commits at lists.llvm.org
Tue May 28 16:01:00 PDT 2024
https://github.com/aaryanshukla created https://github.com/llvm/llvm-project/pull/93621
Implementing the quick exit function.
>From 1bfb3baf6712864e6bbe604082c3a1b389441013 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 28 May 2024 22:40:16 +0000
Subject: [PATCH] [libc] implement quick exit function
Implementing the quick exit function.
---
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/spec/stdc.td | 2 ++
.../baremetal/{quick_exit.cpp => exit.cpp} | 8 ++++--
.../__support/OSUtil/{quick_exit.h => exit.h} | 9 ++++---
.../OSUtil/gpu/{quick_exit.cpp => exit.cpp} | 7 ++++--
.../src/__support/OSUtil/linux/CMakeLists.txt | 2 +-
.../OSUtil/linux/{quick_exit.cpp => exit.cpp} | 7 +++++-
libc/src/__support/libc_assert.h | 4 +--
libc/src/stdlib/CMakeLists.txt | 16 ++++++++++--
libc/src/stdlib/_Exit.cpp | 4 +--
libc/src/stdlib/exit.cpp | 4 +--
libc/src/stdlib/quick_exit.cpp | 25 +++++++++++++++++++
libc/src/stdlib/quick_exit.h | 20 +++++++++++++++
libc/src/unistd/_exit.cpp | 4 +--
libc/test/IntegrationTest/test.h | 10 ++++----
libc/test/src/stdlib/CMakeLists.txt | 17 +++++++++++++
libc/test/src/stdlib/quick_exit_test.cpp | 17 +++++++++++++
libc/utils/HdrGen/Main.cpp | 1 +
18 files changed, 134 insertions(+), 24 deletions(-)
rename libc/src/__support/OSUtil/baremetal/{quick_exit.cpp => exit.cpp} (80%)
rename libc/src/__support/OSUtil/{quick_exit.h => exit.h} (75%)
rename libc/src/__support/OSUtil/gpu/{quick_exit.cpp => exit.cpp} (89%)
rename libc/src/__support/OSUtil/linux/{quick_exit.cpp => exit.cpp} (95%)
create mode 100644 libc/src/stdlib/quick_exit.cpp
create mode 100644 libc/src/stdlib/quick_exit.h
create mode 100644 libc/test/src/stdlib/quick_exit_test.cpp
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5e3ddd34fb4dc..b6ead64e208c7 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -730,6 +730,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdlib.abort
libc.src.stdlib.atexit
libc.src.stdlib.exit
+ libc.src.stdlib.quick_exit
libc.src.stdlib.getenv
# signal.h entrypoints
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index eb67c9b0b009b..20a95b6aae385 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -1071,6 +1071,8 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
FunctionSpec<"exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
FunctionSpec<"atexit", RetValSpec<IntType>, [ArgSpec<AtexitHandlerT>]>,
+ FunctionSpec<"quick_exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
+
]
>;
diff --git a/libc/src/__support/OSUtil/baremetal/quick_exit.cpp b/libc/src/__support/OSUtil/baremetal/exit.cpp
similarity index 80%
rename from libc/src/__support/OSUtil/baremetal/quick_exit.cpp
rename to libc/src/__support/OSUtil/baremetal/exit.cpp
index 5b6fcf42341eb..c77e21ae6602d 100644
--- a/libc/src/__support/OSUtil/baremetal/quick_exit.cpp
+++ b/libc/src/__support/OSUtil/baremetal/exit.cpp
@@ -6,13 +6,17 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
// This is intended to be provided by the vendor.
extern "C" [[noreturn]] void __llvm_libc_quick_exit(int status);
namespace LIBC_NAMESPACE {
+namespace internal {
-[[noreturn]] void quick_exit(int status) { __llvm_libc_quick_exit(status); }
+[[noreturn]] void exit(int status) { __llvm_libc_quick_exit(status); }
+
+
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/__support/OSUtil/quick_exit.h b/libc/src/__support/OSUtil/exit.h
similarity index 75%
rename from libc/src/__support/OSUtil/quick_exit.h
rename to libc/src/__support/OSUtil/exit.h
index e445917059c3e..5bd967ecf8777 100644
--- a/libc/src/__support/OSUtil/quick_exit.h
+++ b/libc/src/__support/OSUtil/exit.h
@@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H
namespace LIBC_NAMESPACE {
+namespace internal {
-[[noreturn]] void quick_exit(int status);
+[[noreturn]] void exit(int status);
+
+}
}
diff --git a/libc/src/__support/OSUtil/gpu/quick_exit.cpp b/libc/src/__support/OSUtil/gpu/exit.cpp
similarity index 89%
rename from libc/src/__support/OSUtil/gpu/quick_exit.cpp
rename to libc/src/__support/OSUtil/gpu/exit.cpp
index af4795905e786..e9744a69650a4 100644
--- a/libc/src/__support/OSUtil/gpu/quick_exit.cpp
+++ b/libc/src/__support/OSUtil/gpu/exit.cpp
@@ -6,14 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
+namespace internal {
-[[noreturn]] void quick_exit(int status) {
+[[noreturn]] void exit(int status) {
// We want to first make sure the server is listening before we exit.
rpc::Client::Port port = rpc::client.open<RPC_EXIT>();
port.send_and_recv([](rpc::Buffer *) {}, [](rpc::Buffer *) {});
@@ -25,4 +26,6 @@ namespace LIBC_NAMESPACE {
gpu::end_program();
}
+
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 239d115704927..9a55232d532fe 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -7,7 +7,7 @@ add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
add_object_library(
linux_util
SRCS
- quick_exit.cpp
+ exit.cpp
HDRS
io.h
syscall.h
diff --git a/libc/src/__support/OSUtil/linux/quick_exit.cpp b/libc/src/__support/OSUtil/linux/exit.cpp
similarity index 95%
rename from libc/src/__support/OSUtil/linux/quick_exit.cpp
rename to libc/src/__support/OSUtil/linux/exit.cpp
index 51b3231d389f2..8dccfc22f3799 100644
--- a/libc/src/__support/OSUtil/linux/quick_exit.cpp
+++ b/libc/src/__support/OSUtil/linux/exit.cpp
@@ -11,6 +11,8 @@
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE {
+namespace internal {
+
// mark as no_stack_protector for x86 since TLS can be torn down before calling
// quick_exit so that the stack protector canary cannot be loaded.
@@ -18,11 +20,14 @@ namespace LIBC_NAMESPACE {
__attribute__((no_stack_protector))
#endif
__attribute__((noreturn)) void
-quick_exit(int status) {
+exit(int status) {
for (;;) {
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit_group, status);
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit, status);
}
}
+
+}
+
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/__support/libc_assert.h b/libc/src/__support/libc_assert.h
index 61f075435b552..ca04e7024964c 100644
--- a/libc/src/__support/libc_assert.h
+++ b/libc/src/__support/libc_assert.h
@@ -21,7 +21,7 @@
#else // Not LIBC_COPT_USE_C_ASSERT
#include "src/__support/OSUtil/io.h"
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#include "src/__support/integer_to_string.h"
#include "src/__support/macros/attributes.h" // For LIBC_INLINE
@@ -76,7 +76,7 @@ LIBC_INLINE void report_assertion_failure(const char *assertion,
"' in function: '"); \
LIBC_NAMESPACE::write_to_stderr(__PRETTY_FUNCTION__); \
LIBC_NAMESPACE::write_to_stderr("'\n"); \
- LIBC_NAMESPACE::quick_exit(0xFF); \
+ LIBC_NAMESPACE::internal::exit(0xFF); \
} \
} while (false)
#endif // NDEBUG
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 9b76a6a0f8575..ef74ca4fd0e70 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -2,6 +2,7 @@ add_entrypoint_object(
atoi
SRCS
atoi.cpp
+ quick_exit.cpp
HDRS
atoi.h
DEPENDS
@@ -13,8 +14,7 @@ add_entrypoint_object(
atof
SRCS
atof.cpp
- HDRS
- atof.h
+ atof.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_float
@@ -432,6 +432,18 @@ add_entrypoint_object(
._Exit
.atexit
libc.src.__support.OSUtil.osutil
+
+)
+
+add_entrypoint_object(
+ quick_exit
+ SRCS
+ quick_exit.cpp
+ HDRS
+ quick_exit.h
+ DEPENDS
+ libc.src.errno.errno
+
)
add_entrypoint_object(
diff --git a/libc/src/stdlib/_Exit.cpp b/libc/src/stdlib/_Exit.cpp
index 233af20973924..03a766261014e 100644
--- a/libc/src/stdlib/_Exit.cpp
+++ b/libc/src/stdlib/_Exit.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#include "src/__support/common.h"
#include "src/stdlib/_Exit.h"
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE {
[[noreturn]] LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
- quick_exit(status);
+ internal::exit(status);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp
index ba87bffaeb541..1f7ccbb556607 100644
--- a/libc/src/stdlib/exit.cpp
+++ b/libc/src/stdlib/exit.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/exit.h"
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#include "src/__support/common.h"
extern "C" void __cxa_finalize(void *);
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE {
[[noreturn]] LLVM_LIBC_FUNCTION(void, exit, (int status)) {
__cxa_finalize(nullptr);
- quick_exit(status);
+ internal::exit(status);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/quick_exit.cpp b/libc/src/stdlib/quick_exit.cpp
new file mode 100644
index 0000000000000..5b14683a0d956
--- /dev/null
+++ b/libc/src/stdlib/quick_exit.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of quick_exit --------------------------------------------===//
+//
+// 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/stdlib/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/common.h"
+
+//extern "C" void __cxa_finalize(void *);
+
+namespace LIBC_NAMESPACE {
+
+[[noreturn]] LLVM_LIBC_FUNCTION(void, quick_exit, (int status)) {
+ //__cxa_finalize(nullptr);
+ exit(status);
+}
+
+
+}
+ // namespace LIBC_NAMESPACE
+
diff --git a/libc/src/stdlib/quick_exit.h b/libc/src/stdlib/quick_exit.h
new file mode 100644
index 0000000000000..1ebf689e1868e
--- /dev/null
+++ b/libc/src/stdlib/quick_exit.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for quick_exit -------------------*- 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_STDLIB_QUICK_EXIT_H
+#define LLVM_LIBC_SRC_STDLIB_QUICK_EXIT_H
+
+#include <stdlib.h>
+
+namespace LIBC_NAMESPACE {
+
+[[noreturn]] void quick_exit(int status);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_QUICK_EXIT_H
diff --git a/libc/src/unistd/_exit.cpp b/libc/src/unistd/_exit.cpp
index 6fbf3a51d42f4..4b652a2c13fd1 100644
--- a/libc/src/unistd/_exit.cpp
+++ b/libc/src/unistd/_exit.cpp
@@ -7,13 +7,13 @@
//===----------------------------------------------------------------------===//
#include "src/unistd/_exit.h"
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
[[noreturn]] LLVM_LIBC_FUNCTION(void, _exit, (int status)) {
- quick_exit(status);
+ internal::exit(status);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/test/IntegrationTest/test.h b/libc/test/IntegrationTest/test.h
index 64906ef179391..14e6f22f0ee67 100644
--- a/libc/test/IntegrationTest/test.h
+++ b/libc/test/IntegrationTest/test.h
@@ -10,7 +10,7 @@
#define LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H
#include "src/__support/OSUtil/io.h"
-#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/OSUtil/exit.h"
#define __AS_STRING(val) #val
#define __CHECK_TRUE(file, line, val, should_exit) \
@@ -18,7 +18,7 @@
LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \
line) ": Expected '" #val "' to be true, but is false\n"); \
if (should_exit) \
- LIBC_NAMESPACE::quick_exit(127); \
+ LIBC_NAMESPACE::internal::exit(127); \
}
#define __CHECK_FALSE(file, line, val, should_exit) \
@@ -26,7 +26,7 @@
LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \
line) ": Expected '" #val "' to be false, but is true\n"); \
if (should_exit) \
- LIBC_NAMESPACE::quick_exit(127); \
+ LIBC_NAMESPACE::internal::exit(127); \
}
#define __CHECK_EQ(file, line, val1, val2, should_exit) \
@@ -34,7 +34,7 @@
LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \
line) ": Expected '" #val1 "' to be equal to '" #val2 "'\n"); \
if (should_exit) \
- LIBC_NAMESPACE::quick_exit(127); \
+ LIBC_NAMESPACE::internal::exit(127); \
}
#define __CHECK_NE(file, line, val1, val2, should_exit) \
@@ -42,7 +42,7 @@
LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \
line) ": Expected '" #val1 "' to not be equal to '" #val2 "'\n"); \
if (should_exit) \
- LIBC_NAMESPACE::quick_exit(127); \
+ LIBC_NAMESPACE::internal::exit(127); \
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 28c5b566cc477..e07e8b651322e 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -324,6 +324,23 @@ add_libc_test(
libc.src.stdlib.srand
)
+add_libc_test(
+ quick_exit_test
+ # The EXPECT_EXITS test is only availible for unit tests.
+ UNIT_TEST_ONLY
+ SUITE
+ libc-stdlib-tests
+ SRCS
+ quick_exit_test.cpp
+ DEPENDS
+ libc.include.stdlib
+ libc.src.stdlib._Exit
+ libc.src.stdlib.quick_exit
+ libc.src.stdlib.atexit
+ libc.src.__support.CPP.array
+ libc.src.__support.CPP.utility
+ )
+
if(LLVM_LIBC_FULL_BUILD)
add_libc_test(
diff --git a/libc/test/src/stdlib/quick_exit_test.cpp b/libc/test/src/stdlib/quick_exit_test.cpp
new file mode 100644
index 0000000000000..8ed878a11575b
--- /dev/null
+++ b/libc/test/src/stdlib/quick_exit_test.cpp
@@ -0,0 +1,17 @@
+//===-- Unittests for quick_exit ------------------------------------------===//
+//
+// 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/stdlib/quick_exit.h"
+#include "test/UnitTest/Test.h"
+
+#include <stdlib.h>
+
+TEST(LlvmLibcStdlib, quick_exit) {
+ EXPECT_EXITS([] { LIBC_NAMESPACE::quick_exit(1); }, 1);
+ EXPECT_EXITS([] { LIBC_NAMESPACE::quick_exit(65); }, 65);
+}
diff --git a/libc/utils/HdrGen/Main.cpp b/libc/utils/HdrGen/Main.cpp
index d3418f206b10e..92269dd70ae19 100644
--- a/libc/utils/HdrGen/Main.cpp
+++ b/libc/utils/HdrGen/Main.cpp
@@ -65,3 +65,4 @@ int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv);
return TableGenMain(argv[0], &llvm_libc::HeaderGeneratorMain);
}
+
More information about the libc-commits
mailing list