From 12d69338c5e787034065c45cbfdbdf3ee316b041 Mon Sep 17 00:00:00 2001 From: Sid Hussmann Date: Fri, 29 Nov 2019 16:26:20 +0100 Subject: [PATCH] protobuf_grpc: use pthread Fixes pagefaults. This includes the changes provided by ssumpf in 6726aef. Issue #190 --- lib/symbols/grpc | 2 + run/grpc-server.run | 157 +++++++++++++++++++++++ run/grpc-startup.run | 169 +++++++++++++++++++++++++ run/grpc.run | 27 ++-- src/test/grpc/client/greeter_client.cc | 95 ++++++++++++++ src/test/grpc/client/target.mk | 1 - src/test/grpc/server/greeter_server.cc | 3 +- src/test/grpc/server/greeter_server.h | 2 +- src/test/grpc/server/main.cc | 28 ++-- 9 files changed, 455 insertions(+), 29 deletions(-) create mode 100644 run/grpc-server.run create mode 100644 run/grpc-startup.run create mode 100644 src/test/grpc/client/greeter_client.cc diff --git a/lib/symbols/grpc b/lib/symbols/grpc index c2fb0b0..7f11c3e 100644 --- a/lib/symbols/grpc +++ b/lib/symbols/grpc @@ -14,3 +14,5 @@ _ZN9grpc_impl13ServerBuilderD1Ev W _ZN9grpc_impl17CreateChannelImplERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10shared_ptrINS_18ChannelCredentialsEE W _ZN9grpc_impl25InsecureServerCredentialsEv W _ZN9grpc_impl26InsecureChannelCredentialsEv W +_ZN9grpc_impl7ChannelD0Ev W +_ZN4grpc12experimental29ChannelResetConnectionBackoffEPN9grpc_impl7ChannelE W diff --git a/run/grpc-server.run b/run/grpc-server.run new file mode 100644 index 0000000..7318d02 --- /dev/null +++ b/run/grpc-server.run @@ -0,0 +1,157 @@ +# To execute this run script on a development PC, you need to setup a TAP device +# first: + +# netdev=wlp2s0 +# tapdev=tap0 +# user=developer +# +# sudo ip tuntap add dev $tapdev mode tap user $user +# sudo ip address flush dev $tapdev +# sudo ip address add 10.0.2.1/24 brd 10.0.2.255 dev $tapdev +# sudo ip link set dev $tapdev addr 02:00:00:ca:fe:01 +# sudo ip link set dev $tapdev up +# +# connect using your favorite grpc client +# E.g. https://github.com/sidhussmann/grpc-connection-stress +# ./stress_grpc.sh 10.0.2.55:8899 + + + + +create_boot_directory + + +import_from_depot [depot_user]/src/[base_src] +import_from_depot [depot_user]/src/init +import_from_depot [depot_user]/src/libc +import_from_depot [depot_user]/src/libcrypto +import_from_depot [depot_user]/src/nic_router +import_from_depot [depot_user]/src/posix +import_from_depot [depot_user]/src/protobuf +import_from_depot [depot_user]/src/libssl +import_from_depot [depot_user]/src/report_rom +import_from_depot [depot_user]/src/stdcxx +import_from_depot [depot_user]/src/vfs +import_from_depot [depot_user]/src/vfs_lxip +import_from_depot [depot_user]/src/zlib + + +set build_components { + drivers/nic + test/grpc/server +} + + +build $build_components + + +set nic_router_reporting 0 + + +set config { + + + + + + + + + + + + + + + + +} + +append config { + + + + + + + + + + 2000-01-01 00:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + + +install_config $config + + +set boot_modules { + grpc_server + grpc.lib.so + libc_pipe.lib.so + vfs_lwip.lib.so + linux_nic_drv +} + + +append qemu_args " -nographic " + + +build_boot_image $boot_modules + + +run_genode_until forever diff --git a/run/grpc-startup.run b/run/grpc-startup.run new file mode 100644 index 0000000..028ad1d --- /dev/null +++ b/run/grpc-startup.run @@ -0,0 +1,169 @@ +create_boot_directory + + +import_from_depot [depot_user]/src/[base_src] +import_from_depot [depot_user]/src/dynamic_rom +import_from_depot [depot_user]/src/init +import_from_depot [depot_user]/src/libc +import_from_depot [depot_user]/src/libcrypto +import_from_depot [depot_user]/src/nic_router +import_from_depot [depot_user]/src/posix +import_from_depot [depot_user]/src/protobuf +import_from_depot [depot_user]/src/libssl +import_from_depot [depot_user]/src/report_rom +import_from_depot [depot_user]/src/stdcxx +import_from_depot [depot_user]/src/vfs +import_from_depot [depot_user]/src/vfs_lwip +import_from_depot [depot_user]/src/zlib + + +set build_components { + test/grpc/server + test/grpc/client +} + + +build $build_components + + +set nic_router_reporting 0 + + +set config { + + + + + + + + + + + + + + + + +} +append_if $nic_router_reporting config { + + + + + + + + + +} +append config { + + + + } +append_if $nic_router_reporting config { + } +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2000-01-01 00:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + + +install_config $config + + +set boot_modules { + grpc_server + grpc_client + grpc.lib.so + libc_pipe.lib.so +} + + +append qemu_args " -nographic " + + +build_boot_image $boot_modules + + +run_genode_until {.*Error: thread 'runner' tried to self de-struct - sleeping forever.} 300 diff --git a/run/grpc.run b/run/grpc.run index 3ba0a0d..9247bc2 100644 --- a/run/grpc.run +++ b/run/grpc.run @@ -1,7 +1,7 @@ create_boot_directory -import_from_depot [depot_user]/src/[base_src] +# import_from_depot [depot_user]/src/[base_src] import_from_depot [depot_user]/src/dynamic_rom import_from_depot [depot_user]/src/init import_from_depot [depot_user]/src/libc @@ -14,10 +14,13 @@ import_from_depot [depot_user]/src/report_rom import_from_depot [depot_user]/src/stdcxx import_from_depot [depot_user]/src/vfs import_from_depot [depot_user]/src/vfs_lwip +import_from_depot [depot_user]/src/vfs_lxip import_from_depot [depot_user]/src/zlib set build_components { + core + timer test/grpc/server test/grpc/client } @@ -35,6 +38,7 @@ set config { + @@ -102,6 +106,7 @@ append config { + @@ -110,8 +115,8 @@ append config { - - + + @@ -135,6 +140,7 @@ append config { + @@ -143,8 +149,8 @@ append config { - - + + @@ -158,8 +164,8 @@ append config { - - + + @@ -176,13 +182,13 @@ append config { - + - + @@ -197,8 +203,11 @@ install_config $config set boot_modules { + core + timer grpc_server grpc_client + ld.lib.so grpc.lib.so libc_pipe.lib.so } diff --git a/src/test/grpc/client/greeter_client.cc b/src/test/grpc/client/greeter_client.cc new file mode 100644 index 0000000..62b07c7 --- /dev/null +++ b/src/test/grpc/client/greeter_client.cc @@ -0,0 +1,95 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + + + std::cout << "GreeterClient started" << std::endl; + for (auto i = 0; i < 100; i++) { + std::shared_ptr channel { grpc::CreateChannel( + "10.10.10.55:50051", grpc::InsecureChannelCredentials()) }; + GreeterClient greeter(channel); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter " << i << " received: " << reply << std::endl; + + grpc::experimental::ChannelResetConnectionBackoff(channel.get()); + } + std::cout << "GreeterClient stopped" << std::endl; + + return 0; +} diff --git a/src/test/grpc/client/target.mk b/src/test/grpc/client/target.mk index 44b2c17..4238030 100644 --- a/src/test/grpc/client/target.mk +++ b/src/test/grpc/client/target.mk @@ -17,7 +17,6 @@ SRC_CC := greeter_client.cc SRC_CC += helloworld.pb.cc SRC_CC += helloworld.grpc.pb.cc -vpath greeter_client.cc $(GRPC_DIR)/examples/cpp/helloworld vpath helloworld.proto $(PROTO_DIR) $(SRC_CC): helloworld.grpc.pb.h diff --git a/src/test/grpc/server/greeter_server.cc b/src/test/grpc/server/greeter_server.cc index 36fd7c4..af9b728 100644 --- a/src/test/grpc/server/greeter_server.cc +++ b/src/test/grpc/server/greeter_server.cc @@ -49,8 +49,7 @@ class GreeterServiceImpl final : public Greeter::Service { } }; -void RunServer() { - std::string server_address("10.10.10.55:50051"); +void RunServer(const char* server_address) { GreeterServiceImpl service; ServerBuilder builder; diff --git a/src/test/grpc/server/greeter_server.h b/src/test/grpc/server/greeter_server.h index 1dc0617..f56095c 100644 --- a/src/test/grpc/server/greeter_server.h +++ b/src/test/grpc/server/greeter_server.h @@ -1,4 +1,4 @@ #pragma once -void RunServer(); +void RunServer(const char* server_address); diff --git a/src/test/grpc/server/main.cc b/src/test/grpc/server/main.cc index b2bff57..d5b472a 100644 --- a/src/test/grpc/server/main.cc +++ b/src/test/grpc/server/main.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "greeter_server.h" enum { STACK_SIZE = 0xF000 }; @@ -10,37 +11,32 @@ enum { STACK_SIZE = 0xF000 }; namespace Grpc_server { using namespace Genode; - class Runner; class Server_main; } -class Grpc_server::Runner : public Thread +static void *start_func(void* envp) { - public: - Runner(Env& env) - : Thread(env, "runner", STACK_SIZE) - { - } + Genode::Env& env = *(reinterpret_cast(envp)); + Genode::Attached_rom_dataspace config { env, "config" }; + Genode::String<256> server_address = config.xml().attribute_value("server_address", Genode::String<256>("0.0.0.0:8899")); + Libc::with_libc([&] () { + RunServer(server_address.string()); + }); - void entry() override - { - Libc::with_libc([] () { - RunServer(); - }); - } -}; + return nullptr; +} class Grpc_server::Server_main { private: Env& _env; - Runner _runner { _env }; + pthread_t _t; public: Server_main(Env& env) : _env(env) { - _runner.start(); + pthread_create(&_t, 0, start_func, &env); } };