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 * Implementation-private attribute structure (for extensibility).
39 pthread_barrierattr_init(pthread_barrierattr_t
*attr
)
43 if ((ap
= lmalloc(sizeof (barrierattr_t
))) == NULL
)
45 ap
->pshared
= PTHREAD_PROCESS_PRIVATE
;
46 attr
->__pthread_barrierattrp
= ap
;
51 pthread_barrierattr_destroy(pthread_barrierattr_t
*attr
)
53 if (attr
== NULL
|| attr
->__pthread_barrierattrp
== NULL
)
55 lfree(attr
->__pthread_barrierattrp
, sizeof (barrierattr_t
));
56 attr
->__pthread_barrierattrp
= NULL
;
61 pthread_barrierattr_setpshared(pthread_barrierattr_t
*attr
, int pshared
)
65 if (attr
== NULL
|| (ap
= attr
->__pthread_barrierattrp
) == NULL
||
66 (pshared
!= PTHREAD_PROCESS_PRIVATE
&&
67 pshared
!= PTHREAD_PROCESS_SHARED
))
69 ap
->pshared
= pshared
;
74 pthread_barrierattr_getpshared(const pthread_barrierattr_t
*attr
, int *pshared
)
78 if (attr
== NULL
|| (ap
= attr
->__pthread_barrierattrp
) == NULL
||
81 *pshared
= ap
->pshared
;
86 pthread_barrier_init(pthread_barrier_t
*barrier
,
87 const pthread_barrierattr_t
*attr
, uint_t count
)
89 mutex_t
*mp
= (mutex_t
*)&barrier
->__pthread_barrier_lock
;
90 cond_t
*cvp
= (cond_t
*)&barrier
->__pthread_barrier_cond
;
95 type
= PTHREAD_PROCESS_PRIVATE
;
96 else if ((ap
= attr
->__pthread_barrierattrp
) != NULL
)
102 (type
!= PTHREAD_PROCESS_PRIVATE
&& type
!= PTHREAD_PROCESS_SHARED
))
105 barrier
->__pthread_barrier_count
= count
;
106 barrier
->__pthread_barrier_current
= count
;
107 barrier
->__pthread_barrier_cycle
= 0;
108 barrier
->__pthread_barrier_reserved
= 0;
109 (void) mutex_init(mp
, type
, NULL
);
110 (void) cond_init(cvp
, type
, NULL
);
113 * This should be at the beginning of the function,
114 * but for the sake of old broken applications that
115 * do not have proper alignment for their barriers
116 * (and don't check the return code from pthread_barrier_init),
117 * we put it here, after initializing the barrier regardless.
119 if (((uintptr_t)barrier
& (_LONG_LONG_ALIGNMENT
- 1)) &&
120 curthread
->ul_misaligned
== 0)
127 pthread_barrier_destroy(pthread_barrier_t
*barrier
)
129 mutex_t
*mp
= (mutex_t
*)&barrier
->__pthread_barrier_lock
;
130 cond_t
*cvp
= (cond_t
*)&barrier
->__pthread_barrier_cond
;
132 (void) mutex_destroy(mp
);
133 (void) cond_destroy(cvp
);
134 (void) memset(barrier
, -1, sizeof (*barrier
));
139 * pthread_barrier_wait() is not a cancellation point;
142 pthread_barrier_wait(pthread_barrier_t
*barrier
)
144 mutex_t
*mp
= (mutex_t
*)&barrier
->__pthread_barrier_lock
;
145 cond_t
*cvp
= (cond_t
*)&barrier
->__pthread_barrier_cond
;
149 (void) mutex_lock(mp
);
151 if (--barrier
->__pthread_barrier_current
== 0) {
152 barrier
->__pthread_barrier_cycle
++;
153 barrier
->__pthread_barrier_current
=
154 barrier
->__pthread_barrier_count
;
155 (void) mutex_unlock(mp
);
156 (void) cond_broadcast(cvp
);
157 return (PTHREAD_BARRIER_SERIAL_THREAD
);
160 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cancel_state
);
161 cycle
= barrier
->__pthread_barrier_cycle
;
163 (void) cond_wait(cvp
, mp
);
164 } while (cycle
== barrier
->__pthread_barrier_cycle
);
165 (void) pthread_setcancelstate(cancel_state
, NULL
);
167 (void) mutex_unlock(mp
);