1 /*
2 * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2022-11-15
13 * Description: pthread attr功能实现
14 */
15
16 #include "pthread.h"
17 #include "sched.h"
18 #include "prt_posix_internal.h"
19
pthread_attr_init(pthread_attr_t * attr)20 int pthread_attr_init(pthread_attr_t *attr)
21 {
22 if (attr == NULL) {
23 return ENOMEM;
24 }
25
26 attr->schedpolicy = PTHREAD_DEFAULT_POLICY;
27 attr->stackaddr = NULL;
28 attr->stacksize = (int)g_tskModInfo.defaultSize;
29 attr->schedparam.sched_priority = PTHREAD_DEFAULT_PRIORITY;
30 attr->detachstate = PTHREAD_CREATE_JOINABLE;
31 attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
32 attr->is_initialized = PTHREAD_ATTR_INIT;
33
34 return OS_OK;
35 }
36
pthread_attr_destroy(pthread_attr_t * attr)37 int pthread_attr_destroy(pthread_attr_t *attr)
38 {
39 if (attr != NULL && attr->is_initialized != PTHREAD_ATTR_UNINIT) {
40 *attr = (pthread_attr_t){0};
41 return OS_OK;
42 }
43
44 return EINVAL;
45 }
46
pthread_attr_getdetachstate(const pthread_attr_t * attr,int * detachState)47 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState)
48 {
49 if (attr == NULL || detachState == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
50 return EINVAL;
51 }
52
53 *detachState = attr->detachstate;
54
55 return OS_OK;
56 }
57
pthread_attr_setdetachstate(pthread_attr_t * attr,int detachState)58 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState)
59 {
60 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
61 return EINVAL;
62 }
63
64 if (detachState > PTHREAD_CREATE_JOINABLE || detachState < PTHREAD_CREATE_DETACHED) {
65 return EINVAL;
66 }
67
68 attr->detachstate = detachState;
69
70 return OS_OK;
71 }
72
pthread_attr_getschedpolicy(const pthread_attr_t * attr,int * schedpolicy)73 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *schedpolicy)
74 {
75 if (attr == NULL || schedpolicy == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
76 return EINVAL;
77 }
78
79 *schedpolicy = attr->schedpolicy;
80
81 return OS_OK;
82 }
83
pthread_attr_setschedpolicy(pthread_attr_t * attr,int schedpolicy)84 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy)
85 {
86 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT || schedpolicy > PTHREAD_DEFAULT_POLICY) {
87 return EINVAL;
88 }
89
90 if (schedpolicy < 0) {
91 return ENOTSUP;
92 }
93
94 attr->schedpolicy = schedpolicy;
95
96 return OS_OK;
97 }
98
pthread_attr_getstacksize(const pthread_attr_t * attr,size_t * stackSize)99 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
100 {
101 if (attr == NULL || stackSize == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
102 return EINVAL;
103 }
104
105 *stackSize = attr->stacksize;
106
107 return OS_OK;
108 }
109
pthread_attr_setstacksize(pthread_attr_t * attr,size_t stackSize)110 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
111 {
112 U64 stackAddrLen;
113
114 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
115 return EINVAL;
116 }
117
118 if (stackSize < OS_TSK_MIN_STACK_SIZE) {
119 return EINVAL;
120 }
121
122 stackAddrLen = (U64)(stackSize);
123 /* posix接口不实现msgq, queNum默认为0 */
124 if ((uintptr_t)attr->stackaddr != 0U) {
125 stackAddrLen += (uintptr_t)(attr->stackaddr);
126 }
127 /* 保证栈空间在4G范围内不溢出 */
128 if (stackAddrLen > OS_MAX_U32) {
129 return EINVAL;
130 }
131
132 attr->stacksize = (int)stackSize;
133
134 return OS_OK;
135 }
136
pthread_attr_getstackaddr(const pthread_attr_t * attr,void ** stackAddr)137 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr)
138 {
139 if (attr == NULL || stackAddr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
140 return EINVAL;
141 }
142
143 *stackAddr = attr->stackaddr;
144
145 return OS_OK;
146 }
147
pthread_attr_setstackaddr(pthread_attr_t * attr,void * stackAddr)148 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr)
149 {
150 U64 stackAddrLen;
151
152 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
153 return EINVAL;
154 }
155
156 stackAddrLen = (U32)(attr->stacksize);
157 /* posix接口不实现msgq, queNum默认为0 */
158 if ((uintptr_t)stackAddr != 0U) {
159 stackAddrLen += (uintptr_t)(stackAddr);
160 }
161 /* 保证栈空间在4G范围内不溢出 */
162 if (stackAddrLen > OS_MAX_U32) {
163 return EINVAL;
164 }
165
166 attr->stackaddr = stackAddr;
167
168 return OS_OK;
169 }
170
pthread_attr_getstack(const pthread_attr_t * attr,void ** stackAddr,size_t * stackSize)171 int pthread_attr_getstack(const pthread_attr_t *attr, void **stackAddr, size_t *stackSize)
172 {
173 if (attr == NULL || stackAddr == NULL || stackSize == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
174 return EINVAL;
175 }
176
177 *stackAddr = attr->stackaddr;
178 *stackSize = attr->stacksize;
179
180 return OS_OK;
181 }
182
pthread_attr_setstack(pthread_attr_t * attr,void * stackAddr,size_t stackSize)183 int pthread_attr_setstack(pthread_attr_t *attr, void *stackAddr, size_t stackSize)
184 {
185 U64 stackAddrLen;
186
187 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
188 return EINVAL;
189 }
190
191 if (stackSize < (long)OS_TSK_MIN_STACK_SIZE) {
192 return EINVAL;
193 }
194
195 stackAddrLen = (U64)(stackSize);
196 /* posix接口不实现msgq, queNum默认为0 */
197 if ((uintptr_t)stackAddr != 0U) {
198 stackAddrLen += (uintptr_t)(stackAddr);
199 }
200 /* 保证栈空间在4G范围内不溢出 */
201 if (stackAddrLen > OS_MAX_U32) {
202 return EINVAL;
203 }
204
205 attr->stackaddr = stackAddr;
206 attr->stacksize = (int)stackSize;
207
208 return OS_OK;
209 }
210
pthread_attr_getinheritsched(const pthread_attr_t * attr,int * inheritsched)211 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
212 {
213 if (attr == NULL || inheritsched == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
214 return EINVAL;
215 }
216
217 *inheritsched = attr->inheritsched;
218
219 return OS_OK;
220 }
221
pthread_attr_setinheritsched(pthread_attr_t * attr,int inheritsched)222 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
223 {
224 if (attr == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
225 return EINVAL;
226 }
227
228 if ((U32)inheritsched > (U32)PTHREAD_EXPLICIT_SCHED) {
229 return EINVAL;
230 }
231
232 attr->inheritsched = inheritsched;
233
234 return OS_OK;
235 }
236
pthread_attr_getschedparam(const pthread_attr_t * attr,struct sched_param * schedparam)237 int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *schedparam)
238 {
239 if (attr == NULL || schedparam == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
240 return EINVAL;
241 }
242
243 schedparam->sched_priority = attr->schedparam.sched_priority;
244
245 return OS_OK;
246 }
247
pthread_attr_setschedparam(pthread_attr_t * attr,const struct sched_param * schedparam)248 int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *schedparam)
249 {
250 if (attr == NULL || schedparam == NULL || attr->is_initialized == PTHREAD_ATTR_UNINIT) {
251 return EINVAL;
252 }
253 /* task 优先级范围 OS_TSK_PRIORITY_HIGHEST <= priority < OS_TSK_PRIORITY_LOWEST, 避免与idle线程优先级一致得不到调度 */
254 if (schedparam->sched_priority < OS_TSK_PRIORITY_HIGHEST || schedparam->sched_priority >= OS_TSK_PRIORITY_LOWEST) {
255 return ENOTSUP;
256 }
257
258 attr->schedparam.sched_priority = schedparam->sched_priority;
259
260 return OS_OK;
261 }
262