epicsThreadShow() zombies

Flag when the thread has returned, but the tracking
struct is still around.  eg. in need of joining.
This commit is contained in:
Michael Davidsaver
2023-05-23 10:30:31 -07:00
committed by Dirk Zimoch
parent 49b9573f3a
commit cb6442da71
7 changed files with 27 additions and 5 deletions

View File

@@ -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 */

View File

@@ -23,6 +23,7 @@
#include <sys/types.h>
#include <sys/prctl.h>
#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");
}
}

View File

@@ -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);
}
}

View File

@@ -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(),

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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,&param);
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");
}
}