Skip to content

Commit 12aa9de

Browse files
authored
add fenv cache to task struct (#51288)
Fixes #51277, though we give no guarantee that it keeps working this way, or that calling `setrounding_raw` won't lead to other undefined behavior. To give some examples: ```julia julia> t = Base.Rounding.setrounding_raw(Float64, Base.Rounding.to_fenv(RoundDown)) do Task(() -> println(rounding(Float64))) end Task (runnable) @0x000000010dff04c0 julia> rounding(Float64) RoundingMode{:Nearest}() julia> wait(schedule(t)) RoundingMode{:Down}() # currently gives RoundingMode{:Nearest}() julia> rounding(Float64) RoundingMode{:Nearest}() julia> Base.Rounding.setrounding_raw(Float64, Base.Rounding.to_fenv(RoundDown)) do Threads.@threads :static for i = 1:Threads.nthreads() println(Threads.threadid() => rounding(Float64)) end end 1 => RoundingMode{:Down}() 2 => RoundingMode{:Down}() # currently gives RoundingMode{:Nearest}() 4 => RoundingMode{:Down}() # currently gives RoundingMode{:Nearest}() 3 => RoundingMode{:Down}() # currently gives RoundingMode{:Nearest}() ```
1 parent df5f437 commit 12aa9de

File tree

2 files changed

+8
-0
lines changed

2 files changed

+8
-0
lines changed

src/julia.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "libsupport.h"
2121
#include <stdint.h>
2222
#include <string.h>
23+
#include <fenv.h>
2324

2425
#include "htable.h"
2526
#include "arraylist.h"
@@ -2282,6 +2283,9 @@ typedef struct _jl_task_t {
22822283
uint16_t priority;
22832284

22842285
// hidden state:
2286+
// cached floating point environment
2287+
// only updated at task switch
2288+
fenv_t fenv;
22852289

22862290
// id of owning thread - does not need to be defined until the task runs
22872291
_Atomic(int16_t) tid;

src/task.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ JL_NO_ASAN static void ctx_switch(jl_task_t *lastt)
534534
jl_set_pgcstack(&t->gcstack);
535535
jl_signal_fence();
536536
lastt->ptls = NULL;
537+
fegetenv(&lastt->fenv);
537538
#ifdef MIGRATE_TASKS
538539
ptls->previous_task = lastt;
539540
#endif
@@ -726,6 +727,7 @@ JL_DLLEXPORT void jl_switch(void) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER
726727
0 == ptls->finalizers_inhibited);
727728
ptls->finalizers_inhibited = finalizers_inhibited;
728729
jl_timing_block_task_enter(ct, ptls, blk); (void)blk;
730+
fesetenv(&ct->fenv);
729731

730732
sig_atomic_t other_defer_signal = ptls->defer_signal;
731733
ptls->defer_signal = defer_signal;
@@ -1138,6 +1140,7 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion
11381140
t->excstack = NULL;
11391141
t->ctx.started = 0;
11401142
t->priority = 0;
1143+
fegetenv(&t->fenv);
11411144
jl_atomic_store_relaxed(&t->tid, -1);
11421145
t->threadpoolid = ct->threadpoolid;
11431146
t->ptls = NULL;
@@ -1239,6 +1242,7 @@ CFI_NORETURN
12391242
if (!pt->sticky && !pt->ctx.copy_stack)
12401243
jl_atomic_store_release(&pt->tid, -1);
12411244
#endif
1245+
fesetenv(&ct->fenv);
12421246

12431247
ct->ctx.started = 1;
12441248
JL_PROBE_RT_START_TASK(ct);

0 commit comments

Comments
 (0)