replacements for osdSem

This commit is contained in:
Marty Kraimer
2000-12-20 21:02:04 +00:00
parent a5ee8cf64a
commit d3c0f075cf
22 changed files with 2099 additions and 2 deletions

View File

@@ -118,8 +118,19 @@ INC += osiSock.h
INC += osdSock.h
INC += osiInterrupt.h
INC += osdInterrupt.h
#Marty remove the following
INC += osiSem.h
INC += osdSem.h
INC += osiMutex.h
INC += osiEvent.h
INC += epicsMutex.h
INC += osdMutex.h
INC += epicsEvent.h
INC += osdEvent.h
INC += epicsAssert.h
INC += epicsFindSymbol.h
INC += osiPoolStatus.h
@@ -131,8 +142,6 @@ INC += osdTime.h
INC += osiSigPipeIgnore.h
INC += osdSigPipeIgnore.h
INC += tsStamp.h
INC += osiMutex.h
INC += osiEvent.h
INC += osiProcess.h
INC += osiUnistd.h
INC += osiWireFormat.h
@@ -143,7 +152,12 @@ SRCS += osdAssert.c
SRCS += osdFindSymbol.c
SRCS += osdInterrupt.c
SRCS += osdPoolStatus.c
#Marty remove the following
SRCS += osdSem.c
SRCS += osdMutex.c
SRCS += osdEvent.c
SRCS += osdThread.c
SRCS += osiThread.cpp
SRCS += osdTime.cpp

View File

@@ -0,0 +1,197 @@
/*
* RTEMS osdEvent.c
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
/*
* We want to print out some information which is
* normally hidden from application programs.
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
#include <assert.h>
#include <stdio.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsEvent.h"
#include "osiThread.h"
#include "errlog.h"
/*
* Some performance tuning instrumentation
*/
#ifdef EPICS_RTEMS_SEMAPHORE_STATS
unsigned long semStat[6];
#define SEMSTAT(i) semStat[i]++;
#else
#define SEMSTAT(i)
#endif
/*
* Create a simple binary semaphore
*/
epicsEventId
epicsEventCreate(epicsEventInitialState initialState)
{
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
static char c3 = 'a';
sc = rtems_semaphore_create (rtems_build_name ('B', c3, 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') {
if (c3 == 'z') {
c3 = 'a';
}
else {
c3++;
}
c2 = 'a';
}
else {
c2++;
}
c1 = 'a';
}
else {
c1++;
}
rtems_interrupt_enable (level);
return (epicsEventId)sid;
}
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
{
epicsEventId id = epicsEventCreate (initialState);
assert (id);
return id;
}
void
epicsEventDestroy(epicsEventId 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
epicsEventSignal(epicsEventId 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));
}
epicsEventWaitStatus
epicsEventWait(epicsEventId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
SEMSTAT(0)
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
return epicsEventWaitError;
return epicsEventWaitOK;
}
epicsEventWaitStatus
epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
rtems_interval delay;
extern double rtemsTicksPerSecond_double;
SEMSTAT(1)
delay = timeOut * rtemsTicksPerSecond_double;
if (delay == 0)
delay = 1;
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
if (sc == RTEMS_SUCCESSFUL)
return epicsEventWaitOK;
else if (sc == RTEMS_TIMEOUT)
return epicsEventWaitTimeout;
else
return epicsEventWaitError;
}
epicsEventWaitStatus
epicsEventTryWait(epicsEventId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
SEMSTAT(2)
sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
if (sc == RTEMS_SUCCESSFUL)
return epicsEventWaitOK;
else if (sc == RTEMS_UNSATISFIED)
return epicsEventWaitTimeout;
else
return epicsEventWaitError;
}
void
epicsEventShow(epicsEventId id, unsigned int level)
{
#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__
rtems_id sid = (rtems_id)id;
Semaphore_Control *the_semaphore;
Semaphore_Control semaphore;
Objects_Locations location;
the_semaphore = _Semaphore_Get (sid, &location);
if (location != OBJECTS_LOCAL)
return;
/*
* Yes, there's a race condition here since an interrupt might
* change things while the copy is in progress, but the information
* is only for display, so it's not that critical.
*/
semaphore = *the_semaphore;
_Thread_Enable_dispatch();
printf (" %8.8x ", sid);
if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) {
printf ("Count: %d", semaphore.Core_control.semaphore.count);
}
else {
if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) {
char name[20];
threadGetName ((threadId)semaphore.Core_control.mutex.holder_id, name, sizeof name);
printf ("Held by:%8.8x (%s) Nest count:%d",
semaphore.Core_control.mutex.holder_id,
name,
semaphore.Core_control.mutex.nest_count);
}
else {
printf ("Not Held");
}
}
printf ("\n");
#endif
}

View File

@@ -0,0 +1,9 @@
/*
* RTEMS osdEvent.h
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
/* osdEvent.h not needed */

View File

