blob: 0ad9a146c61a4c51ca87d49199162aa58ba22725 [file] [log] [blame]
Shunkai Yaoea24c1a2022-09-28 17:39:23 +00001/*
2 * Copyright (C) 2022 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#define LOG_TAG "AHAL_EffectThread"
18#include <android-base/logging.h>
19#include <pthread.h>
20#include <sys/resource.h>
21
22#include "effect-impl/EffectThread.h"
23
24namespace aidl::android::hardware::audio::effect {
25
26EffectThread::EffectThread() {
27 LOG(DEBUG) << __func__;
28}
29
30EffectThread::~EffectThread() {
31 destroy();
32 LOG(DEBUG) << __func__ << " done";
33};
34
35RetCode EffectThread::create(const std::string& name, const int priority) {
36 if (mThread.joinable()) {
37 LOG(WARNING) << __func__ << " thread already created, no-op";
38 return RetCode::SUCCESS;
39 }
40 mName = name;
41 mPriority = priority;
42 mThread = std::thread(&EffectThread::threadLoop, this);
43 LOG(DEBUG) << __func__ << " " << name << " priority " << mPriority << " done";
44 return RetCode::SUCCESS;
45}
46
47RetCode EffectThread::destroy() {
48 {
49 std::lock_guard lg(mMutex);
50 mStop = mExit = true;
51 }
52 mCv.notify_one();
53
54 if (mThread.joinable()) {
55 mThread.join();
56 }
57 LOG(DEBUG) << __func__ << " done";
58 return RetCode::SUCCESS;
59}
60
61RetCode EffectThread::start() {
62 if (!mThread.joinable()) {
63 LOG(ERROR) << __func__ << " thread already destroyed";
64 return RetCode::ERROR;
65 }
66
67 {
68 std::lock_guard lg(mMutex);
69 if (!mStop) {
70 LOG(WARNING) << __func__ << " already start";
71 return RetCode::SUCCESS;
72 }
73 mStop = false;
74 }
75
76 mCv.notify_one();
77 LOG(DEBUG) << __func__ << " done";
78 return RetCode::SUCCESS;
79}
80
81RetCode EffectThread::stop() {
82 if (!mThread.joinable()) {
83 LOG(ERROR) << __func__ << " thread already destroyed";
84 return RetCode::ERROR;
85 }
86
87 {
88 std::lock_guard lg(mMutex);
89 if (mStop) {
90 LOG(WARNING) << __func__ << " already stop";
91 return RetCode::SUCCESS;
92 }
93 mStop = true;
94 }
95 LOG(DEBUG) << __func__ << " done";
96 return RetCode::SUCCESS;
97}
98
99void EffectThread::threadLoop() {
100 pthread_setname_np(pthread_self(), mName.substr(0, MAX_TASK_COMM_LEN - 1).c_str());
101 setpriority(PRIO_PROCESS, 0, mPriority);
102 while (true) {
103 bool needExit = false;
104 {
105 std::unique_lock l(mMutex);
106 mCv.wait(l, [&]() REQUIRES(mMutex) {
107 needExit = mExit;
108 return mExit || !mStop;
109 });
110 }
111 if (needExit) {
112 LOG(WARNING) << __func__ << " EXIT!";
113 return;
114 }
115 // process without lock
116 process();
117 }
118}
119
120std::string toString(RetCode& code) {
121 switch (code) {
122 case RetCode::SUCCESS:
123 return "SUCCESS";
124 case RetCode::ERROR:
125 return "ERROR";
126 default:
127 return "EnumError";
128 }
129}
130
131} // namespace aidl::android::hardware::audio::effect