g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base
From: Ralph Lange <Ralph.Lange@gmx.de>
To: mp+112806@code.launchpad.net
Date: Fri, 29 Jun 2012 16:14:19 -0000
Ralph Lange has proposed merging lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base.

Requested reviews:
  EPICS Core Developers (epics-core)

For more details, see:
https://code.launchpad.net/~ralph-lange/epics-base/thread-hooks/+merge/112806

Adds two interfaces for user hooks that are being called from epicsThread:

epicsThreadAddStartHook(func) and epicsThreadAddExitHook(func) each add a user function to an internal list of hooks that are being called from the thread context, immediately before or after each thread's main routine runs.
For Linux, the default start hook adds the thread's Linux LWP ID to the thread info block and sets the Linux name to match the epics thread name, and epicsShowThread() is overwritten to print this LWP ID instead of the POSIX thread ID.

epicsThreadMap(func) immediately calls the user supplied func for each currently existing thread.

Caveat: The WIN32 implementation needs the start/exit hooks calls added - I simply do not understand this implementation well enough to do that.
The vxWorks implementation of epicsThreadMap() only works for up to 2048 threads, and needs to be made dynamic.
-- 
https://code.launchpad.net/~ralph-lange/epics-base/thread-hooks/+merge/112806
Your team EPICS Core Developers is requested to review the proposed merge of lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base.
=== modified file 'src/libCom/osi/Makefile'
--- src/libCom/osi/Makefile	2012-05-03 17:19:34 +0000
+++ src/libCom/osi/Makefile	2012-06-29 16:13:32 +0000
@@ -104,6 +104,8 @@
 osdThread_CPPFLAGS += $(THREAD_CPPFLAGS_$(USE_POSIX_THREAD_PRIORITY_SCHEDULING))
 
 Com_SRCS += osdThread.c
+Com_SRCS += osdThreadExtra.c
+Com_SRCS += osdThreadHooks.c
 Com_SRCS += osdMutex.c
 Com_SRCS += osdEvent.c
 Com_SRCS += osdTime.cpp

=== modified file 'src/libCom/osi/epicsThread.h'
--- src/libCom/osi/epicsThread.h	2010-04-26 20:38:11 +0000
+++ src/libCom/osi/epicsThread.h	2012-06-29 16:13:32 +0000
@@ -3,8 +3,8 @@
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* Copyright (c) 2012 ITER Organization
+* EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
 #ifndef epicsThreadh
@@ -101,6 +101,19 @@
 epicsShareFunc void epicsShareAPI epicsThreadShow(
     epicsThreadId id,unsigned int level);
 
+/* Hooks being called when a thread starts or exits */
+typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id);
+epicsShareFunc void epicsShareAPI epicsThreadHooksInit(void);
+epicsShareFunc void epicsShareAPI epicsThreadAddStartHook(EPICS_THREAD_HOOK_ROUTINE hook);
+epicsShareFunc void epicsShareAPI epicsThreadAddExitHook(EPICS_THREAD_HOOK_ROUTINE hook);
+epicsShareFunc void epicsShareAPI epicsThreadRunStartHooks(epicsThreadId id);
+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);

