This is Unofficial EPICS BASE Doxygen Site
osdThread.c File Reference
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <syslog.h>
#include <limits.h>
#include <pthread.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsStdio.h"
#include "errlog.h"
#include "epicsMutex.h"
#include "epicsString.h"
#include "epicsThread.h"
#include "cantProceed.h"
#include "osiUnistd.h"
#include "osdInterrupt.h"
#include "epicsExit.h"
#include "epicsAtomic.h"
+ Include dependency graph for osdThread.c:

Go to the source code of this file.

Classes

struct  taskVar
 
struct  bitmap
 

Macros

#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__   1
 
#define RTEMS_NOTEPAD_TASKVAR   11
 
#define EPICS_THREAD_ONCE_DONE   (epicsThreadId) 1
 

Functions

LIBCOM_API void osdThreadHooksRun (epicsThreadId id)
 
LIBCOM_API void osdThreadHooksRunMain (epicsThreadId id)
 
int epicsThreadGetOsiPriorityValue (int ossPriority)
 
int epicsThreadGetOssPriorityValue (unsigned int osiPriority)
 
LIBCOM_API epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove (unsigned int priority, unsigned *pPriorityJustAbove)
 
LIBCOM_API epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow (unsigned int priority, unsigned *pPriorityJustBelow)
 
unsigned int epicsThreadGetStackSize (epicsThreadStackSizeClass size)
 
void epicsThreadExitMain (void)
 
void epicsThreadRealtimeLock (void)
 
epicsThreadId epicsThreadCreateOpt (const char *name, EPICSTHREADFUNC funptr, void *parm, const epicsThreadOpts *opts)
 Allocate and start a new OS thread. More...
 
epicsThreadId threadMustCreate (const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
 
void epicsThreadMustJoin (epicsThreadId id)
 
void epicsThreadSuspendSelf (void)
 
void epicsThreadResume (epicsThreadId id)
 
unsigned int epicsThreadGetPriority (epicsThreadId id)
 
unsigned int epicsThreadGetPrioritySelf (void)
 
void epicsThreadSetPriority (epicsThreadId id, unsigned int osip)
 
int epicsThreadIsEqual (epicsThreadId id1, epicsThreadId id2)
 
int epicsThreadIsSuspended (epicsThreadId id)
 
void epicsThreadSleep (double seconds)
 Block the calling thread for at least the specified time. More...
 
epicsThreadId epicsThreadGetIdSelf (void)
 
const char * epicsThreadGetNameSelf (void)
 
void epicsThreadGetName (epicsThreadId id, char *name, size_t size)
 
epicsThreadId epicsThreadGetId (const char *name)
 
void epicsThreadOnce (epicsThreadOnceId *id, void(*func)(void *), void *arg)
 
epicsThreadPrivateId epicsThreadPrivateCreate ()
 
void epicsThreadPrivateDelete (epicsThreadPrivateId id)
 
void epicsThreadPrivateSet (epicsThreadPrivateId id, void *pvt)
 
void * epicsThreadPrivateGet (epicsThreadPrivateId id)
 
void epicsThreadShow (epicsThreadId id, unsigned int level)
 
void epicsThreadMap (EPICS_THREAD_HOOK_ROUTINE func)
 
void epicsThreadShowAll (unsigned int level)
 
double epicsThreadSleepQuantum (void)
 Query a value approximating the OS timer/scheduler resolution. More...
 
LIBCOM_API int epicsThreadGetCPUs (void)
 

Macro Definition Documentation

#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__   1

Definition at line 15 of file osdThread.c.

#define EPICS_THREAD_ONCE_DONE   (epicsThreadId) 1
#define RTEMS_NOTEPAD_TASKVAR   11

Definition at line 62 of file osdThread.c.

Function Documentation

epicsThreadId epicsThreadCreateOpt ( const char *  name,
EPICSTHREADFUNC  funptr,
void *  parm,
const epicsThreadOpts opts 
)

Allocate and start a new OS thread.

Parameters
nameA name describing this thread. Appears in various log and error message.
funptrThe thread main function.
parmPassed to thread main function.
optsModifiers for the new thread, or NULL to use target specific defaults.
Returns
NULL on error

Definition at line 308 of file osdThread.c.

311 {
312  unsigned int stackSize;
313  rtems_id tid;
314  rtems_status_code sc;
315  char c[4];
316 
317  if (!initialized)
318  epicsThreadInit();
319 
320  if (!opts) {
321  static const epicsThreadOpts opts_default = EPICS_THREAD_OPTS_INIT;
322  opts = &opts_default;
323  }
324  stackSize = opts->stackSize;
325  if (stackSize <= epicsThreadStackBig)
326  stackSize = epicsThreadGetStackSize(stackSize);
327 
328  if (stackSize < RTEMS_MINIMUM_STACK_SIZE) {
329  errlogPrintf ("Warning: epicsThreadCreate %s illegal stackSize %d\n",
330  name, stackSize);
331  stackSize = RTEMS_MINIMUM_STACK_SIZE;
332  }
333  strncpy (c, name, sizeof c);
334  sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]),
336  stackSize,
337  RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
338  RTEMS_FLOATING_POINT|RTEMS_LOCAL,
339  &tid);
340  if (sc != RTEMS_SUCCESSFUL) {
341  errlogPrintf ("epicsThreadCreate create failure for %s: %s\n",
342  name, rtems_status_text(sc));
343  return 0;
344  }
345  sc = setThreadInfo (tid, name, funptr, parm, opts->joinable);
346  if (sc != RTEMS_SUCCESSFUL) {
347  errlogPrintf ("epicsThreadCreate create failure during setup for %s: %s\n",
348  name, rtems_status_text(sc));
349  rtems_task_delete(tid);
350  return 0;
351  }
352  return (epicsThreadId)tid;
353 }
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass stackSizeClass)
Definition: osdThread.c:466
unsigned int joinable
Definition: epicsThread.h:158
int epicsThreadGetOssPriorityValue(unsigned int osiPriority)
Definition: osdThread.c:98
unsigned int stackSize
Definition: epicsThread.h:154
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
unsigned int priority
Definition: epicsThread.h:150
#define EPICS_THREAD_OPTS_INIT
Definition: epicsThread.h:167
void epicsThreadExitMain ( void  )

