Numerous modifications to track changes to OSI/OSD API.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* RTEMS osiThread.c
|
||||
* RTEMS osdThread.c
|
||||
* $Id$
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
@@ -15,26 +15,12 @@
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <avl.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user