[libc] Small change to accept lambda types in rpc::dispatch
Summary: This change allows lambdas to be used in the RPC dispatching functions. Just requires an extra function trait to convert a lambda with no captures into a function pointer. Also rearranged where the `Port` lives because it looks better no that we may use a lambda and it's more consistent with the dispatch usage (putting the client at the start).
This commit is contained in:
parent
3a658906ef
commit
846e61c0fb
@ -217,7 +217,7 @@ dispatch(rpc::Client &client, FnTy, CallArgs... args) {
|
||||
// Invoke a function on the server on behalf of the client. Recieves the
|
||||
// arguments through the interface and forwards them to the function.
|
||||
template <uint32_t NUM_LANES, typename FnTy>
|
||||
RPC_ATTRS constexpr void invoke(FnTy fn, rpc::Server::Port &port) {
|
||||
RPC_ATTRS constexpr void invoke(rpc::Server::Port &port, FnTy fn) {
|
||||
using Traits = function_traits<FnTy>;
|
||||
using RetTy = typename Traits::return_type;
|
||||
using TupleTy = typename Traits::arg_types;
|
||||
|
||||
@ -440,13 +440,17 @@ RPC_ATTRS constexpr uint64_t string_length(const char *s) {
|
||||
return static_cast<uint64_t>(end - s + 1);
|
||||
}
|
||||
|
||||
/// Helper for dealing with function types.
|
||||
/// Helper for dealing with function pointers and lambda types.
|
||||
template <typename> struct function_traits;
|
||||
template <typename R, typename... Args> struct function_traits<R (*)(Args...)> {
|
||||
using return_type = R;
|
||||
using arg_types = rpc::tuple<Args...>;
|
||||
static constexpr uint64_t ARITY = sizeof...(Args);
|
||||
};
|
||||
template <typename T> T &&declval();
|
||||
template <typename T>
|
||||
struct function_traits
|
||||
: function_traits<decltype(+declval<rpc::remove_reference_t<T>>())> {};
|
||||
|
||||
template <typename T, typename U>
|
||||
RPC_ATTRS constexpr T max(const T &a, const U &b) {
|
||||
|
||||
@ -77,7 +77,10 @@ int c_string(const char *s) {
|
||||
int empty() { return 42; }
|
||||
|
||||
// 7. Divergent values.
|
||||
void divergent(int *) {}
|
||||
void divergent(int *p) {
|
||||
assert(p);
|
||||
*p = *p;
|
||||
}
|
||||
|
||||
//===------------------------------------------------------------------------===
|
||||
// RPC client dispatch.
|
||||
@ -117,25 +120,28 @@ template <uint32_t NUM_LANES>
|
||||
rpc::Status handleOpcodesImpl(rpc::Server::Port &Port) {
|
||||
switch (Port.get_opcode()) {
|
||||
case FOO_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(foo, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, foo);
|
||||
break;
|
||||
case VOID_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(void_fn, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, void_fn);
|
||||
break;
|
||||
case WRITEBACK_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(writeback_fn, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, writeback_fn);
|
||||
break;
|
||||
case CONST_PTR_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(sum_const, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, sum_const);
|
||||
break;
|
||||
case STRING_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(c_string, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, c_string);
|
||||
break;
|
||||
case EMPTY_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(empty, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, empty);
|
||||
break;
|
||||
case DIVERGENT_OPCODE:
|
||||
rpc::invoke<NUM_LANES>(divergent, Port);
|
||||
rpc::invoke<NUM_LANES>(Port, [](int *p) {
|
||||
assert(p);
|
||||
*p = *p;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return rpc::RPC_UNHANDLED_OPCODE;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user