@@ -0,0 +1,232 @@
/*
* RTEMS osdMutex.c
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
/*
* We want to print out some information which is
* normally hidden from application programs.
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
#include <assert.h>
#include <stdio.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsMutex.h"
#include "epicsEvent.h"
#include "osiThread.h"
#include "errlog.h"
#define RTEMS_FAST_MUTEX
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
/*
* Some performance tuning instrumentation
*/
#ifdef EPICS_RTEMS_SEMAPHORE_STATS
unsigned long semStat[6];
#define SEMSTAT(i) semStat[i]++;
#else
#define SEMSTAT(i)
#endif
epicsMutexId
epicsMutexCreate(void)
{
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
static char c3 = 'a';
sc = rtems_semaphore_create (rtems_build_name ('M', c3, 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') {
if (c3 == 'z') {
c3 = 'a';
}
else {
c3++;
}
c2 = 'a';
}
else {
c2++;
}
c1 = 'a';
}
else {
c1++;
}
rtems_interrupt_enable (level);
#ifdef RTEMS_FAST_MUTEX
{
Semaphore_Control *the_semaphore;
Objects_Locations location;
the_semaphore = _Semaphore_Get( sid, &location );
_Thread_Enable_dispatch();
return the_semaphore;
}
#endif
return (epicsMutexId)sid;
}
epicsMutexId epicsMutexMustCreate(void)
{
epicsMutexId id = epicsMutexCreate ();
assert (id);
return id;
}
void epicsMutexDestroy(epicsMutexId id)
{
rtems_status_code sc;
rtems_id sid;
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
sid = the_semaphore->Object.id;
#else
sid = (rtems_id)id;
#endif
sc = rtems_semaphore_delete (sid);
if (sc == RTEMS_RESOURCE_IN_USE) {
rtems_semaphore_release (sid);
sc = rtems_semaphore_delete (sid);
}
if (sc != RTEMS_SUCCESSFUL)
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
}
void epicsMutexUnlock(epicsMutexId id)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
_Thread_Disable_dispatch();
_CORE_mutex_Surrender (
&the_semaphore->Core_control.mutex,
the_semaphore->Object.id,
NULL
);
_Thread_Enable_dispatch();
#else
epicsEventSignal (id);
#endif
}
epicsMutexLockStatus epicsMutexLock(epicsMutexId id)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
ISR_Level level;
SEMSTAT(3)
_ISR_Disable( level );
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
the_semaphore->Object.id,
1, /* TRUE or FALSE */
0, /* same as passed to obtain -- ticks */
level
);
if (_Thread_Executing->Wait.return_code == 0)
return epicsMutexLockOK;
else
return epicsMutexLockError;
#else
SEMSTAT(3)
return((epicsEventWait (id) == epicsEventWaitOK)
?epicsMutexLockOK : epicsMutexLockError);
#endif
}
epicsMutexLockStatus epicsMutexLockWithTimeout(
epicsMutexId id, double timeOut)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
ISR_Level level;
rtems_interval delay;
extern double rtemsTicksPerSecond_double;
SEMSTAT(4)
delay = timeOut * rtemsTicksPerSecond_double;
if (delay == 0)
delay = 1;
_ISR_Disable( level );
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
the_semaphore->Object.id,
1, /* TRUE or FALSE */
delay, /* same as passed to obtain -- ticks */
level
);
if (_Thread_Executing->Wait.return_code == 0)
return epicsMutexLockOK;
else
return epicsMutexLockError;
#else
epicsEventWaitStatus status;
SEMSTAT(4)
status = epicsEventWaitWithTimeout(id,timeOut);
return((status==epicsEventWaitOK
? epicsMutexLockOK
: (status==epicsEventWaitTimeout)
? epicsMutexLockTimeout
: epicsMutexLockError));
#endif
}
epicsMutexLockStatus epicsMutexTryLock(epicsMutexId id)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
ISR_Level level;
SEMSTAT(5)
_ISR_Disable( level );
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
the_semaphore->Object.id,
0, /* TRUE or FALSE */
0, /* same as passed to obtain -- ticks */
level
);
if (_Thread_Executing->Wait.return_code == 0)
return epicsMutexLockOK;
else
return epicsMutexLockError;
#else
epicsEventWaitStatus status;
SEMSTAT(5)
status = epicsEventTryWait(id);
return((status==epicsEventWaitOK
? epicsMutexLockOK
: (status==epicsEventWaitTimeout)
? epicsMutexLockTimeout
: epicsMutexLockError));
#endif
}
epicsShareFunc void epicsMutexShow(epicsMutexId id,unsigned int level)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
id = (epicsMutexId)the_semaphore->Object.id;
#endif
epicsEventShow (id,level);
}

View File

@@ -0,0 +1,9 @@
/*
* RTEMS osdMutex.h
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
/* osdSem.h not needed */

View File

@@ -0,0 +1,176 @@
/* osdEvent.c */
/*
* $Id$
* WIN32 version
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* 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 <limits.h>
#ifndef VC_EXTRALEAN
# define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
/* including less than this causes conflicts with winsock2.h :-( */
#define _WIN32_WINNT 0x400
#include <winsock2.h>
#define epicsExportSharedSymbols
#include "shareLib.h"
#include "epicsEvent.h"
#include "epicsAssert.h"
#include "cantProceed.h"
static const unsigned mSecPerSecOsdSem = 1000u;
typedef struct eventSem {
HANDLE handle;
}eventSem;
/*
* epicsEventCreate ()
*/
epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
epicsEventInitialState initialState )
{
eventSem *pSem;
pSem = malloc ( sizeof ( *pSem ) );
if ( pSem ) {
pSem->handle = CreateEvent ( NULL, FALSE, initialState?TRUE:FALSE, NULL );
if ( pSem->handle == 0 ) {
free ( pSem );
pSem = 0;
}
}
return ( epicsEventId ) pSem;
}
/*
* epicsEventMustCreate ()
*/
epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
epicsEventInitialState initialState )
{
epicsEventId id = epicsEventCreate ( initialState );
assert ( id );
return id;
}
/*
* epicsEventDestroy ()
*/
epicsShareFunc void epicsShareAPI epicsEventDestroy (epicsEventId id)
{
eventSem *pSem = (eventSem *) id;
CloseHandle (pSem->handle);
free (pSem);
}
/*
* epicsEventSignal ()
*/
epicsShareFunc void epicsShareAPI epicsEventSignal (epicsEventId id)
{
eventSem *pSem = (eventSem *) id;
BOOL status;
status = SetEvent (pSem->handle);
assert (status);
}
/*
* epicsEventLock ()
*/
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventLock (epicsEventId id)
{
eventSem *pSem = (eventSem *) id;
DWORD status;
status = WaitForSingleObject (pSem->handle, INFINITE);
if ( status == WAIT_OBJECT_0 ) {
return epicsEventWaitOK;
}
else {
return epicsEventWaitError;
}
}
/*
* epicsEventWaitWithTimeout ()
*/
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
epicsEventId id, double timeOut)
{
eventSem *pSem = (eventSem *) id;
DWORD status;
DWORD tmo;
tmo = (DWORD) (timeOut * mSecPerSecOsdSem);
status = WaitForSingleObject (pSem->handle, tmo);
if ( status == WAIT_OBJECT_0 ) {
return epicsEventWaitOK;
}
else if (status == WAIT_TIMEOUT) {
return epicsEventWaitTimeout;
}
else {
return epicsEventWaitError;
}
}
/*
* epicsEventTryWait ()
*/
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait (epicsEventId id)
{
eventSem *pSem = (eventSem *) id;
DWORD status;
status = WaitForSingleObject (pSem->handle, 0);
if ( status == WAIT_OBJECT_0 ) {
return epicsEventWaitOK;
}
else if (status == WAIT_TIMEOUT) {
return epicsEventWaitTimeout;
}
else {
return epicsEventWaitError;
}
}
/*
* epicsEventShow ()
*/
epicsShareFunc void epicsShareAPI epicsEventShow (epicsEventId id, unsigned level)
{
}

