Compare commits
104 Commits
sync_with_
...
PSI-7.0.8.
| Author | SHA1 | Date | |
|---|---|---|---|
| 54117d5371 | |||
| cc134d4649 | |||
| 012c4c73f1 | |||
| 96864abb6c | |||
| ad00947d48 | |||
| 2db99d46a7 | |||
| 11661455f1 | |||
| ecb02803c8 | |||
| fcb720275a | |||
| 87d492bffd | |||
|
|
1a9dc993c1 | ||
| b379c6f3a5 | |||
| da010afde9 | |||
| cb710920d0 | |||
| 87dea74dcd | |||
| d35c7fe5eb | |||
| c5469efca1 | |||
| fd436c40e8 | |||
| 8557d8adce | |||
| a0c55f597b | |||
| 9090f54f45 | |||
| 6085f9eb0b | |||
| a1de706d2c | |||
| 0b12a0cf7e | |||
|
|
cb1571783b | ||
|
|
5dfc6caf3c | ||
|
|
cb49bd0133 | ||
|
|
4720b61c1f | ||
| 4383cf291e | |||
|
|
a6977ae731 | ||
| e9dcdd8936 | |||
|
|
07cbf00187 | ||
|
|
c75b9ad0be | ||
|
|
87acb98d1e | ||
|
|
403e203325 | ||
|
|
a7a56912eb | ||
|
|
fe4a32e425 | ||
|
|
823386573f | ||
|
|
ea8247586f | ||
|
|
e88a186fc3 | ||
|
|
20f32068c3 | ||
|
|
8998341588 | ||
|
|
448fde0671 | ||
|
|
477e36b1f0 | ||
|
|
fad830bd14 | ||
|
|
331df3d7e4 | ||
|
|
4a53713f37 | ||
|
|
2e6fd505d2 | ||
|
|
5ecf7d18a8 | ||
|
|
56dbc949ff | ||
| e2bb42d8d3 | |||
| abcada0d85 | |||
| 2c35d60a64 | |||
| af1b77eb0f | |||
| 93947eb027 | |||
|
|
6a369acd0b | ||
| 961671259f | |||
|
|
db2482117d | ||
| a66caa5985 | |||
| 4803aae904 | |||
| 427be18e2e | |||
| fff690a449 | |||
| 428b836500 | |||
| 6c74507b11 | |||
| 122ca4e1d3 | |||
|
|
d9d35a4eab | ||
|
|
116881ad87 | ||
| 96857d92bc | |||
|
|
0cf8c934f9 | ||
|
|
69d05fe5b0 | ||
|
|
511bf1ffca | ||
|
|
7a7028de56 | ||
|
|
7a65c001ce | ||
|
|
0bc6ff3d4c | ||
|
|
f2fe9d1203 | ||
|
|
ffc2d0f23a | ||
|
|
a352865df9 | ||
|
|
63740f2edd | ||
|
|
f4be9daf4d | ||
|
|
3fa1932345 | ||
|
|
95bd5453d9 | ||
|
|
eb3f8a004c | ||
|
|
9f868a1074 | ||
|
|
b41787b6bf | ||
| 19b232545c | |||
|
|
2ca70d3aa2 | ||
|
|
395015aac4 | ||
|
|
92cae86ff2 | ||
|
|
49ea46ee5e | ||
|
|
df908f299b | ||
|
|
6dec68554c | ||
|
|
badd8f518d | ||
|
|
766c9906b5 | ||
|
|
60fa2d31da | ||
|
|
88ea1507f4 | ||
|
|
8c08c57247 | ||
|
|
45b3bce515 | ||
|
|
7c4a21eab4 | ||
|
|
fab8fd7102 | ||
|
|
3d25756065 | ||
|
|
5aca4c684c | ||
|
|
39b5c01c5d | ||
|
|
3b22e5f710 | ||
|
|
9f660f2238 |
1
.github/workflows/ci-scripts-build.yml
vendored
1
.github/workflows/ci-scripts-build.yml
vendored
@@ -29,6 +29,7 @@ on:
|
||||
- '.gitattributes'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
SETUP_PATH: .ci-local:.ci
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -18,3 +18,7 @@ O.*/
|
||||
.*.swp
|
||||
.DS_Store
|
||||
.iocsh_history
|
||||
RPMS
|
||||
SRPMS
|
||||
BUILDROOT
|
||||
*.rpm
|
||||
|
||||
3
Makefile
3
Makefile
@@ -30,3 +30,6 @@ copysrc:
|
||||
|
||||
tar:
|
||||
tar cfjP epics_base-$(EPICS_VERSION_NUMBER).tar.bz2 $(INSTALL_LOCATION)
|
||||
|
||||
rpm:
|
||||
rpmbuild -bb epics-base.spec
|
||||
|
||||
@@ -48,7 +48,7 @@ EPICS_VERSION = 7
|
||||
EPICS_REVISION = 0
|
||||
|
||||
# EPICS_MODIFICATION must be a number >=0 and <256
|
||||
EPICS_MODIFICATION = 7
|
||||
EPICS_MODIFICATION = 8
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included in the official EPICS version number if zero
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
EPICS_CA_MAJOR_VERSION = 4
|
||||
EPICS_CA_MINOR_VERSION = 14
|
||||
EPICS_CA_MAINTENANCE_VERSION = 3
|
||||
EPICS_CA_MAINTENANCE_VERSION = 4
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
|
||||
@@ -422,10 +422,10 @@ INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS)))
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Installed file permissions
|
||||
BIN_PERMISSIONS = 555
|
||||
LIB_PERMISSIONS = 444
|
||||
SHRLIB_PERMISSIONS = 555
|
||||
INSTALL_PERMISSIONS = 444
|
||||
BIN_PERMISSIONS = 755
|
||||
LIB_PERMISSIONS = 644
|
||||
SHRLIB_PERMISSIONS = 755
|
||||
INSTALL_PERMISSIONS = 644
|
||||
|
||||
#---------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Version number for the database APIs and shared library
|
||||
|
||||
EPICS_DATABASE_MAJOR_VERSION = 3
|
||||
EPICS_DATABASE_MINOR_VERSION = 22
|
||||
EPICS_DATABASE_MINOR_VERSION = 23
|
||||
EPICS_DATABASE_MAINTENANCE_VERSION = 1
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Version number for the libcom APIs and shared library
|
||||
|
||||
EPICS_LIBCOM_MAJOR_VERSION = 3
|
||||
EPICS_LIBCOM_MINOR_VERSION = 22
|
||||
EPICS_LIBCOM_MINOR_VERSION = 23
|
||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
@@ -514,6 +514,13 @@ ifneq (,$(strip $(SHRLIB_VERSION)))
|
||||
@$(RM) $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
ln -s $< $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
endif # SHRLIB_VERSION
|
||||
else # SHRLIB_SUFFIX
|
||||
ifeq ($(BUILD_CLASS),HOST)
|
||||
ifneq (,$(strip $(SHRLIB_VERSION)))
|
||||
@$(RM) $@.$(SHRLIB_VERSION)
|
||||
ln -s $< $@.$(SHRLIB_VERSION)
|
||||
endif # HOST
|
||||
endif # SHRLIB_VERSION
|
||||
endif # SHRLIB_SUFFIX
|
||||
|
||||
ifneq ($(INSTALL_TCLLIB),$(INSTALL_BIN))
|
||||
@@ -545,11 +552,11 @@ endif # LOADABLE_SHRLIB_SUFFIX
|
||||
ifneq ($(INSTALL_CONFIGS),)
|
||||
$(INSTALL_CONFIG)/%: %
|
||||
$(ECHO) "Installing config file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D))
|
||||
|
||||
$(INSTALL_CONFIG)/%: ../%
|
||||
$(ECHO) "Installing config file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D))
|
||||
endif
|
||||
|
||||
$(INSTALL_INCLUDE)/%: $(COMMON_DIR)/%
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
TOOLSET_LOCATION = /opt/rh
|
||||
TOOLSET = devtoolset-12
|
||||
STD_CXXFLAGS = -std=c++20
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
TOOLSET_LOCATION = /opt/rh
|
||||
TOOLSET = gcc-toolset-12
|
||||
STD_CXXFLAGS = -std=c++20
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
STD_CXXFLAGS = -std=c++2a
|
||||
|
||||
20
configure/os/CONFIG.Common.RHEL9-x86_64
Normal file
20
configure/os/CONFIG.Common.RHEL9-x86_64
Normal file
@@ -0,0 +1,20 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
TOOLSET_LOCATION = /opt/rh
|
||||
TOOLSET = gcc-toolset-12
|
||||
STD_CXXFLAGS = -std=c++20
|
||||
|
||||
# Fix bug in gcc-toolset-11 calling the old assembler
|
||||
ifneq ($(filter %-11,$(TOOLSET)),)
|
||||
TARGET_CPPFLAGS += $(TOOLSET_DIR:%=-B$(SYSROOT)%/bin)
|
||||
TARGET_LDFLAGS += $(TOOLSET_DIR:%=-B$(SYSROOT)%/bin)
|
||||
endif
|
||||
|
||||
ifneq (($(TOOLSET)),)
|
||||
# Perl requests (native) annobin incompatible with the annobin from any TOOLSET
|
||||
# Disable Perl specific CFLAGS
|
||||
override Cap5_CFLAGS=
|
||||
endif
|
||||
5
configure/os/CONFIG.Common.RHEL9-x86_64-clang
Normal file
5
configure/os/CONFIG.Common.RHEL9-x86_64-clang
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
|
||||
STD_CXXFLAGS = -std=c++2a
|
||||
@@ -1,6 +1,6 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 5.5.1
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/Tornado2.2.1
|
||||
WIND_BASE = /opt/VxWorks/Tornado2.2.1
|
||||
|
||||
#there is a problem with our ccppc and optimization
|
||||
# -O0 works, -O and -O1 and higher are buggy
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32
|
||||
VXWORKS_VERSION = 6.9
|
||||
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
#export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH:%=%:)$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.9
|
||||
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
#export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH:%=%:)($(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
|
||||
# -fno-implicit-fp causes error: "unable to find a register to spill in class 'FLOAT_REGS'"
|
||||
ARCH_DEP_CFLAGS = -mcpu=604 -mstrict-align
|
||||
|
||||
@@ -5,18 +5,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = x86_64
|
||||
|
||||
LDLIBS_SHARED_YES=LDLIBS
|
||||
|
||||
SDK = gcc
|
||||
SDK_DIR = /opt/xgcc/gcc-8.3.0-deb10
|
||||
GNU_ARCH = x86_64-deb10-linux-gnu
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
|
||||
GNU_DIR = $(SDK_DIR)
|
||||
GNU_BIN = $(GNU_DIR)/bin/
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=x86_64-deb10-linux-gnu
|
||||
|
||||
ARCH_DEP_CPPFLAGS =
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
GNU_DIR = /opt/xgcc/gcc-8.3.0-deb10
|
||||
GNU_TARGET = x86_64-deb10-linux-gnu
|
||||
|
||||
STD_CXXFLAGS = -std=c++17
|
||||
|
||||
@@ -5,17 +5,10 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = gcc
|
||||
SDK_DIR = /opt/xgcc/gcc-8.5.0
|
||||
GNU_ARCH = powerpc-ppmac-linux-gnu
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
|
||||
GNU_DIR = $(SDK_DIR)
|
||||
GNU_BIN = $(GNU_DIR)/bin/
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=powerpc-ppmac-linux-gnu
|
||||
GNU_DIR = /opt/xgcc/gcc-8.5.0
|
||||
GNU_TARGET = powerpc-ppmac-linux-gnu
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath,/opt/xgcc/gcc-8.5.0/$(GNU_ARCH)/lib
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/lib/powerpc-linux-gnu/
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/usr/lib/powerpc-linux-gnu/
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(GNU_DIR)/$(GNU_TARGET)/sys-root/lib/powerpc-linux-gnu
|
||||
|
||||
STD_CXXFLAGS = -std=c++17
|
||||
|
||||
@@ -24,13 +24,13 @@ STATIC_LDFLAGS_NO=
|
||||
STATIC_LDLIBS_YES= -Wl,-Bdynamic
|
||||
|
||||
# Set runtime path for shared libraries if LINKER_USE_RPATH=YES
|
||||
SHRLIBDIR_RPATH_LDFLAGS_YES = $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%)
|
||||
SHRLIBDIR_RPATH_LDFLAGS_YES = $(subst $(abspath $(LINKER_ORIGIN_ROOT)),$(FINAL_LOCATION),$(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%)) $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)
|
||||
SHRLIBDIR_RPATH_LDFLAGS_ORIGIN = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(SHRLIB_DEPLIB_DIRS))
|
||||
SHRLIBDIR_LDFLAGS += \
|
||||
$(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH))
|
||||
|
||||
# Set runtime path for products if LINKER_USE_RPATH=YES
|
||||
PRODDIR_RPATH_LDFLAGS_YES = $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%)
|
||||
PRODDIR_RPATH_LDFLAGS_YES = $(subst $(abspath $(LINKER_ORIGIN_ROOT)),$(FINAL_LOCATION),$(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%)) $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)
|
||||
PRODDIR_RPATH_LDFLAGS_ORIGIN = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(PROD_DEPLIB_DIRS))
|
||||
PRODDIR_LDFLAGS += \
|
||||
$(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH))
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
# Include definitions common to all Linux ARM targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-arm
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/arm-linux-4.4.2-v4
|
||||
GNU_DIR=/opt/moxa/arm-linux-4.4.2-v4
|
||||
GNU_TARGET=arm
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(GNU_DIR)/arm-none-linux-gnueabi/lib
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
ARCH_CLASS = xscale
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/xscale_be/armv5teb-montavista-linuxeabi
|
||||
GNU_DIR=/opt/moxa/xscale_be/armv5teb-montavista-linuxeabi
|
||||
|
||||
ARCH_DEP_CFLAGS += -funwind-tables
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# National Instruments CompactRIO running LabView RT 19.5.1
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
@@ -8,10 +9,13 @@ ARCH_CLASS = arm
|
||||
GNU_TARGET = arm-linux-gnu
|
||||
|
||||
SYSROOT = /opt/LabVIEW-RT-19.5.1/arm/sysroots/armv7a-vfp-neon-nilrt-linux-gnueabi
|
||||
GNU_BIN = /bin
|
||||
GNU_BIN = /opt/RHEL7/bin
|
||||
|
||||
# Needed on RHEL9:
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)/usr/$$LIB:/opt/RHEL7/$$LIB
|
||||
|
||||
ARCH_DEP_CPPFLAGS += -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon
|
||||
ARCH_DEP_CXXFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/arm-nilrt-linux-gnueabi/
|
||||
ARCH_DEP_CXXFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/
|
||||
ARCH_DEP_CXXFLAGS += -I=/usr/include/c++/4.7.2/arm-nilrt-linux-gnueabi
|
||||
ARCH_DEP_CXXFLAGS += -I=/usr/include/c++/4.7.2
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
@@ -10,13 +10,13 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
# Due to missing/messed up libs in the toolchain, readline needs copies of
|
||||
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
|
||||
# /lib/arm-linux-gnueabihf/ to the toolchain, e.g.
|
||||
# $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
|
||||
# $(SDK_DIR)/$(SDK_TARGET)/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
|
||||
# and manually created links libtinfo.so.5 and libreadline.so.
|
||||
# For gcc-linaro-arm-linux-gnueabihf-raspbian, an existing incompatible
|
||||
# libtinfo.so.5 is in the way. Remove it.
|
||||
# (Built with glibc 2.16 like installed on Raspbian 9 but toolchain uses glibc 2.13.)
|
||||
# Also copy /usr/include/readline/ directory from some readline 6 installation
|
||||
# to $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/usr/include/
|
||||
# to $(SDK_DIR)/$(SDK_TARGET)/arm-linux-gnueabihf/libc/usr/include/
|
||||
|
||||
ARCH_CLASS = arm
|
||||
|
||||
@@ -25,10 +25,10 @@ SDK_DIR = /opt/raspberrypi/arm-bcm2708
|
||||
# Available SDK_TARGETs:
|
||||
|
||||
# gcc 4.8.3 for 32 bit hosts with GLIBC 2.3 or higher
|
||||
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
|
||||
# gcc 4.8.3 for 64 bit hosts with GLIBC 2.14 or higher
|
||||
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
|
||||
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
|
||||
|
||||
# gcc 4.7.1 for 64 bit hosts with GLIBC 2.8 or higher
|
||||
# SDK_TARGET = arm-linux-gnueabihf
|
||||
@@ -37,5 +37,8 @@ SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
# SDK_TARGET = arm-bcm2708hardfp-linux-gnueabi
|
||||
# SDK_TARGET = arm-bcm2708-linux-gnueabi
|
||||
|
||||
# gcc 4.9.3 for 64 bit hosts
|
||||
# arm-rpi-4.9.3-linux-gnueabihf
|
||||
|
||||
GNU_DIR = $(SDK_DIR)/$(SDK_TARGET)
|
||||
GNU_TARGET = $(if $(filter arm-bcm2708%,SDK_TARGET),$(SDK_TARGET),arm-linux-gnueabihf)
|
||||
|
||||
@@ -2,5 +2,9 @@ include $(CONFIG)/os/CONFIG.windows-x64.windows-x64
|
||||
|
||||
VALID_BUILDS = Ioc Command
|
||||
|
||||
PATH := /opt/wine-msvc-2017/bin/x64:$(PATH)
|
||||
MSVC_VERSION ?= 2019
|
||||
PATH := /opt/gfa-wine/bin:/opt/wine-msvc-$(MSVC_VERSION)/bin/x64:$(PATH)
|
||||
export WINEPREFIX = $(HOME)/.wine-$(EPICS_HOST_ARCH)
|
||||
export WINEDEBUG=fixme-all
|
||||
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||
export WINE = wine64
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
# MSVC_VERSION 2019 in wine 4 for on RHEL7 would require winetricks
|
||||
MSVC_VERSION = 2017
|
||||
include $(CONFIG)/os/CONFIG.Linux.windows-x64
|
||||
|
||||
@@ -12,7 +12,10 @@ include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
SYSROOT = /opt/RHEL7
|
||||
|
||||
# "Cross" TOOLSET progs need to find their libraries
|
||||
LD_LIBRARY_PATH = $(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB)
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB)
|
||||
|
||||
# The linker has problems to find indirectly referenced libraries
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
|
||||
|
||||
# These programs have library problems when using them
|
||||
# from SYSROOT but without TOOLSET.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
GNU_BIN = /opt/RHEL7/bin
|
||||
3
configure/os/CONFIG.RHEL9-x86_64.Common
Normal file
3
configure/os/CONFIG.RHEL9-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
18
configure/os/CONFIG.RHEL9-x86_64.RHEL7-x86_64
Normal file
18
configure/os/CONFIG.RHEL9-x86_64.RHEL7-x86_64
Normal file
@@ -0,0 +1,18 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
|
||||
# "Cross compile" for RHEL7-x86_64
|
||||
# Expects RHEL7 RPMs c++ and readline-devel installed
|
||||
# in $(SYSROOT)
|
||||
# This can be installed on RHEL7 with:
|
||||
# yum install --installroot=$(SYSROOT) <packages>
|
||||
# (Assuming $(SYSROOT) is on a shared network volume.)
|
||||
# Optionally use a newer TOOLSET (installed on $(SYSROOT)).
|
||||
|
||||
SYSROOT = /opt/RHEL7
|
||||
|
||||
# "Cross" TOOLSET progs need to find their libraries
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB:)/usr/$$LIB:$(SYSROOT)/usr/$$LIB
|
||||
|
||||
# The linker has problems to find indirectly referenced libraries
|
||||
PROD_LDLIBS += $(LDLIBS)
|
||||
22
configure/os/CONFIG.RHEL9-x86_64.RHEL8-x86_64
Normal file
22
configure/os/CONFIG.RHEL9-x86_64.RHEL8-x86_64
Normal file
@@ -0,0 +1,22 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
|
||||
# "Cross compile" for RHEL8-x86_64
|
||||
# Expects RHEL8 RPMs gcc-toolset-12-gcc-c++ and readline-devel
|
||||
# to be installed in $(SYSROOT)
|
||||
# These can be installed on RHEL8 with:
|
||||
# yum install --installroot=$(SYSROOT) <packages>
|
||||
# (Assuming $(SYSROOT) is on a shared network volume.)
|
||||
|
||||
SYSROOT = /opt/RHEL8
|
||||
|
||||
# "Cross" TOOLSET progs need to find their libraries.
|
||||
# But linker gets confused with LD_LIBRARY_PATH.
|
||||
# Thus only wrap the compiler.
|
||||
WRAPPER = -wrapper env,LD_LIBRARY_PATH=$(TOOLSET_DIR:%=$(SYSROOT)%/usr/lib64:)/usr/lib64:$(SYSROOT)/usr/lib64
|
||||
TARGET_CPPFLAGS += $(WRAPPER)
|
||||
|
||||
# These programs as cross tools would also need LD_LIBRARY_PATH.
|
||||
# But but our host versions work just fine.
|
||||
AR = ar -rc
|
||||
RANLIB = ranlib
|
||||
2
configure/os/CONFIG.RHEL9-x86_64.RHEL9-x86_64
Normal file
2
configure/os/CONFIG.RHEL9-x86_64.RHEL9-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
1
configure/os/CONFIG.RHEL9-x86_64.windows-x64
Normal file
1
configure/os/CONFIG.RHEL9-x86_64.windows-x64
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Linux.windows-x64
|
||||
@@ -16,7 +16,7 @@ OPT_WHOLE_PROGRAM = YES
|
||||
|
||||
WINLINK = link
|
||||
|
||||
RCCMD = rc -l 0x409 $(INCLUDES) -fo $@ $<
|
||||
RCCMD = rc -nologo -l 0x409 $(INCLUDES) -fo $@ $<
|
||||
|
||||
ARCMD = lib -nologo -verbose -out:$@ $(LIB_OPT_LDFLAGS) $(LIBRARY_LD_OBJS)
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
@@ -87,11 +87,14 @@ CODE_CXXFLAGS =
|
||||
#WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
|
||||
#WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION)
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/VxWorks$(VXWORKS_VERSION)
|
||||
WIND_BASE = /opt/VxWorks/VxWorks$(VXWORKS_VERSION)
|
||||
|
||||
#--------------------------------------------------
|
||||
# Modules we cannot build with old compiler
|
||||
|
||||
# For the license counter
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
|
||||
PV_MODULES = pv% normativeTypes
|
||||
SKIP_BUILDS_5 = $(PV_MODULES)
|
||||
SKIP_BUILDS_OLD = $(PV_MODULES)
|
||||
|
||||
@@ -3,8 +3,3 @@ include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64-clang
|
||||
CROSS_COMPILER_RUNTEST_ARCHS += RHEL7-x86_64-clang
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
# Not available on RHEL8
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
|
||||
@@ -5,7 +5,3 @@ CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64-clang
|
||||
|
||||
# Build for old RHEL7 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
|
||||
10
configure/os/CONFIG_SITE.RHEL9-x86_64.Common
Normal file
10
configure/os/CONFIG_SITE.RHEL9-x86_64.Common
Normal file
@@ -0,0 +1,10 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL9-x86_64-clang
|
||||
|
||||
# Build for old RHEL8 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64
|
||||
|
||||
# Build for old RHEL7 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64
|
||||
5
configure/os/CONFIG_SITE.UnixCommon.Common
Normal file
5
configure/os/CONFIG_SITE.UnixCommon.Common
Normal file
@@ -0,0 +1,5 @@
|
||||
# Make sure hosts tools find their libraries during build
|
||||
# even if FINAL_LOCATION differs from INSTALL_LOCATION
|
||||
ifneq ($(FINAL_LOCATION:$(INSTALL_LOCATION)=),)
|
||||
export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH:%=%:)$(INSTALL_HOST_LIB)
|
||||
endif
|
||||
@@ -11,10 +11,6 @@ INSTALL_LOCATION=/usr/local/epics/base-$(EPICS_VERSION).$(EPICS_REVISION).$(EPIC
|
||||
GNU_HOST_ARCH=i686
|
||||
GNU_HOST_OS=linux
|
||||
|
||||
# set LD_LIBRARY_PATH may cause problems for eldk53-ppc4xxFP
|
||||
# not exported LD_LIBRARY_PATH causes problem for RHEL7 cross compilation
|
||||
export LD_LIBRARY_PATH=
|
||||
|
||||
# vxWorks for MVxxxx boards
|
||||
#CROSS_COMPILER_TARGET_ARCHS += T2-ppc604
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V67-ppc604
|
||||
@@ -38,7 +34,7 @@ CROSS_COMPILER_TARGET_ARCHS += eldk52-e500v2
|
||||
|
||||
# DeltaTau PowerPMAC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
|
||||
#CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
|
||||
|
||||
# Test other vxWorks versions
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V66-ppc603
|
||||
@@ -48,9 +44,6 @@ CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
|
||||
# (No PVA because of old compiler)
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V62-ppc604
|
||||
|
||||
# Raspberry Pi
|
||||
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
|
||||
|
||||
# RTEMS (Can only have 1 RTEMS major version in 1 EPICS installation
|
||||
# because they overwrite their header files.)
|
||||
#CROSS_COMPILER_TARGET_ARCHS += RTEMS49-pc386
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Needed by gcc
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH):$(RTEMS_BASE)/lib
|
||||
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(RTEMS_BASE)/lib
|
||||
|
||||
|
||||
@@ -25,4 +25,10 @@ CROSS_COMPILER_TARGET_ARCHS += yocto40-aarch64
|
||||
CROSS_COMPILER_TARGET_ARCHS += deb10-x86_64
|
||||
|
||||
# Newer DeltaTau PowerPMAC
|
||||
#CROSS_COMPILER_TARGET_ARCHS += gcc8-ppc4xxFP
|
||||
CROSS_COMPILER_TARGET_ARCHS += gcc8-ppc4xxFP
|
||||
|
||||
# Raspberry Pi
|
||||
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
|
||||
@@ -20,7 +20,68 @@ should also be read to understand what has changed since earlier releases:
|
||||
|
||||
**This version of EPICS has not been released yet.**
|
||||
|
||||
## Changes made on the 7.0 branch since 7.0.7
|
||||
## Changes made on the 7.0 branch since 7.0.8
|
||||
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.8
|
||||
|
||||
### bi "Raw Soft Channel" use MASK
|
||||
|
||||
If MASK is non-zero, The raw device support will now apply MASK to the
|
||||
value read into RVAL.
|
||||
eg. allows extraction of a bit from an input integer.
|
||||
|
||||
```
|
||||
record(longin, "integer") {
|
||||
field(VAL, "0xff")
|
||||
}
|
||||
record(bi, "bit1") {
|
||||
field(DESC, "extract bit 1")
|
||||
field(DTYP, "Raw Soft Channel")
|
||||
field(INP , "integer")
|
||||
field(MASK, "0x2")
|
||||
field(ZNAM, "Clear")
|
||||
field(ONAM, "Set")
|
||||
}
|
||||
```
|
||||
|
||||
### ANSI escapes in stderr
|
||||
|
||||
ANSI escape charactor sequences may now be printed to the stderr stream.
|
||||
These escapes will appear in logs captured from that stream.
|
||||
Tools which parse and/or render these logs may need to be adjusted to
|
||||
either strip out the escapes, or to translate them into markup.
|
||||
(see [ansi2html](https://pypi.org/project/ansi2html/) for example)
|
||||
|
||||
### Allow explicit append with `dbRecordsOnceOnly!=0`
|
||||
|
||||
Previously setting `dbRecordsOnceOnly!=0` prevented any further changes to a record via a .db file. eg.
|
||||
|
||||
```
|
||||
record(ai, "myrec") {}
|
||||
```
|
||||
|
||||
`dbRecordsOnceOnly!=0` previously disallowed appending fields with either form:
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # error
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
Beginning with this release, `dbRecordsOnceOnly!=0` allows appending when explicitly intended (when record type is `"*"`).
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # allowed
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
### PROC field changed to ASL0
|
||||
|
||||
The PROC field has been changed from access security level ASL1 to ASL0.
|
||||
This allows users to trigger processing a record without having the rights
|
||||
to reconfigure the records.
|
||||
|
||||
### bi "Raw Soft Channel" use MASK
|
||||
|
||||
|
||||
@@ -48,14 +48,14 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<p>The following roles are used below:</p>
|
||||
|
||||
<dl>
|
||||
<dt><strong>Release Manager</strong> ()</dt>
|
||||
<dt><strong>Release Manager</strong></dt>
|
||||
<dd>Responsible for managing and tagging the release</dd>
|
||||
<dt><strong>Platform Developers</strong> (informal)</dt>
|
||||
<dd>Responsible for individual operating system platforms</dd>
|
||||
<dt><strong>Core Developers</strong></dt>
|
||||
<dd>Responsible for maintaining the EPICS software</dd>
|
||||
<dt><strong>Application Developers</strong></dt>
|
||||
<dd>Responsible for support modules that depend on EPICS Base.</dd>
|
||||
<dt><strong>APS Website Editor</strong> (Andrew Johnson)</dt>
|
||||
<dd>Responsible for the APS EPICS website</dd>
|
||||
<dt><strong>Website Editors</strong></dt>
|
||||
<dd>Responsible for the EPICS websites</dd>
|
||||
</dl>
|
||||
|
||||
<form>
|
||||
@@ -72,23 +72,22 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
<td>Email all developers about the upcoming release and ask for a list
|
||||
of remaining tasks that must be finished.</td>
|
||||
<td>Notify core developers about the upcoming release and ask about any
|
||||
remaining tasks that must be finished.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>All developers</td>
|
||||
<td>Check the bug tracker for any outstanding items and handle
|
||||
appropriately. All bugs that have been fixed should have been marked
|
||||
as Fix Committed.</td>
|
||||
appropriately.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
<td>Set the Feature Freeze date, by which time all Git commits for
|
||||
enhancements and new functionality should have been completed. After
|
||||
this date, commits should only be made to fix problems that show up
|
||||
during testing.</td>
|
||||
<td>Set a Feature Freeze date, by which time all Git branches for
|
||||
enhancements and new functionality should have been merged. After this
|
||||
date, commits and merges should only be made to fix problems that show
|
||||
up during testing.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
@@ -97,6 +96,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Ensure that documentation will be updated before the release date:
|
||||
<ul>
|
||||
<li>Release Notes</li>
|
||||
<li>Doxygen annotations</li>
|
||||
<li>Other documents</li>
|
||||
</ul>
|
||||
</td>
|
||||
@@ -104,13 +104,8 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
<td>Review and update this checklist for the upcoming release.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
<td>Create a release milestone on Launchpad. If a target release date is
|
||||
known set "Date Targeted" to the expected release date.</td>
|
||||
<td>Review and update this checklist for the upcoming release.
|
||||
Update the release version number in the tags and messages below.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3">Testing</th>
|
||||
@@ -118,7 +113,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Platform Developers</td>
|
||||
<td>Run the built-in test programs on all available host platforms using
|
||||
<td>Run the internal test programs on all available host platforms using
|
||||
<blockquote><tt>
|
||||
make -s runtests
|
||||
</tt></blockquote></td>
|
||||
@@ -156,6 +151,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Check that documentation has been updated:
|
||||
<ul>
|
||||
<li>Release Notes</li>
|
||||
<li>Doxygen annotations</li>
|
||||
<li>Other documents</li>
|
||||
</ul>
|
||||
</td>
|
||||
@@ -167,8 +163,8 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Obtain a positive <q>Ok to release</q> from developers.</td>
|
||||
<td>Core Developers</td>
|
||||
<td>Reach a consensus that the software is ready to release.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3">Creating the final release version</th>
|
||||
@@ -191,27 +187,29 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
cd base-7.0/modules/<module>/documentation<br />
|
||||
pandoc -f gfm -t html -o RELEASE_NOTES.html RELEASE_NOTES.md
|
||||
</tt></blockquote>
|
||||
Commit changes (don't push).</li>
|
||||
Commit these changes (don't push).</li>
|
||||
|
||||
<li>Edit the module's release version file
|
||||
<tt>configure/CONFIG_<i>module</i>_VERSION</tt> and its top-level
|
||||
<tt>Doxyfile</tt>; set the <tt>DEVELOPMENT_FLAG</tt> value to 0 and
|
||||
remove <tt>-dev</tt> from the <tt>PROJECT_NUMBER</tt> string.
|
||||
Commit changes (don't push).</li>
|
||||
<tt>configure/CONFIG_<i>module</i>_VERSION</tt> and the
|
||||
<tt>Doxyfile</tt>s in the top-level and/or documentation
|
||||
directories. In these, set <tt>DEVELOPMENT_FLAG</tt> to 0 and remove
|
||||
<tt>-dev</tt> from the <tt>PROJECT_NUMBER</tt> string. Commit these
|
||||
changes (don't push).</li>
|
||||
|
||||
<li>Tag the module:
|
||||
<blockquote><tt>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.7' <module-version>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.8' <module-version>
|
||||
</tt></blockquote>
|
||||
</li>
|
||||
|
||||
<li>Update the git submodule on the Base-7.0 branch to the
|
||||
newly-tagged version, but don't commit yet:
|
||||
newly-tagged version, check the module's status matches the tag:
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules<br />
|
||||
git add <module><br />
|
||||
git submodule status --cached
|
||||
</tt></blockquote>
|
||||
Don't commit the submodule updates yet.
|
||||
</li>
|
||||
|
||||
<li>Edit the module's release version file
|
||||
@@ -221,7 +219,8 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tt>PROJECT_NUMBER</tt> string, appending <tt>-dev</tt> to the new
|
||||
module version number. Commit changes.</li>
|
||||
|
||||
<li>Push commits and the new tag to the submodule's GitHub repository:
|
||||
<li>Push commits and the new tag to the submodule's GitHub repository
|
||||
(assumed to be the <tt>upstream</tt> remote):
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules/<module><br />
|
||||
git push --follow-tags upstream master
|
||||
@@ -270,10 +269,9 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Tag the epics-base module in Git:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.7
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.8
|
||||
</tt></blockquote>
|
||||
<p>Don't push anything to the Launchpad repository
|
||||
yet.</p>
|
||||
<p>Don't push to GitHub yet.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -305,12 +303,12 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
files and directories that are only used for continuous integration:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
./.tools/make-tar.sh R7.0.7 ../base-7.0.7.tar.gz base-7.0.7/
|
||||
./.tools/make-tar.sh R7.0.8 ../base-7.0.8.tar.gz base-7.0.8/
|
||||
</tt></blockquote>
|
||||
Create a GPG signature file of the tarfile as follows:
|
||||
<blockquote><tt>
|
||||
cd ..<br />
|
||||
gpg --armor --sign --detach-sig base-7.0.7.tar.gz
|
||||
gpg --armor --sign --detach-sig base-7.0.8.tar.gz
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -318,8 +316,9 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Test the tar file by extracting its contents and building it on at
|
||||
least one supported platform. When this succeeds the commits and new git
|
||||
tag can be pushed to the Launchpad repository:
|
||||
least one supported platform. If this succeeds the commits and new git
|
||||
tag can be pushed to the GitHub repository's 7.0 branch (assumed to be
|
||||
the <tt>upstream</tt> remote):
|
||||
<blockquote><tt>
|
||||
git push --follow-tags upstream 7.0
|
||||
</tt></blockquote>
|
||||
@@ -367,7 +366,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th colspan="3">Publish to epics-controls</th>
|
||||
<th colspan="3">Publish to epics-controls.org</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
@@ -375,7 +374,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
|
||||
epics-controls web-server.
|
||||
<blockquote><tt>
|
||||
scp base-7.0.7.tar.gz base-7.0.7.tar.gz.asc epics-controls:download/base<br />
|
||||
scp base-7.0.8.tar.gz base-7.0.8.tar.gz.asc epics-controls:download/base<br />
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -392,22 +391,22 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th colspan="3">Publish to Launchpad</th>
|
||||
<th colspan="3">Publish to GitHub</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Go to the Launchpad milestone for this release. Click the Create
|
||||
release button and add the release date. Put a URL for the release page
|
||||
in the Release notes box, and click the Create release button. Upload
|
||||
the tar file and its <tt>.asc</tt> signature file to the new Launchpad
|
||||
release page.</td>
|
||||
<td>Go to the GitHub
|
||||
<a href="https://github.com/epics-base/epics-base/releases/new?tag=R7.0.8">
|
||||
Create release from tag R7.0.8</a> page.
|
||||
Upload the tar file and its <tt>.asc</tt> signature file to the new
|
||||
GitHub release page.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Find all Launchpad bug reports with the status Fix Committed which
|
||||
have been fixed in this release and mark them Fix Released.</td>
|
||||
<td>We used to close out bug reports in Launchpad at release-time, this
|
||||
would be the time to do that if we have an equivalent on GitHub.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
6
epics-base.sh
Normal file
6
epics-base.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
_OLD_EXTGLOB=$(shopt -p extglob)
|
||||
shopt -s extglob
|
||||
test -n "$EPICS_HOST_ARCH" || export EPICS_HOST_ARCH=$(/bin/sed "s%cpe:/o:redhat:enterprise_linux:\([0-9]*\).*%RHEL\1-`/bin/uname -m`%" /etc/system-release-cpe)
|
||||
PATH=${PATH//?(:)\/usr\/local\/epics\/base-+([0-9]).+([0-9]).+([0-9])\/bin\/$EPICS_HOST_ARCH}:$EPICS_BASE/bin/$EPICS_HOST_ARCH
|
||||
eval $_OLD_EXTGLOB
|
||||
unset _OLD_EXTGLOB
|
||||
486
epics-base.spec
Normal file
486
epics-base.spec
Normal file
@@ -0,0 +1,486 @@
|
||||
# Always make sure EpicsVersion.Version-Release matches the git tag!
|
||||
|
||||
%define EpicsVersion 7.0.8
|
||||
|
||||
Name: epics-base-%{EpicsVersion}
|
||||
Summary: EPICS Base %{EpicsVersion}
|
||||
Version: 1
|
||||
Release: 0%{?dist}
|
||||
License: EPICS Open License
|
||||
Group: Development/Languages
|
||||
URL: https://git.psi.ch/epics_base/base-7.0
|
||||
|
||||
Obsoletes: caRepeater = 1
|
||||
|
||||
%define module_name %{name}
|
||||
%define prog_folder /usr/local/epics/base-%{EpicsVersion}
|
||||
|
||||
%define debug_package %{nil}
|
||||
%define _build_id_links none
|
||||
|
||||
# do not strip libraries
|
||||
%global __strip /bin/true
|
||||
%undefine __brp_strip
|
||||
|
||||
%undefine __brp_mangle_shebangs
|
||||
%undefine __brp_ldconfig
|
||||
%define _binaries_in_noarch_packages_terminate_build 0
|
||||
|
||||
%if %{defined rhel}
|
||||
%global epics_host_arch RHEL%{rhel}-%{_host_cpu}
|
||||
%endif
|
||||
# else define epics_host_arch as suitable
|
||||
|
||||
%description
|
||||
EPICS is a set of Open Source software tools, libraries and applications
|
||||
developed collaboratively and used worldwide to create distributed soft
|
||||
real-time control systems for scientific instruments such as a particle
|
||||
accelerators, telescopes and other large scientific experiments.
|
||||
This RPM is a binary-only package.
|
||||
|
||||
###########################################
|
||||
|
||||
%package host-devel
|
||||
Requires: make >= 3.80
|
||||
BuildRequires: make >= 3.80
|
||||
BuildRequires: gfa-cross-compiler-links
|
||||
%if %{?rhel} >= 9
|
||||
BuildRequires: gfa-wine
|
||||
%else
|
||||
BuildRequires: wine
|
||||
%endif
|
||||
|
||||
Summary: Minimal stuff needed to build EPICS host apps
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
# This EPICS installation uses the toolset 12 compiler
|
||||
%if 0%{?rhel} == 7
|
||||
Requires: devtoolset-12-gcc-c++
|
||||
BuildRequires: devtoolset-12-gcc-c++
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} >= 8
|
||||
Requires: gcc-toolset-12-gcc-c++
|
||||
BuildRequires: gcc-toolset-12-gcc-c++
|
||||
%endif
|
||||
|
||||
# The perl stuff we need
|
||||
Requires: perl-interpreter >= 5.10.1
|
||||
BuildRequires: perl-interpreter >= 5.10.1
|
||||
|
||||
%if 0%{?rhel} >= 7
|
||||
Requires: perl-File-Path perl-Getopt-Long perl-Pod-Usage perl-Time-HiRes perl-Data-Dumper perl-Scalar-List-Utils
|
||||
BuildRequires: perl-File-Path perl-Getopt-Long perl-Pod-Usage perl-Time-HiRes perl-Data-Dumper perl-Scalar-List-Utils
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} >= 8
|
||||
Requires: perl-Text-Tabs+Wrap
|
||||
BuildRequires: perl-Text-Tabs+Wrap
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} >= 9
|
||||
Requires: perl-File-Find perl-File-Basename perl-File-Copy perl-FindBin perl-Getopt-Std perl-POSIX
|
||||
BuildRequires: perl-File-Find perl-File-Basename perl-File-Copy perl-FindBin perl-Getopt-Std perl-POSIX
|
||||
%endif
|
||||
|
||||
# Perl auto-detection is broken
|
||||
# It does not find all EPICS internal packages
|
||||
%global __requires_exclude_from ^%{prog_folder}/bin/.*\\.pl$
|
||||
|
||||
%description host-devel
|
||||
Contains headers etc to build EPICS host applications.
|
||||
|
||||
###########################################
|
||||
|
||||
%package compat
|
||||
Summary: EPICS base %{EpicsVersion} for other RHEL versions
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
AutoReqProv: no
|
||||
|
||||
%description compat
|
||||
Contains EPICS binaries that run on other RHEL versions.
|
||||
|
||||
###########################################
|
||||
|
||||
%package wine
|
||||
Summary: EPICS base %{EpicsVersion} for wine
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
%if %{?rhel} >= 9
|
||||
Requires: gfa-wine
|
||||
%else
|
||||
Requires: wine
|
||||
%endif
|
||||
|
||||
%description wine
|
||||
Allows to run EPICS in wine.
|
||||
|
||||
###########################################
|
||||
|
||||
%package boot
|
||||
Summary: EPICS base %{EpicsVersion} for boot servers
|
||||
BuildArch: noarch
|
||||
AutoReqProv: no
|
||||
Prefix: /usr/local/epics
|
||||
|
||||
%description boot
|
||||
Contains files needed on NFS server to boot EPICS targets from.
|
||||
This package can be relocated.
|
||||
|
||||
###########################################
|
||||
|
||||
%package devel
|
||||
Summary: EPICS base %{EpicsVersion} for development environments
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: %{name}-host-devel = %{version}-%{release}
|
||||
Requires: gfa-cross-compiler-links
|
||||
BuildArch: noarch
|
||||
AutoReqProv: no
|
||||
|
||||
%description devel
|
||||
All what is needed to develop EPICS for different target architectures.
|
||||
|
||||
###########################################
|
||||
|
||||
%package devel-static
|
||||
Summary: EPICS base %{EpicsVersion} for development environments including static libraries
|
||||
Requires: %{name}-devel = %{version}-%{release}
|
||||
BuildArch: noarch
|
||||
AutoReqProv: no
|
||||
|
||||
%description devel-static
|
||||
Contains the static libraries (*.a) for EPICS development systems.
|
||||
Only needed to build statically linked applications.
|
||||
|
||||
###########################################
|
||||
|
||||
%package src
|
||||
Summary: Sources code of EPICS base %{EpicsVersion}
|
||||
BuildArch: noarch
|
||||
AutoReqProv: no
|
||||
Prefix: /usr/local/epics
|
||||
|
||||
%description src
|
||||
The source code of EPICS base %{EpicsVersion}.
|
||||
May help when debugging
|
||||
|
||||
###########################################
|
||||
|
||||
%package doc
|
||||
Summary: EPICS base %{EpicsVersion} documentation
|
||||
BuildArch: noarch
|
||||
AutoReqProv: no
|
||||
Prefix: /usr/local/epics
|
||||
|
||||
%description doc
|
||||
The documentation of EPICS base %{EpicsVersion}.
|
||||
|
||||
###########################################
|
||||
|
||||
# Our sources are locally in this directory
|
||||
# and here we also build
|
||||
# RPMS will be stored here, too
|
||||
%define _topdir %(pwd)
|
||||
%define _sourcedir %{_topdir}
|
||||
%define _builddir %{_topdir}
|
||||
|
||||
%prep
|
||||
%{__rm} -rf %{buildroot}/usr/lib
|
||||
%{__rm} -f modules/RELEASE.*.local
|
||||
git submodule update --init --recursive modules
|
||||
%{__mkdir_p} RPMS
|
||||
|
||||
%build
|
||||
%if %{defined epics_host_arch}
|
||||
export EPICS_HOST_ARCH=%{epics_host_arch}
|
||||
%endif
|
||||
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} FINAL_LOCATION=%{prog_folder}
|
||||
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} copysrc
|
||||
|
||||
# remove files we do not need
|
||||
shopt -s extglob
|
||||
%{__rm} -f %{buildroot}%{prog_folder}/bin/{V,RTEMS}*/{*Harness,softIoc,softIocPVA}
|
||||
%{__rm} -f %{buildroot}%{prog_folder}/bin/RTEMS*/TEMP.*
|
||||
|
||||
# fix permissions of caRepeater.service
|
||||
%{__chmod} 644 %{buildroot}%{prog_folder}/bin/*/caRepeater.service
|
||||
|
||||
# install the profile script
|
||||
/bin/sed 's!\$EPICS_BASE!%{prog_folder}!' epics-base.sh > %{buildroot}%{prog_folder}/bin/epics-base.sh
|
||||
|
||||
# copy over old libraries for compatibility
|
||||
%if %{?rhel} > 7
|
||||
%{__cp} /opt/RHEL7/lib64/libreadline.so.6 %{buildroot}%{prog_folder}/lib/RHEL7-x86_64
|
||||
%endif
|
||||
%if %{?rhel} > 8
|
||||
%{__cp} /opt/RHEL7/lib64/libtinfo.so.5 %{buildroot}%{prog_folder}/lib/RHEL7-x86_64
|
||||
%{__cp} /opt/RHEL8/lib64/libreadline.so.7 %{buildroot}%{prog_folder}/lib/RHEL8-x86_64
|
||||
%endif
|
||||
|
||||
# Do not use install section because build already installed
|
||||
# and install will delete our buildroot!
|
||||
|
||||
%clean
|
||||
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} realclean
|
||||
%{__rm} -f modules/RELEASE.*.local
|
||||
%{__rm} -rf %{buildroot}
|
||||
%{__cp} %{_rpmdir}/*/%{name}*%{version}-%{release}.*.rpm %{_sourcedir}
|
||||
|
||||
# Link caRepeater and profile script to highest installed EPICS version after install and uninstall
|
||||
%post
|
||||
shopt -s extglob
|
||||
%{__rm} -f /etc/profile.d/epics-base.sh
|
||||
%{__ln_s} "$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/epics-base.sh | /usr/bin/head -n1)" /etc/profile.d/
|
||||
SYSTEMD_DIR=$(pkg-config systemd --variable=systemdsystemunitdir)
|
||||
if [ -n "$SYSTEMD_DIR" ]
|
||||
then
|
||||
%{__rm} -f $SYSTEMD_DIR/caRepeater.service
|
||||
LATEST_REPEATER=$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/%{epics_host_arch}/caRepeater.service | /usr/bin/head -n1)
|
||||
%{__ln_s} $LATEST_REPEATER $SYSTEMD_DIR/
|
||||
systemctl daemon-reload
|
||||
systemctl reenable caRepeater.service
|
||||
systemctl start caRepeater.service
|
||||
fi
|
||||
|
||||
%postun
|
||||
shopt -s extglob
|
||||
%{__rm} -f /etc/profile.d/epics-base.sh
|
||||
%{__ln_s} "$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/epics-base.sh 2>/dev/null | /usr/bin/head -n1)" /etc/profile.d/ 2>/dev/null
|
||||
SYSTEMD_DIR=$(pkg-config systemd --variable=systemdsystemunitdir)
|
||||
if [ -n "$SYSTEMD_DIR" ]
|
||||
then
|
||||
LATEST_REPEATER=$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/%{epics_host_arch}/caRepeater.service 2>/dev/null | /usr/bin/head -n1)
|
||||
if [ -z "$LATEST_REPEATER" ]
|
||||
then
|
||||
systemctl disable caRepeater.service
|
||||
# Do not stop or restart caRepeater.service
|
||||
# because EPICS clients cannot handle that.
|
||||
# Next reboot will take care of this.
|
||||
fi
|
||||
%{__rm} -f $SYSTEMD_DIR/caRepeater.service
|
||||
if [ -n "$LATEST_REPEATER" ]
|
||||
then
|
||||
%{__ln_s} $LATEST_REPEATER $SYSTEMD_DIR/ 2>/dev/null
|
||||
systemctl reenable caRepeater.service
|
||||
fi
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{prog_folder}
|
||||
%dir %{prog_folder}/configure
|
||||
%{prog_folder}/configure/CONFIG_BASE_VERSION
|
||||
|
||||
%dir %{prog_folder}/dbd
|
||||
%{prog_folder}/dbd/softIoc*.dbd
|
||||
|
||||
%dir %{prog_folder}/bin
|
||||
%dir %{prog_folder}/lib
|
||||
%{prog_folder}/db
|
||||
|
||||
%{prog_folder}/bin/epics-base.sh
|
||||
%{prog_folder}/lib/perl/EpicsHostArch.pl
|
||||
%{prog_folder}/lib/perl/CA.pm
|
||||
%dir %{prog_folder}/lib/perl
|
||||
%dir %{prog_folder}/lib/perl/*
|
||||
%dir %{prog_folder}/lib/perl/*/*-linux-thread-multi
|
||||
%{prog_folder}/lib/perl/*/*-linux-thread-multi/libCap5.so
|
||||
|
||||
# Install host binaries but avoid installing *.pl scripts
|
||||
# and other development tools
|
||||
|
||||
%dir %{prog_folder}/bin/%{epics_host_arch}*
|
||||
%{prog_folder}/bin/%{epics_host_arch}*/[Scips]*[^.]??
|
||||
%{prog_folder}/bin/%{epics_host_arch}*/p2p
|
||||
%{prog_folder}/bin/%{epics_host_arch}*/msi
|
||||
%dir %{prog_folder}/lib/%{epics_host_arch}*
|
||||
%{prog_folder}/lib/%{epics_host_arch}*/*.so*
|
||||
|
||||
###########################################
|
||||
|
||||
%files compat
|
||||
%if %{?rhel} > 7
|
||||
%dir %{prog_folder}/bin/RHEL7*
|
||||
%{prog_folder}/bin/RHEL7*/[Scips]*[^.]??
|
||||
%{prog_folder}/bin/RHEL7*/p2p
|
||||
%{prog_folder}/bin/RHEL7*/msi
|
||||
%dir %{prog_folder}/lib/RHEL7*
|
||||
%{prog_folder}/lib/RHEL7*/*.so*
|
||||
%endif
|
||||
|
||||
%if %{?rhel} > 8
|
||||
%dir %{prog_folder}/bin/RHEL8*
|
||||
%{prog_folder}/bin/RHEL8*/[Scips]*[^.]??
|
||||
%{prog_folder}/bin/RHEL8*/p2p
|
||||
%{prog_folder}/bin/RHEL8*/msi
|
||||
%dir %{prog_folder}/lib/RHEL8*
|
||||
%{prog_folder}/lib/RHEL8*/*.so*
|
||||
%endif
|
||||
|
||||
%if %{?rhel} > 9
|
||||
%dir %{prog_folder}/bin/RHEL9*
|
||||
%{prog_folder}/bin/RHEL9*/[Scips]*[^.]??
|
||||
%{prog_folder}/bin/RHEL9*/p2p
|
||||
%{prog_folder}/bin/RHEL9*/msi
|
||||
%dir %{prog_folder}/lib/RHEL9*
|
||||
%{prog_folder}/lib/RHEL9*/*.so*
|
||||
%endif
|
||||
|
||||
###########################################
|
||||
|
||||
%files wine
|
||||
%{prog_folder}/bin/win*
|
||||
|
||||
###########################################
|
||||
|
||||
%files boot
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{prog_folder}
|
||||
%dir %{prog_folder}/configure
|
||||
%{prog_folder}/configure/CONFIG_BASE_VERSION
|
||||
|
||||
%dir %{prog_folder}/dbd
|
||||
%{prog_folder}/dbd/softIoc*.dbd
|
||||
%{prog_folder}/db
|
||||
|
||||
%dir %{prog_folder}/lib
|
||||
# avoid pulling in pkgconfig and perl
|
||||
%dir %{prog_folder}/lib/[a-z]*-*
|
||||
%{prog_folder}/lib/[a-z]*-*/*.so*
|
||||
|
||||
%dir %{prog_folder}/bin
|
||||
# avoid pulling in host files again
|
||||
# but get all cross architectures (mostly lower case)
|
||||
# including all Windows dlls (hence listed twice: here and in wine)
|
||||
%dir %{prog_folder}/bin/[a-z]*
|
||||
%{prog_folder}/bin/[a-z]*/[Scips]*[^.]??
|
||||
%{prog_folder}/bin/[a-z]*/msi*
|
||||
%{prog_folder}/bin/[a-z]*/acctst*
|
||||
%{prog_folder}/bin/[a-z]*/*.dll
|
||||
|
||||
# vxWorks and RTEMS
|
||||
%dir %{prog_folder}/bin/V*
|
||||
%{prog_folder}/bin/V*/*.munch
|
||||
%{prog_folder}/bin/V*/*.o
|
||||
%dir %{prog_folder}/bin/RTEMS*
|
||||
%{prog_folder}/bin/RTEMS*/*.boot
|
||||
|
||||
###########################################
|
||||
|
||||
%files host-devel
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{prog_folder}/include
|
||||
%{prog_folder}/include/*.h
|
||||
%{prog_folder}/include/compiler
|
||||
%dir %{prog_folder}/include/os
|
||||
%{prog_folder}/include/os/Linux/
|
||||
%{prog_folder}/include/os/WIN32/
|
||||
%{prog_folder}/include/pv/
|
||||
%{prog_folder}/include/pva/
|
||||
%{prog_folder}/include/valgrind/
|
||||
%{prog_folder}/include/flex.skel.static
|
||||
%{prog_folder}/templates
|
||||
%dir %{prog_folder}/cfg
|
||||
%{prog_folder}/cfg/CONFIG*
|
||||
%{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.%{epics_host_arch}*
|
||||
%{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.win*
|
||||
%dir %{prog_folder}/configure
|
||||
%{prog_folder}/configure/RELEASE
|
||||
%{prog_folder}/configure/CONFIG*
|
||||
%{prog_folder}/configure/RULES*
|
||||
%dir %{prog_folder}/configure/os
|
||||
%{prog_folder}/configure/os/CONFIG.Common.UnixCommon
|
||||
%{prog_folder}/configure/os/CONFIG.Common.linuxCommon
|
||||
%{prog_folder}/configure/os/CONFIG.Common.linux-clang
|
||||
%{prog_folder}/configure/os/CONFIG.Common.linux-%{_host_cpu}*
|
||||
%{prog_folder}/configure/os/CONFIG.Common.%{epics_host_arch}*
|
||||
%{prog_folder}/configure/os/CONFIG.UnixCommon.Common
|
||||
%{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.Common
|
||||
%{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.%{epics_host_arch}*
|
||||
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.Common
|
||||
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.linux-%{__isa_name}*
|
||||
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.win*
|
||||
%{prog_folder}/configure/os/CONFIG.Linux.win*
|
||||
%{prog_folder}/configure/os/CONFIG.win*.win*
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.Common.linuxCommon
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.Common.linux-%{__isa_name}*
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.%{epics_host_arch}*.Common
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.Common
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.UnixCommon
|
||||
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.linux-%{__isa_name}*
|
||||
%{prog_folder}/bin/%{epics_host_arch}*/[^Scips]*[^.]??
|
||||
%{prog_folder}/bin/%{epics_host_arch}*/*.??
|
||||
%dir %{prog_folder}/lib/pkgconfig
|
||||
%{prog_folder}/lib/pkgconfig/epics-base.pc
|
||||
%{prog_folder}/lib/pkgconfig/epics-base-%{epics_host_arch}*.pc
|
||||
%{prog_folder}/lib/perl/EPICS
|
||||
%{prog_folder}/lib/perl/DBD*
|
||||
%{prog_folder}/dbd
|
||||
|
||||
###########################################
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%{prog_folder}/include/os/vxWorks/
|
||||
%{prog_folder}/include/os/RTEMS/
|
||||
%exclude %{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.%{epics_host_arch}*
|
||||
%exclude %{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.win*
|
||||
%{prog_folder}/cfg/TOOLCHAIN.*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Common.%{epics_host_arch}*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Common.UnixCommon
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Common.linuxCommon
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Common.linux-clang
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Common.linux-%{_host_cpu}*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.UnixCommon.Common
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.Common
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.%{epics_host_arch}*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.Common
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.linux-%{__isa_name}*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.win*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.Linux.win*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG.win*.win*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.Common.linuxCommon
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.Common.linux-%{__isa_name}*
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.%{epics_host_arch}*.Common
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.Common
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.UnixCommon
|
||||
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.linux-%{__isa_name}*
|
||||
%{prog_folder}/configure/os/
|
||||
%exclude %{prog_folder}/lib/pkgconfig/epics-base.pc
|
||||
%exclude %{prog_folder}/lib/pkgconfig/epics-base-%{epics_host_arch}*.pc
|
||||
%{prog_folder}/lib/pkgconfig/
|
||||
%exclude %{prog_folder}/bin/%{epics_host_arch}*/[^Scips]*[^.]??
|
||||
%exclude %{prog_folder}/bin/%{epics_host_arch}*/*.??
|
||||
%exclude %{prog_folder}/bin/*/[^Scips]*[^.]??
|
||||
%exclude %{prog_folder}/bin/*/*.??
|
||||
|
||||
# VxWorks and RTEMS need static libs
|
||||
%{prog_folder}/lib/V*
|
||||
%{prog_folder}/lib/RTEMS*
|
||||
%{prog_folder}/lib/win*
|
||||
|
||||
###########################################
|
||||
|
||||
%files devel-static
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
# Install bulky static libs for Linux targets only on request
|
||||
%dir %{prog_folder}/lib/RHEL*
|
||||
%{prog_folder}/lib/RHEL*/*.a
|
||||
%dir %{prog_folder}/lib/[a-z]*
|
||||
%{prog_folder}/lib/[a-z]*/*.a
|
||||
|
||||
###########################################
|
||||
|
||||
%files src
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{prog_folder}
|
||||
%{prog_folder}/modules
|
||||
|
||||
###########################################
|
||||
|
||||
%files doc
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{prog_folder}
|
||||
%docdir %{prog_folder}/html
|
||||
%{prog_folder}/html
|
||||
@@ -34,12 +34,6 @@ pvDatabase_DEPEND_DIRS = pvAccess
|
||||
SUBMODULES += pva2pva
|
||||
pva2pva_DEPEND_DIRS = pvAccess
|
||||
|
||||
SUBMODULES += example
|
||||
example_DEPEND_DIRS = pva2pva pvaClient
|
||||
|
||||
SUBMODULES += pcas
|
||||
pcas_DEPEND_DIRS = ca
|
||||
|
||||
# Allow sites to add extra submodules
|
||||
-include Makefile.local
|
||||
|
||||
|
||||
2
modules/Makefile.local
Normal file
2
modules/Makefile.local
Normal file
@@ -0,0 +1,2 @@
|
||||
SUBMODULES += pcas
|
||||
pcas_DEPEND_DIRS = ca
|
||||
@@ -2575,7 +2575,8 @@ void monitorUpdateTest ( chid chan, unsigned interestLevel )
|
||||
SEVCHK ( ca_get ( DBR_FLOAT, chan, &temp ), NULL );
|
||||
SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL );
|
||||
|
||||
/* printf ( "flow control bypassed %u events\n", flowCtrlCount ); */
|
||||
if (0)
|
||||
printf ( "flow control bypassed %u events\n", flowCtrlCount );
|
||||
|
||||
showProgressEnd ( interestLevel );
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string> // vxWorks 6.0 requires this include
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "dbDefs.h"
|
||||
#include "epicsGuard.h"
|
||||
#include "epicsVersion.h"
|
||||
@@ -1008,7 +1009,7 @@ bool cac::defaultExcep (
|
||||
char buf[512];
|
||||
char hostName[64];
|
||||
iiu.getHostName ( guard, hostName, sizeof ( hostName ) );
|
||||
sprintf ( buf, "host=%s ctx=%.400s", hostName, pCtx );
|
||||
epicsSnprintf( buf, sizeof(buf), "host=%s ctx=%.400s", hostName, pCtx );
|
||||
this->notify.exception ( guard, status, buf, 0, 0u );
|
||||
return true;
|
||||
}
|
||||
@@ -1312,7 +1313,7 @@ void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
|
||||
const char * pChannelName, const char * pAcc, const char * pRej )
|
||||
{
|
||||
char buf[256];
|
||||
sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s",
|
||||
epicsSnprintf( buf, sizeof(buf), "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s",
|
||||
pChannelName, pAcc, pRej );
|
||||
{
|
||||
callbackManager mgr ( this->notify, this->cbMutex );
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
|
||||
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
|
||||
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -28,6 +31,7 @@
|
||||
|
||||
#include "envDefs.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsStdioRedirect.h"
|
||||
#include "errlog.h"
|
||||
#include "osiWireFormat.h"
|
||||
@@ -35,39 +39,6 @@
|
||||
#include "addrList.h"
|
||||
#include "iocinf.h"
|
||||
|
||||
/*
|
||||
* getToken()
|
||||
*/
|
||||
static char *getToken ( const char **ppString, char *pBuf, unsigned bufSIze )
|
||||
{
|
||||
bool tokenFound = false;
|
||||
const char *pToken;
|
||||
unsigned i;
|
||||
|
||||
pToken = *ppString;
|
||||
while ( isspace (*pToken) && *pToken ){
|
||||
pToken++;
|
||||
}
|
||||
|
||||
for ( i=0u; i<bufSIze; i++ ) {
|
||||
if ( isspace (pToken[i]) || pToken[i]=='\0' ) {
|
||||
pBuf[i] = '\0';
|
||||
*ppString = &pToken[i];
|
||||
if ( i != 0 ) {
|
||||
tokenFound = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pBuf[i] = pToken[i];
|
||||
}
|
||||
|
||||
if ( tokenFound ) {
|
||||
pBuf[bufSIze-1] = '\0';
|
||||
return pBuf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* addAddrToChannelAccessAddressList ()
|
||||
*/
|
||||
@@ -77,9 +48,7 @@ extern "C" int epicsStdCall addAddrToChannelAccessAddressList
|
||||
{
|
||||
osiSockAddrNode *pNewNode;
|
||||
const char *pStr;
|
||||
const char *pToken;
|
||||
struct sockaddr_in addr;
|
||||
char buf[256u]; /* large enough to hold an IP address or hostname */
|
||||
int status, ret = -1;
|
||||
|
||||
pStr = envGetConfigParamPtr (pEnv);
|
||||
@@ -87,31 +56,45 @@ extern "C" int epicsStdCall addAddrToChannelAccessAddressList
|
||||
return ret;
|
||||
}
|
||||
|
||||
while ( ( pToken = getToken (&pStr, buf, sizeof (buf) ) ) ) {
|
||||
status = aToIPAddr ( pToken, port, &addr );
|
||||
if (status<0) {
|
||||
fprintf ( stderr, "%s: Parsing '%s'\n", __FILE__, pEnv->name);
|
||||
fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken);
|
||||
continue;
|
||||
try {
|
||||
std::vector<char> scratch(pStr, pStr+strlen(pStr)+1); // copy chars and trailing nil
|
||||
|
||||
char *save = NULL;
|
||||
for(const char *pToken = epicsStrtok_r(&scratch[0], " \t\n\r", &save);
|
||||
pToken;
|
||||
pToken = epicsStrtok_r(NULL, " \t\n\r", &save))
|
||||
{
|
||||
if(!pToken[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
status = aToIPAddr ( pToken, port, &addr );
|
||||
if (status<0) {
|
||||
fprintf ( stderr, "%s: Parsing '%s'\n", __FILE__, pEnv->name);
|
||||
fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
|
||||
if (pNewNode==NULL) {
|
||||
fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n");
|
||||
break;
|
||||
}
|
||||
|
||||
pNewNode->addr.ia = addr;
|
||||
|
||||
/*
|
||||
* LOCK applied externally
|
||||
*/
|
||||
ellAdd (pList, &pNewNode->node);
|
||||
ret = 0; /* success if anything is added to the list */
|
||||
}
|
||||
|
||||
if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
|
||||
if (pNewNode==NULL) {
|
||||
fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n");
|
||||
break;
|
||||
}
|
||||
|
||||
pNewNode->addr.ia = addr;
|
||||
|
||||
/*
|
||||
* LOCK applied externally
|
||||
*/
|
||||
ellAdd (pList, &pNewNode->node);
|
||||
ret = 0; /* success if anything is added to the list */
|
||||
} catch(std::exception&) { // only bad_alloc currently possible
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -90,7 +90,7 @@ static const iocshFuncDef asprulesFuncDef = {
|
||||
"asprules",1,asprulesArgs,
|
||||
"List rules of an Access Security Group.\n"
|
||||
"If no Group is specified then list the rules for all groups\n"
|
||||
"Example: asprules mygroup"
|
||||
"Example: asprules mygroup\n"
|
||||
};
|
||||
static void asprulesCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
|
||||
@@ -240,6 +240,7 @@ The B<SPVT> field is for internal use by the scanning system.
|
||||
}
|
||||
field(PROC,DBF_UCHAR) {
|
||||
prompt("Force Processing")
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
interest(3)
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ void testdbPrepare(void)
|
||||
{
|
||||
if(!testEvtLock)
|
||||
testEvtLock = epicsMutexMustCreate();
|
||||
initHookAnnounce(initHookAfterPrepareDatabase);
|
||||
}
|
||||
|
||||
void testdbReadDatabase(const char* file,
|
||||
@@ -94,6 +95,7 @@ void testIocShutdownOk(void)
|
||||
|
||||
void testdbCleanup(void)
|
||||
{
|
||||
initHookAnnounce(initHookBeforeCleanupDatabase);
|
||||
dbFreeBase(pdbbase);
|
||||
db_cleanup_events();
|
||||
initHookFree();
|
||||
|
||||
@@ -118,6 +118,10 @@ typedef struct dbRecordNode {
|
||||
char *recordname;
|
||||
ELLLIST infoList; /*LIST head of info nodes*/
|
||||
int flags;
|
||||
/** Parse order of this record()
|
||||
* @since UNRELEASED
|
||||
*/
|
||||
unsigned order;
|
||||
struct dbRecordNode *aliasedRecnode; /* NULL unless flags|DBRN_FLAGS_ISALIAS */
|
||||
}dbRecordNode;
|
||||
|
||||
@@ -184,5 +188,9 @@ typedef struct dbBase {
|
||||
struct gphPvt *pgpHash;
|
||||
short ignoreMissingMenus;
|
||||
short loadCdefs;
|
||||
/** Total number of records.
|
||||
* @since UNRELEASED
|
||||
*/
|
||||
unsigned no_records;
|
||||
}dbBase;
|
||||
#endif
|
||||
|
||||
@@ -247,23 +247,23 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
}
|
||||
my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
|
||||
freeListInitPvt(&freeListPvt,sizeof(tempListNode),100);
|
||||
if(substitutions) {
|
||||
if(macCreateHandle(&macHandle,NULL)) {
|
||||
epicsPrintf("macCreateHandle error\n");
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
macParseDefns(macHandle,(char *)substitutions,&macPairs);
|
||||
if(macPairs ==NULL) {
|
||||
macDeleteHandle(macHandle);
|
||||
macHandle = NULL;
|
||||
} else {
|
||||
macInstallMacros(macHandle,macPairs);
|
||||
free((void *)macPairs);
|
||||
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
|
||||
}
|
||||
macSuppressWarning(macHandle,dbQuietMacroWarnings);
|
||||
if (substitutions == NULL)
|
||||
substitutions = "";
|
||||
if(macCreateHandle(&macHandle,NULL)) {
|
||||
epicsPrintf("macCreateHandle error\n");
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
macParseDefns(macHandle,substitutions,&macPairs);
|
||||
if(macPairs == NULL) {
|
||||
macDeleteHandle(macHandle);
|
||||
macHandle = NULL;
|
||||
} else {
|
||||
macInstallMacros(macHandle,macPairs);
|
||||
free(macPairs);
|
||||
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
|
||||
}
|
||||
macSuppressWarning(macHandle,dbQuietMacroWarnings);
|
||||
pinputFile = dbCalloc(1,sizeof(inputFile));
|
||||
if (filename) {
|
||||
pinputFile->filename = macEnvExpand(filename);
|
||||
|
||||
@@ -193,7 +193,7 @@ struct lset;
|
||||
struct link {
|
||||
struct dbCommon *precord; /* Pointer to record owning link */
|
||||
short type;
|
||||
short flags;
|
||||
unsigned short flags;
|
||||
struct lset *lset;
|
||||
char *text; /* Raw link text */
|
||||
union value value;
|
||||
|
||||
@@ -61,8 +61,8 @@ this chapter for information on soft device support.
|
||||
If the record gets its values from hardware or uses the C<Raw Soft Channel>
|
||||
device support, the device support routines place the value in the RVAL
|
||||
field.
|
||||
(Since UNRELEASED) If the MASK field is non-zero, then this MASK is applied to RVAL.
|
||||
The value of RVAL is then converted using the process described in the
|
||||
(Since 7.0.8) If the MASK field is non-zero, then this MASK is applied to RVAL.
|
||||
The value from RVAL is then converted using the process described in the
|
||||
next section.
|
||||
|
||||
=fields INP, DTYP, ZNAM, ONAM, RVAL, VAL
|
||||
|
||||
@@ -158,7 +158,7 @@ CEIL: Ceiling (unary)
|
||||
FLOOR: Floor (unary)
|
||||
|
||||
=item *
|
||||
FMOD: Floating point modulo (binary) Added in UNRELEASED
|
||||
FMOD: Floating point modulo (binary) Added in 7.0.8
|
||||
|
||||
=item *
|
||||
LOG: Log base 10 (unary)
|
||||
|
||||
@@ -184,7 +184,7 @@ CEIL: Ceiling (unary)
|
||||
FLOOR: Floor (unary)
|
||||
|
||||
=item *
|
||||
FMOD: Floating point modulo (binary) Added in UNRELEASED
|
||||
FMOD: Floating point modulo (binary) Added in 7.0.8
|
||||
|
||||
=item *
|
||||
LOG: Log base 10 (unary)
|
||||
|
||||
@@ -85,7 +85,7 @@ for information on the format of hardware addresses and database links.
|
||||
|
||||
=head4 Menu longoutOOPT
|
||||
|
||||
The OOPT field was added in EPICS UNRELEASED.
|
||||
The OOPT field was added in EPICS 7.0.8.
|
||||
|
||||
It determines the condition that causes the output link to be
|
||||
written to. It's a menu field that has six choices:
|
||||
@@ -119,7 +119,7 @@ VAL is non-zero and last value was zero.
|
||||
|
||||
=head4 Changes in OUT field when OOPT = On Change
|
||||
|
||||
The OOCH field was added in EPICS UNRELEASED.
|
||||
The OOCH field was added in EPICS 7.0.8.
|
||||
|
||||
If OOCH is C<YES> (its default value) and the OOPT field is C<On Change>,
|
||||
the record will write to the device support the first time the record gets
|
||||
|
||||
@@ -20,10 +20,14 @@ use EPICS::Getopts;
|
||||
use EPICS::Readfile;
|
||||
use EPICS::macLib;
|
||||
|
||||
our ($opt_D, @opt_I, @opt_S, $opt_o);
|
||||
our ($opt_D, $opt_A, @opt_I, @opt_S, $opt_o);
|
||||
|
||||
getopts('DI@S@o:') or
|
||||
die "Usage: dbdExpand [-D] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ...";
|
||||
getopts('DAI@S@o:') or
|
||||
die "Usage: dbdExpand [-D] [-A] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ...";
|
||||
|
||||
if ($opt_A) {
|
||||
$DBD::Parser::allowAutoDeclarations = 1;
|
||||
}
|
||||
|
||||
my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32?
|
||||
my $macros = EPICS::macLib->new(@opt_S);
|
||||
|
||||
@@ -366,7 +366,7 @@ long epicsStdCall asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt,
|
||||
{
|
||||
ASGMEMBER *pasgmember = asMemberPvt;
|
||||
ASGCLIENT *pasgclient;
|
||||
int len, i;
|
||||
size_t len, i;
|
||||
|
||||
long status;
|
||||
if(!asActive) return(S_asLib_asNotActive);
|
||||
@@ -394,7 +394,7 @@ long epicsStdCall asChangeClient(
|
||||
{
|
||||
ASGCLIENT *pasgclient = asClientPvt;
|
||||
long status;
|
||||
int len, i;
|
||||
size_t len, i;
|
||||
|
||||
if(!asActive) return(S_asLib_asNotActive);
|
||||
if(!pasgclient) return(S_asLib_badClient);
|
||||
|
||||
@@ -222,7 +222,7 @@ extern "C" {
|
||||
* - n parameter minimum value: min(a, b, ...)
|
||||
* - Square root: sqr(a) or sqrt(a)
|
||||
* - Floating point modulo: fmod(num, den)
|
||||
* \since The fmod() function was added in UNRELEASED
|
||||
* \since The fmod() function was added in 7.0.8
|
||||
*
|
||||
* -# ***Trigonometric Functions***
|
||||
* Standard circular trigonometric functions, with angles expressed in radians:
|
||||
|
||||
@@ -180,8 +180,8 @@ LIBCOM_API void errlogAddListener(errlogListener listener, void *pPrivate);
|
||||
* \param listener Function pointer of type ::errlogListener
|
||||
* \param pPrivate This will be passed as the first argument of listener()
|
||||
*
|
||||
* \since UNRELEASED Safe to call from a listener callback.
|
||||
* \until UNRELEASED Self-removal from a listener callback caused corruption.
|
||||
* \since 7.0.8 Safe to call from a listener callback.
|
||||
* \until 7.0.8 Self-removal from a listener callback caused corruption.
|
||||
*/
|
||||
LIBCOM_API int errlogRemoveListeners(errlogListener listener,
|
||||
void *pPrivate);
|
||||
|
||||
@@ -19,7 +19,7 @@ parse_CPPFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE)
|
||||
|
||||
INC += flex.skel.static
|
||||
|
||||
# flex.c is included in parse.c
|
||||
# flex.c, scan.c and yylex.c are #included by parse.c
|
||||
e_flex_SRCS += ccl.c
|
||||
e_flex_SRCS += dfa.c
|
||||
e_flex_SRCS += ecs.c
|
||||
|
||||
@@ -132,7 +132,6 @@ void cclnegate(int cclp)
|
||||
void list_character_set(FILE *file, int cset[])
|
||||
{
|
||||
int i;
|
||||
char *readable_form();
|
||||
|
||||
putc( '[', file );
|
||||
|
||||
|
||||
@@ -188,7 +188,6 @@ int main(int argc, char *argv[])
|
||||
void flexend(int status)
|
||||
{
|
||||
int tblsiz;
|
||||
char *flex_gettime();
|
||||
|
||||
if ( skelfile != NULL )
|
||||
{
|
||||
@@ -382,7 +381,7 @@ void flexend(int status)
|
||||
void flexinit(int argc, char **argv)
|
||||
{
|
||||
int i, sawcmpflag;
|
||||
char *arg, *flex_gettime(), *mktemp();
|
||||
char *arg;
|
||||
|
||||
printstats = syntaxerror = trace = spprdflt = interactive = caseins = false;
|
||||
backtrack_report = performance_report = ddebug = fulltbl = fullspd = false;
|
||||
|
||||
@@ -567,8 +567,8 @@ extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
|
||||
extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
|
||||
extern int num_backtracking, bol_needed;
|
||||
|
||||
void *allocate_array(int size, int element_size);
|
||||
void *reallocate_array(void *array, int size, int element_size);
|
||||
extern void *allocate_array(int size, int element_size);
|
||||
extern void *reallocate_array(void *array, int size, int element_size);
|
||||
|
||||
#define allocate_integer_array(size) \
|
||||
(int *) allocate_array( size, sizeof( int ) )
|
||||
@@ -677,10 +677,20 @@ extern int all_upper (Char *);
|
||||
/* bubble sort an integer array */
|
||||
extern void bubble (int [], int);
|
||||
|
||||
/* replace upper-case letter to lower-case */
|
||||
extern Char clower(int c);
|
||||
|
||||
/* returns copy of a string */
|
||||
extern char *copy_string(char *str);
|
||||
|
||||
/* returns copy of a (potentially) unsigned string */
|
||||
extern Char *copy_unsigned_string(Char *str);
|
||||
|
||||
/* shell sort a character array */
|
||||
extern void cshell (Char [], int, int);
|
||||
|
||||
extern void dataend (void); /* finish up a block of data declarations */
|
||||
/* finish up a block of data declarations */
|
||||
extern void dataend (void);
|
||||
|
||||
/* report an error message and terminate */
|
||||
extern void flexerror (char[]) NORETURN;
|
||||
@@ -688,6 +698,9 @@ extern void flexerror (char[]) NORETURN;
|
||||
/* report a fatal error message and terminate */
|
||||
extern void flexfatal (char[]);
|
||||
|
||||
/* return current time */
|
||||
extern char *flex_gettime();
|
||||
|
||||
/* report an error message formatted with one integer argument */
|
||||
extern void lerrif (char[], int);
|
||||
|
||||
@@ -700,11 +713,18 @@ extern void line_directive_out (FILE*);
|
||||
/* generate a data statment for a two-dimensional array */
|
||||
extern void mk2data (int);
|
||||
|
||||
extern void mkdata (int); /* generate a data statement */
|
||||
/* generate a data statement */
|
||||
extern void mkdata (int);
|
||||
|
||||
/* return the integer represented by a string of digits */
|
||||
extern int myctoi (Char []);
|
||||
|
||||
/* return character corresponding to escape sequence */
|
||||
extern Char myesc(Char *array);
|
||||
|
||||
/* return the the human-readable form of a character */
|
||||
extern char *readable_form(int c);
|
||||
|
||||
/* write out one section of the skeleton file */
|
||||
extern void skelout (void);
|
||||
|
||||
@@ -784,8 +804,14 @@ extern void cclinstal (Char [], int);
|
||||
/* lookup the number associated with character class */
|
||||
extern int ccllookup (Char []);
|
||||
|
||||
extern void ndinstal (char[], Char[]); /* install a name definition */
|
||||
extern void scinstal (char[], int); /* make a start condition */
|
||||
/* install a name definition */
|
||||
extern void ndinstal (char[], Char[]);
|
||||
|
||||
/* lookup a name definition */
|
||||
extern Char *ndlookup(char *nd);
|
||||
|
||||
/* make a start condition */
|
||||
extern void scinstal (char[], int);
|
||||
|
||||
/* lookup the number associated with a start condition */
|
||||
extern int sclookup (char[]);
|
||||
|
||||
@@ -217,7 +217,6 @@ void genecs(void)
|
||||
int i, j;
|
||||
static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n";
|
||||
int numrows;
|
||||
Char clower();
|
||||
|
||||
if ( numecs < csize )
|
||||
printf( C_char_decl, "YY_CHAR", "yy_ec", csize );
|
||||
@@ -237,8 +236,6 @@ void genecs(void)
|
||||
|
||||
if ( trace )
|
||||
{
|
||||
char *readable_form();
|
||||
|
||||
fputs( "\n\nEquivalence Classes:\n\n", stderr );
|
||||
|
||||
numrows = csize / 8;
|
||||
|
||||
@@ -34,11 +34,18 @@
|
||||
|
||||
int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
|
||||
int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
|
||||
Char clower();
|
||||
|
||||
static int madeany = false; /* whether we've made the '.' character class */
|
||||
int previous_continued_action; /* whether the previous rule's action was '|' */
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
void build_eof_action( void );
|
||||
void synerr( char str[] );
|
||||
void format_pinpoint_message( char msg[], char arg[] );
|
||||
void pinpoint_message( char str[] );
|
||||
void yyerror( char msg[] );
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
@@ -626,7 +633,7 @@ string : string CHAR
|
||||
* conditions
|
||||
*/
|
||||
|
||||
void build_eof_action()
|
||||
void build_eof_action( void )
|
||||
|
||||
{
|
||||
int i;
|
||||
@@ -652,8 +659,7 @@ void build_eof_action()
|
||||
|
||||
/* synerr - report a syntax error */
|
||||
|
||||
void synerr( str )
|
||||
char str[];
|
||||
void synerr( char str[] )
|
||||
|
||||
{
|
||||
syntaxerror = true;
|
||||
@@ -665,8 +671,7 @@ char str[];
|
||||
* pinpointing its location
|
||||
*/
|
||||
|
||||
void format_pinpoint_message( msg, arg )
|
||||
char msg[], arg[];
|
||||
void format_pinpoint_message( char msg[], char arg[] )
|
||||
|
||||
{
|
||||
char errmsg[MAXLINE];
|
||||
@@ -678,8 +683,7 @@ char msg[], arg[];
|
||||
|
||||
/* pinpoint_message - write out a message, pinpointing its location */
|
||||
|
||||
void pinpoint_message( str )
|
||||
char str[];
|
||||
void pinpoint_message( char str[] )
|
||||
|
||||
{
|
||||
fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str );
|
||||
@@ -690,8 +694,7 @@ char str[];
|
||||
* currently, messages are ignore
|
||||
*/
|
||||
|
||||
void yyerror( msg )
|
||||
char msg[];
|
||||
void yyerror( char msg[] )
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
@@ -953,6 +953,7 @@ void yy_load_buffer_state ( void );
|
||||
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
|
||||
void yy_delete_buffer ( YY_BUFFER_STATE b );
|
||||
void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
|
||||
void set_input_file( char *file );
|
||||
|
||||
#define yy_new_buffer yy_create_buffer
|
||||
|
||||
@@ -966,7 +967,7 @@ YY_DECL
|
||||
static int bracelevel, didadef;
|
||||
int i, indented_code = false, checking_used = false, new_xlation = false;
|
||||
int doing_codeblock = false;
|
||||
Char nmdef[MAXLINE], myesc();
|
||||
Char nmdef[MAXLINE];
|
||||
|
||||
|
||||
if ( yy_init )
|
||||
@@ -1488,7 +1489,6 @@ case 65:
|
||||
# line 333 "scan.l"
|
||||
{
|
||||
Char *nmdefptr;
|
||||
Char *ndlookup();
|
||||
|
||||
(void) strcpy( nmstr, (char *) yytext );
|
||||
nmstr[yyleng - 1] = '\0'; /* chop trailing brace */
|
||||
@@ -2230,8 +2230,7 @@ int yywrap()
|
||||
|
||||
/* set_input_file - open the given file (if NULL, stdin) for scanning */
|
||||
|
||||
void set_input_file( file )
|
||||
char *file;
|
||||
void set_input_file( char *file )
|
||||
|
||||
{
|
||||
if ( file )
|
||||
|
||||
@@ -108,8 +108,6 @@ void cclinstal(Char *ccltxt, int cclnum)
|
||||
/* we don't bother checking the return status because we are not called
|
||||
* unless the symbol is new
|
||||
*/
|
||||
Char *copy_unsigned_string();
|
||||
|
||||
(void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum,
|
||||
ccltab, CCL_HASH_SIZE );
|
||||
}
|
||||
@@ -191,9 +189,6 @@ int hashfunct(char *str, int hash_size)
|
||||
|
||||
void ndinstal(char *nd, Char *def)
|
||||
{
|
||||
char *copy_string();
|
||||
Char *copy_unsigned_string();
|
||||
|
||||
if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0,
|
||||
ndtbl, NAME_TABLE_HASH_SIZE ) )
|
||||
synerr( "name defined twice" );
|
||||
@@ -227,8 +222,6 @@ Char *ndlookup(char *nd)
|
||||
|
||||
void scinstal(char *str, int xcluflg)
|
||||
{
|
||||
char *copy_string();
|
||||
|
||||
/* bit of a hack. We know how the default start-condition is
|
||||
* declared, and don't put out a define for it, because it
|
||||
* would come out as "#define 0 1"
|
||||
|
||||
@@ -63,7 +63,7 @@ GPHENTRY * epicsStdCall gphFindParse(gphPvt *pgphPvt, const char *name, size_t l
|
||||
ELLLIST **paplist;
|
||||
ELLLIST *gphlist;
|
||||
GPHENTRY *pgphNode;
|
||||
int hash;
|
||||
unsigned hash;
|
||||
|
||||
if (pgphPvt == NULL) return NULL;
|
||||
paplist = pgphPvt->paplist;
|
||||
@@ -99,7 +99,7 @@ GPHENTRY * epicsStdCall gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
|
||||
ELLLIST **paplist;
|
||||
ELLLIST *plist;
|
||||
GPHENTRY *pgphNode;
|
||||
int hash;
|
||||
unsigned hash;
|
||||
|
||||
if (pgphPvt == NULL) return NULL;
|
||||
paplist = pgphPvt->paplist;
|
||||
@@ -144,7 +144,7 @@ void epicsStdCall gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid)
|
||||
ELLLIST **paplist;
|
||||
ELLLIST *plist = NULL;
|
||||
GPHENTRY *pgphNode;
|
||||
int hash;
|
||||
unsigned hash;
|
||||
|
||||
if (pgphPvt == NULL) return;
|
||||
paplist = pgphPvt->paplist;
|
||||
|
||||
@@ -139,6 +139,9 @@ const char *initHookName(int state)
|
||||
"initHookBeforeFree",
|
||||
"initHookAfterShutdown",
|
||||
|
||||
"initHookAfterPrepareDatabase",
|
||||
"initHookBeforeCleanupDatabase",
|
||||
|
||||
"initHookAfterInterruptAccept",
|
||||
"initHookAtEnd"
|
||||
};
|
||||
|
||||
@@ -71,6 +71,7 @@ extern "C" {
|
||||
* if the IOC is later paused and restarted.
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
// iocInit() begins
|
||||
initHookAtIocBuild = 0, /**< Start of iocBuild() / iocInit() */
|
||||
initHookAtBeginning, /**< Database sanity checks passed */
|
||||
@@ -110,7 +111,7 @@ typedef enum {
|
||||
*/
|
||||
initHookAfterCloseLinks,
|
||||
/** \brief Scan tasks stopped.
|
||||
* \since UNRELEASED Triggered during normal IOC shutdown
|
||||
* \since 7.0.8 Triggered during normal IOC shutdown
|
||||
* \since 7.0.3.1 Added, triggered only by unittest code.
|
||||
*/
|
||||
initHookAfterStopScan,
|
||||
@@ -119,7 +120,7 @@ typedef enum {
|
||||
*/
|
||||
initHookAfterStopCallback,
|
||||
/** \brief CA links stopped.
|
||||
* \since UNRELEASED Triggered during normal IOC shutdown
|
||||
* \since 7.0.8 Triggered during normal IOC shutdown
|
||||
* \since 7.0.3.1 Added, triggered only by unittest code.
|
||||
*/
|
||||
initHookAfterStopLinks,
|
||||
@@ -133,6 +134,17 @@ typedef enum {
|
||||
initHookAfterShutdown,
|
||||
// iocShutdown() ends
|
||||
|
||||
/** \brief Called during testdbPrepare()
|
||||
* Use this hook to repeat actions each time an empty test database is initialized.
|
||||
* \since 7.0.8 Added, triggered only by unittest code.
|
||||
*/
|
||||
initHookAfterPrepareDatabase,
|
||||
/** \brief Called during testdbCleanup()
|
||||
* Use this hook to perform cleanup each time before a test database is free()'d.
|
||||
* \since 7.0.8 Added, triggered only by unittest code.
|
||||
*/
|
||||
initHookBeforeCleanupDatabase,
|
||||
|
||||
/* Deprecated states: */
|
||||
/** Only announced once. Deprecated in favor of initHookAfterDatabaseRunning */
|
||||
initHookAfterInterruptAccept,
|
||||
|
||||
@@ -66,12 +66,16 @@ typedef enum {
|
||||
iocshArgPdbbase,
|
||||
iocshArgArgv,
|
||||
iocshArgPersistentString,
|
||||
/** Equivalent to iocshArgString with a hint for tab completion as a record name.
|
||||
* @since UNRELEASED
|
||||
/**
|
||||
* Equivalent to iocshArgString with a hint for tab completion that the
|
||||
* argument is a record name.
|
||||
* @since 7.0.8
|
||||
*/
|
||||
iocshArgStringRecord,
|
||||
/** Equivalent to iocshArgString with a hint for tab completion as a file system path.
|
||||
* @since UNRELEASED
|
||||
/**
|
||||
* Equivalent to iocshArgString with a hint for tab completion that the
|
||||
* argument is a file system path.
|
||||
* @since 7.0.8
|
||||
*/
|
||||
iocshArgStringPath,
|
||||
}iocshArgType;
|
||||
|
||||
@@ -193,7 +193,7 @@ static const iocshFuncDef epicsEnvShowFuncDef = {"epicsEnvShow",1,epicsEnvShowAr
|
||||
" (default) - show all environment variables\n"
|
||||
" name - show value of specific environment variable\n"
|
||||
"Example: epicsEnvShow\n"
|
||||
"Example: epicsEnvShow PATH"};
|
||||
"Example: epicsEnvShow PATH\n"};
|
||||
static void epicsEnvShowCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
epicsEnvShow (args[0].sval);
|
||||
|
||||
@@ -43,7 +43,7 @@ static char ioc_log_file_command[256];
|
||||
|
||||
|
||||
struct iocLogClient {
|
||||
int insock;
|
||||
SOCKET insock;
|
||||
struct ioc_log_server *pserver;
|
||||
size_t nChar;
|
||||
char recvbuf[1024];
|
||||
|
||||
@@ -15,40 +15,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Up to now epicsShareThings have been declared as imports
|
||||
* (Appropriate for other stuff)
|
||||
* After setting the following they will be declared as exports
|
||||
* (Appropriate for what we implement)
|
||||
*/
|
||||
#include <epicsAssert.h>
|
||||
#include "adjustment.h"
|
||||
|
||||
LIBCOM_API size_t adjustToWorstCaseAlignment(size_t size)
|
||||
size_t adjustToWorstCaseAlignment(size_t size)
|
||||
{
|
||||
int align_size, adjust;
|
||||
struct test_long_word { char c; long lw; };
|
||||
struct test_double { char c; double d; };
|
||||
struct test_ptr { char c; void *p; };
|
||||
int test_long_size = sizeof(struct test_long_word) - sizeof(long);
|
||||
int test_double_size = sizeof(struct test_double) - sizeof(double);
|
||||
int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *);
|
||||
size_t adjusted_size = size;
|
||||
union aline {
|
||||
/* largest primative types (so far...) */
|
||||
double dval;
|
||||
size_t uval;
|
||||
char *ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Use Jeff's alignment tests to determine worst case of long,
|
||||
* double or pointer alignment requirements.
|
||||
*/
|
||||
align_size = test_long_size > test_ptr_size ?
|
||||
test_long_size : test_ptr_size;
|
||||
/* assert that alignment size is a power of 2 */
|
||||
STATIC_ASSERT((sizeof(union aline) & (sizeof(union aline)-1))==0);
|
||||
|
||||
align_size = align_size > test_double_size ?
|
||||
align_size : test_double_size;
|
||||
/* round up to aligment size */
|
||||
size--;
|
||||
size |= sizeof(union aline)-1;
|
||||
size++;
|
||||
|
||||
/*
|
||||
* Increase the size to fit worst case alignment if not already
|
||||
* properly aligned.
|
||||
*/
|
||||
adjust = align_size - size%align_size;
|
||||
if (adjust != align_size) adjusted_size += adjust;
|
||||
|
||||
return (adjusted_size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#include "cantProceed.h"
|
||||
#include "epicsExit.h"
|
||||
|
||||
void epicsMutexCleanup(void);
|
||||
|
||||
typedef struct exitNode {
|
||||
ELLNODE node;
|
||||
epicsExitFunc func;
|
||||
@@ -115,8 +113,6 @@ LIBCOM_API void epicsExitCallAtExits(void)
|
||||
epicsExitCallAtExitsPvt ( pep );
|
||||
destroyExitPvt ( pep );
|
||||
}
|
||||
/* Handle specially to avoid circular reference */
|
||||
epicsMutexCleanup();
|
||||
}
|
||||
|
||||
LIBCOM_API void epicsExitCallAtThreadExits(void)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <climits>
|
||||
#include <stdexcept>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
//#define EPICS_FREELIST_DEBUG
|
||||
#define EPICS_PRIVATE_API
|
||||
@@ -82,7 +83,6 @@ struct ipAddrToAsciiGlobal : public epicsThreadRunable {
|
||||
|
||||
virtual void run ();
|
||||
|
||||
char nameTmp [1024];
|
||||
tsFreeList
|
||||
< ipAddrToAsciiTransactionPrivate, 0x80 >
|
||||
transactionFreeList;
|
||||
@@ -297,6 +297,8 @@ ipAddrToAsciiTransaction & ipAddrToAsciiEnginePrivate::createTransaction ()
|
||||
|
||||
void ipAddrToAsciiGlobal::run ()
|
||||
{
|
||||
std::vector<char> nameTmp(1024);
|
||||
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
while ( ! this->exitFlag ) {
|
||||
{
|
||||
@@ -313,14 +315,13 @@ void ipAddrToAsciiGlobal::run ()
|
||||
|
||||
if ( this->exitFlag )
|
||||
{
|
||||
sockAddrToDottedIP ( & addr.sa, this->nameTmp,
|
||||
sizeof ( this->nameTmp ) );
|
||||
sockAddrToDottedIP ( & addr.sa, &nameTmp[0], nameTmp.size() );
|
||||
}
|
||||
else {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
// depending on DNS configuration, this could take a very long time
|
||||
// so we release the lock
|
||||
sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) );
|
||||
sockAddrToA ( &addr.sa, &nameTmp[0], nameTmp.size() );
|
||||
}
|
||||
|
||||
// the ipAddrToAsciiTransactionPrivate destructor is allowed to
|
||||
@@ -339,7 +340,7 @@ void ipAddrToAsciiGlobal::run ()
|
||||
{
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
// don't call callback with lock applied
|
||||
pCur->pCB->transactionComplete ( this->nameTmp );
|
||||
pCur->pCB->transactionComplete ( &nameTmp[0] );
|
||||
}
|
||||
|
||||
this->callbackInProgress = false;
|
||||
|
||||
@@ -26,30 +26,23 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsThread.h"
|
||||
#include "valgrind/valgrind.h"
|
||||
#include "ellLib.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsMutexImpl.h"
|
||||
#include "epicsThread.h"
|
||||
#include "cantProceed.h"
|
||||
|
||||
static epicsThreadOnceId epicsMutexOsiOnce = EPICS_THREAD_ONCE_INIT;
|
||||
static ELLLIST mutexList;
|
||||
static ELLLIST freeList;
|
||||
|
||||
struct epicsMutexParm {
|
||||
ELLNODE node;
|
||||
epicsMutexOSD * id;
|
||||
# ifdef LOG_LAST_OWNER
|
||||
epicsThreadId lastOwner;
|
||||
# endif
|
||||
const char *pFileName;
|
||||
int lineno;
|
||||
};
|
||||
|
||||
static epicsMutexOSD * epicsMutexGlobalLock;
|
||||
static ELLLIST mutexList = ELLLIST_INIT;
|
||||
|
||||
/* Specially initialized to bootstrap initialization.
|
||||
* When supported (posix and !rtems) use statically initiallized mutex.
|
||||
* Otherwise, initialize via epicsMutexOsdSetup().
|
||||
*/
|
||||
struct epicsMutexParm epicsMutexGlobalLock = {ELLNODE_INIT, __FILE__, __LINE__};
|
||||
|
||||
// vxWorks 5.4 gcc fails during compile when I use std::exception
|
||||
using namespace std;
|
||||
@@ -76,176 +69,82 @@ const char * epicsMutex::invalidMutex::what () const throw ()
|
||||
return "epicsMutex::invalidMutex()";
|
||||
}
|
||||
|
||||
static void epicsMutexOsiInit(void *) {
|
||||
ellInit(&mutexList);
|
||||
ellInit(&freeList);
|
||||
VALGRIND_CREATE_MEMPOOL(&freeList, 0, 0);
|
||||
epicsMutexGlobalLock = epicsMutexOsdCreate();
|
||||
}
|
||||
|
||||
epicsMutexId epicsStdCall epicsMutexOsiCreate(
|
||||
const char *pFileName,int lineno)
|
||||
{
|
||||
epicsMutexOSD * id;
|
||||
epicsMutexOsdSetup();
|
||||
|
||||
epicsThreadOnce(&epicsMutexOsiOnce, epicsMutexOsiInit, NULL);
|
||||
epicsMutexId ret = (epicsMutexId)calloc(1, sizeof(*ret));
|
||||
if(ret) {
|
||||
ret->pFileName = pFileName;
|
||||
ret->lineno = lineno;
|
||||
|
||||
if(!epicsMutexOsdPrepare(ret)) {
|
||||
epicsMutexMustLock(&epicsMutexGlobalLock);
|
||||
ellAdd(&mutexList, &ret->node);
|
||||
(void)epicsMutexUnlock(&epicsMutexGlobalLock);
|
||||
|
||||
} else {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
id = epicsMutexOsdCreate();
|
||||
if(!id) {
|
||||
return 0;
|
||||
}
|
||||
epicsMutexLockStatus lockStat =
|
||||
epicsMutexOsdLock(epicsMutexGlobalLock);
|
||||
assert ( lockStat == epicsMutexLockOK );
|
||||
epicsMutexParm *pmutexNode =
|
||||
reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) );
|
||||
if(pmutexNode) {
|
||||
ellDelete(&freeList,&pmutexNode->node);
|
||||
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
|
||||
} else {
|
||||
pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) );
|
||||
}
|
||||
VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm));
|
||||
pmutexNode->id = id;
|
||||
# ifdef LOG_LAST_OWNER
|
||||
pmutexNode->lastOwner = 0;
|
||||
# endif
|
||||
pmutexNode->pFileName = pFileName;
|
||||
pmutexNode->lineno = lineno;
|
||||
ellAdd(&mutexList,&pmutexNode->node);
|
||||
epicsMutexOsdUnlock(epicsMutexGlobalLock);
|
||||
return(pmutexNode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
epicsMutexId epicsStdCall epicsMutexOsiMustCreate(
|
||||
const char *pFileName,int lineno)
|
||||
{
|
||||
epicsMutexId id = epicsMutexOsiCreate(pFileName,lineno);
|
||||
assert(id);
|
||||
return(id );
|
||||
if(!id) {
|
||||
cantProceed("epicsMutexOsiMustCreate() fails at %s:%d\n",
|
||||
pFileName, lineno);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
|
||||
{
|
||||
epicsMutexLockStatus lockStat =
|
||||
epicsMutexOsdLock(epicsMutexGlobalLock);
|
||||
assert ( lockStat == epicsMutexLockOK );
|
||||
ellDelete(&mutexList,&pmutexNode->node);
|
||||
epicsMutexOsdDestroy(pmutexNode->id);
|
||||
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
|
||||
VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node));
|
||||
ellAdd(&freeList,&pmutexNode->node);
|
||||
epicsMutexOsdUnlock(epicsMutexGlobalLock);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
|
||||
{
|
||||
epicsMutexOsdUnlock(pmutexNode->id);
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsStdCall epicsMutexLock(
|
||||
epicsMutexId pmutexNode)
|
||||
{
|
||||
epicsMutexLockStatus status =
|
||||
epicsMutexOsdLock(pmutexNode->id);
|
||||
# ifdef LOG_LAST_OWNER
|
||||
if ( status == epicsMutexLockOK ) {
|
||||
pmutexNode->lastOwner = epicsThreadGetIdSelf();
|
||||
}
|
||||
# endif
|
||||
return status;
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsStdCall epicsMutexTryLock(
|
||||
epicsMutexId pmutexNode)
|
||||
{
|
||||
epicsMutexLockStatus status =
|
||||
epicsMutexOsdTryLock(pmutexNode->id);
|
||||
# ifdef LOG_LAST_OWNER
|
||||
if ( status == epicsMutexLockOK ) {
|
||||
pmutexNode->lastOwner = epicsThreadGetIdSelf();
|
||||
}
|
||||
# endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Empty the freeList.
|
||||
* Called from epicsExit.c, but not via epicsAtExit()
|
||||
* to avoid the possibility of a circular reference.
|
||||
*/
|
||||
extern "C"
|
||||
void epicsMutexCleanup(void)
|
||||
{
|
||||
ELLNODE *cur;
|
||||
epicsMutexLockStatus lockStat =
|
||||
epicsMutexOsdLock(epicsMutexGlobalLock);
|
||||
assert ( lockStat == epicsMutexLockOK );
|
||||
|
||||
while((cur=ellGet(&freeList))!=NULL) {
|
||||
VALGRIND_MEMPOOL_FREE(&freeList, cur);
|
||||
free(cur);
|
||||
if(pmutexNode) {
|
||||
epicsMutexMustLock(&epicsMutexGlobalLock);
|
||||
ellDelete(&mutexList, &pmutexNode->node);
|
||||
(void)epicsMutexUnlock(&epicsMutexGlobalLock);
|
||||
epicsMutexOsdCleanup(pmutexNode);
|
||||
free(pmutexNode);
|
||||
}
|
||||
|
||||
epicsMutexOsdUnlock(epicsMutexGlobalLock);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsMutexShow(
|
||||
epicsMutexId pmutexNode, unsigned int level)
|
||||
{
|
||||
# ifdef LOG_LAST_OWNER
|
||||
char threadName [255];
|
||||
if ( pmutexNode->lastOwner ) {
|
||||
# error currently not safe to fetch name for stale thread
|
||||
epicsThreadGetName ( pmutexNode->lastOwner,
|
||||
threadName, sizeof ( threadName ) );
|
||||
}
|
||||
else {
|
||||
strcpy ( threadName, "<not used>" );
|
||||
}
|
||||
printf("epicsMutexId %p last owner \"%s\" source %s line %d\n",
|
||||
(void *)pmutexNode, threadName,
|
||||
pmutexNode->pFileName, pmutexNode->lineno);
|
||||
# else
|
||||
printf("epicsMutexId %p source %s line %d\n",
|
||||
(void *)pmutexNode, pmutexNode->pFileName,
|
||||
pmutexNode->lineno);
|
||||
# endif
|
||||
printf("epicsMutexId %p source %s line %d\n",
|
||||
(void *)pmutexNode, pmutexNode->pFileName,
|
||||
pmutexNode->lineno);
|
||||
if ( level > 0 ) {
|
||||
epicsMutexOsdShow(pmutexNode->id,level-1);
|
||||
epicsMutexOsdShow(pmutexNode,level-1);
|
||||
}
|
||||
}
|
||||
|
||||
void epicsStdCall epicsMutexShowAll(int onlyLocked,unsigned int level)
|
||||
{
|
||||
epicsMutexParm *pmutexNode;
|
||||
epicsMutexOsdSetup();
|
||||
|
||||
if (epicsMutexOsiOnce == EPICS_THREAD_ONCE_INIT)
|
||||
return;
|
||||
|
||||
printf("ellCount(&mutexList) %d ellCount(&freeList) %d\n",
|
||||
ellCount(&mutexList),ellCount(&freeList));
|
||||
printf("ellCount(&mutexList) %d\n", ellCount(&mutexList));
|
||||
epicsMutexOsdShowAll();
|
||||
epicsMutexLockStatus lockStat =
|
||||
epicsMutexOsdLock(epicsMutexGlobalLock);
|
||||
assert ( lockStat == epicsMutexLockOK );
|
||||
pmutexNode = reinterpret_cast < epicsMutexParm * > ( ellFirst(&mutexList) );
|
||||
while(pmutexNode) {
|
||||
epicsMutexMustLock(&epicsMutexGlobalLock);
|
||||
for(ELLNODE *cur =ellFirst(&mutexList); cur; cur = ellNext(cur)) {
|
||||
epicsMutexParm *lock = CONTAINER(cur, epicsMutexParm, node);
|
||||
if(onlyLocked) {
|
||||
epicsMutexLockStatus status;
|
||||
status = epicsMutexOsdTryLock(pmutexNode->id);
|
||||
if(status==epicsMutexLockOK) {
|
||||
epicsMutexOsdUnlock(pmutexNode->id);
|
||||
pmutexNode =
|
||||
reinterpret_cast < epicsMutexParm * >
|
||||
( ellNext(&pmutexNode->node) );
|
||||
continue;
|
||||
// cycle through to test state
|
||||
if(epicsMutexTryLock(lock)==epicsMutexLockOK) {
|
||||
epicsMutexUnlock(lock);
|
||||
continue; // was not locked, skip
|
||||
}
|
||||
}
|
||||
epicsMutexShow(pmutexNode, level);
|
||||
pmutexNode =
|
||||
reinterpret_cast < epicsMutexParm * > ( ellNext(&pmutexNode->node) );
|
||||
epicsMutexShow(lock, level);
|
||||
}
|
||||
epicsMutexOsdUnlock(epicsMutexGlobalLock);
|
||||
epicsMutexUnlock(&epicsMutexGlobalLock);
|
||||
}
|
||||
|
||||
#if !defined(__GNUC__) || __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<8)
|
||||
|
||||
@@ -247,21 +247,6 @@ LIBCOM_API void epicsStdCall epicsMutexShow(
|
||||
LIBCOM_API void epicsStdCall epicsMutexShowAll(
|
||||
int onlyLocked,unsigned int level);
|
||||
|
||||
/**@privatesection
|
||||
* The following are interfaces to the OS dependent
|
||||
* implementation and should NOT be called directly by
|
||||
* user code.
|
||||
*/
|
||||
struct epicsMutexOSD * epicsMutexOsdCreate(void);
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD *);
|
||||
void epicsMutexOsdUnlock(struct epicsMutexOSD *);
|
||||
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *);
|
||||
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *);
|
||||
void epicsMutexOsdShow(struct epicsMutexOSD *,unsigned int level);
|
||||
#ifdef EPICS_PRIVATE_API
|
||||
void epicsMutexOsdShowAll(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
66
modules/libcom/src/osi/epicsMutexImpl.h
Normal file
66
modules/libcom/src/osi/epicsMutexImpl.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* Copyright (c) 2023 Michael Davidsaver
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* Only include from osdMutex.c */
|
||||
|
||||
#ifndef epicsMutexImpl_H
|
||||
#define epicsMutexImpl_H
|
||||
|
||||
#if defined(vxWorks)
|
||||
# include <vxWorks.h>
|
||||
# include <semLib.h>
|
||||
#elif defined(_WIN32)
|
||||
# define VC_EXTRALEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#elif defined(__rtems__)
|
||||
# include <rtems.h>
|
||||
# include <rtems/score/cpuopts.h>
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "ellLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct epicsMutexParm {
|
||||
/* global list of mutex */
|
||||
ELLNODE node;
|
||||
/* location where mutex was allocated */
|
||||
const char *pFileName;
|
||||
int lineno;
|
||||
#if defined(vxWorks)
|
||||
SEM_ID osd;
|
||||
#elif defined(_WIN32)
|
||||
CRITICAL_SECTION osd;
|
||||
#elif defined(__RTEMS_MAJOR__) && __RTEMS_MAJOR__<5
|
||||
Semaphore_Control *osd;
|
||||
#else
|
||||
pthread_mutex_t osd;
|
||||
#endif
|
||||
};
|
||||
|
||||
void epicsMutexOsdSetup(void);
|
||||
long epicsMutexOsdPrepare(struct epicsMutexParm *);
|
||||
void epicsMutexOsdCleanup(struct epicsMutexParm *);
|
||||
void epicsMutexOsdShow(struct epicsMutexParm *,unsigned int level);
|
||||
void epicsMutexOsdShowAll(void);
|
||||
|
||||
extern struct epicsMutexParm epicsMutexGlobalLock;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C
|
||||
#endif
|
||||
|
||||
#endif // epicsMutexImpl_H
|
||||
@@ -238,7 +238,7 @@ size_t epicsStdCall epicsTimeToStrftime (char *pBuff, size_t bufLength, const ch
|
||||
// convert nanosecs to integer of correct range
|
||||
frac /= div[fracWid];
|
||||
char fracFormat[32];
|
||||
sprintf ( fracFormat, "%%0%lulu", fracWid );
|
||||
epicsSnprintf ( fracFormat, sizeof ( fracFormat ), "%%0%lulu", fracWid );
|
||||
int status = epicsSnprintf ( pBufCur, bufLenLeft, fracFormat, frac );
|
||||
if ( status > 0 ) {
|
||||
unsigned long nChar = static_cast < unsigned long > ( status );
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsThread.h"
|
||||
#include "rtemsNamePvt.h"
|
||||
#include "errlog.h"
|
||||
|
||||
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
|
||||
@@ -48,11 +49,9 @@ 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';
|
||||
static uint32_t name;
|
||||
|
||||
sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1),
|
||||
sc = rtems_semaphore_create (next_rtems_name ('B', &name),
|
||||
initialState,
|
||||
RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
|
||||
@@ -62,26 +61,6 @@ epicsEventCreate(epicsEventInitialState initialState)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
@@ -26,97 +27,84 @@
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsMutexImpl.h"
|
||||
#include "rtemsNamePvt.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "errlog.h"
|
||||
|
||||
#define RTEMS_FAST_MUTEX
|
||||
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
|
||||
/*
|
||||
* Some performance tuning instrumentation
|
||||
*/
|
||||
#ifdef EPICS_RTEMS_SEMAPHORE_STATS
|
||||
unsigned long semMstat[4];
|
||||
#define SEMSTAT(i) semMstat[i]++;
|
||||
#else
|
||||
#define SEMSTAT(i)
|
||||
#endif
|
||||
uint32_t next_rtems_name(char prefix, uint32_t* counter)
|
||||
{
|
||||
uint32_t next;
|
||||
rtems_interrupt_level level;
|
||||
char a, b, c;
|
||||
|
||||
struct epicsMutexOSD *
|
||||
epicsMutexOsdCreate(void)
|
||||
rtems_interrupt_disable (level);
|
||||
next = *counter;
|
||||
*counter = (next+1)%(26u*26u*26u);
|
||||
rtems_interrupt_enable (level);
|
||||
|
||||
a = 'a' + (next % 26u);
|
||||
next /= 26u;
|
||||
b = 'a' + (next % 26u);
|
||||
next /= 26u;
|
||||
c = 'a' + (next % 26u); // modulo should be redundant, but ... paranoia
|
||||
|
||||
return rtems_build_name(prefix, a, b, c);
|
||||
}
|
||||
|
||||
void epicsMutexOsdSetup(void)
|
||||
{
|
||||
// TODO: use RTEMS_SYSINIT_ITEM() ?
|
||||
if(!epicsMutexGlobalLock.osd) {
|
||||
epicsMutexOsdPrepare(&epicsMutexGlobalLock);
|
||||
}
|
||||
}
|
||||
|
||||
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id sid;
|
||||
rtems_interrupt_level level;
|
||||
static char c1 = 'a';
|
||||
static char c2 = 'a';
|
||||
static char c3 = 'a';
|
||||
static uint32_t name;
|
||||
|
||||
sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1),
|
||||
sc = rtems_semaphore_create (next_rtems_name ('M', &name),
|
||||
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;
|
||||
return ENOMEM;
|
||||
}
|
||||
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;
|
||||
Objects_Locations location;
|
||||
|
||||
the_semaphore = _Semaphore_Get( sid, &location );
|
||||
_Thread_Enable_dispatch();
|
||||
mutex->osd = _Semaphore_Get( sid, &location );
|
||||
_Thread_Enable_dispatch(); /* _Semaphore_Get() disables */
|
||||
|
||||
return (struct epicsMutexOSD *)the_semaphore;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return (struct epicsMutexOSD *)sid;
|
||||
}
|
||||
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD * id)
|
||||
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id sid;
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
Semaphore_Control *the_semaphore = mutex->osd;
|
||||
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 %p (%lx): %s\n", id, (unsigned long)sid, rtems_status_text (sc));
|
||||
errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n",
|
||||
mutex, (unsigned long)sid, rtems_status_text (sc));
|
||||
}
|
||||
|
||||
void epicsMutexOsdUnlock(struct epicsMutexOSD * id)
|
||||
void epicsMutexUnlock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
Semaphore_Control *the_semaphore = mutex->osd;
|
||||
_Thread_Disable_dispatch();
|
||||
_CORE_mutex_Surrender (
|
||||
&the_semaphore->Core_control.mutex,
|
||||
@@ -124,18 +112,13 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * id)
|
||||
NULL
|
||||
);
|
||||
_Thread_Enable_dispatch();
|
||||
#else
|
||||
epicsEventSignal (id);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id)
|
||||
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
Semaphore_Control *the_semaphore = mutex->osd;
|
||||
ISR_Level level;
|
||||
SEMSTAT(0)
|
||||
_ISR_Disable( level );
|
||||
_CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
@@ -148,19 +131,12 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id)
|
||||
return epicsMutexLockOK;
|
||||
else
|
||||
return epicsMutexLockError;
|
||||
#else
|
||||
SEMSTAT(0)
|
||||
return((epicsEventWait (id) == epicsEventWaitOK)
|
||||
?epicsMutexLockOK : epicsMutexLockError);
|
||||
#endif
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
|
||||
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
Semaphore_Control *the_semaphore = mutex->osd;
|
||||
ISR_Level level;
|
||||
SEMSTAT(2)
|
||||
_ISR_Disable( level );
|
||||
_CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
@@ -175,25 +151,12 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
|
||||
return epicsMutexLockTimeout;
|
||||
else
|
||||
return epicsMutexLockError;
|
||||
#else
|
||||
epicsEventWaitStatus status;
|
||||
SEMSTAT(2)
|
||||
status = epicsEventTryWait(id);
|
||||
return((status==epicsEventWaitOK
|
||||
? epicsMutexLockOK
|
||||
: (status==epicsEventWaitTimeout)
|
||||
? epicsMutexLockTimeout
|
||||
: epicsMutexLockError));
|
||||
#endif
|
||||
}
|
||||
|
||||
LIBCOM_API void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level)
|
||||
LIBCOM_API void epicsMutexOsdShow(struct epicsMutexParm *mutex,unsigned int level)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
id = (struct epicsMutexOSD *)the_semaphore->Object.id;
|
||||
#endif
|
||||
epicsEventShow ((epicsEventId)id,level);
|
||||
Semaphore_Control *the_semaphore = mutex->osd;
|
||||
epicsEventShow ((epicsEventId)the_semaphore->Object.id,level);
|
||||
}
|
||||
|
||||
void epicsMutexOsdShowAll(void) {}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "epicsStdio.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsMutexImpl.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsThread.h"
|
||||
#include "cantProceed.h"
|
||||
@@ -59,7 +60,7 @@ struct taskVar {
|
||||
unsigned int threadVariableCapacity;
|
||||
void **threadVariables;
|
||||
};
|
||||
static struct epicsMutexOSD *taskVarMutex;
|
||||
static struct epicsMutexParm taskVarMutex = {ELLNODE_INIT, __FILE__, __LINE__};
|
||||
static struct taskVar *taskVarHead;
|
||||
#define RTEMS_NOTEPAD_TASKVAR 11
|
||||
|
||||
@@ -67,15 +68,7 @@ static struct taskVar *taskVarHead;
|
||||
* Support for `once-only' execution
|
||||
*/
|
||||
static volatile int initialized = 0; /* strictly speaking 'volatile' is not enough here, but it shouldn't hurt */
|
||||
static struct epicsMutexOSD *onceMutex;
|
||||
|
||||
static
|
||||
void epicsMutexOsdMustLock(struct epicsMutexOSD * L)
|
||||
{
|
||||
while(epicsMutexOsdLock(L)!=epicsMutexLockOK) {
|
||||
cantProceed("epicsThreadOnce() mutex error");
|
||||
}
|
||||
}
|
||||
static struct epicsMutexParm onceMutex = {ELLNODE_INIT, __FILE__, __LINE__};
|
||||
|
||||
/*
|
||||
* Just map osi 0 to 99 into RTEMS 199 to 100
|
||||
@@ -161,13 +154,13 @@ epicsThreadGetStackSize (epicsThreadStackSizeClass size)
|
||||
static void
|
||||
taskVarLock (void)
|
||||
{
|
||||
epicsMutexOsdMustLock (taskVarMutex);
|
||||
epicsMutexMustLock (&taskVarMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
taskVarUnlock (void)
|
||||
{
|
||||
epicsMutexOsdUnlock (taskVarMutex);
|
||||
epicsMutexUnlock (&taskVarMutex);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -243,7 +236,7 @@ setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr,
|
||||
v->threadVariables = NULL;
|
||||
v->isRunning = 1;
|
||||
if (joinable) {
|
||||
char c[3];
|
||||
char c[3] = {0,0,0};
|
||||
strncpy(c, v->name, 3);
|
||||
sc = rtems_barrier_create(rtems_build_name('~', c[0], c[1], c[2]),
|
||||
RTEMS_BARRIER_AUTOMATIC_RELEASE | RTEMS_LOCAL,
|
||||
@@ -288,10 +281,8 @@ epicsThreadInit (void)
|
||||
rtems_task_priority old;
|
||||
|
||||
rtems_task_set_priority (RTEMS_SELF, epicsThreadGetOssPriorityValue(99), &old);
|
||||
onceMutex = epicsMutexOsdCreate();
|
||||
taskVarMutex = epicsMutexOsdCreate();
|
||||
if (!onceMutex || !taskVarMutex)
|
||||
cantProceed("epicsThreadInit() can't create global mutexes\n");
|
||||
epicsMutexOsdPrepare(&taskVarMutex);
|
||||
epicsMutexOsdPrepare(&onceMutex);
|
||||
rtems_task_ident (RTEMS_SELF, 0, &tid);
|
||||
if(setThreadInfo (tid, "_main_", NULL, NULL, 0) != RTEMS_SUCCESSFUL)
|
||||
cantProceed("epicsThreadInit() unable to setup _main_");
|
||||
@@ -317,7 +308,7 @@ epicsThreadCreateOpt (
|
||||
unsigned int stackSize;
|
||||
rtems_id tid;
|
||||
rtems_status_code sc;
|
||||
char c[4];
|
||||
char c[4] = {0,0,0,0};
|
||||
|
||||
if (!initialized)
|
||||
epicsThreadInit();
|
||||
@@ -612,26 +603,26 @@ void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg)
|
||||
#define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1
|
||||
|
||||
if (!initialized) epicsThreadInit();
|
||||
epicsMutexOsdMustLock(onceMutex);
|
||||
epicsMutexMustLock(&onceMutex);
|
||||
if (*id != EPICS_THREAD_ONCE_DONE) {
|
||||
if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */
|
||||
*id = epicsThreadGetIdSelf(); /* mark active */
|
||||
epicsMutexOsdUnlock(onceMutex);
|
||||
epicsMutexUnlock(&onceMutex);
|
||||
func(arg);
|
||||
epicsMutexOsdMustLock(onceMutex);
|
||||
epicsMutexMustLock(&onceMutex);
|
||||
*id = EPICS_THREAD_ONCE_DONE; /* mark done */
|
||||
} else if (*id == epicsThreadGetIdSelf()) {
|
||||
epicsMutexOsdUnlock(onceMutex);
|
||||
epicsMutexUnlock(&onceMutex);
|
||||
cantProceed("Recursive epicsThreadOnce() initialization\n");
|
||||
} else
|
||||
while (*id != EPICS_THREAD_ONCE_DONE) {
|
||||
/* Another thread is in the above func(arg) call. */
|
||||
epicsMutexOsdUnlock(onceMutex);
|
||||
epicsMutexUnlock(&onceMutex);
|
||||
epicsThreadSleep(epicsThreadSleepQuantum());
|
||||
epicsMutexOsdMustLock(onceMutex);
|
||||
epicsMutexMustLock(&onceMutex);
|
||||
}
|
||||
}
|
||||
epicsMutexOsdUnlock(onceMutex);
|
||||
epicsMutexUnlock(&onceMutex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
20
modules/libcom/src/osi/os/RTEMS-score/rtemsNamePvt.h
Normal file
20
modules/libcom/src/osi/os/RTEMS-score/rtemsNamePvt.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Michael Davidsaver
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS Base is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#ifndef RTEMSNAMEPVT_H
|
||||
#define RTEMSNAMEPVT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Compute rtems_build_name(prefix, A, B, C) where A, B, C are the letters a-z.
|
||||
* eg. "Qaaa"
|
||||
*
|
||||
* 'counter' is incremented atomically during each call.
|
||||
*/
|
||||
uint32_t next_rtems_name(char prefix, uint32_t* counter);
|
||||
|
||||
#endif // RTEMSNAMEPVT_H
|
||||
@@ -20,147 +20,59 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define VC_EXTRALEAN
|
||||
#define STRICT
|
||||
#include <windows.h>
|
||||
#if _WIN32_WINNT < 0x0501
|
||||
# error Minimum supported is Windows XP
|
||||
#endif
|
||||
|
||||
#define EPICS_PRIVATE_API
|
||||
|
||||
#include "libComAPI.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsMutexImpl.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsStdio.h"
|
||||
|
||||
typedef struct epicsMutexOSD {
|
||||
union {
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION criticalSection;
|
||||
} os;
|
||||
} epicsMutexOSD;
|
||||
|
||||
static BOOL thisIsNT = FALSE;
|
||||
static LONG weHaveInitialized = 0;
|
||||
|
||||
/*
|
||||
* epicsMutexCreate ()
|
||||
*/
|
||||
epicsMutexOSD * epicsMutexOsdCreate ( void )
|
||||
static epicsThreadOnceId epicsMutexOsdOnce = EPICS_THREAD_ONCE_INIT;
|
||||
static void epicsMutexOsdInit(void* unused)
|
||||
{
|
||||
epicsMutexOSD * pSem;
|
||||
|
||||
if ( ! weHaveInitialized ) {
|
||||
BOOL status;
|
||||
OSVERSIONINFO osInfo;
|
||||
osInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO );
|
||||
status = GetVersionEx ( & osInfo );
|
||||
thisIsNT = status && ( osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT );
|
||||
weHaveInitialized = 1;
|
||||
}
|
||||
|
||||
pSem = malloc ( sizeof (*pSem) );
|
||||
if ( pSem ) {
|
||||
if ( thisIsNT ) {
|
||||
InitializeCriticalSection ( &pSem->os.criticalSection );
|
||||
}
|
||||
else {
|
||||
pSem->os.mutex = CreateMutex ( NULL, FALSE, NULL );
|
||||
if ( pSem->os.mutex == 0 ) {
|
||||
free ( pSem );
|
||||
pSem = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pSem;
|
||||
(void)unused;
|
||||
InitializeCriticalSection(&epicsMutexGlobalLock.osd);
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsMutexOsdDestroy ()
|
||||
*/
|
||||
void epicsMutexOsdDestroy ( epicsMutexOSD * pSem )
|
||||
void epicsMutexOsdSetup()
|
||||
{
|
||||
if ( thisIsNT ) {
|
||||
DeleteCriticalSection ( &pSem->os.criticalSection );
|
||||
}
|
||||
else {
|
||||
CloseHandle ( pSem->os.mutex );
|
||||
}
|
||||
free ( pSem );
|
||||
epicsThreadOnce(&epicsMutexOsdOnce, &epicsMutexOsdInit, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsMutexOsdUnlock ()
|
||||
*/
|
||||
void epicsMutexOsdUnlock ( epicsMutexOSD * pSem )
|
||||
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
|
||||
{
|
||||
if ( thisIsNT ) {
|
||||
LeaveCriticalSection ( &pSem->os.criticalSection );
|
||||
}
|
||||
else {
|
||||
BOOL success = ReleaseMutex ( pSem->os.mutex );
|
||||
assert ( success );
|
||||
}
|
||||
InitializeCriticalSection(&mutex->osd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsMutexOsdLock ()
|
||||
*/
|
||||
epicsMutexLockStatus epicsMutexOsdLock ( epicsMutexOSD * pSem )
|
||||
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
|
||||
{
|
||||
if ( thisIsNT ) {
|
||||
EnterCriticalSection ( &pSem->os.criticalSection );
|
||||
}
|
||||
else {
|
||||
DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE );
|
||||
if ( status != WAIT_OBJECT_0 ) {
|
||||
return epicsMutexLockError;
|
||||
}
|
||||
}
|
||||
DeleteCriticalSection(&mutex->osd);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsMutexUnlock ( struct epicsMutexParm *mutex )
|
||||
{
|
||||
LeaveCriticalSection ( &mutex->osd );
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsStdCall epicsMutexLock ( struct epicsMutexParm *mutex )
|
||||
{
|
||||
EnterCriticalSection ( &mutex->osd );
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsMutexOsdTryLock ()
|
||||
*/
|
||||
epicsMutexLockStatus epicsMutexOsdTryLock ( epicsMutexOSD * pSem )
|
||||
epicsMutexLockStatus epicsStdCall epicsMutexTryLock ( struct epicsMutexParm *mutex )
|
||||
{
|
||||
if ( thisIsNT ) {
|
||||
if ( TryEnterCriticalSection ( &pSem->os.criticalSection ) ) {
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
else {
|
||||
return epicsMutexLockTimeout;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DWORD status = WaitForSingleObject ( pSem->os.mutex, 0 );
|
||||
if ( status != WAIT_OBJECT_0 ) {
|
||||
if (status == WAIT_TIMEOUT) {
|
||||
return epicsMutexLockTimeout;
|
||||
}
|
||||
else {
|
||||
return epicsMutexLockError;
|
||||
}
|
||||
}
|
||||
}
|
||||
return epicsMutexLockOK;
|
||||
return TryEnterCriticalSection ( &mutex->osd ) ? epicsMutexLockOK : epicsMutexLockTimeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsMutexOsdShow ()
|
||||
*/
|
||||
void epicsMutexOsdShow ( epicsMutexOSD * pSem, unsigned level )
|
||||
void epicsMutexOsdShow ( struct epicsMutexParm *mutex, unsigned level )
|
||||
{
|
||||
if ( thisIsNT ) {
|
||||
printf ("epicsMutex: win32 critical section at %p\n",
|
||||
(void * ) & pSem->os.criticalSection );
|
||||
}
|
||||
else {
|
||||
printf ( "epicsMutex: win32 mutex at %p\n",
|
||||
( void * ) pSem->os.mutex );
|
||||
}
|
||||
(void)level;
|
||||
printf ("epicsMutex: win32 critical section at %p\n",
|
||||
(void * ) & mutex->osd );
|
||||
}
|
||||
|
||||
void epicsMutexOsdShowAll(void) {}
|
||||
|
||||
@@ -119,8 +119,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
|
||||
return socket ( domain, type, protocol );
|
||||
}
|
||||
|
||||
LIBCOM_API int epicsStdCall epicsSocketAccept (
|
||||
int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
|
||||
LIBCOM_API SOCKET epicsStdCall epicsSocketAccept (
|
||||
SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
|
||||
{
|
||||
return accept ( sock, pAddr, addrlen );
|
||||
}
|
||||
|
||||
@@ -500,8 +500,6 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter )
|
||||
BOOL success;
|
||||
|
||||
if ( pGbl ) {
|
||||
setThreadName ( pParm->id, pParm->pName );
|
||||
|
||||
success = FlsSetValue ( pGbl->flsIndexThreadLibraryEPICS, pParm );
|
||||
if ( success ) {
|
||||
osdThreadHooksRun ( ( epicsThreadId ) pParm );
|
||||
@@ -659,6 +657,7 @@ epicsThreadId epicsThreadCreateOpt (
|
||||
pParmWIN32->id = ( DWORD ) threadId ;
|
||||
}
|
||||
|
||||
setThreadName ( pParmWIN32->id, pParmWIN32->pName );
|
||||
osdPriority = epicsThreadGetOsdPriorityValue (opts->priority);
|
||||
bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority );
|
||||
if (!bstat) {
|
||||
|
||||
@@ -215,6 +215,7 @@ void currentTime :: startPLL ()
|
||||
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
|
||||
& this->threadId );
|
||||
assert ( this->threadHandle );
|
||||
setThreadName ( this->threadId, "EPICS Time PLL" );
|
||||
BOOL bstat = SetThreadPriority (
|
||||
this->threadHandle, THREAD_PRIORITY_HIGHEST );
|
||||
assert ( bstat );
|
||||
@@ -496,7 +497,6 @@ static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn )
|
||||
{
|
||||
currentTime * pCT =
|
||||
reinterpret_cast < currentTime * > ( pCurrentTimeIn );
|
||||
setThreadName ( pCT->threadId, "EPICS Time PLL" );
|
||||
while ( ! pCT->threadShutdownCmd ) {
|
||||
Sleep ( currentTime :: pllDelay * 1000 /* mS */ );
|
||||
pCT->updatePLL ();
|
||||
|
||||
@@ -40,7 +40,16 @@ struct threadNode {
|
||||
struct eventNode *evp;
|
||||
void *buf;
|
||||
unsigned int size;
|
||||
volatile bool eventSent;
|
||||
bool eventSent;
|
||||
inline
|
||||
threadNode()
|
||||
:evp(NULL)
|
||||
,buf(NULL)
|
||||
,size(0u)
|
||||
,eventSent(false)
|
||||
{
|
||||
memset(&link, 0, sizeof(link));
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -366,9 +375,10 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size,
|
||||
|
||||
freeEventNode(pmsg, threadNode.evp, status);
|
||||
|
||||
bool wasSent = threadNode.eventSent;
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
|
||||
if (threadNode.eventSent && (threadNode.size <= size))
|
||||
if (wasSent && (threadNode.size <= size))
|
||||
return threadNode.size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -24,18 +24,19 @@
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <ctype.h>
|
||||
#include <envDefs.h>
|
||||
|
||||
#define EPICS_PRIVATE_API
|
||||
#define epicsStdioStdStreams
|
||||
#define epicsStdioStdPrintfEtc
|
||||
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsMutexImpl.h"
|
||||
#include "osdPosixMutexPriv.h"
|
||||
#include "epicsThread.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "envDefs.h"
|
||||
|
||||
#define checkStatus(status,message) \
|
||||
if((status)) { \
|
||||
@@ -128,62 +129,62 @@ static int mutexLock(pthread_mutex_t *id)
|
||||
return status;
|
||||
}
|
||||
|
||||
typedef struct epicsMutexOSD {
|
||||
pthread_mutex_t lock;
|
||||
} epicsMutexOSD;
|
||||
/* used if OS does not support statically allocated mutex */
|
||||
static pthread_once_t epicsMutexOsdOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
epicsMutexOSD *pmutex;
|
||||
int status;
|
||||
|
||||
pmutex = calloc(1, sizeof(*pmutex));
|
||||
if(!pmutex)
|
||||
return NULL;
|
||||
|
||||
status = osdPosixMutexInit(&pmutex->lock, PTHREAD_MUTEX_RECURSIVE);
|
||||
if (!status)
|
||||
return pmutex;
|
||||
|
||||
free(pmutex);
|
||||
return NULL;
|
||||
static void epicsMutexOsdInit(void)
|
||||
{
|
||||
int ret = pthread_mutex_init(&epicsMutexGlobalLock.osd, NULL);
|
||||
if(ret) {
|
||||
/* something has gone wrong early. Not much can be done...*/
|
||||
fprintf(stderr, "osdMutex early init failure %d.\n", ret);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
|
||||
void epicsMutexOsdSetup()
|
||||
{
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_destroy(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_destroy", "epicsMutexOsdDestroy");
|
||||
free(pmutex);
|
||||
int ret = pthread_once(&epicsMutexOsdOnce, &epicsMutexOsdInit);
|
||||
if(ret) {
|
||||
/* ditto...*/
|
||||
fprintf(stderr, "osdMutex early once failure %d.\n", ret);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
|
||||
long epicsMutexOsdPrepare(struct epicsMutexParm *pmutex) {
|
||||
return osdPosixMutexInit(&pmutex->osd, PTHREAD_MUTEX_RECURSIVE);
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
|
||||
void epicsMutexOsdCleanup(struct epicsMutexParm *pmutex)
|
||||
{
|
||||
int status;
|
||||
int status = pthread_mutex_destroy(&pmutex->osd);
|
||||
checkStatus(status, "pthread_mutex_destroy");
|
||||
}
|
||||
|
||||
status = mutexLock(&pmutex->lock);
|
||||
void epicsMutexUnlock(struct epicsMutexParm * pmutex)
|
||||
{
|
||||
int status = pthread_mutex_unlock(&pmutex->osd);
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock");
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm * pmutex)
|
||||
{
|
||||
int status = mutexLock(&pmutex->osd);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
if(status) {
|
||||
errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n");
|
||||
errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexLock\n");
|
||||
return epicsMutexLockError;
|
||||
}
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
|
||||
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm * pmutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!pmutex) return epicsMutexLockError;
|
||||
status = pthread_mutex_trylock(&pmutex->lock);
|
||||
status = pthread_mutex_trylock(&pmutex->osd);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
if (status == EBUSY) return epicsMutexLockTimeout;
|
||||
if(status) {
|
||||
@@ -193,12 +194,13 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level)
|
||||
void epicsMutexOsdShow(struct epicsMutexParm * pmutex, unsigned int level)
|
||||
{
|
||||
(void)level;
|
||||
/* GLIBC w/ NTPL is passing the &lock.__data.__lock as the first argument (UADDR)
|
||||
* of the futex() syscall. __lock is at offset 0 of the enclosing structures.
|
||||
*/
|
||||
printf(" pthread_mutex_t* uaddr=%p\n", &pmutex->lock);
|
||||
epicsStdoutPrintf(" pthread_mutex_t* uaddr=%p\n", &pmutex->osd);
|
||||
}
|
||||
|
||||
void epicsMutexOsdShowAll(void)
|
||||
@@ -207,11 +209,11 @@ void epicsMutexOsdShowAll(void)
|
||||
int proto = -1;
|
||||
int ret = pthread_mutexattr_getprotocol(&globalAttrRecursive, &proto);
|
||||
if(ret) {
|
||||
printf("PI maybe not enabled: %d\n", ret);
|
||||
epicsStdoutPrintf("PI maybe not enabled: %d\n", ret);
|
||||
} else {
|
||||
printf("PI is%s enabled\n", proto==PTHREAD_PRIO_INHERIT ? "" : " not");
|
||||
epicsStdoutPrintf("PI is%s enabled\n", proto==PTHREAD_PRIO_INHERIT ? "" : " not");
|
||||
}
|
||||
#else
|
||||
printf("PI not supported\n");
|
||||
epicsStdoutPrintf("PI not supported\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "osiSock.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAtomic.h"
|
||||
|
||||
/* Linux and *BSD (at least) specific way to atomically set O_CLOEXEC.
|
||||
* RTEMS 5.1 provides SOCK_CLOEXEC, but doesn't implement accept4()
|
||||
@@ -60,19 +61,18 @@ static void unlockInfo (void)
|
||||
epicsMutexUnlock (infoMutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOOP
|
||||
*/
|
||||
|
||||
static size_t nAttached;
|
||||
|
||||
int osiSockAttach()
|
||||
{
|
||||
epicsAtomicIncrSizeT(&nAttached);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOOP
|
||||
*/
|
||||
void osiSockRelease()
|
||||
{
|
||||
epicsAtomicDecrSizeT(&nAttached);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,6 +83,11 @@ void osiSockRelease()
|
||||
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
|
||||
int domain, int type, int protocol )
|
||||
{
|
||||
static unsigned char warnAttached;
|
||||
if(!epicsAtomicGetSizeT(&nAttached) && !warnAttached) {
|
||||
warnAttached = 1;
|
||||
errlogPrintf(ERL_WARNING ": epicsSocketCreate() without osiSockAttach() is not portable\n");
|
||||
}
|
||||
SOCKET sock = socket ( domain, type | SOCK_CLOEXEC, protocol );
|
||||
if ( sock < 0 ) {
|
||||
sock = INVALID_SOCKET;
|
||||
@@ -119,8 +124,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
|
||||
return sock;
|
||||
}
|
||||
|
||||
LIBCOM_API int epicsStdCall epicsSocketAccept (
|
||||
int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
|
||||
LIBCOM_API SOCKET epicsStdCall epicsSocketAccept (
|
||||
SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
|
||||
{
|
||||
#ifndef HAVE_SOCK_CLOEXEC
|
||||
int newSock = accept ( sock, pAddr, addrlen );
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <objLib.h>
|
||||
#include <sysLib.h>
|
||||
@@ -23,30 +24,47 @@ int sysClkRateGet(void);
|
||||
#define EPICS_PRIVATE_API
|
||||
|
||||
#include "epicsMutex.h"
|
||||
|
||||
struct epicsMutexOSD * epicsMutexOsdCreate(void)
|
||||
#include "epicsMutexImpl.h"
|
||||
|
||||
void epicsMutexOsdSetup(void)
|
||||
{
|
||||
return((struct epicsMutexOSD *)
|
||||
semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY));
|
||||
if(!epicsMutexGlobalLock.osd) {
|
||||
epicsMutexOsdPrepare(&epicsMutexGlobalLock);
|
||||
}
|
||||
}
|
||||
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD * id)
|
||||
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
|
||||
{
|
||||
semDelete((SEM_ID)id);
|
||||
mutex->osd = semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY);
|
||||
return mutex->osd ? 0 : ENOMEM;
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
|
||||
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
|
||||
{
|
||||
int status;
|
||||
status = semTake((SEM_ID)id,NO_WAIT);
|
||||
semDelete(mutex->osd);
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
return semTake(mutex->osd,WAIT_FOREVER)==OK ? epicsMutexLockOK : epicsMutexLockError;
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
int status = semTake(mutex->osd,NO_WAIT);
|
||||
if(status==OK) return(epicsMutexLockOK);
|
||||
if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsMutexLockTimeout);
|
||||
return(epicsMutexLockError);
|
||||
}
|
||||
|
||||
void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level)
|
||||
void epicsMutexUnlock(struct epicsMutexParm *mutex)
|
||||
{
|
||||
semShow((SEM_ID)id,level);
|
||||
semGive(mutex->osd);
|
||||
}
|
||||
|
||||
void epicsMutexOsdShow(struct epicsMutexParm *mutex,unsigned int level)
|
||||
{
|
||||
semShow(mutex->osd,level);
|
||||
}
|
||||
|
||||
void epicsMutexOsdShowAll(void) {}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user