6069 libdisasm: instrlen arch op should have a sane default
[illumos-gate.git] / usr / src / lib / libc / port / threads / pthr_attr.c
blob51d08b4a5dcf1952bea220f0487cf5afd1b58ac2
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include "lint.h"
28 #include "thr_uberdata.h"
29 #include <sched.h>
32 * Default attribute object for pthread_create() with NULL attr pointer.
33 * Note that the 'guardsize' field is initialized on the first call.
35 const thrattr_t *
36 def_thrattr(void)
38 static thrattr_t thrattr = {
39 0, /* stksize */
40 NULL, /* stkaddr */
41 PTHREAD_CREATE_JOINABLE, /* detachstate */
42 PTHREAD_CREATE_NONDAEMON_NP, /* daemonstate */
43 PTHREAD_SCOPE_PROCESS, /* scope */
44 0, /* prio */
45 SCHED_OTHER, /* policy */
46 PTHREAD_INHERIT_SCHED, /* inherit */
47 0 /* guardsize */
49 if (thrattr.guardsize == 0)
50 thrattr.guardsize = _sysconf(_SC_PAGESIZE);
51 return (&thrattr);
55 * pthread_attr_init: allocates the attribute object and initializes it
56 * with the default values.
58 #pragma weak _pthread_attr_init = pthread_attr_init
59 int
60 pthread_attr_init(pthread_attr_t *attr)
62 thrattr_t *ap;
64 if ((ap = lmalloc(sizeof (thrattr_t))) != NULL) {
65 *ap = *def_thrattr();
66 attr->__pthread_attrp = ap;
67 return (0);
69 return (ENOMEM);
73 * pthread_attr_destroy: frees the attribute object and invalidates it
74 * with NULL value.
76 int
77 pthread_attr_destroy(pthread_attr_t *attr)
79 if (attr == NULL || attr->__pthread_attrp == NULL)
80 return (EINVAL);
81 lfree(attr->__pthread_attrp, sizeof (thrattr_t));
82 attr->__pthread_attrp = NULL;
83 return (0);
87 * pthread_attr_clone: make a copy of a pthread_attr_t.
89 int
90 pthread_attr_clone(pthread_attr_t *attr, const pthread_attr_t *old_attr)
92 thrattr_t *ap;
93 const thrattr_t *old_ap =
94 old_attr? old_attr->__pthread_attrp : def_thrattr();
96 if (old_ap == NULL)
97 return (EINVAL);
98 if ((ap = lmalloc(sizeof (thrattr_t))) == NULL)
99 return (ENOMEM);
100 *ap = *old_ap;
101 attr->__pthread_attrp = ap;
102 return (0);
106 * pthread_attr_equal: compare two pthread_attr_t's, return 1 if equal.
107 * A NULL pthread_attr_t pointer implies default attributes.
108 * This is a consolidation-private interface, for librt.
111 pthread_attr_equal(const pthread_attr_t *attr1, const pthread_attr_t *attr2)
113 const thrattr_t *ap1 = attr1? attr1->__pthread_attrp : def_thrattr();
114 const thrattr_t *ap2 = attr2? attr2->__pthread_attrp : def_thrattr();
116 if (ap1 == NULL || ap2 == NULL)
117 return (0);
118 return (ap1 == ap2 || memcmp(ap1, ap2, sizeof (thrattr_t)) == 0);
122 * pthread_attr_setstacksize: sets the user stack size, minimum should
123 * be PTHREAD_STACK_MIN (MINSTACK).
124 * This is equivalent to stksize argument in thr_create().
127 pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
129 thrattr_t *ap;
131 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
132 stacksize >= MINSTACK) {
133 ap->stksize = stacksize;
134 return (0);
136 return (EINVAL);
140 * pthread_attr_getstacksize: gets the user stack size.
142 #pragma weak _pthread_attr_getstacksize = pthread_attr_getstacksize
144 pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
146 thrattr_t *ap;
148 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
149 stacksize != NULL) {
150 *stacksize = ap->stksize;
151 return (0);
153 return (EINVAL);
157 * pthread_attr_setstackaddr: sets the user stack addr.
158 * This is equivalent to stkaddr argument in thr_create().
161 pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
163 thrattr_t *ap;
165 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL) {
166 ap->stkaddr = stackaddr;
167 return (0);
169 return (EINVAL);
173 * pthread_attr_getstackaddr: gets the user stack addr.
175 #pragma weak _pthread_attr_getstackaddr = pthread_attr_getstackaddr
177 pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
179 thrattr_t *ap;
181 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
182 stackaddr != NULL) {
183 *stackaddr = ap->stkaddr;
184 return (0);
186 return (EINVAL);
190 * pthread_attr_setdetachstate: sets the detach state to DETACHED or JOINABLE.
191 * PTHREAD_CREATE_DETACHED is equivalent to thr_create(THR_DETACHED).
194 pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
196 thrattr_t *ap;
198 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
199 (detachstate == PTHREAD_CREATE_DETACHED ||
200 detachstate == PTHREAD_CREATE_JOINABLE)) {
201 ap->detachstate = detachstate;
202 return (0);
204 return (EINVAL);
208 * pthread_attr_getdetachstate: gets the detach state.
210 #pragma weak _pthread_attr_getdetachstate = pthread_attr_getdetachstate
212 pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
214 thrattr_t *ap;
216 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
217 detachstate != NULL) {
218 *detachstate = ap->detachstate;
219 return (0);
221 return (EINVAL);
225 * pthread_attr_setdaemonstate_np: sets the daemon state to DAEMON or NONDAEMON.
226 * PTHREAD_CREATE_DAEMON is equivalent to thr_create(THR_DAEMON).
227 * For now, this is a private interface in libc.
230 pthread_attr_setdaemonstate_np(pthread_attr_t *attr, int daemonstate)
232 thrattr_t *ap;
234 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
235 (daemonstate == PTHREAD_CREATE_DAEMON_NP ||
236 daemonstate == PTHREAD_CREATE_NONDAEMON_NP)) {
237 ap->daemonstate = daemonstate;
238 return (0);
240 return (EINVAL);
244 * pthread_attr_getdaemonstate_np: gets the daemon state.
245 * For now, this is a private interface in libc.
248 pthread_attr_getdaemonstate_np(const pthread_attr_t *attr, int *daemonstate)
250 thrattr_t *ap;
252 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
253 daemonstate != NULL) {
254 *daemonstate = ap->daemonstate;
255 return (0);
257 return (EINVAL);
261 * pthread_attr_setscope: sets the scope to SYSTEM or PROCESS.
262 * This is equivalent to setting THR_BOUND flag in thr_create().
265 pthread_attr_setscope(pthread_attr_t *attr, int scope)
267 thrattr_t *ap;
269 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
270 (scope == PTHREAD_SCOPE_SYSTEM ||
271 scope == PTHREAD_SCOPE_PROCESS)) {
272 ap->scope = scope;
273 return (0);
275 return (EINVAL);
279 * pthread_attr_getscope: gets the scheduling scope.
281 #pragma weak _pthread_attr_getscope = pthread_attr_getscope
283 pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
285 thrattr_t *ap;
287 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
288 scope != NULL) {
289 *scope = ap->scope;
290 return (0);
292 return (EINVAL);
296 * pthread_attr_setinheritsched: sets the scheduling parameters to be
297 * EXPLICIT or INHERITED from parent thread.
300 pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
302 thrattr_t *ap;
304 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
305 (inherit == PTHREAD_EXPLICIT_SCHED ||
306 inherit == PTHREAD_INHERIT_SCHED)) {
307 ap->inherit = inherit;
308 return (0);
310 return (EINVAL);
314 * pthread_attr_getinheritsched: gets the scheduling inheritance.
316 #pragma weak _pthread_attr_getinheritsched = pthread_attr_getinheritsched
318 pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
320 thrattr_t *ap;
322 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
323 inherit != NULL) {
324 *inherit = ap->inherit;
325 return (0);
327 return (EINVAL);
331 * pthread_attr_setschedpolicy: sets the scheduling policy.
334 pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
336 thrattr_t *ap;
338 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
339 policy != SCHED_SYS && get_info_by_policy(policy) != NULL) {
340 ap->policy = policy;
341 return (0);
343 return (EINVAL);
347 * pthread_attr_getpolicy: gets the scheduling policy.
349 #pragma weak _pthread_attr_getschedpolicy = pthread_attr_getschedpolicy
351 pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
353 thrattr_t *ap;
355 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
356 policy != NULL) {
357 *policy = ap->policy;
358 return (0);
360 return (EINVAL);
364 * pthread_attr_setschedparam: sets the scheduling parameters.
365 * Currently, we support priority only.
368 pthread_attr_setschedparam(pthread_attr_t *attr,
369 const struct sched_param *param)
371 thrattr_t *ap;
373 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
374 param != NULL) {
375 ap->prio = param->sched_priority;
376 return (0);
378 return (EINVAL);
382 * pthread_attr_getschedparam: gets the scheduling parameters.
383 * Currently, only priority is defined as sched parameter.
385 #pragma weak _pthread_attr_getschedparam = pthread_attr_getschedparam
387 pthread_attr_getschedparam(const pthread_attr_t *attr,
388 struct sched_param *param)
390 thrattr_t *ap;
392 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
393 param != NULL) {
394 param->sched_priority = ap->prio;
395 return (0);
397 return (EINVAL);
401 * UNIX98
402 * pthread_attr_setguardsize: sets the guardsize
405 pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
407 thrattr_t *ap;
409 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL) {
410 ap->guardsize = guardsize;
411 return (0);
413 return (EINVAL);
417 * UNIX98
418 * pthread_attr_getguardsize: gets the guardsize
421 pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
423 thrattr_t *ap;
425 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
426 guardsize != NULL) {
427 *guardsize = ap->guardsize;
428 return (0);
430 return (EINVAL);
434 * pthread_attr_setstack: sets the user stack addr and stack size.
435 * This is equivalent to the stack_base and stack_size arguments
436 * to thr_create().
439 pthread_attr_setstack(pthread_attr_t *attr,
440 void *stackaddr, size_t stacksize)
442 thrattr_t *ap;
444 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
445 stacksize >= MINSTACK) {
446 ap->stkaddr = stackaddr;
447 ap->stksize = stacksize;
448 if (stackaddr != NULL &&
449 setup_top_frame(stackaddr, stacksize, NULL) == NULL)
450 return (EACCES);
451 return (0);
453 return (EINVAL);
457 * pthread_attr_getstack: gets the user stack addr and stack size.
460 pthread_attr_getstack(const pthread_attr_t *attr,
461 void **stackaddr, size_t *stacksize)
463 thrattr_t *ap;
465 if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
466 stackaddr != NULL && stacksize != NULL) {
467 *stackaddr = ap->stkaddr;
468 *stacksize = ap->stksize;
469 return (0);
471 return (EINVAL);