If the main routine is done but wants to let other threads run it can call this routine. This should be the last call in main, except the final return. On most systems epicsThreadExitMain never returns.This must only be called by the main thread.

Definition at line 219 of file osdThread.c.

220 {
221 }
LIBCOM_API int epicsThreadGetCPUs ( void  )

Return a value approximating the number of threads which this target can run in parallel. This value is advisory.

Returns
>=1

Definition at line 862 of file osdThread.c.

863 {
864 #if defined(RTEMS_SMP)
865  return rtems_smp_get_number_of_processors();
866 #else
867  return 1;
868 #endif
869 }
epicsThreadId epicsThreadGetId ( const char *  name)

Attempt to find the first instance of a thread by name.

Returns
An epicsThreadId, or NULL if no such thread is currently running. Note that a non-NULL ID may still be invalid if this call races with thread exit.
Warning
Safe use of this function requires external knowledge that this thread will not return.

Definition at line 579 of file osdThread.c.

580 {
581  struct taskVar *v;
582  rtems_id tid = 0;
583 
584  /*
585  * Linear search is good enough since this routine
586  * is invoked only by command-line calls.
587  */
588  taskVarLock ();
589  for (v = taskVarHead ; v != NULL ; v = v->forw) {
590  if (strcmp (name, v->name) == 0) {
591  tid = v->id;
592  break;
593  }
594  }
595  taskVarUnlock ();
596  return (epicsThreadId)tid;
597 }
struct taskVar * forw
Definition: osdThread.c:48
rtems_id id
Definition: osdThread.c:51
#define NULL
Definition: catime.c:38
char * name
Definition: osdThread.c:50
epicsThreadId epicsThreadGetIdSelf ( void  )

Find an epicsThreadId associated with the current thread. For non-EPICS threads, a new epicsThreadId may be allocated.

Definition at line 510 of file osdThread.c.

511 {
512  rtems_id tid;
513 
514  rtems_task_ident (RTEMS_SELF, 0, &tid);
515  return (epicsThreadId)tid;
516 }
void epicsThreadGetName ( epicsThreadId  id,
char *  name,
size_t  size 
)

Copy out the thread name into the provided buffer.

Guaranteed to be null terminated. size is number of bytes in buffer to hold name (including terminator). Failure results in an empty string stored in name.

