Skip to content

Commit 99dddb3

Browse files
authored
make sched_task more robust (#59669)
If the sched_task ever dies, we need to recreate a new one. Creating a new one is very cheap, so it is unclear why we don't always do it this way. But at least do it this way if it ever dies (e.g. from an untimely InterruptException). Fix #58689
1 parent e91ab4f commit 99dddb3

File tree

3 files changed

+42
-20
lines changed

3 files changed

+42
-20
lines changed

base/task.jl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,9 +1132,25 @@ function throwto(t::Task, @nospecialize exc)
11321132
return try_yieldto(identity)
11331133
end
11341134

1135-
@inline function wait_forever()
1135+
function wait_forever()
11361136
while true
1137-
wait()
1137+
try
1138+
while true
1139+
wait()
1140+
end
1141+
catch e
1142+
local errs = stderr
1143+
# try to display the failure atomically
1144+
errio = IOContext(PipeBuffer(), errs::IO)
1145+
emphasize(errio, "Internal Task ")
1146+
display_error(errio, current_exceptions())
1147+
write(errs, errio)
1148+
# victimize another random Task also
1149+
if Threads.threadid() == 1 && isa(e, InterruptException) && isempty(Workqueue)
1150+
backend = repl_backend_task()
1151+
backend isa Task && throwto(backend, e)
1152+
end
1153+
end
11381154
end
11391155
end
11401156

@@ -1195,6 +1211,7 @@ function wait()
11951211
# thread sleep logic.
11961212
sched_task = get_sched_task()
11971213
if ct !== sched_task
1214+
istaskdone(sched_task) && (sched_task = @task wait())
11981215
return yieldto(sched_task)
11991216
end
12001217
task = ccall(:jl_task_get_next, Ref{Task}, (Any, Any, Any), trypoptask, W, checktaskempty)

contrib/juliac/juliac-buildscript.jl

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,35 +66,39 @@ let include_result = Base.include(Main, ARGS[1])
6666
end
6767
end
6868
end
69-
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{Base.SubString{String}, 1}, String))
70-
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{String, 1}, Char))
71-
entrypoint(Base.task_done_hook, (Task,))
72-
entrypoint(Base.wait, ())
73-
entrypoint(Base.wait_forever, ())
74-
entrypoint(Base.trypoptask, (Base.StickyWorkqueue,))
75-
entrypoint(Base.checktaskempty, ())
76-
if ARGS[3] == "true"
77-
Base.Compiler.add_ccallable_entrypoints!()
78-
end
79-
80-
# Export info about entrypoints and structs needed to create header files
81-
if length(ARGS) >= 4
82-
abi_export = ARGS[4]
83-
open(abi_export, "w") do io
84-
write_abi_metadata(io)
85-
end
86-
end
8769
end
8870

8971
# Run the verifier in the current world (before build-script modifications),
9072
# so that error messages and types print in their usual way.
9173
Core.Compiler._verify_trim_world_age[] = Base.get_world_counter()
9274

75+
# Apply hacks
76+
9377
if Base.JLOptions().trim != 0
9478
include(joinpath(@__DIR__, "juliac-trim-base.jl"))
9579
include(joinpath(@__DIR__, "juliac-trim-stdlib.jl"))
9680
end
9781

82+
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{Base.SubString{String}, 1}, String))
83+
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{String, 1}, Char))
84+
entrypoint(Base.task_done_hook, (Task,))
85+
entrypoint(Base.wait, ())
86+
entrypoint(Base.wait_forever, ())
87+
entrypoint(Base.trypoptask, (Base.StickyWorkqueue,))
88+
entrypoint(Base.checktaskempty, ())
89+
90+
if ARGS[3] == "true"
91+
Base.Compiler.add_ccallable_entrypoints!()
92+
end
93+
94+
# Export info about entrypoints and structs needed to create header files
95+
if length(ARGS) >= 4
96+
abi_export = ARGS[4]
97+
open(abi_export, "w") do io
98+
write_abi_metadata(io)
99+
end
100+
end
101+
98102
empty!(Core.ARGS)
99103
empty!(Base.ARGS)
100104
empty!(LOAD_PATH)

contrib/juliac/juliac-trim-base.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ end
1212
depwarn(msg, funcsym; force::Bool=false) = nothing
1313
_assert_tostring(msg) = ""
1414
reinit_stdio() = nothing
15+
wait_forever() = while true; wait(); end
1516
JuliaSyntax.enable_in_core!() = nothing
1617
init_active_project() = ACTIVE_PROJECT[] = nothing
1718
set_active_project(projfile::Union{AbstractString,Nothing}) = ACTIVE_PROJECT[] = projfile

0 commit comments

Comments
 (0)