From 087d666f088f2f084c6b9f07ee389ce89f6ab604 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 May 2011 07:29:15 -0600 Subject: [PATCH] win32: fix timer-thread handling for places --- src/racket/src/mzmark_port.inc | 29 -------- src/racket/src/mzmarksrc.c | 12 ---- src/racket/src/port.c | 123 +++++++++++++++++++++------------ 3 files changed, 78 insertions(+), 86 deletions(-) diff --git a/src/racket/src/mzmark_port.inc b/src/racket/src/mzmark_port.inc index d6bd5be8de..44148216e4 100644 --- a/src/racket/src/mzmark_port.inc +++ b/src/racket/src/mzmark_port.inc @@ -1,34 +1,5 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ -#ifdef WINDOWS_PROCESSES -static int mark_thread_memory_SIZE(void *p, struct NewGC *gc) { - return - gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Memory)); -} - -static int mark_thread_memory_MARK(void *p, struct NewGC *gc) { - Scheme_Thread_Memory *tm = (Scheme_Thread_Memory *)p; - gcMARK2(tm->prev, gc); - gcMARK2(tm->next, gc); - - return - gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Memory)); -} - -static int mark_thread_memory_FIXUP(void *p, struct NewGC *gc) { - Scheme_Thread_Memory *tm = (Scheme_Thread_Memory *)p; - gcFIXUP2(tm->prev, gc); - gcFIXUP2(tm->next, gc); - - return - gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Memory)); -} - -#define mark_thread_memory_IS_ATOMIC 0 -#define mark_thread_memory_IS_CONST_SIZE 1 - -#endif - static int mark_input_file_SIZE(void *p, struct NewGC *gc) { return gcBYTES_TO_WORDS(sizeof(Scheme_Input_File)); diff --git a/src/racket/src/mzmarksrc.c b/src/racket/src/mzmarksrc.c index 90080767d2..fea9e597ef 100644 --- a/src/racket/src/mzmarksrc.c +++ b/src/racket/src/mzmarksrc.c @@ -1538,18 +1538,6 @@ END portfun; START port; -#ifdef WINDOWS_PROCESSES -mark_thread_memory { - mark: - Scheme_Thread_Memory *tm = (Scheme_Thread_Memory *)p; - gcMARK2(tm->prev, gc); - gcMARK2(tm->next, gc); - - size: - gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Memory)); -} -#endif - mark_input_file { mark: Scheme_Input_File *i = (Scheme_Input_File *)p; diff --git a/src/racket/src/port.c b/src/racket/src/port.c index 2090ef8d08..4684479760 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -1120,13 +1120,14 @@ void scheme_collapse_win_fd(void *fds) /* Racket creates Windows threads for various purposes, including non-blocking FILE reads. Unfortunately, these threads can confuse - the GC if they move virtual pages around while its marking. So we + the Boehm GC if they move virtual pages around while its marking. So we remember each created thread and suspend it during GC. This work is not necessary if GC_use_registered_statics is set. */ +#ifndef MZ_PRECISE_GC -#ifdef WINDOWS_PROCESSES +# ifdef WINDOWS_PROCESSES typedef struct Scheme_Thread_Memory { MZTAG_IF_REQUIRED void *handle; @@ -1140,22 +1141,16 @@ Scheme_Thread_Memory *tm_start, *tm_next; void scheme_init_thread_memory() { -#ifndef MZ_PRECISE_GC REGISTER_SO(tm_start); REGISTER_SO(tm_next); -#endif /* We start with a pre-allocated tm because we want to register a thread before performing any allocations. */ -#ifdef MZ_PRECISE_GC - tm_next = (Scheme_Thread_Memory *)malloc(sizeof(Scheme_Thread_Memory)); -#else tm_next = MALLOC_ONE_RT(Scheme_Thread_Memory); -#endif -#ifdef MZTAG_REQUIRED +# ifdef MZTAG_REQUIRED tm_next->type = scheme_rt_thread_memory; -#endif +# endif /* scheme_init_thread() will replace these: */ GC_set_collect_start_callback(scheme_suspend_remembered_threads); @@ -1176,14 +1171,10 @@ Scheme_Thread_Memory *scheme_remember_thread(void *t, int autoclose) tm->next->prev = tm; tm_start = tm; -#ifdef MZ_PRECISE_GC - tm_next = (Scheme_Thread_Memory *)malloc(sizeof(Scheme_Thread_Memory)); -#else tm_next = MALLOC_ONE_RT(Scheme_Thread_Memory); -#endif -#ifdef MZTAG_REQUIRED +# ifdef MZTAG_REQUIRED tm_next->type = scheme_rt_thread_memory; -#endif +# endif return tm; } @@ -1206,10 +1197,6 @@ void scheme_forget_thread(struct Scheme_Thread_Memory *tm) tm->next = NULL; tm->prev = NULL; - -#ifdef MZ_PRECISE_GC - free(tm); -#endif } void scheme_forget_subthread(struct Scheme_Thread_Memory *tm) @@ -1240,9 +1227,6 @@ void scheme_suspend_remembered_threads(void) tm->next->prev = prev; tm->next = NULL; tm->prev = NULL; -#ifdef MZ_PRECISE_GC - free(tm); -#endif keep = 0; } } @@ -1268,8 +1252,23 @@ void scheme_resume_remembered_threads(void) } } +# endif + +#else + +typedef struct Scheme_Thread_Memory Scheme_Thread_Memory; + +void scheme_init_thread_memory() { } +Scheme_Thread_Memory *scheme_remember_thread(void *t, int autoclose) { return NULL; } +void scheme_remember_subthread(struct Scheme_Thread_Memory *tm, void *t) { } +void scheme_forget_thread(struct Scheme_Thread_Memory *tm) { } +void scheme_forget_subthread(struct Scheme_Thread_Memory *tm) { } +void scheme_suspend_remembered_threads() { } +void scheme_resume_remembered_threads(void) { } + #endif + /*========================================================================*/ /* Generic port support */ /*========================================================================*/ @@ -8861,51 +8860,86 @@ int scheme_get_external_event_fd(void) #ifdef USE_WIN32_THREAD_TIMER -static HANDLE itimer; -static OS_SEMAPHORE_TYPE itimer_semaphore; -static intptr_t itimer_delay; -typedef struct { +typedef struct ITimer_Data { + int done; + HANDLE itimer; + intptr_t delay; + OS_SEMAPHORE_TYPE semaphore; + OS_SEMAPHORE_TYPE done_semaphore; int volatile *fuel_counter_ptr; uintptr_t volatile *jit_stack_boundary_ptr; -} Win_Itimer_Data; +} ITimer_Data; + +THREAD_LOCAL_DECL(static ITimer_Data *itimerdata); static long WINAPI ITimer(void *data) XFORM_SKIP_PROC { - Win_Itimer_Data *d = (Win_Itimer_Data *)data; + ITimer_Data *d = (ITimer_Data *)data; - WaitForSingleObject(itimer_semaphore, INFINITE); + WaitForSingleObject(d->semaphore, INFINITE); - scheme_init_os_thread(); - - while (1) { - if (WaitForSingleObject(itimer_semaphore, itimer_delay / 1000) == WAIT_TIMEOUT) { + while (!d->done) { + if (WaitForSingleObject(d->semaphore, d->delay / 1000) == WAIT_TIMEOUT) { *d->fuel_counter_ptr = 0; *d->jit_stack_boundary_ptr = (uintptr_t)-1; - WaitForSingleObject(itimer_semaphore, INFINITE); + if (!d->done) + WaitForSingleObject(d->semaphore, INFINITE); } } - /* scheme_done_os_thread(); */ + ReleaseSemaphore(d->done_semaphore, 1, NULL); + + return 0; } static void scheme_start_itimer_thread(intptr_t usec) { DWORD id; - if (!itimer) { - Win_Itimer_Data *d; - d = malloc(sizeof(Win_Itimer_Data)); + if (!itimerdata) { + ITimer_Data *d; + HANDLE itimer, sema; + + d = malloc(sizeof(ITimer_Data)); + memset(d, 0, sizeof(ITimer_Data)); + d->fuel_counter_ptr = &scheme_fuel_counter; d->jit_stack_boundary_ptr = &scheme_jit_stack_boundary; + + sema = CreateSemaphore(NULL, 0, 1, NULL); + d->semaphore = sema; + sema = CreateSemaphore(NULL, 0, 1, NULL); + d->done_semaphore = sema; + itimer = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)ITimer, d, 0, &id); - itimer_semaphore = CreateSemaphore(NULL, 0, 1, NULL); scheme_remember_thread(itimer, 0); + d->itimer = itimer; + + itimerdata = d; } - itimer_delay = usec; - ReleaseSemaphore(itimer_semaphore, 1, NULL); + itimerdata->delay = usec; + ReleaseSemaphore(itimerdata->semaphore, 1, NULL); +} + +static void scheme_stop_itimer_thread() +{ + ITimer_Data *d = itimerdata; + + scheme_forget_thread(d->itimer); + + d->done = 1; + ReleaseSemaphore(d->semaphore, 1, NULL); + + WaitForSingleObject(d->done_semaphore, INFINITE); + + CloseHandle(d->semaphore); + CloseHandle(d->done_semaphore); + CloseHandle(d->itimer); + + free(d); } #endif @@ -9072,6 +9106,8 @@ void scheme_kill_green_thread_timer() { #if defined(USE_PTHREAD_THREAD_TIMER) kill_green_thread_timer(); +#elif defined(USE_WIN32_THREAD_TIMER) + scheme_stop_itimer_thread(); #endif } @@ -9280,9 +9316,6 @@ START_XFORM_SKIP; static void register_traversers(void) { -#ifdef WINDOWS_PROCESSES - GC_REG_TRAV(scheme_rt_thread_memory, mark_thread_memory); -#endif GC_REG_TRAV(scheme_rt_input_file, mark_input_file); GC_REG_TRAV(scheme_rt_output_file, mark_output_file);