Making a task.sticky = false run in any thread

I was experimenting with multithreading to learn more about Julia’s multithreading capabilities. I tried to replicate the @spawn steps with ordinary Task creation:

function prime_check(n)
    for i = 2:n/2
        if n%i == 0
            return nothing
        end
    end
    return n
end

function primes_spawn!(A , value)
    cond = ReentrantLock()
    @sync for i = 2:value
        Threads.@spawn begin
            a = prime_check(i)
            if a != nothing
                lock(cond)
                push!(A, a)
                unlock(cond)
            end
        end
    end
end

function primes_task!(A, value::Int)
    cond = ReentrantLock()
    for i = 2:value
        let 
            local task = Task(()->prime_check(i))
            task.sticky = false
            schedule(task)
            if fetch(task) != nothing
                lock(cond)
                println(fetch(task), " running on thread ", threadid())
                #push!(A, fetch(task))
                unlock(cond)
                wait(task)
            end
        end
    end
end

When I run it I get the following result:

A = Int64[]
primes_task!(A, 20)
2 running on thread 1
3 running on thread 1
5 running on thread 1
7 running on thread 1
11 running on thread 1
13 running on thread 1
17 running on thread 1
19 running on thread 1

Julia code warns the following:

#Note there are three reasons a Task might be put into a sticky queue
# even if t.sticky == false:
# 1. The Task’s stack is currently being used by the scheduler for a certain thread.
# 2. There is only 1 thread.
# 3. The multiq is full (can be fixed by making it growable).

But I don’t know where to fix it to make it work correctly.

1 Like

Did you end up getting an answer?

Edit: if anybody stumbles across this, I found this paper useful for understanding Julias Task system.

1 Like

Make sure to pass -t auto as a command line option for Julia to launch multiple threads.