=== added file 'src/libCom/osi/os/Linux/osdThread.h'
--- src/libCom/osi/os/Linux/osdThread.h	1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/Linux/osdThread.h	2012-06-29 16:13:32 +0000
@@ -0,0 +1,48 @@
+/*************************************************************************\
+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+*     National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+*     Operator of Los Alamos National Laboratory.
+* EPICS BASE Versions 3.13.7
+* and higher are distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+#ifndef osdThreadh
+#define osdThreadh
+
+#include <pthread.h>
+
+#include "shareLib.h"
+#include "ellLib.h"
+#include "epicsEvent.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct epicsThreadOSD {
+    ELLNODE            node;
+    pthread_t          tid;
+    pid_t              lwpId;
+    pthread_attr_t     attr;
+    struct sched_param schedParam;
+    EPICSTHREADFUNC    createFunc;
+    void              *createArg;
+    epicsEventId       suspendEvent;
+    int                isSuspended;
+    int                isEpicsThread;
+    int                isFifoScheduled;
+    int                isOnThreadList;
+    unsigned int       osiPriority;
+    char               name[1];     /* actually larger */
+} epicsThreadOSD;
+
+epicsShareFunc pthread_t epicsShareAPI epicsThreadGetPosixThreadId(epicsThreadId id);
+
+epicsShareFunc void epicsShowThreadInfo(epicsThreadOSD *pthreadInfo, unsigned int level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* osdThreadh */

=== added file 'src/libCom/osi/os/Linux/osdThreadExtra.c'
--- src/libCom/osi/os/Linux/osdThreadExtra.c	1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/Linux/osdThreadExtra.c	2012-06-29 16:13:32 +0000
@@ -0,0 +1,63 @@
+/*************************************************************************\
+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+*     National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+*     Operator of Los Alamos National Laboratory.
+* Copyright (c) 2012 ITER Organization
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/* Author:  Marty Kraimer Date:    18JAN2000 */
+
+/* This differs from the posix implementation of epicsThread by:
+ * - printing the Linux LWP ID instead of the POSIX thread ID in the show routines
+ * - installing a default thread start hook, that sets the Linux thread name to the
+ *   EPICS thread name to make it visible on OS level, and discovers the LWP ID */
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/prctl.h>
+
+#define epicsExportSharedSymbols
+#include "epicsStdio.h"
+#include "ellLib.h"
+#include "epicsEvent.h"
+#include "epicsThread.h"
+
+void epicsShowThreadInfo(epicsThreadOSD *pthreadInfo, unsigned int level)
+{
+    if(!pthreadInfo) {
+        fprintf(epicsGetStdout(),"            NAME     EPICS ID   "
+            "LWP ID   OSIPRI  OSSPRI  STATE\n");
+    } else {
+        struct sched_param param;
+        int policy;
+        int priority = 0;
+
+        if(pthreadInfo->tid) {
+            int status;
+            status = pthread_getschedparam(pthreadInfo->tid,&policy,&param);
+            if(!status) priority = param.sched_priority;
+        }
+        fprintf(epicsGetStdout(),"%16.16s %12p %8lu    %3d%8d %8.8s\n",
+             pthreadInfo->name,(void *)
+             pthreadInfo,(unsigned long)pthreadInfo->lwpId,
+             pthreadInfo->osiPriority,priority,
+             pthreadInfo->isSuspended?"SUSPEND":"OK");
+    }
+}
+
+static void thread_hook(epicsThreadOSD *pthreadInfo)
+{
+    /* Set the name of the thread's process. Limited to 16 characters. */
+    char comm[16];
+    snprintf(comm, sizeof(comm), "%s", pthreadInfo->name);
+    prctl(PR_SET_NAME, comm, 0l, 0l, 0l);
+    pthreadInfo->lwpId = syscall(SYS_gettid);
+}
+
+EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultStartHook = thread_hook;
+EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultExitHook;

=== modified file 'src/libCom/osi/os/RTEMS/osdThread.c'
--- src/libCom/osi/os/RTEMS/osdThread.c	2010-10-05 19:27:37 +0000
+++ src/libCom/osi/os/RTEMS/osdThread.c	2012-06-29 16:13:32 +0000
@@ -164,7 +164,9 @@
 {
     struct taskVar *v = (struct taskVar *)arg;
 
+    epicsThreadRunStartHooks(pthreadInfo);
     (*v->funptr)(v->parm);
+    epicsThreadRunExitHooks(pthreadInfo);
     epicsExitCallAtThreadExits ();
     taskVarLock ();
     if (v->back)
@@ -235,6 +237,7 @@
         taskVarMutex = epicsMutexMustCreate ();
         rtems_task_ident (RTEMS_SELF, 0, &tid);
         setThreadInfo (tid, "_main_", NULL, NULL);
+        epicsThreadHooksInit();
         initialized = 1;
         epicsThreadCreate ("ImsgDaemon", 99,
                 epicsThreadGetStackSize (epicsThreadStackSmall),
@@ -674,6 +677,23 @@
     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;

=== modified file 'src/libCom/osi/os/WIN32/osdThread.c'
--- src/libCom/osi/os/WIN32/osdThread.c	2012-02-03 00:14:01 +0000
+++ src/libCom/osi/os/WIN32/osdThread.c	2012-06-29 16:13:32 +0000
@@ -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>
@@ -975,6 +982,28 @@
 }
 
 /*
+ * 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 ()
  */
 epicsShareFunc void epicsShareAPI epicsThreadShowAll ( unsigned level )
@@ -987,9 +1016,9 @@
     }
 
     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 );
     }

