replacements for osdSem
This commit is contained in:
@@ -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
|
||||
|
||||
197
src/libCom/osi/os/RTEMS/osdEvent.c
Normal file
197
src/libCom/osi/os/RTEMS/osdEvent.c
Normal 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
|
||||
}
|
||||
9
src/libCom/osi/os/RTEMS/osdEvent.h
Normal file
9
src/libCom/osi/os/RTEMS/osdEvent.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* RTEMS osdEvent.h
|
||||
* $Id$
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
* (306) 966-6055
|
||||
*/
|
||||
|
||||
/* osdEvent.h not needed */
|
||||
232
src/libCom/osi/os/RTEMS/osdMutex.c
Normal file
232
src/libCom/osi/os/RTEMS/osdMutex.c
Normal 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);
|
||||
}
|
||||
9
src/libCom/osi/os/RTEMS/osdMutex.h
Normal file
9
src/libCom/osi/os/RTEMS/osdMutex.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* RTEMS osdMutex.h
|
||||
* $Id$
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
* (306) 966-6055
|
||||
*/
|
||||
|
||||
/* osdSem.h not needed */
|
||||
176
src/libCom/osi/os/WIN32/osdEvent.c
Normal file
176
src/libCom/osi/os/WIN32/osdEvent.c
Normal 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)
|
||||
{
|
||||
}
|
||||
32
src/libCom/osi/os/WIN32/osdEvent.h
Normal file
32
src/libCom/osi/os/WIN32/osdEvent.h
Normal 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 */
|
||||
448
src/libCom/osi/os/WIN32/osdMutex.c
Normal file
448
src/libCom/osi/os/WIN32/osdMutex.c
Normal 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
|
||||
|
||||
36
src/libCom/osi/os/WIN32/osdMutex.h
Normal file
36
src/libCom/osi/os/WIN32/osdMutex.h
Normal 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 */
|
||||
164
src/libCom/osi/os/posix/osdEvent.c
Normal file
164
src/libCom/osi/os/posix/osdEvent.c
Normal 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)
|
||||
{
|
||||
}
|
||||
1
src/libCom/osi/os/posix/osdEvent.h
Normal file
1
src/libCom/osi/os/posix/osdEvent.h
Normal file
@@ -0,0 +1 @@
|
||||
/* for a pure posix implementation no osdEvent.h definitions are needed*/
|
||||
219
src/libCom/osi/os/posix/osdMutex.c
Normal file
219
src/libCom/osi/os/posix/osdMutex.c
Normal 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);
|
||||
}
|
||||
1
src/libCom/osi/os/posix/osdMutex.h
Normal file
1
src/libCom/osi/os/posix/osdMutex.h
Normal file
@@ -0,0 +1 @@
|
||||
/* for a pure posix implementation no osdMutex.h definitions are needed*/
|
||||
64
src/libCom/osi/os/vxWorks/osdEvent.c
Normal file
64
src/libCom/osi/os/vxWorks/osdEvent.c
Normal 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);
|
||||
}
|
||||
22
src/libCom/osi/os/vxWorks/osdEvent.h
Normal file
22
src/libCom/osi/os/vxWorks/osdEvent.h
Normal 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)
|
||||
65
src/libCom/osi/os/vxWorks/osdMutex.c
Normal file
65
src/libCom/osi/os/vxWorks/osdMutex.c
Normal 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);
|
||||
}
|
||||
22
src/libCom/osi/os/vxWorks/osdMutex.h
Normal file
22
src/libCom/osi/os/vxWorks/osdMutex.h
Normal 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)
|
||||
@@ -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
|
||||
|
||||
168
src/libCom/test/epicsEventTest.cpp
Normal file
168
src/libCom/test/epicsEventTest.cpp
Normal 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;
|
||||
}
|
||||
46
src/libCom/test/epicsEventTestMain.cpp
Normal file
46
src/libCom/test/epicsEventTestMain.cpp
Normal 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);
|
||||
}
|
||||
116
src/libCom/test/epicsMutexTest.cpp
Normal file
116
src/libCom/test/epicsMutexTest.cpp
Normal 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;
|
||||
}
|
||||
46
src/libCom/test/epicsMutexTestMain.cpp
Normal file
46
src/libCom/test/epicsMutexTestMain.cpp
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user