• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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