fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / Base / Threading / OSGBarrier.inl
blob9090cc6a76e122606acf6df4ed5dd98995958bee
1 /*---------------------------------------------------------------------------*\
2  *                                OpenSG                                     *
3  *                                                                           *
4  *                                                                           *
5  *           Copyright (C) 2003 by the OpenSG Forum                          *
6  *                                                                           *
7  *                            www.opensg.org                                 *
8  *                                                                           *
9  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
10  *                                                                           *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13  *                                License                                    *
14  *                                                                           *
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.                               *
18  *                                                                           *
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.                          *
23  *                                                                           *
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.                 *
27  *                                                                           *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30  *                                Changes                                    *
31  *                                                                           *
32  *                                                                           *
33  *                                                                           *
34  *                                                                           *
35  *                                                                           *
36  *                                                                           *
37 \*---------------------------------------------------------------------------*/
39 OSG_BEGIN_NAMESPACE
41 inline
42 void BarrierCommonBase::setNumWaitFor(UInt32 uiNumWaitFor)
44     _uiNumWaitFor = uiNumWaitFor;
48 #if defined (OSG_USE_PTHREADS)
50 /*------------------------------- Enter -----------------------------------*/
52 inline
53 void PThreadBarrierBase::enter(void)
55     if(_uiNumWaitFor <= 1)
56         return;
58     pthread_mutex_lock(&(_pLockOne));
60     UInt32 localCurrentCond = _uiCurrentCond;
62     _uiCount++;
64     if(_uiCount < _uiNumWaitFor)
65     {
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)
70         {
71             pthread_cond_wait(&(_pWakeupCondition[_uiCurrentCond]),
72                               &(_pLockOne)                         );
73         }
74     }
75     else
76     {
77         // ok, enough threads are waiting
78         //  => wake up all waiting threads
80         pthread_cond_broadcast(&(_pWakeupCondition[_uiCurrentCond]));
82         _uiCount       = 0;
83         _uiCurrentCond = 1 - _uiCurrentCond;
84     }
86     pthread_mutex_unlock(&(_pLockOne));
89 inline
90 void PThreadBarrierBase::enter(UInt32 uiNumWaitFor)
92     _uiNumWaitFor = uiNumWaitFor;
94     enter();
97 inline
98 UInt32 PThreadBarrierBase::getNumWaiting(void)
100     UInt32 numWaiting = 0;
102     pthread_mutex_lock  (&(_pLockOne));
103     numWaiting = _uiCount;
104     pthread_mutex_unlock(&(_pLockOne));
106     return numWaiting;
109 #endif /* OSG_USE_PTHREADS */
113 #if defined (OSG_USE_SPROC)
115 /*------------------------------ Enter ------------------------------------*/
117 inline
118 void SprocBarrierBase::enter(void)
120     if(_pBarrier != NULL)
121         barrier(_pBarrier, _uiNumWaitFor);
124 inline
125 void SprocBarrierBase::enter(UInt32 uiNumWaitFor)
127     _uiNumWaitFor = uiNumWaitFor;
129     enter();
132 inline
133 UInt32 SprocBarrierBase::getNumWaiting(void)
135     SFATAL << "SprocBarrierBase::getNumWaiting: Operation not supported."
136            << std::endl;
138     return 0;
141 #endif /* OSG_USE_SPROC */
145 #if defined (OSG_USE_WINTHREADS)
147 /*------------------------------ Enter ------------------------------------*/
149 inline
150 void WinThreadBarrierBase::enter(void)
152     if(_uiNumWaitFor <= 1)
153         return;
155     WaitForSingleObject(_pMutex1, INFINITE);
157     _uiCount++;
159     if(_uiCount < _uiNumWaitFor)
160     {
161         /* not enough threads are waiting => wait */
163         SignalObjectAndWait(_pMutex1,
164                             _pBarrierSema[_uiCurrentCond],
165                              INFINITE,
166                              FALSE);
167     }
168     else
169     {
170         /* ok, enough threads are waiting
171            => wake up all waiting threads
172         */
174         ReleaseSemaphore(_pBarrierSema[_uiCurrentCond],
175                          _uiNumWaitFor - 1,
176                          NULL);
178         _uiCount       = 0;
179         _uiCurrentCond = 1 - _uiCurrentCond;
181         ReleaseMutex(_pMutex1);
182     }
185 inline
186 void WinThreadBarrierBase::enter(UInt32 uiNumWaitFor)
188     _uiNumWaitFor = uiNumWaitFor;
190     enter();
193 inline
194 UInt32 WinThreadBarrierBase::getNumWaiting(void)
196     UInt32 numWaiting = 0;
198     WaitForSingleObject(_pMutex1, INFINITE);
199     numWaiting = _uiCount;
200     ReleaseMutex       (_pMutex1          );
202     return numWaiting;
205 #endif /* OSG_USE_WINTHREADS */
207 inline
208 Barrier::ObjTransitPtr Barrier::create(void)
210     return Barrier::get(NULL, false);
213 inline
214 const MPBarrierType &Barrier::getClassType(void)
216     return _type;
219 /*------------------------------- Enter -----------------------------------*/
222 inline
223 void Barrier::setNumWaitFor(UInt32 uiNumWaitFor)
225     Inherited::setNumWaitFor(uiNumWaitFor);
228 inline
229 UInt32 Barrier::getNumWaiting(void)
231     return Inherited::getNumWaiting();
234 inline
235 void Barrier::enter(void)
237     Inherited::enter();
240 inline
241 void Barrier::enter(UInt32 uiNumWaitFor)
243     Inherited::enter(uiNumWaitFor);
246 OSG_END_NAMESPACE