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         mStop = false;
72         mCv.notify_one();
73     }
74 
75     LOG(VERBOSE) << mName << __func__;
76     return RetCode::SUCCESS;
77 }
78 
stopThread()79 RetCode EffectThread::stopThread() {
80     {
81         std::lock_guard lg(mThreadMutex);
82         mStop = true;
83         mCv.notify_one();
84     }
85 
86     LOG(VERBOSE) << mName << __func__;
87     return RetCode::SUCCESS;
88 }
89 
threadLoop()90 void EffectThread::threadLoop() {
91     pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
92     setpriority(PRIO_PROCESS, 0, mPriority);
93     while (true) {
94         {
95             std::unique_lock l(mThreadMutex);
96             ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
97             mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
98             if (mExit) {
99                 LOG(VERBOSE) << mName << " threadLoop EXIT!";
100                 return;
101             }
102         }
103         process();
104     }
105 }
106 
107 }  // namespace aidl::android::hardware::audio::effect
108