renamed files

This commit is contained in:
Jeff Hill
2000-01-28 02:24:14 +00:00
parent d184d47a67
commit d16b7ddfb9
23 changed files with 1703 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
/*
* RTEMS osiInterrupt.c
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
#include <syslog.h>
#include <rtems.h>
#include <rtems/error.h>
#include "errlog.h"
#define INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT 100
static rtems_id interruptContextMessageQueue;
int
interruptLock (void)
{
rtems_interrupt_level level;
rtems_interrupt_disable (level);
return level;
}
void
interruptUnlock (int key)
{
rtems_interrupt_level level = key;
rtems_interrupt_enable (level);
}
int
interruptIsInterruptContext (void)
{
return rtems_interrupt_is_in_progress ();
}
/*
* Pass a message from an interrupt context.
* Note that this passes a pointer to the message, not the message itself.
* This implies that the message must remain valid after the
* interrupt context is no longer active.
*/
void
interruptContextMessage (const char *message)
{
rtems_message_queue_send (interruptContextMessageQueue, &message, sizeof message);
}
/*
* Daemon to process interrupt context messages
*/
rtems_task
InterruptContextMessageDaemon (rtems_task_argument arg)
{
const char *message;
rtems_unsigned32 size;
rtems_status_code sc;
sc = rtems_message_queue_create (rtems_build_name ('I', 'C', 'M', 'Q'),
INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT,
sizeof message,
RTEMS_FIFO | RTEMS_LOCAL,
&interruptContextMessageQueue);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf ("Can't create interrupt context message queue: %s\n", rtems_status_text (sc));
rtems_task_suspend (RTEMS_SELF);
}
for (;;) {
sc = rtems_message_queue_receive (interruptContextMessageQueue,
&message,
&size,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf ("Can't receive message from interrupt context: %s\n", rtems_status_text (sc));
rtems_task_suspend (RTEMS_SELF);
}
if (size == sizeof message)
syslog (LOG_ERR, "%s", message);
else
errlogPrintf ("Received %d-byte message from interrupt context", size);
}
}

View File

@@ -0,0 +1,11 @@
/*
* RTEMS osiInterrupt.h
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
int interruptLock (void);
void interruptUnlock (int key);
int interruptIsInterruptContext (void);
void interruptContextMessage (const char *message);

View File

@@ -0,0 +1,191 @@
/*
* RTEMS osiSem.c
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
#include <assert.h>
#include <rtems.h>
#include <rtems/error.h>
#include "osiSem.h"
#include "errlog.h"
/*
* Create a simple binary semaphore
*/
semId
semBinaryCreate(int initialState)
{
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
sc = rtems_semaphore_create (rtems_build_name ('S', 'B', c2, c1),
initialState,
RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
0,
&sid);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf ("Can't create binary semaphore: %s\n", rtems_status_text (sc));
return NULL;
}
rtems_interrupt_disable (level);
if (c1 == 'z') {
if (c2 == 'z')
c2 = 'a';
else
c2++;
c1 = 'a';
}
else {
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;
}
void
semBinaryDestroy(semId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_semaphore_delete (sid);
if (sc != RTEMS_SUCCESSFUL)
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
}
void
semBinaryGive(semId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_semaphore_release (sid);
if (sc != RTEMS_SUCCESSFUL)
errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
}
semTakeStatus
semBinaryTake(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)
return semTakeError;
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)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
rtems_interval delay;
extern double rtemsTicksPerSecond_double;
delay = timeOut * rtemsTicksPerSecond_double;
if (delay == 0)
delay = 1;
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
if (sc == RTEMS_SUCCESSFUL)
return semTakeOK;
else if (sc == RTEMS_TIMEOUT)
return semTakeTimeout;
else
return semTakeError;
}
semTakeStatus
semBinaryTakeNoWait(semId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
if (sc == RTEMS_SUCCESSFUL)
return semTakeOK;
else if (sc == RTEMS_TIMEOUT)
return semTakeTimeout;
else
return semTakeError;
}
void
semBinaryShow(semId id)
{
}
semId
semMutexCreate(void)
{
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
sc = rtems_semaphore_create (rtems_build_name ('S', 'M', c2, c1),
1,
RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY |RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
0,
&sid);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc));
return NULL;
}
rtems_interrupt_disable (level);
if (c1 == 'z') {
if (c2 == 'z')
c2 = 'a';
else
c2++;
c1 = 'a';
}
else {
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;
}

View File

