blob: 80f120b0f002bae488d5d6cdd802fff1464ef481 [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() {
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000031 destroyThread();
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000032 LOG(DEBUG) << __func__ << " done";
33};
34
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000035RetCode EffectThread::createThread(const std::string& name, const int priority) {
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000036 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
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000047RetCode EffectThread::destroyThread() {
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000048 {
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
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000061RetCode EffectThread::startThread() {
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000062 if (!mThread.joinable()) {
63 LOG(ERROR) << __func__ << " thread already destroyed";
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000064 return RetCode::ERROR_THREAD;
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000065 }
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
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000081RetCode EffectThread::stopThread() {
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000082 if (!mThread.joinable()) {
83 LOG(ERROR) << __func__ << " thread already destroyed";
Shunkai Yaoa4ab38c2022-10-14 01:07:47 +000084 return RetCode::ERROR_THREAD;
Shunkai Yaoea24c1a2022-09-28 17:39:23 +000085 }
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
Shunkai Yaoea24c1a2022-09-28 17:39:23 +0000120} // namespace aidl::android::hardware::audio::effect