Threads now take a label which can be displayed via system tools (e.g. top, ps).
This commit is contained in:
parent
24e35872b2
commit
64df75d9aa
@ -1368,7 +1368,7 @@ cw::rc_t cw::audio::device::alsa::create( handle_t& hRef, struct driver_str*& dr
|
||||
p->pollfds = mem::allocZ<struct pollfd>( p->pollfdsAllocCnt );
|
||||
p->pollfdsDesc = mem::allocZ<pollfdsDesc_t>(p->pollfdsAllocCnt );
|
||||
|
||||
if((rc = thread::create(p->thH,_threadFunc,p)) != kOkRC )
|
||||
if((rc = thread::create(p->thH,_threadFunc,p,"alsa_audio")) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Thread create failed.");
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ cw::rc_t cw::audio::device::file::create( handle_t& hRef, struct driver_str*&
|
||||
p->driver.deviceSeek = deviceSeek;
|
||||
p->driver.deviceRealTimeReport = deviceRealTimeReport;
|
||||
|
||||
if((rc = create( p->threadH, _threadCbFunc, p )) != kOkRC )
|
||||
if((rc = create( p->threadH, _threadCbFunc, p, "audio_dev_test" )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Audio device file thread create failed.");
|
||||
goto errLabel;
|
||||
|
@ -412,7 +412,7 @@ int main( int argc, const char* argv[] )
|
||||
|
||||
|
||||
// create the TCP listening thread
|
||||
if((rc = thread::create( app.tcpThreadH, tcpReceiveCallback, &app )) != kOkRC )
|
||||
if((rc = thread::create( app.tcpThreadH, tcpReceiveCallback, &app, "avahi_suf" )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// Allocate Avahi thread
|
||||
|
@ -942,7 +942,7 @@ namespace cw
|
||||
return cwLogError(rc,"Unable to create EuCon server.");
|
||||
|
||||
// Create the application thread
|
||||
if((rc = thread::create( app.thH, appThreadFunc, &app )) != kOkRC )
|
||||
if((rc = thread::create( app.thH, appThreadFunc, &app, "eu_con" )) != kOkRC )
|
||||
return cwLogError(rc,"App thread create failed.");
|
||||
|
||||
// Start the application thread
|
||||
|
10
cwIo.cpp
10
cwIo.cpp
@ -371,7 +371,7 @@ namespace cw
|
||||
|
||||
time::get(t->nextTime);
|
||||
|
||||
if((rc = thread_mach::add(p->threadMachH,_timerThreadCb,t)) != kOkRC )
|
||||
if((rc = thread_mach::add(p->threadMachH,_timerThreadCb,t, label)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Timer thread assignment failed.");
|
||||
}
|
||||
@ -848,7 +848,7 @@ namespace cw
|
||||
|
||||
// create the socket thread
|
||||
if( p->sockN > 0 )
|
||||
if((rc = thread_mach::add(p->threadMachH,_socketThreadFunc,p)) != kOkRC )
|
||||
if((rc = thread_mach::add(p->threadMachH,_socketThreadFunc,p,"io_socket")) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Error creating socket thread.");
|
||||
goto errLabel;
|
||||
@ -1567,7 +1567,7 @@ namespace cw
|
||||
}
|
||||
|
||||
// create the audio group thread
|
||||
if((rc = thread_mach::add(p->threadMachH,_audioGroupThreadFunc,p->audioGroupA+i)) != kOkRC )
|
||||
if((rc = thread_mach::add(p->threadMachH,_audioGroupThreadFunc,p->audioGroupA+i,"io_audio_group")) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Error creating audio group thread.");
|
||||
goto errLabel;
|
||||
@ -2462,7 +2462,7 @@ void cw::io::realTimeReport( handle_t h )
|
||||
// Thread
|
||||
//
|
||||
|
||||
cw::rc_t cw::io::threadCreate( handle_t h, unsigned id, bool asyncFl, void* arg )
|
||||
cw::rc_t cw::io::threadCreate( handle_t h, unsigned id, bool asyncFl, void* arg, const char* label )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = _handleToPtr(h);
|
||||
@ -2475,7 +2475,7 @@ cw::rc_t cw::io::threadCreate( handle_t h, unsigned id, bool asyncFl, void* arg
|
||||
t->link = p->threadL;
|
||||
p->threadL = t;
|
||||
|
||||
if((rc = thread_mach::add( p->threadMachH, _threadFunc, t )) != kOkRC )
|
||||
if((rc = thread_mach::add( p->threadMachH, _threadFunc, t, label )) != kOkRC )
|
||||
rc = cwLogError(rc,"Thread create failed.");
|
||||
|
||||
return rc;
|
||||
|
2
cwIo.h
2
cwIo.h
@ -177,7 +177,7 @@ namespace cw
|
||||
//
|
||||
// Thread
|
||||
//
|
||||
rc_t threadCreate( handle_t h, unsigned id, bool asyncFl, void* arg );
|
||||
rc_t threadCreate( handle_t h, unsigned id, bool asyncFl, void* arg, const char* label );
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -94,13 +94,13 @@ cw::rc_t cw::min_test( const object_t* cfg )
|
||||
if((rc = create(app.ioH,cfg,minTestCb,&app)) != kOkRC )
|
||||
return rc;
|
||||
|
||||
if((rc = threadCreate( app.ioH, kThread0Id, asyncFl, &app )) != kOkRC )
|
||||
if((rc = threadCreate( app.ioH, kThread0Id, asyncFl, &app, "min_test_0" )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Thread 0 create failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = threadCreate( app.ioH, kThread1Id, asyncFl, &app )) != kOkRC )
|
||||
if((rc = threadCreate( app.ioH, kThread1Id, asyncFl, &app, "min_test_1" )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Thread 1 create failed.");
|
||||
goto errLabel;
|
||||
|
@ -1317,7 +1317,7 @@ cw::rc_t cw::net::mdns::test()
|
||||
}
|
||||
|
||||
// create the TCP listening thread
|
||||
if((rc = thread::create( app.tcpThreadH, tcpReceiveCallback, &app )) != kOkRC )
|
||||
if((rc = thread::create( app.tcpThreadH, tcpReceiveCallback, &app, "mdns" )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
|
@ -216,7 +216,8 @@ cw::rc_t cw::midi::device::create( handle_t& hRef,
|
||||
|
||||
if((rc = thread::create(p->threadH,
|
||||
_thread_func,
|
||||
p)) != kOkRC )
|
||||
p,
|
||||
"midi_dev")) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The MIDI file device thread create failed.");
|
||||
goto errLabel;
|
||||
@ -556,7 +557,7 @@ errLabel:
|
||||
|
||||
cw::rc_t cw::midi::device::start( handle_t h )
|
||||
{
|
||||
rc_t rc;
|
||||
rc_t rc = kOkRC;
|
||||
device_t* p = _handleToPtr(h);
|
||||
|
||||
if( p->fileDevStateId != kPlayingStateId )
|
||||
|
@ -365,7 +365,7 @@ cw::rc_t cw::nbmem::test_multi_threaded()
|
||||
ctx.threadA[i].varA = mem::allocZ<void*>(threadVarN);
|
||||
ctx.threadA[i].varN = threadVarN;
|
||||
|
||||
if((rc = thread::create(ctx.threadA[i].threadH, _test_thread_func, ctx.threadA + i )) != kOkRC )
|
||||
if((rc = thread::create(ctx.threadA[i].threadH, _test_thread_func, ctx.threadA + i, "nb_mem" )) != kOkRC )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ cw::rc_t cw::serialPortSrv::create( handle_t& h, unsigned pollPeriodMs, unsigned
|
||||
if((rc = serialPort::create( p->mgrH, recvBufByteN)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = thread::create( p->threadH, threadCallback, p)) != kOkRC )
|
||||
if((rc = thread::create( p->threadH, threadCallback, p, "serial_srv")) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
p->pollPeriodMs = pollPeriodMs;
|
||||
|
@ -1211,7 +1211,7 @@ cw::rc_t cw::socksrv::createMgrSrv( handle_t& hRef, unsigned timeOutMs, unsigne
|
||||
goto errLabel;
|
||||
|
||||
// create the thread
|
||||
if((rc = thread::create( p->thH, _threadFunc, p)) != kOkRC )
|
||||
if((rc = thread::create( p->thH, _threadFunc, p, "sock")) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
p->timeOutMs = timeOutMs;
|
||||
|
@ -110,7 +110,7 @@ cw::rc_t cw::net::srv::create(
|
||||
if((rc = socket::create( p->sockH, port, flags, timeOutMs, remoteAddr, remotePort, localAddr )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = thread::create( p->threadH, _threadFunc, p )) != kOkRC )
|
||||
if((rc = thread::create( p->threadH, _threadFunc, p, "tcp_sock_srv" )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
p->flags = srvFlags;
|
||||
|
@ -120,7 +120,7 @@ cw::rc_t cw::net::socket::test( portNumber_t localPort, const char* remoteAddr,
|
||||
if((rc = create(app.sockH,localPort, kBlockingFl,timeOutMs, NULL, kInvalidPortNumber )) != kOkRC )
|
||||
return rc;
|
||||
|
||||
if((rc = thread::create( app.threadH, _dgramThreadFunc, &app )) != kOkRC )
|
||||
if((rc = thread::create( app.threadH, _dgramThreadFunc, &app, "tcp_sock_test_tcp" )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = thread::unpause( app.threadH )) != kOkRC )
|
||||
@ -176,7 +176,7 @@ cw::rc_t cw::net::socket::test_tcp( portNumber_t localPort, const char* remoteAd
|
||||
return rc;
|
||||
|
||||
// create the listening thread (which is really only used by the server)
|
||||
if((rc = thread::create( app.threadH, streamFl ? _tcpStreamThreadFunc : _dgramThreadFunc, &app )) != kOkRC )
|
||||
if((rc = thread::create( app.threadH, streamFl ? _tcpStreamThreadFunc : _dgramThreadFunc, &app, "tcp_sock_test" )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// if this is a streaming client then connect to the server (which must have already been started)
|
||||
|
29
cwThread.cpp
29
cwThread.cpp
@ -31,6 +31,7 @@ namespace cw
|
||||
unsigned pauseMicros;
|
||||
unsigned sleepMicros;
|
||||
pthread_attr_t attr;
|
||||
char* label;
|
||||
|
||||
} thread_t;
|
||||
|
||||
@ -120,7 +121,7 @@ namespace cw
|
||||
}
|
||||
|
||||
|
||||
cw::rc_t cw::thread::create( handle_t& hRef, cbFunc_t func, void* funcArg, int stateMicros, int pauseMicros )
|
||||
cw::rc_t cw::thread::create( handle_t& hRef, cbFunc_t func, void* funcArg, const char* label, int stateMicros, int pauseMicros )
|
||||
{
|
||||
rc_t rc;
|
||||
int sysRC;
|
||||
@ -136,6 +137,7 @@ cw::rc_t cw::thread::create( handle_t& hRef, cbFunc_t func, void* funcArg, int s
|
||||
p->pauseMicros = pauseMicros;
|
||||
p->stateId = kPausedThId;
|
||||
p->sleepMicros = 15000;
|
||||
p->label = mem::duplStr(label);
|
||||
|
||||
if((sysRC = pthread_attr_init(&p->attr)) != 0)
|
||||
{
|
||||
@ -162,8 +164,16 @@ cw::rc_t cw::thread::create( handle_t& hRef, cbFunc_t func, void* funcArg, int s
|
||||
rc = cwLogSysError(kOpFailRC,sysRC,"Thread create failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if( label != nullptr )
|
||||
pthread_setname_np(p->pThreadH, label);
|
||||
|
||||
|
||||
hRef.set(p);
|
||||
|
||||
|
||||
cwLogInfo("Thread %s id:%p created.",cwStringNullGuard(label), p->pThreadH);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -182,16 +192,16 @@ cw::rc_t cw::thread::destroy( handle_t& hRef )
|
||||
|
||||
// wait for the thread to exit and then deallocate the thread object
|
||||
if((rc = _waitForState(p,kExitedThId)) != kOkRC )
|
||||
return cwLogError(rc,"Thread timed out waiting for destroy.");
|
||||
return cwLogError(rc,"Thread '%s' timed out waiting for destroy.",p->label);
|
||||
|
||||
// Block until the thread is actually fully cleaned up
|
||||
if((sysRC = pthread_join(p->pThreadH,NULL)) != 0)
|
||||
rc = cwLogSysError(kOpFailRC,sysRC,"Thread join failed.");
|
||||
rc = cwLogSysError(kOpFailRC,sysRC,"Thread '%s' join failed.",p->label);
|
||||
|
||||
//if( pthread_attr_destroy(&p->attr) != 0 )
|
||||
// rc = cwLogError(kOpFailRC,"Thread attribute destroy failed.");
|
||||
|
||||
|
||||
mem::release(p->label);
|
||||
mem::release(p);
|
||||
hRef.clear();
|
||||
|
||||
@ -227,7 +237,7 @@ cw::rc_t cw::thread::pause( handle_t h, unsigned cmdFlags )
|
||||
rc = _waitForState(p,waitId);
|
||||
|
||||
if( rc != kOkRC )
|
||||
cwLogError(rc,"Thread timed out waiting for '%s'. pauseMicros:%i stateMicros:%i sleepMicros:%i", pauseFl ? "pause" : "un-pause",p->pauseMicros,p->stateMicros,p->sleepMicros);
|
||||
cwLogError(rc,"Thread '%s' timed out waiting for '%s'. pauseMicros:%i stateMicros:%i sleepMicros:%i", p->label, pauseFl ? "pause" : "un-pause",p->pauseMicros,p->stateMicros,p->sleepMicros);
|
||||
|
||||
return rc;
|
||||
|
||||
@ -258,6 +268,13 @@ cw::thread::thread_id_t cw::thread::id()
|
||||
return id.u.id;
|
||||
}
|
||||
|
||||
const char* cw::thread::label( handle_t h )
|
||||
{
|
||||
thread_t* p = _handleToPtr(h);
|
||||
return p->label==nullptr ? "<no_thread_label>" : p->label;
|
||||
}
|
||||
|
||||
|
||||
unsigned cw::thread::stateTimeOutMicros( handle_t h)
|
||||
{
|
||||
thread_t* p = _handleToPtr(h);
|
||||
@ -288,7 +305,7 @@ cw::rc_t cw::threadTest()
|
||||
rc_t rc;
|
||||
char c = 0;
|
||||
|
||||
if((rc = thread::create(h,_threadTestCb,&val)) != kOkRC )
|
||||
if((rc = thread::create(h,_threadTestCb,&val,"thread_test")) != kOkRC )
|
||||
return rc;
|
||||
|
||||
if((rc = thread::pause(h,0)) != kOkRC )
|
||||
|
11
cwThread.h
11
cwThread.h
@ -5,6 +5,8 @@ namespace cw
|
||||
{
|
||||
namespace thread
|
||||
{
|
||||
const int kDefaultStateTimeOutMicros=100000;
|
||||
const int kDefaultPauseMicros = 10000;
|
||||
typedef enum
|
||||
{
|
||||
kNotInitThId,
|
||||
@ -23,7 +25,13 @@ namespace cw
|
||||
// The thread is in the 'paused' state after it is created.
|
||||
// stateMicros = total time out duration for switching to the exit state or for switching in/out of pause state.
|
||||
// pauseMicros = duration of thread sleep interval when in paused state.
|
||||
rc_t create( handle_t& hRef, cbFunc_t func, void* funcArg, int stateTimeOutMicros=100000, int pauseMicros=10000 );
|
||||
rc_t create( handle_t& hRef,
|
||||
cbFunc_t func,
|
||||
void* funcArg,
|
||||
const char* label, // Assign a label which will show up via `top -H` or `ps -T`.
|
||||
int stateTimeOutMicros=kDefaultStateTimeOutMicros,
|
||||
int pauseMicros=kDefaultPauseMicros );
|
||||
|
||||
rc_t destroy( handle_t& hRef );
|
||||
|
||||
|
||||
@ -35,6 +43,7 @@ namespace cw
|
||||
|
||||
// Return the thread id of the calling context.
|
||||
thread_id_t id();
|
||||
const char* label( handle_t h );
|
||||
|
||||
unsigned stateTimeOutMicros( handle_t h);
|
||||
unsigned pauseMicros( handle_t h );
|
||||
|
@ -25,13 +25,13 @@ namespace cw
|
||||
thread_mach_t* _handleToPtr( handle_t h )
|
||||
{ return handleToPtr<handle_t,thread_mach_t>(h); }
|
||||
|
||||
rc_t _add( thread_mach_t* p, threadFunc_t func, void* arg )
|
||||
rc_t _add( thread_mach_t* p, threadFunc_t func, void* arg, const char* label )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
thread_t* t = mem::allocZ<thread_t>();
|
||||
|
||||
if((rc = thread::create(t->thH, func, arg )) != kOkRC )
|
||||
if((rc = thread::create(t->thH, func, arg, label==nullptr ? "thread_mach" : label )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Thread create failed.");
|
||||
goto errLabel;
|
||||
@ -90,7 +90,7 @@ cw::rc_t cw::thread_mach::create( handle_t& hRef, threadFunc_t threadFunc, void*
|
||||
{
|
||||
void* arg = ctxA + (i*contexRecdByteN);
|
||||
|
||||
if((rc = _add(p, threadFunc, arg)) != kOkRC )
|
||||
if((rc = _add(p, threadFunc, arg, nullptr)) != kOkRC )
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
@ -103,10 +103,10 @@ cw::rc_t cw::thread_mach::create( handle_t& hRef, threadFunc_t threadFunc, void*
|
||||
return rc;
|
||||
}
|
||||
|
||||
cw::rc_t cw::thread_mach::add( handle_t h, threadFunc_t threadFunc, void* arg )
|
||||
cw::rc_t cw::thread_mach::add( handle_t h, threadFunc_t threadFunc, void* arg, const char* label )
|
||||
{
|
||||
thread_mach_t* p = _handleToPtr(h);
|
||||
return _add(p,threadFunc,arg);
|
||||
return _add(p,threadFunc,arg, label);
|
||||
}
|
||||
|
||||
cw::rc_t cw::thread_mach::destroy( handle_t& hRef )
|
||||
|
@ -16,7 +16,7 @@ namespace cw
|
||||
|
||||
// Create an additional thread. Note that the additional thread will be started by the next
|
||||
// call to 'start()'.
|
||||
rc_t add( handle_t h, threadFunc_t threadFunc, void* arg );
|
||||
rc_t add( handle_t h, threadFunc_t threadFunc, void* arg, const char* label );
|
||||
|
||||
// Start all threads
|
||||
rc_t start( handle_t h );
|
||||
|
@ -68,7 +68,7 @@ cw::rc_t cw::websockSrv::create(
|
||||
goto errLabel;
|
||||
|
||||
|
||||
if((rc = thread::create(p->_thread,_websockSrvThreadCb,p)) != kOkRC )
|
||||
if((rc = thread::create(p->_thread,_websockSrvThreadCb,p,"web_sock_srv")) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
p->_timeOutMs = timeOutMs;
|
||||
|
Loading…
Reference in New Issue
Block a user