@@ -0,0 +1,407 @@
/*
* RTEMS osiThread.c
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <assert.h>
#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
*/
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 */
/* osi = 199 - RTEMS */
int threadGetOsiPriorityValue(int ossPriority)
{
return (199 - ossPriority);
}
int threadGetOssPriorityValue(int osiPriority)
{
return (199 - osiPriority);
}
#define ARCH_STACK_FACTOR 2
unsigned int
threadGetStackSize (threadStackSizeClass size)
{
switch(size) {
case threadStackSmall: return( 4000*ARCH_STACK_FACTOR);
case threadStackMedium: return( 6000*ARCH_STACK_FACTOR);
case threadStackBig: return(11000*ARCH_STACK_FACTOR);
default:
errlogPrintf("threadGetStackSize illegal argument");
}
return(11000*ARCH_STACK_FACTOR);
}
/*
* The task wrapper
*/
static rtems_task
threadWrapper (rtems_task_argument arg)
{
struct taskVars *v = (struct taskVars *)arg;
(*v->funptr)(v->parm);
threadDestroy (threadGetIdSelf ());
}
/*
* Create and start a new thread
*/
threadId
threadCreate (const char *name,
unsigned int priority, unsigned int stackSize,
THREADFUNC funptr,void *parm)
{
struct taskVars *v;
rtems_id tid, safe;
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);
return 0;
}
strncpy (c, name, sizeof c);
sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]),
threadGetOssPriorityValue (priority),
stackSize,
RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
RTEMS_FLOATING_POINT|RTEMS_LOCAL,
&tid);
if (sc != RTEMS_SUCCESSFUL) {
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;
}
threadId
threadMustCreate (const char *name,
unsigned int priority, unsigned int stackSize,
THREADFUNC funptr,void *parm)
{
threadId tid;
if ((tid = threadCreate (name, priority, stackSize, funptr, parm)) == NULL)
cantProceed (0);
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)
{
rtems_id tid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_task_suspend (tid);
if(sc != RTEMS_SUCCESSFUL)
errlogPrintf("threadSuspend failed: %s\n", rtems_status_text (sc));
}
void threadResume(threadId id)
{
rtems_id tid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_task_resume (tid);
if(sc != RTEMS_SUCCESSFUL)
errlogPrintf("threadResume failed: %s\n", rtems_status_text (sc));
}
int threadGetPriority(threadId id)
{
rtems_id tid = (rtems_id)id;
rtems_status_code sc;
rtems_task_priority pri;
sc = rtems_task_set_priority (tid, RTEMS_CURRENT_PRIORITY, &pri);
if (sc != RTEMS_SUCCESSFUL)
errlogPrintf("threadGetPriority failed: %s\n", rtems_status_text (sc));
return threadGetOsiPriorityValue (pri);
}
void
threadSetPriority (threadId id,int osip)
{
rtems_id tid = (rtems_id)id;
rtems_status_code sc;
rtems_task_priority pri = threadGetOssPriorityValue(osip);
sc = rtems_task_set_priority (tid, pri, &pri);
if (sc != RTEMS_SUCCESSFUL)
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)
{
return (id1 == id2);
}
int
threadIsSuspended (threadId id)
{
rtems_id tid = (rtems_id)id;
rtems_status_code sc;
switch (sc = rtems_task_is_suspended (tid)) {
case RTEMS_SUCCESSFUL:
return 0;
case RTEMS_ALREADY_SUSPENDED:
return 1;
default:
errlogPrintf("threadIsSuspended: %s\n", rtems_status_text (sc));
return 0;
}
}
int
threadIsReady (threadId id)
{
return !threadIsSuspended(id);
}
void
threadSleep (double seconds)
{
rtems_status_code sc;
rtems_interval delay;
extern double rtemsTicksPerSecond_double;
delay = seconds * rtemsTicksPerSecond_double;
sc = rtems_task_wake_after (delay);
if(sc != RTEMS_SUCCESSFUL)
errlogPrintf("threadSleep: %s\n", rtems_status_text (sc));
}
threadId
threadGetIdSelf (void)
{
rtems_id tid;
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);
}

View File

