00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifdef OSG_DOC_FILES_IN_MODULE
00040
00043 #endif
00044
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047
00048 #include "OSGConfig.h"
00049
00050 #include <iostream>
00051
00052 #include "OSGThread.h"
00053 #include "OSGBaseFunctions.h"
00054 #include "OSGChangeList.h"
00055 #include "OSGThreadManager.h"
00056 #include "OSGLog.h"
00057
00058 #if ! defined (OSG_USE_PTHREADS) && ! defined (OSG_USE_WINTHREADS)
00059 #include <sys/types.h>
00060 #include <sys/prctl.h>
00061 #include <errno.h>
00062
00063 #include <sys/types.h>
00064 #include <sys/wait.h>
00065 #include <unistd.h>
00066 #include <signal.h>
00067 #endif
00068
00069 OSG_USING_NAMESPACE
00070
00071 const UInt32 ThreadCommonBase::InvalidAspect =
00072 TypeTraits<UInt32>::BitsSet;
00073
00074 Int32 ThreadCommonBase::_force_aspect = -1;
00075
00076
00077
00078
00079 void ThreadCommonBase::setForceAspect(Int32 aspect)
00080 {
00081 #ifdef OSG_FORCE_ASPECT
00082 _force_aspect = aspect;
00083 #else
00084 SFATAL << "ThreadCommonBase::setForceAspect: not supported, please enable it in scons build system via 'force_aspect=1'" << std::endl;
00085 #endif
00086 }
00087
00088 Int32 ThreadCommonBase::getForceAspect(void)
00089 {
00090 return _force_aspect;
00091 }
00092
00093
00094
00095
00096 ChangeList *ThreadCommonBase::getChangeList(void)
00097 {
00098 return _pChangeList;
00099 }
00100
00101
00102
00103
00104 ThreadCommonBase::ThreadCommonBase(const Char8 *szName,
00105 UInt32 uiId) :
00106
00107 Inherited (szName,
00108 uiId ),
00109
00110 _uiAspectId (0 ),
00111 _pChangeList(NULL )
00112 {
00113 }
00114
00115
00116
00117
00118 ThreadCommonBase::~ThreadCommonBase(void)
00119 {
00120 subRefP(_pChangeList);
00121 }
00122
00123
00124
00125
00126 void ThreadCommonBase::setAspect(UInt32 uiAspectId)
00127 {
00128 _uiAspectId = uiAspectId;
00129 }
00130
00131 void ThreadCommonBase::setChangeList(ChangeList *pChangeList)
00132 {
00133 setRefP(_pChangeList, pChangeList);
00134 }
00135
00136
00137
00138
00139 #if defined (OSG_USE_PTHREADS)
00140
00141 #if defined(OSG_PTHREAD_ELF_TLS)
00142 __thread UInt32 PThreadBase::_uiTLSAspectId = 0;
00143 __thread ChangeList *PThreadBase::_pTLSChangeList = NULL;
00144 #else
00145 pthread_key_t PThreadBase::_aspectKey;
00146 pthread_key_t PThreadBase::_changeListKey;
00147 #endif
00148
00149
00150
00151
00152 UInt32 PThreadBase::getAspect(void)
00153 {
00154 #ifdef OSG_FORCE_ASPECT
00155 if(_force_aspect != -1)
00156 return _force_aspect;
00157 #endif
00158
00159 #if defined(OSG_PTHREAD_ELF_TLS)
00160 return _uiTLSAspectId;
00161 #else
00162 UInt32 *pUint;
00163
00164 pUint = static_cast<UInt32 *>(pthread_getspecific(_aspectKey));
00165
00166 return *pUint;
00167 #endif
00168
00169 }
00170
00171 ChangeList *PThreadBase::getCurrentChangeList(void)
00172 {
00173 #if defined(OSG_PTHREAD_ELF_TLS)
00174 return _pTLSChangeList;
00175 #else
00176 ChangeList **pCList;
00177
00178 pCList = static_cast<ChangeList **>(pthread_getspecific(_changeListKey));
00179
00180 return *pCList;
00181 #endif
00182 }
00183
00184
00185
00186
00187
00188
00189 bool PThreadBase::runFunction(ThreadFuncF fThreadFunc,
00190 UInt32 uiAspectId,
00191 void *pThreadArg)
00192 {
00193 if(uiAspectId >= ThreadManager::getNumAspects())
00194 {
00195 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00196 return false;
00197 }
00198
00199 Inherited::setAspect(uiAspectId);
00200
00201 return Inherited::runFunction(fThreadFunc, pThreadArg);
00202 }
00203
00204
00205
00206
00207 #if !defined(OSG_PTHREAD_ELF_TLS)
00208 void PThreadBase::freeAspect(void *pAspect)
00209 {
00210 UInt32 *pUint = static_cast<UInt32 *>(pAspect);
00211
00212 if(pUint != NULL)
00213 delete pUint;
00214 }
00215
00216 void PThreadBase::freeChangeList(void *pChangeList)
00217 {
00218 ChangeList **pCl = static_cast<ChangeList **>(pChangeList);
00219
00220 if(pCl != NULL)
00221 delete pCl;
00222 }
00223 #endif
00224
00225
00226
00227
00228 PThreadBase::PThreadBase(const Char8 *szName,
00229 UInt32 uiId) :
00230 Inherited(szName, uiId)
00231 {
00232 }
00233
00234
00235
00236
00237 PThreadBase::~PThreadBase(void)
00238 {
00239 }
00240
00241
00242
00243
00244 void PThreadBase::init(void)
00245 {
00246 if(_bInitialized == true)
00247 return;
00248
00249 Inherited::init();
00250
00251 if(_bInitialized == true)
00252 {
00253 setupAspect ();
00254 setupChangeList();
00255 }
00256 }
00257
00258
00259 void PThreadBase::setupAspect(void)
00260 {
00261
00262 #if defined(OSG_PTHREAD_ELF_TLS)
00263 _uiTLSAspectId = Inherited::_uiAspectId;
00264 #else
00265 UInt32 *pUint = new UInt32;
00266
00267 *pUint = Inherited::_uiAspectId;
00268
00269 pthread_setspecific(_aspectKey, static_cast<void *>(pUint));
00270 #endif
00271 }
00272
00273 void PThreadBase::setupChangeList(void)
00274 {
00275 #if defined(OSG_PTHREAD_ELF_TLS)
00276 if(Inherited::_pChangeList == NULL)
00277 {
00278 _pTLSChangeList = new ChangeList;
00279
00280 Inherited::setChangeList(_pTLSChangeList);
00281 }
00282 else
00283 {
00284 _pTLSChangeList = Inherited::_pChangeList;
00285
00286 _pTLSChangeList->clearAll();
00287 }
00288
00289 _pTLSChangeList->setAspect(Inherited::_uiAspectId);
00290 #else
00291 ChangeList **pChangeList = new ChangeList *;
00292
00293 if(Inherited::_pChangeList == NULL)
00294 {
00295 *pChangeList = new ChangeList;
00296
00297 Inherited::setChangeList(*pChangeList);
00298 }
00299 else
00300 {
00301 *pChangeList = Inherited::_pChangeList;
00302
00303 (*pChangeList)->clearAll();
00304 }
00305
00306 (*pChangeList)->setAspect(Inherited::_uiAspectId);
00307 pthread_setspecific(_changeListKey, static_cast<void *>(pChangeList));
00308 #endif
00309 }
00310
00311 #endif
00312
00313
00314
00315
00316 #if defined (OSG_USE_SPROC)
00317
00318
00319
00320
00321 UInt32 SprocBase::getAspect(void)
00322 {
00323 #ifdef OSG_FORCE_ASPECT
00324 if(_force_aspect != -1)
00325 return _force_aspect;
00326 #endif
00327
00328 return ((OSGProcessData *) PRDA->usr_prda.fill)->_uiAspectId;
00329 }
00330
00331 ChangeList *SprocBase::getCurrentChangeList(void)
00332 {
00333 return ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList;
00334 }
00335
00336
00337
00338
00339
00340
00341 bool SprocBase::runFunction(ThreadFuncF fThreadFunc,
00342 UInt32 uiAspectId,
00343 void *pThreadArg)
00344 {
00345 if(uiAspectId >= ThreadManager::getNumAspects())
00346 {
00347 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00348 return false;
00349 }
00350
00351 Inherited::setAspect(uiAspectId);
00352
00353 return Inherited::runFunction(fThreadFunc, pThreadArg);
00354 }
00355
00356
00357
00358
00359 SprocBase::SprocBase(const Char8 *szName,
00360 UInt32 uiId) :
00361 Inherited(szName, uiId)
00362 {
00363 }
00364
00365
00366
00367
00368 SprocBase::~SprocBase(void)
00369 {
00370 }
00371
00372
00373
00374
00375 void SprocBase::setAspectInternal(UInt32 uiAspect)
00376 {
00377 ((OSGProcessData *) PRDA->usr_prda.fill)->_uiAspectId = uiAspect;
00378 }
00379
00380
00381
00382
00383 void SprocBase::init(void)
00384 {
00385 if(_bInitialized == true)
00386 return;
00387
00388 Inherited::init();
00389
00390 if(_bInitialized == true)
00391 {
00392 setAspectInternal (this->_uiAspectId);
00393 setupChangeListInternal();
00394 }
00395 }
00396
00397 void SprocBase::setupChangeListInternal(void)
00398 {
00399 if(Inherited::_pChangeList == NULL)
00400 {
00401 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList =
00402 new ChangeList();
00403
00404 Inherited::setChangeList(
00405 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList);
00406 }
00407 else
00408 {
00409 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList =
00410 Inherited::_pChangeList;
00411
00412 Inherited::_pChangeList->clearAll();
00413 }
00414
00415 Inherited::_pChangeList->setAspect(Inherited::_uiAspectId);
00416 }
00417
00418 #endif
00419
00420
00421
00422
00423 #if defined (OSG_USE_WINTHREADS)
00424
00425 #if defined(OSG_ASPECT_USE_LOCALSTORAGE)
00426 UInt32 WinThreadBase::_aspectKey = 0;
00427 UInt32 WinThreadBase::_changeListKey = 0;
00428 #endif
00429
00430 #if defined(OSG_ASPECT_USE_DECLSPEC)
00431 static __declspec (thread) UInt32 _uiAspectLocal = 0;
00432 static __declspec (thread) ChangeList *_pChangeListLocal = NULL;
00433 #endif
00434
00435
00436
00437
00438 UInt32 WinThreadBase::getAspect(void)
00439 {
00440 #ifdef OSG_FORCE_ASPECT
00441 if(_force_aspect != -1)
00442 return _force_aspect;
00443 #endif
00444
00445 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00446 UInt32 *pUint;
00447
00448 pUint = (UInt32 *) TlsGetValue(_aspectKey);
00449
00450 return *pUint;
00451 #endif
00452 #ifdef OSG_ASPECT_USE_DECLSPEC
00453 return _uiAspectLocal;
00454 #endif
00455 }
00456
00457 ChangeList *WinThreadBase::getCurrentChangeList(void)
00458 {
00459 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00460 ChangeList **pCList;
00461
00462 pCList = (ChangeList **) TlsGetValue(_changeListKey);
00463
00464 return *pCList;
00465 #endif
00466 #ifdef OSG_ASPECT_USE_DECLSPEC
00467 return _pChangeListLocal;
00468 #endif
00469 }
00470
00471
00472
00473
00474
00475
00476 bool WinThreadBase::runFunction(ThreadFuncF fThreadFunc,
00477 UInt32 uiAspectId,
00478 void *pThreadArg)
00479 {
00480 if(uiAspectId >= ThreadManager::getNumAspects())
00481 {
00482 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00483 return false;
00484 }
00485
00486 Inherited::setAspect(uiAspectId);
00487
00488 return Inherited::runFunction(fThreadFunc, pThreadArg);
00489 }
00490
00491
00492
00493
00494 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00495 void WinThreadBase::freeAspect(void)
00496 {
00497 UInt32 *pUint;
00498
00499 pUint = (UInt32 *) TlsGetValue(_aspectKey);
00500
00501 delete pUint;
00502 }
00503
00504 void WinThreadBase::freeChangeList(void)
00505 {
00506 ChangeList **pCList;
00507
00508 pCList = (ChangeList **) TlsGetValue(_changeListKey);
00509
00510 delete pCList;
00511 }
00512 #endif
00513
00514
00515
00516
00517 WinThreadBase::WinThreadBase(const Char8 *szName,
00518 UInt32 uiId) :
00519 Inherited(szName, uiId)
00520 {
00521 }
00522
00523
00524
00525
00526 WinThreadBase::~WinThreadBase(void)
00527 {
00528 }
00529
00530
00531
00532
00533 void WinThreadBase::init(void)
00534 {
00535 if(_bInitialized == true)
00536 return;
00537
00538 Inherited::init();
00539
00540 if(_bInitialized == true)
00541 {
00542 setupAspect ();
00543 setupChangeList();
00544 }
00545 }
00546
00547 void WinThreadBase::setupAspect(void)
00548 {
00549 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00550 UInt32 *pUint = new UInt32;
00551
00552 *pUint = Inherited::_uiAspectId;
00553
00554 TlsSetValue(_aspectKey, pUint);
00555 #endif
00556
00557 #ifdef OSG_ASPECT_USE_DECLSPEC
00558 _uiAspectLocal = Inherited::_uiAspectId;
00559 #endif
00560 }
00561
00562 void WinThreadBase::setupChangeList(void)
00563 {
00564 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00565 ChangeList **pChangeList = new ChangeList *;
00566
00567 if(Inherited::_pChangeList == NULL)
00568 {
00569 *pChangeList = new ChangeList;
00570
00571 Inherited::setChangeList(*pChangeList);
00572 }
00573 else
00574 {
00575 *pChangeList = Inherited::_pChangeList;
00576
00577 (*pChangeList)->clearAll();
00578 }
00579
00580 (*pChangeList)->setAspect(Inherited::_uiAspectId);
00581 TlsSetValue(_changeListKey, pChangeList);
00582 #endif
00583
00584 #if defined (OSG_ASPECT_USE_DECLSPEC)
00585 if(Inherited::_pChangeList == NULL)
00586 {
00587 _pChangeListLocal = new ChangeList;
00588 Inherited::setChangeList(_pChangeListLocal);
00589 }
00590 else
00591 {
00592 _pChangeListLocal = Inherited::_pChangeList;
00593
00594 _pChangeListLocal->clearAll();
00595 }
00596
00597 _pChangeListLocal->setAspect(Inherited::_uiAspectId);
00598 #endif
00599 }
00600
00601 #endif
00602
00603
00604
00605
00606 MPThreadType Thread::_type("OSGThread",
00607 "OSGBaseThread",
00608 reinterpret_cast<CreateThreadF>(Thread::create),
00609 static_cast<InitThreadingF>(Thread::initThreading));
00610
00611
00612
00613
00614 ThreadBase *Thread::getCurrent(void)
00615 {
00616 return static_cast<ThreadBase *>(Inherited::getCurrent());
00617 }
00618
00619 Thread *Thread::get(const Char8 *szName)
00620 {
00621 BaseThread *pThread = ThreadManager::the()->getThread(szName, "OSGThread");
00622
00623 return dynamic_cast<Thread *>(pThread);
00624 }
00625
00626 Thread *Thread::find(const Char8 *szName)
00627 {
00628 BaseThread *pThread = ThreadManager::the()->findThread(szName);
00629
00630 return dynamic_cast<Thread *>(pThread);
00631 }
00632
00633 void Thread::run(UInt32 uiAspectId)
00634 {
00635 Inherited::runFunction(runWorkProc, uiAspectId, this);
00636 }
00637
00638
00639
00640
00641 Thread *Thread::create(const Char8 *szName, UInt32 uiId)
00642 {
00643 return new Thread(szName, uiId);
00644 }
00645
00646 void Thread::initThreading(void)
00647 {
00648 FINFO(("Thread::initThreading\n"))
00649
00650 #if defined(OSG_USE_PTHREADS) && !defined(OSG_PTHREAD_ELF_TLS)
00651 int rc;
00652
00653 rc = pthread_key_create(&(Thread::_aspectKey),
00654 Thread::freeAspect);
00655
00656 FFASSERT((rc == 0), 1, ("Failed to create pthread aspect key\n");)
00657
00658 rc = pthread_key_create(&(Thread::_changeListKey),
00659 Thread::freeChangeList);
00660
00661 FFASSERT((rc == 0), 1, ("Failed to create pthread changelist key\n");)
00662 #endif
00663
00664 #if defined(OSG_USE_WINTHREADS) && defined(OSG_ASPECT_USE_LOCALSTORAGE)
00665 Thread::_aspectKey = TlsAlloc();
00666
00667 FFASSERT((Thread::_aspectKey != 0xFFFFFFFF), 1,
00668 ("Failed to alloc aspect key local storage\n");)
00669
00670 Thread::_changeListKey = TlsAlloc();
00671
00672 FFASSERT((Thread::_changeListKey != 0xFFFFFFFF), 1,
00673 ("Failed to alloc changelist key local storage\n");)
00674 #endif
00675
00676 ThreadManager::setAppThreadType("OSGThread");
00677 }
00678
00679
00680
00681
00682 Thread::Thread(const Char8 *szName, UInt32 uiId) :
00683 Inherited(szName, uiId)
00684 {
00685 }
00686
00687
00688
00689
00690 Thread::~Thread(void)
00691 {
00692 }
00693
00694
00695
00696
00697 MPThreadType ExternalThread::_type(
00698 "OSGExternalThread",
00699 "OSGMPBase",
00700 reinterpret_cast<CreateThreadF>(ExternalThread::create),
00701 NULL);
00702
00703
00704
00705
00706 ThreadBase *ExternalThread::getCurrent(void)
00707 {
00708 return static_cast<ThreadBase *>(Inherited::getCurrent());
00709 }
00710
00711 ExternalThread *ExternalThread::get(const Char8 *szName)
00712 {
00713 BaseThread *pThread = ThreadManager::the()->getThread(szName,
00714 "OSGExternalThread");
00715
00716 return dynamic_cast<ExternalThread *>(pThread);
00717 }
00718
00719 ExternalThread *ExternalThread::find(const Char8 *szName)
00720 {
00721 BaseThread *pThread = ThreadManager::the()->findThread(szName);
00722
00723 return dynamic_cast<ExternalThread *>(pThread);
00724 }
00725
00726 void ExternalThread::initialize(UInt32 uiAspectId)
00727 {
00728 if(_bInitialized == true)
00729 return;
00730
00731 Inherited::setAspect(uiAspectId);
00732
00733 this->init();
00734 }
00735
00736
00737
00738
00739 ExternalThread *ExternalThread::create(const Char8 *szName,
00740 UInt32 uiId)
00741 {
00742 return new ExternalThread(szName, uiId);
00743 }
00744
00745 #if 0
00746 void ExternalThread::initThreading(void)
00747 {
00748 FINFO(("Thread::initThreading\n"))
00749
00750 #ifdef OSG_ASPECT_USE_PTHREADKEY
00751 int rc;
00752
00753 rc = pthread_key_create(&(Thread::_aspectKey),
00754 Thread::freeAspect);
00755
00756 FFASSERT((rc == 0), 1, ("Failed to create pthread aspect key\n");)
00757
00758 rc = pthread_key_create(&(Thread::_changeListKey),
00759 Thread::freeChangeList);
00760
00761 FFASSERT((rc == 0), 1, ("Failed to create pthread changelist key\n");)
00762 #endif
00763
00764 #ifdef OSG_ASPECT_USE_PTHREADSELF
00765
00766 Thread::_vAspects .resize(16);
00767 Thread::_vChangelists.resize(16);
00768
00769 for(UInt32 i = 0; i < 16; i++)
00770 {
00771 Thread::_vAspects[i] = 0;
00772 Thread::_vChangelists[i] = NULL;
00773 }
00774 #endif
00775
00776 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00777 Thread::_aspectKey = TlsAlloc();
00778
00779 FFASSERT((Thread::_aspectKey != 0xFFFFFFFF), 1,
00780 ("Failed to alloc aspect key local storage\n");)
00781
00782 Thread::_changeListKey = TlsAlloc();
00783
00784 FFASSERT((Thread::_changeListKey != 0xFFFFFFFF), 1,
00785 ("Failed to alloc changelist key local storage\n");)
00786 #endif
00787
00788 ThreadManager::setAppThreadType("OSGThread");
00789 }
00790 #endif
00791
00792
00793
00794
00795 ExternalThread::ExternalThread(const Char8 *szName, UInt32 uiId) :
00796 Inherited(szName, uiId)
00797 {
00798 }
00799
00800
00801
00802
00803 ExternalThread::~ExternalThread(void)
00804 {
00805 }
00806
00807
00808
00809
00810
00811 #ifdef __sgi
00812 #pragma set woff 1174
00813 #endif
00814
00815 #ifdef OSG_LINUX_ICC
00816 #pragma warning( disable : 177 )
00817 #endif
00818
00819 namespace
00820 {
00821 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00822 static Char8 cvsid_hpp[] = OSGTHREAD_HEADER_CVSID;
00823 }