Basic Task Cooperation with Locks


#1

Dear Julia wizards: I understand that parallelism is still a work in progress, but I would like to know how to sketch the following code.

My code wants to maintain a shared (int) vector of what each CPU core is and/or has been working on. Before any core can alter this super-global “work in progress” queue, it needs to lock it. (Ideally, code would work both with shared memory threads and with full processes.) I very much like to define and type all my variables.

Here is an (incorrect) sketch of the task:

mutable struct WO; wo::Vector{Int}; n::Int, lock::SpinLock; end
function WO(n::Int) = workedon( fill(-1,n), n, **notlocked** )  ## constructor

w= WO(100)   ## a new WO queue for 100 int tasks

function insert( w::WO, newtask::Int )
    lock( w.lock )
    for i=1:w.n ;  (w[i]<0) && ( w[i]= newtask; break; ) ; end#for
    unlock( w.lock )
end#function##

function taskof( w::WO, i::Int )
    waitlockopen( w.lock )
    w[i]
end#function##

any CPU core can call insert() whenever it likes (without contention); and taskof() won’t pull off a number while another process happens to be inserting. I am trying to give a minimal example—my real functions are much more involved.

I have many questions here, although better than detailed answers would be a template for how this should be done correctly. The questions are such as:

  • Is SpinLock the right tool for multiple CPU coordination?
  • how do I initialize the lock in the constructor?
  • is lock/unlock correct? how does another CPU test for state of lock?
  • can one reasonably write code that works either with threads (sharing memory) or processes? the former works much better for small memory footprints; the latter for large memory footprints. (I know there are no Sharedstruct types.)

advice appreciated.

/iaw