dennisg@kgw2.bwi.WEC.COM (Dennis Glatting) (03/17/90)
how is mutex_lock() implemented in the NeXT computer? i have several tasks with several threads each. i had a thread lock a mutex with mutex_lock() then, unfortunatly, died. the mutex stayed locked. i noticed that the NeXT was running a bit slow so i fired up gdb of the task in question. i found more than one thread in cthread_yield(). my question is: when you call mutex_lock() and the mutex is locked then what happens? does the thread do a cthread_yield() until the mutex is unlocked? if that is true then why? it seems a waste of cpu. -- dennisg@kgw2.bwi.WEC.COM | Dennis P. Glatting ..!uunet!tron!kgw2!dennisg |
mbj@spice.cs.cmu.edu (Michael Jones) (03/18/90)
In article <429@kgw2.bwi.WEC.COM>, dennisg@kgw2.bwi.WEC.COM (Dennis Glatting) writes: > > how is mutex_lock() implemented in the NeXT computer? > > i have several tasks with several threads each. i had a thread lock a > mutex with mutex_lock() then, unfortunatly, died. the mutex stayed locked. > i noticed that the NeXT was running a bit slow so i fired up gdb of > the task in question. i found more than one thread in cthread_yield(). > my question is: when you call mutex_lock() and the mutex is locked then > what happens? does the thread do a cthread_yield() until the mutex > is unlocked? if that is true then why? it seems a waste of cpu. mutex_lock(m) spins a few times calling mutex_try_lock(m), and then spins alternating between mutex_try_lock(m) and cthread_yield(). mutex_try_lock(m) is a test-and-set on the mutex. Now to answer your real question. No, it's not a waste of cpu to spin on a mutex in a correctly written threads application. A mutex provides mutual exclusion between two threads. It's intended to be called only when the mutual exclusion is of a short or bounded duration. It's not the right primitive for unbounded waiting. Any potentially unbounded waiting should be done using condition_wait and condition_{signal,broadcast} (which don't spin). If a thread dies, none of the memory resources which it logically owns will be cleaned up. That includes its locks. If a thread dies, you have an incorrect program anyway, and the fact that some locks are still held is the least of your problems. -- Mike
jwag@moose.sgi.com (Chris Wagner) (03/22/90)
In article <8460@pt.cs.cmu.edu>, mbj@spice.cs.cmu.edu (Michael Jones) writes: > In article <429@kgw2.bwi.WEC.COM>, dennisg@kgw2.bwi.WEC.COM (Dennis Glatting) writes: > > > > how is mutex_lock() implemented in the NeXT computer? > > > > i have several tasks with several threads each. i had a thread lock a > > mutex with mutex_lock() then, unfortunatly, died. the mutex stayed locked. > > i noticed that the NeXT was running a bit slow so i fired up gdb of > > the task in question. i found more than one thread in cthread_yield(). > > my question is: when you call mutex_lock() and the mutex is locked then > > what happens? does the thread do a cthread_yield() until the mutex > > is unlocked? if that is true then why? it seems a waste of cpu. > > mutex_lock(m) spins a few times calling mutex_try_lock(m), and then spins > alternating between mutex_try_lock(m) and cthread_yield(). mutex_try_lock(m) > is a test-and-set on the mutex. > > Now to answer your real question. No, it's not a waste of cpu to spin on a > mutex in a correctly written threads application. A mutex provides mutual > exclusion between two threads. It's intended to be called only when the > mutual exclusion is of a short or bounded duration. It's not the right > primitive for unbounded waiting. Any potentially unbounded waiting should be > done using condition_wait and condition_{signal,broadcast} (which don't spin). > > If a thread dies, none of the memory resources which it logically owns will be > cleaned up. That includes its locks. If a thread dies, you have an incorrect > program anyway, and the fact that some locks are still held is the least of > your problems. > > -- Mike Although in many cases, spinning is a good idea - what happens when a thread holds a lock for what it thnks is a short time - however during the few instructions it has the lock it gets context switched, other threads trying to get the lcok will spin a while then yield. Thats ok as long the the number of threads is not too much greater than the number of processors - but what happens when you have 100 or more threads going after a single lock often, the time till the thread that owns the lock gets to run could be fairly long. Chris Wagner
mbj@spice.cs.cmu.edu (Michael Jones) (03/23/90)
In article <5612@odin.corp.sgi.com>, jwag@moose.sgi.com (Chris Wagner) writes: > In article <8460@pt.cs.cmu.edu>, mbj@spice.cs.cmu.edu (Michael Jones) writes: > > Now to answer your real question. No, it's not a waste of cpu to spin on a > > mutex in a correctly written threads application. A mutex provides mutual > > exclusion between two threads. It's intended to be called only when the > > mutual exclusion is of a short or bounded duration. It's not the right > > primitive for unbounded waiting. Any potentially unbounded waiting should > > be done using condition_wait and condition_{signal,broadcast} (which > > don't spin). > > Although in many cases, spinning is a good idea - what happens when a > thread holds a lock for what it thnks is a short time - however during the > few instructions it has the lock it gets context switched, other threads > trying to get the lcok will spin a while then yield. Thats ok as long the > the number of threads is not too much greater than the number of processors > - but what happens when you have 100 or more threads going after a single > lock often, the time till the thread that owns the lock gets to run could > be fairly long. The case you describe can certainly happen although it should be quite rare. A timeslice should be substantially larger than the window during which you hold a mutex, so this should happen only with probability (mutex_time)/(slice_time). (And in actuality, it probably happens far less than that for the following reason -- mutexes will often be acquired following a condition_wait; if the condition_wait blocked, the mutex will be acquired at the beginning of a timeslice.) Even if it does happen, the cthread_yield() in the spin loop of mutex_lock() will yield the processor to another thread within a few dozen (application) instructions, allowing other threads to have their turn. That having been said, if you do have a parallel program with 100 threads contending frequently for a single resource you'll probably incur synchronization delays no matter what algorithm you use. Restructuring your algorithm to avoid this bottleneck might be appropriate. Profiling your should help determine if you have a contention bottleneck. If you have a potential bottleneck you can at least reduce wasted cycles by protecting this resource with a condition variable rather than a mutex if contention is statisticly probably, rather than statisticly unlikely (the case for which mutexes are appropriate). -- Mike