Definition at line 528 of file osdThread.c.

529 {
530  rtems_id tid = (rtems_id)id;
531  struct taskVar *v;
532  int haveName = 0;
533 
534  taskVarLock ();
535  for (v=taskVarHead ; v != NULL ; v=v->forw) {
536  if (v->id == tid) {
537  strncpy(name, v->name, size);
538  haveName = 1;
539  break;
540  }
541  }
542  taskVarUnlock ();
543  if (!haveName) {
544 #if (__RTEMS_MAJOR__>4 || \
545  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>8) || \
546  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==8 && __RTEMS_REVISION__>=99))
547  if (_Objects_Get_name_as_string((rtems_id)id, size, name) != NULL)
548  haveName = 1;
549 #else
550  /*
551  * Try to get the RTEMS task name
552  */
553  Thread_Control *thr;
554  Objects_Locations l;
555  if ((thr=_Thread_Get(tid, &l)) != NULL) {
556  if (OBJECTS_LOCAL == l) {
557  int length;
558  Objects_Information *oi = _Objects_Get_information(tid);
559  if (oi->name_length >= size)
560  length = size - 1;
561  else
562  length = oi->name_length;
563  if (oi->is_string)
564  strncpy(name, thr->Object.name, length);
565  else
566  _Objects_Copy_name_raw( &thr->Object.name, name, length);
567  name[length] = '\0';
568  haveName = 1;
569  }
570  _Thread_Enable_dispatch();
571  }
572 #endif
573  }
574  if (!haveName)
575  snprintf(name, size, "0x%lx", (long)tid);
576  name[size-1] = '\0';
577 }
struct taskVar * forw
Definition: osdThread.c:48
rtems_id id
Definition: osdThread.c:51
#define NULL
Definition: catime.c:38
int snprintf(char *str, size_t size, const char *format,...)
char * name
Definition: osdThread.c:50
const char* epicsThreadGetNameSelf ( void  )

Return the name of the current thread.

Returns
Never NULL. Storage lifetime tied to epicsThreadId.

This is either a copy of the string passed to epicsThread*Create*(), or an arbitrary unique string for non-EPICS threads.

Definition at line 518 of file osdThread.c.

519 {
520  uint32_t note;
521  struct taskVar *v;
522 
523  rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, &note);
524  v = (void *)note;
525  return v->name;
526 }
#define RTEMS_NOTEPAD_TASKVAR
Definition: osdThread.c:62
char * name
Definition: osdThread.c:50
int epicsThreadGetOsiPriorityValue ( int  ossPriority)

Definition at line 85 of file osdThread.c.

86 {
87  if (ossPriority < 100) {
89  }
90  else if (ossPriority > 199) {
92  }
93  else {
94  return (199u - (unsigned int)ossPriority);
95  }
96 }
#define epicsThreadPriorityMax
Definition: epicsThread.h:71
#define epicsThreadPriorityMin
Definition: epicsThread.h:72
int epicsThreadGetOssPriorityValue ( unsigned int  osiPriority)

Definition at line 98 of file osdThread.c.

99 {
100  if (osiPriority > 99) {
101  return 100;
102  }
103  else {
104  return (199 - (signed int)osiPriority);
105  }
106 }
unsigned int epicsThreadGetPriority ( epicsThreadId  id)

Return thread OSI priority

Definition at line 434 of file osdThread.c.

435 {
436  rtems_id tid = (rtems_id)id;
437  rtems_status_code sc;
438  rtems_task_priority pri;
439 
440  sc = rtems_task_set_priority (tid, RTEMS_CURRENT_PRIORITY, &pri);
441  if (sc != RTEMS_SUCCESSFUL)
442  errlogPrintf("epicsThreadGetPriority failed: %s\n",
443  rtems_status_text(sc));
444  return epicsThreadGetOsiPriorityValue(pri);
445 }
int epicsThreadGetOsiPriorityValue(int ossPriority)
Definition: osdThread.c:85
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
unsigned int epicsThreadGetPrioritySelf ( void  )

Return thread OSI priority

Definition at line 447 of file osdThread.c.

448 {
449  return epicsThreadGetPriority((epicsThreadId)RTEMS_SELF);
450 }
LIBCOM_API unsigned int epicsStdCall epicsThreadGetPriority(epicsThreadId pthreadInfo)
Definition: osdThread.c:701
unsigned int epicsThreadGetStackSize ( epicsThreadStackSizeClass  size)

