2020-04-10 01:06:33 +00:00
|
|
|
#include "cwCommon.h"
|
|
|
|
#include "cwLog.h"
|
|
|
|
#include "cwCommonImpl.h"
|
|
|
|
#include "cwMem.h"
|
|
|
|
#include "cwThread.h"
|
|
|
|
#include "cwThreadMach.h"
|
|
|
|
|
|
|
|
namespace cw
|
|
|
|
{
|
|
|
|
namespace thread_mach
|
|
|
|
{
|
|
|
|
typedef struct thread_str
|
|
|
|
{
|
|
|
|
thread::handle_t thH;
|
2021-01-20 18:11:44 +00:00
|
|
|
threadFunc_t func;
|
2020-04-10 01:06:33 +00:00
|
|
|
void* arg;
|
2021-01-20 18:11:44 +00:00
|
|
|
struct thread_str* link;
|
2020-04-10 01:06:33 +00:00
|
|
|
} thread_t;
|
|
|
|
|
|
|
|
typedef struct thread_mach_str
|
|
|
|
{
|
2021-01-20 18:11:44 +00:00
|
|
|
thread_t* threadL;
|
2020-04-10 01:06:33 +00:00
|
|
|
} thread_mach_t;
|
|
|
|
|
|
|
|
thread_mach_t* _handleToPtr( handle_t h )
|
|
|
|
{ return handleToPtr<handle_t,thread_mach_t>(h); }
|
|
|
|
|
2024-02-18 13:37:33 +00:00
|
|
|
rc_t _add( thread_mach_t* p, threadFunc_t func, void* arg, const char* label )
|
2020-04-10 01:06:33 +00:00
|
|
|
{
|
|
|
|
rc_t rc = kOkRC;
|
2021-01-20 18:11:44 +00:00
|
|
|
|
|
|
|
thread_t* t = mem::allocZ<thread_t>();
|
|
|
|
|
2024-02-18 13:37:33 +00:00
|
|
|
if((rc = thread::create(t->thH, func, arg, label==nullptr ? "thread_mach" : label )) != kOkRC )
|
2021-01-20 18:11:44 +00:00
|
|
|
{
|
|
|
|
rc = cwLogError(rc,"Thread create failed.");
|
|
|
|
goto errLabel;
|
|
|
|
}
|
|
|
|
|
|
|
|
t->func = func;
|
|
|
|
t->arg = arg;
|
|
|
|
t->link = p->threadL;
|
|
|
|
p->threadL = t;
|
|
|
|
|
|
|
|
errLabel:
|
|
|
|
if( rc != kOkRC )
|
|
|
|
mem::release(t);
|
2020-04-10 01:06:33 +00:00
|
|
|
|
2021-01-20 18:11:44 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc_t _destroy( thread_mach_t* p )
|
|
|
|
{
|
|
|
|
rc_t rc = kOkRC;
|
|
|
|
thread_t* t=p->threadL;
|
|
|
|
while( t != nullptr )
|
2020-04-10 01:06:33 +00:00
|
|
|
{
|
2021-01-20 18:11:44 +00:00
|
|
|
thread_t* t0 = t->link;
|
|
|
|
if((rc = destroy(t->thH)) != kOkRC )
|
2020-04-10 01:06:33 +00:00
|
|
|
{
|
2021-01-20 18:11:44 +00:00
|
|
|
rc = cwLogError(rc,"Thread destroy failed.");
|
2020-04-10 01:06:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-01-20 18:11:44 +00:00
|
|
|
|
|
|
|
mem::release(t);
|
|
|
|
t = t0;
|
2020-04-10 01:06:33 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 02:47:26 +00:00
|
|
|
mem::release(p);
|
|
|
|
|
2020-04-10 01:06:33 +00:00
|
|
|
return rc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cw::rc_t cw::thread_mach::create( handle_t& hRef, threadFunc_t threadFunc, void* contextArray, unsigned contexRecdByteN, unsigned threadN )
|
|
|
|
{
|
|
|
|
rc_t rc;
|
|
|
|
|
|
|
|
if((rc = destroy(hRef)) != kOkRC )
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
thread_mach_t* p = mem::allocZ<thread_mach_t>();
|
|
|
|
|
2021-01-20 18:11:44 +00:00
|
|
|
uint8_t* ctxA = reinterpret_cast<uint8_t*>(contextArray);
|
2020-04-10 01:06:33 +00:00
|
|
|
|
|
|
|
for(unsigned i=0; i<threadN; ++i)
|
|
|
|
{
|
2021-01-20 18:11:44 +00:00
|
|
|
void* arg = ctxA + (i*contexRecdByteN);
|
2020-04-10 01:06:33 +00:00
|
|
|
|
2024-02-18 13:37:33 +00:00
|
|
|
if((rc = _add(p, threadFunc, arg, nullptr)) != kOkRC )
|
2020-04-10 01:06:33 +00:00
|
|
|
goto errLabel;
|
|
|
|
}
|
|
|
|
|
2020-04-10 02:47:26 +00:00
|
|
|
hRef.set(p);
|
|
|
|
|
2020-04-10 01:06:33 +00:00
|
|
|
errLabel:
|
|
|
|
if( rc != kOkRC )
|
|
|
|
_destroy(p);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2024-02-18 13:37:33 +00:00
|
|
|
cw::rc_t cw::thread_mach::add( handle_t h, threadFunc_t threadFunc, void* arg, const char* label )
|
2021-01-20 18:11:44 +00:00
|
|
|
{
|
|
|
|
thread_mach_t* p = _handleToPtr(h);
|
2024-02-18 13:37:33 +00:00
|
|
|
return _add(p,threadFunc,arg, label);
|
2021-01-20 18:11:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 01:06:33 +00:00
|
|
|
cw::rc_t cw::thread_mach::destroy( handle_t& hRef )
|
|
|
|
{
|
|
|
|
rc_t rc = kOkRC;
|
|
|
|
if( !hRef.isValid() )
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
thread_mach_t* p = _handleToPtr(hRef);
|
|
|
|
|
|
|
|
if((rc = _destroy(p)) != kOkRC )
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
hRef.clear();
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
cw::rc_t cw::thread_mach::start( handle_t h )
|
|
|
|
{
|
|
|
|
rc_t rc = kOkRC;
|
|
|
|
rc_t rc0;
|
|
|
|
|
|
|
|
thread_mach_t* p = _handleToPtr(h);
|
2021-01-20 18:11:44 +00:00
|
|
|
for(thread_t* t=p->threadL; t!=nullptr; t=t->link)
|
|
|
|
if((rc0 = thread::unpause( t->thH )) != kOkRC )
|
|
|
|
rc = cwLogError(rc0,"Thread start failed.");
|
2020-04-10 01:06:33 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
cw::rc_t cw::thread_mach::stop( handle_t h )
|
|
|
|
{
|
|
|
|
rc_t rc = kOkRC;
|
|
|
|
rc_t rc0;
|
|
|
|
|
|
|
|
thread_mach_t* p = _handleToPtr(h);
|
2021-01-20 18:11:44 +00:00
|
|
|
for(thread_t* t=p->threadL; t!=nullptr; t=t->link)
|
|
|
|
if((rc0 = thread::pause( t->thH, thread::kPauseFl | thread::kWaitFl )) != kOkRC )
|
|
|
|
rc = cwLogError(rc0,"Thread stop failed.");
|
2020-04-10 01:06:33 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2021-01-20 18:11:44 +00:00
|
|
|
|
|
|
|
bool cw::thread_mach::is_shutdown( handle_t h )
|
|
|
|
{
|
|
|
|
thread_mach_t* p = _handleToPtr(h);
|
|
|
|
for(thread_t* t=p->threadL; t!=nullptr; t=t->link)
|
|
|
|
if( thread::state(t->thH) != thread::kExitedThId )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|