1c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten/*
2c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * Copyright (C) 2016 The Android Open Source Project
3c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten *
4c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * you may not use this file except in compliance with the License.
6c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * You may obtain a copy of the License at
7c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten *
8c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten *
10c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * See the License for the specific language governing permissions and
14c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten * limitations under the License.
15c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten */
16c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
17c05b8d7df46619d3474356241d47655478b8bc82Glenn Kastennamespace android {
18c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
19c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten// T is FastMixer or FastCapture
20c05b8d7df46619d3474356241d47655478b8bc82Glenn Kastentemplate<typename T> class AutoPark {
21c05b8d7df46619d3474356241d47655478b8bc82Glenn Kastenpublic:
22c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
23c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    // Park the specific FastThread, which can be nullptr, in hot idle if not currently idling
2434f28cbb1d52348deb8dc868530eae2b3f22931eChih-Hung Hsieh    explicit AutoPark(const sp<T>& fastThread) : mFastThread(fastThread)
25c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    {
26c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten        mPreviousCommand = FastThreadState::HOT_IDLE;
27c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten        if (fastThread != nullptr) {
28c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            auto sq = mFastThread->sq();
29c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            FastThreadState *state = sq->begin();
30c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            if (!(state->mCommand & FastThreadState::IDLE)) {
31c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten                mPreviousCommand = state->mCommand;
32c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten                state->mCommand = FastThreadState::HOT_IDLE;
33c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten                sq->end();
34c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten                sq->push(sq->BLOCK_UNTIL_ACKED);
35c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            } else {
36c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten                sq->end(false /*didModify*/);
37c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            }
38c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten        }
39c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    }
40c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
41c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    // Remove the FastThread from hot idle if necessary
42c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    ~AutoPark()
43c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    {
44c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten        if (!(mPreviousCommand & FastThreadState::IDLE)) {
45c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            ALOG_ASSERT(mFastThread != nullptr);
46c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            auto sq = mFastThread->sq();
47c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            FastThreadState *state = sq->begin();
48c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            ALOG_ASSERT(state->mCommand == FastThreadState::HOT_IDLE);
49c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            state->mCommand = mPreviousCommand;
50c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            sq->end();
51c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten            sq->push(sq->BLOCK_UNTIL_PUSHED);
52c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten        }
53c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    }
54c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
55c05b8d7df46619d3474356241d47655478b8bc82Glenn Kastenprivate:
56c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    const sp<T>                 mFastThread;
57c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    // if !&IDLE, holds the FastThread state to restore after new parameters processed
58c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten    FastThreadState::Command    mPreviousCommand;
59c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten};  // class AutoPark
60c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten
61c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten}   // namespace
62