View File

@@ -0,0 +1,32 @@
/* osdEvent.c */
/*
* $Id$
* WIN32 version
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* 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
*/
/* osdEvent.h not needed */

View File

@@ -0,0 +1,448 @@
/* osdMutex.c */
/*
* $Id$
* WIN32 version
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* 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 <limits.h>
#ifndef VC_EXTRALEAN
# define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
/* including less than this causes conflicts with winsock2.h :-( */
#define _WIN32_WINNT 0x400
#include <winsock2.h>
#define epicsExportSharedSymbols
#include "shareLib.h"
#include "epicsMutex.h"
#include "epicsAssert.h"
#include "cantProceed.h"
static const unsigned mSecPerSecOsdSem = 1000u;
#if 0
typedef struct mutexSem {
HANDLE handle;
}mutexSem;
/*
* epicsMutexCreate ()
*/
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexCreate (void)
{
mutexSem *pSem;
pSem = malloc ( sizeof (*pSem) );
if (pSem) {
pSem->handle = CreateMutex (NULL, FALSE, NULL);
if (pSem->handle==0) {
free (pSem);
pSem = 0;
}
}
return (epicsMutexId) pSem;
}
/*
* epicsMutexMustCreate ()
*/
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexMustCreate ()
{
epicsMutexId id = epicsMutexCreate ();
assert (id);
return id;
}
/*
* epicsMutexDestroy ()
*/
epicsShareFunc void epicsShareAPI epicsMutexDestroy (epicsMutexId id)
{
mutexSem *pSem = (mutexSem *) id;
CloseHandle (pSem->handle);
free (pSem);
}
/*
* epicsMutexUnlock ()
*/
epicsShareFunc void epicsShareAPI epicsMutexUnlock (epicsMutexId id)
{
mutexSem *pSem = (mutexSem *) id;
BOOL success;
success = ReleaseMutex (pSem->handle);
assert (success);
}
/*
* epicsMutexLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock (epicsMutexId id)
{
mutexSem *pSem = (mutexSem *) id;
DWORD status;
status = WaitForSingleObject (pSem->handle, INFINITE);
if ( status == WAIT_OBJECT_0 ) {
return epicsMutexLockOK;
}
else {
return epicsMutexLockError;
}
}
/*
* epicsMutexLockWithTimeout ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLockWithTimeout (epicsMutexId id, double timeOut)
{
mutexSem *pSem = (mutexSem *) id;
DWORD status;
DWORD tmo;
tmo = (DWORD) (timeOut * mSecPerSecOsdSem);
status = WaitForSingleObject (pSem->handle, tmo);
if ( status == WAIT_OBJECT_0 ) {
return epicsMutexLockOK;
}
else if (status == WAIT_TIMEOUT) {
return epicsMutexLockTimeout;
}
else {
return epicsMutexLockError;
}
}
/*
* epicsMutexTryLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock (epicsMutexId id)
{
mutexSem *pSem = (mutexSem *) id;
DWORD status;
status = WaitForSingleObject (pSem->handle, 0);
if ( status == WAIT_OBJECT_0 ) {
return epicsMutexLockOK;
}
else if (status == WAIT_TIMEOUT) {
return epicsMutexLockTimeout;
}
else {
return epicsMutexLockError;
}
}
/*
* epicsMutexShow ()
*/
epicsShareFunc void epicsShareAPI epicsMutexShow (epicsMutexId id, unsigned level)
{
}
#elif 0
typedef struct mutexSem {
CRITICAL_SECTION cs;
} mutexSem;
/*
* epicsMutexCreate ()
*/
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexCreate ( void )
{
mutexSem *pSem;
pSem = malloc ( sizeof (*pSem) );
if ( pSem ) {
InitializeCriticalSection ( &pSem->cs );
}
return (epicsMutexId) pSem;
}
/*
* epicsMutexMustCreate ()
*/
epicsShareFunc semBinaryId epicsShareAPI epicsMutexMustCreate ()
{
epicsMutexId id = epicsMutexCreate ();
assert ( id );
return id;
}
/*
* epicsMutexDestroy ()
*/
epicsShareFunc void epicsShareAPI epicsMutexDestroy ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
DeleteCriticalSection ( &pSem->cs );
free ( pSem );
}
/*
* epicsMutexUnlock ()
*/
epicsShareFunc void epicsShareAPI epicsMutexUnlock ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
LeaveCriticalSection ( &pSem->cs );
}
/*
* epicsMutexLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
EnterCriticalSection ( &pSem->cs );
return epicsMutexLockOK;
}
/*
* epicsMutexLockWithTimeout ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLockWithTimeout ( epicsMutexId id, double timeOut )
{
mutexSem *pSem = ( mutexSem * ) id;
EnterCriticalSection ( &pSem->cs );
return epicsMutexLockOK;
}
/*
* epicsMutexTryLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
if ( TryEnterCriticalSection ( &pSem->cs ) ) {
return epicsMutexLockOK;
}
else {
return epicsMutexLockTimeout;
}
}
/*
* epicsMutexShow ()
*/
epicsShareFunc void epicsShareAPI epicsMutexShow ( epicsMutexId id, unsigned level )
{
}
#else
typedef struct mutexSem {
CRITICAL_SECTION cs;
DWORD threadId;
HANDLE unlockSignal;
unsigned count;
} mutexSem;
/*
* epicsMutexCreate ()
*/
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexCreate ( void )
{
mutexSem *pSem;
pSem = malloc ( sizeof (*pSem) );
if ( pSem ) {
pSem->unlockSignal = CreateEvent ( NULL, FALSE, FALSE, NULL );
if ( pSem->unlockSignal == 0 ) {
free ( pSem );
pSem = 0;
}
else {
InitializeCriticalSection ( &pSem->cs );
pSem->threadId = 0;
pSem->count = 0u;
}
}
return (epicsMutexId) pSem;
}
/*
* epicsMutexMustCreate ()
*/
epicsShareFunc semBinaryId epicsShareAPI epicsMutexMustCreate ()
{
epicsMutexId id = epicsMutexCreate ();
assert ( id );
return id;
}
/*
* epicsMutexDestroy ()
*/
epicsShareFunc void epicsShareAPI epicsMutexDestroy ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
DeleteCriticalSection ( &pSem->cs );
CloseHandle ( pSem->unlockSignal );
free ( pSem );
}
/*
* epicsMutexUnlock ()
*/
epicsShareFunc void epicsShareAPI epicsMutexUnlock ( epicsMutexId id )
{
mutexSem *pSem = ( mutexSem * ) id;
unsigned signalNeeded;
DWORD status;
EnterCriticalSection ( &pSem->cs );
//assert ( pSem->threadId == GetCurrentThreadId () );
assert ( pSem->count > 0u );
pSem->count--;
if ( pSem->count == 0 ) {
pSem->threadId = 0;
signalNeeded = 1;
}
else {
signalNeeded = 0;
}
LeaveCriticalSection ( &pSem->cs );
if ( signalNeeded ) {
status = SetEvent ( pSem->unlockSignal );
assert ( status );
}
}
/*
* epicsMutexLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock ( epicsMutexId id )
{
DWORD thisThread = GetCurrentThreadId ();
mutexSem *pSem = ( mutexSem * ) id;
EnterCriticalSection ( &pSem->cs );
while ( pSem->count && pSem->threadId != thisThread ) {
DWORD status;
LeaveCriticalSection ( &pSem->cs );
status = WaitForSingleObject ( pSem->unlockSignal, INFINITE );
if ( status == WAIT_TIMEOUT ) {
return epicsMutexLockTimeout;
}
EnterCriticalSection ( &pSem->cs );
}
pSem->threadId = thisThread;
assert ( pSem->count != UINT_MAX );
pSem->count++;
LeaveCriticalSection ( &pSem->cs );
return epicsMutexLockOK;
}
/*
* epicsMutexLockWithTimeout ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLockWithTimeout ( epicsMutexId id, double timeOut )
{
DWORD thisThread = GetCurrentThreadId ();
mutexSem *pSem = ( mutexSem * ) id;
EnterCriticalSection ( &pSem->cs );
while ( pSem->count && pSem->threadId != thisThread ) {
DWORD tmo;
DWORD status;
LeaveCriticalSection ( &pSem->cs );
tmo = ( DWORD ) ( timeOut * mSecPerSecOsdSem );
status = WaitForSingleObject ( pSem->unlockSignal, tmo );
if ( status == WAIT_TIMEOUT ) {
return epicsMutexLockTimeout;
}
EnterCriticalSection ( &pSem->cs );
}
pSem->threadId = thisThread;
assert ( pSem->count != UINT_MAX );
pSem->count++;
LeaveCriticalSection ( &pSem->cs );
return epicsMutexLockOK;
}
/*
* epicsMutexTryLock ()
*/
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock ( epicsMutexId id )
{
DWORD thisThread = GetCurrentThreadId ();
mutexSem *pSem = ( mutexSem * ) id;
EnterCriticalSection ( &pSem->cs );
if ( pSem->count && pSem->threadId != thisThread ) {
LeaveCriticalSection ( &pSem->cs );
return epicsMutexLockTimeout;
}
pSem->threadId = thisThread;
assert ( pSem->count != UINT_MAX );
pSem->count++;
LeaveCriticalSection ( &pSem->cs );
return epicsMutexLockOK;
}
/*
* epicsMutexShow ()
*/
epicsShareFunc void epicsShareAPI epicsMutexShow ( epicsMutexId id, unsigned level )
{
}
#endif

