1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-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 #include "OSGConfig.h"
44 #if defined(OSG_USE_SPROC)
50 #include "OSGThreadManager.h"
51 #include "OSGBaseInitFunctions.h"
53 #include "OSGThread.h"
54 #include "OSGAspectPool.h"
58 ThreadManager
*ThreadManager::_pThreadManager
= NULL
;
59 BaseThreadRefPtr
ThreadManager::_pAppThread
= NULL
;
61 bool ThreadManager::_bShutdownInProgress
= false;
63 Char8
*ThreadManager::_szAppThreadType
= NULL
;
66 /*-------------------------- Get / Set ------------------------------------*/
68 void ThreadManager::setAppThreadType(const Char8
*szAppThreadType
)
70 osgStringDup(szAppThreadType
, _szAppThreadType
);
74 ThreadManager
*ThreadManager::the(void)
76 if(_pThreadManager
== NULL
)
77 _pThreadManager
= new ThreadManager();
79 return _pThreadManager
;
83 BaseThread
*ThreadManager::getAppThread(void)
89 /*-------------------- Create Threading Elements --------------------------*/
91 BaseThreadTransitPtr
ThreadManager::getThread(const Char8
*szName
,
93 const Char8
*szTypeName
)
95 BaseThreadTransitPtr
returnValue(NULL
);
97 _storePLock
->acquire();
99 returnValue
= _sThreadStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
101 _storePLock
->release();
106 BarrierTransitPtr
ThreadManager::getBarrier(const Char8
*szName
,
108 const Char8
*szTypeName
)
110 BarrierTransitPtr
returnValue(NULL
);
112 _storePLock
->acquire();
114 returnValue
= _sBarrierStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
116 _storePLock
->release();
121 CondVarTransitPtr
ThreadManager::getCondVar(const Char8
*szName
,
123 const Char8
*szTypeName
)
125 CondVarTransitPtr
returnValue(NULL
);
127 _storePLock
->acquire();
129 returnValue
= _sCondVarStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
131 _storePLock
->release();
136 LockTransitPtr
ThreadManager::getLock(const Char8
*szName
,
138 const Char8
*szTypeName
)
140 LockTransitPtr
returnValue(NULL
);
142 _storePLock
->acquire();
144 returnValue
= _sLockStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
146 _storePLock
->release();
151 LockPoolTransitPtr
ThreadManager::getLockPool(const Char8
*szName
,
153 const Char8
*szTypeName
)
155 LockPoolTransitPtr
returnValue(NULL
);
157 _storePLock
->acquire();
159 returnValue
= _sLockPoolStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
161 _storePLock
->release();
166 SemaphoreTransitPtr
ThreadManager::getSemaphore(const Char8
*szName
,
168 const Char8
*szTypeName
)
170 SemaphoreTransitPtr
returnValue(NULL
);
172 _storePLock
->acquire();
174 returnValue
= _sSemaphoreStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
176 _storePLock
->release();
181 BaseThread
*ThreadManager::findThread(const Char8
*szName
)
183 BaseThread
*returnValue
= NULL
;
185 _storePLock
->acquire();
187 returnValue
= _sThreadStore
.findMPField(szName
);
189 _storePLock
->release();
194 Barrier
*ThreadManager::findBarrier(const Char8
*szName
)
196 Barrier
*returnValue
= NULL
;
198 _storePLock
->acquire();
200 returnValue
= _sBarrierStore
.findMPField(szName
);
202 _storePLock
->release();
207 CondVar
*ThreadManager::findCondVar(const Char8
*szName
)
209 CondVar
*returnValue
= NULL
;
211 _storePLock
->acquire();
213 returnValue
= _sCondVarStore
.findMPField(szName
);
215 _storePLock
->release();
220 Lock
*ThreadManager::findLock(const Char8
*szName
)
222 Lock
*returnValue
= NULL
;
224 _storePLock
->acquire();
226 returnValue
= _sLockStore
.findMPField(szName
);
228 _storePLock
->release();
233 LockPool
*ThreadManager::findLockPool(const Char8
*szName
)
235 LockPool
*returnValue
= NULL
;
237 _storePLock
->acquire();
239 returnValue
= _sLockPoolStore
.findMPField(szName
);
241 _storePLock
->release();
246 Semaphore
*ThreadManager::findSemaphore(const Char8
*szName
)
248 Semaphore
*returnValue
= NULL
;
250 _storePLock
->acquire();
252 returnValue
= _sSemaphoreStore
.findMPField(szName
);
254 _storePLock
->release();
259 void ThreadManager::dump(void)
261 ThreadStore::MPFieldMapCIt tI
= _sThreadStore
._mFieldMap
.begin();
262 ThreadStore::MPFieldMapCIt tE
= _sThreadStore
._mFieldMap
.end ();
264 for(; tI
!= tE
; ++tI
)
266 FLOG(("ThreadManager::dump: "
267 "thread [%s|%p] is still alive ([%d]). \n",
269 static_cast<void *>((*tI
).second
),
270 (*tI
).second
->exists()));
273 BarrierStore::MPFieldMapCIt bI
= _sBarrierStore
._mFieldMap
.begin();
274 BarrierStore::MPFieldMapCIt bE
= _sBarrierStore
._mFieldMap
.end ();
276 for(; bI
!= bE
; ++bI
)
278 FINFO(("ThreadManager::dump: "
279 "barrier [%s|%p] is still alive\n",
281 static_cast<void *>((*bI
).second
)));
285 CondVarStore::MPFieldMapCIt cI
= _sCondVarStore
._mFieldMap
.begin();
286 CondVarStore::MPFieldMapCIt cE
= _sCondVarStore
._mFieldMap
.end ();
288 for(; cI
!= cE
; ++cI
)
290 FLOG(("ThreadManager::dump: "
291 "condvar [%s|%p] is still alive\n",
293 static_cast<void *>((*cI
).second
)));
297 LockStore::MPFieldMapCIt lI
= _sLockStore
._mFieldMap
.begin();
298 LockStore::MPFieldMapCIt lE
= _sLockStore
._mFieldMap
.end ();
300 for(; lI
!= lE
; ++lI
)
302 FLOG(("ThreadManager::dump: "
303 "lock [%s|%p] is still alive\n",
305 static_cast<void *>((*lI
).second
)));
308 LockPoolStore::MPFieldMapCIt lpI
= _sLockPoolStore
._mFieldMap
.begin();
309 LockPoolStore::MPFieldMapCIt lpE
= _sLockPoolStore
._mFieldMap
.end ();
311 for(; lpI
!= lpE
; ++lpI
)
313 FLOG(("ThreadManager::dump: "
314 "lockpool [%s|%p] is still alive\n",
315 (*lpI
).first
.c_str(),
316 static_cast<void *>((*lpI
).second
)));
320 SemaphoreStore::MPFieldMapCIt sI
= _sSemaphoreStore
._mFieldMap
.begin();
321 SemaphoreStore::MPFieldMapCIt sE
= _sSemaphoreStore
._mFieldMap
.end ();
323 for(; sI
!= sE
; ++sI
)
325 FLOG(("ThreadManager::dump: "
326 "semaphore [%s|%p] is still alive\n",
328 static_cast<void *>((*sI
).second
)));
332 ("Sizes: ThreadStore: %" PRISize
" BarrierStore: %" PRISize
333 " CondVarStore: %" PRISize
" LockStore: %" PRISize
" LockPoolStore: %"
334 PRISize
" SemaphoreStore: %" PRISize
"\n",
335 _sThreadStore
._mFieldMap
.size(),
336 _sBarrierStore
._mFieldMap
.size(),
337 _sCondVarStore
._mFieldMap
.size(),
338 _sLockStore
._mFieldMap
.size(),
339 _sLockPoolStore
._mFieldMap
.size(),
340 _sSemaphoreStore
._mFieldMap
.size()));
343 /*------------------------------- Get -------------------------------------*/
345 #if defined(OSG_USE_SPROC)
346 usptr_t
*ThreadManager::getArena(void)
352 /*------------------------------ Helper -----------------------------------*/
354 bool ThreadManager::initialize(void)
356 return the()->init();
359 bool ThreadManager::terminate (void)
361 bool returnValue
= the()->shutdown();
363 delete _pThreadManager
;
365 _pThreadManager
= NULL
;
370 void ThreadManager::remove(BaseThread
*pThread
)
372 if(_bShutdownInProgress
== true)
375 _storePLock
->acquire();
377 _sThreadStore
.removeMPField(pThread
);
379 _storePLock
->release();
382 void ThreadManager::remove(Barrier
*pBarrier
)
384 if(_bShutdownInProgress
== true)
387 _storePLock
->acquire();
389 _sBarrierStore
.removeMPField(pBarrier
);
391 _storePLock
->release();
394 void ThreadManager::remove(CondVar
*pCondVar
)
396 if(_bShutdownInProgress
== true)
399 _storePLock
->acquire();
401 _sCondVarStore
.removeMPField(pCondVar
);
403 _storePLock
->release();
406 void ThreadManager::remove(Lock
*pLock
)
408 if(_bShutdownInProgress
== true)
411 _storePLock
->acquire();
413 _sLockStore
.removeMPField(pLock
);
415 _storePLock
->release();
418 void ThreadManager::remove(LockPool
*pLockPool
)
420 if(_bShutdownInProgress
== true)
423 _storePLock
->acquire();
425 _sLockPoolStore
.removeMPField(pLockPool
);
427 _storePLock
->release();
430 void ThreadManager::remove(Semaphore
*pSemaphore
)
432 if(_bShutdownInProgress
== true)
435 _storePLock
->acquire();
437 _sSemaphoreStore
.removeMPField(pSemaphore
);
439 _storePLock
->release();
442 UInt32
ThreadManager::registerThreadType(MPThreadType
*pType
)
444 return _sThreadStore
.registerMPType(pType
);
447 UInt32
ThreadManager::registerBarrierType(MPBarrierType
*pType
)
449 return _sBarrierStore
.registerMPType(pType
);
452 UInt32
ThreadManager::registerCondVarType(MPCondVarType
*pType
)
454 return _sCondVarStore
.registerMPType(pType
);
457 UInt32
ThreadManager::registerLockType(MPLockType
*pType
)
459 return _sLockStore
.registerMPType(pType
);
462 UInt32
ThreadManager::registerLockPoolType(MPLockPoolType
*pType
)
464 return _sLockPoolStore
.registerMPType(pType
);
467 UInt32
ThreadManager::registerSemaphoreType(MPSemaphoreType
*pType
)
469 return _sSemaphoreStore
.registerMPType(pType
);
473 #pragma set woff 1209
476 bool ThreadManager::init(void)
478 bool returnValue
= true;
480 FDEBUG(("OSGThreadManager init\n"))
482 #if defined(OSG_USE_SPROC)
483 usconfig(CONF_AUTOGROW
, 1);
484 usconfig(CONF_INITUSERS
, 20);
485 usconfig(CONF_INITSIZE
, 10 * 1048576);
486 usconfig(CONF_CHMOD
, 0666);
488 _pArena
= usinit("/dev/zero");
492 SFATAL
<< "OSGTM : could not initialize arena " << errno
<< std::endl
;
497 SINFO
<< "OSGTM : got arena " << _pArena
<< std::endl
;
501 _storePLock
= _sLockStore
.getMPField("OSGTMStoreLock", "OSGLock", true);
503 if(_storePLock
== NULL
)
505 SFATAL
<< "OSGTM : could not get table lock" << std::endl
;
511 SINFO
<< "OSGTM : got table lock " << _storePLock
<< std::endl
;
514 if(_szAppThreadType
== NULL
)
516 FINFO(("OSGTM : create -OSGBaseThread- app thread\n"));
518 _pAppThread
= getThread("OSGAppThread", true, "OSGBaseThread");
522 FINFO(("OSGTM : create -%s- app thread\n", _szAppThreadType
));
524 _pAppThread
= getThread("OSGAppThread", true, _szAppThreadType
);
527 FFASSERT((_pAppThread
!= NULL
), 1,
528 ("OSGTM : could not get application thread \n"););
531 FINFO(("OSGTM : got application thread %p\n",
532 static_cast<void *>(_pAppThread
.get())));
534 AspectPool::the()->get("AppThreadAspect");
542 #pragma reset woff 1209
545 bool ThreadManager::shutdown(void)
547 FDEBUG(("OSGThreadManager shutdown\n"))
549 _bShutdownInProgress
= true;
551 _pAppThread
->shutdown();
557 ThreadStore::MPFieldMapCIt tI
= _sThreadStore
._mFieldMap
.begin();
558 ThreadStore::MPFieldMapCIt tE
= _sThreadStore
._mFieldMap
.end ();
560 for(; tI
!= tE
; ++tI
)
562 if(tI
->first
!= "OSGAppThread")
564 FWARNING(("ThreadManager::shutdown: "
565 "thread [%s|%p] is still alive ([%d]). \n",
567 static_cast<void *>((*tI
).second
),
568 (*tI
).second
->exists()));
572 BarrierStore::MPFieldMapCIt bI
= _sBarrierStore
._mFieldMap
.begin();
573 BarrierStore::MPFieldMapCIt bE
= _sBarrierStore
._mFieldMap
.end ();
575 for(; bI
!= bE
; ++bI
)
577 FWARNING(("ThreadManager::shutdown: "
578 "barrier [%s|%p] is still alive\n",
580 static_cast<void *>((*bI
).second
)));
584 CondVarStore::MPFieldMapCIt cI
= _sCondVarStore
._mFieldMap
.begin();
585 CondVarStore::MPFieldMapCIt cE
= _sCondVarStore
._mFieldMap
.end ();
587 for(; cI
!= cE
; ++cI
)
589 FWARNING(("ThreadManager::shutdown: "
590 "condvar [%s|%p] is still alive\n",
592 static_cast<void *>((*cI
).second
)));
596 LockStore::MPFieldMapCIt lI
= _sLockStore
._mFieldMap
.begin();
597 LockStore::MPFieldMapCIt lE
= _sLockStore
._mFieldMap
.end ();
599 for(; lI
!= lE
; ++lI
)
601 if(lI
->first
!= "OSGTMStoreLock" &&
602 lI
->first
!= "OSG::Log::_pLogLock" )
604 FWARNING(("ThreadManager::shutdown: "
605 "lock [%s|%p] is still alive\n",
607 static_cast<void *>((*lI
).second
)));
611 LockPoolStore::MPFieldMapCIt lpI
= _sLockPoolStore
._mFieldMap
.begin();
612 LockPoolStore::MPFieldMapCIt lpE
= _sLockPoolStore
._mFieldMap
.end ();
614 for(; lpI
!= lpE
; ++lpI
)
616 FWARNING(("ThreadManager::shutdown: "
617 "lockpool [%s|%p] is still alive\n",
618 (*lpI
).first
.c_str(),
619 static_cast<void *>((*lpI
).second
)));
623 SemaphoreStore::MPFieldMapCIt sI
= _sSemaphoreStore
._mFieldMap
.begin();
624 SemaphoreStore::MPFieldMapCIt sE
= _sSemaphoreStore
._mFieldMap
.end ();
626 for(; sI
!= sE
; ++sI
)
628 FWARNING(("ThreadManager::shutdown: "
629 "semaphore [%s|%p] is still alive\n",
631 static_cast<void *>((*sI
).second
)));
637 ("Sizes: ThreadStore: %" PRISize
" BarrierStore: %" PRISize
638 " CondVarStore: %" PRISize
" LockStore: %" PRISize
" LockPoolStore: %"
639 PRISize
" SemaphoreStore: %" PRISize
"\n",
640 _sThreadStore
._mFieldMap
.size(),
641 _sBarrierStore
._mFieldMap
.size(),
642 _sCondVarStore
._mFieldMap
.size(),
643 _sLockStore
._mFieldMap
.size(),
644 _sLockPoolStore
._mFieldMap
.size(),
645 _sSemaphoreStore
._mFieldMap
.size()));
647 _sThreadStore
.clear();
648 _sBarrierStore
.clear();
649 _sCondVarStore
.clear();
650 _sLockStore
.clear();
651 _sLockPoolStore
.clear();
652 _sSemaphoreStore
.clear();
654 Thread::terminateThreading();
656 #if defined(OSG_USE_SPROC)
664 /*--------------------------- Constructors --------------------------------*/
666 ThreadManager::ThreadManager(void) :
676 #if defined(OSG_USE_SPROC)
681 /*---------------------------- Destructo ----------------------------------*/
683 ThreadManager::~ThreadManager(void)
685 delete [] _szAppThreadType
;