Remove explicit instantiation of SingleStateQueue

Refactoring now possible due to changes in the Android
atomic include.

Change-Id: Ia0094d322d9ad3d8c186307306821376ca8002c4
diff --git a/include/media/SingleStateQueue.h b/include/media/SingleStateQueue.h
index 04c5fd0..e2e58c5 100644
--- a/include/media/SingleStateQueue.h
+++ b/include/media/SingleStateQueue.h
@@ -21,6 +21,7 @@
 // Non-blocking single-reader / single-writer multi-word atomic load / store
 
 #include <stdint.h>
+#include <cutils/atomic.h>
 
 namespace android {
 
@@ -41,28 +42,47 @@
         void                init() { mAck = 0; mSequence = 0; }
 
         volatile int32_t    mAck;
-#if 0
-        int                 mPad[7];
-        // cache line boundary
-#endif
         volatile int32_t    mSequence;
         T                   mValue;
     };
 
     class Mutator {
     public:
-        Mutator(Shared *shared);
-        /*virtual*/ ~Mutator() { }
+        Mutator(Shared *shared)
+            : mSequence(0), mShared(shared)
+        {
+            // exactly one of Mutator and Observer must initialize, currently it is Observer
+            // shared->init();
+        }
 
         // push new value onto state queue, overwriting previous value;
         // returns a sequence number which can be used with ack()
-        int32_t push(const T& value);
+        int32_t push(const T& value)
+        {
+            Shared *shared = mShared;
+            int32_t sequence = mSequence;
+            sequence++;
+            android_atomic_acquire_store(sequence, &shared->mSequence);
+            shared->mValue = value;
+            sequence++;
+            android_atomic_release_store(sequence, &shared->mSequence);
+            mSequence = sequence;
+            // consider signalling a futex here, if we know that observer is waiting
+            return sequence;
+        }
 
         // return true if most recent push has been observed
-        bool ack();
+        bool ack() const
+        {
+            return mShared->mAck - mSequence == 0;
+        }
 
         // return true if a push with specified sequence number or later has been observed
-        bool ack(int32_t sequence);
+        bool ack(int32_t sequence) const
+        {
+            // this relies on 2's complement rollover to detect an ancient sequence number
+            return mShared->mAck - sequence >= 0;
+        }
 
     private:
         int32_t     mSequence;
@@ -71,11 +91,45 @@
 
     class Observer {
     public:
-        Observer(Shared *shared);
-        /*virtual*/ ~Observer() { }
+        Observer(Shared *shared)
+            : mSequence(0), mSeed(1), mShared(shared)
+        {
+            // exactly one of Mutator and Observer must initialize, currently it is Observer
+            shared->init();
+        }
 
         // return true if value has changed
-        bool poll(T& value);
+        bool poll(T& value)
+        {
+            Shared *shared = mShared;
+            int32_t before = shared->mSequence;
+            if (before == mSequence) {
+                return false;
+            }
+            for (int tries = 0; ; ) {
+                const int MAX_TRIES = 5;
+                if (before & 1) {
+                    if (++tries >= MAX_TRIES) {
+                        return false;
+                    }
+                    before = shared->mSequence;
+                } else {
+                    android_memory_barrier();
+                    T temp = shared->mValue;
+                    int32_t after = android_atomic_release_load(&shared->mSequence);
+                    if (after == before) {
+                        value = temp;
+                        shared->mAck = before;
+                        mSequence = before;
+                        return true;
+                    }
+                    if (++tries >= MAX_TRIES) {
+                        return false;
+                    }
+                    before = after;
+                }
+            }
+        }
 
     private:
         int32_t     mSequence;