cwThread.cpp : Fixed but with cycle count limit and added tests to threadTest().

This commit is contained in:
kevin 2024-09-15 14:53:18 -04:00
parent 10b5e88b0e
commit 6fcc1fa0ec

View File

@ -37,8 +37,9 @@ namespace cw
char* label; char* label;
mutex::handle_t mutexH; mutex::handle_t mutexH;
unsigned cycleIdx; unsigned cycleIdx; // current cycle phase
unsigned cycleCnt; unsigned cycleCnt; // cycle phase limit
unsigned execCnt;
} thread_t; } thread_t;
@ -135,20 +136,25 @@ namespace cw
if( p->func(p->funcArg)==false ) if( p->func(p->funcArg)==false )
break; break;
curDoFlags = p->doFlags.load(std::memory_order_acquire);
if( cwIsNotFlag(curDoFlags,kDoExitThFl) )
{
p->cycleIdx += 1; p->cycleIdx += 1;
// if a cycle limit was set then check if the limit was reached // if a cycle limit was set then check if the limit was reached
bool cycles_done_fl = p->cycleCnt > 0 && p->cycleIdx >= p->cycleCnt; 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 // check if we have been requested to enter the pause state
if( cwIsNotFlag(curDoFlags,kDoExitThFl) && (cwIsFlag(curDoFlags,kDoPauseThFl) || cycles_done_fl) ) if( (cwIsFlag(curDoFlags,kDoPauseThFl) || cycles_done_fl) )
{ {
p->stateId.store(kPausedThId,std::memory_order_release); p->stateId.store(kPausedThId,std::memory_order_release);
p->doFlags.store(0,std::memory_order_release);
} }
} }
}
}while( cwIsFlag(curDoFlags,kDoExitThFl) == false ); }while( cwIsFlag(curDoFlags,kDoExitThFl) == false );
pthread_cleanup_pop(1); pthread_cleanup_pop(1);
@ -294,6 +300,8 @@ cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags, unsigned cycleCnt )
bool isPausedFl = curStateId == kPausedThId; bool isPausedFl = curStateId == kPausedThId;
stateId_t waitId; stateId_t waitId;
p->cycleCnt = cycleCnt;
if( isPausedFl == pauseFl ) if( isPausedFl == pauseFl )
return kOkRC; return kOkRC;
@ -304,7 +312,6 @@ cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags, unsigned cycleCnt )
} }
else else
{ {
p->cycleCnt = cycleCnt;
p->doFlags.store(kDoRunThFl,std::memory_order_release); p->doFlags.store(kDoRunThFl,std::memory_order_release);
waitId = kRunningThId; waitId = kRunningThId;
if((rc = signalCondVar(p->mutexH)) != kOkRC ) if((rc = signalCondVar(p->mutexH)) != kOkRC )
@ -372,9 +379,10 @@ unsigned cw::thread::pauseMicros( handle_t h )
namespace cw namespace cw
{ {
time::spec_t g_t0{}; time::spec_t g_t0 = {0,0};
time_t g_micros = 0; time_t g_micros = 0;
unsigned g_n = 0; unsigned g_n = 0;
bool _threadTestCb( void* p ) bool _threadTestCb( void* p )
{ {
if( g_t0.tv_nsec != 0 ) if( g_t0.tv_nsec != 0 )
@ -398,13 +406,14 @@ cw::rc_t cw::threadTest()
unsigned val = 0; unsigned val = 0;
rc_t rc; rc_t rc;
char c = 0; char c = 0;
unsigned cycleCnt = 0;
// create the thread // create the thread
if((rc = thread::create(h,_threadTestCb,&val,"thread_test")) != kOkRC ) if((rc = thread::create(h,_threadTestCb,&val,"thread_test")) != kOkRC )
return rc; return rc;
// start the thread // start the thread
if((rc = thread::pause(h,0)) != kOkRC ) if((rc = thread::pause(h,0,cycleCnt)) != kOkRC )
goto errLabel; goto errLabel;
@ -419,7 +428,7 @@ cw::rc_t cw::threadTest()
switch(c) switch(c)
{ {
case 'o': case 'o':
cwLogInfo("val: 0x%x\n",val); cwLogInfo("val: 0x%x %i\n",val,val);
break; break;
case 's': case 's':
@ -431,7 +440,11 @@ cw::rc_t cw::threadTest()
if( thread::state(h) == thread::kPausedThId ) if( thread::state(h) == thread::kPausedThId )
{ {
time::get(g_t0); time::get(g_t0);
rc = thread::pause(h,thread::kWaitFl); // We don't set kWaitFl w/ cycleCnt>0 because we are running very
// few cycles - the cycles will run and the
// state of the thread will return to 'paused'
// before _waitForState() can notice the 'running' state.
rc = thread::pause(h, cycleCnt==0 ? thread::kWaitFl : 0,cycleCnt);
} }
else else
rc = thread::pause(h,thread::kPauseFl|thread::kWaitFl); rc = thread::pause(h,thread::kPauseFl|thread::kWaitFl);
@ -448,7 +461,7 @@ cw::rc_t cw::threadTest()
break; break;
case 'q': case 'q':
printf("wakeup micros:%li cnt:%i avg:%li\n",g_micros,g_n,g_micros/g_n); printf("wakeup micros:%li cnt:%i avg:%li\n",g_micros,g_n,g_n>0 ? g_micros/g_n : 0);
break; break;
//default: //default: