00001
00002
00003
00004 #ifndef __J2K__PThread_CPP__
00005 #define __J2K__PThread_CPP__
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <j2k/445/Posix/PThread.hpp>
00018 #include <j2k/445/Posix/Mutex.cpp>
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 ULONG PThread::log_create_count = 0;
00060 ULONG PThread::log_delete_count = 0;
00061
00062
00063
00064
00065 ULONG PThread::log_start_count = 0;
00066 ULONG PThread::log_stop_count = 0;
00067
00068
00069 PThread_Mutex PThread::guard;
00070
00071
00072
00073
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
00088
00089 memset( &attr, 0, sizeof( pthread_attr_t ) );
00090
00091
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
00105
00106 inline PThread::PThread( const PThread& src )
00107 {
00108 memcpy( &attr, &src.attr, sizeof( pthread_attr_t ) );
00109 }
00110
00111
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
00119 inline PThread::~PThread()
00120 {
00121 stop();
00122
00123 exit();
00124
00125
00126
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
00155
00156
00157
00158
00159 if ( pid >= 0 && pid != INVALID_PID ) return;
00160
00161 cout << "Creating the thread...";
00162
00163 int rc = pthread_create( &pid, NULL, Wrapper, (void*)this );
00164
00165 cout << "Thread created...";
00166 start_param = NULL;
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
00204
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
00217
00218
00219
00220
00221
00222
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
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
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
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
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
00355
00356
00357
00358
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
00376
00377
00378
00379
00380
00381
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
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
00405
00406
00407
00408
00409
00410
00411
00412
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
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
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
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
00468
00469
00470
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
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
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
00526
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
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
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
00604 inline int PThread::getConcurrency()
00605 {
00606 return pthread_getconcurrency();
00607 }
00608
00609
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
00619 inline void* PThread::getKey( pthread_key_t key )
00620 {
00621 return pthread_getspecific( key );
00622 }
00623
00624
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
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
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
00652 inline pthread_t PThread::getSelf() {
00653 return pthread_self();
00654 }
00655
00656
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
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
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
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
00698 inline void PThread::testCancellation() {
00699 pthread_testcancel();
00700 }
00701
00702
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
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 #endif