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 
17 #ifndef SINGLE_STATE_QUEUE_H
18 #define SINGLE_STATE_QUEUE_H
19 
20 // Non-blocking single element state queue, or
21 // Non-blocking single-reader / single-writer multi-word atomic load / store
22 
23 #include <stdint.h>
24 
25 namespace android {
26 
27 template<typename T> class SingleStateQueue {
28 
29 public:
30 
31     class Mutator;
32     class Observer;
33 
34     struct Shared {
35         // needs to be part of a union so don't define constructor or destructor
36 
37         friend class Mutator;
38         friend class Observer;
39 
40 private:
initShared41         void                init() { mAck = 0; mSequence = 0; }
42 
43         volatile int32_t    mAck;
44 #if 0
45         int                 mPad[7];
46         // cache line boundary
47 #endif
48         volatile int32_t    mSequence;
49         T                   mValue;
50     };
51 
52     class Mutator {
53     public:
54         Mutator(Shared *shared);
~Mutator()55         /*virtual*/ ~Mutator() { }
56 
57         // push new value onto state queue, overwriting previous value;
58         // returns a sequence number which can be used with ack()
59         int32_t push(const T& value);
60 
61         // return true if most recent push has been observed
62         bool ack();
63 
64         // return true if a push with specified sequence number or later has been observed
65         bool ack(int32_t sequence);
66 
67     private:
68         int32_t     mSequence;
69         Shared * const mShared;
70     };
71 
72     class Observer {
73     public:
74         Observer(Shared *shared);
~Observer()75         /*virtual*/ ~Observer() { }
76 
77         // return true if value has changed
78         bool poll(T& value);
79 
80     private:
81         int32_t     mSequence;
82         int         mSeed;  // for PRNG
83         Shared * const mShared;
84     };
85 
86 #if 0
87     SingleStateQueue(void /*Shared*/ *shared);
88     /*virtual*/ ~SingleStateQueue() { }
89 
90     static size_t size() { return sizeof(Shared); }
91 #endif
92 
93 };
94 
95 }   // namespace android
96 
97 #endif  // SINGLE_STATE_QUEUE_H
98