View File

@@ -0,0 +1,36 @@
/* osdMutex.h */
/*
* $Id$
* WIN32 version
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* 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
*/
#ifndef osdMutexh
#define osdMutexh
#endif /* osdMutexh */

View File

@@ -0,0 +1,164 @@
/* osi/os/posix/osdEvent.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 "epicsEvent.h"
#include "osiThread.h"
#include "cantProceed.h"
#include "tsStamp.h"
#include "errlog.h"
#include "epicsAssert.h"
/* Until these can be demonstrated to work leave them undefined*/
#undef _POSIX_THREAD_PROCESS_SHARED
#undef _POSIX_THREAD_PRIO_INHERIT
typedef struct event {
pthread_mutex_t mutex;
pthread_cond_t cond;
int isFull;
}event;
#define checkStatus(status,message) \
if((status)) { \
errlogPrintf("%s failed: error %s\n",(message),strerror((status)));}
#define checkStatusQuit(status,message,method) \
if(status) { \
errlogPrintf("%s failed: error %s\n",(message),strerror((status))); \
cantProceed((method)); \
}
static void convertDoubleToWakeTime(double timeout,struct timespec *wakeTime)
{
struct timespec wait;
TS_STAMP stamp;
if(timeout<0.0) timeout = 0.0;
else if(timeout>3600.0) timeout = 3600.0;
tsStampGetCurrent(&stamp);
tsStampToTimespec(wakeTime, &stamp);
wait.tv_sec = timeout;
wait.tv_nsec = (long)((timeout - (double)wait.tv_sec) * 1e9);
wakeTime->tv_sec += wait.tv_sec;
wakeTime->tv_nsec += wait.tv_nsec;
if(wakeTime->tv_nsec>1000000000L) {
wakeTime->tv_nsec -= 1000000000L;
++wakeTime->tv_sec;
}
}
epicsEventId epicsEventCreate(epicsEventInitialState initialState)
{
event *pevent;
int status;
pevent = callocMustSucceed(1,sizeof(event),"epicsEventCreate");
status = pthread_mutex_init(&pevent->mutex,0);
checkStatusQuit(status,"pthread_mutex_init","epicsEventCreate");
status = pthread_cond_init(&pevent->cond,0);
checkStatusQuit(status,"pthread_cond_init","epicsEventCreate");
if(initialState==epicsEventFull) pevent->isFull = 1;
return((epicsEventId)pevent);
}
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
{
epicsEventId id = epicsEventCreate (initialState);
assert (id);
return id;
}
void epicsEventDestroy(epicsEventId id)
{
event *pevent = (event *)id;
int status;
status = pthread_mutex_destroy(&pevent->mutex);
checkStatus(status,"pthread_mutex_destroy");
status = pthread_cond_destroy(&pevent->cond);
checkStatus(status,"pthread_cond_destroy");
free(pevent);
}
void epicsEventSignal(epicsEventId id)
{
event *pevent = (event *)id;
int status;
status = pthread_mutex_lock(&pevent->mutex);
checkStatusQuit(status,"pthread_mutex_lock","epicsEventSignal");
if(!pevent->isFull) {
pevent->isFull = 1;
status = pthread_cond_signal(&pevent->cond);
checkStatus(status,"pthread_cond_signal");
}
status = pthread_mutex_unlock(&pevent->mutex);
checkStatusQuit(status,"pthread_mutex_unlock","epicsEventSignal");
}
epicsEventWaitStatus epicsEventWait(epicsEventId id)
{
event *pevent = (event *)id;
int status;
if(!pevent) return(epicsEventWaitError);
status = pthread_mutex_lock(&pevent->mutex);
checkStatusQuit(status,"pthread_mutex_lock","epicsEventWait");
/*no need for while since caller must be prepared for no work*/
if(!pevent->isFull) {
status = pthread_cond_wait(&pevent->cond,&pevent->mutex);
checkStatusQuit(status,"pthread_cond_wait","epicsEventWait");
}
pevent->isFull = 0;
status = pthread_mutex_unlock(&pevent->mutex);
checkStatusQuit(status,"pthread_mutex_unlock","epicsEventWait");
return(epicsEventWaitOK);
}
epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeout)
{
event *pevent = (event *)id;
struct timespec wakeTime;
int status = 0;
int unlockStatus;
status = pthread_mutex_lock(&pevent->mutex);
checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout");
if(!pevent->isFull) {
convertDoubleToWakeTime(timeout,&wakeTime);
status = pthread_cond_timedwait(
&pevent->cond,&pevent->mutex,&wakeTime);
}
if(status==0) pevent->isFull = 0;
unlockStatus = pthread_mutex_unlock(&pevent->mutex);
checkStatusQuit(unlockStatus,"pthread_mutex_unlock","epicsEventWaitWithTimeout");
if(status==0) return(epicsEventWaitOK);
if(status==ETIMEDOUT) return(epicsEventWaitTimeout);
checkStatus(status,"pthread_cond_timedwait");
return(epicsEventWaitError);
}
epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
{
return(epicsEventWaitWithTimeout(id,0.0));
}
void epicsEventShow(epicsEventId id,unsigned int level)
{
}

