| @@ -1,458 +1,464 @@ | | | @@ -1,458 +1,464 @@ |
1 | /* $NetBSD: pthread_attr.c,v 1.13 2010/08/06 05:25:02 christos Exp $ */ | | 1 | /* $NetBSD: pthread_attr.c,v 1.14 2010/08/06 14:23:06 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Nathan J. Williams. | | 8 | * by Nathan J. Williams. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright | | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the | | 16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. | | 17 | * documentation and/or other materials provided with the distribution. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __RCSID("$NetBSD: pthread_attr.c,v 1.13 2010/08/06 05:25:02 christos Exp $"); | | 33 | __RCSID("$NetBSD: pthread_attr.c,v 1.14 2010/08/06 14:23:06 christos Exp $"); |
34 | | | 34 | |
35 | #include <errno.h> | | 35 | #include <errno.h> |
36 | #include <stdio.h> | | 36 | #include <stdio.h> |
37 | #include <stdlib.h> | | 37 | #include <stdlib.h> |
38 | #include <string.h> | | 38 | #include <string.h> |
39 | #include <unistd.h> | | 39 | #include <unistd.h> |
40 | | | 40 | |
41 | #include "pthread.h" | | 41 | #include "pthread.h" |
42 | #include "pthread_int.h" | | 42 | #include "pthread_int.h" |
43 | | | 43 | |
| | | 44 | #ifndef __lint__ |
| | | 45 | #define pthread_attr_get_np _pthread_attr_get_np |
| | | 46 | #endif |
| | | 47 | |
| | | 48 | __weak_alias(pthread_attr_get_np, _pthread_attr_get_np) |
| | | 49 | |
44 | static struct pthread_attr_private *pthread__attr_init_private( | | 50 | static struct pthread_attr_private *pthread__attr_init_private( |
45 | pthread_attr_t *); | | 51 | pthread_attr_t *); |
46 | | | 52 | |
47 | static struct pthread_attr_private * | | 53 | static struct pthread_attr_private * |
48 | pthread__attr_init_private(pthread_attr_t *attr) | | 54 | pthread__attr_init_private(pthread_attr_t *attr) |
49 | { | | 55 | { |
50 | struct pthread_attr_private *p; | | 56 | struct pthread_attr_private *p; |
51 | | | 57 | |
52 | if ((p = attr->pta_private) != NULL) | | 58 | if ((p = attr->pta_private) != NULL) |
53 | return p; | | 59 | return p; |
54 | | | 60 | |
55 | p = malloc(sizeof(*p)); | | 61 | p = malloc(sizeof(*p)); |
56 | if (p != NULL) { | | 62 | if (p != NULL) { |
57 | memset(p, 0, sizeof(*p)); | | 63 | memset(p, 0, sizeof(*p)); |
58 | attr->pta_private = p; | | 64 | attr->pta_private = p; |
59 | p->ptap_policy = SCHED_OTHER; | | 65 | p->ptap_policy = SCHED_OTHER; |
60 | } | | 66 | } |
61 | return p; | | 67 | return p; |
62 | } | | 68 | } |
63 | | | 69 | |
64 | | | 70 | |
65 | int | | 71 | int |
66 | pthread_attr_init(pthread_attr_t *attr) | | 72 | pthread_attr_init(pthread_attr_t *attr) |
67 | { | | 73 | { |
68 | | | 74 | |
69 | attr->pta_magic = PT_ATTR_MAGIC; | | 75 | attr->pta_magic = PT_ATTR_MAGIC; |
70 | attr->pta_flags = 0; | | 76 | attr->pta_flags = 0; |
71 | attr->pta_private = NULL; | | 77 | attr->pta_private = NULL; |
72 | | | 78 | |
73 | return 0; | | 79 | return 0; |
74 | } | | 80 | } |
75 | | | 81 | |
76 | | | 82 | |
77 | int | | 83 | int |
78 | pthread_attr_destroy(pthread_attr_t *attr) | | 84 | pthread_attr_destroy(pthread_attr_t *attr) |
79 | { | | 85 | { |
80 | struct pthread_attr_private *p; | | 86 | struct pthread_attr_private *p; |
81 | | | 87 | |
82 | if ((p = attr->pta_private) != NULL) | | 88 | if ((p = attr->pta_private) != NULL) |
83 | free(p); | | 89 | free(p); |
84 | | | 90 | |
85 | return 0; | | 91 | return 0; |
86 | } | | 92 | } |
87 | | | 93 | |
88 | | | 94 | |
89 | int | | 95 | int |
90 | pthread_attr_get_np(pthread_t thread, pthread_attr_t *attr) | | 96 | pthread_attr_get_np(pthread_t thread, pthread_attr_t *attr) |
91 | { | | 97 | { |
92 | struct pthread_attr_private *p; | | 98 | struct pthread_attr_private *p; |
93 | | | 99 | |
94 | p = pthread__attr_init_private(attr); | | 100 | p = pthread__attr_init_private(attr); |
95 | if (p == NULL) | | 101 | if (p == NULL) |
96 | return ENOMEM; | | 102 | return ENOMEM; |
97 | | | 103 | |
98 | attr->pta_flags = thread->pt_flags & | | 104 | attr->pta_flags = thread->pt_flags & |
99 | (PT_FLAG_DETACHED | PT_FLAG_SCOPE_SYSTEM | PT_FLAG_EXPLICIT_SCHED); | | 105 | (PT_FLAG_DETACHED | PT_FLAG_SCOPE_SYSTEM | PT_FLAG_EXPLICIT_SCHED); |
100 | | | 106 | |
101 | p->ptap_namearg = thread->pt_name; | | 107 | p->ptap_namearg = thread->pt_name; |
102 | p->ptap_stackaddr = thread->pt_stack.ss_sp; | | 108 | p->ptap_stackaddr = thread->pt_stack.ss_sp; |
103 | p->ptap_stacksize = thread->pt_stack.ss_size; | | 109 | p->ptap_stacksize = thread->pt_stack.ss_size; |
104 | p->ptap_guardsize = (size_t)sysconf(_SC_PAGESIZE); | | 110 | p->ptap_guardsize = (size_t)sysconf(_SC_PAGESIZE); |
105 | return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp); | | 111 | return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp); |
106 | } | | 112 | } |
107 | | | 113 | |
108 | | | 114 | |
109 | int | | 115 | int |
110 | pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) | | 116 | pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) |
111 | { | | 117 | { |
112 | | | 118 | |
113 | if (attr->pta_flags & PT_FLAG_DETACHED) | | 119 | if (attr->pta_flags & PT_FLAG_DETACHED) |
114 | *detachstate = PTHREAD_CREATE_DETACHED; | | 120 | *detachstate = PTHREAD_CREATE_DETACHED; |
115 | else | | 121 | else |
116 | *detachstate = PTHREAD_CREATE_JOINABLE; | | 122 | *detachstate = PTHREAD_CREATE_JOINABLE; |
117 | | | 123 | |
118 | return 0; | | 124 | return 0; |
119 | } | | 125 | } |
120 | | | 126 | |
121 | | | 127 | |
122 | int | | 128 | int |
123 | pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) | | 129 | pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) |
124 | { | | 130 | { |
125 | | | 131 | |
126 | switch (detachstate) { | | 132 | switch (detachstate) { |
127 | case PTHREAD_CREATE_JOINABLE: | | 133 | case PTHREAD_CREATE_JOINABLE: |
128 | attr->pta_flags &= ~PT_FLAG_DETACHED; | | 134 | attr->pta_flags &= ~PT_FLAG_DETACHED; |
129 | break; | | 135 | break; |
130 | case PTHREAD_CREATE_DETACHED: | | 136 | case PTHREAD_CREATE_DETACHED: |
131 | attr->pta_flags |= PT_FLAG_DETACHED; | | 137 | attr->pta_flags |= PT_FLAG_DETACHED; |
132 | break; | | 138 | break; |
133 | default: | | 139 | default: |
134 | return EINVAL; | | 140 | return EINVAL; |
135 | } | | 141 | } |
136 | | | 142 | |
137 | return 0; | | 143 | return 0; |
138 | } | | 144 | } |
139 | | | 145 | |
140 | | | 146 | |
141 | int | | 147 | int |
142 | pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guard) | | 148 | pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guard) |
143 | { | | 149 | { |
144 | struct pthread_attr_private *p; | | 150 | struct pthread_attr_private *p; |
145 | | | 151 | |
146 | if ((p = attr->pta_private) == NULL) | | 152 | if ((p = attr->pta_private) == NULL) |
147 | *guard = (size_t)sysconf(_SC_PAGESIZE); | | 153 | *guard = (size_t)sysconf(_SC_PAGESIZE); |
148 | else | | 154 | else |
149 | *guard = p->ptap_guardsize; | | 155 | *guard = p->ptap_guardsize; |
150 | | | 156 | |
151 | return 0; | | 157 | return 0; |
152 | } | | 158 | } |
153 | | | 159 | |
154 | | | 160 | |
155 | int | | 161 | int |
156 | pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard) | | 162 | pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard) |
157 | { | | 163 | { |
158 | struct pthread_attr_private *p; | | 164 | struct pthread_attr_private *p; |
159 | | | 165 | |
160 | p = pthread__attr_init_private(attr); | | 166 | p = pthread__attr_init_private(attr); |
161 | if (p == NULL) | | 167 | if (p == NULL) |
162 | return ENOMEM; | | 168 | return ENOMEM; |
163 | | | 169 | |
164 | p->ptap_guardsize = guard; | | 170 | p->ptap_guardsize = guard; |
165 | | | 171 | |
166 | return 0; | | 172 | return 0; |
167 | } | | 173 | } |
168 | | | 174 | |
169 | | | 175 | |
170 | int | | 176 | int |
171 | pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) | | 177 | pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) |
172 | { | | 178 | { |
173 | | | 179 | |
174 | if (attr->pta_flags & PT_FLAG_EXPLICIT_SCHED) | | 180 | if (attr->pta_flags & PT_FLAG_EXPLICIT_SCHED) |
175 | *inherit = PTHREAD_EXPLICIT_SCHED; | | 181 | *inherit = PTHREAD_EXPLICIT_SCHED; |
176 | else | | 182 | else |
177 | *inherit = PTHREAD_INHERIT_SCHED; | | 183 | *inherit = PTHREAD_INHERIT_SCHED; |
178 | | | 184 | |
179 | return 0; | | 185 | return 0; |
180 | } | | 186 | } |
181 | | | 187 | |
182 | | | 188 | |
183 | int | | 189 | int |
184 | pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) | | 190 | pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) |
185 | { | | 191 | { |
186 | | | 192 | |
187 | switch (inherit) { | | 193 | switch (inherit) { |
188 | case PTHREAD_INHERIT_SCHED: | | 194 | case PTHREAD_INHERIT_SCHED: |
189 | attr->pta_flags &= ~PT_FLAG_EXPLICIT_SCHED; | | 195 | attr->pta_flags &= ~PT_FLAG_EXPLICIT_SCHED; |
190 | break; | | 196 | break; |
191 | case PTHREAD_EXPLICIT_SCHED: | | 197 | case PTHREAD_EXPLICIT_SCHED: |
192 | attr->pta_flags |= PT_FLAG_EXPLICIT_SCHED; | | 198 | attr->pta_flags |= PT_FLAG_EXPLICIT_SCHED; |
193 | break; | | 199 | break; |
194 | default: | | 200 | default: |
195 | return EINVAL; | | 201 | return EINVAL; |
196 | } | | 202 | } |
197 | | | 203 | |
198 | return 0; | | 204 | return 0; |
199 | } | | 205 | } |
200 | | | 206 | |
201 | | | 207 | |
202 | int | | 208 | int |
203 | pthread_attr_getscope(const pthread_attr_t *attr, int *scope) | | 209 | pthread_attr_getscope(const pthread_attr_t *attr, int *scope) |
204 | { | | 210 | { |
205 | | | 211 | |
206 | if (attr->pta_flags & PT_FLAG_SCOPE_SYSTEM) | | 212 | if (attr->pta_flags & PT_FLAG_SCOPE_SYSTEM) |
207 | *scope = PTHREAD_SCOPE_SYSTEM; | | 213 | *scope = PTHREAD_SCOPE_SYSTEM; |
208 | else | | 214 | else |
209 | *scope = PTHREAD_SCOPE_PROCESS; | | 215 | *scope = PTHREAD_SCOPE_PROCESS; |
210 | | | 216 | |
211 | return 0; | | 217 | return 0; |
212 | } | | 218 | } |
213 | | | 219 | |
214 | | | 220 | |
215 | int | | 221 | int |
216 | pthread_attr_setscope(pthread_attr_t *attr, int scope) | | 222 | pthread_attr_setscope(pthread_attr_t *attr, int scope) |
217 | { | | 223 | { |
218 | | | 224 | |
219 | switch (scope) { | | 225 | switch (scope) { |
220 | case PTHREAD_SCOPE_PROCESS: | | 226 | case PTHREAD_SCOPE_PROCESS: |
221 | attr->pta_flags &= ~PT_FLAG_SCOPE_SYSTEM; | | 227 | attr->pta_flags &= ~PT_FLAG_SCOPE_SYSTEM; |
222 | break; | | 228 | break; |
223 | case PTHREAD_SCOPE_SYSTEM: | | 229 | case PTHREAD_SCOPE_SYSTEM: |
224 | attr->pta_flags |= PT_FLAG_SCOPE_SYSTEM; | | 230 | attr->pta_flags |= PT_FLAG_SCOPE_SYSTEM; |
225 | break; | | 231 | break; |
226 | default: | | 232 | default: |
227 | return EINVAL; | | 233 | return EINVAL; |
228 | } | | 234 | } |
229 | | | 235 | |
230 | return 0; | | 236 | return 0; |
231 | } | | 237 | } |
232 | | | 238 | |
233 | | | 239 | |
234 | int | | 240 | int |
235 | pthread_attr_setschedparam(pthread_attr_t *attr, | | 241 | pthread_attr_setschedparam(pthread_attr_t *attr, |
236 | const struct sched_param *param) | | 242 | const struct sched_param *param) |
237 | { | | 243 | { |
238 | struct pthread_attr_private *p; | | 244 | struct pthread_attr_private *p; |
239 | int error; | | 245 | int error; |
240 | | | 246 | |
241 | if (param == NULL) | | 247 | if (param == NULL) |
242 | return EINVAL; | | 248 | return EINVAL; |
243 | p = pthread__attr_init_private(attr); | | 249 | p = pthread__attr_init_private(attr); |
244 | if (p == NULL) | | 250 | if (p == NULL) |
245 | return ENOMEM; | | 251 | return ENOMEM; |
246 | error = pthread__checkpri(param->sched_priority); | | 252 | error = pthread__checkpri(param->sched_priority); |
247 | if (error == 0) | | 253 | if (error == 0) |
248 | p->ptap_sp = *param; | | 254 | p->ptap_sp = *param; |
249 | return error; | | 255 | return error; |
250 | } | | 256 | } |
251 | | | 257 | |
252 | | | 258 | |
253 | int | | 259 | int |
254 | pthread_attr_getschedparam(const pthread_attr_t *attr, | | 260 | pthread_attr_getschedparam(const pthread_attr_t *attr, |
255 | struct sched_param *param) | | 261 | struct sched_param *param) |
256 | { | | 262 | { |
257 | struct pthread_attr_private *p; | | 263 | struct pthread_attr_private *p; |
258 | | | 264 | |
259 | if (param == NULL) | | 265 | if (param == NULL) |
260 | return EINVAL; | | 266 | return EINVAL; |
261 | p = attr->pta_private; | | 267 | p = attr->pta_private; |
262 | if (p == NULL) | | 268 | if (p == NULL) |
263 | memset(param, 0, sizeof(*param)); | | 269 | memset(param, 0, sizeof(*param)); |
264 | else | | 270 | else |
265 | *param = p->ptap_sp; | | 271 | *param = p->ptap_sp; |
266 | return 0; | | 272 | return 0; |
267 | } | | 273 | } |
268 | | | 274 | |
269 | | | 275 | |
270 | int | | 276 | int |
271 | pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) | | 277 | pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) |
272 | { | | 278 | { |
273 | struct pthread_attr_private *p; | | 279 | struct pthread_attr_private *p; |
274 | | | 280 | |
275 | | | 281 | |
276 | switch (policy) { | | 282 | switch (policy) { |
277 | case SCHED_OTHER: | | 283 | case SCHED_OTHER: |
278 | case SCHED_FIFO: | | 284 | case SCHED_FIFO: |
279 | case SCHED_RR: | | 285 | case SCHED_RR: |
280 | p = pthread__attr_init_private(attr); | | 286 | p = pthread__attr_init_private(attr); |
281 | if (p == NULL) | | 287 | if (p == NULL) |
282 | return ENOMEM; | | 288 | return ENOMEM; |
283 | p->ptap_policy = policy; | | 289 | p->ptap_policy = policy; |
284 | return 0; | | 290 | return 0; |
285 | default: | | 291 | default: |
286 | return ENOTSUP; | | 292 | return ENOTSUP; |
287 | } | | 293 | } |
288 | } | | 294 | } |
289 | | | 295 | |
290 | | | 296 | |
291 | int | | 297 | int |
292 | pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) | | 298 | pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) |
293 | { | | 299 | { |
294 | struct pthread_attr_private *p; | | 300 | struct pthread_attr_private *p; |
295 | | | 301 | |
296 | p = attr->pta_private; | | 302 | p = attr->pta_private; |
297 | if (p == NULL) { | | 303 | if (p == NULL) { |
298 | *policy = SCHED_OTHER; | | 304 | *policy = SCHED_OTHER; |
299 | return 0; | | 305 | return 0; |
300 | } | | 306 | } |
301 | *policy = p->ptap_policy; | | 307 | *policy = p->ptap_policy; |
302 | return 0; | | 308 | return 0; |
303 | } | | 309 | } |
304 | | | 310 | |
305 | | | 311 | |
306 | int | | 312 | int |
307 | pthread_attr_getstack(const pthread_attr_t *attr, void **addr, size_t *size) | | 313 | pthread_attr_getstack(const pthread_attr_t *attr, void **addr, size_t *size) |
308 | { | | 314 | { |
309 | struct pthread_attr_private *p; | | 315 | struct pthread_attr_private *p; |
310 | | | 316 | |
311 | if ((p = attr->pta_private) == NULL) { | | 317 | if ((p = attr->pta_private) == NULL) { |
312 | *addr = NULL; | | 318 | *addr = NULL; |
313 | *size = pthread__stacksize; | | 319 | *size = pthread__stacksize; |
314 | } else { | | 320 | } else { |
315 | *addr = p->ptap_stackaddr; | | 321 | *addr = p->ptap_stackaddr; |
316 | *size = p->ptap_stacksize; | | 322 | *size = p->ptap_stacksize; |
317 | } | | 323 | } |
318 | | | 324 | |
319 | return 0; | | 325 | return 0; |
320 | } | | 326 | } |
321 | | | 327 | |
322 | | | 328 | |
323 | int | | 329 | int |
324 | pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size) | | 330 | pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size) |
325 | { | | 331 | { |
326 | struct pthread_attr_private *p; | | 332 | struct pthread_attr_private *p; |
327 | | | 333 | |
328 | p = pthread__attr_init_private(attr); | | 334 | p = pthread__attr_init_private(attr); |
329 | if (p == NULL) | | 335 | if (p == NULL) |
330 | return ENOMEM; | | 336 | return ENOMEM; |
331 | | | 337 | |
332 | p->ptap_stackaddr = addr; | | 338 | p->ptap_stackaddr = addr; |
333 | p->ptap_stacksize = size; | | 339 | p->ptap_stacksize = size; |
334 | | | 340 | |
335 | return 0; | | 341 | return 0; |
336 | } | | 342 | } |
337 | | | 343 | |
338 | | | 344 | |
339 | int | | 345 | int |
340 | pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size) | | 346 | pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size) |
341 | { | | 347 | { |
342 | struct pthread_attr_private *p; | | 348 | struct pthread_attr_private *p; |
343 | | | 349 | |
344 | if ((p = attr->pta_private) == NULL) | | 350 | if ((p = attr->pta_private) == NULL) |
345 | *size = pthread__stacksize; | | 351 | *size = pthread__stacksize; |
346 | else | | 352 | else |
347 | *size = p->ptap_stacksize; | | 353 | *size = p->ptap_stacksize; |
348 | | | 354 | |
349 | return 0; | | 355 | return 0; |
350 | } | | 356 | } |
351 | | | 357 | |
352 | | | 358 | |
353 | int | | 359 | int |
354 | pthread_attr_setstacksize(pthread_attr_t *attr, size_t size) | | 360 | pthread_attr_setstacksize(pthread_attr_t *attr, size_t size) |
355 | { | | 361 | { |
356 | struct pthread_attr_private *p; | | 362 | struct pthread_attr_private *p; |
357 | | | 363 | |
358 | if (size < (size_t)sysconf(_SC_THREAD_STACK_MIN)) | | 364 | if (size < (size_t)sysconf(_SC_THREAD_STACK_MIN)) |
359 | return EINVAL; | | 365 | return EINVAL; |
360 | | | 366 | |
361 | p = pthread__attr_init_private(attr); | | 367 | p = pthread__attr_init_private(attr); |
362 | if (p == NULL) | | 368 | if (p == NULL) |
363 | return ENOMEM; | | 369 | return ENOMEM; |
364 | | | 370 | |
365 | p->ptap_stacksize = size; | | 371 | p->ptap_stacksize = size; |
366 | | | 372 | |
367 | return 0; | | 373 | return 0; |
368 | } | | 374 | } |
369 | | | 375 | |
370 | | | 376 | |
371 | int | | 377 | int |
372 | pthread_attr_getstackaddr(const pthread_attr_t *attr, void **addr) | | 378 | pthread_attr_getstackaddr(const pthread_attr_t *attr, void **addr) |
373 | { | | 379 | { |
374 | struct pthread_attr_private *p; | | 380 | struct pthread_attr_private *p; |
375 | | | 381 | |
376 | if ((p = attr->pta_private) == NULL) | | 382 | if ((p = attr->pta_private) == NULL) |
377 | *addr = NULL; | | 383 | *addr = NULL; |
378 | else | | 384 | else |
379 | *addr = p->ptap_stackaddr; | | 385 | *addr = p->ptap_stackaddr; |
380 | | | 386 | |
381 | return 0; | | 387 | return 0; |
382 | } | | 388 | } |
383 | | | 389 | |
384 | | | 390 | |
385 | int | | 391 | int |
386 | pthread_attr_setstackaddr(pthread_attr_t *attr, void *addr) | | 392 | pthread_attr_setstackaddr(pthread_attr_t *attr, void *addr) |
387 | { | | 393 | { |
388 | struct pthread_attr_private *p; | | 394 | struct pthread_attr_private *p; |
389 | | | 395 | |
390 | p = pthread__attr_init_private(attr); | | 396 | p = pthread__attr_init_private(attr); |
391 | if (p == NULL) | | 397 | if (p == NULL) |
392 | return ENOMEM; | | 398 | return ENOMEM; |
393 | | | 399 | |
394 | p->ptap_stackaddr = addr; | | 400 | p->ptap_stackaddr = addr; |
395 | | | 401 | |
396 | return 0; | | 402 | return 0; |
397 | } | | 403 | } |
398 | | | 404 | |
399 | | | 405 | |
400 | int | | 406 | int |
401 | pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len, | | 407 | pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len, |
402 | void **argp) | | 408 | void **argp) |
403 | { | | 409 | { |
404 | struct pthread_attr_private *p; | | 410 | struct pthread_attr_private *p; |
405 | | | 411 | |
406 | if ((p = attr->pta_private) == NULL) { | | 412 | if ((p = attr->pta_private) == NULL) { |
407 | name[0] = '\0'; | | 413 | name[0] = '\0'; |
408 | if (argp != NULL) | | 414 | if (argp != NULL) |
409 | *argp = NULL; | | 415 | *argp = NULL; |
410 | } else { | | 416 | } else { |
411 | strlcpy(name, p->ptap_name, len); | | 417 | strlcpy(name, p->ptap_name, len); |
412 | if (argp != NULL) | | 418 | if (argp != NULL) |
413 | *argp = p->ptap_namearg; | | 419 | *argp = p->ptap_namearg; |
414 | } | | 420 | } |
415 | | | 421 | |
416 | return 0; | | 422 | return 0; |
417 | } | | 423 | } |
418 | | | 424 | |
419 | | | 425 | |
420 | int | | 426 | int |
421 | pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg) | | 427 | pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg) |
422 | { | | 428 | { |
423 | struct pthread_attr_private *p; | | 429 | struct pthread_attr_private *p; |
424 | int namelen; | | 430 | int namelen; |
425 | | | 431 | |
426 | p = pthread__attr_init_private(attr); | | 432 | p = pthread__attr_init_private(attr); |
427 | if (p == NULL) | | 433 | if (p == NULL) |
428 | return ENOMEM; | | 434 | return ENOMEM; |
429 | | | 435 | |
430 | namelen = snprintf(p->ptap_name, PTHREAD_MAX_NAMELEN_NP, name, arg); | | 436 | namelen = snprintf(p->ptap_name, PTHREAD_MAX_NAMELEN_NP, name, arg); |
431 | if (namelen >= PTHREAD_MAX_NAMELEN_NP) { | | 437 | if (namelen >= PTHREAD_MAX_NAMELEN_NP) { |
432 | p->ptap_name[0] = '\0'; | | 438 | p->ptap_name[0] = '\0'; |
433 | return EINVAL; | | 439 | return EINVAL; |
434 | } | | 440 | } |
435 | p->ptap_namearg = arg; | | 441 | p->ptap_namearg = arg; |
436 | | | 442 | |
437 | return 0; | | 443 | return 0; |
438 | } | | 444 | } |
439 | | | 445 | |
440 | int | | 446 | int |
441 | pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) | | 447 | pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) |
442 | { | | 448 | { |
443 | attr->pta_flags |= PT_FLAG_SUSPENDED; | | 449 | attr->pta_flags |= PT_FLAG_SUSPENDED; |
444 | return 0; | | 450 | return 0; |
445 | } | | 451 | } |
446 | | | 452 | |
447 | int | | 453 | int |
448 | pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) | | 454 | pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) |
449 | { | | 455 | { |
450 | int error; | | 456 | int error; |
451 | if ((error = pthread_attr_init(attr)) != 0) | | 457 | if ((error = pthread_attr_init(attr)) != 0) |
452 | return error; | | 458 | return error; |
453 | if ((error = pthread_attr_get_np(thread, attr)) != 0) { | | 459 | if ((error = pthread_attr_get_np(thread, attr)) != 0) { |
454 | (void)pthread_attr_destroy(attr); | | 460 | (void)pthread_attr_destroy(attr); |
455 | return error; | | 461 | return error; |
456 | } | | 462 | } |
457 | return 0; | | 463 | return 0; |
458 | } | | 464 | } |