[libc-commits] [libc] [libc] Add GPU support for the 'system' function (PR #109687)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Mon Sep 23 11:57:34 PDT 2024


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/109687

>From 511b4603bd1f05089ed66b11beb1c5922cbad6a2 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 23 Sep 2024 12:13:52 -0500
Subject: [PATCH] [libc] Add GPU support for the 'system' function

Summary:
This function can easily be implemented by forwarding it to the host
process. This shows up in a few places that we might want to test the
GPU so it should be provided. Also, I find the idea of the GPU
offloading work to the CPU via `system` very funny.
---
 libc/config/gpu/entrypoints.txt              |  1 +
 libc/docs/gpu/support.rst                    |  1 +
 libc/include/llvm-libc-types/rpc_opcodes_t.h |  1 +
 libc/newhdrgen/yaml/stdlib.yaml              |  6 ++++
 libc/spec/stdc.td                            |  2 ++
 libc/src/stdlib/CMakeLists.txt               |  7 +++++
 libc/src/stdlib/gpu/CMakeLists.txt           | 13 ++++++++-
 libc/src/stdlib/gpu/system.cpp               | 29 ++++++++++++++++++++
 libc/src/stdlib/system.h                     | 20 ++++++++++++++
 libc/utils/gpu/server/rpc_server.cpp         | 11 ++++++++
 10 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/stdlib/gpu/system.cpp
 create mode 100644 libc/src/stdlib/system.h

diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 706f603b6ff56f..9fb89e6fd8d28a 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -191,6 +191,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.at_quick_exit
     libc.src.stdlib.quick_exit
     libc.src.stdlib.getenv
+    libc.src.stdlib.system
 
     # TODO: Implement these correctly
     libc.src.stdlib.aligned_alloc
diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index c8b1052ce16895..fada2d4c29c49a 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -176,6 +176,7 @@ atol           |check|
 atoll          |check|
 exit           |check|    |check|
 abort          |check|    |check|
+system         |check|    |check|
 labs           |check|
 llabs          |check|
 div            |check|
diff --git a/libc/include/llvm-libc-types/rpc_opcodes_t.h b/libc/include/llvm-libc-types/rpc_opcodes_t.h
index 45050e8521f7a0..3b388de6888c5d 100644
--- a/libc/include/llvm-libc-types/rpc_opcodes_t.h
+++ b/libc/include/llvm-libc-types/rpc_opcodes_t.h
@@ -38,6 +38,7 @@ typedef enum {
   RPC_PRINTF_TO_STDERR_PACKED,
   RPC_PRINTF_TO_STREAM_PACKED,
   RPC_REMOVE,
+  RPC_SYSTEM,
   RPC_LAST = 0xFFFF,
 } rpc_opcode_t;
 
diff --git a/libc/newhdrgen/yaml/stdlib.yaml b/libc/newhdrgen/yaml/stdlib.yaml
index 5da49b8a89101c..c6c95e421cee35 100644
--- a/libc/newhdrgen/yaml/stdlib.yaml
+++ b/libc/newhdrgen/yaml/stdlib.yaml
@@ -333,3 +333,9 @@ functions:
       - type: char **__restrict
       - type: int
       - type: locale_t
+  - name: system
+    standards:
+      - stdc
+    return_type: int
+    arguments:
+      - type: const char *
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index c7b697d438a89e..7caf543748151a 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -1340,6 +1340,8 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"atexit", RetValSpec<IntType>, [ArgSpec<AtexitHandlerT>]>,
           FunctionSpec<"exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
           FunctionSpec<"quick_exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
+
+          FunctionSpec<"system", RetValSpec<IntType>, [ArgSpec<ConstCharPtr>]>,
       ]
   >;
 
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 7fc68cb35e8489..1b5b2cb1552646 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -621,3 +621,10 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.abort
 )
+
+add_entrypoint_object(
+  system
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.system
+)
diff --git a/libc/src/stdlib/gpu/CMakeLists.txt b/libc/src/stdlib/gpu/CMakeLists.txt
index 073f81515870b9..3c0588a27e7e0f 100644
--- a/libc/src/stdlib/gpu/CMakeLists.txt
+++ b/libc/src/stdlib/gpu/CMakeLists.txt
@@ -61,5 +61,16 @@ add_entrypoint_object(
     ../abort.h
   DEPENDS
     libc.include.stdlib
-    libc.src.__support.GPU.allocator
+    libc.src.__support.RPC.rpc_client
+)
+
+add_entrypoint_object(
+  system
+  SRCS
+    system.cpp
+  HDRS
+    ../system.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.__support.RPC.rpc_client
 )
diff --git a/libc/src/stdlib/gpu/system.cpp b/libc/src/stdlib/gpu/system.cpp
new file mode 100644
index 00000000000000..acf3a8c941ffa9
--- /dev/null
+++ b/libc/src/stdlib/gpu/system.cpp
@@ -0,0 +1,29 @@
+//===-- GPU implementation of system --------------------------------------===//
+//
+// 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/__support/RPC/rpc_client.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+
+#include "src/stdlib/system.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
+  int ret;
+  rpc::Client::Port port = rpc::client.open<RPC_SYSTEM>();
+  port.send_n(command, internal::string_length(command) + 1);
+  port.recv(
+      [&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
+  port.close();
+
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/system.h b/libc/src/stdlib/system.h
new file mode 100644
index 00000000000000..3358ca7bb7a619
--- /dev/null
+++ b/libc/src/stdlib/system.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for system ------------------------*- 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_SYSTEM_H
+#define LLVM_LIBC_SRC_STDLIB_SYSTEM_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int system(const char *command);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_SYSTEM_H
diff --git a/libc/utils/gpu/server/rpc_server.cpp b/libc/utils/gpu/server/rpc_server.cpp
index 0d4d1adecabb4c..8708f946b310ee 100644
--- a/libc/utils/gpu/server/rpc_server.cpp
+++ b/libc/utils/gpu/server/rpc_server.cpp
@@ -392,6 +392,17 @@ rpc_status_t handle_server_impl(
     });
     break;
   }
+  case RPC_SYSTEM: {
+    uint64_t sizes[lane_size] = {0};
+    void *args[lane_size] = {nullptr};
+    port->recv_n(args, sizes, [&](uint64_t size) { return new char[size]; });
+    port->send([&](rpc::Buffer *buffer, uint32_t id) {
+      buffer->data[0] = static_cast<uint64_t>(
+          system(reinterpret_cast<const char *>(args[id])));
+      delete[] reinterpret_cast<uint8_t *>(args[id]);
+    });
+    break;
+  }
   case RPC_NOOP: {
     port->recv([](rpc::Buffer *) {});
     break;



More information about the libc-commits mailing list