diff --git a/cwThread.cpp b/cwThread.cpp index fa56eab..cc098a4 100644 --- a/cwThread.cpp +++ b/cwThread.cpp @@ -37,6 +37,8 @@ namespace cw char* label; mutex::handle_t mutexH; + unsigned cycleIdx; + unsigned cycleCnt; } thread_t; @@ -122,6 +124,7 @@ namespace cw // check if we have been requested to leave the pause state if( cwIsFlag(curDoFlags,kDoRunThFl) ) { + p->cycleIdx = 0; p->stateId.store(kRunningThId,std::memory_order_release); } } @@ -132,10 +135,15 @@ namespace cw if( p->func(p->funcArg)==false ) break; + p->cycleIdx += 1; + + // if a cycle limit was set then check if the limit was reached + bool cycles_done_fl = p->cycleCnt > 0 && p->cycleIdx >= p->cycleCnt; + curDoFlags = p->doFlags.load(std::memory_order_acquire); // check if we have been requested to enter the pause state - if( cwIsFlag(curDoFlags,kDoPauseThFl) ) + if( cwIsNotFlag(curDoFlags,kDoExitThFl) && (cwIsFlag(curDoFlags,kDoPauseThFl) || cycles_done_fl) ) { p->stateId.store(kPausedThId,std::memory_order_release); } @@ -276,7 +284,7 @@ cw::rc_t cw::thread::destroy( handle_t& hRef ) } -cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags ) +cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags, unsigned cycleCnt ) { rc_t rc = kOkRC; bool pauseFl = cwIsFlag(cmdFlags,kPauseFl); @@ -296,6 +304,7 @@ cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags ) } else { + p->cycleCnt = cycleCnt; p->doFlags.store(kDoRunThFl,std::memory_order_release); waitId = kRunningThId; if((rc = signalCondVar(p->mutexH)) != kOkRC ) @@ -316,8 +325,8 @@ errLabel: } -cw::rc_t cw::thread::unpause( handle_t h ) -{ return pause( h, kWaitFl); } +cw::rc_t cw::thread::unpause( handle_t h, unsigned cycleCnt ) +{ return pause( h, kWaitFl, cycleCnt); } cw::thread::stateId_t cw::thread::state( handle_t h ) { diff --git a/cwThread.h b/cwThread.h index 4260bd1..4263b4a 100644 --- a/cwThread.h +++ b/cwThread.h @@ -34,10 +34,12 @@ namespace cw rc_t destroy( handle_t& hRef ); - + + // 'cycleCnt' gives a limit on the count of time the thread function should be called + // when the thread exits the pause state. It is ignored if kPauseFl is set in 'cmdFlags' enum { kPauseFl=0x01, kWaitFl=0x02 }; - rc_t pause( handle_t h, unsigned cmdFlags = kWaitFl ); - rc_t unpause( handle_t h ); // same as threadPause(h,kWaitFl) + rc_t pause( handle_t h, unsigned cmdFlags = kWaitFl, unsigned cycleCnt=0 ); + rc_t unpause( handle_t h, unsigned cycleCnt=0 ); // same as threadPause(h,kWaitFl) stateId_t state( handle_t h );