Use a separate mutex to protect all_tasks, avoiding a lock-order-reversal
authorSimon Marlow <marlowsd@gmail.com>
Fri, 16 Jul 2010 15:08:32 +0000 (15:08 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Fri, 16 Jul 2010 15:08:32 +0000 (15:08 +0000)
commited30194937e0562e62da3e71f9da8585ac6cf477
tree37c9f2e82ff9c4970b1aecacae70e93ec5c0402f
parent93c872cfb680bb72c26da8f1fd9c9921f3211de1
Use a separate mutex to protect all_tasks, avoiding a lock-order-reversal
In GHC 6.12.x I found a rare deadlock caused by this
lock-order-reversal:

AQ cap->lock
  startWorkerTask
    newTask
      AQ sched_mutex

scheduleCheckBlackHoles
  AQ sched_mutex
   unblockOne_
    wakeupThreadOnCapabilty
      AQ cap->lock

so sched_mutex and cap->lock are taken in a different order in two
places.

This doesn't happen in the HEAD because we don't have
scheduleCheckBlackHoles, but I thought it would be prudent to make
this less likely to happen in the future by using a different mutex in
newTask.  We can clearly see that the all_tasks mutex cannot be
involved in a deadlock, becasue we never call anything else while
holding it.
rts/Task.c