From 5a02ed2f3505f5ed3282c6b43963e19e63e49905 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Tue, 25 Aug 2015 15:47:29 +0200 Subject: Fix ethread events with timeout Lots of pthread platforms unnecessarily falled back on the pipe/select solution. This since we tried to use the same monotonic clock source for pthread_cond_timedwait() as used by OS monotonic time. This has been fixed on most platforms by using another clock source. Darwin can however not use pthread_cond_timedwait() with monotonic clock source and has to use the pipe/select solution. On darwin we now use select with _DARWIN_UNLIMITED_SELECT in order to be able to handle a large amount of file descriptors. --- erts/emulator/beam/erl_process.c | 7 ++++++- erts/emulator/beam/erl_threads.h | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index ee1dd36d48..58698173be 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -7938,11 +7938,16 @@ sched_thread_func(void *vesdp) ErtsThrPrgrCallbacks callbacks; ErtsSchedulerData *esdp = vesdp; Uint no = esdp->no; +#ifdef ERTS_SMP + erts_tse_t *tse; +#endif erts_sched_init_time_sup(esdp); #ifdef ERTS_SMP - ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = erts_tse_fetch(); + tse = erts_tse_fetch(); + erts_tse_prepare_timed(tse); + ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = tse; callbacks.arg = (void *) esdp->ssi; callbacks.wakeup = thr_prgr_wakeup; callbacks.prepare_wait = thr_prgr_prep_wait; diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 5347979372..34f91e2ec8 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -649,6 +649,7 @@ ERTS_GLB_INLINE void erts_tsd_set(erts_tsd_key_t key, void *value); ERTS_GLB_INLINE void * erts_tsd_get(erts_tsd_key_t key); ERTS_GLB_INLINE erts_tse_t *erts_tse_fetch(void); ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep); +ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep); ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep); ERTS_GLB_INLINE void erts_tse_reset(erts_tse_t *ep); ERTS_GLB_INLINE int erts_tse_wait(erts_tse_t *ep); @@ -3461,6 +3462,15 @@ ERTS_GLB_INLINE void erts_tse_return(erts_tse_t *ep) #endif } +ERTS_GLB_INLINE void erts_tse_prepare_timed(erts_tse_t *ep) +{ +#ifdef USE_THREADS + int res = ethr_event_prepare_timed(&((ethr_ts_event *) ep)->event); + if (res != 0) + erts_thr_fatal_error(res, "prepare timed"); +#endif +} + ERTS_GLB_INLINE void erts_tse_set(erts_tse_t *ep) { #ifdef USE_THREADS -- cgit v1.2.3