View File

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

View File

@@ -0,0 +1,219 @@
/* osi/os/posix/osdMutex.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 "epicsMutex.h"
#include "osiThread.h"
#include "cantProceed.h"
#include "tsStamp.h"
#include "errlog.h"
#include "epicsAssert.h"
/* Until these can be demonstrated to work leave them undefined*/
#undef _POSIX_THREAD_PROCESS_SHARED
#undef _POSIX_THREAD_PRIO_INHERIT
typedef struct mutex {
pthread_mutexattr_t mutexAttr;
pthread_mutex_t lock;
pthread_cond_t waitToBeOwner;
#if defined _POSIX_THREAD_PROCESS_SHARED
pthread_condattr_t condAttr;
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
int count;
int owned; /* TRUE | FALSE */
pthread_t ownerTid;
}mutex;
#define checkStatus(status,message) \
if((status)) { \
errlogPrintf("%s failed: error %s\n",(message),strerror((status)));}
#define checkStatusQuit(status,message,method) \
if(status) { \
errlogPrintf("%s failed: error %s\n",(message),strerror((status))); \
cantProceed((method)); \
}
static void convertDoubleToWakeTime(double timeout,struct timespec *wakeTime)
{
struct timespec wait;
TS_STAMP stamp;
if(timeout<0.0) timeout = 0.0;
else if(timeout>3600.0) timeout = 3600.0;
tsStampGetCurrent(&stamp);
tsStampToTimespec(wakeTime, &stamp);
wait.tv_sec = timeout;
wait.tv_nsec = (long)((timeout - (double)wait.tv_sec) * 1e9);
wakeTime->tv_sec += wait.tv_sec;
wakeTime->tv_nsec += wait.tv_nsec;
if(wakeTime->tv_nsec>1000000000L) {
wakeTime->tv_nsec -= 1000000000L;
++wakeTime->tv_sec;
}
}
epicsMutexId epicsMutexCreate(void) {
mutex *pmutex;
int status;
pmutex = callocMustSucceed(1,sizeof(mutex),"epicsMutexCreate");
status = pthread_mutexattr_init(&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutexattr_init","epicsMutexCreate");
#if defined _POSIX_THREAD_PRIO_INHERIT
status = pthread_mutexattr_setprotocol(
&pmutex->mutexAttr,PTHREAD_PRIO_INHERIT);
if(errVerbose) checkStatus(status,"pthread_mutexattr_setprotocal");
#endif /*_POSIX_THREAD_PRIO_INHERIT*/
status = pthread_mutex_init(&pmutex->lock,&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutex_init","epicsMutexCreate");
#if defined _POSIX_THREAD_PROCESS_SHARED
status = pthread_condattr_init(&pmutex->condAttr);
checkStatus(status,"pthread_condattr_init");
status = pthread_condattr_setpshared(&pmutex->condAttr,
PTHREAD_PROCESS_PRIVATE);
checkStatus(status,"pthread_condattr_setpshared");
status = pthread_cond_init(&pmutex->waitToBeOwner,&pmutex->condAttr);
#else
status = pthread_cond_init(&pmutex->waitToBeOwner,0);
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
checkStatusQuit(status,"pthread_cond_init","epicsMutexCreate");
return((epicsMutexId)pmutex);
}
epicsMutexId epicsMutexMustCreate(void)
{
epicsMutexId id = epicsMutexCreate ();
assert (id);
return id;
}
void epicsMutexDestroy(epicsMutexId id)
{
mutex *pmutex = (mutex *)id;
int status;
status = pthread_cond_destroy(&pmutex->waitToBeOwner);
checkStatus(status,"pthread_cond_destroy");
#if defined _POSIX_THREAD_PROCESS_SHARED
status = pthread_condattr_destroy(&pmutex->condAttr);
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
status = pthread_mutex_destroy(&pmutex->lock);
checkStatus(status,"pthread_mutex_destroy");
status = pthread_mutexattr_destroy(&pmutex->mutexAttr);
checkStatus(status,"pthread_mutexattr_destroy");
free(pmutex);
}
void epicsMutexUnlock(epicsMutexId id)
{
mutex *pmutex = (mutex *)id;
int status;
status = pthread_mutex_lock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexUnlock");
if((pmutex->count<=0) || (pmutex->ownerTid != pthread_self())) {
errlogPrintf("epicsMutexUnlock but caller is not owner\n");
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexUnlock");
return;
}
pmutex->count--;
if(pmutex->count == 0) {
pmutex->owned = 0;
pmutex->ownerTid = 0;
pthread_cond_signal(&pmutex->waitToBeOwner);
}
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexUnlock");
}
epicsMutexLockStatus epicsMutexLock(epicsMutexId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
int status;
if(!pmutex || !tid) return(epicsMutexLockError);
status = pthread_mutex_lock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexLock");
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid))
pthread_cond_wait(&pmutex->waitToBeOwner,&pmutex->lock);
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexLock");
return(epicsMutexLockOK);
}
epicsMutexLockStatus epicsMutexLockWithTimeout(epicsMutexId id, double timeout)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
struct timespec wakeTime;
int status,unlockStatus;
convertDoubleToWakeTime(timeout,&wakeTime);
status = pthread_mutex_lock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexLockWithTimeout");
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) {
status = pthread_cond_timedwait(
&pmutex->waitToBeOwner,&pmutex->lock,&wakeTime);
if(!status) break;
}
if(status==0) {
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
}
unlockStatus = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(unlockStatus,"pthread_mutex_lock","epicsMutexLockWithTimeout");
if(status==0) return(epicsMutexLockOK);
if(status==ETIMEDOUT) return(epicsMutexLockTimeout);
checkStatusQuit(status,"pthread_cond_timedwait","epicsMutexLockWithTimeout");
return(epicsMutexLockError);
}
epicsMutexLockStatus epicsMutexTryLock(epicsMutexId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
epicsMutexLockStatus status = epicsMutexLockError;
int pthreadStatus;
pthreadStatus = pthread_mutex_lock(&pmutex->lock);
checkStatusQuit(pthreadStatus,"pthread_mutex_lock","epicsMutexTryLock");
if(!pmutex->owned || pthread_equal(pmutex->ownerTid,tid)) {
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
status = 0;
}
pthreadStatus = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(pthreadStatus,"pthread_mutex_unlock","epicsMutexTryLock");
return(status);
}
void epicsMutexShow(epicsMutexId id,unsigned int level)
{
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 osdMutex.h definitions are needed*/

View File

@@ -0,0 +1,64 @@
/* os/vxWorks/osdEvent.c */
/* Author: Marty Kraimer Date: 25AUG99 */
/********************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 <vxWorks.h>
#include <semLib.h>
#include <time.h>
#include <objLib.h>
#include <sysLib.h>
/* The following not defined in an vxWorks header */
int sysClkRateGet(void);
#include "epicsEvent.h"
epicsEventId epicsEventCreate(epicsEventInitialState initialState)
{
return((epicsEventId)semBCreate(
SEM_Q_FIFO,((initialState==epicsEventEmpty) ? SEM_EMPTY : SEM_FULL)));
}
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
{
epicsEventId id = epicsEventCreate (initialState);
assert (id);
return id;
}
void epicsEventDestroy(epicsEventId id)
{
semDelete((SEM_ID)id);
}
epicsEventWaitStatus epicsEventTakeWithTimeout(
epicsEventId id, double timeOut)
{
int status;
int ticks;
ticks = (int)(timeOut * (double)sysClkRateGet());
if(ticks<=0) ticks = 1;
status = semTake((SEM_ID)id,ticks);
if(status==OK) return(epicsEventWaitOK);
if(errno==S_objLib_OBJ_TIMEOUT) return(epicsEventWaitTimeout);
return(epicsEventWaitError);
}
epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
{
int status;
status = semTake((SEM_ID)id,NO_WAIT);
if(status==OK) return(epicsEventWaitOK);
if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsEventWaitTimeout);
return(epicsEventWaitError);
}
void epicsEventShow(epicsEventId id,unsigned int level)
{
semShow((SEM_ID)id,level);
}

