From f4af39b60e09faae16acc99d3f389c79afb1b115 Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Fri, 28 Aug 2009 21:46:47 +0100 Subject: [PATCH] thread_id is a pthread_t on unix --- vm/factor.cpp | 15 ++++----------- vm/factor.hpp | 2 ++ vm/main-unix.cpp | 1 + vm/main-windows-nt.cpp | 1 + vm/os-macosx.mm | 2 +- vm/os-unix.cpp | 20 ++++++++++++++++++-- vm/os-unix.hpp | 6 +++++- vm/os-windows-nt.cpp | 25 ++++++++++++++++++++++--- vm/os-windows-nt.hpp | 6 +++++- vm/vm.hpp | 16 ++++++++-------- 10 files changed, 67 insertions(+), 27 deletions(-) diff --git a/vm/factor.cpp b/vm/factor.cpp index 741800f8d1..4ef4d11796 100755 --- a/vm/factor.cpp +++ b/vm/factor.cpp @@ -5,19 +5,11 @@ namespace factor factorvm *vm; -unordered_map thread_vms; - -factorvm *lookup_vm(unsigned long threadid) +void init_globals() { - return thread_vms[threadid]; + init_platform_globals(); } -void register_vm(unsigned long threadid, factorvm *thevm) -{ - thread_vms[threadid] = thevm; -} - - void factorvm::default_parameters(vm_parameters *p) { p->image_path = NULL; @@ -217,7 +209,6 @@ void factorvm::factor_sleep(long us) void factorvm::start_standalone_factor(int argc, vm_char **argv) { - register_vm(thread_id(),this); vm_parameters p; default_parameters(&p); init_parameters_from_args(&p,argc,argv); @@ -234,6 +225,7 @@ struct startargs { void* start_standalone_factor_thread(void *arg) { factorvm *newvm = new factorvm; + register_vm_with_thread(newvm); startargs *args = (startargs*) arg; newvm->start_standalone_factor(args->argc, args->argv); return 0; @@ -244,6 +236,7 @@ VM_C_API void start_standalone_factor(int argc, vm_char **argv) { factorvm *newvm = new factorvm; vm = newvm; + register_vm_with_thread(newvm); return newvm->start_standalone_factor(argc,argv); } diff --git a/vm/factor.hpp b/vm/factor.hpp index 46662072b5..5f41c952e1 100644 --- a/vm/factor.hpp +++ b/vm/factor.hpp @@ -1,6 +1,8 @@ namespace factor { +VM_C_API void init_globals(); + VM_C_API void start_standalone_factor(int argc, vm_char **argv); VM_C_API THREADHANDLE start_standalone_factor_in_new_thread(int argc, vm_char **argv); } diff --git a/vm/main-unix.cpp b/vm/main-unix.cpp index bc605e3cfd..b8914e2bd3 100644 --- a/vm/main-unix.cpp +++ b/vm/main-unix.cpp @@ -2,6 +2,7 @@ int main(int argc, char **argv) { + factor::init_globals(); factor::start_standalone_factor(argc,argv); return 0; } diff --git a/vm/main-windows-nt.cpp b/vm/main-windows-nt.cpp index 2120717d86..df4a1172f1 100644 --- a/vm/main-windows-nt.cpp +++ b/vm/main-windows-nt.cpp @@ -16,6 +16,7 @@ int WINAPI WinMain( return 1; } + factor::init_globals(); #ifdef FACTOR_MULTITHREADED factor::THREADHANDLE thread = factor::start_standalone_factor_in_new_thread(nArgs,szArglist); WaitForSingleObject(thread, INFINITE); diff --git a/vm/os-macosx.mm b/vm/os-macosx.mm index e4da7b2221..7f692def06 100644 --- a/vm/os-macosx.mm +++ b/vm/os-macosx.mm @@ -5,7 +5,7 @@ namespace factor { -void c_to_factor_toplevel(cell quot) +void factorvm::c_to_factor_toplevel(cell quot) { for(;;) { diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index 4cee04a11b..7913647f3e 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -17,10 +17,26 @@ THREADHANDLE start_thread(void *(*start_routine)(void *),void *args) return thread; } -unsigned long thread_id(){ - return pthread_self(); + +pthread_key_t tlsKey = 0; + +void init_platform_globals() +{ + if (pthread_key_create(&tlsKey, NULL) != 0){ + fatal_error("pthread_key_create() failed",0); + } + } +void register_vm_with_thread(factorvm *vm) +{ + pthread_setspecific(tlsKey,vm); +} + +factorvm *tls_vm() +{ + return (factorvm*)pthread_getspecific(tlsKey); +} static void *null_dll; diff --git a/vm/os-unix.hpp b/vm/os-unix.hpp index e3e207f641..5f84106f97 100644 --- a/vm/os-unix.hpp +++ b/vm/os-unix.hpp @@ -45,7 +45,7 @@ typedef char symbol_char; typedef pthread_t THREADHANDLE; THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); -unsigned long thread_id(); +pthread_t thread_id(); void unix_init_signals(); void signal_handler(int signal, siginfo_t* siginfo, void* uap); @@ -54,5 +54,9 @@ void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap); s64 current_micros(); void sleep_micros(cell usec); +void init_platform_globals(); +struct factorvm; +void register_vm_with_thread(factorvm *vm); +factorvm *tls_vm(); void open_console(); } diff --git a/vm/os-windows-nt.cpp b/vm/os-windows-nt.cpp index fbaadaaba7..ee00e1434a 100755 --- a/vm/os-windows-nt.cpp +++ b/vm/os-windows-nt.cpp @@ -3,12 +3,31 @@ namespace factor { + THREADHANDLE start_thread(void *(*start_routine)(void *),void *args){ return (void*) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0); } -unsigned long thread_id(){ - return GetCurrentThreadId(); + +DWORD dwTlsIndex; + +void init_platform_globals() +{ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) { + fatal_error("TlsAlloc failed - out of indexes",0); + } +} + +void register_vm_with_thread(factorvm *vm) +{ + if (! TlsSetValue(dwTlsIndex, vm)) { + fatal_error("TlsSetValue failed",0); + } +} + +factorvm *tls_vm() +{ + return (factorvm*)TlsGetValue(dwTlsIndex); } @@ -22,7 +41,7 @@ s64 current_micros() FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) { - factorvm *myvm = lookup_vm(GetCurrentThreadId()); + factorvm *myvm = SIGNAL_VM_PTR(); PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord; CONTEXT *c = (CONTEXT*)pe->ContextRecord; diff --git a/vm/os-windows-nt.hpp b/vm/os-windows-nt.hpp index 385553e11e..366348a898 100755 --- a/vm/os-windows-nt.hpp +++ b/vm/os-windows-nt.hpp @@ -29,6 +29,10 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe); typedef HANDLE THREADHANDLE; THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); -unsigned long thread_id(); + +void init_platform_globals(); +struct factorvm; +void register_vm_with_thread(factorvm *vm); +factorvm *tls_vm(); } diff --git a/vm/vm.hpp b/vm/vm.hpp index a16ff21121..b94ba16e00 100644 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -690,12 +690,11 @@ struct factorvm { }; -extern factorvm *lookup_vm(unsigned long threadid); -extern void register_vm(unsigned long threadid,factorvm *vm); +// #define FACTOR_SINGLE_THREADED_SINGLETON +#define FACTOR_SINGLE_THREADED_TESTING -#define FACTOR_SINGLE_THREADED - -#ifdef FACTOR_SINGLE_THREADED +#ifdef FACTOR_SINGLE_THREADED_SINGLETON +/* calls are dispatched using the singleton */ extern factorvm *vm; #define PRIMITIVE_GETVM() vm #define PRIMITIVE_OVERFLOW_GETVM() vm @@ -704,13 +703,14 @@ extern void register_vm(unsigned long threadid,factorvm *vm); #define SIGNAL_VM_PTR() vm #endif -#ifdef FACTOR_TESTING_MULTITHREADED +#ifdef FACTOR_SINGLE_THREADED_TESTING +/* calls are dispatched as per multithreaded, but checked against singleton */ extern factorvm *vm; #define PRIMITIVE_GETVM() ((factorvm*)myvm) #define PRIMITIVE_OVERFLOW_GETVM() vm #define VM_PTR myvm #define ASSERTVM() assert(vm==myvm) - #define SIGNAL_VM_PTR() lookup_vm(thread_id()) + #define SIGNAL_VM_PTR() tls_vm() #endif #ifdef FACTOR_MULTITHREADED @@ -718,7 +718,7 @@ extern void register_vm(unsigned long threadid,factorvm *vm); #define PRIMITIVE_OVERFLOW_GETVM() ((factorvm*)myvm) #define VM_PTR myvm #define ASSERTVM() - #define SIGNAL_VM_PTR() lookup_vm(thread_id()) + #define SIGNAL_VM_PTR() tls_vm() #endif } -- 2.34.1