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"
57 ThreadManager
*ThreadManager::_pThreadManager
= NULL
;
58 BaseThreadRefPtr
ThreadManager::_pAppThread
= NULL
;
60 bool ThreadManager::_bShutdownInProgress
= false;
62 Char8
*ThreadManager::_szAppThreadType
= NULL
;
65 /*-------------------------- Get / Set ------------------------------------*/
67 void ThreadManager::setAppThreadType(const Char8
*szAppThreadType
)
69 osgStringDup(szAppThreadType
, _szAppThreadType
);
73 ThreadManager
*ThreadManager::the(void)
75 if(_pThreadManager
== NULL
)
76 _pThreadManager
= new ThreadManager();
78 return _pThreadManager
;
82 BaseThread
*ThreadManager::getAppThread(void)
88 /*-------------------- Create Threading Elements --------------------------*/
90 BaseThreadTransitPtr
ThreadManager::getThread(const Char8
*szName
,
92 const Char8
*szTypeName
)
94 BaseThreadTransitPtr
returnValue(NULL
);
96 _storePLock
->acquire();
98 returnValue
= _sThreadStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
100 _storePLock
->release();
105 BarrierTransitPtr
ThreadManager::getBarrier(const Char8
*szName
,
107 const Char8
*szTypeName
)
109 BarrierTransitPtr
returnValue(NULL
);
111 _storePLock
->acquire();
113 returnValue
= _sBarrierStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
115 _storePLock
->release();
120 CondVarTransitPtr
ThreadManager::getCondVar(const Char8
*szName
,
122 const Char8
*szTypeName
)
124 CondVarTransitPtr
returnValue(NULL
);
126 _storePLock
->acquire();
128 returnValue
= _sCondVarStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
130 _storePLock
->release();
135 LockTransitPtr
ThreadManager::getLock(const Char8
*szName
,
137 const Char8
*szTypeName
)
139 LockTransitPtr
returnValue(NULL
);
141 _storePLock
->acquire();
143 returnValue
= _sLockStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
145 _storePLock
->release();
150 LockPoolTransitPtr
ThreadManager::getLockPool(const Char8
*szName
,
152 const Char8
*szTypeName
)
154 LockPoolTransitPtr
returnValue(NULL
);
156 _storePLock
->acquire();
158 returnValue
= _sLockPoolStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
160 _storePLock
->release();
165 SemaphoreTransitPtr
ThreadManager::getSemaphore(const Char8
*szName
,
167 const Char8
*szTypeName
)
169 SemaphoreTransitPtr
returnValue(NULL
);
171 _storePLock
->acquire();
173 returnValue
= _sSemaphoreStore
.getMPField(szName
, szTypeName
, bGlobal
!= 0);
175 _storePLock
->release();
180 BaseThread
*ThreadManager::findThread(const Char8
*szName
)
182 BaseThread
*returnValue
= NULL
;
184 _storePLock
->acquire();
186 returnValue
= _sThreadStore
.findMPField(szName
);
188 _storePLock
->release();
193 Barrier
*ThreadManager::findBarrier(const Char8
*szName
)
195 Barrier
*returnValue
= NULL
;
197 _storePLock
->acquire();
199 returnValue
= _sBarrierStore
.findMPField(szName
);
201 _storePLock
->release();
206 CondVar
*ThreadManager::findCondVar(const Char8
*szName
)
208 CondVar
*returnValue
= NULL
;
210 _storePLock
->acquire();
212 returnValue
= _sCondVarStore
.findMPField(szName
);
214 _storePLock
->release();
219 Lock
*ThreadManager::findLock(const Char8
*szName
)
221 Lock
*returnValue
= NULL
;
223 _storePLock
->acquire();
225 returnValue
= _sLockStore
.findMPField(szName
);
227 _storePLock
->release();
232 LockPool
*ThreadManager::findLockPool(const Char8
*szName
)
234 LockPool
*returnValue
= NULL
;
236 _storePLock
->acquire();
238 returnValue
= _sLockPoolStore
.findMPField(szName
);
240 _storePLock
->release();
245 Semaphore
*ThreadManager::findSemaphore(const Char8
*szName
)
247 Semaphore
*returnValue
= NULL
;
249 _storePLock
->acquire();
251 returnValue
= _sSemaphoreStore
.findMPField(szName
);
253 _storePLock
->release();
258 void ThreadManager::dump(void)
260 ThreadStore::MPFieldMapCIt tI
= _sThreadStore
._mFieldMap
.begin();
261 ThreadStore::MPFieldMapCIt tE
= _sThreadStore
._mFieldMap
.end ();
263 for(; tI
!= tE
; ++tI
)
265 FLOG(("ThreadManager::dump: "
266 "thread [%s|%p] is still alive ([%d]). \n",
269 (*tI
).second
->exists()));
272 BarrierStore::MPFieldMapCIt bI
= _sBarrierStore
._mFieldMap
.begin();
273 BarrierStore::MPFieldMapCIt bE
= _sBarrierStore
._mFieldMap
.end ();
275 for(; bI
!= bE
; ++bI
)
277 FINFO(("ThreadManager::dump: "
278 "barrier [%s|%p] is still alive\n",
284 CondVarStore::MPFieldMapCIt cI
= _sCondVarStore
._mFieldMap
.begin();
285 CondVarStore::MPFieldMapCIt cE
= _sCondVarStore
._mFieldMap
.end ();
287 for(; cI
!= cE
; ++cI
)
289 FLOG(("ThreadManager::dump: "
290 "condvar [%s|%p] is still alive\n",
296 LockStore::MPFieldMapCIt lI
= _sLockStore
._mFieldMap
.begin();
297 LockStore::MPFieldMapCIt lE
= _sLockStore
._mFieldMap
.end ();
299 for(; lI
!= lE
; ++lI
)
301 FLOG(("ThreadManager::dump: "
302 "lock [%s|%p] is still alive\n",
307 LockPoolStore::MPFieldMapCIt lpI
= _sLockPoolStore
._mFieldMap
.begin();
308 LockPoolStore::MPFieldMapCIt lpE
= _sLockPoolStore
._mFieldMap
.end ();
310 for(; lpI
!= lpE
; ++lpI
)
312 FLOG(("ThreadManager::dump: "
313 "lockpool [%s|%p] is still alive\n",
314 (*lpI
).first
.c_str(),
319 SemaphoreStore::MPFieldMapCIt sI
= _sSemaphoreStore
._mFieldMap
.begin();
320 SemaphoreStore::MPFieldMapCIt sE
= _sSemaphoreStore
._mFieldMap
.end ();
322 for(; sI
!= sE
; ++sI
)
324 FLOG(("ThreadManager::dump: "
325 "semaphore [%s|%p] is still alive\n",
331 ("Sizes: ThreadStore: %"PRISize
" BarrierStore: %"PRISize
332 " CondVarStore: %"PRISize
" LockStore: %"PRISize
" LockPoolStore: %"
333 PRISize
" SemaphoreStore: %"PRISize
"\n",
334 _sThreadStore
._mFieldMap
.size(),
335 _sBarrierStore
._mFieldMap
.size(),
336 _sCondVarStore
._mFieldMap
.size(),
337 _sLockStore
._mFieldMap
.size(),
338 _sLockPoolStore
._mFieldMap
.size(),
339 _sSemaphoreStore
._mFieldMap
.size()));
342 /*------------------------------- Get -------------------------------------*/
344 #if defined(OSG_USE_SPROC)
345 usptr_t
*ThreadManager::getArena(void)
351 /*------------------------------ Helper -----------------------------------*/
353 bool ThreadManager::initialize(void)
355 return the()->init();
358 bool ThreadManager::terminate (void)
360 bool returnValue
= the()->shutdown();
362 delete _pThreadManager
;
364 _pThreadManager
= NULL
;
369 void ThreadManager::remove(BaseThread
*pThread
)
371 if(_bShutdownInProgress
== true)
374 _storePLock
->acquire();
376 _sThreadStore
.removeMPField(pThread
);
378 _storePLock
->release();
381 void ThreadManager::remove(Barrier
*pBarrier
)
383 if(_bShutdownInProgress
== true)
386 _storePLock
->acquire();
388 _sBarrierStore
.removeMPField(pBarrier
);
390 _storePLock
->release();
393 void ThreadManager::remove(CondVar
*pCondVar
)
395 if(_bShutdownInProgress
== true)
398 _storePLock
->acquire();
400 _sCondVarStore
.removeMPField(pCondVar
);
402 _storePLock
->release();
405 void ThreadManager::remove(Lock
*pLock
)
407 if(_bShutdownInProgress
== true)
410 _storePLock
->acquire();
412 _sLockStore
.removeMPField(pLock
);
414 _storePLock
->release();
417 void ThreadManager::remove(LockPool
*pLockPool
)
419 if(_bShutdownInProgress
== true)
422 _storePLock
->acquire();
424 _sLockPoolStore
.removeMPField(pLockPool
);
426 _storePLock
->release();
429 void ThreadManager::remove(Semaphore
*pSemaphore
)
431 if(_bShutdownInProgress
== true)
434 _storePLock
->acquire();
436 _sSemaphoreStore
.removeMPField(pSemaphore
);
438 _storePLock
->release();
441 UInt32
ThreadManager::registerThreadType(MPThreadType
*pType
)
443 return _sThreadStore
.registerMPType(pType
);
446 UInt32
ThreadManager::registerBarrierType(MPBarrierType
*pType
)
448 return _sBarrierStore
.registerMPType(pType
);
451 UInt32
ThreadManager::registerCondVarType(MPCondVarType
*pType
)
453 return _sCondVarStore
.registerMPType(pType
);
456 UInt32
ThreadManager::registerLockType(MPLockType
*pType
)
458 return _sLockStore
.registerMPType(pType
);
461 UInt32
ThreadManager::registerLockPoolType(MPLockPoolType
*pType
)
463 return _sLockPoolStore
.registerMPType(pType
);
466 UInt32
ThreadManager::registerSemaphoreType(MPSemaphoreType
*pType
)
468 return _sSemaphoreStore
.registerMPType(pType
);
472 #pragma set woff 1209
475 bool ThreadManager::init(void)
477 bool returnValue
= true;
479 FDEBUG(("OSGThreadManager init\n"))
481 #if defined(OSG_USE_SPROC)
482 usconfig(CONF_AUTOGROW
, 1);
483 usconfig(CONF_INITUSERS
, 20);
484 usconfig(CONF_INITSIZE
, 10 * 1048576);
485 usconfig(CONF_CHMOD
, 0666);
487 _pArena
= usinit("/dev/zero");
491 SFATAL
<< "OSGTM : could not initialize arena " << errno
<< std::endl
;
496 SINFO
<< "OSGTM : got arena " << _pArena
<< std::endl
;
500 _storePLock
= _sLockStore
.getMPField("OSGTMStoreLock", "OSGLock", true);
502 if(_storePLock
== NULL
)
504 SFATAL
<< "OSGTM : could not get table lock" << std::endl
;
510 SINFO
<< "OSGTM : got table lock " << _storePLock
<< std::endl
;
513 if(_szAppThreadType
== NULL
)
515 FINFO(("OSGTM : create -OSGBaseThread- app thread\n"));
517 _pAppThread
= getThread("OSGAppThread", true, "OSGBaseThread");
521 FINFO(("OSGTM : create -%s- app thread\n", _szAppThreadType
));
523 _pAppThread
= getThread("OSGAppThread", true, _szAppThreadType
);
526 FFASSERT((_pAppThread
!= NULL
), 1,
527 ("OSGTM : could not get application thread \n"););
530 FINFO(("OSGTM : got application thread %p\n", _pAppThread
.get()));
538 #pragma reset woff 1209
541 bool ThreadManager::shutdown(void)
543 FDEBUG(("OSGThreadManager shutdown\n"))
545 _bShutdownInProgress
= true;
547 _pAppThread
->shutdown();
553 ThreadStore::MPFieldMapCIt tI
= _sThreadStore
._mFieldMap
.begin();
554 ThreadStore::MPFieldMapCIt tE
= _sThreadStore
._mFieldMap
.end ();
556 for(; tI
!= tE
; ++tI
)
558 if(tI
->first
!= "OSGAppThread")
560 FWARNING(("ThreadManager::shutdown: "
561 "thread [%s|%p] is still alive ([%d]). \n",
564 (*tI
).second
->exists()));
568 BarrierStore::MPFieldMapCIt bI
= _sBarrierStore
._mFieldMap
.begin();
569 BarrierStore::MPFieldMapCIt bE
= _sBarrierStore
._mFieldMap
.end ();
571 for(; bI
!= bE
; ++bI
)
573 FWARNING(("ThreadManager::shutdown: "
574 "barrier [%s|%p] is still alive\n",
580 CondVarStore::MPFieldMapCIt cI
= _sCondVarStore
._mFieldMap
.begin();
581 CondVarStore::MPFieldMapCIt cE
= _sCondVarStore
._mFieldMap
.end ();
583 for(; cI
!= cE
; ++cI
)
585 FWARNING(("ThreadManager::shutdown: "
586 "condvar [%s|%p] is still alive\n",
592 LockStore::MPFieldMapCIt lI
= _sLockStore
._mFieldMap
.begin();
593 LockStore::MPFieldMapCIt lE
= _sLockStore
._mFieldMap
.end ();
595 for(; lI
!= lE
; ++lI
)
597 if(lI
->first
!= "OSGTMStoreLock" &&
598 lI
->first
!= "OSG::Log::_pLogLock" )
600 FWARNING(("ThreadManager::shutdown: "
601 "lock [%s|%p] is still alive\n",
607 LockPoolStore::MPFieldMapCIt lpI
= _sLockPoolStore
._mFieldMap
.begin();
608 LockPoolStore::MPFieldMapCIt lpE
= _sLockPoolStore
._mFieldMap
.end ();
610 for(; lpI
!= lpE
; ++lpI
)
612 FWARNING(("ThreadManager::shutdown: "
613 "lockpool [%s|%p] is still alive\n",
614 (*lpI
).first
.c_str(),
619 SemaphoreStore::MPFieldMapCIt sI
= _sSemaphoreStore
._mFieldMap
.begin();
620 SemaphoreStore::MPFieldMapCIt sE
= _sSemaphoreStore
._mFieldMap
.end ();
622 for(; sI
!= sE
; ++sI
)
624 FWARNING(("ThreadManager::shutdown: "
625 "semaphore [%s|%p] is still alive\n",
633 ("Sizes: ThreadStore: %"PRISize
" BarrierStore: %"PRISize
634 " CondVarStore: %"PRISize
" LockStore: %"PRISize
" LockPoolStore: %"
635 PRISize
" SemaphoreStore: %"PRISize
"\n",
636 _sThreadStore
._mFieldMap
.size(),
637 _sBarrierStore
._mFieldMap
.size(),
638 _sCondVarStore
._mFieldMap
.size(),
639 _sLockStore
._mFieldMap
.size(),
640 _sLockPoolStore
._mFieldMap
.size(),
641 _sSemaphoreStore
._mFieldMap
.size()));
643 _sThreadStore
.clear();
644 _sBarrierStore
.clear();
645 _sCondVarStore
.clear();
646 _sLockStore
.clear();
647 _sLockPoolStore
.clear();
648 _sSemaphoreStore
.clear();
650 Thread::terminateThreading();
652 #if defined(OSG_USE_SPROC)
660 /*--------------------------- Constructors --------------------------------*/
662 ThreadManager::ThreadManager(void) :
672 #if defined(OSG_USE_SPROC)
677 /*---------------------------- Destructo ----------------------------------*/
679 ThreadManager::~ThreadManager(void)
681 delete [] _szAppThreadType
;