@@ -0,0 +1,82 @@
/* $Id$
* assertUNIX.c
* Author: Jeffrey Hill
* Date: 02-27-95
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define epicsExportSharedSymbols
#include "dbDefs.h"
#include "epicsPrint.h"
#include "epicsVersion.h"
#include "epicsAssert.h"
#include "cantProceed.h"
/*
* epicsAssert ()
*/
epicsShareFunc void epicsShareAPI
epicsAssert (const char *pFile, const unsigned line,
const char *pExp, const char *pAuthorName)
{
epicsPrintf (
"\n\n\nA call to \"assert (%s)\" failed in %s line %d.\n", pExp, pFile, line);
epicsPrintf (
"The file \"core\" will be created in the current working directory.\n");
epicsPrintf (
"Please save this file and the text of this message in order to assist\n");
epicsPrintf (
"in diagnosing this problem.\n");
if (pAuthorName) {
epicsPrintf (
"Please send the text of this message to \"%s\"\n", pAuthorName);
epicsPrintf (
"(the author of this call to assert()) or to \"tech-talk@aps.anl.gov\"\n");
}
else {
epicsPrintf (
"Please contact the author of this software or else send the text of\n");
epicsPrintf (
"this message to \"tech-talk@aps.anl.gov\"\n");
}
epicsPrintf ("This problem occurred in \"%s\"\n", epicsReleaseVersion);
cantProceed ("assert fail");
}

View File

@@ -0,0 +1,6 @@
/* osi/osiFindGlobalSymbol.c */
#define epicsExportSharedSymbols
#include "osiFindGlobalSymbol.h"
epicsShareFunc void * epicsShareAPI osiFindGlobalSymbol(const char *name) { return 0;}

View File

@@ -0,0 +1,5 @@
#ifdef osdFindGlobalSymbolh
#define osdFindGlobalSymbolh
#endif /* osdFindGlobalSymbolh */

View File

@@ -0,0 +1,47 @@
/* osi/osiInterrupt.c */
/* Author: Marty Kraimer Date: 15JUL99 */
/********************COPYRIGHT NOTIFICATION**********************************
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
****************************************************************************/
/* This is a version that does not allow osi calls at interrupt level */
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#define epicsExportSharedSymbols
#include "osiSem.h"
#include "cantProceed.h"
#include "errlog.h"
#include "osiInterrupt.h"
static semId globalLock=0;
static int firstTime = 1;
epicsShareFunc int epicsShareAPI interruptLock()
{
if(firstTime) globalLock = semMutexMustCreate();
semMutexMustTake(globalLock);
return(0);
}
epicsShareFunc void epicsShareAPI interruptUnlock(int key)
{
if(firstTime) cantProceed("interruptUnlock called before interruptLock\n");
semMutexGive(globalLock);
}
epicsShareFunc int epicsShareAPI interruptIsInterruptContext() { return(0);}
epicsShareFunc void epicsShareAPI interruptContextMessage(const char *message)
{
errlogPrintf("%s",message);
}

View File

@@ -0,0 +1,5 @@
#ifndef osdInterrupth
#define osdInterrupth
#endif /* osdInterrupth */

View File

@@ -0,0 +1,14 @@
#define epicsExportSharedSymbols
#include "osiPoolStatus.h"
/*
* osiSufficentSpaceInPool ()
*
* @@@@@ not implemented @@@@@
*
*/
epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ()
{
return 1;
}

View File

@@ -0,0 +1,5 @@
#ifndef osdPoolStatush
#define osdPoolStatush
#endif /* osdPoolStatush */

View File