=== added file 'src/libCom/osi/os/default/osdThreadExtra.c'
--- src/libCom/osi/os/default/osdThreadExtra.c	1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/default/osdThreadExtra.c	2012-06-29 16:13:32 +0000
@@ -0,0 +1,13 @@
+/*************************************************************************\
+* Copyright (c) 2012 ITER Organization
+*
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/* Author:  Ralph Lange   Date:  26 Jun 2012 */
+
+/* Null default thread hooks for all platforms that do not do anything special */
+
+EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultStartHook;
+EPICS_THREAD_HOOK_ROUTINE epicsThreadDefaultExitHook;

=== added file 'src/libCom/osi/os/default/osdThreadHooks.c'
--- src/libCom/osi/os/default/osdThreadHooks.c	1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/default/osdThreadHooks.c	2012-06-29 16:13:32 +0000
@@ -0,0 +1,87 @@
+/*************************************************************************\
+* Copyright (c) 2012 ITER Organization
+*
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/* Author:  Ralph Lange   Date:  28 Jun 2012 */
+
+/* Secure hooks for epicsThread */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#define epicsExportSharedSymbols
+#include "ellLib.h"
+#include "epicsMutex.h"
+#include "epicsThread.h"
+
+#define checkStatusOnceReturn(status, message, method) \
+if((status)) { \
+    fprintf(stderr,"%s error %s\n",(message),strerror((status))); \
+    fprintf(stderr," %s\n",(method)); \
+    return; }
+
+typedef struct epicsThreadHook {
+    ELLNODE                   node;
+    EPICS_THREAD_HOOK_ROUTINE func;
+} epicsThreadHook;
+
+static ELLLIST startHooks = ELLLIST_INIT;
+static ELLLIST exitHooks = ELLLIST_INIT;
+static epicsMutexId hookLock;
+
+static void addHook (ELLLIST *list, EPICS_THREAD_HOOK_ROUTINE func)
+{
+    epicsThreadHook *pHook;
+
+    pHook = calloc(1, sizeof(epicsThreadHook));
+    if (!pHook) checkStatusOnceReturn(errno,"calloc","epicsThreadAddStartHook");
+    pHook->func = func;
+    epicsMutexLock(hookLock);
+    ellInsert(list, NULL, &pHook->node);
+    epicsMutexUnlock(hookLock);
+}
+
+static void runHooks (ELLLIST *list, epicsThreadId id) {
+    epicsThreadHook *pHook;
+
+    /* As we're only ever inserting hooks at the head of the list, forward traversing is safe */
+    pHook = (epicsThreadHook *) ellFirst(list);
+    while (pHook) {
+        pHook->func(id);
+        pHook = (epicsThreadHook *) ellNext(&pHook->node);
+    }
+}
+
+epicsShareFunc void epicsShareAPI epicsThreadAddStartHook(EPICS_THREAD_HOOK_ROUTINE hook)
+{
+    addHook(&startHooks, hook);
+}
+
+epicsShareFunc void epicsShareAPI epicsThreadAddExitHook(EPICS_THREAD_HOOK_ROUTINE hook)
+{
+    addHook(&exitHooks, hook);
+}
+
+epicsShareFunc void epicsShareAPI epicsThreadHooksInit(void)
+{
+    if (!hookLock) {
+        hookLock = epicsMutexMustCreate();
+        if (epicsThreadDefaultStartHook) epicsThreadAddStartHook(epicsThreadDefaultStartHook);
+        if (epicsThreadDefaultExitHook) epicsThreadAddExitHook(epicsThreadDefaultExitHook);
+    }
+}
+
+epicsShareFunc void epicsShareAPI epicsThreadRunStartHooks(epicsThreadId id)
+{
+    runHooks(&startHooks, id);
+}
+
+epicsShareFunc void epicsShareAPI epicsThreadRunExitHooks(epicsThreadId id)
+{
+    runHooks(&exitHooks, id);
+}

=== modified file 'src/libCom/osi/os/posix/osdThread.c'
--- src/libCom/osi/os/posix/osdThread.c	2012-06-19 19:28:26 +0000
+++ src/libCom/osi/os/posix/osdThread.c	2012-06-29 16:13:32 +0000
@@ -3,6 +3,7 @@
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
+* Copyright (c) 2012 ITER Organization
 * EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
