Skip to content

Commit

Permalink
change the design to hooking of __cxa_get_globals(), so that we don't…
Browse files Browse the repository at this point in the history
… need to switch exception state
  • Loading branch information
lihuiba committed Nov 5, 2024
1 parent f51192b commit cedd27a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
16 changes: 12 additions & 4 deletions thread/test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,14 +405,22 @@ TEST(Perf, ThreadSwitchWithStandaloneTSUpdater)
return;
}

inline int std_uncaught_exceptions() {
#if __cplusplus > 201700L
return std::uncaught_exceptions();
#else
return std::uncaught_exception();
#endif
}

TEST(exception, switch)
{
class Foo {
public:
~Foo() {
LOG_INFO("before thread_yield():", VALUE(std::uncaught_exceptions()));
LOG_INFO("before thread_yield():", VALUE(std_uncaught_exceptions()));
photon::thread_yield();
LOG_INFO("after thread_yield():", VALUE(std::uncaught_exceptions()));
LOG_INFO("after thread_yield():", VALUE(std_uncaught_exceptions()));
}
};

Expand All @@ -429,8 +437,8 @@ TEST(exception, switch)
bool quit = false;
auto th = photon::thread_create11([&](){
while(!quit) {
LOG_INFO(VALUE(std::uncaught_exceptions()));
EXPECT_EQ(std::uncaught_exceptions(), 0);
LOG_INFO(VALUE(std_uncaught_exceptions()));
EXPECT_EQ(std_uncaught_exceptions(), 0);
try {
throw 3.1415926f;
} catch(...) { }
Expand Down
46 changes: 27 additions & 19 deletions thread/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ limitations under the License.
#include <thread>
#include <mutex>
#include <condition_variable>
#include <dlfcn.h>

#ifdef _WIN64
#include <processthreadsapi.h>
Expand Down Expand Up @@ -197,6 +198,7 @@ namespace photon
size_t stack_size;
// offset 96B
condition_variable cond; /* used for join */
uint64_t __gh_globals[2] = {0};

enum shift {
joinable = 0,
Expand Down Expand Up @@ -649,20 +651,33 @@ namespace photon
}

static void _photon_thread_die(thread* th) asm("_photon_thread_die");
struct __cxa_eh_globals
{
void * caughtExceptions;
unsigned int uncaughtExceptions;
struct __cxa_eh_globals {
void* caughtExceptions;
unsigned int uncaughtExceptions;
};

extern "C" __cxa_eh_globals* __cxa_get_globals (void);

static void* cxa_get_globals() asm("cxa_get_globals");

static __attribute__((used))
void* cxa_get_globals() {
return __cxa_get_globals();
inline void install_hook(void* target, void* hook) {
auto page = (uint64_t)target & ~4095UL;
int ret = mprotect((void*)page, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
assert(ret == 0); (void)ret;
*(uint16_t*)((char*)target + 0) = 0xb848; // movabs imm64 to rax
*(uint64_t*)((char*)target + 2) = (uint64_t)hook;
*(uint16_t*)((char*)target + 10) = 0xe0ff; // jmp *rax
}
inline void* install_hook(const char* sym, void* hook) {
auto addr = dlsym(RTLD_DEFAULT, sym);
assert(addr);
install_hook(addr, hook);
return addr;
}
static __cxa_eh_globals* cxa_get_globals (void) {
thread_local __cxa_eh_globals eh = {0};
return !CURRENT ? &eh : (__cxa_eh_globals*) CURRENT->__gh_globals;
}
__attribute__((constructor))
static void install_eh_globals_hook() {
install_hook("__cxa_get_globals", (void*)&cxa_get_globals);
}


#if defined(__x86_64__)
#if !defined(_WIN64)
Expand Down Expand Up @@ -826,11 +841,6 @@ R"(

DEF_ASM_FUNC(_photon_thread_stub)
R"(
sub sp, sp, #16
bl cxa_get_globals
add sp, sp, #16
str xzr, [x0, #0x0]
str wzr, [x0, #0x8]
ldp x0, x1, [x29, #0x40] //; load arg, start into x0, x1
str xzr, [x29, #0x40] //; set arg as 0
blr x1 //; start(x0)
Expand All @@ -847,7 +857,6 @@ R"(

inline void switch_context(thread* from, thread* to) {
prepare_switch(from, to);
auto exception_state = *__cxa_get_globals();
auto _t_ = to->stack.pointer_ref();
register auto f asm("x0") = from->stack.pointer_ref();
register auto t asm("x1") = _t_;
Expand All @@ -862,7 +871,6 @@ R"(
// Corouptable register, may change ,should save
"x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16",
"x17", "x18");
*__cxa_get_globals() = exception_state;
}

inline void switch_context_defer(thread* from, thread* to,
Expand Down

0 comments on commit cedd27a

Please sign in to comment.