libCom/osi: Add epicsThreadMap (calls user function for each thread)
This commit is contained in:
@@ -111,6 +111,9 @@ epicsShareFunc void epicsShareAPI epicsThreadRunExitHooks(epicsThreadId id);
|
||||
epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultStartHook;
|
||||
epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultExitHook;
|
||||
|
||||
/* Map func to all threads */
|
||||
epicsShareFunc void epicsShareAPI epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func);
|
||||
|
||||
typedef struct epicsThreadPrivateOSD * epicsThreadPrivateId;
|
||||
epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void);
|
||||
epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id);
|
||||
|
||||
@@ -677,6 +677,23 @@ void epicsThreadShow (epicsThreadId id, unsigned int level)
|
||||
fprintf(epicsGetStdout(),"*** Thread %x does not exist.\n", (unsigned int)id);
|
||||
}
|
||||
|
||||
void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func)
|
||||
{
|
||||
struct taskVar *v;
|
||||
|
||||
taskVarLock ();
|
||||
/*
|
||||
* Map tasks in the order of creation (backwards through list)
|
||||
*/
|
||||
for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw)
|
||||
continue;
|
||||
while (v) {
|
||||
func (v, arg);
|
||||
v = v->back;
|
||||
}
|
||||
taskVarUnlock ();
|
||||
}
|
||||
|
||||
void epicsThreadShowAll (unsigned int level)
|
||||
{
|
||||
struct taskVar *v;
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* FIXME:
|
||||
* The Windows implementation for thread hooks is still missing.
|
||||
* epicsThreadHooksInit(); as part of the initialization
|
||||
* epicsThreadRunStartHooks(pthreadInfo); from thread context before the user func runs
|
||||
* epicsThreadRunExitHooks(pthreadInfo); from thread context after the user func exits
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -974,6 +981,28 @@ static void epicsThreadShowPrivate ( epicsThreadId id, unsigned level )
|
||||
fprintf (epicsGetStdout(),"\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsThreadMap ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func )
|
||||
{
|
||||
win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal ();
|
||||
win32ThreadParam * pParm;
|
||||
|
||||
if ( ! pGbl ) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterCriticalSection ( & pGbl->mutex );
|
||||
|
||||
for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList );
|
||||
pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) {
|
||||
func ( ( epicsThreadId ) pParm );
|
||||
}
|
||||
|
||||
LeaveCriticalSection ( & pGbl->mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsThreadShowAll ()
|
||||
*/
|
||||
@@ -987,9 +1016,9 @@ epicsShareFunc void epicsShareAPI epicsThreadShowAll ( unsigned level )
|
||||
}
|
||||
|
||||
EnterCriticalSection ( & pGbl->mutex );
|
||||
|
||||
|
||||
epicsThreadShowPrivate ( 0, level );
|
||||
for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList );
|
||||
for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList );
|
||||
pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) {
|
||||
epicsThreadShowPrivate ( ( epicsThreadId ) pParm, level );
|
||||
}
|
||||
|
||||
@@ -734,6 +734,25 @@ epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo,
|
||||
name[size-1] = '\0';
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo;
|
||||
int status;
|
||||
|
||||
epicsThreadInit();
|
||||
status = mutexLock(&listLock);
|
||||
checkStatus(status, "pthread_mutex_lock epicsThreadMap");
|
||||
if (status)
|
||||
return;
|
||||
pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
|
||||
while (pthreadInfo) {
|
||||
func(pthreadInfo);
|
||||
pthreadInfo = (epicsThreadOSD *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
status = pthread_mutex_unlock(&listLock);
|
||||
checkStatus(status, "pthread_mutex_unlock epicsThreadMap");
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo;
|
||||
@@ -784,7 +803,6 @@ epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsi
|
||||
if (!found)
|
||||
printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void)
|
||||
{
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
static const unsigned stackSizeTable[epicsThreadStackBig+1] =
|
||||
{4000*ARCH_STACK_FACTOR, 6000*ARCH_STACK_FACTOR, 11000*ARCH_STACK_FACTOR};
|
||||
|
||||
/* FIXME: this is the beta implementation of epicsThreadMap for vxWorks. See below. */
|
||||
#define ID_LIST_SIZE 2048
|
||||
static int taskIdList[ID_LIST_SIZE];
|
||||
|
||||
/*The following forces atReboot to be loaded*/
|
||||
extern int atRebootExtern;
|
||||
static struct pext {
|
||||
@@ -315,6 +319,23 @@ void epicsThreadGetName (epicsThreadId id, char *name, size_t size)
|
||||
name[size-1] = '\0';
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func )
|
||||
{
|
||||
/* FIXME: add better vxWorks implementation that uses a dynamic taskIdList */
|
||||
/* Andrew says:
|
||||
* use the vxWorks routine taskIdListGet();
|
||||
* that seems better, although there's no API to tell you how many tasks exist
|
||||
* (I guess you could keep a count yourself if you register
|
||||
* taskCreateHook and taskDeleteHook routines). */
|
||||
int noTasks;
|
||||
int i;
|
||||
|
||||
noTasks = taskIdListGet(taskIdList, ID_LIST_SIZE);
|
||||
for (i = 0; i < noTasks; i++) {
|
||||
func (i);
|
||||
}
|
||||
}
|
||||
|
||||
void epicsThreadShowAll(unsigned int level)
|
||||
{
|
||||
taskShow(0,2);
|
||||
|
||||
Reference in New Issue
Block a user