Get a stack size value that can be given to epicsThreadCreate().

Parameters
sizeone of the values epicsThreadStackSmall, epicsThreadStackMedium or epicsThreadStackBig.

Definition at line 140 of file osdThread.c.

141 {
142  unsigned int stackSize = 11000;
143  switch(size) {
144  case epicsThreadStackSmall: stackSize = 5000; break;
145  case epicsThreadStackMedium: stackSize = 8000; break;
146  case epicsThreadStackBig: break;
147  default:
148  errlogPrintf("epicsThreadGetStackSize illegal argument");
149  break;
150  }
151  if (stackSize < RTEMS_MINIMUM_STACK_SIZE)
152  stackSize = RTEMS_MINIMUM_STACK_SIZE;
153  return stackSize;
154 }
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
LIBCOM_API epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow ( unsigned int  priority,
unsigned *  pPriorityJustBelow 
)

Lookup the next usage OSI priority such that priority > *pPriorityJustBelow if this is possible with the current target configuration and privlages.

Definition at line 128 of file osdThread.c.

129 {
130  unsigned newPriority = priority - 1;
131 
132  if (newPriority <= 99) {
133  *pPriorityJustBelow = newPriority;
135  }
137 }
int epicsThreadIsEqual ( epicsThreadId  id1,
epicsThreadId  id2 
)

Test if two thread IDs actually refer to the same OS thread

Definition at line 466 of file osdThread.c.

467 {
468  return (id1 == id2);
469 }
int epicsThreadIsSuspended ( epicsThreadId  id)

How and why a thread can be suspended is implementation dependent. A thread calling epicsThreadSuspendSelf() should result in this routine returning true for that thread, but a thread may also be suspended for other reasons.

Definition at line 472 of file osdThread.c.

473 {
474  rtems_id tid = (rtems_id)id;
475  rtems_status_code sc;
476 
477  switch (sc = rtems_task_is_suspended (tid)) {
478  case RTEMS_SUCCESSFUL:
479  return 0;
480 
481  case RTEMS_ALREADY_SUSPENDED:
482  return 1;
483 
484  default:
485  return 1;
486  }
487 }
LIBCOM_API epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove ( unsigned int  priority,
unsigned *  pPriorityJustAbove 
)

Lookup the next usage OSI priority such that priority < *pPriorityJustBelow if this is possible with the current target configuration and privlages.

Definition at line 112 of file osdThread.c.

113 {
114  unsigned newPriority = priority + 1;
115 
116  newPriority = priority + 1;
117  if (newPriority <= 99) {
118  *pPriorityJustAbove = newPriority;
120  }
122 }
void epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE  func)

Call func once for every known thread.

Definition at line 820 of file osdThread.c.

821 {
822  struct taskVar *v;
823 
824  taskVarLock ();
825  /*
826  * Map tasks in the order of creation (backwards through list)
827  */
828  for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw)
829  continue;
830  while (v) {
831  func ((epicsThreadId)v->id);
832  v = v->back;
833  }
834  taskVarUnlock ();
835 }
struct taskVar * forw
Definition: osdThread.c:48
rtems_id id
Definition: osdThread.c:51
#define NULL
Definition: catime.c:38
struct taskVar * back
Definition: osdThread.c:49
void epicsThreadMustJoin ( epicsThreadId  id)

Wait for a joinable thread to exit (return from its main function)

Definition at line 367 of file osdThread.c.

