• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 #include "os/thread.h"
17 
18 #include "utils/span.h"
19 #include "utils/logger.h"
20 
21 #include <cstdio>
22 
23 #include <array>
24 #include <cstdint>
25 #include "os/failure_retry.h"
26 #ifdef PANDA_TARGET_UNIX
27 #include <fcntl.h>
28 #include <pthread.h>
29 #include <unistd.h>
30 #include <sys/resource.h>
31 #include <sys/syscall.h>
32 #include <csignal>
33 #endif
34 #include <securec.h>
35 #include <unistd.h>
36 
37 namespace panda::os::thread {
38 
GetCurrentThreadId()39 ThreadId GetCurrentThreadId()
40 {
41 #if defined(HAVE_GETTID)
42     static_assert(sizeof(decltype(gettid())) == sizeof(ThreadId), "Incorrect alias for ThreadID");
43     return static_cast<ThreadId>(gettid());
44 #elif defined(PANDA_TARGET_MACOS) || defined(PANDA_TARGET_IOS)
45     uint64_t tid64;
46     pthread_threadid_np(NULL, &tid64);
47     return static_cast<ThreadId>(tid64);
48 #else
49     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
50     return static_cast<ThreadId>(syscall(SYS_gettid));
51 #endif
52 }
53 
GetPid()54 int GetPid()
55 {
56     return getpid();
57 }
58 
SetPriority(int thread_id,int prio)59 int SetPriority(int thread_id, int prio)
60 {
61     // The priority can be set within range [-20, 19]
62     ASSERT(prio <= 19);  // 19: the lowest priority
63     ASSERT(prio >= -20);  // -20: the highest priority
64     // The return value is 0 if the function succeeds, and -1 if it fails.
65     return setpriority(PRIO_PROCESS, thread_id, prio);
66 }
67 
GetPriority(int thread_id)68 int GetPriority(int thread_id)
69 {
70     return getpriority(PRIO_PROCESS, thread_id);
71 }
72 
SetThreadName(native_handle_type pthread_handle,const char * name)73 int SetThreadName(native_handle_type pthread_handle, const char *name)
74 {
75     ASSERT(pthread_handle != 0);
76 #if defined(PANDA_TARGET_MACOS) || defined(PANDA_TARGET_IOS)
77     return pthread_setname_np(name);
78 #else
79     return pthread_setname_np(pthread_handle, name);
80 #endif
81 }
82 
GetNativeHandle()83 native_handle_type GetNativeHandle()
84 {
85     return pthread_self();
86 }
87 
ThreadYield()88 void ThreadYield()
89 {
90     std::this_thread::yield();
91 }
92 
NativeSleep(unsigned int ms)93 void NativeSleep(unsigned int ms)
94 {
95     std::this_thread::sleep_for(std::chrono::milliseconds(ms));
96 }
97 
ThreadDetach(native_handle_type pthread_handle)98 void ThreadDetach(native_handle_type pthread_handle)
99 {
100     pthread_detach(pthread_handle);
101 }
102 
ThreadExit(void * ret)103 void ThreadExit(void *ret)
104 {
105     pthread_exit(ret);
106 }
107 
ThreadJoin(native_handle_type pthread_handle,void ** ret)108 void ThreadJoin(native_handle_type pthread_handle, void **ret)
109 {
110     pthread_join(pthread_handle, ret);
111 }
112 
ThreadSendSignal(native_handle_type pthread_handle,int sig)113 void ThreadSendSignal(native_handle_type pthread_handle, int sig)
114 {
115     LOG_IF(pthread_kill(pthread_handle, sig) != 0, FATAL, COMMON) << "pthread_kill failed";
116 }
117 
ThreadGetStackInfo(native_handle_type thread,void ** stack_addr,size_t * stack_size,size_t * guard_size)118 int ThreadGetStackInfo(native_handle_type thread, void **stack_addr, size_t *stack_size, size_t *guard_size)
119 {
120     pthread_attr_t attr;
121     int s = pthread_attr_init(&attr);
122 #if !defined(PANDA_TARGET_MACOS) && !defined(PANDA_TARGET_IOS)
123     s += pthread_getattr_np(thread, &attr);
124     if (s == 0) {
125         s += pthread_attr_getguardsize(&attr, guard_size);
126         s += pthread_attr_getstack(&attr, stack_addr, stack_size);
127     }
128 #else
129     s += pthread_attr_getguardsize(&attr, guard_size);
130     s += pthread_attr_getstack(&attr, stack_addr, stack_size);
131 #endif
132     s += pthread_attr_destroy(&attr);
133     return s;
134 }
135 
136 }  // namespace panda::os::thread
137