@@ -0,0 +1,190 @@
/* $Id$ */
/* Author: Marty Kraimer Date: 15JUL99 */
/********************COPYRIGHT NOTIFICATION**********************************
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
****************************************************************************/
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#define epicsExportSharedSymbols
#include "dbDefs.h"
#include "cantProceed.h"
#include "osiInterrupt.h"
#include "osiRing.h"
typedef struct ringPvt {
int size;
int nextGet;
int nextPut;
int isFull;
char *buffer;
}ringPvt;
epicsShareFunc ringId epicsShareAPI ringCreate(int size)
{
ringPvt *pring = callocMustSucceed(1,sizeof(ringPvt),"ringCreate");
pring->size = size;
pring->buffer = callocMustSucceed(size,sizeof(char),"ringCreate");
return((void *)pring);
}
epicsShareFunc void epicsShareAPI ringDelete(ringId id)
{
ringPvt *pring = (ringPvt *)id;
free((void *)pring->buffer);
free((void *)pring);
}
epicsShareFunc int epicsShareAPI ringGet(ringId id, char *value,int nbytes)
{
ringPvt *pring = (ringPvt *)id;
int nextGet = pring->nextGet;
int nextPut = pring->nextPut;
int size = pring->size;
int nToGet;
int lockKey;
if(nextGet < nextPut) {
if(nbytes > (nextPut - nextGet)) return(0);
memcpy(value,&pring->buffer[nextGet],nbytes);
nextGet += nbytes;
if(nextGet>=size) nextGet = 0;
lockKey = interruptLock();
pring->nextGet = nextGet;
pring->isFull = 0;
interruptUnlock(lockKey);
return(nbytes);
}
if(nextGet==nextPut && !pring->isFull ) return(0);
if(nbytes > (nextPut + (size - nextGet))) return(0);
nToGet = size - nextGet;
if(nToGet>nbytes) nToGet = nbytes;
memcpy(value,&pring->buffer[nextGet],nToGet);
value += nToGet;
nextGet += nToGet;
nToGet = nbytes - nToGet;
if(nToGet>0) {
nextGet = 0;
memcpy(value,&pring->buffer[0],nToGet);
nextGet += nToGet;
}
if(nextGet>=size) nextGet = 0;
lockKey = interruptLock();
pring->nextGet = nextGet;
pring->isFull = 0;
interruptUnlock(lockKey);
return(nbytes);
}
epicsShareFunc int epicsShareAPI ringPut(ringId id, char *value,int nbytes)
{
ringPvt *pring = (ringPvt *)id;
int nextGet = pring->nextGet;
int nextPut = pring->nextPut;
int size = pring->size;
int nToPut;
int lockKey;
if(nextPut < nextGet) {
if(nbytes > (nextGet - nextPut)) return(0);
memcpy(&pring->buffer[nextPut],value,nbytes);
nextPut += nbytes;
if(nextPut>=size) nextPut = 0;
lockKey = interruptLock();
pring->nextPut = nextPut;
if(nextPut==nextGet) pring->isFull = 1;
interruptUnlock(lockKey);
return(nbytes);
}
if(nextGet==nextPut && pring->isFull ) return(0);
if(nbytes > (nextGet + (size - nextPut))) return(0);
nToPut = size - nextPut;
if(nToPut>nbytes) nToPut = nbytes;
memcpy(&pring->buffer[nextPut],value,nToPut);
value += nToPut;
nextPut += nToPut;
nToPut = nbytes - nToPut;
if(nToPut>0) {
nextPut = 0;
memcpy(&pring->buffer[0],value,nToPut);
nextPut += nToPut;
}
if(nextPut>=size) nextPut = 0;
lockKey = interruptLock();
pring->nextPut = nextPut;
if(nextPut==nextGet) pring->isFull = 1;
interruptUnlock(lockKey);
return(nbytes);
}
epicsShareFunc void epicsShareAPI ringFlush(ringId id)
{
ringPvt *pring = (ringPvt *)id;
int lockKey;
lockKey = interruptLock();
pring->nextGet = pring->nextPut = 0;
pring->isFull = 0;
interruptUnlock(lockKey);
}
epicsShareFunc int epicsShareAPI ringFreeBytes(ringId id)
{
ringPvt *pring = (ringPvt *)id;
int n;
int lockKey;
lockKey = interruptLock();
n = pring->nextGet - pring->nextPut;
if(n<=0) n += pring->size;
if(pring->isFull) n = 0;
interruptUnlock(lockKey);
return(n);
}
epicsShareFunc int epicsShareAPI ringUsedBytes(ringId id)
{
ringPvt *pring = (ringPvt *)id;
int n;
int lockKey;
lockKey = interruptLock();
n = pring->nextPut - pring->nextGet;
if(n<0) n += pring->size;
if(pring->isFull) n = pring->size;
interruptUnlock(lockKey);
return(n);
}
epicsShareFunc int epicsShareAPI ringSize(ringId id)
{
ringPvt *pring = (ringPvt *)id;
return(pring->size);
}
epicsShareFunc int epicsShareAPI ringIsEmpty(ringId id)
{
ringPvt *pring = (ringPvt *)id;
int lockKey;
int result;
lockKey = interruptLock();
result = (pring->nextGet==pring->nextPut && !pring->isFull) ? TRUE : FALSE;
interruptUnlock(lockKey);
return(result);
}
epicsShareFunc int epicsShareAPI ringIsFull(ringId id)
{
ringPvt *pring = (ringPvt *)id;
return(pring->isFull);
}

View File

@@ -0,0 +1,5 @@
#ifndef osdRingh
#define osdRingh
#endif /* osdRingh */

View File