368 {
369  rtems_id target_tid = (rtems_id)id, self_tid;
370  struct taskVar *v = 0;
371 
372  rtems_task_ident (RTEMS_SELF, 0, &self_tid);
373 
374  {
375  uint32_t note;
376  rtems_task_get_note (target_tid, RTEMS_NOTEPAD_TASKVAR, &note);
377  v = (void *)note;
378  }
379  /* 'v' may be NULL if 'id' represents a non-EPICS thread other than _main_. */
380 
381  if(!v || !v->joinable) {
382  if(epicsThreadGetIdSelf()==id) {
383  errlogPrintf("Warning: %s thread self-join of unjoinable\n", v ? v->name : "non-EPICS thread");
384 
385  } else {
386  /* try to error nicely, however in all likelyhood de-ref of
387  * 'id' has already caused SIGSEGV as we are racing thread exit,
388  * which free's 'id'.
389  */
390  cantProceed("Error: %s thread not joinable.\n", v->name);
391  }
392  return;
393 
394  } else if(target_tid!=self_tid) {
395  /* wait for target to complete */
396  rtems_status_code sc = rtems_barrier_wait(v->join_barrier, RTEMS_NO_TIMEOUT);
397  if(sc!=RTEMS_SUCCESSFUL)
398  cantProceed("oopsj %s\n", rtems_status_text(sc));
399 
400  if(sc != RTEMS_SUCCESSFUL) {
401  errlogPrintf("epicsThreadMustJoin('%s') -> %s\n", v->name, rtems_status_text(sc));
402  }
403  }
404 
405  v->joinable = 0;
406  taskUnref(v);
407  /* target task may be deleted.
408  * self task is not deleted, even for self join.
409  */
410 }
#define RTEMS_NOTEPAD_TASKVAR
Definition: osdThread.c:62
rtems_id join_barrier
Definition: osdThread.c:52
rtems_id id
Definition: osdThread.c:51
int joinable
Definition: osdThread.c:54
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
LIBCOM_API void cantProceed(const char *msg,...)
Definition: cantProceed.c:54
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
char * name
Definition: osdThread.c:50
void epicsThreadOnce ( epicsThreadOnceId id,
void(*)(void *)  func,
void *  arg 
)

Definition at line 602 of file osdThread.c.

603 {
604  #define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1
605 
606  if (!initialized) epicsThreadInit();
607  epicsMutexOsdMustLock(onceMutex);
608  if (*id != EPICS_THREAD_ONCE_DONE) {
609  if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */
610  *id = epicsThreadGetIdSelf(); /* mark active */
611  epicsMutexOsdUnlock(onceMutex);
612  func(arg);
613  epicsMutexOsdMustLock(onceMutex);
614  *id = EPICS_THREAD_ONCE_DONE; /* mark done */
615  } else if (*id == epicsThreadGetIdSelf()) {
616  epicsMutexOsdUnlock(onceMutex);
617  cantProceed("Recursive epicsThreadOnce() initialization\n");
618  } else
619  while (*id != EPICS_THREAD_ONCE_DONE) {
620  /* Another thread is in the above func(arg) call. */
621  epicsMutexOsdUnlock(onceMutex);
623  epicsMutexOsdMustLock(onceMutex);
624  }
625  }
626  epicsMutexOsdUnlock(onceMutex);
627 }
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
LIBCOM_API double epicsStdCall epicsThreadSleepQuantum()
Query a value approximating the OS timer/scheduler resolution.
Definition: osdThread.c:981
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
#define EPICS_THREAD_ONCE_DONE
LIBCOM_API void cantProceed(const char *msg,...)
Definition: cantProceed.c:54
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
epicsThreadPrivateId epicsThreadPrivateCreate ( void  )

Allocate a new thread local variable. This variable will initially hold NULL for each thread.

Definition at line 633 of file osdThread.c.

634 {
635  unsigned int taskVarIndex;
636  static volatile unsigned int threadVariableCount = 0;
637 
638  if (!initialized) epicsThreadInit ();
639  taskVarLock ();
640  taskVarIndex = ++threadVariableCount;
641  taskVarUnlock ();
642  return (epicsThreadPrivateId)taskVarIndex;
643 }
void epicsThreadPrivateDelete ( epicsThreadPrivateId  id)

Free a thread local variable

Definition at line 645 of file osdThread.c.

646 {
647  /* empty */
648 }
void* epicsThreadPrivateGet ( epicsThreadPrivateId  )

Fetch the current value of a thread local variable

Definition at line 671 of file osdThread.c.

672 {
673  unsigned int varIndex = (unsigned int)id;
674  uint32_t note;
675  struct taskVar *v;
676 
677  rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, &note);
678  v = (struct taskVar *)note;
679  if (varIndex >= v->threadVariableCapacity)
680  return NULL;
681  return v->threadVariables[varIndex];
682 }
#define RTEMS_NOTEPAD_TASKVAR
Definition: osdThread.c:62
#define NULL
Definition: catime.c:38
void ** threadVariables
Definition: osdThread.c:58
unsigned int threadVariableCapacity
Definition: osdThread.c:57
void epicsThreadPrivateSet ( epicsThreadPrivateId  ,
void *   
)

