From 55170581c4179d37d42c6e0975b290ee08dd14d0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Nov 2012 12:56:09 -0600 Subject: [PATCH] fix locking for futures on uniprocessors The scheme_is_multiprocessor() function wasn't the right guard for whether to use a locking compare-and-swap instruction; any use of pthread-based futures needs the compare-and-swap. Merge to v5.3.1 --- src/racket/src/future.c | 19 ++++++++----------- src/racket/src/hash.c | 4 +--- src/racket/src/jitcommon.c | 4 ++-- src/racket/src/jitinline.c | 2 +- src/racket/src/schpriv.h | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 77a12fc9c6..2028c5006f 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -156,7 +156,7 @@ static Scheme_Object *processor_count(int argc, Scheme_Object *argv[]) return scheme_make_integer(1); } -int scheme_is_multiprocessor(int now) +int scheme_is_multithreaded(int now) { return 0; } @@ -2195,17 +2195,14 @@ static void init_cpucount(void) #endif } -int scheme_is_multiprocessor(int now) +int scheme_is_multithreaded(int now) { - if (cpucount > 1) { - if (!now) - return 1; - else { - Scheme_Future_State *fs = scheme_future_state; - return (fs && fs->future_threads_created); - } - } else - return 0; + if (!now) + return 1; + else { + Scheme_Future_State *fs = scheme_future_state; + return (fs && fs->future_threads_created); + } } Scheme_Object *processor_count(int argc, Scheme_Object *argv[]) diff --git a/src/racket/src/hash.c b/src/racket/src/hash.c index 3df6636489..58ebf57d30 100644 --- a/src/racket/src/hash.c +++ b/src/racket/src/hash.c @@ -61,8 +61,6 @@ static void register_traversers(void); running in a future and setting flags on pairs. */ SHARED_OK static uintptr_t keygen; -XFORM_NONGCING extern int scheme_is_multiprocessor(); - XFORM_NONGCING static MZ_INLINE uintptr_t PTR_TO_LONG(Scheme_Object *o) { @@ -92,7 +90,7 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o) #endif if (!v) v = 0x1AD0; #ifdef MZ_USE_FUTURES - if (SCHEME_PAIRP(o) && scheme_is_multiprocessor(1)) { + if (SCHEME_PAIRP(o) && scheme_is_multithreaded(1)) { /* Use CAS to avoid losing a hash code due to a conflict with JIT-generated `list?' test, which itself uses CAS to set "is a list" or "not a list" flags on pairs. */ diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index a68f80cf77..c338efc6be 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -2530,7 +2530,7 @@ static int common7(mz_jit_state *jitter, void *_data) jit_ldxi_s(JIT_R2, JIT_R1, &MZ_OPT_HASH_KEY(&((Scheme_Stx *)0x0)->iso)); #ifdef MZ_USE_FUTURES - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { /* Need an atomic update in case another thread is setting a hash code on the target pair. */ ref5 = jit_bmsi_i(jit_forward(), JIT_R2, PAIR_IS_LIST); @@ -2567,7 +2567,7 @@ static int common7(mz_jit_state *jitter, void *_data) jit_ldxi_s(JIT_R2, JIT_R1, &MZ_OPT_HASH_KEY(&((Scheme_Stx *)0x0)->iso)); #ifdef MZ_USE_FUTURES /* As above: */ - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { ref5 = jit_bmsi_i(jit_forward(), JIT_R2, PAIR_IS_NON_LIST); jit_movr_i(JIT_R0, JIT_R2); jit_ori_i(JIT_R2, JIT_R2, PAIR_IS_NON_LIST); diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 1a63080d1a..a601bf54a0 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -3318,7 +3318,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int /* This is the actual CAS: */ #ifdef MZ_USE_FUTURES - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { jit_lock_cmpxchgr_l(JIT_R1, JIT_V1); /* implicitly uses JIT_R0 */ reffalse = (JNEm(jit_forward(), 0,0,0), _jit.x.pc); } else diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index e8a9f8e73d..9620c62046 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -303,7 +303,7 @@ void scheme_free_dynamic_extensions(void); void scheme_free_all_code(void); void scheme_free_ghbn_data(void); -XFORM_NONGCING int scheme_is_multiprocessor(int now); +XFORM_NONGCING int scheme_is_multithreaded(int now); /* Type readers & writers for compiled code data */ typedef Scheme_Object *(*Scheme_Type_Reader)(Scheme_Object *list);