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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include "thr_uberdata.h"
32 * Default attribute object for pthread_create() with NULL attr pointer.
33 * Note that the 'guardsize' field is initialized on the first call.
38 static thrattr_t thrattr
= {
41 PTHREAD_CREATE_JOINABLE
, /* detachstate */
42 PTHREAD_CREATE_NONDAEMON_NP
, /* daemonstate */
43 PTHREAD_SCOPE_PROCESS
, /* scope */
45 SCHED_OTHER
, /* policy */
46 PTHREAD_INHERIT_SCHED
, /* inherit */
49 if (thrattr
.guardsize
== 0)
50 thrattr
.guardsize
= _sysconf(_SC_PAGESIZE
);
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
60 pthread_attr_init(pthread_attr_t
*attr
)
64 if ((ap
= lmalloc(sizeof (thrattr_t
))) != NULL
) {
66 attr
->__pthread_attrp
= ap
;
73 * pthread_attr_destroy: frees the attribute object and invalidates it
77 pthread_attr_destroy(pthread_attr_t
*attr
)
79 if (attr
== NULL
|| attr
->__pthread_attrp
== NULL
)
81 lfree(attr
->__pthread_attrp
, sizeof (thrattr_t
));
82 attr
->__pthread_attrp
= NULL
;
87 * pthread_attr_clone: make a copy of a pthread_attr_t.
90 pthread_attr_clone(pthread_attr_t
*attr
, const pthread_attr_t
*old_attr
)
93 const thrattr_t
*old_ap
=
94 old_attr
? old_attr
->__pthread_attrp
: def_thrattr();
98 if ((ap
= lmalloc(sizeof (thrattr_t
))) == NULL
)
101 attr
->__pthread_attrp
= ap
;
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
)
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
)
131 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
132 stacksize
>= MINSTACK
) {
133 ap
->stksize
= stacksize
;
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
)
148 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
150 *stacksize
= ap
->stksize
;
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
)
165 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
) {
166 ap
->stkaddr
= stackaddr
;
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
)
181 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
183 *stackaddr
= ap
->stkaddr
;
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
)
198 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
199 (detachstate
== PTHREAD_CREATE_DETACHED
||
200 detachstate
== PTHREAD_CREATE_JOINABLE
)) {
201 ap
->detachstate
= detachstate
;
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
)
216 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
217 detachstate
!= NULL
) {
218 *detachstate
= ap
->detachstate
;
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
)
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
;
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
)
252 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
253 daemonstate
!= NULL
) {
254 *daemonstate
= ap
->daemonstate
;
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
)
269 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
270 (scope
== PTHREAD_SCOPE_SYSTEM
||
271 scope
== PTHREAD_SCOPE_PROCESS
)) {
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
)
287 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
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
)
304 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
305 (inherit
== PTHREAD_EXPLICIT_SCHED
||
306 inherit
== PTHREAD_INHERIT_SCHED
)) {
307 ap
->inherit
= inherit
;
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
)
322 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
324 *inherit
= ap
->inherit
;
331 * pthread_attr_setschedpolicy: sets the scheduling policy.
334 pthread_attr_setschedpolicy(pthread_attr_t
*attr
, int policy
)
338 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
339 policy
!= SCHED_SYS
&& get_info_by_policy(policy
) != NULL
) {
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
)
355 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
357 *policy
= ap
->policy
;
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
)
373 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
375 ap
->prio
= param
->sched_priority
;
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
)
392 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
394 param
->sched_priority
= ap
->prio
;
402 * pthread_attr_setguardsize: sets the guardsize
405 pthread_attr_setguardsize(pthread_attr_t
*attr
, size_t guardsize
)
409 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
) {
410 ap
->guardsize
= guardsize
;
418 * pthread_attr_getguardsize: gets the guardsize
421 pthread_attr_getguardsize(const pthread_attr_t
*attr
, size_t *guardsize
)
425 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
427 *guardsize
= ap
->guardsize
;
434 * pthread_attr_setstack: sets the user stack addr and stack size.
435 * This is equivalent to the stack_base and stack_size arguments
439 pthread_attr_setstack(pthread_attr_t
*attr
,
440 void *stackaddr
, size_t stacksize
)
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
)
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
)
465 if (attr
!= NULL
&& (ap
= attr
->__pthread_attrp
) != NULL
&&
466 stackaddr
!= NULL
&& stacksize
!= NULL
) {
467 *stackaddr
= ap
->stkaddr
;
468 *stacksize
= ap
->stksize
;