* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: barrier.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)barrier.c 1.2 06/09/12 SMI"
barrier_init(barrier_t
*bp
, int count
)
for (i
= 0; i
< 2; ++i
) {
struct _sb
*sbp
= &(bp
->sb
[i
]);
if (n
= mutex_init(&sbp
->wait_lk
, NULL
, NULL
))
if (n
= cond_init(&sbp
->wait_cv
, NULL
, NULL
))
barrier_wait(barrier_t
*bp
)
struct _sb
*sbp
= bp
->sbp
;
mutex_lock(&sbp
->wait_lk
);
/* last thread to reach barrier */
/* reset runner count and switch sub-barriers */
sbp
->runners
= bp
->maxcnt
;
bp
->sbp
= (bp
->sbp
== &bp
->sb
[0])
? &bp
->sb
[1] : &bp
->sb
[0];
/* wake up the waiters */
cond_broadcast(&sbp
->wait_cv
);
sbp
->runners
--; /* one less runner */
while (sbp
->runners
!= bp
->maxcnt
)
cond_wait(&sbp
->wait_cv
, &sbp
->wait_lk
);
mutex_unlock(&sbp
->wait_lk
);
barrier_busy_init(barrier_busy_t
*bbp
, int count
)
bbp
->sbbp
= &bbp
->sbb
[0];
for (i
= 0; i
< 2; ++i
) {
struct _sbb
*sbbp
= &(bbp
->sbb
[i
]);
barrier_busy_wait(barrier_busy_t
*bbp
)
extern uint32_t sim_atomic_add_32_nv(uint32_t *target
, int32_t delta
);
struct _sbb
*sbbp
= bbp
->sbbp
;
if (sim_atomic_add_32_nv((uint32_t *)&sbbp
->runners
, -1) == 0) {
/* last thread to reach barrier */
/* switch sub-barriers, reset runner count and "cv" */
bbp
->sbbp
= (bbp
->sbbp
== &bbp
->sbb
[0])
? &bbp
->sbb
[1] : &bbp
->sbb
[0];
bbp
->sbbp
->runners
= bbp
->maxcnt
;
/* release the busy-waiters */