Is there a possibility to prevent task switches in a block of code?

I would like to ensure that within a certain block of code no task switch can happen.

A bit like an “atomic block” for async tasks

No. IIRC we don’t have a way of marking critical region

is there already an issue for this feature request?

I opened an issue Feature Request: Possibility to mark certain code block as "Prevent taskswitch" · Issue #52313 · JuliaLang/julia · GitHub

Whatever this may be, transforming code that has “yield to another task” steps at arbitrary nested calls into code that has none at all would need some internals magic for sure. The more language-level approach would be to not schedule a task to begin with or never use task-switching methods in a block. As you’re probably hinting, substituting non-switching versions so thoroughly would be a chore. For the issue’s example, there’s Base.Libc.systemsleep.

Is this even possible in a non real-time OS?

Afaik task switches only occur at certain method calls, is it possible to ensure that a block of code doesn’t make any of these calls? Essentially, write a “kernel” which does the pure steps, and doesn’t make any extraneous method calls which might trigger a task switch like I/O (if that’s possible for your use case).

this is about the Julia Task, nothing to do with OS. But I do question the actual safety constraint this function can provide is even useful


that’s not a semantic guarentee made by Julia, it can do task switch any time it wants to, in practice if you have a tight kernel task switching is unlikely to happen but that shouldn’t be the way to achive critical region. It’s not reliable anyway

1 Like

Intuitively whatever triggers the task-switch, maybe simply sleep, could have a switch to not do a taskswitch but use Base.Libc.systemsleep instead.

If it is really only about sleep, I could build a Cassette Meta transformer which replaces all invokations to sleep with invokations to Base.Libc.systemsleep. This has the disadvantage of possibly intense recompilation, but would work.

Don’t think we can do anything about the OS, but this is about Julia’s task scheduler

the case I have is that I run a couple of Base.run() and HTTP requests and was confused about which trigger taskswitches and which not.

A preven_taskswitch function would be the simple solution

Isn’t julia’s task system cooperative, meaning that there are a lot of yield points all over the place? I think IO is a big one that yields

function foo()
    for i = 1:10000
        print("a")
    end
end

function bar()
    for i = 1:10000
        print("b")
    end
end


t1 = @async foo()
t2 = @async bar()

prints

abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab...

indicating that the print calls yield.

3 Likes

that sounds horrible. I always thought we only need Atomics for Threads (also the documentation suggests this).
What you are writing would destroy plenty of async based logics

have you not seen PSA: Thread-local state is no longer recommended ?

1 Like

the link is not about async tasks, but about Threads

async has the exact same issue:

julia> f(i) = (sleep(0.01); return i)
f (generic function with 1 method)

julia> state = [0]
1-element Vector{Int64}:
 0

julia> @sync for i ∈ 1:100
               @async state[1] += f(i)
             end

julia> state
1-element Vector{Int64}:
 100
1 Like

you are calling sleep

this seems to indicate that async task can indeed not be interrupted anywhere, but just at certain points like sleep

sleep() can be anything! Julia does not have a list of “possibly yileding” function and guarentee everything else is non-yielding

edit:
oh yeah, of course anything print() or any logging happens you’re out

impressive!!!

thank you for the example. That looks like it is almost impossible to prevent task switches.

So I am back to locking :laughing:

please link to the documentation which says so

It is pretty unbelievable for me to take your saying literal.