extern void make_timer_thread(void (*thread_fun) (void)) { UINT thread_id; #ifndef NATIVE_THREADS /* set main_thread here, then the timer thread can suspend it */ set_main_thread(); #endif timer_event = (word*) CreateEvent(NULL, /* no security */ FALSE, /* auto-reset */ FALSE, /* initially unsignalled */ NULL); /* un-named */ if (timer_event == NULL) error("CreateEvent() has failed; GetLastError() returns %u", GetLastError()); DIAGNOSTIC(4,"made timer event",0,0); timer_thread = (word*) CreateThread(NULL, /* no security */ 0, /* same stack size as main() */ (LPTHREAD_START_ROUTINE) thread_fun, (LPVOID) 0, /* thread_fun takes no arguments */ 0, /* no special creation flags */ &thread_id); if (timer_thread == NULL) error("CreateThread() has failed; GetLastError() returns %u", GetLastError()); DIAGNOSTIC(2,"made timer thread with id %d",thread_id,0); }
extern void native_make_thread(struct c_state *c_state) { DWORD thread_id; c_state->native.event = (word*) CreateEvent (NULL, /* no security */ FALSE, /* auto-reset */ FALSE, /* initially unsignalled */ NULL); /* un-named */ if (c_state->native.event == NULL) error("CreateEvent() has failed; GetLastError() returns %u", GetLastError()); DIAGNOSTIC(4,"Native threads system created new event handle 0x%x", c_state->native.event,0); c_state->native.thread = (word*) CreateThread (NULL, /* no security */ 0, /* same stack size as main() */ (LPTHREAD_START_ROUTINE) native_thread_run, (LPVOID) c_state, /* the argument to native_thread_run */ 0, /* no special creation flags */ &thread_id); if (c_state->native.thread == NULL) error ("CreateThread has failed; GetLastError() returns %u", GetLastError()); DIAGNOSTIC(4,"new native thread id %u made, handle 0x%x",thread_id, c_state->native.thread); }
static void native_thread_run(struct c_state *c_state) { void (*continuation)(void); DIAGNOSTIC(2,"starting new native thread, waiting for event",0,0); wait_for_event(c_state->native.event); continuation = (void (*)(void))c_state->eip; DIAGNOSTIC(3,"in new thread, calling continuation 0x%x",continuation,0); continuation(); }
extern void native_unmake_thread(struct c_state *c_state) { DIAGNOSTIC(2,"unmaking native thread",0,0); c_state->eip = (word)native_thread_exit; set_event(c_state->native.event); DIAGNOSTIC(3,"set event on thread to unmake, waiting on thread",0,0); wait_for_event(c_state->native.thread); DIAGNOSTIC(3,"unmade thread signalled, closing handles",0,0); close_handle(c_state->native.thread); close_handle(c_state->native.event); DIAGNOSTIC(3,"closed handles; native thread is history",0,0); }
extern void unmake_timer_thread(void) { CONTEXT timer_thread_context; BOOL result; DIAGNOSTIC(2,"unmaking timer thread",0,0); suspend_thread(timer_thread); DIAGNOSTIC(3,"timer thread suspended",0,0); timer_thread_context.ContextFlags = CONTEXT_CONTROL; result = GetThreadContext((HANDLE)timer_thread, &timer_thread_context); if (result == FALSE) error("GetThreadContext(timer) failed; GetLastError() returns %d", GetLastError()); DIAGNOSTIC(3,"timer thread context obtained",0,0); timer_thread_context.Eip = (DWORD)timer_thread_end; result = SetThreadContext((HANDLE)timer_thread, &timer_thread_context); if (result == FALSE) error("SetThreadContext(timer) failed; GetLastError() returns %d", GetLastError()); DIAGNOSTIC(3,"timer thread context set",0,0); set_event(timer_event); DIAGNOSTIC(3,"timer event set",0,0); resume_thread(timer_thread); DIAGNOSTIC(3,"timer thread resumed",0,0); wait_for_event(timer_thread); DIAGNOSTIC(3,"timer thread signalled",0,0); close_handle(timer_thread); close_handle(timer_event); DIAGNOSTIC(2,"timer thread unmade and forgotten",0,0); }
extern struct thread_state * native_thread_yield(struct thread_state *this_thread, struct thread_state *other_thread) { DIAGNOSTIC(2,"Native thread %d yielding to native thread %d", this_thread->number, other_thread->number); previous_thread = this_thread; set_event(other_thread->c_state.native.event); DIAGNOSTIC(3,"Native thread %d set event in thread %d, waiting for event", this_thread->number, other_thread->number); wait_for_event(this_thread->c_state.native.event); DIAGNOSTIC(3,"Back in native thread %d",this_thread->number,0); return previous_thread; }
int TDUniqueId::generate_unique_id() { int result; // initialize the random number generator, using time as a seed; do it here // instead of as a static variable of the class to add a little more randomness // to the seed (which uses the time) static RandomMersenne rng(time(NULL)); // generate random no. and check for duplicate; keep generating until // we find a non-duplicate; initialize found to true so that we can // test for duplicates in the loop below bool found = false; TDUIDList::iterator found_value; do { result = (int)(rng.genrand_int31()); found_value = uniqueIdList.lower_bound(result); if(found_value != uniqueIdList.end()) { found = ((*found_value).first == result); if (found) DIAGNOSTIC("Duplicate UID found - very unusual!\n"); } } while (found); return result; }
extern void native_make_top_thread(struct c_state *c_state) { HANDLE pseudo_top_thread_handle; c_state->native.event = (word*) CreateEvent (NULL, /* no security */ FALSE, /* auto-reset */ FALSE, /* initially unsignalled */ NULL); /* un-named */ if (c_state->native.event == NULL) error("CreateEvent() has failed; GetLastError() returns %u", GetLastError()); DIAGNOSTIC(4,"Native threads created event handle 0x%x for top thread", c_state->native.event,0); pseudo_top_thread_handle = GetCurrentThread(); c_state->native.thread = (word*) duplicate_handle(pseudo_top_thread_handle); DIAGNOSTIC(4,"top thread handle 0x%x obtained",c_state->native.thread,0); }
static void close_handle(word *handle) { HANDLE true_handle = (HANDLE) handle; BOOL result = CloseHandle(true_handle); if (result == FALSE) error ("CloseHandle() returned FALSE, GetLastError() gives %u\n", GetLastError()); DIAGNOSTIC(4,"native thread system closed handle 0x%x",handle,0); }
static void CALLBACK time_callback(UINT id, UINT msg, DWORD arg, DWORD dw1, DWORD dw2) { DIAGNOSTIC(4,"in timer callback, notifying timer thread",0,0); timer_event = (MMRESULT)NULL; notify_timer_thread(); }
extern void pioc_init(void) { int pid = getpid(); char filename[] = "/proc/000000"; sprintf(filename,"/proc/%d",pid); DIAGNOSTIC(2,"opening %s for process control",filename,0); self_proc_fd = open(filename, O_RDONLY); if (self_proc_fd == -1) error("error on opening process control file; errno set to %d",errno); }
extern void *os_allocator(int code, void *arg) { switch (code) { case OS_ALLOCATOR_MALLOC_ZERO: DIAGNOSTIC(4,"malloc(0)",0,0); return malloc(1); break; case OS_ALLOCATOR_REALLOC_NULL_ZERO: DIAGNOSTIC(4,"realloc(NULL,0)",0,0); return malloc(1); break; case OS_ALLOCATOR_REALLOC_P_ZERO: DIAGNOSTIC(4,"realloc(0x%08x,0)",arg,0); free(arg); return malloc(1); break; default: error("Unknown code in os_allocator"); } return NULL; }
extern word* suspend_current_thread(void) { word *thread = #ifdef NATIVE_THREADS CURRENT_THREAD->c_state.native.thread; #else main_thread; #endif suspend_thread(thread); DIAGNOSTIC(2,"suspended ML threads",0,0); return thread; }
static void time_begin(void) { MMRESULT result = timeBeginPeriod(time_resolution); switch(result) { case TIMERR_NOERROR: DIAGNOSTIC(4,"timeBeginPeriod(%d) succeeded",time_resolution,0); break; case TIMERR_NOCANDO: error("timeBeginPeriod() reports that %d resolution is not possible", time_resolution); default: error("timeBeginPeriod() returned %d",result); } }
extern void start_timer(unsigned int milliseconds) { /* would like to use TIME_CALLBACK_EVENT_SET here, but it doesn't work * on Win95 */ int tries = 0; while (tries < 10) { timer_event = timeSetEvent(milliseconds, /* how soon */ time_resolution, /* with what resolution */ (LPTIMECALLBACK) time_callback, 0, /* argument to time_callback */ TIME_ONESHOT); /* not periodic */ if (timer_event == (MMRESULT)NULL) { tries++; DIAGNOSTIC(1, "timeSetEvent() returned NULL at try %d", tries, 0); } else { DIAGNOSTIC(4,"set timer event id %d with delay of %dms", timer_event,milliseconds); break; } } if (tries >= 10) error("timeSetEvent() returned NULL"); }
static void get_min_period(void) { TIMECAPS tc; MMRESULT result = timeGetDevCaps(&tc, sizeof(TIMECAPS)); switch(result) { case TIMERR_NOERROR: DIAGNOSTIC(4,"time caps: %d min, %d max",tc.wPeriodMin,tc.wPeriodMax); break; case TIMERR_STRUCT: error("timeGetDevCaps() failed"); default: error ("timeGetDevCaps() returned %d",result); } time_resolution = tc.wPeriodMin; }
static HANDLE duplicate_handle(HANDLE handle) { HANDLE process = GetCurrentProcess(); HANDLE new_handle; BOOL result = DuplicateHandle(process, handle, process, &new_handle, 0, TRUE, DUPLICATE_SAME_ACCESS); if (result == FALSE) error("DuplicateHandle() returned FALSE, GetLastError gives %u\n", GetLastError()); DIAGNOSTIC(4,"native threads system duplicated handle 0x%08x to give 0x%08x", handle,new_handle); return new_handle; }
extern void resume_current_thread(word *thread) { DIAGNOSTIC(2,"resuming ML threads",0,0); resume_thread(thread); }
extern void notify_timer_thread(void) { DIAGNOSTIC(4,"notifying timer thread",0,0); set_event(timer_event); }
extern void timer_thread_wait(void) { DIAGNOSTIC(4,"timer thread waiting for timer event",0,0); wait_for_event(timer_event); DIAGNOSTIC(4,"timer thread received timer event",0,0); }
static void native_thread_exit(struct c_state *c_state) { DIAGNOSTIC(2,"leaving native thread",0,0); ExitThread(0); }
static void timer_thread_end(void) { DIAGNOSTIC(2,"leaving timer thread",0,0); ExitThread(0); }
static void set_main_thread(void) { HANDLE pseudo_main_thread_handle = GetCurrentThread(); main_thread = (word*) duplicate_handle(pseudo_main_thread_handle); DIAGNOSTIC(4,"main thread handle 0x%x obtained", main_thread,0); }