factorvm *vm;
-unordered_map<long,factorvm*> 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;
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);
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;
{
factorvm *newvm = new factorvm;
vm = newvm;
+ register_vm_with_thread(newvm);
return newvm->start_standalone_factor(argc,argv);
}
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);
}
int main(int argc, char **argv)
{
+ factor::init_globals();
factor::start_standalone_factor(argc,argv);
return 0;
}
return 1;
}
+ factor::init_globals();
#ifdef FACTOR_MULTITHREADED
factor::THREADHANDLE thread = factor::start_standalone_factor_in_new_thread(nArgs,szArglist);
WaitForSingleObject(thread, INFINITE);
namespace factor
{
-void c_to_factor_toplevel(cell quot)
+void factorvm::c_to_factor_toplevel(cell quot)
{
for(;;)
{
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;
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);
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();
}
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);
}
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;
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();
}
};
-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
#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
#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
}