1/*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#include "lint.h"
28#include "thr_uberdata.h"
29
30/*
31 * pthread_condattr_init: allocates the cond attribute object and
32 * initializes it with the default values.
33 */
34#pragma weak _pthread_condattr_init = pthread_condattr_init
35int
36pthread_condattr_init(pthread_condattr_t *attr)
37{
38	cvattr_t *ap;
39
40	if ((ap = lmalloc(sizeof (cvattr_t))) == NULL)
41		return (ENOMEM);
42	ap->pshared = PTHREAD_PROCESS_PRIVATE;
43	ap->clockid = CLOCK_REALTIME;
44	attr->__pthread_condattrp = ap;
45	return (0);
46}
47
48/*
49 * pthread_condattr_destroy: frees the cond attribute object and
50 * invalidates it with NULL value.
51 */
52int
53pthread_condattr_destroy(pthread_condattr_t *attr)
54{
55	if (attr == NULL || attr->__pthread_condattrp == NULL)
56		return (EINVAL);
57	lfree(attr->__pthread_condattrp, sizeof (cvattr_t));
58	attr->__pthread_condattrp = NULL;
59	return (0);
60}
61
62/*
63 * pthread_condattr_setclock: sets the clockid attribute.
64 */
65int
66pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
67{
68	cvattr_t *ap;
69
70	if (attr != NULL && (ap = attr->__pthread_condattrp) != NULL &&
71	    (clock_id == CLOCK_REALTIME || clock_id == CLOCK_HIGHRES)) {
72		ap->clockid = clock_id;
73		return (0);
74	}
75	return (EINVAL);
76}
77
78/*
79 * pthread_condattr_getclock: gets the shared attr.
80 */
81int
82pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id)
83{
84	cvattr_t *ap;
85
86	if (attr != NULL && (ap = attr->__pthread_condattrp) != NULL &&
87	    clock_id != NULL) {
88		*clock_id = ap->clockid;
89		return (0);
90	}
91	return (EINVAL);
92}
93
94
95/*
96 * pthread_condattr_setpshared: sets the shared attr to PRIVATE or SHARED.
97 * This is equivalent to setting USYNC_PROCESS/USYNC_THREAD flag in cond_init().
98 */
99int
100pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
101{
102	cvattr_t *ap;
103
104	if (attr != NULL && (ap = attr->__pthread_condattrp) != NULL &&
105	    (pshared == PTHREAD_PROCESS_PRIVATE ||
106	    pshared == PTHREAD_PROCESS_SHARED)) {
107		ap->pshared = pshared;
108		return (0);
109	}
110	return (EINVAL);
111}
112
113/*
114 * pthread_condattr_getpshared: gets the shared attr.
115 */
116#pragma weak _pthread_condattr_getpshared = pthread_condattr_getpshared
117int
118pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)
119{
120	cvattr_t *ap;
121
122	if (attr != NULL && (ap = attr->__pthread_condattrp) != NULL &&
123	    pshared != NULL) {
124		*pshared = ap->pshared;
125		return (0);
126	}
127	return (EINVAL);
128}
129
130/*
131 * pthread_cond_init: Initializes the cond object. It copies the
132 * pshared attr into type argument and calls cond_init().
133 */
134#pragma weak _pthread_cond_init = pthread_cond_init
135int
136pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
137{
138	cvattr_t *ap;
139	int type;
140	clockid_t clock_id;
141	int error;
142
143	if (attr == NULL) {
144		type = PTHREAD_PROCESS_PRIVATE;
145		clock_id = CLOCK_REALTIME;
146	} else if ((ap = attr->__pthread_condattrp) != NULL) {
147		type = ap->pshared;
148		clock_id = ap->clockid;
149	} else {
150		return (EINVAL);
151	}
152
153	if (clock_id != CLOCK_REALTIME && clock_id != CLOCK_HIGHRES)
154		error = EINVAL;
155	else if ((error = cond_init((cond_t *)cond, type, NULL)) == 0)
156		((cond_t *)cond)->cond_clockid = (uint8_t)clock_id;
157
158	return (error);
159}
160