xref: /aosp_15_r20/hardware/interfaces/audio/aidl/default/EffectThread.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
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 #include <cstddef>
18 #include <memory>
19 
20 #define LOG_TAG "AHAL_EffectThread"
21 #include <android-base/logging.h>
22 #include <pthread.h>
23 #include <sys/resource.h>
24 
25 #include "effect-impl/EffectThread.h"
26 #include "effect-impl/EffectTypes.h"
27 
28 namespace aidl::android::hardware::audio::effect {
29 
~EffectThread()30 EffectThread::~EffectThread() {
31     destroyThread();
32 }
33 
createThread(const std::string & name,int priority)34 RetCode EffectThread::createThread(const std::string& name, int priority) {
35     if (mThread.joinable()) {
36         LOG(WARNING) << mName << __func__ << " thread already created, no-op";
37         return RetCode::SUCCESS;
38     }
39 
40     mName = name;
41     mPriority = priority;
42     {
43         std::lock_guard lg(mThreadMutex);
44         mStop = true;
45         mExit = false;
46     }
47 
48     mThread = std::thread(&EffectThread::threadLoop, this);
49     LOG(VERBOSE) << mName << __func__ << " priority " << mPriority << " done";
50     return RetCode::SUCCESS;
51 }
52 
destroyThread()53 RetCode EffectThread::destroyThread() {
54     {
55         std::lock_guard lg(mThreadMutex);
56         mStop = mExit = true;
57     }
58 
59     mCv.notify_one();
60     if (mThread.joinable()) {
61         mThread.join();
62     }
63 
64     LOG(VERBOSE) << mName << __func__;
65     return RetCode::SUCCESS;
66 }
67 
startThread()68 RetCode EffectThread::startThread() {
69     {
70         std::lock_guard lg(mThreadMutex);
71         if (mDraining) {
72             mDraining = false;
73         } else {
74             mStop = false;
75         }
76         mCv.notify_one();
77     }
78 
79     LOG(VERBOSE) << mName << __func__;
80     return RetCode::SUCCESS;
81 }
82 
stopThread()83 RetCode EffectThread::stopThread() {
84     {
85         std::lock_guard lg(mThreadMutex);
86         mStop = true;
87         mCv.notify_one();
88     }
89 
90     LOG(VERBOSE) << mName << __func__;
91     return RetCode::SUCCESS;
92 }
93 
startDraining()94 RetCode EffectThread::startDraining() {
95     std::lock_guard lg(mThreadMutex);
96     mDraining = true;
97     mCv.notify_one();
98 
99     LOG(VERBOSE) << mName << __func__;
100     return RetCode::SUCCESS;
101 }
102 
finishDraining()103 RetCode EffectThread::finishDraining() {
104     std::lock_guard lg(mThreadMutex);
105     mDraining = false;
106     mStop = true;
107     mCv.notify_one();
108 
109     LOG(VERBOSE) << mName << __func__;
110     return RetCode::SUCCESS;
111 }
112 
threadLoop()113 void EffectThread::threadLoop() {
114     pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
115     setpriority(PRIO_PROCESS, 0, mPriority);
116     while (true) {
117         {
118             std::unique_lock l(mThreadMutex);
119             ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
120             mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
121             if (mExit) {
122                 LOG(VERBOSE) << mName << " threadLoop EXIT!";
123                 return;
124             }
125         }
126         process();
127     }
128 }
129 
130 }  // namespace aidl::android::hardware::audio::effect
131