@@ -0,0 +1,11 @@
#define epicsExportSharedSymbols
#include "osiSigPipeIgnore.h"
/*
* NOOP
*/
epicsShareFunc void epicsShareAPI installSigPipeIgnore (void)
{
}

View File

@@ -0,0 +1,5 @@
#ifndef osdSigPipeIgnoreh
#define osdSigPipeIgnoreh
#endif /* osdSigPipeIgnoreh */

View File

@@ -0,0 +1,237 @@
/* osiSem.c */
/* Author: Marty Kraimer Date: 13AUG1999 */
/********************COPYRIGHT NOTIFICATION**********************************
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
****************************************************************************/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include "osiSem.h"
#include "cantProceed.h"
#include "errlog.h"
typedef struct cond {
pthread_mutex_t mutex;
pthread_cond_t condition;
}cond;
typedef struct mutex {
pthread_mutexattr_t attr;
pthread_mutex_t lock; /*lock for structure */
pthread_cond_t waitToBeOwner;
int count;
int owned; /* TRUE | FALSE */
pthread_t ownerTid;
}mutex;
semId semBinaryCreate(int initialState)
{
cond *pcond;
int status;
pcond = callocMustSucceed(1,sizeof(cond),"semBinaryCreate");
status = pthread_mutex_init(&pcond->mutex,0);
if(status) {
errlogPrintf("pthread_mutex_init failed: error %s\n",
strerror(status));
cantProceed("semBinaryCreate");
}
status = pthread_cond_init(&pcond->condition,0);
if(status) {
errlogPrintf("pthread_cond_init failed: error %s\n",
strerror(status));
cantProceed("semBinaryCreate");
}
return((semId)pcond);
}
void semBinaryDestroy(semId id)
{
cond *pcond = (cond *)id;
int status;
status = pthread_mutex_destroy(&pcond->mutex);
if(status) errlogPrintf("pthread_mutex_destroy error %s\n",strerror(status));
status = pthread_cond_destroy(&pcond->condition);
if(status) errlogPrintf("pthread_cond_destroy error %s\n",strerror(status));
free(pcond);
}
void semBinaryGive(semId id)
{
cond *pcond = (cond *)id;
int status;
status = pthread_cond_signal(&pcond->condition);
if(status) errlogPrintf("pthread_cond_signal error %s\n",strerror(status));
}
semTakeStatus semBinaryTake(semId id)
{
cond *pcond = (cond *)id;
int status;
status = pthread_cond_wait(&pcond->condition,&pcond->mutex);
if(status) errlogPrintf("pthread_cond_wait error %s\n",strerror(status));
if(status) return(semTakeError);
return(semTakeOK);
}
semTakeStatus semBinaryTakeTimeout(semId id, double timeOut)
{
cond *pcond = (cond *)id;
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
struct timespec wait;
int status;
wait.tv_sec = timeOut;
wait.tv_nsec = (long)((timeOut - (double)wait.tv_sec) * 1e9);
status = pthread_cond_timedwait(
&pcond->condition,&pcond->mutex,&wait);
if(status==ETIMEDOUT) return(semTakeTimeout);
if(status) errlogPrintf("pthread_cond_wait error %s\n",strerror(status));
return(0);
}
semTakeStatus semBinaryTakeNoWait(semId id)
{
return(semBinaryTakeTimeout(id,0.0));
}
void semBinaryShow(semId id)
{
}
semId semMutexCreate(void) {
mutex *pmutex;
int status;
pmutex = callocMustSucceed(1,sizeof(mutex),"semMutexCreate");
status = pthread_mutexattr_init(&pmutex->attr);
if(status) {
errlogPrintf("pthread_mutexattr_init failed: error %s\n",
strerror(status));
cantProceed("semMutexCreate");
}
#ifdef PTHREAD_PRIO_INHERIT
status = pthread_mutexattr_setprotocol(&pmutex->attr,PTHREAD_PRIO_INHERIT);
if(status) {
errlogPrintf("pthread_mutexattr_setprotocal failed: error %s\n",
strerror(status));
}
#endif
status = pthread_mutex_init(&pmutex->lock,&pmutex->attr);
if(status) {
errlogPrintf("pthread_mutex_init failed: error %s\n",
strerror(status));
cantProceed("semMutexCreate");
}
status = pthread_cond_init(&pmutex->waitToBeOwner,0);
if(status) {
errlogPrintf("pthread_cond_init failed: error %s\n",
strerror(status));
cantProceed("semMutexCreate");
}
return((semId)pmutex);
}
void semMutexDestroy(semId id)
{
mutex *pmutex = (mutex *)id;
int status;
status = pthread_mutex_destroy(&pmutex->lock);
if(status) errlogPrintf("pthread_mutex_destroy error %s\n",strerror(status));
status = pthread_cond_destroy(&pmutex->waitToBeOwner);
if(status) errlogPrintf("pthread_cond_destroy error %s\n",strerror(status));
status = pthread_mutexattr_destroy(&pmutex->attr);
if(status) errlogPrintf("pthread_mutexattr_destroy error %s\n",strerror(status));
free(pmutex);
}
void semMutexGive(semId id)
{
mutex *pmutex = (mutex *)id;
pthread_mutex_lock(&pmutex->lock);
pmutex->count--;
if(pmutex->count == 0) {
pmutex->owned = 0;
pmutex->ownerTid = 0;
pthread_cond_signal(&pmutex->waitToBeOwner);
}
pthread_mutex_unlock(&pmutex->lock);
}
semTakeStatus semMutexTake(semId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
pthread_mutex_lock(&pmutex->lock);
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid))
pthread_cond_wait(&pmutex->waitToBeOwner,&pmutex->lock);
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
pthread_mutex_unlock(&pmutex->lock);
return(0);
}
semTakeStatus semMutexTakeTimeout(semId id, double timeOut)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
struct timespec wait;
wait.tv_sec = timeOut;
wait.tv_nsec = (long)((timeOut - (double)wait.tv_sec) * 1e9);
pthread_mutex_lock(&pmutex->lock);
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) {
int status;
status = pthread_cond_timedwait(
&pmutex->waitToBeOwner,&pmutex->lock,&wait);
if(!status) break;
if(status==ETIMEDOUT) return(semTakeTimeout);
return(semTakeError);
}
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
pthread_mutex_unlock(&pmutex->lock);
return(0);
}
semTakeStatus semMutexTakeNoWait(semId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
semTakeStatus status = semTakeError;
pthread_mutex_lock(&pmutex->lock);
if(!pmutex->owned || pthread_equal(pmutex->ownerTid,tid)) {
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
status = 0;
}
pthread_mutex_unlock(&pmutex->lock);
return(status);
}
void semMutexShow(semId id)
{
mutex *pmutex = (mutex *)id;
printf("ownerTid %p count %d owned %d\n",
pmutex->ownerTid,pmutex->count,pmutex->owned);
}

