Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/Posix/PThread.cpp

Go to the documentation of this file.
00001 // Made by Fred, for Coen445.
00002 // LGPL licensed.
00003 
00004 #ifndef __J2K__PThread_CPP__
00005 #define __J2K__PThread_CPP__
00006 
00007 /*************************************************************************
00008  **  FILE NAME   : <j2k/445/Posix/PThread.cpp>                          **
00009  **  CLASS NAME  : PThread                                              **
00010  **  DESCRIPTION : This class allows the creation of Generic Thread     **
00011  **                which takes care of the internals                    **
00012  **                of the PThread features. Any other subsequent        **
00013  **                classes can use this thread, or can appear as thread **
00014  **                just by inheriting from this basic class.            **
00015  *************************************************************************/
00016 
00017 #include <j2k/445/Posix/PThread.hpp>
00018 #include <j2k/445/Posix/Mutex.cpp>
00019 
00020 /**************************************************************
00021 ***************************************************************
00022 ***  Attribute         Default Value                        ***
00023 ***  =========         =============                        *** 
00024 ***   detachstate       PTHREAD_CREATE_JOINABLE             *** 
00025 ***   schedpolicy       PTHREAD_INHERIT_SCHED               ***
00026 ***   schedparam        Inherited from parent PThread       *** 
00027 ***   contentionscope   PTHREAD_SCOPE_SYSTEM                *** 
00028 ***   stacksize         4096                                *** 
00029 ***   stackaddr         NULL                                ***
00030 ***************************************************************
00031 **************************************************************/
00032 
00033 /**************************************************************
00034 ***************************************************************
00035 ***                                                         ***
00036 ***   typedef struct {                                      ***
00037 ***     int detachstate;                                    ***
00038 ***     int schedpolicy;                                    ***
00039 ***     struct sched_param schedparam;                      ***
00040 ***     int inheritsched;                                   ***
00041 ***     int scope;                                          ***
00042 ***   } pthread_attr_t;                                     ***
00043 ***                                                         ***
00044 ***************************************************************
00045 **************************************************************/
00046 
00047 /*************************************************************************
00048  **                 Static Data Members                                 **
00049  **                                                                     **
00050  **     These are used to provide simple mechanisms                     **
00051  **     for derived classes and callers to know where                   **
00052  **     things stand in terms of the number of threads                  **
00053  **     currently running, etc.                                         **
00054  *************************************************************************/
00055 
00056  //  This class also keeps track of the number
00057  //  of instances created and deleted.
00058 
00059  ULONG  PThread::log_create_count = 0;
00060  ULONG  PThread::log_delete_count = 0;
00061 
00062  //  Also, this class provides mechanisms for tracking
00063  //  the number of instances stopped or started.
00064 
00065  ULONG  PThread::log_start_count  = 0;
00066  ULONG  PThread::log_stop_count   = 0;
00067 
00068 
00069  PThread_Mutex  PThread::guard;
00070  
00071  // Default Constructor
00072  // Assign default values and set PID = -1
00073  // to indicate that no thread was created yet.
00074 
00075  inline PThread::PThread( BOOL autostart = FALSE, BOOL autojoin = FALSE )
00076   : start_stack(  DEFAULT_STACK  ), 
00077     start_algo(   DEFAULT_ALGO   ), 
00078     start_prio(   DEFAULT_PRIO   ), 
00079     start_policy( DEFAULT_POLICY ), 
00080     start_param(  NULL           ),
00081     isDetached(   TRUE           ),
00082     termination_requested( FALSE ),
00083     pid( INVALID_PID )
00084  {
00085 
00086 
00087    // Make sure every member even 
00088    // the very deep ones are ZERO or NULL.
00089    memset( &attr, 0, sizeof( pthread_attr_t ) );
00090 
00091    // Initialize the PThread attribute to defaults
00092    int err = pthread_attr_init( &attr );
00093    MC_OnError( err, Error, "An error occured while initializing a pthread attribute." )
00094 
00095    guard.lock();
00096    threadNo = ++log_create_count;
00097    guard.unlock();
00098 
00099 
00100    if ( autostart ) start();
00101    if ( autojoin  ) join();
00102  }
00103 
00104  // VERIFY THOSE !
00105  // Copy Constructor
00106  inline PThread::PThread( const PThread& src ) 
00107  {
00108    memcpy( &attr, &src.attr, sizeof( pthread_attr_t ) );
00109  }
00110 
00111  // Assign Operator
00112  inline const PThread& PThread::operator=( const PThread& src ) {
00113    memcpy( &attr, &src.attr, sizeof( pthread_attr_t ) );
00114    return *this;
00115  }
00116 
00117 
00118  // Virtual Destructor
00119  inline PThread::~PThread() 
00120  {
00121    stop();
00122    // kill(); // Cancel ?
00123    exit();
00124   
00125    // Weirdly this does absolutely nothing !
00126    // on Linux implementation ! =?
00127    int err = pthread_attr_destroy( &attr );
00128    MC_OnError( err, Error, "An error occured while deleting a pthread attribute." )
00129 
00130    guard.lock();
00131    ++log_delete_count;
00132    guard.unlock();
00133  }
00134 
00135  void PThread::yield() 
00136  {
00137    sched_yield();
00138  }
00139 
00140  void PThread::start() {
00141     cout << "PThead::start()";
00142  
00143     PThread::start( (size_t)DEFAULT_STACK, 
00144                     (int)DEFAULT_ALGO, 
00145                     (int)DEFAULT_PRIO,
00146                     (int)DEFAULT_POLICY );
00147 
00148     cout << "end start()"; 
00149  }
00150 
00151  void PThread::start( size_t stack_size, int algo, int prio, int policy )
00152  {
00153 /*
00154   size_t stack_size = DEFAULT_STACK, 
00155   int    algo       = DEFAULT_ALGO, 
00156   int    prio       = DEFAULT_PRIO, 
00157   int    policy     = DEFAULT_POLICY )
00158 */ 
00159    if ( pid >= 0 && pid != INVALID_PID ) return;
00160    
00161    cout << "Creating the thread...";
00162    // Call the static Wrapper() which will call the dynamic run()
00163    int rc = pthread_create( &pid, NULL, Wrapper, (void*)this );
00164 
00165    cout << "Thread created...";
00166    start_param  = NULL;  // getSchedulerParam();
00167    start_stack  = stack_size;
00168    start_algo   = algo;
00169    start_prio   = prio;
00170    start_policy = policy;
00171 
00172    if ( rc != 0 ) {
00173      char* m = "Unable to start the thread.";
00174      cout << '[' << m << rc << ']';
00175      if ( rc == -1 )     cout << "Forgot to include libraries:  g++ -lpthread -lrt -lsocket -lnsl -g PThread.cpp";
00176      if ( rc == ENOMEM ) cout << "ENOMEM";
00177      if ( rc == EINVAL ) cout << "EINVAL";
00178      if ( rc == EPERM  ) cout << "EPERM";
00179 
00180      MC_OnError( rc, Error, "while starting a thread." )
00181    }
00182 
00183    detach();
00184  }
00185 
00186  inline void PThread::stop() {
00187    if ( pid < 0 ) return;
00188  
00189    pthread_cancel( pid );
00190    pid = INVALID_PID;
00191  }
00192 
00193  inline pid_t PThread::getPID() 
00194  {
00195    return pid;
00196  }
00197 
00198  inline BOOL PThread::isStarted() 
00199  {
00200    return ( pid >= 0 && pid != INVALID_PID );
00201  }
00202 
00203  // Kill the old version of PThread and Start it again.
00204  // Return, if PThread was not started.
00205  void PThread::refresh() 
00206  {
00207    if ( pid < 0 || pid == INVALID_PID ) return;
00208    stop();
00209    start( start_stack, start_algo, start_prio, start_policy );
00210  }
00211 
00212 
00213 /******************************************************************
00214 *******************************************************************
00215 ***                                                             ***
00216 ***  Detach state:                                              ***
00217 ***                                                             ***
00218 *** PTHREAD_CREATE_JOINABLE == 0  ( DEFAULT )                   ***
00219 ***   PThread is created in a joinable state.                   ***
00220 ***                                                             ***
00221 *** PTHREAD_CREATE_DETACHED != 0                                ***
00222 ***   PThread is created in a detached state.                   ***
00223 ***                                                             ***
00224 *******************************************************************
00225 ******************************************************************/
00226 
00227    inline int PThread::getDetachState() 
00228    {
00229       int state = 0;
00230       int err = pthread_attr_getdetachstate( &attr, &state );
00231 
00232       MC_OnError( err, Error, "An error occured while getting the detach state." )
00233       return state;
00234    }
00235 
00236    inline void PThread::setDetachState( int state ) 
00237    {
00238       int s = state;
00239 
00240       // To avoid EINVAL
00241       if ( s != 0 ) {
00242         s = PTHREAD_CREATE_DETACHED;
00243       }
00244 
00245       int err = pthread_attr_setdetachstate( &attr, s );
00246       MC_OnError( err, Error, "An error occured while setting the detach state." )
00247    }
00248 
00249 /******************************************************************
00250 *******************************************************************
00251 ***                                                             ***
00252 ***  If guardsize is 0, threads created with attr have          ***
00253 ***  no guard area; otherwise, a guard area of at least         ***
00254 ***  guardsize bytes is provided. The default guardsize         ***
00255 ***  can be found using the _SC_PAGESIZE constant               ***
00256 ***  in a call to sysconf().                                    ***
00257 ***                                                             ***
00258 ***  The guardsize attribute controls the size of the guard     ***
00259 ***  area for the thread's stack. This guard area helps         ***
00260 ***  protect against stack overflows; guardsize bytes           ***
00261 ***  of extra memory is allocated at the overflow end           ***
00262 ***  of the stack. If a PThread overflows into this buffer      ***
00263 ***  it receives a SIGSEGV signal.                              ***
00264 ***                                                             ***
00265 ***  The guardsize attribute is provided because:               ***
00266 ***                                                             ***
00267 ***  - Stack overflow protection can waste system resources.    ***
00268 ***    An application that creates many threads can save        ***
00269 ***    system resources by turning off guard areas              ***
00270 ***    if it trusts its threads not to overflow the stack.      ***
00271 ***                                                             ***
00272 ***  - When threads allocate large objects on the stack,        ***
00273 ***    a large guardsize is required to detect stack overflows. ***
00274 ***                                                             ***
00275 ***                                                             ***
00276 ***  NOTICE:                                                    ***
00277 ***  =======                                                    ***
00278 ***                                                             ***
00279 ***  If the caller is providing a stack                         ***
00280 ***  (using attr's stackaddr attribute;                         ***
00281 ***   see pthread_attr_setstackaddr()),                         ***
00282 ***  the guardsize is ignored and there's no stack overflow     ***
00283 ***  protection for that PThread.                               ***
00284 ***                                                             ***
00285 ***  The guardsize argument is completely ignored               ***
00286 ***  when using a physical mode memory manager.                 ***
00287 ***                                                             ***
00288 *******************************************************************
00289 ******************************************************************/
00290 
00291    inline size_t PThread::getGuardSize() 
00292    {
00293       size_t sz = 0;
00294       int err = pthread_attr_getguardsize( &attr, &sz );
00295       MC_OnError( err, Error, "An error occured while getting the guard size." );
00296 
00297       return sz;
00298    }
00299 
00300    inline void PThread::setGuardSize( size_t sz ) 
00301    {
00302       int err = pthread_attr_setstacksize( &attr, sz );
00303       MC_OnError( err, Error, "An error occured while setting the guard size." );
00304    }
00305 
00306 
00307  inline int PThread::getScheduler() 
00308  { 
00309    return sched_getscheduler( pid );
00310  }
00311 
00312  inline void PThread::setScheduler( int sched, const sched_param* param )
00313  {
00314    sched_setscheduler( pid, sched, param );
00315  }
00316 
00317  inline void PThread::setScheduler( int sched ) 
00318  {
00319    sched_param* param;
00320    sched_getparam( pid, param );
00321    sched_setscheduler( pid, sched, param );
00322  }
00323 
00324  inline void PThread::resetScheduler() 
00325  {
00326    setScheduler( start_algo );
00327  }
00328 
00329  inline sched_param*  PThread::getSchedulerParam() 
00330  {
00331    int policy = 0;
00332    sched_param* param = NULL;
00333    int err = pthread_getschedparam( pid, &policy, param );
00334    MC_OnError( err, Error, "An error occured while getting the PThread scheduling parameters." );
00335    return param;
00336  }
00337 
00338  // Set PThread scheduling parameters
00339  inline void PThread::setSchedulerParam( int policy, const sched_param* param = NULL )
00340  {
00341    int err = pthread_setschedparam( pid, policy, param );
00342    MC_OnError( err, Error, "An error occured while setting the PThread scheduling parameters." );
00343  }
00344 
00345  inline void PThread::resetSchedulerParam() 
00346  {
00347    int err = pthread_setschedparam( pid, start_policy, start_param );
00348    MC_OnError( err, Error, "An error occured while resetting the PThread scheduling parameters." );
00349  }
00350 
00351 /******************************************************************
00352 *******************************************************************
00353 ***                                                             ***
00354 ***  Get PThread inherit scheduling attribute                   ***
00355 ***                                                             ***
00356 ***  The inherit scheduling attribute determines                ***
00357 ***  whether a PThread inherits the scheduling                  ***
00358 ***  policy of its parent.                                      ***
00359 ***                                                             ***
00360 *******************************************************************
00361 ******************************************************************/
00362 
00363    inline int PThread::getInheritSched() 
00364    {
00365      int sched = 0;
00366      int err = pthread_attr_getinheritsched( &attr, &sched );
00367      MC_OnError( err, Error, "An error occured while getting the inherited scheduling scheme." );
00368    
00369      return sched;
00370    }
00371 
00372 /******************************************************************
00373 *******************************************************************
00374 ***                                                             ***
00375 ***  Set PThread inherit scheduling attribute                   ***
00376 ***                                                             ***
00377 *** PTHREAD_INHERIT_SCHED   ( DEFAULT )                         ***
00378 ***   PThread inherits the scheduling policy of parent PThread. ***
00379 ***                                                             ***
00380 *** PTHREAD_EXPLICIT_SCHED                                      ***
00381 ***   PThread has the scheduling policy specified in attr.      ***
00382 ***                                                             ***
00383 *******************************************************************
00384 ******************************************************************/
00385 
00386    inline void PThread::setInheritSched( int sched ) 
00387    {
00388      int err = pthread_attr_setinheritsched( &attr, sched );
00389      MC_OnError( err, Error, "An error occured while setting the inherited scheduling scheme." );
00390    }
00391 
00392    // This is to be ajusted with maybe a sched_param class !?
00393    inline sched_param* PThread::getSchedParam() 
00394    {
00395      sched_param* param = NULL;
00396      int err = pthread_attr_getschedparam( &attr, param );
00397      MC_OnError( err, Error, "An error occured while getting the scheduling parameters." );
00398      return param;
00399    }
00400 
00401 /******************************************************************
00402 *******************************************************************
00403 ***                                                             ***
00404 ***  Get PThread scheduling parameters                          ***
00405 ***                                                             ***
00406 ***  sched_priority                                             ***
00407 ***    Inherited from parent PThread ( DEFAULT )                ***
00408 ***                                                             ***
00409 ***  The PThread scheduling parameters are only used            ***
00410 ***  if you have set the PThread inherit scheduling             ***
00411 ***  attribute to PTHREAD_EXPLICIT_SCHED                        ***
00412 ***   using pthread_attr_setinheritsched().                     ***
00413 ***                                                             ***
00414 *******************************************************************
00415 ******************************************************************/
00416 
00417    inline void PThread::setSchedParam( sched_param* param ) 
00418    {
00419      int err = pthread_attr_setschedparam( &attr, param );
00420      MC_OnError( err, Error, "An error occured while setting the scheduling parameters." );
00421    }
00422 
00423 
00424    // Get PThread scheduling policy attribute
00425    inline int PThread::getSchedPolicy() 
00426    {
00427      int policy = 0;
00428      int err = pthread_attr_getschedpolicy( &attr, &policy );
00429      MC_OnError( err, Error, "An error occured while getting the scheduling policies." );
00430 
00431      return policy;
00432    }
00433 
00434 
00435 /******************************************************************
00436 *******************************************************************
00437 ***                                                             ***
00438 ***  Sets the PThread scheduling policy attribute               ***
00439 ***  in the PThread attribute object attr to policy.            ***
00440 ***                                                             ***
00441 ***  The PThread scheduling policy attribute can have           ***
00442 ***  the following values on QNX/Neutrino:                      ***
00443 ***                                                             ***
00444 ***  SCHED_FIFO       First-In First-Out scheduling.            ***
00445 ***  SCHED_RR         Round-Robin scheduling.                   ***
00446 ***  SCHED_OTHER      Currently the same as SCHED_RR.           ***
00447 ***  SCHED_NOCHANGE   Don't change the policy.                  ***
00448 ***                                                             ***
00449 ***  The policy attribute is only used if you have set          ***
00450 ***  the PThread inherit scheduling attribute                   ***
00451 ***  to PTHREAD_EXPLICIT_SCHED using                            ***
00452 ***  pthread_attr_setinheritsched().                            ***
00453 ***                                                             ***
00454 *******************************************************************
00455 ******************************************************************/
00456 
00457 
00458    inline void PThread::setSchedPolicy( int policy ) 
00459    {
00460      int err = pthread_attr_setschedpolicy( &attr, policy );
00461      MC_OnError( err, Error, "An error occured while setting the scheduling policies." );
00462    }
00463 
00464 /******************************************************************
00465 *******************************************************************
00466 ***                                                             ***
00467 ***  Sets the PThread contention scope attribute                ***
00468 ***                                                             ***
00469 ***  PTHREAD_SCOPE_SYSTEM  (DEFAULT and ONLY VALUE)             ***
00470 ***    All threads are scheduled together.                      ***
00471 ***                                                             ***
00472 *******************************************************************
00473 ******************************************************************/
00474 
00475  inline int PThread::getScope() 
00476  {
00477    int scope = 0;
00478    int err = pthread_attr_getscope( &attr, &scope );
00479    MC_OnError( err, Error, "An error occured while getting the PThread scope." );
00480    return scope;
00481  }
00482 
00483  inline void PThread::setScope( int scope ) 
00484  {
00485    int err = pthread_attr_setscope( &attr, scope );
00486    MC_OnError( err, Error, "An error occured while setting the PThread scope." );
00487  }
00488 
00489 /******************************************************************
00490 *******************************************************************
00491 ***                                                             ***
00492 ***  Sets the PThread stack address attribute                   ***
00493 ***                                                             ***
00494 ***  The default value for the PThread stack address attribute  ***
00495 ***  is NULL. A PThread created with a NULL stack address       ***
00496 ***  attribute will have a stack dynamically allocated          ***
00497 ***  by the system of minimum size PTHREAD_STACK_MIN.           ***
00498 ***  The allocated stack will be reclaimed when the PThread     ***
00499 ***  terminates. If a stack is allocated by the user then       ***
00500 ***  it must be released by the user.                           ***
00501 ***                                                             ***
00502 ***  For QNX/Neutrino, PTHREAD_STACK_MIN is enough memory       ***
00503 ***  to run a PThread that does nothing !                       ***
00504 ***                                                             ***
00505 *******************************************************************
00506 ******************************************************************/
00507 
00508    inline void* PThread::getStackAddress() 
00509    {
00510      void* stack = NULL;
00511      int err = pthread_attr_getstackaddr( &attr, &stack );
00512      MC_OnError( err, Error, "An error occured while getting the Stack address." );
00513      return stack;
00514    }
00515 
00516    inline void PThread::setStackAddress( void* stack_addr ) 
00517    {
00518      int err = pthread_attr_setstackaddr( &attr, stack_addr );
00519      MC_OnError( err, Error, "An error occured while setting the Stack address." );
00520    }
00521 
00522 /******************************************************************
00523 *******************************************************************
00524 ***                                                             ***
00525 ***  The stacksize must be larger than PTHREAD_STACK_MIN,       ***
00526 ***  which is the default value.                                ***
00527 ***                                                             ***
00528 *******************************************************************
00529 ******************************************************************/
00530 
00531    inline size_t PThread::getStackSize() 
00532    {
00533      size_t sz = 0;
00534      int err = pthread_attr_getstacksize( &attr, &sz );
00535      MC_OnError( err, Error, "An error occured while getting the Stack size." );
00536      return sz;
00537    }
00538 
00539 
00540    inline void PThread::setStackSize( size_t sz ) 
00541    {
00542      int err = 0;
00543    err = pthread_attr_setstacksize( &attr, sz );
00544      MC_OnError( err, Error, "An error occured while setting the Stack size." );
00545    }
00546 
00547 /******************************************************************
00548 *******************************************************************
00549 ***                                                             ***
00550 ***  This function request that the the thread be cancelled     ***
00551 ***  (terminated). The cancellation type and state of the       ***
00552 ***  target determine when the cancellation takes effect.       ***
00553 ***                                                             ***
00554 ***  When the cancellation is acted on, the target's            ***
00555 ***  cancellation cleanup handlers are called.                  ***
00556 ***                                                             ***
00557 ***  When the last cancellation cleanup handler returns,        ***
00558 ***  the data destructor function is called, once this          ***
00559 ***  is done the thread is terminated.                          ***
00560 ***                                                             ***
00561 ***  The cancellation processing in the target thread runs      ***
00562 ***  asynchronously with respect to the calling thread.         ***
00563 ***                                                             ***
00564 *******************************************************************
00565 ******************************************************************/
00566 
00567    // Cancel PThread
00568    inline void PThread::cancel()
00569    {
00570      int err = pthread_cancel( pid );
00571      MC_OnError( err, Error, "An error occured while cancelling a PThread." );
00572    }
00573 
00574    inline void PThread::create( const pthread_attr_t* attr ) 
00575    {
00576      int err = pthread_create( &pid, attr, Wrapper, (void*)&(*this) );
00577      MC_OnError( err, Error, "An error occured while creating a PThread." );
00578    }
00579 
00580    inline void PThread::detach() 
00581    {
00582      if ( pid < 0    ) return;
00583      if ( isDetached ) return;
00584 
00585      int err = pthread_detach( pid );
00586      isDetached = TRUE;
00587 
00588      MC_OnError( err, Error, "An error occured while detaching a PThread." );
00589    }
00590 
00591    inline const BOOL PThread::operator==( const PThread& right ) {
00592       return !( pthread_equal( pid, right.pid ) );
00593    }
00594 
00595    inline const BOOL PThread::operator!=( const PThread& right ) {
00596       return !( *this == right );
00597    }
00598 
00599    inline void PThread::exit() {
00600      pthread_exit( NULL );
00601    }
00602 
00603    // Get the level of PThread concurrency
00604    inline int PThread::getConcurrency()
00605    {
00606      return pthread_getconcurrency();
00607    }
00608 
00609    // Get PThread scheduling parameters
00610    inline sched_param*  PThread::getSchedParam( int* policy ) 
00611    {
00612      sched_param* param = NULL;
00613  
00614      int err = pthread_getschedparam( pid, policy, param );
00615      MC_OnError( err, Error, "An error occured while getting scheduling parameters." );
00616    }
00617  
00618    // Get PThread specific key data value
00619    inline void* PThread::getKey( pthread_key_t key ) 
00620    {
00621      return pthread_getspecific( key );
00622    }
00623  
00624    // Join PThread
00625    inline void PThread::join( void** value_ptr = NULL )
00626    {
00627      int err = 0;
00628      if ( pid < 0 ) return;
00629      if ( !isDetached )
00630        err = pthread_join( pid, value_ptr );
00631 
00632      isDetached = FALSE;
00633      MC_OnError( err, Error, "An error occured while joining a PThread." );
00634    }
00635  
00636    // Send a signal to a PThread
00637    inline void PThread::kill( int sig ) 
00638    {
00639      int err = pthread_kill( pid, sig );
00640      MC_OnError( err, Error, "An error occured while killing a PThread." );
00641    }
00642  
00643    // Dynamic package initialization
00644    inline void PThread::dynamicPackageInit(  void (*init_routine)(void)  ) 
00645    {
00646      pthread_once_t once_control = PTHREAD_ONCE_INIT;
00647      int err = pthread_once( &once_control, init_routine );
00648      MC_OnError( err, Error, "An error occured while doing a dynamic package initialization." );
00649    }
00650  
00651    // Get calling thread's ID
00652    inline pthread_t PThread::getSelf() {
00653      return pthread_self();
00654    }
00655  
00656    // Set a thread's cancellation state
00657    inline int PThread::setCancelState( int new_state ) 
00658    {
00659      int old_state = 0;
00660      int err = pthread_setcancelstate( new_state, &old_state );
00661      MC_OnError( err, Error, "An error occured while setting the cancel state." );
00662    } 
00663 
00664    inline int PThread::enableCancel() 
00665    {
00666      return setCancelState( PTHREAD_CANCEL_ENABLE );
00667    }
00668 
00669    inline int PThread::disableCancel() 
00670    {
00671      return setCancelState( PTHREAD_CANCEL_DISABLE );
00672    }
00673  
00674    // Set the concurrency level for a PThread
00675    inline void PThread::setCocurrencyLevel( int new_level )
00676    {
00677      int err = pthread_setconcurrency( new_level );
00678      MC_OnError( err, Error, "An error occured while setting the cancel state." );
00679    }
00680 
00681    // Set PThread specific key data value
00682    inline void PThread::setKeyValue( pthread_key_t key, const void* value )
00683    {
00684      int err = pthread_setspecific( key, value );
00685      MC_OnError( err, Error, "An error occured while setting the PThread specific key value.");
00686    }
00687  
00688    // Examine and change blocked signals
00689    inline sigset_t* PThread::changeBlockedSignals( int how, const sigset_t* set )
00690    {
00691      sigset_t* oset = NULL;
00692      int err = pthread_sigmask( how, set, oset );
00693      MC_OnError( err, Error, "An error occured while changing the PThread blocked signals.");
00694      return oset;
00695    }
00696  
00697    // Test PThread cancellation
00698    inline void PThread::testCancellation() {
00699      pthread_testcancel();
00700    }
00701  
00702  // Get statistic log about general threads status 
00703 
00704  ULONG PThread::get_create_count()
00705  {
00706    guard.lock();
00707    ULONG count = log_create_count;
00708    guard.unlock();
00709    return count;
00710  }
00711 
00712  ULONG PThread::get_delete_count()
00713  {
00714    guard.lock();
00715    ULONG count = log_delete_count;
00716    guard.unlock();
00717    return count;
00718  }
00719 
00720  ULONG PThread::get_start_count()
00721  {
00722    guard.lock();
00723    ULONG count = log_start_count;
00724    guard.unlock();
00725    return count;
00726  }
00727 
00728  ULONG PThread::get_stop_count()
00729  {
00730    guard.lock();
00731    ULONG count = log_stop_count;
00732    guard.unlock();
00733    return count;
00734  }
00735 
00736  BOOL PThread::poll_termrequest()
00737  {
00738    guard.lock();
00739    BOOL req = termination_requested;
00740    guard.unlock();
00741    return req;
00742  }
00743 
00744  void PThread::request_termination()
00745  {
00746    guard.lock();
00747    termination_requested = TRUE;
00748    guard.unlock();
00749  }
00750 
00751 
00752 /*
00753  // QNX only !?
00754  inline int PThread::getPriority() 
00755  {
00756    return getprio( pid );
00757  }
00758 
00759  inline void PThread::setPriority( int prio ) 
00760  {
00761    setprio( pid, prio );
00762  }
00763 
00764  inline void PThread::resetPriority() 
00765  {
00766    setprio( pid, start_prio );
00767  }
00768 */
00769 
00770 #endif

Generated on Sun Oct 14 18:46:40 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001