@@ -57,22 +58,6 @@
     int                schedPolicy;
 } commonAttr;
 
-typedef struct epicsThreadOSD {
-    ELLNODE            node;
-    pthread_t          tid;
-    pthread_attr_t     attr;
-    struct sched_param schedParam;
-    EPICSTHREADFUNC    createFunc;
-    void              *createArg;
-    epicsEventId       suspendEvent;
-    int                isSuspended;
-    int                isEpicsThread;
-    int                isFifoScheduled;
-    int                isOnThreadList;
-    unsigned int       osiPriority;
-    char               name[1];     /* actually larger */
-} epicsThreadOSD;
-
 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
 typedef struct {
     int min_pri, max_pri;
@@ -366,6 +351,7 @@
     checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit");
     status = atexit(epicsExitCallAtExits);
     checkStatusOnce(status,"atexit");
+    epicsThreadHooksInit();
     epicsThreadOnceCalled = 1;
 }
 
@@ -375,7 +361,7 @@
     int status;
     int oldtype;
     sigset_t blockAllSig;
- 
+
     sigfillset(&blockAllSig);
     pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL);
     status = pthread_setspecific(getpthreadInfo,arg);
@@ -388,9 +374,11 @@
     pthreadInfo->isOnThreadList = 1;
     status = pthread_mutex_unlock(&listLock);
     checkStatusQuit(status,"pthread_mutex_unlock","start_routine");
+    epicsThreadRunStartHooks(pthreadInfo);
 
     (*pthreadInfo->createFunc)(pthreadInfo->createArg);
 
+    epicsThreadRunExitHooks(pthreadInfo);
     epicsExitCallAtThreadExits ();
 
     free_threadInfo(pthreadInfo);
@@ -747,27 +735,23 @@
     name[size-1] = '\0';
 }
 
-static void showThreadInfo(epicsThreadOSD *pthreadInfo,unsigned int level)
+epicsShareFunc void epicsShareAPI epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func)
 {
-    if(!pthreadInfo) {
-        fprintf(epicsGetStdout(),"            NAME     EPICS ID   "
-            "PTHREAD ID   OSIPRI  OSSPRI  STATE\n");
-    } else {
-        struct sched_param param;
-        int policy;
-        int priority = 0;
+    epicsThreadOSD *pthreadInfo;
+    int status;
 
-        if(pthreadInfo->tid) {
-            int status;
-            status = pthread_getschedparam(pthreadInfo->tid,&policy,&param);
-            if(!status) priority = param.sched_priority;
-        }
-        fprintf(epicsGetStdout(),"%16.16s %12p %12lu    %3d%8d %8.8s\n",
-             pthreadInfo->name,(void *)
-             pthreadInfo,(unsigned long)pthreadInfo->tid,
-             pthreadInfo->osiPriority,priority,
-             pthreadInfo->isSuspended?"SUSPEND":"OK");
+    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)
@@ -783,7 +767,7 @@
         return;
     pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
     while(pthreadInfo) {
-        showThreadInfo(pthreadInfo,level);
+        epicsShowThreadInfo(pthreadInfo,level);
         pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
     }
     status = pthread_mutex_unlock(&listLock);
@@ -798,7 +782,7 @@
 
     epicsThreadInit();
     if(!showThread) {
-        showThreadInfo(0,level);
+        epicsShowThreadInfo(0,level);
         return;
     }
     status = mutexLock(&listLock);
@@ -810,7 +794,7 @@
         if (((epicsThreadId)pthreadInfo == showThread)
          || ((epicsThreadId)pthreadInfo->tid == showThread)) {
             found = 1;
-            showThreadInfo(pthreadInfo,level);
+            epicsShowThreadInfo(pthreadInfo,level);
         }
         pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
     }
@@ -820,7 +804,6 @@
     if (!found)
         printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);
 }