View File

@@ -0,0 +1 @@
/* for a pure posix implementation no osdSem.h definitions are needed*/

View File

@@ -0,0 +1,80 @@
/*
* install NOOP SIGPIPE handler
*
* escape into C to call signal because of a brain dead
* signal() func proto supplied in signal.h by gcc 2.7.2
*/
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define epicsExportSharedSymbols
#include "osiSigPipeIgnore.h"
typedef void (*pSigFunc) ();
static pSigFunc pReplacedFunc;
static void localInstallSigPipeIgnore (void);
/*
* ignoreSigPipe ()
*/
static void ignoreSigPipe (int param)
{
if (pReplacedFunc) {
(*pReplacedFunc) (param);
}
/*
* some versios of unix reset to SIG_DFL
* each time that the signal occurs
*/
localInstallSigPipeIgnore ();
}
/*
* installSigPipeIgnore ()
*/
epicsShareFunc void epicsShareAPI installSigPipeIgnore (void)
{
static int init;
if (init) {
return;
}
localInstallSigPipeIgnore();
init = 1;
}
/*
* localInstallSigPipeIgnore ()
*
* dont allow disconnect to terminate process
* when running in UNIX environment
*
* allow error to be returned to sendto()
* instead of handling disconnect at interrupt
*/
static void localInstallSigPipeIgnore (void)
{
pSigFunc sigRet;
sigRet = signal (SIGPIPE, ignoreSigPipe);
if (sigRet==SIG_ERR) {
fprintf (stderr, "%s replace of SIGPIPE failed beacuse %s\n",
__FILE__, strerror(errno));
}
else if (sigRet!=SIG_DFL && sigRet!=SIG_IGN) {
pReplacedFunc = sigRet;
}
/*
* no infinite loops
*/
if (pReplacedFunc==ignoreSigPipe) {
pReplacedFunc = NULL;
}
}

View File

@@ -0,0 +1,7 @@
#ifndef osdSigPipeIgnoreh
#define osdSigPipeIgnoreh
#edndif /* osdSigPipeIgnoreh */

View File

