[libc-commits] [libc] [libc] Add separate `rand` implementation for baremetal (PR #96798)
Joseph Huber via libc-commits
libc-commits at lists.llvm.org
Wed Jun 26 10:42:32 PDT 2024
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/96798
>From 7c80ee0d82361b98e060c02b444fb5e4b29dc6a0 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Wed, 26 Jun 2024 12:00:10 -0500
Subject: [PATCH 1/2] [libc] Add separate `rand` implementation for baremetal
Summary:
Baremetal targets likely do now want multi-threaded support. Split the
implementation out to make it separate.
---
libc/src/stdlib/CMakeLists.txt | 89 ++++++++++++++----------
libc/src/stdlib/baremetal/CMakeLists.txt | 36 ++++++++++
libc/src/stdlib/baremetal/rand.cpp | 26 +++++++
libc/src/stdlib/baremetal/rand_util.cpp | 18 +++++
libc/src/stdlib/baremetal/rand_util.h | 21 ++++++
libc/src/stdlib/baremetal/srand.cpp | 17 +++++
libc/src/stdlib/linux/CMakeLists.txt | 4 ++
libc/src/stdlib/rand.cpp | 6 --
libc/src/stdlib/srand.cpp | 6 --
9 files changed, 173 insertions(+), 50 deletions(-)
create mode 100644 libc/src/stdlib/baremetal/rand.cpp
create mode 100644 libc/src/stdlib/baremetal/rand_util.cpp
create mode 100644 libc/src/stdlib/baremetal/rand_util.h
create mode 100644 libc/src/stdlib/baremetal/srand.cpp
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 677bf358c82c4..61aa14a8cb0d0 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
add_entrypoint_object(
atoi
SRCS
@@ -285,38 +289,55 @@ add_entrypoint_object(
libc.include.stdlib
)
-add_object_library(
- rand_util
- SRCS
- rand_util.cpp
- HDRS
- rand_util.h
- DEPENDS
- libc.src.__support.common
-)
-add_entrypoint_object(
- rand
- SRCS
- rand.cpp
- HDRS
- rand.h
- DEPENDS
- .rand_util
- libc.include.stdlib
- libc.src.__support.threads.sleep
-)
+if(NOT LIBC_TARGET_OS_IS_BAREMETAL)
+ add_object_library(
+ rand_util
+ SRCS
+ rand_util.cpp
+ HDRS
+ rand_util.h
+ DEPENDS
+ libc.src.__support.common
+ )
-add_entrypoint_object(
- srand
- SRCS
- srand.cpp
- HDRS
- srand.h
- DEPENDS
- .rand_util
- libc.include.stdlib
-)
+ add_entrypoint_object(
+ rand
+ SRCS
+ rand.cpp
+ HDRS
+ rand.h
+ DEPENDS
+ .rand_util
+ libc.include.stdlib
+ libc.src.__support.threads.sleep
+ )
+
+ add_entrypoint_object(
+ srand
+ SRCS
+ srand.cpp
+ HDRS
+ srand.h
+ DEPENDS
+ .rand_util
+ libc.include.stdlib
+ )
+else()
+ add_entrypoint_object(
+ rand
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.rand
+ )
+
+ add_entrypoint_object(
+ srand
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.srand
+ )
+endif()
if(NOT LIBC_TARGET_OS_IS_GPU)
if(LLVM_LIBC_INCLUDE_SCUDO)
@@ -413,14 +434,6 @@ if(NOT LIBC_TARGET_OS_IS_GPU)
endif()
endif()
-if(NOT LLVM_LIBC_FULL_BUILD)
- return()
-endif()
-
-if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
- add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
-endif()
-
if(LIBC_TARGET_OS_IS_GPU)
add_entrypoint_object(
malloc
diff --git a/libc/src/stdlib/baremetal/CMakeLists.txt b/libc/src/stdlib/baremetal/CMakeLists.txt
index 551a83a36b20e..fc43bf3d16b26 100644
--- a/libc/src/stdlib/baremetal/CMakeLists.txt
+++ b/libc/src/stdlib/baremetal/CMakeLists.txt
@@ -1,3 +1,39 @@
+add_object_library(
+ rand_util
+ SRCS
+ rand_util.cpp
+ HDRS
+ rand_util.h
+ DEPENDS
+ libc.src.__support.common
+)
+
+add_entrypoint_object(
+ rand
+ SRCS
+ rand.cpp
+ HDRS
+ ../rand.h
+ DEPENDS
+ .rand_util
+ libc.include.stdlib
+)
+
+add_entrypoint_object(
+ srand
+ SRCS
+ srand.cpp
+ HDRS
+ srand.h
+ DEPENDS
+ .rand_util
+ libc.include.stdlib
+)
+
+if(NOT LLVM_LIBC_FULL_BUILD)
+ return()
+endif()
+
add_entrypoint_object(
abort
SRCS
diff --git a/libc/src/stdlib/baremetal/rand.cpp b/libc/src/stdlib/baremetal/rand.cpp
new file mode 100644
index 0000000000000..a36b6f8da5d8f
--- /dev/null
+++ b/libc/src/stdlib/baremetal/rand.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of rand --------------------------------------------===//
+//
+// 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/rand.h"
+#include "src/__support/common.h"
+#include "src/__support/threads/sleep.h"
+#include "src/stdlib/baremetal/rand_util.h"
+
+namespace LIBC_NAMESPACE {
+
+// An implementation of the xorshift64star pseudo random number generator. This
+// is a good general purpose generator for most non-cryptographics applications.
+LLVM_LIBC_FUNCTION(int, rand, (void)) {
+ unsigned long x = rand_next;
+ x ^= x >> 12;
+ x ^= x << 25;
+ x ^= x >> 27;
+ return static_cast<int>((x * 0x2545F4914F6CDD1Dul) >> 32) & RAND_MAX;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/baremetal/rand_util.cpp b/libc/src/stdlib/baremetal/rand_util.cpp
new file mode 100644
index 0000000000000..4057930758c8f
--- /dev/null
+++ b/libc/src/stdlib/baremetal/rand_util.cpp
@@ -0,0 +1,18 @@
+//===-- Shared utility for rand -------------------------------------------===//
+//
+// 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/rand_util.h"
+#include "src/__support/macros/attributes.h"
+
+namespace LIBC_NAMESPACE {
+
+// C standard 7.10p2: If 'rand' is called before 'srand' it is to
+// proceed as if the 'srand' function was called with a value of '1'.
+unsigned long rand_next = 1;
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/baremetal/rand_util.h b/libc/src/stdlib/baremetal/rand_util.h
new file mode 100644
index 0000000000000..6f8839d093971
--- /dev/null
+++ b/libc/src/stdlib/baremetal/rand_util.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for rand utilities ----------------*- 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_RAND_UTIL_H
+#define LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
+
+#include "src/__support/macros/attributes.h"
+
+namespace LIBC_NAMESPACE {
+
+// We provide the baremetal version of `rand` without any thread-safety.
+extern unsigned long rand_next;
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
diff --git a/libc/src/stdlib/baremetal/srand.cpp b/libc/src/stdlib/baremetal/srand.cpp
new file mode 100644
index 0000000000000..008c7a9e565e4
--- /dev/null
+++ b/libc/src/stdlib/baremetal/srand.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of srand -------------------------------------------===//
+//
+// 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/srand.h"
+#include "src/__support/common.h"
+#include "src/stdlib/rand_util.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, srand, (unsigned int seed)) { rand_next = seed; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index 1d3c00a5e0ddb..df9c25abf3cba 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(NOT LLVM_LIBC_FULL_BUILD)
+ return()
+endif()
+
add_entrypoint_object(
abort
SRCS
diff --git a/libc/src/stdlib/rand.cpp b/libc/src/stdlib/rand.cpp
index 8f2ae90336d51..ff3875c2f6959 100644
--- a/libc/src/stdlib/rand.cpp
+++ b/libc/src/stdlib/rand.cpp
@@ -13,10 +13,6 @@
namespace LIBC_NAMESPACE {
-// Silence warnings on targets with slow atomics.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Watomic-alignment"
-
// An implementation of the xorshift64star pseudo random number generator. This
// is a good general purpose generator for most non-cryptographics applications.
LLVM_LIBC_FUNCTION(int, rand, (void)) {
@@ -33,6 +29,4 @@ LLVM_LIBC_FUNCTION(int, rand, (void)) {
}
}
-#pragma GCC diagnostic pop
-
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/srand.cpp b/libc/src/stdlib/srand.cpp
index 681aad8fac4e8..21166c7a6754e 100644
--- a/libc/src/stdlib/srand.cpp
+++ b/libc/src/stdlib/srand.cpp
@@ -12,14 +12,8 @@
namespace LIBC_NAMESPACE {
-// Silence warnings on targets with slow atomics.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Watomic-alignment"
-
LLVM_LIBC_FUNCTION(void, srand, (unsigned int seed)) {
rand_next.store(seed, cpp::MemoryOrder::RELAXED);
}
-#pragma GCC diagnostic pop
-
} // namespace LIBC_NAMESPACE
>From 0e2c05e465798f8b27a3686553d682d119072208 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Wed, 26 Jun 2024 12:42:22 -0500
Subject: [PATCH 2/2] Address comments
---
libc/src/stdlib/CMakeLists.txt | 1 +
libc/src/stdlib/baremetal/rand.cpp | 3 ++-
libc/src/stdlib/baremetal/rand_util.h | 2 --
libc/src/stdlib/rand_util.h | 1 -
4 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 61aa14a8cb0d0..2ff2fbb480ba9 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -324,6 +324,7 @@ if(NOT LIBC_TARGET_OS_IS_BAREMETAL)
libc.include.stdlib
)
else()
+ # Baremetal targets use a non MT-safe implementation.
add_entrypoint_object(
rand
ALIAS
diff --git a/libc/src/stdlib/baremetal/rand.cpp b/libc/src/stdlib/baremetal/rand.cpp
index a36b6f8da5d8f..39e9b45fef052 100644
--- a/libc/src/stdlib/baremetal/rand.cpp
+++ b/libc/src/stdlib/baremetal/rand.cpp
@@ -8,13 +8,14 @@
#include "src/stdlib/rand.h"
#include "src/__support/common.h"
-#include "src/__support/threads/sleep.h"
#include "src/stdlib/baremetal/rand_util.h"
namespace LIBC_NAMESPACE {
// An implementation of the xorshift64star pseudo random number generator. This
// is a good general purpose generator for most non-cryptographics applications.
+// This function is *not* MT-safe, baremetal callers will need to provide
+// synchronization externally.
LLVM_LIBC_FUNCTION(int, rand, (void)) {
unsigned long x = rand_next;
x ^= x >> 12;
diff --git a/libc/src/stdlib/baremetal/rand_util.h b/libc/src/stdlib/baremetal/rand_util.h
index 6f8839d093971..c9153ac7dd432 100644
--- a/libc/src/stdlib/baremetal/rand_util.h
+++ b/libc/src/stdlib/baremetal/rand_util.h
@@ -9,8 +9,6 @@
#ifndef LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
#define LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
-#include "src/__support/macros/attributes.h"
-
namespace LIBC_NAMESPACE {
// We provide the baremetal version of `rand` without any thread-safety.
diff --git a/libc/src/stdlib/rand_util.h b/libc/src/stdlib/rand_util.h
index 5d7febf8248d8..762448bc87eda 100644
--- a/libc/src/stdlib/rand_util.h
+++ b/libc/src/stdlib/rand_util.h
@@ -10,7 +10,6 @@
#define LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
#include "src/__support/CPP/atomic.h"
-#include "src/__support/macros/attributes.h"
namespace LIBC_NAMESPACE {
More information about the libc-commits
mailing list