• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace OHOS {
23 namespace Media {
Thread(ThreadPriority priority)24 Thread::Thread(ThreadPriority priority) noexcept : id_(), name_(), priority_(priority), state_()
25 {
26 }
27 
Thread(Thread && other)28 Thread::Thread(Thread&& other) noexcept
29 {
30     *this = std::move(other);
31 }
32 
operator =(Thread && other)33 Thread& Thread::operator=(Thread&& other) noexcept
34 {
35     if (this != &other) {
36         AutoLock lock(mutex_);
37         id_ = other.id_;
38         name_ = std::move(other.name_);
39         priority_ = other.priority_;
40         state_ = std::move(other.state_);
41     }
42     return *this;
43 }
44 
~Thread()45 Thread::~Thread() noexcept
46 {
47     if (isExistThread_.load()) {
48         pthread_join(id_, nullptr);
49     }
50 }
51 
HasThread() const52 bool Thread::HasThread() const noexcept
53 {
54     AutoLock lock(mutex_);
55     return state_ != nullptr;
56 }
57 
SetName(const std::string & name)58 void Thread::SetName(const std::string& name)
59 {
60     name_ = name;
61 }
62 
CreateThread(const std::function<void ()> & func)63 bool Thread::CreateThread(const std::function<void()>& func)
64 {
65     {
66         AutoLock lock(mutex_);
67         state_ = std::make_unique<State>();
68         state_->func = func;
69         state_->name = name_;
70     }
71     pthread_attr_t attr;
72     pthread_attr_init(&attr);
73     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
74 #ifdef OHOS_LITE
75     // Only OHOS_LITE can set inheritsched and schedpolicy.
76     pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
77     pthread_attr_setschedpolicy(&attr, SCHED_RR);
78 #endif
79     struct sched_param sched = {static_cast<int>(priority_)};
80     pthread_attr_setschedparam(&attr, &sched);
81 #if defined(THREAD_STACK_SIZE) and THREAD_STACK_SIZE > 0
82     pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
83     MEDIA_LOG_I("thread stack size set to " PUBLIC_LOG_D32, THREAD_STACK_SIZE);
84 #endif
85     int rtv = pthread_create(&id_, &attr, Thread::Run, this);
86     if (rtv == 0) {
87         MEDIA_LOG_I("thread " PUBLIC_LOG_S " create success", name_.c_str());
88         isExistThread_.store(true);
89         SetNameInternal();
90     } else {
91         AutoLock lock(mutex_);
92         if (state_ != nullptr) {
93             state_.reset();
94         }
95         MEDIA_LOG_E("thread create failed, name: " PUBLIC_LOG_S ", rtv: " PUBLIC_LOG_D32, name_.c_str(), rtv);
96     }
97     return rtv == 0;
98 }
99 
IsRunningInSelf()100 bool Thread::IsRunningInSelf()
101 {
102     pthread_t tid = pthread_self();
103     AutoLock lock(mutex_);
104     return tid == id_;
105 }
106 
SetNameInternal()107 void Thread::SetNameInternal()
108 {
109     AutoLock lock(mutex_);
110     if (state_ && !name_.empty()) {
111         constexpr int threadNameMaxSize = 15;
112         if (name_.size() > threadNameMaxSize) {
113             MEDIA_LOG_W("task name " PUBLIC_LOG_S " exceed max size: " PUBLIC_LOG_D32,
114                         name_.c_str(), threadNameMaxSize);
115             name_ = name_.substr(0, threadNameMaxSize);
116         }
117         pthread_setname_np(id_, name_.c_str());
118     }
119 }
120 
Run(void * arg)121 void* Thread::Run(void* arg) // NOLINT: void*
122 {
123     std::function<void()> func;
124     std::string name;
125     {
126         auto currentThread = static_cast<Thread *>(arg);
127         AutoLock lock(currentThread->mutex_);
128         auto state = currentThread->state_.get();
129         if (state == nullptr) {
130             return nullptr;
131         }
132         func = state->func;
133         name = state->name;
134     }
135     func();
136     {
137         auto currentThread = static_cast<Thread *>(arg);
138         AutoLock lock(currentThread->mutex_);
139         currentThread->state_ = nullptr;
140     }
141     MEDIA_LOG_W("Thread " PUBLIC_LOG_S " exited...", name.c_str());
142     return nullptr;
143 }
144 } // namespace Media
145 } // namespace OHOS
146