Update thread local variable

Definition at line 650 of file osdThread.c.

651 {
652  unsigned int varIndex = (unsigned int)id;
653  uint32_t note;
654  struct taskVar *v;
655  int i;
656 
657  rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, &note);
658  v = (struct taskVar *)note;
659  if (varIndex >= v->threadVariableCapacity) {
660  v->threadVariables = realloc (v->threadVariables,
661  (varIndex + 1) * sizeof(void *));
662  if (v->threadVariables == NULL)
663  cantProceed("epicsThreadPrivateSet realloc failed\n");
664  for (i = v->threadVariableCapacity ; i < varIndex ; i++)
665  v->threadVariables[i] = NULL;
666  v->threadVariableCapacity = varIndex + 1;
667  }
668  v->threadVariables[varIndex] = pvt;
669 }
#define RTEMS_NOTEPAD_TASKVAR
Definition: osdThread.c:62
int i
Definition: scan.c:967
#define NULL
Definition: catime.c:38
void ** threadVariables
Definition: osdThread.c:58
LIBCOM_API void cantProceed(const char *msg,...)
Definition: cantProceed.c:54
unsigned int threadVariableCapacity
Definition: osdThread.c:57
void epicsThreadRealtimeLock ( void  )

When real-time scheduling is active, attempt any post-init operations that preserve real-time performance. For POSIX targets this locks the process into RAM, preventing swap-related VM faults.

Definition at line 301 of file osdThread.c.

302 {}
void epicsThreadResume ( epicsThreadId  id)

Resume a thread suspended with epicsThreadSuspendSelf()

Definition at line 423 of file osdThread.c.

424 {
425  rtems_id tid = (rtems_id)id;
426  rtems_status_code sc;
427 
428  sc = rtems_task_resume (tid);
429  if (sc != RTEMS_SUCCESSFUL)
430  errlogPrintf("epicsThreadResume failed: %s\n",
431  rtems_status_text (sc));
432 }
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
void epicsThreadSetPriority ( epicsThreadId  id,
unsigned int  priority 
)

Change OSI priority of target thread.

Definition at line 453 of file osdThread.c.

454 {
455  rtems_id tid = (rtems_id)id;
456  rtems_status_code sc;
457  rtems_task_priority pri = epicsThreadGetOssPriorityValue(osip);
458 
459  sc = rtems_task_set_priority (tid, pri, &pri);
460  if (sc != RTEMS_SUCCESSFUL)
461  errlogPrintf("epicsThreadSetPriority failed: %s\n",
462  rtems_status_text(sc));
463 }
int epicsThreadGetOssPriorityValue(unsigned int osiPriority)
Definition: osdThread.c:98
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
void epicsThreadShow ( epicsThreadId  id,
unsigned int  level 
)

Print info about a single EPICS thread.

Definition at line 800 of file osdThread.c.

801 {
802  struct taskVar *v;
803 
804  if (!id) {
805  epicsThreadShowInfo (NULL, level);
806  return;
807  }
808  taskVarLock ();
809  for (v = taskVarHead ; v != NULL ; v = v->forw) {
810  if ((rtems_id)id == v->id) {
811  epicsThreadShowInfo (v, level);
812  taskVarUnlock ();
813  return;
814  }
815  }
816  taskVarUnlock ();
817  fprintf(epicsGetStdout(),"*** Thread %x does not exist.\n", (unsigned int)id);
818 }
struct taskVar * forw
Definition: osdThread.c:48
rtems_id id
Definition: osdThread.c:51
#define NULL
Definition: catime.c:38
LIBCOM_API void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level)
FILE *epicsStdCall epicsGetStdout(void)
Definition: epicsStdio.c:47
void epicsThreadShowAll ( unsigned int  level)

Print to stdout information about all running EPICS threads.

Parameters
level0 prints minimal output. Higher values print more details.

Definition at line 837 of file osdThread.c.