-
 
 epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void)
 {

=== modified file 'src/libCom/osi/os/posix/osdThread.h'
--- src/libCom/osi/os/posix/osdThread.h	2008-08-06 16:54:25 +0000
+++ src/libCom/osi/os/posix/osdThread.h	2012-06-29 16:13:32 +0000
@@ -13,12 +13,32 @@
 #include <pthread.h>
 
 #include "shareLib.h"
+#include "ellLib.h"
+#include "epicsEvent.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-epicsShareFunc pthread_t epicsShareAPI epicsThreadGetPosixThreadId ( epicsThreadId id );
+typedef struct epicsThreadOSD {
+    ELLNODE            node;
+    pthread_t          tid;
+    pthread_attr_t     attr;
+    struct sched_param schedParam;
+    EPICSTHREADFUNC    createFunc;
+    void              *createArg;
+    epicsEventId       suspendEvent;
+    int                isSuspended;
+    int                isEpicsThread;
+    int                isFifoScheduled;
+    int                isOnThreadList;
+    unsigned int       osiPriority;
+    char               name[1];     /* actually larger */
+} epicsThreadOSD;
+
+epicsShareFunc pthread_t epicsShareAPI epicsThreadGetPosixThreadId(epicsThreadId id);
+
+epicsShareFunc void epicsShowThreadInfo(epicsThreadOSD *pthreadInfo, unsigned int level);
 
 #ifdef __cplusplus
 }

=== added file 'src/libCom/osi/os/posix/osdThreadExtra.c'
--- src/libCom/osi/os/posix/osdThreadExtra.c	1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/posix/osdThreadExtra.c	2012-06-29 16:13:32 +0000
@@ -0,0 +1,42 @@
+/*************************************************************************\
+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+*     National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+*     Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/* Author:  Marty Kraimer Date:    18JAN2000 */
+
+/* This is part of the posix implementation of epicsThread */
+
+#define epicsExportSharedSymbols
+#include "epicsStdio.h"
+#include "ellLib.h"
+#include "epicsEvent.h"
+#include "epicsThread.h"
+
+void epicsShowThreadInfo(epicsThreadOSD *pthreadInfo, unsigned int level)
+{
+    if(!pthreadInfo) {
+        fprintf(epicsGetStdout(),"            NAME     EPICS ID   "
+            "PTHREAD ID   OSIPRI  OSSPRI  STATE\n");
+    } else {
+        struct sched_param param;
+        int policy;
+        int priority = 0;
+
+        if(pthreadInfo->tid) {
+            int status;
+            status = pthread_getschedparam(pthreadInfo->tid,&policy,&param);
+            if(!status) priority = param.sched_priority;
+        }
+        fprintf(epicsGetStdout(),"%16.16s %12p %12lu    %3d%8d %8.8s\n",
+             pthreadInfo->name,(void *)
+             pthreadInfo,(unsigned long)pthreadInfo->tid,
+             pthreadInfo->osiPriority,priority,
+             pthreadInfo->isSuspended?"SUSPEND":"OK");
+    }
+}
+

=== modified file 'src/libCom/osi/os/vxWorks/osdThread.c'
--- src/libCom/osi/os/vxWorks/osdThread.c	2010-08-11 15:45:17 +0000
+++ src/libCom/osi/os/vxWorks/osdThread.c	2012-06-29 16:13:32 +0000
@@ -3,6 +3,7 @@
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
+* Copyright (c) 2012 ITER Organization
 * EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
@@ -42,6 +43,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 {
@@ -88,6 +93,7 @@
     static int lock = 0;
 
     while(!vxTas(&lock)) taskDelay(1);
+    epicsThreadHooksInit();
     if(epicsThreadOnceMutex==0) {
         epicsThreadOnceMutex = semMCreate(
                 SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY);
@@ -157,7 +163,9 @@
     taskVarAdd(tid,(int *)(char *)&papTSD);
     /*Make sure that papTSD is still 0 after that call to taskVarAdd*/
     papTSD = 0;
+    epicsThreadRunStartHooks(pthreadInfo);
     (*func)(parm);
+    epicsThreadRunExitHooks(pthreadInfo);
     epicsExitCallAtThreadExits ();
     free(papTSD);
     taskVarDelete(tid,(int *)(char *)&papTSD);
@@ -312,6 +320,23 @@
     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);


Replies:
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base mdavidsaver
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base Andrew Johnson
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base Ralph Lange
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base Andrew Johnson
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base Andrew Johnson
Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base Andrew Johnson
[Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base noreply

Navigate by Date:
Prev: Re: pend_io Andrew Johnson
Next: Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base mdavidsaver
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
Navigate by Thread:
Prev: RE: pend_io Steve Hunt
Next: Re: [Merge] lp:~ralph-lange/epics-base/thread-hooks into lp:epics-base mdavidsaver
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
ANJ, 26 Nov 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·