libCom/osi: Add epicsThreadMap (calls user function for each thread)

This commit is contained in:
Ralph Lange
2012-06-29 17:54:38 +02:00
parent 1f5376b30b
commit 8c323b2197
5 changed files with 91 additions and 3 deletions
+3
View File
@@ -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);
+17
View File
@@ -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;
+31 -2
View File
@@ -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 );
}
+19 -1
View File
@@ -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)
{
+21
View File
@@ -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);