futures: protect use of mfence by processor count
This commit is contained in:
parent
43cb91e6ee
commit
7ed0d4e00a
|
@ -182,7 +182,7 @@ Errors/exceptions and other kinds of control?
|
||||||
(gen-exp))]))
|
(gen-exp))]))
|
||||||
|
|
||||||
(define-namespace-anchor ns-here)
|
(define-namespace-anchor ns-here)
|
||||||
(let ([seed 587082310 #;(+ 1 (random (expt 2 30)))])
|
(let ([seed (+ 1 (random (expt 2 30)))])
|
||||||
(printf "DrDr Ignore! random-seed ~s\n" seed)
|
(printf "DrDr Ignore! random-seed ~s\n" seed)
|
||||||
(random-seed seed))
|
(random-seed seed))
|
||||||
|
|
||||||
|
|
|
@ -639,6 +639,7 @@ static void make_kernel_env(void)
|
||||||
MZTIMEIT(regexp, scheme_regexp_initialize(env));
|
MZTIMEIT(regexp, scheme_regexp_initialize(env));
|
||||||
#endif
|
#endif
|
||||||
MZTIMEIT(params, scheme_init_parameterization());
|
MZTIMEIT(params, scheme_init_parameterization());
|
||||||
|
MZTIMEIT(futures, scheme_init_futures_once());
|
||||||
MZTIMEIT(places, scheme_init_places_once());
|
MZTIMEIT(places, scheme_init_places_once());
|
||||||
|
|
||||||
MARK_START_TIME();
|
MARK_START_TIME();
|
||||||
|
|
|
@ -146,6 +146,10 @@ void scheme_init_futures(Scheme_Env *env)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scheme_init_futures_once()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "future.h"
|
#include "future.h"
|
||||||
|
@ -256,6 +260,8 @@ static future_t *enqueue_future(Scheme_Future_State *fs, future_t *ft);;
|
||||||
static future_t *get_pending_future(Scheme_Future_State *fs);
|
static future_t *get_pending_future(Scheme_Future_State *fs);
|
||||||
static void receive_special_result(future_t *f, Scheme_Object *retval, int clear);
|
static void receive_special_result(future_t *f, Scheme_Object *retval, int clear);
|
||||||
static void send_special_result(future_t *f, Scheme_Object *retval);
|
static void send_special_result(future_t *f, Scheme_Object *retval);
|
||||||
|
READ_ONLY static int cpucount;
|
||||||
|
static void init_cpucount(void);
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
# define scheme_future_setjmp(newbuf) scheme_jit_setjmp((newbuf).jb)
|
# define scheme_future_setjmp(newbuf) scheme_jit_setjmp((newbuf).jb)
|
||||||
|
@ -339,6 +345,11 @@ void scheme_init_futures(Scheme_Env *env)
|
||||||
scheme_protect_primitive_provide(newenv, NULL);
|
scheme_protect_primitive_provide(newenv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scheme_init_futures_once()
|
||||||
|
{
|
||||||
|
init_cpucount();
|
||||||
|
}
|
||||||
|
|
||||||
void futures_init(void)
|
void futures_init(void)
|
||||||
{
|
{
|
||||||
Scheme_Future_State *fs;
|
Scheme_Future_State *fs;
|
||||||
|
@ -480,6 +491,7 @@ void scheme_future_block_until_gc()
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!fs) return;
|
if (!fs) return;
|
||||||
|
if (!fs->future_threads_created) return;
|
||||||
|
|
||||||
mzrt_mutex_lock(fs->future_mutex);
|
mzrt_mutex_lock(fs->future_mutex);
|
||||||
fs->wait_for_gc = 1;
|
fs->wait_for_gc = 1;
|
||||||
|
@ -492,6 +504,11 @@ void scheme_future_block_until_gc()
|
||||||
*(fs->pool_threads[i]->stack_boundary_pointer) += INITIAL_C_STACK_SIZE;
|
*(fs->pool_threads[i]->stack_boundary_pointer) += INITIAL_C_STACK_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cpucount > 1) {
|
||||||
|
/* `cpucount' is not actually a complete test for whether mfence
|
||||||
|
should work, but the probability of someone using futures
|
||||||
|
on a multiprocessor system without SSE2 seems very low. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__asm {
|
__asm {
|
||||||
mfence
|
mfence
|
||||||
|
@ -499,6 +516,7 @@ void scheme_future_block_until_gc()
|
||||||
#else
|
#else
|
||||||
asm("mfence");
|
asm("mfence");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
mzrt_mutex_lock(fs->future_mutex);
|
mzrt_mutex_lock(fs->future_mutex);
|
||||||
while (fs->gc_not_ok) {
|
while (fs->gc_not_ok) {
|
||||||
|
@ -734,11 +752,9 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[])
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Scheme_Object *processor_count(int argc, Scheme_Object *argv[])
|
static void init_cpucount(void)
|
||||||
/* Called in runtime thread */
|
/* Called in runtime thread */
|
||||||
{
|
{
|
||||||
int cpucount = 0;
|
|
||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
cpucount = sysconf(_SC_NPROCESSORS_ONLN);
|
cpucount = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
#elif OS_X
|
#elif OS_X
|
||||||
|
@ -755,7 +771,11 @@ Scheme_Object *processor_count(int argc, Scheme_Object *argv[])
|
||||||
#else
|
#else
|
||||||
cpucount = THREAD_POOL_SIZE;
|
cpucount = THREAD_POOL_SIZE;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheme_Object *processor_count(int argc, Scheme_Object *argv[])
|
||||||
|
/* Called in runtime thread */
|
||||||
|
{
|
||||||
return scheme_make_integer(cpucount);
|
return scheme_make_integer(cpucount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,7 @@ void scheme_init_foreign(Scheme_Env *env);
|
||||||
void scheme_init_place(Scheme_Env *env);
|
void scheme_init_place(Scheme_Env *env);
|
||||||
void scheme_init_places_once();
|
void scheme_init_places_once();
|
||||||
void scheme_init_futures(Scheme_Env *env);
|
void scheme_init_futures(Scheme_Env *env);
|
||||||
|
void scheme_init_futures_once();
|
||||||
|
|
||||||
void scheme_init_print_buffers_places(void);
|
void scheme_init_print_buffers_places(void);
|
||||||
void scheme_init_string_places(void);
|
void scheme_init_string_places(void);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user