diff --git a/modules/libcom/src/osi/os/Linux/osdThread.h b/modules/libcom/src/osi/os/Linux/osdThread.h index 7f0a8bbc9..4bf7f29a6 100644 --- a/modules/libcom/src/osi/os/Linux/osdThread.h +++ b/modules/libcom/src/osi/os/Linux/osdThread.h @@ -36,6 +36,7 @@ typedef struct epicsThreadOSD { int isEpicsThread; int isRealTimeScheduled; int isOnThreadList; + int isRunning; unsigned int osiPriority; int joinable; char name[1]; /* actually larger */ diff --git a/modules/libcom/src/osi/os/Linux/osdThreadExtra.c b/modules/libcom/src/osi/os/Linux/osdThreadExtra.c index 813846bc2..e10c6fcc5 100644 --- a/modules/libcom/src/osi/os/Linux/osdThreadExtra.c +++ b/modules/libcom/src/osi/os/Linux/osdThreadExtra.c @@ -23,6 +23,7 @@ #include #include +#include "epicsAtomic.h" #include "epicsStdio.h" #include "ellLib.h" #include "epicsEvent.h" @@ -45,11 +46,12 @@ void epicsThreadShowInfo(epicsThreadId pthreadInfo, unsigned int level) if (!status) priority = param.sched_priority; } - fprintf(epicsGetStdout(),"%16.16s %14p %8lu %3d%8d %8.8s\n", + fprintf(epicsGetStdout(),"%16.16s %14p %8lu %3d%8d %8.8s%s\n", pthreadInfo->name,(void *) pthreadInfo,(unsigned long)pthreadInfo->lwpId, pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended ? "SUSPEND" : "OK"); + pthreadInfo->isSuspended ? "SUSPEND" : "OK", + epicsAtomicGetIntT(&pthreadInfo->isRunning) ? "" : " ZOMBIE"); } } diff --git a/modules/libcom/src/osi/os/RTEMS-score/osdThread.c b/modules/libcom/src/osi/os/RTEMS-score/osdThread.c index 110951445..7d37bbe48 100644 --- a/modules/libcom/src/osi/os/RTEMS-score/osdThread.c +++ b/modules/libcom/src/osi/os/RTEMS-score/osdThread.c @@ -53,6 +53,7 @@ struct taskVar { rtems_id join_barrier; /* only valid if joinable */ int refcnt; int joinable; + int isRunning; EPICSTHREADFUNC funptr; void *parm; unsigned int threadVariableCapacity; @@ -197,6 +198,7 @@ threadWrapper (rtems_task_argument arg) osdThreadHooksRun((epicsThreadId)v->id); (*v->funptr)(v->parm); epicsExitCallAtThreadExits (); + epicsAtomicSetIntT(&v->isRunning, 0); taskVarLock (); if (v->back) v->back->forw = v->forw; @@ -239,6 +241,7 @@ setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr, v->refcnt = joinable ? 2 : 1; v->threadVariableCapacity = 0; v->threadVariables = NULL; + v->isRunning = 1; if (joinable) { char c[3]; strncpy(c, v->name, 3); @@ -797,7 +800,11 @@ epicsThreadShowInfo (struct taskVar *v, unsigned int level) fprintf(epicsGetStdout(),"+--------+-----------+--------+--------+---------------------+\n"); } else { fprintf(epicsGetStdout(),"%9.8x", (int)v->id); - showInternalTaskInfo (v->id); + if(epicsAtomicGetIntT(&v->isRunning)) { + showInternalTaskInfo (v->id); + } else { + fprintf(epicsGetStdout(),"%-30s", " *** ZOMBIE task! ***"); + } fprintf(epicsGetStdout()," %s\n", v->name); } } diff --git a/modules/libcom/src/osi/os/WIN32/osdThread.c b/modules/libcom/src/osi/os/WIN32/osdThread.c index 1cfeb3767..5e9eeb435 100644 --- a/modules/libcom/src/osi/os/WIN32/osdThread.c +++ b/modules/libcom/src/osi/os/WIN32/osdThread.c @@ -102,6 +102,7 @@ typedef struct epicsThreadOSD { unsigned epicsPriority; char isSuspended; int joinable; + int isRunning; HANDLE timer; /* waitable timer */ } win32ThreadParam; @@ -519,6 +520,8 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter ) epicsExitCallAtThreadExits (); + epicsAtomicSetIntT(&pParm->isRunning, 0); + /* On Windows we could omit this and rely on the callback given to FlsAlloc() to free. * However < vista doesn't implement FLS at all, and WINE (circa 5.0.3) doesn't * implement fully (dtor never runs). So for EPICS threads, we explicitly @@ -540,6 +543,7 @@ static win32ThreadParam * epicsThreadParmCreate ( const char *pName ) pParmWIN32->pName = (char *) ( pParmWIN32 + 1 ); strcpy ( pParmWIN32->pName, pName ); pParmWIN32->isSuspended = 0; + pParmWIN32->isRunning = 1; epicsAtomicIncrIntT(&pParmWIN32->refcnt); #ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION pParmWIN32->timer = CreateWaitableTimerEx(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); @@ -1044,6 +1048,8 @@ static void epicsThreadShowInfo ( epicsThreadId id, unsigned level ) fprintf (epicsGetStdout(), " %-8p %-8p ", (void *) pParm->handle, (void *) pParm->parm ); } + if(!epicsAtomicGetIntT(&pParm->isRunning)) + fprintf (epicsGetStdout(), " ZOMBIE"); } else { fprintf (epicsGetStdout(), diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c index c814916f8..73e7a2bf6 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.c +++ b/modules/libcom/src/osi/os/posix/osdThread.c @@ -173,6 +173,7 @@ static epicsThreadOSD * create_threadInfo(const char *name) pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name)); if(!pthreadInfo) return NULL; + pthreadInfo->isRunning = 1; pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty); if(!pthreadInfo->suspendEvent){ free(pthreadInfo); @@ -441,6 +442,8 @@ static void * start_routine(void *arg) (*pthreadInfo->createFunc)(pthreadInfo->createArg); epicsExitCallAtThreadExits (); + + epicsAtomicSetIntT(&pthreadInfo->isRunning, 0); return(0); } diff --git a/modules/libcom/src/osi/os/posix/osdThread.h b/modules/libcom/src/osi/os/posix/osdThread.h index 58065a497..ea49030a3 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.h +++ b/modules/libcom/src/osi/os/posix/osdThread.h @@ -34,6 +34,7 @@ typedef struct epicsThreadOSD { int isEpicsThread; int isRealTimeScheduled; int isOnThreadList; + int isRunning; unsigned int osiPriority; int joinable; char name[1]; /* actually larger */ diff --git a/modules/libcom/src/osi/os/posix/osdThreadExtra.c b/modules/libcom/src/osi/os/posix/osdThreadExtra.c index 0fb3023f2..4344110f0 100644 --- a/modules/libcom/src/osi/os/posix/osdThreadExtra.c +++ b/modules/libcom/src/osi/os/posix/osdThreadExtra.c @@ -12,6 +12,7 @@ /* This is part of the posix implementation of epicsThread */ +#include "epicsAtomic.h" #include "epicsStdio.h" #include "ellLib.h" #include "epicsEvent.h" @@ -35,11 +36,12 @@ void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level) status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m); if(!status) priority = param.sched_priority; } - fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n", + fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s%s\n", pthreadInfo->name,(void *) pthreadInfo,(unsigned long)pthreadInfo->tid, pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended?"SUSPEND":"OK"); + pthreadInfo->isSuspended?"SUSPEND":"OK", + epicsAtomicGetIntT(&pthreadInfo->isRunning) ? "" : " ZOMBIE"); } }