View File

@@ -0,0 +1,22 @@
/* os/vxWorks/osdEvent.h */
/* Author: Marty Kraimer Date: 25AUG99 */
/********************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 <vxWorks.h>
#include <semLib.h>
/* If the macro is replaced by inline it is necessary to say
static __inline__
but then a warning message appears everywhere osdEvent.h is included
*/
#define epicsEventSignal(ID) semGive((SEM_ID)(ID))
#define epicsEventWait(ID) \
(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsEventWaitOK : epicsEventWaitError)

View File

@@ -0,0 +1,65 @@
/* os/vxWorks/osdMutex.c */
/* Author: Marty Kraimer Date: 25AUG99 */
/********************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 <vxWorks.h>
#include <semLib.h>
#include <time.h>
#include <objLib.h>
#include <sysLib.h>
/* The following not defined in an vxWorks header */
int sysClkRateGet(void);
#include "epicsMutex.h"
epicsMutexId epicsMutexCreate(void)
{
return((epicsMutexId)
semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY));
}
epicsMutexId epicsMutexMustCreate(void)
{
epicsMutexId id = epicsMutexCreate ();
assert (id);
return id;
}
void epicsMutexDestroy(epicsMutexId id)
{
semDelete((SEM_ID)id);
}
epicsMutexLockStatus epicsMutexTakeWithTimeout(
epicsMutexId id, double timeOut)
{
int status;
int ticks;
ticks = (int)(timeOut * (double)sysClkRateGet());
if(ticks<=0) ticks = 1;
status = semTake((SEM_ID)id,ticks);
if(status==OK) return(epicsMutexLockOK);
if(errno==S_objLib_OBJ_TIMEOUT) return(epicsMutexLockTimeout);
return(epicsMutexLockError);
}
epicsMutexLockStatus epicsMutexTryLock(epicsMutexId id)
{
int status;
status = semTake((SEM_ID)id,NO_WAIT);
if(status==OK) return(epicsMutexLockOK);
if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsMutexLockTimeout);
return(epicsMutexLockError);
}
void epicsMutexShow(epicsMutexId id,unsigned int level)
{
semShow((SEM_ID)id,level);
}

