HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Thread scheduling and mutual exclusion

05-24-2007, 05:41 PM#1
weaaddar
Warcraft III threads have three states, running,ready and waiting state.

When a thread is in the running state it runs until it completes, its quantom expires, or it sleeps (I think TriggerSleepAction,waitforsound and TriggerStartSync). Threads in the running state can only transition to the waiting state.

When a thread is in the sleeping state it waits until the condition has been met, and it is put back on the ready queue. Threads in this state can only transition to the ready state.

Finally, the ready state a thread basically waits to be scheduled, and then transitions to the running state.

The problem lies in large code executions. Since a running thread is never preempted and returned to the waiting queue, it runs until its quantom expires and then it dies. There are many simple solutions, which is ussually achieved by using timers and attaching state to them. Essientially extending the current quantom, but there is the problem that we don't know if they will immedietly run.

Let's consider a very terrible idea in warcraft III Distributed computing. For whatever reason you decided you want to use 12 players networked to do LU decompisition on a large global array. You'd use LocalPlayer()==Player(0) to make Player(0) the conductor, and any other player as a worker thread. After each all the computations for a row are done, Player(0) is to instruct each of the worker threads to wake up, copy thier done work into the global array, and then reassign work to the threads. However, since we lack any type atomic operations (in this sense I mean thinsg like test-and-set, fetch-and-increment) I don't really know how we'd build semaphores,mutexs or any other things to help avoid deadlock. I also don't think that these threads can wait or launch new threads without causing desync. We need some sort of way to do scheduling that allows preemption and rescheduling of quatom expired threads.
I don't know how to do it to be honest.
For atomic operations perhaps we can fake them by using some warcraft 3 atomic interactions
For a spinning lock mutexs I think we can do something like this:
Collapse JASS:
struct mutex
integer id //an itemtype that has no cooldown, no effect and is instant cast with one charge.
unit m //a unit with an inventory that they can use.
item it //an item of type id
   method lock takes nothing returns boolean
      loop
        exitwhen ( UnitUseItem(.m,.it))
      endloop
      return true
    endmethod
    method unlock takes nothing returns nothing
      set .it=UnitAddItemById( .m,.id)
    endmethod
    static method create takes unit m,integer id returns mutex
       local mutex mu=mutex.allocate()
       set .m=m
       set .id=id
       set .it=UnitAddItemById(.m,.id)
       return mu
    endmethod
endstruct
Of course this type of mutex won't work with current scheduling, We would need one that would preempt threads if neccessary.