1 /*
2 * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3 */
4
5 #include <errno.h>
6 #include <string.h>
7 #include <pthread.h>
8 #include <sched.h>
9
10 #include "internal/pthread.h"
11
pthread_attr_init(pthread_attr_t * attr)12 int pthread_attr_init(pthread_attr_t *attr)
13 {
14 if (attr == NULL) {
15 return EINVAL;
16 }
17
18 memset(attr, 0, sizeof(pthread_attr_t));
19 attr->stacksize = PTHREAD_DEFAULT_STACK_SIZE;
20 attr->sched_priority = PTHREAD_DEFAULT_PRIORITY;
21 attr->sched_slice = PTHREAD_DEFAULT_SLICE;
22 attr->detachstate = PTHREAD_CREATE_JOINABLE;
23 attr->contentionscope = PTHREAD_SCOPE_SYSTEM;
24 attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
25 attr->guardsize = PTHREAD_DEFAULT_GUARD_SIZE;
26 attr->stackaddr = NULL;
27 attr->flag = PTHREAD_DYN_INIT;
28
29 return 0;
30 }
31
pthread_attr_destroy(pthread_attr_t * attr)32 int pthread_attr_destroy(pthread_attr_t *attr)
33 {
34 if (attr == NULL) {
35 return EINVAL;
36 }
37
38 memset(attr, 0, sizeof(pthread_attr_t));
39
40 return 0;
41 }
42
pthread_attr_setdetachstate(pthread_attr_t * attr,int detachstate)43 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
44 {
45 if ((attr == NULL) || ((detachstate != PTHREAD_CREATE_DETACHED) &&
46 (detachstate != PTHREAD_CREATE_JOINABLE))) {
47 return EINVAL;
48 }
49
50 attr->detachstate = detachstate;
51
52 return 0;
53 }
54
pthread_attr_getdetachstate(const pthread_attr_t * attr,int * detachstate)55 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
56 {
57 if ((attr == NULL) || (detachstate == NULL)) {
58 return EINVAL;
59 }
60
61 *detachstate = attr->detachstate;
62
63 return 0;
64 }
65
pthread_attr_setschedpolicy(pthread_attr_t * attr,int policy)66 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
67 {
68 if ((attr == NULL) || ((policy < SCHED_OTHER) || (policy > SCHED_RR))) {
69 return EINVAL;
70 }
71
72 attr->schedpolicy = policy;
73
74 return 0;
75 }
76
pthread_attr_getschedpolicy(const pthread_attr_t * attr,int * policy)77 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
78 {
79 if ((attr == NULL) || (policy == NULL)) {
80 return EINVAL;
81 }
82
83 *policy = attr->schedpolicy;
84
85 return 0;
86 }
87
pthread_attr_setschedparam(pthread_attr_t * attr,const struct sched_param * param)88 int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
89 {
90 if ((attr == NULL) || (param == NULL)) {
91 return EINVAL;
92 }
93
94 attr->sched_priority = param->sched_priority;
95 attr->sched_slice = param->slice;
96 return 0;
97 }
98
pthread_attr_getschedparam(const pthread_attr_t * attr,struct sched_param * param)99 int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
100 {
101 if ((attr == NULL) || (param == NULL)) {
102 return EINVAL;
103 }
104
105 param->sched_priority = attr->sched_priority;
106 param->slice = attr->sched_slice;
107
108 return 0;
109 }
110
pthread_attr_setstacksize(pthread_attr_t * attr,size_t stacksize)111 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
112 {
113 if ((attr == NULL) || (stacksize <= 0)) {
114 return EINVAL;
115 }
116
117 attr->stacksize = stacksize;
118
119 return 0;
120 }
121
pthread_attr_getstacksize(const pthread_attr_t * attr,size_t * stacksize)122 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
123 {
124 if ((attr == NULL) || (stacksize == NULL)) {
125 return EINVAL;
126 }
127
128 *stacksize = attr->stacksize;
129
130 return 0;
131 }
132
pthread_attr_setstackaddr(pthread_attr_t * attr,void * stackaddr)133 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
134 {
135 if ((attr == NULL) || (stackaddr == NULL)) {
136 return EINVAL;
137 }
138
139 attr->stackaddr = stackaddr;
140
141 return 0;
142 }
143
pthread_attr_getstackaddr(const pthread_attr_t * attr,void ** stackaddr)144 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
145 {
146 if ((attr == NULL) || (stackaddr == NULL)) {
147 return EINVAL;
148 }
149
150 *stackaddr = attr->stackaddr;
151
152 return 0;
153 }
154
pthread_attr_setstack(pthread_attr_t * attr,void * stackaddr,size_t stacksize)155 int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize)
156 {
157 if ((attr == NULL) || (stackaddr == NULL) || (stacksize <= 0)) {
158 return EINVAL;
159 }
160
161 attr->stackaddr = stackaddr;
162 attr->stacksize = stacksize;
163
164 return 0;
165 }
166
pthread_attr_getstack(const pthread_attr_t * attr,void ** stackaddr,size_t * stacksize)167 int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize)
168 {
169 if ((attr == NULL) || (stackaddr == NULL) || (stacksize == NULL)) {
170 return EINVAL;
171 }
172
173 *stackaddr = attr->stackaddr;
174 *stacksize = attr->stacksize;
175
176 return 0;
177 }
178
pthread_attr_getinheritsched(const pthread_attr_t * restrict attr,int * restrict inheritsched)179 int pthread_attr_getinheritsched(const pthread_attr_t *restrict attr, int *restrict inheritsched)
180 {
181 if ((attr == NULL) || (inheritsched == NULL)) {
182 return EINVAL;
183 }
184
185 *inheritsched = attr->inheritsched;
186
187 return 0;
188 }
189
pthread_attr_setinheritsched(pthread_attr_t * attr,int inheritsched)190 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
191 {
192 if ((attr == NULL) || (inheritsched < PTHREAD_INHERIT_SCHED) ||
193 (inheritsched > PTHREAD_EXPLICIT_SCHED)) {
194 return EINVAL;
195 }
196
197 attr->inheritsched = inheritsched;
198
199 return 0;
200 }
201
pthread_attr_setguardsize(pthread_attr_t * attr,size_t guardsize)202 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
203 {
204 /* guardsize stack protection is not supported by kernel */
205 return ENOSYS;
206 }
207
pthread_attr_getguardsize(const pthread_attr_t * attr,size_t * guardsize)208 int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
209 {
210 /* guardsize stack protection is not supported by kernel */
211 return ENOSYS;
212 }
213
pthread_attr_getscope(const pthread_attr_t * restrict attr,int * restrict contentionscope)214 int pthread_attr_getscope(const pthread_attr_t *restrict attr, int *restrict contentionscope)
215 {
216 if ((attr == NULL) || (contentionscope == NULL)) {
217 return EINVAL;
218 }
219
220 *contentionscope = attr->contentionscope;
221
222 return 0;
223 }
224
pthread_attr_setscope(pthread_attr_t * attr,int contentionscope)225 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
226 {
227 if ((attr == NULL) ||
228 ((contentionscope != PTHREAD_SCOPE_PROCESS) && (contentionscope != PTHREAD_SCOPE_SYSTEM))) {
229 return EINVAL;
230 }
231
232 attr->contentionscope = contentionscope;
233
234 return 0;
235 }
236