View File

@@ -0,0 +1,22 @@
/* os/vxWorks/osdMutex.h */
/* Author: Marty Kraimer Date: 25AUG99 */
/********************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 <vxWorks.h>
#include <semLib.h>
/* If the macro is replaced by inline it is necessary to say
static __inline__
but then a warning message appears everywhere osdMutex.h is included
*/
#define epicsMutexUnlock(ID) semGive((SEM_ID)(ID))
#define epicsMutexLock(ID) \
(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsMutexLockOK : epicsMutexLockError)

View File

@@ -14,14 +14,24 @@ ringPointerTestHost_SRCS += ringPointerTestMain.c ringPointerTest.c
PROD += ringPointerTestHost
OBJS_IOC += ringPointerTest
# Marty remover the following
semBinaryTestHost_SRCS += semBinaryTestMain.c semBinaryTest.c
PROD += semBinaryTestHost
OBJS_IOC += semBinaryTest
# Marty remover the following
semMutexTestHost_SRCS += semMutexTestMain.c semMutexTest.c
PROD += semMutexTestHost
OBJS_IOC += semMutexTest
epicsEventTestHost_SRCS += epicsEventTestMain.cpp epicsEventTest.cpp
PROD += epicsEventTestHost
OBJS_IOC += epicsEventTest
epicsMutexTestHost_SRCS += epicsMutexTestMain.cpp epicsMutexTest.cpp
PROD += epicsMutexTestHost
OBJS_IOC += epicsMutexTest
threadTestHost_SRCS += threadTestMain.c threadTest.c
PROD += threadTestHost
OBJS_IOC += threadTest

View File

