mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-19 17:31:55 +00:00
[libc] Support suspending threads during RPC spin loops
The RPC interface relies on waiting on atomic signals to coordinate which side of the protocol is in control of the shared buffer. The GPU client supports briefly suspending the executing thread group. This is used by the thread scheduler to identify which thread groups can be switched out so that others may execute. This allows us to ensure that other threads get a chance to make forward progress while these threads wait on the atomic signal. This is currently only relevant on the client-side. We could use an alternative implementation on the server that uses the standard `nanosleep` on supported hosts. Reviewed By: JonChesterfield, tianshilei1992 Differential Revision: https://reviews.llvm.org/D147238
This commit is contained in:
parent
9255124a07
commit
dff3909c3e
@ -2,6 +2,7 @@ add_header_library(
|
||||
rpc
|
||||
HDRS
|
||||
rpc.h
|
||||
rpc_util.h
|
||||
DEPENDS
|
||||
libc.src.__support.common
|
||||
libc.src.__support.CPP.atomic
|
||||
|
@ -18,6 +18,7 @@
|
||||
#ifndef LLVM_LIBC_SRC_SUPPORT_RPC_RPC_H
|
||||
#define LLVM_LIBC_SRC_SUPPORT_RPC_RPC_H
|
||||
|
||||
#include "rpc_util.h"
|
||||
#include "src/__support/CPP/atomic.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@ -101,8 +102,10 @@ template <typename F, typename U> LIBC_INLINE void Client::run(F fill, U use) {
|
||||
}
|
||||
// Wait for the server to work on the buffer and respond.
|
||||
if (!in & out) {
|
||||
while (!in)
|
||||
while (!in) {
|
||||
sleep_briefly();
|
||||
in = inbox->load(cpp::MemoryOrder::RELAXED);
|
||||
}
|
||||
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
|
||||
}
|
||||
// Apply \p use to the buffer and signal the server.
|
||||
@ -114,8 +117,10 @@ template <typename F, typename U> LIBC_INLINE void Client::run(F fill, U use) {
|
||||
}
|
||||
// Wait for the server to signal the end of the protocol.
|
||||
if (in & !out) {
|
||||
while (in)
|
||||
while (in) {
|
||||
sleep_briefly();
|
||||
in = inbox->load(cpp::MemoryOrder::RELAXED);
|
||||
}
|
||||
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
|
||||
}
|
||||
}
|
||||
|
32
libc/src/__support/RPC/rpc_util.h
Normal file
32
libc/src/__support/RPC/rpc_util.h
Normal file
@ -0,0 +1,32 @@
|
||||
//===-- Shared memory RPC client / server 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_SUPPORT_RPC_RPC_UTILS_H
|
||||
#define LLVM_LIBC_SRC_SUPPORT_RPC_RPC_UTILS_H
|
||||
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/properties/architectures.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace rpc {
|
||||
|
||||
/// Suspend the thread briefly to assist the thread scheduler during busy loops.
|
||||
LIBC_INLINE void sleep_briefly() {
|
||||
#if defined(LIBC_TARGET_ARCH_IS_NVPTX) && __CUDA_ARCH__ >= 700
|
||||
asm("nanosleep.u32 64;" ::: "memory");
|
||||
#elif defined(LIBC_TARGET_ARCH_IS_AMDGPU)
|
||||
__builtin_amdgcn_s_sleep(2);
|
||||
#else
|
||||
// Simply do nothing if sleeping isn't supported on this platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user