diff --git a/src/libCom/osi/os/RTEMS/osdSem.c b/src/libCom/osi/os/RTEMS/osdSem.c index 1ea36146b..5928e0fa5 100644 --- a/src/libCom/osi/os/RTEMS/osdSem.c +++ b/src/libCom/osi/os/RTEMS/osdSem.c @@ -1,5 +1,5 @@ /* - * RTEMS osiSem.c + * RTEMS osdSem.c * $Id$ * Author: W. Eric Norum * eric@cls.usask.ca @@ -16,7 +16,7 @@ /* * Create a simple binary semaphore */ -semId +semBinaryId semBinaryCreate(int initialState) { rtems_status_code sc; @@ -47,21 +47,11 @@ semBinaryCreate(int initialState) c1++; } rtems_interrupt_enable (level); - return (semId)sid; -} - -semId -semBinaryMustCreate(int initialState) -{ - semId sid; - - if ((sid = semBinaryCreate (initialState)) == NULL) - cantProceed ("Can't create binary semaphore"); - return sid; + return (semBinaryId)sid; } void -semBinaryDestroy(semId id) +semBinaryDestroy(semBinaryId id) { rtems_id sid = (rtems_id)id; rtems_status_code sc; @@ -72,7 +62,7 @@ semBinaryDestroy(semId id) } void -semBinaryGive(semId id) +semBinaryGive(semBinaryId id) { rtems_id sid = (rtems_id)id; rtems_status_code sc; @@ -83,7 +73,7 @@ semBinaryGive(semId id) } semTakeStatus -semBinaryTake(semId id) +semBinaryTake(semBinaryId id) { rtems_id sid = (rtems_id)id; rtems_status_code sc; @@ -94,21 +84,8 @@ semBinaryTake(semId id) return semTakeOK; } -void -semBinaryMustTake(semId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't obtain semaphore: %s\n", rtems_status_text (sc)); - assert (sc == RTEMS_SUCCESSFUL); - } -} - semTakeStatus -semBinaryTakeTimeout(semId id, double timeOut) +semBinaryTakeTimeout(semBinaryId id, double timeOut) { rtems_id sid = (rtems_id)id; rtems_status_code sc; @@ -128,7 +105,7 @@ semBinaryTakeTimeout(semId id, double timeOut) } semTakeStatus -semBinaryTakeNoWait(semId id) +semBinaryTakeNoWait(semBinaryId id) { rtems_id sid = (rtems_id)id; rtems_status_code sc; @@ -143,11 +120,11 @@ semBinaryTakeNoWait(semId id) } void -semBinaryShow(semId id) +semBinaryShow(semBinaryId id) { } -semId +semMutexId semMutexCreate(void) { rtems_status_code sc; @@ -177,15 +154,5 @@ semMutexCreate(void) c1++; } rtems_interrupt_enable (level); - return (semId)sid; -} - -semId -semMutexMustCreate(void) -{ - semId sid; - - if ((sid = semMutexCreate) == NULL) - cantProceed ("Can't create mutex semaphore"); - return sid; + return (semMutexId)sid; } diff --git a/src/libCom/osi/os/RTEMS/osdSem.h b/src/libCom/osi/os/RTEMS/osdSem.h index 7f5089679..c9dbf379f 100644 --- a/src/libCom/osi/os/RTEMS/osdSem.h +++ b/src/libCom/osi/os/RTEMS/osdSem.h @@ -14,13 +14,36 @@ extern "C" { #include "shareLib.h" -#define semMutexDestroy semBinaryDestroy -#define semMutexGive semBinaryGive -#define semMutexTake semBinaryTake -#define semMutexMustTake semBinaryMustTake -#define semMutexTakeTimeout semBinaryTakeTimeout -#define semMutexTakeNoWait semBinaryTakeNoWait -#define semMutexShow semBinaryShow +epicsShareFunc INLINE void epicsShareAPI semMutexDestroy(semMutexId id) +{ + semBinaryDestroy (id); +} + +epicsShareFunc INLINE void epicsShareAPI semMutexGive(semMutexId id) +{ + semBinaryGive (id); +} + +epicsShareFunc INLINE semTakeStatus epicsShareAPI semMutexTake(semMutexId id) +{ + return semBinaryTake (id); +} + +epicsShareFunc INLINE semTakeStatus epicsShareAPI semMutexTakeTimeout( + semMutexId id, double timeOut) +{ + return semBinaryTakeTimeout (id, timeOut); +} + +epicsShareFunc INLINE semTakeStatus epicsShareAPI semMutexTakeNoWait(semMutexId id) +{ + return semBinaryTakeNoWait (id); +} + +epicsShareFunc void epicsShareAPI semMutexShow(semMutexId id) +{ + semBinaryShow (id); +} #ifdef __cplusplus } diff --git a/src/libCom/osi/os/RTEMS/osdThread.c b/src/libCom/osi/os/RTEMS/osdThread.c index 9f7f7ea8f..0c12d4841 100644 --- a/src/libCom/osi/os/RTEMS/osdThread.c +++ b/src/libCom/osi/os/RTEMS/osdThread.c @@ -1,5 +1,5 @@ /* - * RTEMS osiThread.c + * RTEMS osdThread.c * $Id$ * Author: W. Eric Norum * eric@cls.usask.ca @@ -15,26 +15,12 @@ #include #include -#include #include "errlog.h" #include "ellLib.h" #include "osiThread.h" #include "cantProceed.h" -/* - * This is one place where RTEMS needs a lot of help to implement - * the EPICS operating-system-specific routines. - * 1) RTEMS task names are at most 4 characters long. This is solved - * by using a binary tree (AVL) to map long task names to RTEMS - * task I.D. numbers. - * 2) RTEMS has no notion of task safe/unsafe states. The solution - * here is to add a semaphore which must be held before a task - * can be deleted. - * 3) RTEMS tasks do not destroy themselves when the entry function - * returns. A simple wrapper function fixes this problem - */ - /* * Per-task variables */ @@ -42,63 +28,8 @@ struct taskVars { char *name; THREADFUNC funptr; void *parm; - rtems_id taskSafeSemaphore; - rtems_id tid; }; -/* - * RTEMS task notepad assignments - */ -#define TASK_VARIABLE_NOTE_INDEX 12 - -/* - * Thread name lookup - */ -static rtems_id nameTableMutex; -static avl_tree *nameTable; - -static int -compare_names (const void *a, const void *b, void *param) -{ - const struct taskVars *da = a, *db = b; - int i; - - if ((i = db->name[0] - da->name[0]) == 0) - return strcmp (da->name, db->name); - return i; -} - -void -rtems_epics_task_init (void) -{ - rtems_status_code sc; - - sc = rtems_semaphore_create ( - rtems_build_name ('T', 'H', 'S', 'H'), - 1, - RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, - RTEMS_NO_PRIORITY, - &nameTableMutex); - if (sc != RTEMS_SUCCESSFUL) - rtems_panic ("No nametable mutex"); - nameTable = avl_create (compare_names, NULL); -} - -static rtems_id -tid_for_name (const char *name) -{ - struct taskVars entry, *e; - rtems_id tid = 0; - - rtems_semaphore_obtain (nameTableMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - entry.name = (char *)name; - e = avl_find (nameTable, &entry); - if (e) - tid = e->tid; - rtems_semaphore_release (nameTableMutex); - return tid; -} - /* Just map osi 0 to 99 into RTEMS 199 to 100 */ /* For RTEMS lower number means higher priority */ /* RTEMS = 100 + (99 - osi) = 199 - osi */ @@ -129,7 +60,8 @@ threadGetStackSize (threadStackSizeClass size) } /* - * The task wrapper + * EPICS threads destroy themselves by returning from the thread entry function. + * This simple wrapper provides the same semantics on RTEMS. */ static rtems_task threadWrapper (rtems_task_argument arg) @@ -137,7 +69,9 @@ threadWrapper (rtems_task_argument arg) struct taskVars *v = (struct taskVars *)arg; (*v->funptr)(v->parm); - threadDestroy (threadGetIdSelf ()); + free (v->name); + free (v); + rtems_task_delete (RTEMS_SELF); } /* @@ -149,21 +83,9 @@ threadCreate (const char *name, THREADFUNC funptr,void *parm) { struct taskVars *v; - rtems_id tid, safe; + rtems_id tid; rtems_status_code sc; char c[4]; - static volatile int initialized; - - if (!initialized) { - rtems_mode mode; - - rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode); - if (!initialized) { - rtems_epics_task_init (); - initialized = 1; - } - rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); - } if (stackSize < RTEMS_MINIMUM_STACK_SIZE) { errlogPrintf ("threadCreate %s illegal stackSize %d\n",name,stackSize); @@ -180,30 +102,11 @@ threadCreate (const char *name, errlogPrintf ("threadCreate create failure for %s: %s\n",name, rtems_status_text (sc)); return 0; } - sc = rtems_semaphore_create (rtems_build_name (c[0], c[1], c[2], c[3]), - 1, - RTEMS_FIFO|RTEMS_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL, - 0, - &safe); - if (sc != RTEMS_SUCCESSFUL) { - rtems_task_delete (tid); - errlogPrintf("threadCreate create semaphore failure for %s: %s\n",name, rtems_status_text (sc)); - return 0; - } - v = mallocMustSucceed (sizeof *v, "threadCreate_vars"); v->name = mallocMustSucceed (strlen (name) + 1, "threadCreate_name"); strcpy (v->name, name); - v->tid = tid; - v->taskSafeSemaphore = safe; - - rtems_semaphore_obtain (nameTableMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - avl_insert (nameTable, v); - rtems_semaphore_release (nameTableMutex); - v->funptr = funptr; v->parm = parm; - rtems_task_set_note (tid, TASK_VARIABLE_NOTE_INDEX, (rtems_unsigned32)v); rtems_task_start (tid, threadWrapper, (rtems_task_argument)v); return (threadId)tid; } @@ -220,38 +123,6 @@ threadMustCreate (const char *name, return tid; } -/* - * Destroy a thread - */ -void -threadDestroy (threadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_unsigned32 nv; - struct taskVars *v; - int deleted = 0; - rtems_status_code sc; - - rtems_task_get_note (tid, TASK_VARIABLE_NOTE_INDEX, &nv); - v = (struct taskVars *)nv; - assert (tid == v->tid); - rtems_semaphore_obtain (v->taskSafeSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if ((tid != RTEMS_SELF) && (tid != (rtems_id)threadGetIdSelf())) { - /* FIXME: Should probably obtain the network semaphore here! */ - rtems_task_delete (tid); - deleted = 1; - } - rtems_semaphore_obtain (nameTableMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - avl_delete (nameTable, v); - rtems_semaphore_release (nameTableMutex); - rtems_semaphore_release (v->taskSafeSemaphore); - rtems_semaphore_delete (v->taskSafeSemaphore); - free (v->name); - free (v); - if (!deleted) - sc = rtems_task_delete (tid); -} - void threadSuspend (threadId id) { @@ -273,7 +144,7 @@ void threadResume(threadId id) errlogPrintf("threadResume failed: %s\n", rtems_status_text (sc)); } -int threadGetPriority(threadId id) +unsigned int threadGetPriority(threadId id) { rtems_id tid = (rtems_id)id; rtems_status_code sc; @@ -286,7 +157,7 @@ int threadGetPriority(threadId id) } void -threadSetPriority (threadId id,int osip) +threadSetPriority (threadId id,unsigned int osip) { rtems_id tid = (rtems_id)id; rtems_status_code sc; @@ -297,40 +168,6 @@ threadSetPriority (threadId id,int osip) errlogPrintf("threadSetPriority failed\n", rtems_status_text (sc)); } -void -threadSetDestroySafe (void) -{ - rtems_unsigned32 nv; - struct taskVars *v; - - rtems_task_get_note (RTEMS_SELF, TASK_VARIABLE_NOTE_INDEX, &nv); - v = (struct taskVars *)nv; - rtems_semaphore_obtain (v->taskSafeSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); -} - -void -threadSetDestroyUnsafe (void) -{ - rtems_unsigned32 nv; - struct taskVars *v; - - rtems_task_get_note (RTEMS_SELF, TASK_VARIABLE_NOTE_INDEX, &nv); - v = (struct taskVars *)nv; - rtems_semaphore_release (v->taskSafeSemaphore); -} - -const char * -threadGetName (threadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_unsigned32 nv; - struct taskVars *v; - - rtems_task_get_note (tid, TASK_VARIABLE_NOTE_INDEX, &nv); - v = (struct taskVars *)nv; - return (v->name); -} - int threadIsEqual (threadId id1, threadId id2) { @@ -383,25 +220,3 @@ threadGetIdSelf (void) rtems_task_ident (RTEMS_SELF, 0, &tid); return (threadId)tid; } - -void -threadLockContextSwitch (void) -{ - rtems_mode oldMode; - - rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &oldMode); -} - -void -threadUnlockContextSwitch (void) -{ - rtems_mode oldMode; - - rtems_task_mode (RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &oldMode); -} - -threadId -threadNameToId (const char *name) -{ - return (threadId)tid_for_name (name); -}