WARNING / ACHTUNG / 警告

This page is intended solely as a space to jot notes onto. Do not make any decisions based on the content here. Some portions came from cursory reviews & may, in fact, be incorrect.

User requests

Ioctls

By default, no locking is performed. Typically, a channel lock is acquired in order to complete a few instructions, then is released. (E.g., acquire, set buffer size, release.) This is satisfactory in many cases, but operations which touch other channels make things a little tricky (ex: SNDCTL_AUDIOINFO).

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.

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

  1. CHN_LOCK(channel)
  2. chn_{wr,rd}intr()
  3. CHN_UNLOCK(channel)

RyanBeasley/Notes/snd_locking (last edited 2008-06-17T21:37:41+0000 by anonymous)