From 86dd1d1f7dc46f1e685e3da7f60dc9e11d1c0cdf Mon Sep 17 00:00:00 2001 From: Coldwings Date: Thu, 6 Jul 2023 14:32:54 +0800 Subject: [PATCH] photon thread alloc using static object Signed-off-by: Coldwings --- common/callback.h | 8 ++-- thread/test/CMakeLists.txt | 6 ++- thread/test/test-lib-data.cpp | 85 +++++++++++++++++++++++++++++++++++ thread/thread.cpp | 33 ++++++-------- 4 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 thread/test/test-lib-data.cpp diff --git a/common/callback.h b/common/callback.h index 4b7be5ae..60d74f6a 100644 --- a/common/callback.h +++ b/common/callback.h @@ -50,12 +50,12 @@ struct Delegate : public Delegate_Base template // Function with U* as the 1st argument using UFunc = R (*)(U*, Ts...); - Delegate(void* obj, Func func) { bind(obj, func); } - Delegate(Func func, void* obj) { bind(obj, func); } - Delegate(Func0 func0) { bind(func0); } + constexpr Delegate(void* obj, Func func) : _obj(obj), _func(func) {} + constexpr Delegate(Func func, void* obj) : _obj(obj), _func(func) {} + constexpr Delegate(Func0 func0) : _obj(nullptr), _func((Func&)func0) {} template - Delegate(U* obj, UFunc func) { bind(obj, func); } + constexpr Delegate(U* obj, UFunc func) : _obj(obj), _func((Func&)func) {} template Delegate(U* obj, UMFunc func) { bind(obj, func); } diff --git a/thread/test/CMakeLists.txt b/thread/test/CMakeLists.txt index 32fbd141..9a2d0218 100644 --- a/thread/test/CMakeLists.txt +++ b/thread/test/CMakeLists.txt @@ -28,4 +28,8 @@ add_test(NAME test-tls-order-native COMMAND $ add_executable(test-tls-order-photon test-tls-order-photon.cpp) target_link_libraries(test-tls-order-photon PRIVATE photon_shared ${testing_libs}) -add_test(NAME test-tls-order-photon COMMAND $) \ No newline at end of file +add_test(NAME test-tls-order-photon COMMAND $) + +add_executable(test-lib-data test-lib-data.cpp) +target_link_libraries(test-lib-data PRIVATE photon_shared ${testing_libs}) +add_test(NAME test-lib-data COMMAND $) \ No newline at end of file diff --git a/thread/test/test-lib-data.cpp b/thread/test/test-lib-data.cpp new file mode 100644 index 00000000..110fe2da --- /dev/null +++ b/thread/test/test-lib-data.cpp @@ -0,0 +1,85 @@ +/* +Copyright 2022 The Photon 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 +#include +#include + +bool popen_test(const std::string& cmd, int expect = 0) { + puts(cmd.c_str()); + auto p = popen(cmd.c_str(), "r"); + char buffer[4096]; + while (fgets(buffer, sizeof(buffer), p) != NULL) + ; + auto r = pclose(p); + if (WIFEXITED(r)) return WEXITSTATUS(r) == expect; + puts("Not exit"); + return false; +} + +std::string popen_read(const std::string& cmd, int expect = 0) { + std::string ret; + puts(cmd.c_str()); + auto p = popen(cmd.c_str(), "r"); + char buffer[4096]; + while (fgets(buffer, sizeof(buffer), p) != NULL) { + ret += buffer; + puts(buffer); + } + pclose(p); + return ret; +} + +std::string libpath(uint64_t pid) { + auto path = + popen_read("cat /proc/" + std::to_string(pid) + + "/maps | grep libphoton | tr -s ' ' | cut -f 6 -d ' '" + " | head -n 1"); + EXPECT_FALSE(path.empty()); + char* tp = strdup(path.c_str()); + path = dirname(tp); + puts(path.c_str()); + free(tp); + return path; +} + +TEST(static_lib, photon_thread_alloc) { + auto pid = getpid(); + auto p = libpath(pid) + "/libphoton.a"; + EXPECT_TRUE(popen_test("objdump -tr \"" + p + + "\" | grep photon_thread_allocE | grep .data")); + EXPECT_TRUE(popen_test("objdump -tr \"" + p + + "\" | grep photon_thread_deallocE | grep .data")); +} + +TEST(shared_lib, photon_thread_alloc) { + auto pid = getpid(); + auto p = libpath(pid) + "/libphoton.so"; + EXPECT_TRUE(popen_test("objdump -tr \"" + p + + "\" | grep photon_thread_allocE | grep .data")); + EXPECT_TRUE(popen_test("objdump -tr \"" + p + + "\" | grep photon_thread_deallocE | grep .data")); +} + +int main(int argc, char** argv) { + photon::init(photon::INIT_EVENT_NONE, 0); + DEFER(photon::fini()); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/thread/thread.cpp b/thread/thread.cpp index 4a105262..e4d71fab 100644 --- a/thread/thread.cpp +++ b/thread/thread.cpp @@ -130,17 +130,10 @@ namespace photon free(ptr); } - Delegate &photon_thread_alloc() { - static Delegate _photon_thread_alloc( - &default_photon_thread_stack_alloc, nullptr); - return _photon_thread_alloc; - } - - Delegate &photon_thread_dealloc() { - static Delegate _photon_thread_dealloc( - &default_photon_thread_stack_dealloc, nullptr); - return _photon_thread_dealloc; - } + static Delegate photon_thread_alloc( + &default_photon_thread_stack_alloc, nullptr); + static Delegate photon_thread_dealloc( + &default_photon_thread_stack_dealloc, nullptr); struct vcpu_t; struct thread; @@ -290,7 +283,7 @@ namespace photon assert(state == states::DONE); // `buf` and `stack_size` will always store on register // when calling deallocating. - photon_thread_dealloc()(buf, stack_size); + photon_thread_dealloc(buf, stack_size); } }; @@ -845,7 +838,7 @@ R"( LOG_ERROR_RETURN(ENOSYS, nullptr, "Photon not initialized in this vCPU (OS thread)"); size_t randomizer = (rand() % 32) * (1024 + 8); stack_size = align_up(randomizer + stack_size + sizeof(thread), PAGE_SIZE); - char *ptr = (char *)photon_thread_alloc()(stack_size); + char* ptr = (char*)photon_thread_alloc(stack_size); auto p = ptr + stack_size - sizeof(thread) - randomizer; (uint64_t&)p &= ~63; auto th = new (p) thread; @@ -1815,13 +1808,6 @@ R"( return --_n_vcpu; } - void set_photon_thread_stack_allocator( - Delegate _photon_thread_alloc, - Delegate _photon_thread_dealloc) { - photon_thread_alloc() = _photon_thread_alloc; - photon_thread_dealloc() = _photon_thread_dealloc; - } - void* stackful_malloc(size_t size) { return CURRENT->stackful_malloc(size); } @@ -1829,4 +1815,11 @@ R"( void stackful_free(void* ptr) { CURRENT->stackful_free(ptr); } + + void set_photon_thread_stack_allocator( + Delegate _photon_thread_alloc, + Delegate _photon_thread_dealloc) { + photon_thread_alloc = _photon_thread_alloc; + photon_thread_dealloc = _photon_thread_dealloc; + } }