@@ -0,0 +1,225 @@
/* osiThread.c */
/* Author: Marty Kraimer Date: 18JAN2000 */
/********************COPYRIGHT NOTIFICATION**********************************
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
****************************************************************************/
/* This is a posix implementation of osiThread */
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include <sched.h>
#include "osiThread.h"
#include "osiSem.h"
#include "cantProceed.h"
#include "errlog.h"
static int firstTime = 1;
static pthread_key_t getpthreadInfo;
typedef struct threadInfo {
pthread_t tid;
pthread_attr_t attr;
struct sched_param schedParam;
THREADFUNC createFunc;
void *createArg;
semId suspendSem;
int isSuspended;
int maxPriority;
int minPriority;
unsigned int osiPriority;
int schedPolicy;
} threadInfo;
static void * start_routine(void *arg)
{
threadInfo *pthreadInfo = (threadInfo *)arg;
pthread_setspecific(getpthreadInfo,arg);
(*pthreadInfo->createFunc)(pthreadInfo->createArg);
semBinaryDestroy(pthreadInfo->suspendSem);
pthread_attr_destroy(&pthreadInfo->attr);
free(pthreadInfo);
return(0);
}
static int getOssPriorityValue(threadInfo *pthreadInfo)
{
int maxPriority = pthreadInfo->maxPriority;
int minPriority = pthreadInfo->minPriority;
double slope,oss;
int ossInteger;
if(maxPriority==minPriority) return(maxPriority);
slope = (double)(maxPriority - minPriority)/100.0;
oss = (double)pthreadInfo->osiPriority * slope;
if(minPriority<maxPriority) oss = minPriority +(double)(oss + .5);
else oss = maxPriority - (oss - .5);
return(oss);
}
#if CPU_FAMILY == MC680X0
#define ARCH_STACK_FACTOR 1
#elif CPU_FAMILY == SPARC
#define ARCH_STACK_FACTOR 2
#else
#define ARCH_STACK_FACTOR 2
#endif
/*
* threadGetStackSize ()
*/
unsigned int threadGetStackSize (threadStackSizeClass stackSizeClass)
{
static const unsigned stackSizeTable[threadStackBig+1] =
{4000*ARCH_STACK_FACTOR, 6000*ARCH_STACK_FACTOR, 11000*ARCH_STACK_FACTOR};
if (stackSizeClass<threadStackSmall) {
errlogPrintf("threadGetStackSize illegal argument (too small)");
return stackSizeTable[threadStackBig];
}
if (stackSizeClass>threadStackBig) {
errlogPrintf("threadGetStackSize illegal argument (too large)");
return stackSizeTable[threadStackBig];
}
return stackSizeTable[stackSizeClass];
}
threadId threadCreate(const char *name,
unsigned int priority, unsigned int stackSize,
THREADFUNC funptr,void *parm)
{
threadInfo *pthreadInfo;
pthread_t *ptid;
int status;
if(firstTime) {
firstTime = 0;
pthread_key_create(&getpthreadInfo,0);
}
pthreadInfo = callocMustSucceed(1,sizeof(threadInfo),"threadCreate");
status = pthread_attr_init(&pthreadInfo->attr);
if(status) {
errlogPrintf("pthread_attr_init failed: error %s\n",strerror(status));
cantProceed("threadCreate");
}
status = pthread_attr_setdetachstate(
&pthreadInfo->attr, PTHREAD_CREATE_DETACHED);
if(status) {
errlogPrintf("pthread_attr_setdetachstate1 failed: error %s\n",
strerror(status));
}
status = pthread_attr_setstacksize(
&pthreadInfo->attr, (size_t)stackSize);
if(status) {
errlogPrintf("pthread_attr_setstacksize failed: error %s\n",
strerror(status));
}
/* DO WE WANT TO setscope ???? */
/*pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_SYSTEM);*/
pthreadInfo->schedPolicy = SCHED_FIFO;
pthreadInfo->maxPriority = sched_get_priority_max(pthreadInfo->schedPolicy);
pthreadInfo->minPriority = sched_get_priority_min(pthreadInfo->schedPolicy);
pthreadInfo->osiPriority = priority;
status = pthread_attr_setschedpolicy(
&pthreadInfo->attr,pthreadInfo->schedPolicy);
if(status) {
errlogPrintf("pthread_attr_setschedpolicy failed: error %s\n",
strerror(status));
cantProceed("threadCreate");
}
pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo);
status = pthread_attr_setschedparam(
&pthreadInfo->attr,&pthreadInfo->schedParam);
if(status) {
errlogPrintf("pthread_attr_setschedparam failed: error %s\n",
strerror(status));
cantProceed("threadCreate");
}
pthreadInfo->suspendSem = semBinaryMustCreate(semFull);
status = pthread_create(&pthreadInfo->tid,
&pthreadInfo->attr,start_routine,pthreadInfo);
if(status) {
errlogPrintf("pthread_create failed: error %s\n",strerror(status));
cantProceed("threadCreate");
}
return((threadId)pthreadInfo);
}
void threadSuspend()
{
threadInfo *pthreadInfo = (threadInfo *)pthread_getspecific(getpthreadInfo);
pthreadInfo->isSuspended = 1;
semBinaryMustTake(pthreadInfo->suspendSem);
}
void threadResume(threadId id)
{
threadInfo *pthreadInfo = (threadInfo *)id;
pthreadInfo->isSuspended = 0;
semBinaryGive(pthreadInfo->suspendSem);
}
unsigned int threadGetPriority(threadId id)
{
threadInfo *pthreadInfo = (threadInfo *)id;
return(pthreadInfo->osiPriority);
}
void threadSetPriority(threadId id,unsigned int priority)
{
threadInfo *pthreadInfo = (threadInfo *)id;
int status;
pthreadInfo->osiPriority = priority;
pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo);
status = pthread_attr_setschedparam(
&pthreadInfo->attr,&pthreadInfo->schedParam);
if(status) {
errlogPrintf("threadSetPriority: pthread_attr_setschedparam failed %s\n",
strerror(status));
}
}
int threadIsEqual(threadId id1, threadId id2)
{
threadInfo *p1 = (threadInfo *)id1;
threadInfo *p2 = (threadInfo *)id2;
return(pthread_equal(p1->tid,p2->tid));
}
int threadIsReady(threadId id) {
threadInfo *pthreadInfo = (threadInfo *)id;
return(pthreadInfo->isSuspended ? 1 : 0);
}
int threadIsSuspended(threadId id) {
return(threadIsReady(id) ? 0 : 1);
}
void threadSleep(double seconds)
{
struct timespec delayTime;
struct timespec remainingTime;
delayTime.tv_sec = (time_t)seconds;
delayTime.tv_nsec = (long)(seconds - (double)delayTime.tv_sec);
nanosleep(&delayTime,&remainingTime);
}
threadId threadGetIdSelf(void) {
threadInfo *pthreadInfo = (threadInfo *)pthread_getspecific(getpthreadInfo);
return((threadId)pthreadInfo);
}

