2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <audio_utils/fifo_index.h>
20 #include <audio_utils/futex.h>
22 // These are not implemented within <audio_utils/fifo_index.h>
23 // so that we don't expose futex.
25 uint32_t audio_utils_fifo_index::loadAcquire()
27 return atomic_load_explicit(&mIndex, std::memory_order_acquire);
30 // FIXME should inline this, so that writer32 can also inline it
31 void audio_utils_fifo_index::storeRelease(uint32_t value)
33 atomic_store_explicit(&mIndex, value, std::memory_order_release);
36 int audio_utils_fifo_index::wait(int op, uint32_t expected, const struct timespec *timeout)
38 return sys_futex(&mIndex, op, expected, timeout, NULL, 0);
41 int audio_utils_fifo_index::wake(int op, int waiters)
43 return sys_futex(&mIndex, op, waiters, NULL, NULL, 0);
46 uint32_t audio_utils_fifo_index::loadConsume()
48 return atomic_load_explicit(&mIndex, std::memory_order_consume);
53 RefIndexDeferredStoreReleaseDeferredWake::RefIndexDeferredStoreReleaseDeferredWake(
54 audio_utils_fifo_index& index)
55 : mIndex(index), mValue(0), mWriteback(false), mWaiters(0), mWakeOp(FUTEX_WAIT_PRIVATE)
59 RefIndexDeferredStoreReleaseDeferredWake::~RefIndexDeferredStoreReleaseDeferredWake()
65 void RefIndexDeferredStoreReleaseDeferredWake::set(uint32_t value) {
70 void RefIndexDeferredStoreReleaseDeferredWake::writeback()
73 // TODO When part of a collection, should use relaxed for all but the last writeback
74 mIndex.storeRelease(mValue);
79 void RefIndexDeferredStoreReleaseDeferredWake::writethrough(uint32_t value) {
84 void RefIndexDeferredStoreReleaseDeferredWake::wakeDeferred(int op, int waiters)
89 // default is FUTEX_WAKE_PRIVATE
90 if (op == FUTEX_WAKE) {
93 if (waiters < INT_MAX - mWaiters) {
100 void RefIndexDeferredStoreReleaseDeferredWake::wakeNowIfNeeded()
103 mIndex.wake(mWakeOp, mWaiters);
105 mWakeOp = FUTEX_WAKE_PRIVATE;
109 void RefIndexDeferredStoreReleaseDeferredWake::wakeNow(int op, int waiters)
111 wakeDeferred(op, waiters);
117 RefIndexCachedLoadAcquireDeferredWait::RefIndexCachedLoadAcquireDeferredWait(
118 audio_utils_fifo_index& index)
119 : mIndex(index), mValue(0), mLoaded(false)
123 RefIndexCachedLoadAcquireDeferredWait::~RefIndexCachedLoadAcquireDeferredWait()
127 uint32_t RefIndexCachedLoadAcquireDeferredWait::get()
133 void RefIndexCachedLoadAcquireDeferredWait::prefetch()
136 // TODO When part of a collection, should use relaxed for all but the last load
137 mValue = mIndex.loadAcquire();
142 void RefIndexCachedLoadAcquireDeferredWait::invalidate()
148 uint32_t RefIndexCachedLoadAcquireDeferredWait::readthrough()
155 int RefIndexCachedLoadAcquireDeferredWait::wait(int op, const struct timespec *timeout)
160 int err = mIndex.wait(op, mValue /*expected*/, timeout);