1 /*
2 # Copyright (C) 2024 HiHope Open Source Organization .
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
17 #include <errno.h>
18 #include <pthread.h>
19 #include <limits.h>
20
pthread_attr_init(pthread_attr_t * attr)21 int pthread_attr_init(pthread_attr_t *attr)
22 {
23 if (attr == NULL) {
24 return EINVAL;
25 }
26
27 attr->detachstate = PTHREAD_CREATE_JOINABLE;
28 attr->schedpolicy = SCHED_RR;
29 attr->schedparam.sched_priority = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
30 attr->inheritsched = PTHREAD_INHERIT_SCHED;
31 attr->scope = PTHREAD_SCOPE_PROCESS;
32 attr->stackaddr_set = 0;
33 attr->stackaddr = NULL;
34 attr->stacksize_set = 1;
35 attr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
36
37 return 0;
38 }
39
pthread_attr_destroy(pthread_attr_t * attr)40 int pthread_attr_destroy(pthread_attr_t *attr)
41 {
42 if (attr == NULL) {
43 return EINVAL;
44 }
45
46 /* Nothing to do here... */
47 return 0;
48 }
49
pthread_attr_setdetachstate(pthread_attr_t * attr,int detachState)50 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState)
51 {
52 if ((attr != NULL) && ((detachState == PTHREAD_CREATE_JOINABLE) || (detachState == PTHREAD_CREATE_DETACHED))) {
53 attr->detachstate = (UINT32)detachState;
54 return 0;
55 }
56
57 return EINVAL;
58 }
59
pthread_attr_getdetachstate(const pthread_attr_t * attr,int * detachState)60 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState)
61 {
62 if ((attr == NULL) || (detachState == NULL)) {
63 return EINVAL;
64 }
65
66 *detachState = (int)attr->detachstate;
67
68 return 0;
69 }
70
pthread_attr_setscope(pthread_attr_t * attr,int scope)71 int pthread_attr_setscope(pthread_attr_t *attr, int scope)
72 {
73 if (attr == NULL) {
74 return EINVAL;
75 }
76
77 if (scope == PTHREAD_SCOPE_PROCESS) {
78 attr->scope = (unsigned int)scope;
79 return 0;
80 }
81
82 if (scope == PTHREAD_SCOPE_SYSTEM) {
83 return ENOTSUP;
84 }
85
86 return EINVAL;
87 }
88
pthread_attr_getscope(const pthread_attr_t * attr,int * scope)89 int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
90 {
91 if ((attr == NULL) || (scope == NULL)) {
92 return EINVAL;
93 }
94
95 *scope = (int)attr->scope;
96
97 return 0;
98 }
99
pthread_attr_setinheritsched(pthread_attr_t * attr,int inherit)100 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
101 {
102 if ((attr != NULL) && ((inherit == PTHREAD_INHERIT_SCHED) || (inherit == PTHREAD_EXPLICIT_SCHED))) {
103 attr->inheritsched = (UINT32)inherit;
104 return 0;
105 }
106
107 return EINVAL;
108 }
109
pthread_attr_getinheritsched(const pthread_attr_t * attr,int * inherit)110 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
111 {
112 if ((attr == NULL) || (inherit == NULL)) {
113 return EINVAL;
114 }
115
116 *inherit = (int)attr->inheritsched;
117
118 return 0;
119 }
120
pthread_attr_setschedpolicy(pthread_attr_t * attr,int policy)121 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
122 {
123 if ((attr != NULL) && (policy == SCHED_RR)) {
124 attr->schedpolicy = SCHED_RR;
125 return 0;
126 }
127
128 return EINVAL;
129 }
130
pthread_attr_getschedpolicy(const pthread_attr_t * attr,int * policy)131 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
132 {
133 if ((attr == NULL) || (policy == NULL)) {
134 return EINVAL;
135 }
136
137 *policy = (int)attr->schedpolicy;
138
139 return 0;
140 }
141
pthread_attr_setschedparam(pthread_attr_t * attr,const struct sched_param * param)142 int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
143 {
144 if ((attr == NULL) || (param == NULL)) {
145 return EINVAL;
146 } else if ((param->sched_priority < OS_TASK_PRIORITY_HIGHEST) ||
147 (param->sched_priority >= OS_TASK_PRIORITY_LOWEST)) {
148 return ENOTSUP;
149 }
150
151 attr->schedparam = *param;
152
153 return 0;
154 }
155
pthread_attr_getschedparam(const pthread_attr_t * attr,struct sched_param * param)156 int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
157 {
158 if ((attr == NULL) || (param == NULL)) {
159 return EINVAL;
160 }
161
162 *param = attr->schedparam;
163
164 return 0;
165 }
166
167 /*
168 * Set starting address of stack. Whether this is at the start or end of
169 * the memory block allocated for the stack depends on whether the stack
170 * grows up or down.
171 */
pthread_attr_setstackaddr(pthread_attr_t * attr,void * stackAddr)172 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr)
173 {
174 if (attr == NULL) {
175 return EINVAL;
176 }
177
178 attr->stackaddr_set = 1;
179 attr->stackaddr = stackAddr;
180
181 return 0;
182 }
183
pthread_attr_getstackaddr(const pthread_attr_t * attr,void ** stackAddr)184 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr)
185 {
186 if (((attr != NULL) && (stackAddr != NULL)) && attr->stackaddr_set) {
187 *stackAddr = attr->stackaddr;
188 return 0;
189 }
190
191 return EINVAL; /* Stack address not set, return EINVAL. */
192 }
193
pthread_attr_setstacksize(pthread_attr_t * attr,size_t stackSize)194 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
195 {
196 /* Reject inadequate stack sizes */
197 if ((attr == NULL) || (stackSize < PTHREAD_STACK_MIN)) {
198 return EINVAL;
199 }
200
201 attr->stacksize_set = 1;
202 attr->stacksize = stackSize;
203
204 return 0;
205 }
206
pthread_attr_getstacksize(const pthread_attr_t * attr,size_t * stackSize)207 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
208 {
209 /* Reject attempts to get a stack size when one has not been set. */
210 if ((attr == NULL) || (stackSize == NULL) || (!attr->stacksize_set)) {
211 return EINVAL;
212 }
213
214 *stackSize = attr->stacksize;
215
216 return 0;
217 }
218