o merged in changes from the "compiler specific build" branch
o changed implementation of default mutex locked version to be POSIX specific so we can use a static pthread mutex which is more efficent
This commit is contained in:
@@ -382,11 +382,11 @@ INSTALL_PERMISSIONS = 444
|
||||
#
|
||||
# auto determine the directory paths that things are installed to
|
||||
# RULES:
|
||||
# 0) found in any one of several compiler specific area
|
||||
# 0) found in any one of several compiler specific paths
|
||||
# => install to $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)
|
||||
# 1) not found in (0) and found in any one of several os specific area
|
||||
# 1) not found in (0) and found in any one of several OS specific paths
|
||||
# => install to $(INSTALL_INCLUDE)/os/$(OS_CLASS)
|
||||
# 2) not found in (1) and found in generic area
|
||||
# 2) not found in (1) and found in generic paths
|
||||
# => install to $(INSTALL_INCLUDE)
|
||||
# 3) not found in (1) or (2) then may be (not yet) computer generated
|
||||
# => install into $(INSTALL_INCLUDE)/os/$(OS_CLASS) and let
|
||||
|
||||
@@ -415,7 +415,7 @@ $(INSTALL_INCLUDE)/% : %
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_INCLUDE)/os/$(OS_CLASS)/% : %
|
||||
$(ECHO) "Installing os dependent include file $@"
|
||||
$(ECHO) "Installing OS dependent include file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/% : %
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
#-------------------------------------------------------
|
||||
|
||||
# GNU_DIR used when COMMANDLINE_LIBRARY is READLINE
|
||||
#GNU_DIR=C:/cygwin
|
||||
#GNU_DIR=C:/cygwin
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
#AR = $(CMPLR_PREFIX)ar -rc
|
||||
#LD = $(CMPLR_PREFIX)ld -r
|
||||
#RANLIB = $(CMPLR_PREFIX)ranlib
|
||||
|
||||
|
||||
+3
-5
@@ -136,7 +136,6 @@ INC += epicsExport.h
|
||||
INC += unixFileName.h
|
||||
INC += locationException.h
|
||||
INC += ipAddrToAsciiAsynchronous.h
|
||||
INC += compilerDependencies.h
|
||||
INC += epicsUnitTest.h
|
||||
INC += testMain.h
|
||||
SRCS += aToIPAddr.c
|
||||
@@ -185,9 +184,8 @@ INC += osiWireFormat.h
|
||||
INC += osdWireFormat.h
|
||||
INC += osdWireConfig.h
|
||||
INC += epicsAtomic.h
|
||||
INC += epicsAtomicLocked.h
|
||||
INC += epicsAtomicOSD.h
|
||||
INC += epicsAtomicCD.h
|
||||
INC += epicsAtomicOSD.h
|
||||
INC += epicsEndian.h
|
||||
INC += epicsReadline.h
|
||||
INC += epicsMessageQueue.h
|
||||
@@ -199,6 +197,8 @@ INC += devLib.h
|
||||
INC += devLibVME.h
|
||||
INC += devLibVMEImpl.h
|
||||
INC += osdVME.h
|
||||
INC += compilerDependencies.h
|
||||
INC += compilerSpecific.h
|
||||
|
||||
SRCS += epicsThread.cpp
|
||||
SRCS += epicsMutex.cpp
|
||||
@@ -206,7 +206,6 @@ SRCS += epicsEvent.cpp
|
||||
SRCS += epicsTime.cpp
|
||||
SRCS += epicsMessageQueue.cpp
|
||||
SRCS += epicsMath.cpp
|
||||
SRCS += epicsAtomicLocked.cpp
|
||||
SRCS += epicsAtomicOSD.cpp
|
||||
|
||||
SRCS += epicsGeneralTime.c
|
||||
@@ -228,7 +227,6 @@ SRCS += epicsTempFile.cpp
|
||||
SRCS += epicsStdio.c
|
||||
SRCS += osdStdio.c
|
||||
|
||||
|
||||
osdEnv_CFLAGS_WIN32= -U__STDC__
|
||||
|
||||
SRCS += osdThread.c
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerDependencies_h
|
||||
#define compilerDependencies_h
|
||||
|
||||
/*
|
||||
* This is an attempt to move all tests identifying what features a
|
||||
* compiler supports into one file.
|
||||
*
|
||||
* Since this is a compiler, and not os dependent, issue then ifdefs
|
||||
* are used. The ifdefs allow us to make the default assumption that
|
||||
* standards incompliance issues will be fixed by future compiler
|
||||
* releases.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
|
||||
#if defined ( _MSC_VER )
|
||||
# if _MSC_VER >= 1200 /* visual studio 6.0 or later */
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# endif
|
||||
# if _MSC_VER > 1300 /* some release after visual studio 7 we hope */
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
# endif
|
||||
#elif defined ( __HP_aCC )
|
||||
# if _HP_aCC > 33300
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# endif
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#elif defined ( __BORLANDC__ )
|
||||
# if __BORLANDC__ >= 0x600
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# endif
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#elif defined ( __GNUC__ )
|
||||
# if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95 )
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
# endif
|
||||
# if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 96 )
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# endif
|
||||
#else
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#endif
|
||||
|
||||
/*
|
||||
* usage: void func () epicsThrows (( std::bad_alloc, std::logic_error ))
|
||||
*/
|
||||
#if defined ( CXX_THROW_SPECIFICATION )
|
||||
# define epicsThrows(X) throw X
|
||||
#else
|
||||
# define epicsThrows(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & ))
|
||||
*/
|
||||
#if defined ( CXX_PLACEMENT_DELETE )
|
||||
# define epicsPlacementDeleteOperator(X) void operator delete X;
|
||||
#else
|
||||
# define epicsPlacementDeleteOperator(X)
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# define EPICS_PRINTF_STYLE(f,a) __attribute__((format(__printf__,f,a)))
|
||||
#else
|
||||
# define EPICS_PRINTF_STYLE(f,a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deprecation marker
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# define EPICS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
# define EPICS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif /* ifndef compilerDependencies_h */
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerSpecific_h
|
||||
#define compilerSpecific_h
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
# error compiler/borland/compilerSpecific.h is only for use with the Borland compiler
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* in general we dont like ifdefs but they do allow us to check the
|
||||
* compiler version and make the optimistic assumption that
|
||||
* standards incompliance issues will be fixed by future compiler
|
||||
* releases
|
||||
*/
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
#if __BORLANDC__ >= 0x600
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
#endif
|
||||
|
||||
#define CXX_THROW_SPECIFICATION
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#define EPICS_PRINTF_STYLE(f,a)
|
||||
|
||||
/*
|
||||
* Deprecation marker
|
||||
*/
|
||||
#define EPICS_DEPRECATED
|
||||
|
||||
#endif /* ifndef compilerSpecific_h */
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerSpecific_h
|
||||
#define compilerSpecific_h
|
||||
|
||||
#ifndef __clang__
|
||||
# error compiler/clang/compilerSpecific.h is only for use with the clang compiler
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING: the current state of this file is only based on reading clang manuals
|
||||
* and has not actually been tested with the compiler
|
||||
*/
|
||||
#pragma warning compiler/clang/compilerSpecific.h is based on reading the manual, but hasnt been tested with the clang compiler
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
#define CXX_PLACEMENT_DELETE
|
||||
#define CXX_THROW_SPECIFICATION
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#if __has_attribute(format)
|
||||
# define EPICS_PRINTF_STYLE(f,a) __attribute__((format(__printf__,f,a)))
|
||||
#else
|
||||
# define EPICS_PRINTF_STYLE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deprecation marker if possible
|
||||
*/
|
||||
#if __has_attribute(deprecated)
|
||||
# define EPICS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
# define EPICS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif /* ifndef compilerSpecific_h */
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerSpecific_h
|
||||
#define compilerSpecific_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*
|
||||
* (our default guess is that the compiler implements the C++ 97 standard)
|
||||
*/
|
||||
#define CXX_THROW_SPECIFICATION
|
||||
#define CXX_PLACEMENT_DELETE
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
* (our default guess is that the compiler doesnt implement non-standard extensions)
|
||||
*/
|
||||
#define EPICS_PRINTF_STYLE(f,a)
|
||||
|
||||
/*
|
||||
* Deprecation marker
|
||||
* (our default guess is that the compiler doesnt implement non-standard extensions)
|
||||
*/
|
||||
#define EPICS_DEPRECATED
|
||||
|
||||
#endif /* ifndef compilerSpecific_h */
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerSpecific_h
|
||||
#define compilerSpecific_h
|
||||
|
||||
#ifndef __GNUC__
|
||||
# error compiler/gcc/compilerSpecific.h is only for use with the gnu compiler
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* in general we dont like ifdefs but they do allow us to check the
|
||||
* compiler version and make the optimistic assumption that
|
||||
* standards incompliance issues will be fixed by future compiler
|
||||
* releases
|
||||
*/
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
|
||||
#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95 )
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 96 )
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#define EPICS_PRINTF_STYLE(f,a) __attribute__((format(__printf__,f,a)))
|
||||
|
||||
/*
|
||||
* Deprecation marker if possible
|
||||
*/
|
||||
|
||||
#define EPICS_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
#endif /* ifndef compilerSpecific_h */
|
||||
@@ -50,6 +50,8 @@
|
||||
&& GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T ) \
|
||||
|| GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER
|
||||
|
||||
#define OSD_ATOMIC_INLINE_DEFINITION
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -120,11 +122,6 @@ OSD_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT *
|
||||
#endif
|
||||
|
||||
#else /* if GCC_ATOMIC_INTRINSICS_AVAIL */
|
||||
|
||||
# if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER && __i386
|
||||
/* 386 hardware is probably rare today even in embedded systems */
|
||||
# warning "this code will run much faster if specifying i486 or better"
|
||||
# endif
|
||||
|
||||
/*
|
||||
* not available as gcc intrinsics so we
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerSpecific_h
|
||||
#define compilerSpecific_h
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# error compiler/msvc/compilerSpecific.h is only for use with the Microsoft compiler
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* in general we dont like ifdefs but they do allow us to check the
|
||||
* compiler version and make the optimistic assumption that
|
||||
* standards incompliance issues will be fixed by future compiler
|
||||
* releases
|
||||
*/
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
#if _MSC_VER >= 1200 /* visual studio 6.0 or later */
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
#endif
|
||||
|
||||
#if _MSC_VER > 1300 /* some release after visual studio 7 we hope */
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#define EPICS_PRINTF_STYLE(f,a)
|
||||
|
||||
/*
|
||||
* Deprecation marker
|
||||
*/
|
||||
#define EPICS_DEPRECATED
|
||||
|
||||
#endif /* ifndef compilerSpecific_h */
|
||||
@@ -66,6 +66,8 @@
|
||||
# error unexpected target architecture, msvc version of epicsAtomicCD.h
|
||||
#endif
|
||||
|
||||
#define OSD_ATOMIC_INLINE_DEFINITION
|
||||
|
||||
/*
|
||||
* The windows doc appears to recommend defining InterlockedExchange
|
||||
* to be _InterlockedExchange to cause it to be an intrinsic, but that
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef compilerDependencies_h
|
||||
#define compilerDependencies_h
|
||||
|
||||
#include "compilerSpecific.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* usage: void func () epicsThrows (( std::bad_alloc, std::logic_error ))
|
||||
*
|
||||
* Note: now a widely accepted concensus (ref Meyers and C++ faq) is that
|
||||
* one should avoid using throw specifications in C++ code
|
||||
*/
|
||||
#if defined ( CXX_THROW_SPECIFICATION )
|
||||
# define epicsThrows(X) throw X
|
||||
#else
|
||||
# define epicsThrows(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & ))
|
||||
*/
|
||||
#if defined ( CXX_PLACEMENT_DELETE )
|
||||
# define epicsPlacementDeleteOperator(X) void operator delete X;
|
||||
#else
|
||||
# define epicsPlacementDeleteOperator(X)
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ifndef compilerDependencies_h */
|
||||
@@ -81,25 +81,6 @@ epicsShareFunc EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTa
|
||||
EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal );
|
||||
|
||||
|
||||
/*
|
||||
* the following are, never inline and always synchronized by a global
|
||||
* mutual exclusion lock, implementations of the epicsAtomicXxxx interface
|
||||
* which may used to implement the epicsAtomicXxxx functions when
|
||||
* more efficent primitives aren't available
|
||||
*/
|
||||
epicsShareFunc size_t epicsLockedIncrSizeT ( size_t * pTarget );
|
||||
epicsShareFunc size_t epicsLockedDecrSizeT ( size_t * pTarget );
|
||||
epicsShareFunc void epicsLockedSetSizeT ( size_t * pTarget, size_t newVal );
|
||||
epicsShareFunc void epicsLockedSetUIntT ( unsigned * pTarget, unsigned newVal );
|
||||
epicsShareFunc void epicsLockedSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newVal );
|
||||
epicsShareFunc size_t epicsLockedGetSizeT ( const size_t * pTarget );
|
||||
epicsShareFunc unsigned epicsLockedGetUIntT ( const unsigned * pTarget );
|
||||
epicsShareFunc EpicsAtomicPtrT epicsLockedGetPtrT ( const EpicsAtomicPtrT * pTarget );
|
||||
epicsShareFunc unsigned epicsLockedCmpAndSwapUIntT ( unsigned * pTarget,
|
||||
unsigned oldval, unsigned newval );
|
||||
epicsShareFunc EpicsAtomicPtrT epicsLockedCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget,
|
||||
EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2011 LANS LLC, as Operator of
|
||||
* Los Alamos National Laboratory.
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef epicsAtomicGuard_h
|
||||
#define epicsAtomicGuard_h
|
||||
|
||||
//
|
||||
// This header file is intended only for use with the epicsAtomicLocked
|
||||
// header file. The intent is that an OS specific implementation of
|
||||
// epicsAtomicOSD.cpp might first include this file, next implement
|
||||
// AtomicGuard depending on os specific capabilities, and finally include
|
||||
// the epicsAtomicLocked header file to define the various epicsAtomicXxxx
|
||||
// functions.
|
||||
//
|
||||
// The AtomicGuard class is defined in a seperate header file
|
||||
// from the epicsAtomicLocked header for two reasons.
|
||||
// o First, it must be possible to have an inline definition of the
|
||||
// AtomicGuard member functions, and that isnt possible if the
|
||||
// epicsAtomicXxxx function definitions in the epicsAtomicLocked
|
||||
// header file have already been seen by the translation unit.
|
||||
// o Second, we need to enforce a uniform interface for all definitions
|
||||
// of the the AtomicGuard constructor and destructor member functions
|
||||
// requiring that no exception are thrown. This is because the
|
||||
// epicsAtomicXxxx functions in the epicsAtomicLocked header file are
|
||||
// directly callable by C code.
|
||||
//
|
||||
// The epicsAtomicXxxx functions in the epicsAtomicLocked do not pass
|
||||
// any parameters to the AtomicGuard constructor, and therefore the lock
|
||||
// used by AtomicGuard is restricted to be a global lock for the entire
|
||||
// multithreaded executable. Therefore, AtomicGuard will typically
|
||||
// reference some translation unit scope limited global variable in
|
||||
// the anonymous namespace for implementation of the locking primitive.
|
||||
//
|
||||
|
||||
namespace {
|
||||
struct AtomicGuard {
|
||||
AtomicGuard () throw ();
|
||||
~AtomicGuard () throw ();
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
#endif // ifndef epicsAtomicGuard_h
|
||||
@@ -1,158 +0,0 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2011 LANS LLC, as Operator of
|
||||
* Los Alamos National Laboratory.
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*
|
||||
* Provide a global mutex version of the atomic functions for when
|
||||
* we dont have more efficent OS primitives or compiler intriniscs
|
||||
* to use instead.
|
||||
*
|
||||
* We implement these mutex-based primitives upon the libCom private
|
||||
* interface epicsMutexOsdXxxx because, in libCom, it is convenient
|
||||
* to make this a standalone primitive upon which we can implement
|
||||
* epicsMutex.
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsAtomic.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsMutex.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class AtomicGuard {
|
||||
public:
|
||||
AtomicGuard ();
|
||||
~AtomicGuard ();
|
||||
private:
|
||||
static epicsMutexOSD * m_pMutex;
|
||||
static epicsThreadOnceId m_onceFlag;
|
||||
static void m_once ( void * );
|
||||
};
|
||||
|
||||
//
|
||||
// c++ 0x specifies the behavior for concurrent
|
||||
// access to block scope statics but some compiler
|
||||
// writers, lacking clear guidance in the earlier
|
||||
// c++ standards, curiously implement thread unsafe
|
||||
// block static variables despite ensuring for
|
||||
// proper multithreaded behavior for many other
|
||||
// parst of the compiler infrastructure such as
|
||||
// runtime support for exception handling
|
||||
//
|
||||
// since this is potentially used by the implementation
|
||||
// of staticInstance we cant use it here and must use
|
||||
// epicsThreadOnce despite its perfomance pentalty
|
||||
//
|
||||
// using epicsThreadOnce here (at this time) increases
|
||||
// the overhead of AtomicGuard by as much as 100%
|
||||
//
|
||||
epicsMutexOSD * AtomicGuard :: m_pMutex = 0;
|
||||
epicsThreadOnceId AtomicGuard :: m_onceFlag = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
void AtomicGuard :: m_once ( void * )
|
||||
{
|
||||
m_pMutex = epicsMutexOsdCreate ();
|
||||
}
|
||||
|
||||
inline AtomicGuard :: AtomicGuard ()
|
||||
{
|
||||
|
||||
epicsThreadOnce ( & m_onceFlag, m_once, 0 );
|
||||
const int status = epicsMutexOsdLock ( m_pMutex );
|
||||
assert ( status == epicsMutexLockOK );
|
||||
}
|
||||
|
||||
inline AtomicGuard :: ~AtomicGuard ()
|
||||
{
|
||||
epicsMutexOsdUnlock ( m_pMutex );
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
size_t epicsLockedIncrSizeT ( size_t * pTarget )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
return ++(*pTarget);
|
||||
}
|
||||
|
||||
size_t epicsLockedDecrSizeT ( size_t * pTarget )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
return --(*pTarget);
|
||||
}
|
||||
|
||||
void epicsLockedSetSizeT ( size_t * pTarget, size_t newVal )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
void epicsLockedSetUIntT ( unsigned * pTarget, unsigned newVal )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
void epicsLockedSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newVal )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
unsigned epicsLockedGetUIntT ( const unsigned * pTarget )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
size_t epicsLockedGetSizeT ( const size_t * pTarget )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
EpicsAtomicPtrT epicsLockedGetPtrT ( const EpicsAtomicPtrT * pTarget )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
unsigned epicsLockedCmpAndSwapUIntT ( unsigned * pTarget,
|
||||
unsigned oldval, unsigned newval )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
const unsigned cur = *pTarget;
|
||||
if ( cur == oldval ) {
|
||||
*pTarget = newval;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
EpicsAtomicPtrT epicsLockedCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget,
|
||||
EpicsAtomicPtrT oldval, EpicsAtomicPtrT newval )
|
||||
{
|
||||
AtomicGuard atomicGuard;
|
||||
const EpicsAtomicPtrT cur = *pTarget;
|
||||
if ( cur == oldval ) {
|
||||
*pTarget = newval;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
} // end of extern "C"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,86 +12,108 @@
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
//
|
||||
// The epicsAtomicXxxxx functions herein are implemented with C++ but directly
|
||||
// callable by C code, and therefore they must not be instantiated inline.
|
||||
// Therefore, this isnt a traditional header file because it has function
|
||||
// definitions that are not inline, and must therefore be included by only
|
||||
// one module in the executable - typically this is the epicsAtomicOSD
|
||||
// c++ source file. These out-of-line function definitions are placed in a
|
||||
// header file so that there is potential code reuse when instantiating for
|
||||
// a specific OS. An alternative option would have been to place these
|
||||
// function definitions in a OS type conditionally compiled source file
|
||||
// but this wasnt done because I suspect that selecting the posix version
|
||||
// would require a proliferation of "SRCS_XXXX += xxx.cpp" in the libCom
|
||||
// Makefile for every variety of Unix (a maintenance headache when new
|
||||
// varieties of UNIX are configured).
|
||||
//
|
||||
// Aee also the comments in epicsAtomicGuard header.
|
||||
//
|
||||
|
||||
#ifndef epicsAtomicLocked_h
|
||||
#define epicsAtomicLocked_h
|
||||
|
||||
#if defined ( OSD_ATOMIC_INLINE )
|
||||
#ifndef __cplusplus
|
||||
# error epicsAtomicLocked.h is intended only for use only by C++ code
|
||||
#endif
|
||||
|
||||
#include "epicsAtomic.h" // always cross check the function prototypes
|
||||
#include "epicsAtomicGuard.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
OSD_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget )
|
||||
size_t epicsAtomicIncrSizeT ( size_t * pTarget )
|
||||
{
|
||||
return epicsLockedIncrSizeT ( pTarget );
|
||||
AtomicGuard atomicGuard;
|
||||
return ++(*pTarget);
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget )
|
||||
size_t epicsAtomicDecrSizeT ( size_t * pTarget )
|
||||
{
|
||||
return epicsLockedDecrSizeT ( pTarget );
|
||||
AtomicGuard atomicGuard;
|
||||
return --(*pTarget);
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newVal )
|
||||
void epicsAtomicSetSizeT ( size_t * pTarget, size_t newVal )
|
||||
{
|
||||
epicsLockedSetSizeT ( pTarget, newVal );
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget )
|
||||
void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal )
|
||||
{
|
||||
return epicsLockedGetSizeT ( pTarget );
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
|
||||
void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newVal )
|
||||
{
|
||||
return epicsLockedGetUIntT ( pTarget );
|
||||
AtomicGuard atomicGuard;
|
||||
*pTarget = newVal;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal )
|
||||
unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
|
||||
{
|
||||
epicsLockedSetUIntT ( pTarget, newVal );
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newVal )
|
||||
size_t epicsAtomicGetSizeT ( const size_t * pTarget )
|
||||
{
|
||||
epicsLockedSetPtrT ( pTarget, newVal );
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget )
|
||||
EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget )
|
||||
{
|
||||
return epicsLockedGetPtrT ( pTarget );
|
||||
AtomicGuard atomicGuard;
|
||||
return *pTarget;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE unsigned epicsAtomicCmpAndSwapUIntT ( unsigned * pTarget,
|
||||
unsigned oldVal, unsigned newVal )
|
||||
unsigned epicsAtomicCmpAndSwapUIntT ( unsigned * pTarget,
|
||||
unsigned oldval, unsigned newval )
|
||||
{
|
||||
return epicsLockedCmpAndSwapUIntT ( pTarget, oldVal, newVal );
|
||||
AtomicGuard atomicGuard;
|
||||
const unsigned cur = *pTarget;
|
||||
if ( cur == oldval ) {
|
||||
*pTarget = newval;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
OSD_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget,
|
||||
EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal )
|
||||
EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget,
|
||||
EpicsAtomicPtrT oldval, EpicsAtomicPtrT newval )
|
||||
{
|
||||
return epicsLockedCmpAndSwapPtrT ( pTarget, oldVal, newVal );
|
||||
AtomicGuard atomicGuard;
|
||||
const EpicsAtomicPtrT cur = *pTarget;
|
||||
if ( cur == oldval ) {
|
||||
*pTarget = newval;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#else /* if defined ( OSD_ATOMIC_INLINE ) */
|
||||
|
||||
# define epicsAtomicIncrSizeT epicsLockedIncrSizeT
|
||||
# define epicsAtomicDecrSizeT epicsLockedDecrSizeT
|
||||
# define epicsAtomicSetSizeT epicsLockedSetSizeT
|
||||
# define epicsAtomicSetUIntT epicsLockedSetUIntT
|
||||
# define epicsAtomicSetPtrT epicsLockedSetPtrT
|
||||
# define epicsAtomicGetSizeT epicsLockedGetSizeT
|
||||
# define epicsAtomicGetUIntT epicsLockedGetUIntT
|
||||
# define epicsAtomicGetPtrT epicsLockedGetPtrT
|
||||
# define epicsAtomicCmpAndSwapUIntT epicsLockedCmpAndSwapUIntT
|
||||
# define epicsAtomicCmpAndSwapPtrT epicsLockedCmpAndSwapPtrT
|
||||
|
||||
#endif /* if defined ( OSD_ATOMIC_INLINE ) */
|
||||
} // end of extern "C"
|
||||
|
||||
#endif /* epicsAtomicLocked_h */
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OSD_ATOMIC_INLINE_DEFINITION
|
||||
|
||||
/*
|
||||
* mingw doesnt currently provide MemoryBarrier
|
||||
* (this is mostly for testing purposes as the gnu
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2011 LANS LLC, as Operator of
|
||||
* Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsAtomic.h"
|
||||
|
||||
//
|
||||
// We need a default epicsAtopmicOSD.cpp which is empty for use when
|
||||
// a compiler or inline OS specific implementation is provided. See
|
||||
// "osi/os/posix/epicsAtomicOSD.cpp" for an example OS specific generic
|
||||
// out-of-line implementation based on a mutex lock.
|
||||
//
|
||||
#if ! defined ( OSD_ATOMIC_INLINE_DEFINITION )
|
||||
# error the epicsAtomicXxxxx functions definitions are misssing
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,4 @@
|
||||
#ifndef epicsAtomicOSD_h
|
||||
#define epicsAtomicOSD_h
|
||||
|
||||
#include "epicsAtomicLocked.h"
|
||||
|
||||
#endif /* epicsAtomicOSD_h */
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2011 LANS LLC, as Operator of
|
||||
* Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*
|
||||
* Provide a global mutex version of AtomicGuard on POSIX
|
||||
* systems for when we dont have more efficent compiler or
|
||||
* OS primitives intriniscs to use instead.
|
||||
*
|
||||
* We implement this mutex-based AtomicGuard primitive directly
|
||||
* upon the standalone POSIX pthread library so that the epicsAtomic
|
||||
* library can be used to implement other primitives such
|
||||
* epicsThreadOnce.
|
||||
*
|
||||
* We use a static initialized pthread mutex to minimize code
|
||||
* size, and are also optimistic that this can be more efficent
|
||||
* than pthread_once.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsAtomic.h"
|
||||
|
||||
// If we have an inline implementation then implement
|
||||
// nothing that conflicts here
|
||||
#if ! defined ( OSD_ATOMIC_INLINE_DEFINITION )
|
||||
|
||||
// get the interface for class AtomicGuard
|
||||
#include "epicsAtomicGuard.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// a statically initialized mutex doesnt need to be destroyed
|
||||
static pthread_mutex_t AtomicGuard :: mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
inline AtomicGuard :: AtomicGuard () throw ()
|
||||
{
|
||||
unsigned countDown = 1000u;
|
||||
while ( true ) {
|
||||
status = pthread_mutex_lock ( & mutex );
|
||||
if ( status != EINTR ) break;
|
||||
static const useconds_t retryDelayUSec = 100000;
|
||||
usleep ( retryDelayUSec );
|
||||
countDown--;
|
||||
assert ( countDown );
|
||||
}
|
||||
assert ( status == 0 );
|
||||
}
|
||||
|
||||
inline AtomicGuard :: ~AtomicGuard () throw ()
|
||||
{
|
||||
const int status = pthread_mutex_unlock ( & mutex );
|
||||
assert ( status == 0 );
|
||||
}
|
||||
|
||||
} // end of namespace anonymous
|
||||
|
||||
// Define the epicsAtomicXxxx functions out-of-line using this
|
||||
// implementation of AtomicGuard. Note that this isnt a traditional
|
||||
// c++ header file.
|
||||
#include "epicsAtomicLocked.h"
|
||||
|
||||
#endif // if ! defined ( #define OSD_ATOMIC_INLINE_DEFINITION )
|
||||
@@ -29,6 +29,8 @@
|
||||
#define __STDC_LIMIT_MACROS /* define SIZE_MAX for c++ */
|
||||
#include <stdint.h>
|
||||
|
||||
#define OSD_ATOMIC_INLINE_DEFINITION
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
@@ -97,10 +99,6 @@ OSD_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * p
|
||||
} /* end of extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#else /* ifdef __SunOS_5_10 */
|
||||
|
||||
#include "epicsAtomicLocked.h"
|
||||
|
||||
#endif /* ifdef __SunOS_5_10 */
|
||||
|
||||
#endif /* if defined ( OSD_ATOMIC_INLINE ) */
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <vxAtomicLib.h>
|
||||
|
||||
#define OSD_ATOMIC_INLINE_DEFINITION
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user