Numerous modifications to track changes to OSI/OSD API.

This commit is contained in:
W. Eric Norum
2000-01-29 16:13:52 +00:00
parent 6064fc8385
commit bb656dbd6e
3 changed files with 50 additions and 245 deletions

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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);
}