838 {
839  struct taskVar *v;
840 
841  epicsThreadShowInfo (NULL, level);
842  taskVarLock ();
843  /*
844  * Show tasks in the order of creation (backwards through list)
845  */
846  for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw)
847  continue;
848  while (v) {
849  epicsThreadShowInfo (v, level);
850  v = v->back;
851  }
852  taskVarUnlock ();
853 }
struct taskVar * forw
Definition: osdThread.c:48
#define NULL
Definition: catime.c:38
LIBCOM_API void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level)
struct taskVar * back
Definition: osdThread.c:49
void epicsThreadSleep ( double  seconds)

Block the calling thread for at least the specified time.

Parameters
secondsTime to wait in seconds. Values <=0 blocks for the shortest possible time.

Definition at line 490 of file osdThread.c.

491 {
492  rtems_status_code sc;
493  rtems_interval delay;
494  extern double rtemsTicksPerSecond_double;
495 
496  if (seconds > 0.0) {
497  seconds *= rtemsTicksPerSecond_double;
498  seconds += 0.99999999; /* 8 9s here is optimal */
499  delay = (seconds >= INT_MAX) ? INT_MAX : (int) seconds;
500  }
501  else { /* seconds <= 0 or NAN */
502  delay = 0;
503  }
504  sc = rtems_task_wake_after (delay);
505  if(sc != RTEMS_SUCCESSFUL)
506  errlogPrintf("epicsThreadSleep: %s\n", rtems_status_text(sc));
507 }
double rtemsTicksPerSecond_double
Definition: osdTime.cpp:143
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
double epicsThreadSleepQuantum ( void  )

Query a value approximating the OS timer/scheduler resolution.

Returns
A value in seconds >=0
Warning
On targets other than vxWorks and RTEMS, the quantum value often isn't meaningful. Use of this function is discouraged in portable code.

Definition at line 855 of file osdThread.c.

856 {
857  extern double rtemsTicksPerSecond_double;
858 
859  return 1.0 / rtemsTicksPerSecond_double;
860 }
double rtemsTicksPerSecond_double
Definition: osdTime.cpp:143
void epicsThreadSuspendSelf ( void  )

Block the current thread until epicsThreadResume().

Definition at line 413 of file osdThread.c.

414 {
415  rtems_status_code sc;
416 
417  sc = rtems_task_suspend (RTEMS_SELF);
418  if (sc != RTEMS_SUCCESSFUL)
419  errlogPrintf("epicsThreadSuspendSelf failed: %s\n",
420  rtems_status_text(sc));
421 }
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
LIBCOM_API void osdThreadHooksRun ( epicsThreadId  id)

Definition at line 105 of file osdThreadHooks.c.

106 {
107  threadHookInit();
108 
109  if (epicsMutexLock(hookLock) == epicsMutexLockOK) {
110  epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList);
111 
112  while (pHook) {
113  pHook->func(id);
114  pHook = (epicsThreadHook *) ellNext(&pHook->node);
115  }
116  epicsMutexUnlock(hookLock);
117  }
118  else {
119  fprintf(stderr, "osdThreadHooksRun: Locking problem\n");
120  }
121 }
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
epicsMutexLockStatus epicsStdCall epicsMutexLock(epicsMutexId pmutexNode)
Claim the semaphore, waiting until it&#39;s free if currently owned owned by a different thread...
Definition: epicsMutex.cpp:145
#define stderr
Definition: epicsStdio.h:32
EPICS_THREAD_HOOK_ROUTINE func
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void osdThreadHooksRunMain ( epicsThreadId  id)

Definition at line 99 of file osdThreadHooks.c.

100 {
103 }
LIBCOM_API EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain
epicsThreadId threadMustCreate ( const char *  name,
unsigned int  priority,
unsigned int  stackSize,
EPICSTHREADFUNC  funptr,
void *  parm 
)

Definition at line 356 of file osdThread.c.

359 {
360  epicsThreadId tid = epicsThreadCreate(name, priority, stackSize, funptr, parm);
361 
362  if (tid == NULL)
363  cantProceed(0);
364  return tid;
365 }
#define NULL
Definition: catime.c:38
EPICSTHREADFUNC funptr
Definition: osdThread.c:55
epicsThreadId epicsStdCall epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
Definition: epicsThread.cpp:33
LIBCOM_API void cantProceed(const char *msg,...)
Definition: cantProceed.c:54
char * name
Definition: osdThread.c:50
void * parm
Definition: osdThread.c:56