1/* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#define HST_LOG_TAG "Thread" 17 18#include "osal/task/thread.h" 19#include "common/log.h" 20#include "osal/task/autolock.h" 21 22namespace { 23constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "Thread" }; 24} 25 26namespace OHOS { 27namespace Media { 28Thread::Thread(ThreadPriority priority) noexcept : id_(), name_(), priority_(priority), state_() 29{ 30} 31 32Thread::Thread(Thread&& other) noexcept 33{ 34 *this = std::move(other); 35} 36 37Thread& Thread::operator=(Thread&& other) noexcept 38{ 39 if (this != &other) { 40 AutoLock lock(mutex_); 41 id_ = other.id_; 42 name_ = std::move(other.name_); 43 priority_ = other.priority_; 44 state_ = std::move(other.state_); 45 } 46 return *this; 47} 48 49Thread::~Thread() noexcept 50{ 51 if (isExistThread_.load()) { 52 pthread_join(id_, nullptr); 53 } 54} 55 56bool Thread::HasThread() const noexcept 57{ 58 AutoLock lock(mutex_); 59 return state_ != nullptr; 60} 61 62void Thread::SetName(const std::string& name) 63{ 64 name_ = name; 65} 66 67bool Thread::CreateThread(const std::function<void()>& func) 68{ 69 { 70 AutoLock lock(mutex_); 71 state_ = std::make_unique<State>(); 72 state_->func = func; 73 state_->name = name_; 74 } 75 pthread_attr_t attr; 76 pthread_attr_init(&attr); 77 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 78#ifdef OHOS_LITE 79 // Only OHOS_LITE can set inheritsched and schedpolicy. 80 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 81 pthread_attr_setschedpolicy(&attr, SCHED_RR); 82#endif 83 struct sched_param sched = {static_cast<int>(priority_)}; 84 pthread_attr_setschedparam(&attr, &sched); 85#if defined(THREAD_STACK_SIZE) and THREAD_STACK_SIZE > 0 86 pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE); 87 MEDIA_LOG_I("thread stack size set to " PUBLIC_LOG_D32, THREAD_STACK_SIZE); 88#endif 89 int rtv = pthread_create(&id_, &attr, Thread::Run, this); 90 if (rtv == 0) { 91 MEDIA_LOG_D("thread " PUBLIC_LOG_S " create success", name_.c_str()); 92 isExistThread_.store(true); 93 SetNameInternal(); 94 } else { 95 AutoLock lock(mutex_); 96 if (state_ != nullptr) { 97 state_.reset(); 98 } 99 MEDIA_LOG_E("thread create failed, name: " PUBLIC_LOG_S ", rtv: " PUBLIC_LOG_D32, name_.c_str(), rtv); 100 } 101 return rtv == 0; 102} 103 104bool Thread::IsRunningInSelf() 105{ 106 pthread_t tid = pthread_self(); 107 AutoLock lock(mutex_); 108 return tid == id_; 109} 110 111void Thread::SetNameInternal() 112{ 113 AutoLock lock(mutex_); 114 if (state_ && !name_.empty()) { 115 constexpr int threadNameMaxSize = 15; 116 if (name_.size() > threadNameMaxSize) { 117 MEDIA_LOG_W("task name " PUBLIC_LOG_S " exceed max size: " PUBLIC_LOG_D32, 118 name_.c_str(), threadNameMaxSize); 119 name_ = name_.substr(0, threadNameMaxSize); 120 } 121 pthread_setname_np(id_, name_.c_str()); 122 } 123} 124 125void* Thread::Run(void* arg) // NOLINT: void* 126{ 127 std::function<void()> func; 128 std::string name; 129 { 130 auto currentThread = static_cast<Thread *>(arg); 131 AutoLock lock(currentThread->mutex_); 132 auto state = currentThread->state_.get(); 133 if (state == nullptr) { 134 return nullptr; 135 } 136 func = state->func; 137 name = state->name; 138 } 139 func(); 140 { 141 auto currentThread = static_cast<Thread *>(arg); 142 AutoLock lock(currentThread->mutex_); 143 currentThread->state_ = nullptr; 144 } 145 MEDIA_LOG_W("Thread " PUBLIC_LOG_S " exited...", name.c_str()); 146 return nullptr; 147} 148} // namespace Media 149} // namespace OHOS 150