• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2021 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 "thread.h"
19 #include <new>
20 #include <type_traits>
21 #include "foundation/log.h"
22 
23 namespace OHOS {
24 namespace Media {
25 namespace OSAL {
Thread(ThreadPriority priority)26 Thread::Thread(ThreadPriority priority) noexcept : id_(), name_(), priority_(priority), state_()
27 {
28 }
29 
Thread(Thread && other)30 Thread::Thread(Thread&& other) noexcept
31 {
32     *this = std::move(other);
33 }
34 
operator =(Thread && other)35 Thread& Thread::operator=(Thread&& other) noexcept
36 {
37     if (this != &other) {
38         id_ = other.id_;
39         name_ = std::move(other.name_);
40         priority_ = other.priority_;
41         state_ = std::move(other.state_);
42     }
43     return *this;
44 }
45 
~Thread()46 Thread::~Thread() noexcept
47 {
48     if (state_) {
49         pthread_join(id_, nullptr);
50     }
51 }
52 
HasThread() const53 bool Thread::HasThread() const noexcept
54 {
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     state_ = std::unique_ptr<State>(new State);
66     state_->func = func;
67     state_->name = name_;
68     pthread_attr_t attr;
69     pthread_attr_init(&attr);
70     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
71 #ifdef OHOS_LITE
72     // Only OHOS_LITE can set inheritsched and schedpolicy.
73     pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
74     pthread_attr_setschedpolicy(&attr, SCHED_RR);
75 #endif
76     struct sched_param sched = {static_cast<int>(priority_)};
77     pthread_attr_setschedparam(&attr, &sched);
78 #if defined(THREAD_STACK_SIZE) and THREAD_STACK_SIZE > 0
79     pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
80     MEDIA_LOG_I("thread stack size set to " PUBLIC_LOG_D32, THREAD_STACK_SIZE);
81 #endif
82     int rtv = pthread_create(&id_, &attr, Thread::Run, state_.get());
83     if (rtv == 0) {
84         MEDIA_LOG_I("thread " PUBLIC_LOG_S " create success", name_.c_str());
85         SetNameInternal();
86     } else {
87         state_.reset();
88         MEDIA_LOG_E("thread create failed, name: " PUBLIC_LOG_S ", rtv: " PUBLIC_LOG_D32, name_.c_str(), rtv);
89     }
90     return rtv == 0;
91 }
92 
SetNameInternal()93 void Thread::SetNameInternal()
94 {
95 #ifdef SUPPORT_PTHREAD_NAME
96     if (state_ && !name_.empty()) {
97         constexpr int threadNameMaxSize = 15;
98         if (name_.size() > threadNameMaxSize) {
99             MEDIA_LOG_W("task name " PUBLIC_LOG_S " exceed max size: " PUBLIC_LOG_D32,
100                         name_.c_str(), threadNameMaxSize);
101             name_ = name_.substr(0, threadNameMaxSize);
102         }
103         pthread_setname_np(id_, name_.c_str());
104     }
105 #endif
106 }
107 
Run(void * arg)108 void* Thread::Run(void* arg) // NOLINT: void*
109 {
110     auto state = static_cast<State*>(arg);
111     if (state && state->func) {
112         const std::string name = state->name;
113         state->func();
114         MEDIA_LOG_W("Thread " PUBLIC_LOG_S " exited...", name.c_str());
115     }
116     return nullptr;
117 }
118 } // namespace OSAL
119 } // namespace Media
120 } // namespace OHOS
121