Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
ryanbeasley:notes:snd_locking [2006/08/04 01:38] – RyanBeasleyryanbeasley:notes:snd_locking [2008/06/17 21:37] (current) – converted to 1.6 markup 127.0.0.1
Line 15: Line 15:
 Another toughy are SNDCTL_DSP_SYNCGROUP and SNDCTL_DSP_SYNCSTART.  Syncgroups are singly-linked lists of PCM channels set to begin playing at the same time.  These lists are also kept in a singly linked list, since the number of entries is small and nearly all insert/remove operations are done at the head.  The master list (and all member group lists) are protected by a single mutex, so it is important that a caller acquire this mutex first //without// any channel locks held.  This is necessary for the SYNCSTART operation which iterates over all channels in a group, locks them, and begins playback/recording. Another toughy are SNDCTL_DSP_SYNCGROUP and SNDCTL_DSP_SYNCSTART.  Syncgroups are singly-linked lists of PCM channels set to begin playing at the same time.  These lists are also kept in a singly linked list, since the number of entries is small and nearly all insert/remove operations are done at the head.  The master list (and all member group lists) are protected by a single mutex, so it is important that a caller acquire this mutex first //without// any channel locks held.  This is necessary for the SYNCSTART operation which iterates over all channels in a group, locks them, and begins playback/recording.
  
-Hack of a solution:  in addition to a mutex, each channel maintains a conditional variable (//cv//) and in progress counter (//inprog//).  For operations which might temporarily give up the mutex, //inprog// is incremented before releasing the mutex.  Any other thread that acquires the channel lock should inspect //inprog// - if it is non-zero, that thread should call cv_wait() on the channel's lock & cv.  (This is typically done in a loop.)  When the owning thread reacquires the lock, it should decrement //inprog// and call cv_signal() on the lock & cv.+Hack of a solution:  in addition to a mutex, each channel maintains a conditional variable (**cv**) and in progress counter (**inprog**).  For operations which might temporarily give up the mutex, **inprog** is incremented before releasing the mutex.  Any other thread that acquires the channel lock should inspect **inprog** - if it is non-zero, that thread should call cv_wait() on the channel's lock & cv.  (This is typically done in a loop.)  When the owning thread reacquires the lock, it should decrement **inprog** and call cv_signal() on the lock & cv.
  
 Implementing that scheme would require updating channel.c::chn_lock() to include the cv handling, then updating CHN_LOCK/CHN_UNLOCK macros to make use of these checks. Implementing that scheme would require updating channel.c::chn_lock() to include the cv handling, then updating CHN_LOCK/CHN_UNLOCK macros to make use of these checks.
  
 ==== Interrupts ==== ==== Interrupts ====
 +  - CHN_LOCK(channel)
 +  - chn_{wr,rd}intr()
 +  - CHN_UNLOCK(channel)
  
  • ryanbeasley/notes/snd_locking.1154655500.txt.gz
  • Last modified: 2006/08/04 01:38
  • by RyanBeasley