@@ -0,0 +1,168 @@
/* epicsEventTest.cpp */
/* Author: Marty Kraimer Date: 26JAN2000 */
/********************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 <stddef.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include "osiThread.h"
#include "epicsEvent.h"
#include "epicsMutex.h"
#include "epicsRingPointer.h"
#include "errlog.h"
typedef struct info {
epicsEventId event;
epicsMutexId lockRing;
int quit;
epicsRingPointerId ring;
}info;
static void consumer(void *arg)
{
info *pinfo = (info *)arg;
time_t tp;
threadId idSelf = threadGetIdSelf();
printf("consumer %p starting time %ld\n",idSelf,time(&tp));
while(1) {
epicsEventWaitStatus status;
if(pinfo->quit) {
printf("consumer %p returning time %ld\n",
idSelf,time(&tp));
return;
}
status = epicsEventWait(pinfo->event);
if(status!=epicsEventWaitOK) {
printf("task %p epicsEventWait returned %d time %ld\n",
idSelf,(int)status,time(&tp));
}
while(epicsRingPointerGetUsed(pinfo->ring)>=2) {
threadId message[2];
int i;
for(i=0; i<2; i++) {
if(!(message[i]=epicsRingPointerPop(pinfo->ring)))
printf("consumer error\n");
}
if(message[0]!=message[1]) {
printf("consumer error message %p %p\n",message[0],message[1]);
} else {
printf("consumer message from %p\n",message[0]);
}
}
}
}
static void producer(void *arg)
{
info *pinfo = (info *)arg;
time_t tp;
threadId idSelf = threadGetIdSelf();
int ntimes=0;
printf("producer %p starting time %ld\n",idSelf,time(&tp));
while(1) {
epicsMutexLockStatus status;
++ntimes;
if(pinfo->quit) {
printf("producer %p returning time %ld\n",
idSelf,time(&tp));
return;
}
status = epicsMutexLock(pinfo->lockRing);
if(status!=epicsMutexLockOK) {
printf("producer %p epicsMutexLock returned %d time %ld\n",
idSelf,(int)status,time(&tp));
}
if(epicsRingPointerGetFree(pinfo->ring)>=2) {
int i;
for(i=0; i<2; i++) {
if(!epicsRingPointerPush(pinfo->ring,idSelf))
printf("producer %p error\n",idSelf);
if(i==0 && (ntimes%4==0)) threadSleep(.1);
}
printf("producer %p sending\n",idSelf);
} else {
printf("producer %p ring buffer is full\n",idSelf);
}
epicsMutexUnlock(pinfo->lockRing);
threadSleep(1.0);
epicsEventSignal(pinfo->event);
}
}
extern "C" void epicsEventTest(int nthreads,int verbose)
{
unsigned int stackSize;
threadId *id;
char **name;
int i;
info *pinfo;
epicsEventId event;
int status;
time_t tp;
int errVerboseSave = errVerbose;
threadInit ();
errVerbose = verbose;
event = epicsEventMustCreate(epicsEventEmpty);
printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp));
status = epicsEventWaitWithTimeout(event,2.0);
if(status!=epicsEventWaitTimeout) printf("status %d\n",status);
printf("calling epicsEventTryWait(event) time %ld\n",time(&tp));
status = epicsEventTryWait(event);
if(status!=epicsEventWaitTimeout) printf("status %d\n",status);
printf("calling epicsEventSignal() time %ld\n",time(&tp));
epicsEventSignal(event);
printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp));
status = epicsEventWaitWithTimeout(event,2.0);
if(status) printf("status %d\n",status);
printf("calling epicsEventSignal() time %ld\n",time(&tp));
epicsEventSignal(event);
printf("calling epicsEventTryWait(event) time %ld\n",time(&tp));
status = epicsEventTryWait(event);
if(status) printf("status %d\n",status);
if(nthreads<=0) {
errVerbose = errVerboseSave;
return;
}
pinfo = (info *)calloc(1,sizeof(info));
pinfo->event = event;
pinfo->lockRing = epicsMutexCreate();
pinfo->ring = epicsRingPointerCreate(1024*2);
stackSize = threadGetStackSize(threadStackSmall);
threadCreate("consumer",50,stackSize,consumer,pinfo);
id = (threadId *)calloc(nthreads,sizeof(threadId));
name = (char **)calloc(nthreads,sizeof(char *));
for(i=0; i<nthreads; i++) {
name[i] = (char *)calloc(10,sizeof(char));
sprintf(name[i],"producer%d",i);
id[i] = threadCreate(name[i],40,stackSize,producer,pinfo);
printf("created producer %d id %p time %ld\n",
i, id[i],time(&tp));
}
threadSleep(5.0);
printf("semTest setting quit time %ld\n",time(&tp));
pinfo->quit = 1;
threadSleep(2.0);
epicsEventSignal(pinfo->event);
threadSleep(1.0);
printf("semTest returning time %ld\n",time(&tp));
errVerbose = errVerboseSave;
}

View File

@@ -0,0 +1,46 @@
/* epicsEventTestMain.cpp */
/* Author: Marty Kraimer Date: 26JAN2000 */
/********************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 <stddef.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "osiThread.h"
extern "C" void epicsEventTest(int nthreads,int errVerbose);
int main(int argc,char *argv[])
{
int nthreads = 2;
int errVerbose = 0;
if(argc>1) {
if(isdigit(*argv[1])) {
sscanf(argv[1],"%d",&nthreads);
printf("nthreads %d\n",nthreads);
} else {
printf("Illegal argument %s\n",argv[1]);
}
}
if(argc>2) {
if(isdigit(*argv[2])) {
sscanf(argv[2],"%d",&errVerbose);
printf("errVerbose %d\n",errVerbose);
} else {
printf("Illegal argument %s\n",argv[1]);
}
}
epicsEventTest(nthreads,errVerbose);
printf("main terminating\n");
return(0);
}

View File

@@ -0,0 +1,116 @@
/* epicsMutexTest.c */
/* Author: Marty Kraimer Date: 26JAN2000 */
/********************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 <stddef.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include "osiThread.h"
#include "epicsMutex.h"
#include "errlog.h"
typedef struct info {
int threadnum;
epicsMutexId mutex;
int quit;
}info;
static void mutexThread(void *arg)
{
info *pinfo = (info *)arg;
time_t tp;
printf("mutexThread %d starting time %ld\n",pinfo->threadnum,time(&tp));
while(1) {
epicsMutexLockStatus status;
if(pinfo->quit) {
printf("mutexThread %d returning time %ld\n",
pinfo->threadnum,time(&tp));
return;
}
status = epicsMutexLock(pinfo->mutex);
if(status!=epicsMutexLockOK) {
printf("task %d epicsMutexLock returned %d time %ld\n",
pinfo->threadnum,(int)status,time(&tp));
}
printf("mutexThread %d epicsMutexLock time %ld\n",
pinfo->threadnum,time(&tp));
threadSleep(.1);
epicsMutexUnlock(pinfo->mutex);
threadSleep(.9);
}
}
extern "C" void epicsMutexTest(int nthreads,int verbose)
{
unsigned int stackSize;
threadId *id;
int i;
char **name;
void **arg;
info **pinfo;
epicsMutexId mutex;
int status;
time_t tp;
int errVerboseSave = errVerbose;
threadInit ();
errVerbose = verbose;
mutex = epicsMutexMustCreate();
printf("calling epicsMutexLock(mutex) time %ld\n",time(&tp));
status = epicsMutexLock(mutex);
if(status) printf("status %d\n",status);
printf("calling epicsMutexLockWithTimeout(mutex,2.0) time %ld\n",time(&tp));
status = epicsMutexLockWithTimeout(mutex,2.0);
if(status) printf("status %d\n",status);
printf("calling epicsMutexTryLock(mutex) time %ld\n",time(&tp));
status = epicsMutexTryLock(mutex);
if(status) printf("status %d\n",status);
epicsMutexShow(mutex,1);
printf("calling epicsMutexUnlock() time %ld\n",time(&tp));
epicsMutexUnlock(mutex);
printf("calling epicsMutexUnlock() time %ld\n",time(&tp));
epicsMutexUnlock(mutex);
printf("calling epicsMutexUnlock() time %ld\n",time(&tp));
epicsMutexUnlock(mutex);
epicsMutexShow(mutex,1);
if(nthreads<=0) {
errVerbose = errVerboseSave;
return;
}
id = (void **)calloc(nthreads,sizeof(threadId));
name = (char **)calloc(nthreads,sizeof(char *));
arg = (void **)calloc(nthreads,sizeof(void *));
pinfo = (info **)calloc(nthreads,sizeof(info *));
stackSize = threadGetStackSize(threadStackSmall);
for(i=0; i<nthreads; i++) {
name[i] = (char *)calloc(10,sizeof(char));
sprintf(name[i],"task%d",i);
pinfo[i] = (info *)calloc(1,sizeof(info));
pinfo[i]->threadnum = i;
pinfo[i]->mutex = mutex;
arg[i] = pinfo[i];
id[i] = threadCreate(name[i],40,stackSize,(THREADFUNC)mutexThread,arg[i]);
printf("semTest created mutexThread %d id %p time %ld\n",
i, id[i],time(&tp));
}
threadSleep(5.0);
printf("semTest setting quit time %ld\n",time(&tp));
for(i=0; i<nthreads; i++) {
pinfo[i]->quit = 1;
}
threadSleep(2.0);
errVerbose = errVerboseSave;
}

View File

@@ -0,0 +1,46 @@
/* epicsMutexTestMain.c */
/* Author: Marty Kraimer Date: 26JAN2000 */
/********************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 <stddef.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "osiThread.h"
extern "C" void epicsMutexTest(int nthreads,int errVerbose);
int main(int argc,char *argv[])
{
int nthreads = 2;
int errVerbose = 0;
if(argc>1) {
if(isdigit(*argv[1])) {
sscanf(argv[1],"%d",&nthreads);
printf("nthreads %d\n",nthreads);
} else {
printf("Illegal argument %s\n",argv[1]);
}
}
if(argc>2) {
if(isdigit(*argv[2])) {
sscanf(argv[2],"%d",&errVerbose);
printf("errVerbose %d\n",errVerbose);
} else {
printf("Illegal argument %s\n",argv[1]);
}
}
epicsMutexTest(nthreads,errVerbose);
printf("main terminating\n");
return(0);
}