win32: reduce allocation in the scheduler

It's not clear that the changes affect anything in practice,
but they avoid unnecessary allocation and quadratic behavior
in principle.
This commit is contained in:
Matthew Flatt 2014-09-05 14:58:52 -06:00
parent 3e8ef82c55
commit bc48e9b935
4 changed files with 61 additions and 23 deletions

View File

@ -3248,7 +3248,11 @@ static void ffi_call_in_orig_place(ffi_cif *cif, void *c_func, intptr_t cfoff,
void *sh; void *sh;
int ready; int ready;
todo = (FFI_Orig_Place_Call *)malloc(sizeof(FFI_Orig_Place_Call)); if (cached_orig_place_todo) {
todo = cached_orig_place_todo;
cached_orig_place_todo = NULL;
} else
todo = (FFI_Orig_Place_Call *)malloc(sizeof(FFI_Orig_Place_Call));
sh = scheme_get_signal_handle(); sh = scheme_get_signal_handle();
todo->signal_handle = sh; todo->signal_handle = sh;
todo->needs_queue = 1; todo->needs_queue = 1;
@ -3299,7 +3303,10 @@ static void ffi_call_in_orig_place(ffi_cif *cif, void *c_func, intptr_t cfoff,
if (!todo->signal_handle) { if (!todo->signal_handle) {
/* Done */ /* Done */
mzrt_mutex_unlock(orig_place_mutex); mzrt_mutex_unlock(orig_place_mutex);
free(todo); if (!cached_orig_place_todo)
cached_orig_place_todo = todo;
else
free(todo);
break; break;
} else { } else {
/* Pause to allow actions such as a master GC.... */ /* Pause to allow actions such as a master GC.... */

View File

@ -359,6 +359,7 @@ typedef struct Thread_Local_Variables {
int atomic_timeout_atomic_level_; int atomic_timeout_atomic_level_;
void *scheme_inotify_server_; void *scheme_inotify_server_;
struct Scheme_Object *configuration_callback_cache_[2]; struct Scheme_Object *configuration_callback_cache_[2];
struct FFI_Orig_Place_Call *cached_orig_place_todo_;
} Thread_Local_Variables; } Thread_Local_Variables;
#if defined(IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS) #if defined(IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS)
@ -743,7 +744,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
#define atomic_timeout_atomic_level XOA (scheme_get_thread_local_variables()->atomic_timeout_atomic_level_) #define atomic_timeout_atomic_level XOA (scheme_get_thread_local_variables()->atomic_timeout_atomic_level_)
#define scheme_inotify_server XOA (scheme_get_thread_local_variables()->scheme_inotify_server_) #define scheme_inotify_server XOA (scheme_get_thread_local_variables()->scheme_inotify_server_)
#define configuration_callback_cache XOA (scheme_get_thread_local_variables()->configuration_callback_cache_) #define configuration_callback_cache XOA (scheme_get_thread_local_variables()->configuration_callback_cache_)
#define cached_orig_place_todo XOA (scheme_get_thread_local_variables()->cached_orig_place_todo_)
/* **************************************** */ /* **************************************** */

View File

@ -1156,7 +1156,7 @@ static void reset_wait_array(win_extended_fd_set *efd)
/* Allocate an array that may be big enough to hold all events /* Allocate an array that may be big enough to hold all events
when we eventually call WaitForMultipleObjects. One of the three when we eventually call WaitForMultipleObjects. One of the three
arrays will be big enough. */ arrays will be big enough. */
int sz = (3 * (SCHEME_INT_VAL(efd->alloc) + SCHEME_INT_VAL(efd->num_handles))) + 2; int sz = (3 * (SCHEME_INT_VAL(efd->alloc) + SCHEME_INT_VAL(efd->alloc_handles))) + 2;
HANDLE *wa; HANDLE *wa;
wa = MALLOC_N_ATOMIC(HANDLE, sz); wa = MALLOC_N_ATOMIC(HANDLE, sz);
efd->wait_array = wa; efd->wait_array = wa;
@ -1170,16 +1170,27 @@ void *scheme_init_fdset_array(void *fdarray, int count)
int i; int i;
win_extended_fd_set *fd; win_extended_fd_set *fd;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
int reset = 0;
fd = (win_extended_fd_set *)scheme_get_fdset(fdarray, i); fd = (win_extended_fd_set *)scheme_get_fdset(fdarray, i);
fd->sockets = NULL;
fd->added = scheme_make_integer(0); fd->added = scheme_make_integer(0);
fd->alloc = scheme_make_integer(0); if (SCHEME_INT_VAL(fd->alloc) > (2 * SCHEME_INT_VAL(fd->last_alloc))) {
fd->handles = NULL; fd->alloc = scheme_make_integer(0);
fd->sockets = NULL;
reset = 1;
}
fd->last_alloc = scheme_make_integer(0);
fd->num_handles = scheme_make_integer(0); fd->num_handles = scheme_make_integer(0);
if (SCHEME_INT_VAL(fd->alloc_handles) > (2 * SCHEME_INT_VAL(fd->last_alloc_handles))) {
fd->alloc_handles = scheme_make_integer(0);
fd->handles = NULL;
fd->repost_sema = NULL;
reset = 1;
}
fd->last_alloc_handles = scheme_make_integer(0);
fd->no_sleep = NULL; fd->no_sleep = NULL;
fd->wait_event_mask = scheme_make_integer(0); fd->wait_event_mask = scheme_make_integer(0);
fd->wait_array = NULL; if (reset)
reset_wait_array(fdarray); reset_wait_array(fdarray);
} }
} }
# endif # endif
@ -1224,14 +1235,23 @@ void scheme_fdclr(void *fd, int n)
#endif #endif
} }
#if defined(WIN32_FD_HANDLES)
static int next_size(int v) { return (v ? (2 * v) : 10); }
#endif
void scheme_fdset(void *fd, int n) void scheme_fdset(void *fd, int n)
{ {
#if defined(WIN32_FD_HANDLES) #if defined(WIN32_FD_HANDLES)
win_extended_fd_set *efd = (win_extended_fd_set *)fd; win_extended_fd_set *efd = (win_extended_fd_set *)fd;
if (SCHEME_INT_VAL(efd->added) >= SCHEME_INT_VAL(efd->last_alloc)) {
int na;
na = next_size(SCHEME_INT_VAL(efd->last_alloc));
efd->last_alloc = scheme_make_integer(na);
}
if (SCHEME_INT_VAL(efd->added) >= SCHEME_INT_VAL(efd->alloc)) { if (SCHEME_INT_VAL(efd->added) >= SCHEME_INT_VAL(efd->alloc)) {
SOCKET *naya; SOCKET *naya;
int na; int na;
na = (SCHEME_INT_VAL(efd->alloc) * 2) + 10; na = next_size(SCHEME_INT_VAL(efd->alloc));
naya = (SOCKET *)scheme_malloc_atomic(na * sizeof(SOCKET)); naya = (SOCKET *)scheme_malloc_atomic(na * sizeof(SOCKET));
memcpy(naya, efd->sockets, SCHEME_INT_VAL(efd->alloc) * sizeof(SOCKET)); memcpy(naya, efd->sockets, SCHEME_INT_VAL(efd->alloc) * sizeof(SOCKET));
efd->sockets = naya; efd->sockets = naya;
@ -1361,21 +1381,28 @@ void scheme_add_fd_handle(void *h, void *fds, int repost)
#if defined(WIN32_FD_HANDLES) #if defined(WIN32_FD_HANDLES)
win_extended_fd_set *efd = (win_extended_fd_set *)fds; win_extended_fd_set *efd = (win_extended_fd_set *)fds;
OS_SEMAPHORE_TYPE *hs; OS_SEMAPHORE_TYPE *hs;
int i, *rps; int i, new_i, *rps;
i = SCHEME_INT_VAL(efd->num_handles); if (SCHEME_INT_VAL(efd->num_handles) == SCHEME_INT_VAL(efd->last_alloc_handles)) {
hs = MALLOC_N_ATOMIC(OS_SEMAPHORE_TYPE, i + 1); i = next_size(SCHEME_INT_VAL(efd->last_alloc_handles));
rps = MALLOC_N_ATOMIC(int, i + 1); efd->last_alloc_handles = scheme_make_integer(1);
hs[i] = (OS_SEMAPHORE_TYPE)h;
rps[i] = repost;
while (i--) {
hs[i] = efd->handles[i];
rps[i] = efd->repost_sema[i];
} }
if (SCHEME_INT_VAL(efd->num_handles) == SCHEME_INT_VAL(efd->alloc_handles)) {
i = SCHEME_INT_VAL(efd->alloc_handles);
new_i = next_size(i);
hs = MALLOC_N_ATOMIC(OS_SEMAPHORE_TYPE, new_i);
rps = MALLOC_N_ATOMIC(int, new_i);
memcpy(hs, efd->handles, sizeof(OS_SEMAPHORE_TYPE)*i);
memcpy(rps, efd->repost_sema, sizeof(int)*i);
efd->handles = hs;
efd->repost_sema = rps;
efd->alloc_handles = scheme_make_integer(new_i);
reset_wait_array(efd);
}
i = SCHEME_INT_VAL(efd->num_handles);
efd->handles[i] = (OS_SEMAPHORE_TYPE)h;
efd->repost_sema[i] = repost;
efd->num_handles = scheme_make_integer(1 + SCHEME_INT_VAL(efd->num_handles)); efd->num_handles = scheme_make_integer(1 + SCHEME_INT_VAL(efd->num_handles));
efd->handles = hs;
efd->repost_sema = rps;
reset_wait_array(efd);
#else #else
/* Do nothing. */ /* Do nothing. */
#endif #endif
@ -10444,7 +10471,7 @@ static void clean_up_wait(intptr_t result, OS_SEMAPHORE_TYPE *array,
ReleaseSemaphore(array[result], 1, NULL); ReleaseSemaphore(array[result], 1, NULL);
} }
/* Clear out break semaphore */ /* Clear out break semaphore */
WaitForSingleObject((HANDLE)scheme_break_semaphore, 0); WaitForSingleObject((HANDLE)scheme_break_semaphore, 0);
} }

View File

@ -8,8 +8,11 @@ typedef struct {
Scheme_Object *added; /* fixnum */ Scheme_Object *added; /* fixnum */
Scheme_Object *alloc; /* fixnum */ Scheme_Object *alloc; /* fixnum */
Scheme_Object *last_alloc; /* fixnum */
Scheme_Object *num_handles; /* fixnum */ Scheme_Object *num_handles; /* fixnum */
Scheme_Object *alloc_handles; /* fixnum */
Scheme_Object *last_alloc_handles; /* fixnum */
OS_SEMAPHORE_TYPE *handles; OS_SEMAPHORE_TYPE *handles;
int *repost_sema; int *repost_sema;