View File

@@ -0,0 +1,5 @@
#ifndef osdThreadh
#define osdThreadh
#endif /* osdThreadh */

View File

@@ -0,0 +1,51 @@
//
// should move the gettimeofday() proto
// into a different header
//
#include "osiSock.h"
#define epicsExportSharedSymbols
#include "osiTime.h"
//
// osiTime::osdGetCurrent ()
//
extern "C" epicsShareFunc int epicsShareAPI tsStampGetCurrent (TS_STAMP *pDest)
{
# if defined(CLOCK_REALTIME)
struct timespec ts;
int status;
status = clock_gettime (CLOCK_REALTIME, &ts);
if (status) {
return tsStampERROR;
}
*pDest = osiTime (ts);
return tsStampERROR;
# else
int status;
struct timeval tv;
status = gettimeofday (&tv, NULL);
if (status) {
return tsStampERROR;
}
*pDest = osiTime (tv);
return tsStampERROR;
# endif
}
//
// tsStampGetEvent ()
//
extern "C" epicsShareFunc int epicsShareAPI tsStampGetEvent (TS_STAMP *pDest, unsigned eventNumber)
{
if (eventNumber==tsStampEventCurrentTime) {
return tsStampGetCurrent (pDest);
}
else {
return tsStampERROR;
}
}

View File

@@ -0,0 +1,26 @@
/*
* $Id$
*
* Author: Jeff Hill
*/
#ifndef osdTimeh
#define osdTimeh
#include <unistd.h>
/*
* "struct timespec" is not in all versions of POSIX 1.
* Solaris has it at ISO POSIX-1c so we will start from there,
* but may need to fine tune this
*/
#if _POSIX_VERSION < 199506L
struct timespec {
time_t tv_sec; /* seconds since some epoch */
long tv_nsec; /* nanoseconds within the second */
};
#endif /* if _POSIX_VERSION < 199506L */
#endif /* ifndef osdTimeh */