diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index d962e894153..99f521656e8 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -67,6 +67,17 @@ struct frame_glue_fns; static size_t const TIME_SLICE_IN_MS = 10; +// This helps our preemption scheme handle "running on valgrind". + +#if defined(__WIN32__) +#define YIELD_C_THREAD_IF_ON_VALGRIND (void); +#else +#define YIELD_C_THREAD_IF_ON_VALGRIND \ + if (RUNNING_ON_VALGRIND) { \ + pthread_yield(); \ + } +#endif + // Every reference counted object should derive from this base class. template diff --git a/src/rt/rust_timer.cpp b/src/rt/rust_timer.cpp index bf4d18e836d..9427ec673ff 100644 --- a/src/rt/rust_timer.cpp +++ b/src/rt/rust_timer.cpp @@ -32,10 +32,9 @@ timer_loop(void *ptr) { rust_dom *dom = timer->dom; dom->log(rust_log::TIMER, "in timer 0x%" PRIxPTR, (uintptr_t)timer); size_t ms = TIME_SLICE_IN_MS; - if (!RUNNING_ON_VALGRIND) - ms = 1; while (!timer->exit_flag) { + YIELD_C_THREAD_IF_ON_VALGRIND; #if defined(__WIN32__) Sleep(ms); #else @@ -66,8 +65,6 @@ rust_timer::rust_timer(rust_dom *dom) : pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&thread, &attr, timer_loop, (void *)this); - if (RUNNING_ON_VALGRIND) - usleep(10000); #endif } diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 1aaf89fba97..e931fc9b7f6 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -1,21 +1,24 @@ #include "rust_internal.h" +#include "valgrind.h" // Upcalls. #ifdef __GNUC__ #define LOG_UPCALL_ENTRY(task) \ + YIELD_C_THREAD_IF_ON_VALGRIND; \ (task)->dom->get_log().reset_indent(0); \ (task)->log(rust_log::UPCALL, \ "> UPCALL %s - task: 0x%" PRIxPTR \ - " retpc: x%" PRIxPTR, \ + " retpc: x%" PRIxPTR, \ __FUNCTION__, \ (task), __builtin_return_address(0)); \ (task)->dom->get_log().indent(); #else #define LOG_UPCALL_ENTRY(task) \ + YIELD_C_THREAD_IF_ON_VALGRIND; \ (task)->dom->get_log().reset_indent(0); \ (task)->log(rust_log::UPCALL, \ - "> UPCALL task: x%" PRIxPTR (task)); \ + "> UPCALL task: x%" PRIxPTR (task)); \ (task)->dom->get_log().indent(); #endif diff --git a/src/test/run-pass/preempt.rs b/src/test/run-pass/preempt.rs index 00fc29cae72..ee37bcf44bf 100644 --- a/src/test/run-pass/preempt.rs +++ b/src/test/run-pass/preempt.rs @@ -18,7 +18,7 @@ io fn main() { log "main waiting for alive signal"; i <- alive; log "main got alive signal"; - while (i < 1000) { + while (i < 50) { log "main iterated"; i += 1; }