From 8f6397bf0710174d701514c38d9ffe19c752d9e8 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 (cherry picked from commit 55170581c4179d37d42c6e0975b290ee08dd14d0) --- 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 58babfef63..a6d283544d 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; } @@ -2185,17 +2185,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 b2fa5444eb..1bf70cf146 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -2349,7 +2349,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); @@ -2386,7 +2386,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 c14af07bec..45f3257401 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -2883,7 +2883,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 e924d9476b..547bad1b46 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);