StateQueue.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef ANDROID_AUDIO_STATE_QUEUE_H
  17. #define ANDROID_AUDIO_STATE_QUEUE_H
  18. #include <stdatomic.h>
  19. // The state queue template class was originally driven by this use case / requirements:
  20. // There are two threads: a fast mixer, and a normal mixer, and they share state.
  21. // The interesting part of the shared state is a set of active fast tracks,
  22. // and the output HAL configuration (buffer size in frames, sample rate, etc.).
  23. // Fast mixer thread:
  24. // periodic with typical period < 10 ms
  25. // FIFO/RR scheduling policy and a low fixed priority
  26. // ok to block for bounded time using nanosleep() to achieve desired period
  27. // must not block on condition wait, mutex lock, atomic operation spin, I/O, etc.
  28. // under typical operations of mixing, writing, or adding/removing tracks
  29. // ok to block for unbounded time when the output HAL configuration changes,
  30. // and this may result in an audible artifact
  31. // needs read-only access to a recent stable state,
  32. // but not necessarily the most current one
  33. // only allocate and free memory when configuration changes
  34. // avoid conventional logging, as this is a form of I/O and could block
  35. // defer computation to other threads when feasible; for example
  36. // cycle times are collected by fast mixer thread but the floating-point
  37. // statistical calculations on these cycle times are computed by normal mixer
  38. // these requirements also apply to callouts such as AudioBufferProvider and VolumeProvider
  39. // Normal mixer thread:
  40. // periodic with typical period ~20 ms
  41. // SCHED_OTHER scheduling policy and nice priority == urgent audio
  42. // ok to block, but prefer to avoid as much as possible
  43. // needs read/write access to state
  44. // The normal mixer may need to temporarily suspend the fast mixer thread during mode changes.
  45. // It will do this using the state -- one of the fields tells the fast mixer to idle.
  46. // Additional requirements:
  47. // - observer must always be able to poll for and view the latest pushed state; it must never be
  48. // blocked from seeing that state
  49. // - observer does not need to see every state in sequence; it is OK for it to skip states
  50. // [see below for more on this]
  51. // - mutator must always be able to read/modify a state, it must never be blocked from reading or
  52. // modifying state
  53. // - reduce memcpy where possible
  54. // - work well if the observer runs more frequently than the mutator,
  55. // as is the case with fast mixer/normal mixer.
  56. // It is not a requirement to work well if the roles were reversed,
  57. // and the mutator were to run more frequently than the observer.
  58. // In this case, the mutator could get blocked waiting for a slot to fill up for
  59. // it to work with. This could be solved somewhat by increasing the depth of the queue, but it would
  60. // still limit the mutator to a finite number of changes before it would block. A future
  61. // possibility, not implemented here, would be to allow the mutator to safely overwrite an already
  62. // pushed state. This could be done by the mutator overwriting mNext, but then being prepared to
  63. // read an mAck which is actually for the earlier mNext (since there is a race).
  64. // Solution:
  65. // Let's call the fast mixer thread the "observer" and normal mixer thread the "mutator".
  66. // We assume there is only a single observer and a single mutator; this is critical.
  67. // Each state is of type <T>, and should contain only POD (Plain Old Data) and raw pointers, as
  68. // memcpy() may be used to copy state, and the destructors are run in unpredictable order.
  69. // The states in chronological order are: previous, current, next, and mutating:
  70. // previous read-only, observer can compare vs. current to see the subset that changed
  71. // current read-only, this is the primary state for observer
  72. // next read-only, when observer is ready to accept a new state it will shift it in:
  73. // previous = current
  74. // current = next
  75. // and the slot formerly used by previous is now available to the mutator.
  76. // mutating invisible to observer, read/write to mutator
  77. // Initialization is tricky, especially for the observer. If the observer starts execution
  78. // before the mutator, there are no previous, current, or next states. And even if the observer
  79. // starts execution after the mutator, there is a next state but no previous or current states.
  80. // To solve this, we'll have the observer idle until there is a next state,
  81. // and it will have to deal with the case where there is no previous state.
  82. // The states are stored in a shared FIFO queue represented using a circular array.
  83. // The observer polls for mutations, and receives a new state pointer after a
  84. // a mutation is pushed onto the queue. To the observer, the state pointers are
  85. // effectively in random order, that is the observer should not do address
  86. // arithmetic on the state pointers. However to the mutator, the state pointers
  87. // are in a definite circular order.
  88. #include "Configuration.h"
  89. namespace android {
  90. #ifdef STATE_QUEUE_DUMP
  91. // The StateQueueObserverDump and StateQueueMutatorDump keep
  92. // a cache of StateQueue statistics that can be logged by dumpsys.
  93. // Each individual native word-sized field is accessed atomically. But the
  94. // overall structure is non-atomic, that is there may be an inconsistency between fields.
  95. // No barriers or locks are used for either writing or reading.
  96. // Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks).
  97. // It has a different lifetime than the StateQueue, and so it can't be a member of StateQueue.
  98. struct StateQueueObserverDump {
  99. StateQueueObserverDump() : mStateChanges(0) { }
  100. /*virtual*/ ~StateQueueObserverDump() { }
  101. unsigned mStateChanges; // incremented each time poll() detects a state change
  102. void dump(int fd);
  103. };
  104. struct StateQueueMutatorDump {
  105. StateQueueMutatorDump() : mPushDirty(0), mPushAck(0), mBlockedSequence(0) { }
  106. /*virtual*/ ~StateQueueMutatorDump() { }
  107. unsigned mPushDirty; // incremented each time push() is called with a dirty state
  108. unsigned mPushAck; // incremented each time push(BLOCK_UNTIL_ACKED) is called
  109. unsigned mBlockedSequence; // incremented before and after each time that push()
  110. // blocks for more than one PUSH_BLOCK_ACK_NS;
  111. // if odd, then mutator is currently blocked inside push()
  112. void dump(int fd);
  113. };
  114. #endif
  115. // manages a FIFO queue of states
  116. template<typename T> class StateQueue {
  117. public:
  118. StateQueue();
  119. virtual ~StateQueue();
  120. // Observer APIs
  121. // Poll for a state change. Returns a pointer to a read-only state,
  122. // or NULL if the state has not been initialized yet.
  123. // If a new state has not pushed by mutator since the previous poll,
  124. // then the returned pointer will be unchanged.
  125. // The previous state pointer is guaranteed to still be valid;
  126. // this allows the observer to diff the previous and new states.
  127. const T* poll();
  128. // Mutator APIs
  129. // Begin a mutation. Returns a pointer to a read/write state, except the
  130. // first time it is called the state is write-only and _must_ be initialized.
  131. // Mutations cannot be nested.
  132. // If the state is dirty and has not been pushed onto the state queue yet, then
  133. // this new mutation will be squashed together with the previous one.
  134. T* begin();
  135. // End the current mutation and indicate whether caller modified the state.
  136. // If didModify is true, then the state is marked dirty (in need of pushing).
  137. // There is no rollback option because modifications are done in place.
  138. // Does not automatically push the new state onto the state queue.
  139. void end(bool didModify = true);
  140. // Push a new state, if any, out to the observer via the state queue.
  141. // For BLOCK_NEVER, returns:
  142. // true if not dirty, or dirty and pushed successfully
  143. // false if dirty and not pushed because that would block; remains dirty
  144. // For BLOCK_UNTIL_PUSHED and BLOCK_UNTIL_ACKED, always returns true.
  145. // No-op if there are no pending modifications (not dirty), except
  146. // for BLOCK_UNTIL_ACKED it will wait until a prior push has been acknowledged.
  147. // Must not be called in the middle of a mutation.
  148. enum block_t {
  149. BLOCK_NEVER, // do not block
  150. BLOCK_UNTIL_PUSHED, // block until there's a slot available for the push
  151. BLOCK_UNTIL_ACKED, // also block until the push is acknowledged by the observer
  152. };
  153. bool push(block_t block = BLOCK_NEVER);
  154. // Return whether the current state is dirty (modified and not pushed).
  155. bool isDirty() const { return mIsDirty; }
  156. #ifdef STATE_QUEUE_DUMP
  157. // Register location of observer dump area
  158. void setObserverDump(StateQueueObserverDump *dump)
  159. { mObserverDump = dump != NULL ? dump : &mObserverDummyDump; }
  160. // Register location of mutator dump area
  161. void setMutatorDump(StateQueueMutatorDump *dump)
  162. { mMutatorDump = dump != NULL ? dump : &mMutatorDummyDump; }
  163. #endif
  164. private:
  165. static const unsigned kN = 4; // values < 4 are not supported by this code
  166. T mStates[kN]; // written by mutator, read by observer
  167. // "volatile" is meaningless with SMP, but here it indicates that we're using atomic ops
  168. atomic_uintptr_t mNext; // written by mutator to advance next, read by observer
  169. volatile const T* mAck; // written by observer to acknowledge advance of next, read by mutator
  170. // only used by observer
  171. const T* mCurrent; // most recent value returned by poll()
  172. // only used by mutator
  173. T* mMutating; // where updates by mutator are done in place
  174. const T* mExpecting; // what the mutator expects mAck to be set to
  175. bool mInMutation; // whether we're currently in the middle of a mutation
  176. bool mIsDirty; // whether mutating state has been modified since last push
  177. bool mIsInitialized; // whether mutating state has been initialized yet
  178. #ifdef STATE_QUEUE_DUMP
  179. StateQueueObserverDump mObserverDummyDump; // default area for observer dump if not set
  180. StateQueueObserverDump* mObserverDump; // pointer to active observer dump, always non-NULL
  181. StateQueueMutatorDump mMutatorDummyDump; // default area for mutator dump if not set
  182. StateQueueMutatorDump* mMutatorDump; // pointer to active mutator dump, always non-NULL
  183. #endif
  184. }; // class StateQueue
  185. } // namespace android
  186. #endif // ANDROID_AUDIO_STATE_QUEUE_H