1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2003 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
42 void BarrierCommonBase::setNumWaitFor(UInt32 uiNumWaitFor)
44 _uiNumWaitFor = uiNumWaitFor;
48 #if defined (OSG_USE_PTHREADS)
50 /*------------------------------- Enter -----------------------------------*/
53 void PThreadBarrierBase::enter(void)
55 if(_uiNumWaitFor <= 1)
58 pthread_mutex_lock(&(_pLockOne));
60 UInt32 localCurrentCond = _uiCurrentCond;
64 if(_uiCount < _uiNumWaitFor)
66 // not enough threads are waiting => wait
67 // use a loop to handle spurious wakeups -- loop condition
68 // can not use _uiCount as it is reset in the else branch
69 while(localCurrentCond == _uiCurrentCond)
71 pthread_cond_wait(&(_pWakeupCondition[_uiCurrentCond]),
77 // ok, enough threads are waiting
78 // => wake up all waiting threads
80 pthread_cond_broadcast(&(_pWakeupCondition[_uiCurrentCond]));
83 _uiCurrentCond = 1 - _uiCurrentCond;
86 pthread_mutex_unlock(&(_pLockOne));
90 void PThreadBarrierBase::enter(UInt32 uiNumWaitFor)
92 _uiNumWaitFor = uiNumWaitFor;
98 UInt32 PThreadBarrierBase::getNumWaiting(void)
100 UInt32 numWaiting = 0;
102 pthread_mutex_lock (&(_pLockOne));
103 numWaiting = _uiCount;
104 pthread_mutex_unlock(&(_pLockOne));
109 #endif /* OSG_USE_PTHREADS */
113 #if defined (OSG_USE_SPROC)
115 /*------------------------------ Enter ------------------------------------*/
118 void SprocBarrierBase::enter(void)
120 if(_pBarrier != NULL)
121 barrier(_pBarrier, _uiNumWaitFor);
125 void SprocBarrierBase::enter(UInt32 uiNumWaitFor)
127 _uiNumWaitFor = uiNumWaitFor;
133 UInt32 SprocBarrierBase::getNumWaiting(void)
135 SFATAL << "SprocBarrierBase::getNumWaiting: Operation not supported."
141 #endif /* OSG_USE_SPROC */
145 #if defined (OSG_USE_WINTHREADS)
147 /*------------------------------ Enter ------------------------------------*/
150 void WinThreadBarrierBase::enter(void)
152 if(_uiNumWaitFor <= 1)
155 WaitForSingleObject(_pMutex1, INFINITE);
159 if(_uiCount < _uiNumWaitFor)
161 /* not enough threads are waiting => wait */
163 SignalObjectAndWait(_pMutex1,
164 _pBarrierSema[_uiCurrentCond],
170 /* ok, enough threads are waiting
171 => wake up all waiting threads
174 ReleaseSemaphore(_pBarrierSema[_uiCurrentCond],
179 _uiCurrentCond = 1 - _uiCurrentCond;
181 ReleaseMutex(_pMutex1);
186 void WinThreadBarrierBase::enter(UInt32 uiNumWaitFor)
188 _uiNumWaitFor = uiNumWaitFor;
194 UInt32 WinThreadBarrierBase::getNumWaiting(void)
196 UInt32 numWaiting = 0;
198 WaitForSingleObject(_pMutex1, INFINITE);
199 numWaiting = _uiCount;
200 ReleaseMutex (_pMutex1 );
205 #endif /* OSG_USE_WINTHREADS */
208 Barrier::ObjTransitPtr Barrier::create(void)
210 return Barrier::get(NULL, false);
214 const MPBarrierType &Barrier::getClassType(void)
219 /*------------------------------- Enter -----------------------------------*/
223 void Barrier::setNumWaitFor(UInt32 uiNumWaitFor)
225 Inherited::setNumWaitFor(uiNumWaitFor);
229 UInt32 Barrier::getNumWaiting(void)
231 return Inherited::getNumWaiting();
235 void Barrier::enter(void)
241 void Barrier::enter(UInt32 uiNumWaitFor)
243 Inherited::enter(uiNumWaitFor);