Merge lp:~epics-core/epics-base/add-rtems-4.12-api into lp:~epics-core/epics-base/3.16

Proposed by Andrew Johnson
Status: Rejected
Rejected by: Andrew Johnson
Proposed branch: lp:~epics-core/epics-base/add-rtems-4.12-api
Merge into: lp:~epics-core/epics-base/3.16
Diff against target: 4073 lines (+2253/-730) (has conflicts)
41 files modified
Makefile (+1/-0)
README (+21/-0)
configure/CONFIG_COMMON (+7/-6)
configure/os/CONFIG.Common.RTEMS (+14/-1)
configure/os/CONFIG.Common.RTEMS-beatnik (+6/-5)
configure/os/CONFIG.Common.RTEMS-mvme3100 (+5/-3)
configure/os/CONFIG_SITE.Common.RTEMS (+20/-2)
configure/os/CONFIG_SITE.Common.RTEMS-beatnik (+22/-0)
configure/os/CONFIG_SITE.Common.RTEMS-mvme3100 (+19/-0)
configure/os/CONFIG_SITE.Common.RTEMS-pc386 (+12/-0)
documentation/RELEASE_NOTES.html (+29/-0)
src/ioc/rsrv/caservertask.c (+5/-1)
src/libCom/RTEMS/Makefile (+2/-0)
src/libCom/RTEMS/kernel/rtems_config.c (+6/-6)
src/libCom/RTEMS/kernel/rtems_netconfig.c (+56/-43)
src/libCom/RTEMS/posix/rtems_config.c (+88/-0)
src/libCom/RTEMS/posix/rtems_netconfig.c (+126/-0)
src/libCom/RTEMS/rtems_init.c (+145/-26)
src/libCom/calc/postfix.c (+14/-0)
src/libCom/error/errlog.c (+5/-0)
src/libCom/misc/epicsUnitTest.c (+1/-0)
src/libCom/osi/os/Linux/osdSock.h (+2/-0)
src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c (+367/-0)
src/libCom/osi/os/RTEMS-posix/osdInterrupt.c (+59/-0)
src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp (+163/-0)
src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h (+31/-0)
src/libCom/osi/os/RTEMS-posix/osdMutex.c (+6/-0)
src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c (+34/-0)
src/libCom/osi/os/RTEMS-posix/osdSock.h (+111/-0)
src/libCom/osi/os/WIN32/osdNetIntf.c (+100/-202)
src/libCom/osi/os/default/osdNetIntf.c (+155/-320)
src/libCom/osi/os/posix/osdSockAddrReuse.cpp (+8/-1)
src/libCom/osi/os/posix/osdThread.c (+182/-109)
src/libCom/osi/os/posix/osdThreadExtra.c (+7/-3)
src/libCom/osi/osiSock.c (+157/-0)
src/libCom/osi/osiSock.h (+37/-0)
src/libCom/test/Makefile (+7/-0)
src/libCom/test/epicsMessageQueueTest.cpp (+1/-1)
src/libCom/test/epicsNetIntfTest.c (+220/-0)
src/libCom/test/epicsRunLibComTests.c (+2/-0)
src/libCom/test/ringPointerTest.c (+0/-1)
Text conflict in src/libCom/RTEMS/rtems_init.c
To merge this branch: bzr merge lp:~epics-core/epics-base/add-rtems-4.12-api
Reviewer Review Type Date Requested Status
Andrew Johnson Needs Fixing
Review via email: mp+320503@code.launchpad.net

Description of the change

Heinz's RTEMS-4.12 port with the additional OS_API flag and reorganized to allow switching between kernel and posix implementations. For RTEMS the flag's value is set automatically based on a new RTEMS_SERIES setting in CONFIG_SITE.Common.RTEMS.

I can't implement Michael's request to use explicit paths to the source files without making significant changes to the build rules, and that would probably break a large number of external modules; the OS_API approach is backwards compatible.

I have checked that this branch builds against both RTEMS-4.9.2 and 4.10.2, but I don't have RTEMS-4.12 here to try it against. I have reservations about some of the posix implementations which I will bring up in review comments.

To post a comment you must log in.
Revision history for this message
Andrew Johnson (anj) wrote :

Various inline comments and questions.

Revision history for this message
Andrew Johnson (anj) wrote :

A couple more inline comments/questions.

12746. By Heinz Junkes

in 'configure/os/CONFIG.Common.RTEMS-beatnik
set MY_DO_BOOTP to rtems_bsdnet_do_bootp as I have checked just
   "network booting" with dhcp. Booting with NVRAM-settings not tested until now

in src/libCom/RTEMS/posix/rtems_netconfig.c
Interface named defined in ./configure/os/CONFIG.Common.RTEMS-beatnik
ARCH_DEP_CFLAGS += -DETH_NAME_1=mve1
ARCH_DEP_CFAGS += -DETH_NAME_2=mve2
done just for powerpc-beatnik

Initial date in src/libCom/RTEMS/rtems_init.c
100 years after the sinking of the Titanik, I was 50 years old ;-)

src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c
I still do not know where where routine bspExtMemProb and bspExtInit() come from.

src/libCom/osi/os/posix/osdThread.c
No special rtems-version. I modified the "standard" posix osdThread.c
Add __thread (thread local variable) instead of posix key.
Other stack-space, printk statements, all with #if defined (__rtems__).
Hope this is ok.

12747. By Andrew Johnson

Network config changes, to generalize

12748. By mdavidsaver

libCom: rtems < 4.12 doesn't have SO_REUSEPORT

12749. By mdavidsaver

libCom/RTEMS: avoid multiple defs w/ RTEMS < 4.12

Revision history for this message
Andrew Johnson (anj) wrote :

This branch is *not* ready to merge, sorry, it needs some major cleaning up in places.

Please remove the extraneous comments from the README file.

There are some changes related to multicast options which will probably conflict with my osiSockTest branch (which is aimed at 3.15 but should be merged up first). The osiSockTest branch changes should take precedence over those from this branch.

Please remove the call to epicsThreadShowAll() from testHarness() in epicsUnitTest.c. There appear to be a few other extraneous changes (e.g. adding or removing blank lines to files which are otherwise unchanged) which I would like to see deleted. Code that should be indented but isn't, extraneous commented out lines etc. — these kinds of changes should never have been committed in the first place.

The various rtems-specific includes that have been added to a number of files (e.g. errlog.c) really should be put in an RTEMS-specific osd* header file, although I'm not sure which. We have tried to remove all OS-conditional includes from the general EPICS sources, and I don't want to let them back in again here.

I frown on the use of C++ // comments in .c files. Maybe they don't matter any more with the latest compilers, but I still have to support systems with compilers that don't allow them.

Does this branch include (some of) Michael's osiaddrinfo branch? There are changes in it which seem to be related to that and have his name on them, but I don't know the specifics. That branch had problems on MacOS and some other architectures, so this makes me a little nervous.

review: Needs Fixing
Revision history for this message
Heinz Junkes (junkes) wrote :

Dear Andrew,
thank you for your review.
For me it looks not like a diff to the merge request (and push) I made at ITER on 5th of october.

I pushed my code to git+ssh://<email address hidden>/~epics-core/epics-base/+git/add-rtems-4.12-api

git log shows :

commit 6633ba5483732cd715420f874a85aed11e7df5fb
Author: Heinz Junkes <email address hidden>
Date: Thu Oct 5 14:45:19 2017 +0200

    add define rtems for SO_REUSEPORT etc

commit 2c707a1deebb1072fe77068c0a5fa389aa266c04
Author: Heinz Junkes <email address hidden>
Date: Thu Oct 5 09:24:55 2017 +0200

    RTEMS4.12

commit fdfd324fa760521e106de6165042ceffc5bad4a1
Author: Michael Davidsaver <email address hidden>
Date: Sun Jun 18 20:53:28 2017 +0200

    travis-ci: run RTEMS tests

Cheers,
Heinz

> On 19 Oct 2017, at 04:17, Andrew Johnson <email address hidden> wrote:
>
> Review: Needs Fixing
>
> This branch is *not* ready to merge, sorry, it needs some major cleaning up in places.
>
> Please remove the extraneous comments from the README file.
>
> There are some changes related to multicast options which will probably conflict with my osiSockTest branch (which is aimed at 3.15 but should be merged up first). The osiSockTest branch changes should take precedence over those from this branch.
>
> Please remove the call to epicsThreadShowAll() from testHarness() in epicsUnitTest.c. There appear to be a few other extraneous changes (e.g. adding or removing blank lines to files which are otherwise unchanged) which I would like to see deleted. Code that should be indented but isn't, extraneous commented out lines etc. — these kinds of changes should never have been committed in the first place.
>
> The various rtems-specific includes that have been added to a number of files (e.g. errlog.c) really should be put in an RTEMS-specific osd* header file, although I'm not sure which. We have tried to remove all OS-conditional includes from the general EPICS sources, and I don't want to let them back in again here.
>
> I frown on the use of C++ // comments in .c files. Maybe they don't matter any more with the latest compilers, but I still have to support systems with compilers that don't allow them.
>
> Does this branch include (some of) Michael's osiaddrinfo branch? There are changes in it which seem to be related to that and have his name on them, but I don't know the specifics. That branch had problems on MacOS and some other architectures, so this makes me a little nervous.
>
> --
> https://code.launchpad.net/~epics-core/epics-base/add-rtems-4.12-api/+merge/320503
> Your team EPICS Core Developers is subscribed to branch lp:~epics-core/epics-base/3.16.

Revision history for this message
Andrew Johnson (anj) wrote :

Hello Heinz,

Ahhh, this merge request is for the old Bazaar branch, my sincere apologies for not noticing that. I will mark this one as old and propose a merge of your new version.

- Andrew

Unmerged revisions

12749. By mdavidsaver

libCom/RTEMS: avoid multiple defs w/ RTEMS < 4.12

12748. By mdavidsaver

libCom: rtems < 4.12 doesn't have SO_REUSEPORT

12747. By Andrew Johnson

Network config changes, to generalize

12746. By Heinz Junkes

in 'configure/os/CONFIG.Common.RTEMS-beatnik
set MY_DO_BOOTP to rtems_bsdnet_do_bootp as I have checked just
   "network booting" with dhcp. Booting with NVRAM-settings not tested until now

in src/libCom/RTEMS/posix/rtems_netconfig.c
Interface named defined in ./configure/os/CONFIG.Common.RTEMS-beatnik
ARCH_DEP_CFLAGS += -DETH_NAME_1=mve1
ARCH_DEP_CFAGS += -DETH_NAME_2=mve2
done just for powerpc-beatnik

Initial date in src/libCom/RTEMS/rtems_init.c
100 years after the sinking of the Titanik, I was 50 years old ;-)

src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c
I still do not know where where routine bspExtMemProb and bspExtInit() come from.

src/libCom/osi/os/posix/osdThread.c
No special rtems-version. I modified the "standard" posix osdThread.c
Add __thread (thread local variable) instead of posix key.
Other stack-space, printk statements, all with #if defined (__rtems__).
Hope this is ok.

12745. By Andrew Johnson

Convert to OS_API layout

12744. By Andrew Johnson

Support for OS_API variable

12743. By Heinz Junkes <email address hidden>

RTEMS4.12 Port for EPICS 3.16

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2016-05-22 12:38:18 +0000
+++ Makefile 2017-05-01 18:36:52 +0000
@@ -8,6 +8,7 @@
8#*************************************************************************8#*************************************************************************
99
10TOP = .10TOP = .
11
11include $(TOP)/configure/CONFIG12include $(TOP)/configure/CONFIG
1213
13# Bootstrap resolution: tools not installed yet14# Bootstrap resolution: tools not installed yet
1415
=== modified file 'README'
--- README 2017-02-01 17:57:04 +0000
+++ README 2017-05-01 18:36:52 +0000
@@ -22,3 +22,24 @@
22websites etc. is available on the EPICS home page at22websites etc. is available on the EPICS home page at
23 http://www.aps.anl.gov/epics/23 http://www.aps.anl.gov/epics/
2424
25hpj:
26In configure/CONFIG_COMMON add RTEMS_XVERSION
27$(addprefix $(dir)/, os/$(OS_CLASS)$(RTEMS_XVERSION) $(POSIX_$(POSIX)) os/default ))
28
29add to $Home/configure/CONFIG_USER
30
31#FHI
32EPICS_SITE_VERSION = fhi
33#
34RTEMS_VERSION = 4.12
35#to use new libcom osd files
36RTEMS_XVERSION = 4.12
37
38RTEMS_BASE = /home/h1/RTEMS/rtems-$(RTEMS_VERSION)
39
40# Runs on beatnik board (MVME6100)
41CROSS_COMPILER_TARGET_ARCHS = RTEMS-beatnik
42
43ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=rtems_bsdnet_do_bootp
44ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000
45
2546
=== modified file 'configure/CONFIG_COMMON'
--- configure/CONFIG_COMMON 2017-02-01 17:57:04 +0000
+++ configure/CONFIG_COMMON 2017-05-01 18:36:52 +0000
@@ -4,7 +4,7 @@
4# Copyright (c) 2002 The Regents of the University of California, as4# Copyright (c) 2002 The Regents of the University of California, as
5# Operator of Los Alamos National Laboratory.5# Operator of Los Alamos National Laboratory.
6# EPICS BASE is distributed subject to a Software License Agreement found6# EPICS BASE is distributed subject to a Software License Agreement found
7# in file LICENSE that is included with this distribution. 7# in file LICENSE that is included with this distribution.
8#*************************************************************************8#*************************************************************************
9#9#
10# CONFIG_COMMON10# CONFIG_COMMON
@@ -136,10 +136,11 @@
136#--------------------------------------------------136#--------------------------------------------------
137# vpath directories137# vpath directories
138POSIX_YES = os/posix138POSIX_YES = os/posix
139OS_IMPL_DIRS = $(if $(OS_API),os/$(OS_CLASS)-$(OS_API),) os/$(OS_CLASS)
139GENERIC_SRC_DIRS = .. $(SRC_DIRS)140GENERIC_SRC_DIRS = .. $(SRC_DIRS)
140OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \141OS_SRC_DIRS += . $(foreach dir, $(GENERIC_SRC_DIRS), \
141 $(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default ))142 $(addprefix $(dir)/, $(OS_IMPL_DIRS) $(POSIX_$(POSIX)) os/default ))
142CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \143CMPLR_SRC_DIRS += . $(foreach dir, $(GENERIC_SRC_DIRS), \
143 $(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default ))144 $(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default ))
144ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)145ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)
145146
@@ -261,7 +262,7 @@
261LIBRARY_SRC_CFLAGS=$($(patsubst $*,SHRLIB,$(findstring $*,$(LIBRARY_SRCS)))_CFLAGS)262LIBRARY_SRC_CFLAGS=$($(patsubst $*,SHRLIB,$(findstring $*,$(LIBRARY_SRCS)))_CFLAGS)
262263
263#--------------------------------------------------264#--------------------------------------------------
264# prefix, suffix, and ldflags for loadable shared libraries 265# prefix, suffix, and ldflags for loadable shared libraries
265TARGET_LIB_LDFLAGS=$($(patsubst $*,LOADABLE_,$(findstring $*,$(LOADABLE_LIBRARY)))SHRLIB_LDFLAGS)266TARGET_LIB_LDFLAGS=$($(patsubst $*,LOADABLE_,$(findstring $*,$(LOADABLE_LIBRARY)))SHRLIB_LDFLAGS)
266LOADABLE_SHRLIB_PREFIX=$(SHRLIB_PREFIX)267LOADABLE_SHRLIB_PREFIX=$(SHRLIB_PREFIX)
267LOADABLE_SHRLIB_SUFFIX=$(SHRLIB_SUFFIX)268LOADABLE_SHRLIB_SUFFIX=$(SHRLIB_SUFFIX)
@@ -459,5 +460,5 @@
459SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) )460SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) )
460SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) )461SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) )
461SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) )462SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) )
462 463
463endif464endif
464465
=== modified file 'configure/os/CONFIG.Common.RTEMS'
--- configure/os/CONFIG.Common.RTEMS 2016-05-22 12:38:18 +0000
+++ configure/os/CONFIG.Common.RTEMS 2017-05-01 18:36:52 +0000
@@ -91,14 +91,27 @@
91OS_CLASS = RTEMS91OS_CLASS = RTEMS
9292
93#--------------------------------------------------93#--------------------------------------------------
94# operating system API (src/os/<os_class>-<os_api>)
95OS_API_4.7 = kernel
96OS_API_4.8 = kernel
97OS_API_4.9 = kernel
98OS_API_4.10 = kernel
99OS_API_4.11 = $(error RTEMS-4.11 is not currently supported)
100# Later RTEMS versions will use posix, no need to specify
101OS_API = $(firstword $(OS_API_$(RTEMS_SERIES)) posix)
102
103#--------------------------------------------------
94# Operating system flags104# Operating system flags
95OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm105OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm
96OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \106
107OP_SYS_LDFLAGS_posix += -u POSIX_Init
108OP_SYS_LDFLAGS_kernel += -u Init \
97 $(PROJECT_RELEASE)/lib/no-dpmem.rel \109 $(PROJECT_RELEASE)/lib/no-dpmem.rel \
98 $(PROJECT_RELEASE)/lib/no-mp.rel \110 $(PROJECT_RELEASE)/lib/no-mp.rel \
99 $(PROJECT_RELEASE)/lib/no-part.rel \111 $(PROJECT_RELEASE)/lib/no-part.rel \
100 $(PROJECT_RELEASE)/lib/no-signal.rel \112 $(PROJECT_RELEASE)/lib/no-signal.rel \
101 $(PROJECT_RELEASE)/lib/no-rtmon.rel113 $(PROJECT_RELEASE)/lib/no-rtmon.rel
114OP_SYS_LDFLAGS += $(CPU_CFLAGS) $(OP_SYS_LDFLAGS_$(OS_API))
102115
103MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib116MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib
104117
105118
=== modified file 'configure/os/CONFIG.Common.RTEMS-beatnik'
--- configure/os/CONFIG.Common.RTEMS-beatnik 2016-05-21 02:27:03 +0000
+++ configure/os/CONFIG.Common.RTEMS-beatnik 2017-05-01 18:36:52 +0000
@@ -1,19 +1,20 @@
1#
2# CONFIG.Common.RTEMS-beatnik1# CONFIG.Common.RTEMS-beatnik
2#
3# Author: Dayle Kotturi <dayle@slac.stanford.edu>3# Author: Dayle Kotturi <dayle@slac.stanford.edu>
4#4#
5# All RTEMS targets use the same Makefile fragment5# Site-specific adjustments to these settings belong
6# in the file CONFIG_SITE.Common.RTEMS-beatnik
6#7#
8
7EXE = .elf9EXE = .elf
8RTEMS_TARGET_CPU = powerpc10RTEMS_TARGET_CPU = powerpc
9GNU_TARGET = powerpc-rtems11GNU_TARGET = powerpc-rtems
10ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL12
13# Flags for *all* beatnik builds
11ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD14ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD
12ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=204815ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048
13ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=512016ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
1417
15OP_SYS_LDLIBS += -lbspExt
16
17MUNCH_SUFFIX = .boot18MUNCH_SUFFIX = .boot
18MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))19MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
19define MUNCH_CMD20define MUNCH_CMD
2021
=== modified file 'configure/os/CONFIG.Common.RTEMS-mvme3100'
--- configure/os/CONFIG.Common.RTEMS-mvme3100 2016-05-21 02:27:03 +0000
+++ configure/os/CONFIG.Common.RTEMS-mvme3100 2017-05-01 18:36:52 +0000
@@ -1,18 +1,20 @@
1#
2# CONFIG.Common.RTEMS-mvme31001# CONFIG.Common.RTEMS-mvme3100
2#
3# Author: W. Eric Norum <wenorum@lbl.gov>3# Author: W. Eric Norum <wenorum@lbl.gov>
4#4#
5# All RTEMS targets use the same Makefile fragment5# Site-specific adjustments to these settings belong
6# in the file CONFIG_SITE.Common.RTEMS-mvme3100
6#7#
7EXE = .elf8EXE = .elf
8RTEMS_TARGET_CPU = powerpc9RTEMS_TARGET_CPU = powerpc
9GNU_TARGET = powerpc-rtems10GNU_TARGET = powerpc-rtems
11
10ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL12ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
11ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD13ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD
12ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=204814ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048
13ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=512015ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
1416
15OP_SYS_LDLIBS += -lbspExt17# OP_SYS_LDLIBS += -lbspExt
1618
17MUNCH_SUFFIX = .boot19MUNCH_SUFFIX = .boot
18MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))20MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
1921
=== modified file 'configure/os/CONFIG_SITE.Common.RTEMS'
--- configure/os/CONFIG_SITE.Common.RTEMS 2016-05-21 02:27:03 +0000
+++ configure/os/CONFIG_SITE.Common.RTEMS 2017-05-01 18:36:52 +0000
@@ -3,11 +3,29 @@
3# Site-specific information for all RTEMS targets3# Site-specific information for all RTEMS targets
4#-------------------------------------------------------4#-------------------------------------------------------
55
6# RTEMS Series and Version
7
8#RTEMS_SERIES = 4.9
9#RTEMS_VERSION = 4.9.2
10
11RTEMS_SERIES = 4.10
12RTEMS_VERSION = 4.10.2
13
14#RTEMS_SERIES = 4.12
15#RTEMS_VERSION = 4.12
16
17
6# Where to find RTEMS18# Where to find RTEMS
7#19#
20#RTEMS_BASE = /your/path/to/rtems-$(RTEMS_VERSION)
21
8# APS:22# APS:
9RTEMS_VERSION = 4.10.2
10RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION)23RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION)
24#RTEMS_BASE = /local/anj/RTEMS/rtems-4.12
25
26# FHI:
27#RTEMS_BASE = /home/rtems/RTEMS/rtems-$(RTEMS_VERSION)
28
1129
12# Cross-compile toolchain in $(RTEMS_TOOLS)/bin30# Cross-compile toolchain in $(RTEMS_TOOLS)/bin
13#31#
@@ -24,7 +42,7 @@
24# network configuration you must uncomment and specify your Internet42# network configuration you must uncomment and specify your Internet
25# Domain Name here43# Domain Name here
26#44#
27#OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname>45OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname>
2846
29# Select the command-line-input library to use47# Select the command-line-input library to use
30#48#
3149
=== added file 'configure/os/CONFIG_SITE.Common.RTEMS-beatnik'
--- configure/os/CONFIG_SITE.Common.RTEMS-beatnik 1970-01-01 00:00:00 +0000
+++ configure/os/CONFIG_SITE.Common.RTEMS-beatnik 2017-05-01 18:36:52 +0000
@@ -0,0 +1,22 @@
1# CONFIG_SITE.Common.RTEMS-beatnik
2#
3# Site-specific overrides for RTEMS-beatnik target
4#
5
6# Any sites using the beatnik BSP on more than one kind of MVME
7# board may have difficulties with this release...
8
9# These settings are for MVME6100 boards:
10ARCH_DEP_CFLAGS += -DUSE_ALTIVEC
11
12ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=mve1
13#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1
14#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0
15
16ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=mve2
17#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2
18#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0
19
20# Uncomment this to link against libbspExt
21#OP_SYS_LDLIBS += -lbspExt
22
023
=== added file 'configure/os/CONFIG_SITE.Common.RTEMS-mvme3100'
--- configure/os/CONFIG_SITE.Common.RTEMS-mvme3100 1970-01-01 00:00:00 +0000
+++ configure/os/CONFIG_SITE.Common.RTEMS-mvme3100 2017-05-01 18:36:52 +0000
@@ -0,0 +1,19 @@
1# CONFIG_SITE.Common.RTEMS-mvme3100
2#
3# Site-specific overrides for RTEMS-mvme3100 target
4#
5
6# Any sites using the beatnik BSP on more than one kind of MVME
7# board may have difficulties with this release...
8
9#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=?
10#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1
11#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0
12
13#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=?
14#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2
15#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0
16
17# Uncomment this to link against libbspExt
18#OP_SYS_LDLIBS += -lbspExt
19
020
=== modified file 'configure/os/CONFIG_SITE.Common.RTEMS-pc386'
--- configure/os/CONFIG_SITE.Common.RTEMS-pc386 2002-08-20 16:18:05 +0000
+++ configure/os/CONFIG_SITE.Common.RTEMS-pc386 2017-05-01 18:36:52 +0000
@@ -1,3 +1,15 @@
1# CONFIG_SITE.Common.RTEMS-pc386
1#2#
2# Site-specific overrides for RTEMS-pc386 target3# Site-specific overrides for RTEMS-pc386 target
3#4#
5
6# These NICs support run-time probing:
7#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=fxp1
8#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_ATTACH_1=rtems_fxp_attach
9#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1
10#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0
11
12#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=ep0
13#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_ATTACH_2=rtems_3c509_driver_attach
14#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2
15#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0
416
=== modified file 'documentation/RELEASE_NOTES.html'
--- documentation/RELEASE_NOTES.html 2017-02-01 17:57:04 +0000
+++ documentation/RELEASE_NOTES.html 2017-05-01 18:36:52 +0000
@@ -21,6 +21,35 @@
2121
22-->22-->
2323
24<h3>Support for RTEMS 4.12</h3>
25
26<p>The next major release of the RTEMS real-time OS will be version 4.12 which
27contains many changes including the ability to support SMP systems. The earlier
28EPICS support for RTEMS made use of various RTEMS-specific kernel APIs which
29cannot be used on an SMP system, so the changes here required a completely new
30port to the Posix real-time APIs that RTEMS-4.12 now recommends. A new RTEMS
31configuration variable RTEMS_SERIES has been added which should be set to the
32first two components of the OS version number, e.g. 4.9. When this is 4.12 or
33greater the new libCom/osi/os/RTEMS-posix source files will be used; the older
34API source files can now be found in libCom/osi/os/RTEMS-kernel, and those which
35are common to both installations are in libCom/osi/os/RTEMS.</p>
36
37<p>Note that EPICS Base can only be built for a single RTEMS version at a time.
38 The RTEMS version number is set in the CONFIG_SITE.Common.RTEMS file and
39 cannot be different for specific targets. This allows different header files
40 to be used and installed for the two different APIs.</p>
41
42<h3>Support for multiple APIs in the same OS</h3>
43
44<p>The build configuration files for a particular build target may now select
45between multiple implementations with different OS APIs by setting the GNUmake
46variable <tt>OS_API</tt>. This changes the search path used for OS-specific
47source files, inserting a directory <tt>os/$(OS_CLASS)-$(OS_API)</tt> before
48the existing <tt>os/$(OS_CLASS)</tt> directory. Note though that the include
49file search path does not change, so OS-specific header files must be able to
50handle both APIs simultaneously, and their source files should go in the
51<tt>os/$(OS_CLASS)</tt> directory.</p>
52
24<h3>Echoless comments in iocsh</h3>53<h3>Echoless comments in iocsh</h3>
2554
26<p>The way comments are parsed by the iocsh interpreter has changed. The55<p>The way comments are parsed by the iocsh interpreter has changed. The
2756
=== modified file 'src/ioc/rsrv/caservertask.c'
--- src/ioc/rsrv/caservertask.c 2016-08-30 14:36:51 +0000
+++ src/ioc/rsrv/caservertask.c 2017-05-01 18:36:52 +0000
@@ -308,13 +308,17 @@
308 }308 }
309#ifdef IP_ADD_MEMBERSHIP309#ifdef IP_ADD_MEMBERSHIP
310 {310 {
311#if defined(__rtems__)
312 char flag = 1;
313#else
311 int flag = 1;314 int flag = 1;
315#endif
312 if (setsockopt(beaconSocket, IPPROTO_IP, IP_MULTICAST_LOOP,316 if (setsockopt(beaconSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
313 (char *)&flag, sizeof(flag))<0) {317 (char *)&flag, sizeof(flag))<0) {
314 char sockErrBuf[64];318 char sockErrBuf[64];
315 epicsSocketConvertErrnoToString (319 epicsSocketConvertErrnoToString (
316 sockErrBuf, sizeof ( sockErrBuf ) );320 sockErrBuf, sizeof ( sockErrBuf ) );
317 errlogPrintf("rsrv: failed to set mcast loopback\n");321 errlogPrintf("rsrv: failed to set mcast loopback (%d:%s)\n", errno, sockErrBuf);
318 }322 }
319 }323 }
320#endif324#endif
321325
=== modified file 'src/libCom/RTEMS/Makefile'
--- src/libCom/RTEMS/Makefile 2011-11-14 23:42:50 +0000
+++ src/libCom/RTEMS/Makefile 2017-05-01 18:36:52 +0000
@@ -9,6 +9,8 @@
9TOP=../../..9TOP=../../..
10include $(TOP)/configure/CONFIG10include $(TOP)/configure/CONFIG
1111
12SRC_DIRS += ../$(OS_API)
13
12INC += epicsRtemsInitHooks.h14INC += epicsRtemsInitHooks.h
1315
14rtemsCom_SRCS += rtems_init.c16rtemsCom_SRCS += rtems_init.c
1517
=== added directory 'src/libCom/RTEMS/kernel'
=== renamed file 'src/libCom/RTEMS/rtems_config.c' => 'src/libCom/RTEMS/kernel/rtems_config.c'
--- src/libCom/RTEMS/rtems_config.c 2016-05-22 12:38:18 +0000
+++ src/libCom/RTEMS/kernel/rtems_config.c 2017-05-01 18:36:52 +0000
@@ -1,17 +1,17 @@
1/*************************************************************************\1/*************************************************************************\
2* Copyright (c) 2002 The University of Saskatchewan2* Copyright (c) 2002 The University of Saskatchewan
3* EPICS BASE Versions 3.13.73* EPICS BASE is distributed subject to a Software License Agreement found
4* and higher are distributed subject to a Software License Agreement found4* in file LICENSE that is included with this distribution.
5* in file LICENSE that is included with this distribution.
6\*************************************************************************/5\*************************************************************************/
7/*6/*
8 * RTEMS configuration for EPICS7 * RTEMS configuration for EPICS
9 * Author: W. Eric Norum8 * Author: W. Eric Norum
10 * norume@aps.anl.gov
11 * (630) 252-4793
12 */9 */
1310
14#include <rtems.h>11#include <rtems.h>
12#include <epicsVersion.h>
13#define RTEMS_VERSION_INT \
14 VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, __RTEMS_REVISION__, 0)
1515
16/*16/*
17 ***********************************************************************17 ***********************************************************************
@@ -20,7 +20,7 @@
20 */20 */
21#define CONFIGURE_RTEMS_INIT_TASKS_TABLE21#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
2222
23#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)23#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0)
24# define CONFIGURE_UNIFIED_WORK_AREAS24# define CONFIGURE_UNIFIED_WORK_AREAS
25#else25#else
26# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024)26# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024)
2727
=== renamed file 'src/libCom/RTEMS/rtems_netconfig.c' => 'src/libCom/RTEMS/kernel/rtems_netconfig.c'
--- src/libCom/RTEMS/rtems_netconfig.c 2016-05-22 12:38:18 +0000
+++ src/libCom/RTEMS/kernel/rtems_netconfig.c 2017-05-01 18:36:52 +0000
@@ -19,55 +19,70 @@
19extern void rtems_bsdnet_loopattach();19extern void rtems_bsdnet_loopattach();
20static struct rtems_bsdnet_ifconfig loopback_config = {20static struct rtems_bsdnet_ifconfig loopback_config = {
21 "lo0", /* name */21 "lo0", /* name */
22 (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach, /* attach function */22 (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach,
23 NULL, /* link to next interface */23 NULL, /* last interface */
24 "127.0.0.1", /* IP address */24 "127.0.0.1", /* IP address */
25 "255.0.0.0", /* IP net mask */25 "255.0.0.0", /* IP net mask */
26};26};
2727
28#define stringOf(x) #x
29#define STRING(x) stringOf(x)
30
28/*31/*
29 * The following conditionals select the network interface card.32 * The following configures up to 2 network interface card(s) using
30 *33 * settings in either configure/os/CONFIG_SITE.Common.RTEMS or in a
31 * On RTEMS-pc386 targets all network drivers which support run-time34 * BSP-specific configure/os/CONFIG_SITE.Common.RTEMS-<bsp> file.
32 * probing are linked. 35 * If no settings are provided, it uses the BSP's defaults instead.
33 * On other targets the network interface specified by the board-support
34 * package is used.
35 * To use a different NIC for a particular application, copy this file to the
36 * application directory and make the appropriate changes.
37 */36 */
38#if defined(__i386__)37
39extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);38#if defined(RTEMS_NETWORK_DRIVER_NAME_1)
40static struct rtems_bsdnet_ifconfig fxp_driver_config = {39
41 "fxp1", /* name */40 #if defined(RTEMS_NETWORK_DRIVER_NAME_2)
42 rtems_fxp_attach, /* attach function */41 static struct rtems_bsdnet_ifconfig netdriver_config_2 = {
43 &loopback_config, /* link to next interface */42 STRING(RTEMS_NETWORK_DRIVER_NAME_2),
44};43 #if defined(RTEMS_NETWORK_DRIVER_ATTACH_2)
45extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);44 RTEMS_NETWORK_DRIVER_ATTACH_2, /* specific attach function */
46static struct rtems_bsdnet_ifconfig e3c509_driver_config = {45 #else
47 "ep0", /* name */46 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */
48 rtems_3c509_driver_attach, /* attach function */47 #endif
49 &fxp_driver_config, /* link to next interface */48 &loopback_config, /* loopback interface */
50};49 #if defined(RTEMS_NETWORK_IP4_ADDR_2)
51#define FIRST_DRIVER_CONFIG &e3c509_driver_config50 STRING(RTEMS_NETWORK_IP4_ADDR_2),
52#else51 #if defined(RTEMS_NETWORK_IP4_MASK_2)
5352 STRING(RTEMS_NETWORK_IP4_MASK_2),
54# if defined(__PPC)53 #endif
55 /*54 #endif
56 * FIXME: This really belongs in the BSP55 };
57 */56 #endif /* RTEMS_NETWORK_DRIVER_NAME_2 */
58# ifndef RTEMS_BSP_NETWORK_DRIVER_NAME57
59# define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1"58 static struct rtems_bsdnet_ifconfig netdriver_config = {
60# endif59 STRING(RTEMS_NETWORK_DRIVER_NAME_1),
61# ifndef RTEMS_BSP_NETWORK_DRIVER_ATTACH60 #if defined(RTEMS_NETWORK_DRIVER_ATTACH_1)
62# define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach61 RTEMS_NETWORK_DRIVER_ATTACH_1, /* specific attach function */
63 extern int rtems_dec21140_driver_attach();62 #else
64# endif63 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */
65# endif64 #endif
6665 #if defined(RTEMS_NETWORK_DRIVER_NAME_2)
66 &netdriver_config_2, /* link to next interface */
67 #else
68 &loopback_config, /* loopback interface */
69 #endif
70 #if defined(RTEMS_NETWORK_IP4_ADDR_1)
71 STRING(RTEMS_NETWORK_IP4_ADDR_1),
72 #if defined(RTEMS_NETWORK_IP4_MASK_1)
73 STRING(RTEMS_NETWORK_IP4_MASK_1),
74 #endif
75 #endif
76 };
77 #define FIRST_DRIVER_CONFIG &netdriver_config
78
79#else /* RTEMS_NETWORK_DRIVER_NAME_1 */
80
81/* Use the BSP-provided standard macros */
67static struct rtems_bsdnet_ifconfig bsp_driver_config = {82static struct rtems_bsdnet_ifconfig bsp_driver_config = {
68 RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */83 RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
69 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */84 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
70 &loopback_config, /* link to next interface */85 &loopback_config, /* loopback interface */
71};86};
72#define FIRST_DRIVER_CONFIG &bsp_driver_config87#define FIRST_DRIVER_CONFIG &bsp_driver_config
7388
@@ -77,9 +92,7 @@
77 * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name92 * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name
78 */93 */
79#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME94#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME
80# define XSTR(x) STR(x)95# define MY_DOMAINNAME STRING(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME)
81# define STR(x) #x
82# define MY_DOMAINNAME XSTR(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME)
83#else96#else
84# define MY_DOMAINNAME NULL97# define MY_DOMAINNAME NULL
85#endif98#endif
8699
=== added directory 'src/libCom/RTEMS/posix'
=== added file 'src/libCom/RTEMS/posix/rtems_config.c'
--- src/libCom/RTEMS/posix/rtems_config.c 1970-01-01 00:00:00 +0000
+++ src/libCom/RTEMS/posix/rtems_config.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,88 @@
1/*************************************************************************\
2* Copyright (c) 2002 The University of Saskatchewan
3* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschafto* EPICS
4* BASE is distributed subject to a Software License Agreement found
5* * in file LICENSE that is included with this distribution.
6\*************************************************************************/
7/*
8 * RTEMS configuration for EPICS
9 * Author: W. Eric Norum
10 * Heinz Junkes
11 *
12 * Version for RTEMS-4.12
13 */
14
15#include <rtems.h>
16
17/*
18 ***********************************************************************
19 * RTEMS CONFIGURATION *
20 ***********************************************************************
21 */
22
23extern void *EPICS_WITH_POSIX_Init(void *argument);
24
25#define CONFIGURE_POSIX_INIT_THREAD_TABLE
26#define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT EPICS_WITH_POSIX_Init
27/*
28 * nfs is using rtems tasks
29 */
30#define CONFIGURE_MAXIMUM_TASKS 5
31#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
32#define CONFIGURE_MAXIMUM_SEMAPHORES 5
33#define CONFIGURE_MAXIMUM_EVENTS 5
34
35#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 300
36#define CONFIGURE_MAXIMUM_POSIX_THREADS 200
37#define CONFIGURE_MAXIMUM_POSIX_KEYS 200
38#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 200
39#define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS 100
40#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 300
41#define CONFIGURE_MAXIMUM_POSIX_TIMERS 100
42#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 100
43#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 300
44
45#define CONFIGURE_UNIFIED_WORK_AREAS
46
47#define CONFIGURE_MAXIMUM_PERIODS 5
48#define CONFIGURE_MICROSECONDS_PER_TICK 10000
49#define CONFIGURE_MALLOC_STATISTICS 1
50/* MINIMUM_STACK_SIZE == 8K */
51#define CONFIGURE_EXTRA_TASK_STACKS (1000 * RTEMS_MINIMUM_STACK_SIZE)
52
53#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
54#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
55
56#define CONFIGURE_FILESYSTEM_DEVFS
57#define CONFIGURE_FILESYSTEM_TFTPFS
58#define CONFIGURE_FILESYSTEM_NFS
59#define CONFIGURE_FILESYSTEM_IMFS
60#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
61#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150
62
63#define CONFIGURE_MAXIMUM_NFS_MOUNTS 3
64#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 5
65
66#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (64*1024)
67
68#define CONFIGURE_MAXIMUM_DRIVERS 8
69
70//#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension }
71
72#define CONFIGURE_INIT
73
74
75/*
76 * This should be made BSP dependent, not CPU dependent but I know of no
77 * appropriate conditionals to use.
78 * The new general time support makes including the RTC driverr less important.
79 */
80#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && \
81 !defined(mpc7455) && !defined(__arm__) && !defined(__nios2__)
82 /* don't have RTC code */
83#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
84#endif
85
86
87#include <bsp.h>
88#include <rtems/confdefs.h>
089
=== added file 'src/libCom/RTEMS/posix/rtems_netconfig.c'
--- src/libCom/RTEMS/posix/rtems_netconfig.c 1970-01-01 00:00:00 +0000
+++ src/libCom/RTEMS/posix/rtems_netconfig.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,126 @@
1/*************************************************************************\
2* Copyright (c) 2002 The University of Saskatchewan
3* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
4* EPICS BASE is distributed subject to a Software License Agreement found
5* in file LICENSE that is included with this distribution.
6\*************************************************************************/
7/*
8 * RTEMS network configuration for EPICS
9 * Author: W. Eric Norum
10 * Heinz Junkes
11 *
12 * Version for RTEMS-4.12
13 *
14 * This file can be copied to an application source dirctory
15 * and modified to override the values shown below.
16 */
17#include <stdio.h>
18#include <bsp.h>
19#include <rtems/rtems_bsdnet.h>
20
21#define stringOf(x) #x
22#define STRING(x) stringOf(x)
23
24/*
25 * The following configures up to 2 network interface card(s) using
26 * settings in either configure/os/CONFIG_SITE.Common.RTEMS or in a
27 * BSP-specific configure/os/CONFIG_SITE.Common.RTEMS-<bsp> file.
28 * If no settings are provided, it uses the BSP's defaults instead.
29 */
30
31#if defined(RTEMS_NETWORK_DRIVER_NAME_1)
32
33 #if defined(RTEMS_NETWORK_DRIVER_NAME_2)
34 static struct rtems_bsdnet_ifconfig netdriver_config_2 = {
35 STRING(RTEMS_NETWORK_DRIVER_NAME_2),
36 #if defined(RTEMS_NETWORK_DRIVER_ATTACH_2)
37 RTEMS_NETWORK_DRIVER_ATTACH_2, /* specific attach function */
38 #else
39 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */
40 #endif
41 NULL, /* last interface */
42 #if defined(RTEMS_NETWORK_IP4_ADDR_2)
43 STRING(RTEMS_NETWORK_IP4_ADDR_2),
44 #if defined(RTEMS_NETWORK_IP4_MASK_2)
45 STRING(RTEMS_NETWORK_IP4_MASK_2),
46 #endif
47 #endif
48 };
49 #endif /* RTEMS_NETWORK_DRIVER_NAME_2 */
50
51 static struct rtems_bsdnet_ifconfig netdriver_config = {
52 STRING(RTEMS_NETWORK_DRIVER_NAME_1),
53 #if defined(RTEMS_NETWORK_DRIVER_ATTACH_1)
54 RTEMS_NETWORK_DRIVER_ATTACH_1, /* specific attach function */
55 #else
56 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */
57 #endif
58 #if defined(RTEMS_NETWORK_DRIVER_NAME_2)
59 &netdriver_config_2, /* link to next interface */
60 #else
61 NULL, /* last interface */
62 #endif
63 #if defined(RTEMS_NETWORK_IP4_ADDR_1)
64 STRING(RTEMS_NETWORK_IP4_ADDR_1),
65 #if defined(RTEMS_NETWORK_IP4_MASK_1)
66 STRING(RTEMS_NETWORK_IP4_MASK_1),
67 #endif
68 #endif
69 };
70 #define FIRST_DRIVER_CONFIG &netdriver_config
71
72#else /* RTEMS_NETWORK_DRIVER_NAME_1 */
73
74/* Use the BSP-provided standard macros */
75static struct rtems_bsdnet_ifconfig bsp_driver_config = {
76 RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
77 RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
78 NULL, /* last interface */
79};
80#define FIRST_DRIVER_CONFIG &bsp_driver_config
81
82#endif
83
84/*
85 * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name
86 */
87#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME
88# define MY_DOMAINNAME STRING(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME)
89#else
90# define MY_DOMAINNAME NULL
91#endif
92
93/*
94 * Allow non-BOOTP network configuration
95 */
96#ifndef MY_DO_BOOTP
97# define MY_DO_BOOTP rtems_bsdnet_do_bootp
98#endif
99
100/*
101 * Allow site- and BSP-specific network buffer space configuration.
102 * The macro values are specified in KBytes.
103 */
104#ifndef RTEMS_NETWORK_CONFIG_MBUF_SPACE
105# define RTEMS_NETWORK_CONFIG_MBUF_SPACE 180
106#endif
107#ifndef RTEMS_NETWORK_CONFIG_CLUSTER_SPACE
108# define RTEMS_NETWORK_CONFIG_CLUSTER_SPACE 350
109#endif
110
111/*
112 * Network configuration
113 */
114struct rtems_bsdnet_config rtems_bsdnet_config = {
115 FIRST_DRIVER_CONFIG, /* Link to next interface */
116 MY_DO_BOOTP, /* How to find network config */
117 10, /* If 0 then the network daemons will run at a */
118 /* priority just less than the lowest-priority */
119 /* EPICS scan thread. */
120 /* If non-zero then the network daemons will run */
121 /* at this *RTEMS* priority */
122 RTEMS_NETWORK_CONFIG_MBUF_SPACE*1024,
123 RTEMS_NETWORK_CONFIG_CLUSTER_SPACE*1024,
124 NULL, /* Host name */
125 MY_DOMAINNAME, /* Domain name */
126};
0127
=== modified file 'src/libCom/RTEMS/rtems_init.c'
--- src/libCom/RTEMS/rtems_init.c 2017-02-01 17:57:04 +0000
+++ src/libCom/RTEMS/rtems_init.c 2017-05-01 18:36:52 +0000
@@ -25,12 +25,19 @@
25#include <netinet/in.h>25#include <netinet/in.h>
26#include <arpa/inet.h>26#include <arpa/inet.h>
27#include <rtems.h>27#include <rtems.h>
28#include <epicsVersion.h>
29#define RTEMS_VERSION_INT \
30 VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, __RTEMS_REVISION__, 0)
28#include <rtems/malloc.h>31#include <rtems/malloc.h>
29#include <rtems/error.h>32#include <rtems/error.h>
30#include <rtems/stackchk.h>33#include <rtems/stackchk.h>
31#include <rtems/rtems_bsdnet.h>34#include <rtems/rtems_bsdnet.h>
32#include <rtems/imfs.h>35#include <rtems/imfs.h>
33#include <librtemsNfs.h>36#include <librtemsNfs.h>
37#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
38#include <rtems/libio.h>
39#include <sys/stat.h>
40#endif
34#include <bsp.h>41#include <bsp.h>
3542
36#include "epicsThread.h"43#include "epicsThread.h"
@@ -44,6 +51,13 @@
44#include "osdTime.h"51#include "osdTime.h"
4552
46#include "epicsRtemsInitHooks.h"53#include "epicsRtemsInitHooks.h"
54#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
55#include <rtems/malloc.h>
56#include <rtems/score/heap.h>
57#include <pthread.h>
58#include <assert.h>
59#define rtems_test_assert(_a) assert(_a)
60#endif
4761
48/*62/*
49 * Prototypes for some functions not in header files63 * Prototypes for some functions not in header files
@@ -52,6 +66,49 @@
52int fileno(FILE *);66int fileno(FILE *);
53int main(int argc, char **argv);67int main(int argc, char **argv);
5468
69//Helper function must be made useful
70#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
71
72static int get_current_prio( pthread_t thread )
73{
74rtems_status_code sc;
75rtems_task_priority prio;
76int max;
77
78sc = rtems_task_set_priority( thread, RTEMS_CURRENT_PRIORITY, &prio );
79rtems_test_assert( sc == RTEMS_SUCCESSFUL );
80
81max = sched_get_priority_max( SCHED_FIFO );
82
83return max + 1 - (int) prio;
84}
85
86//We are using posix map osi 0-100 to posix 100-200
87int epicsThreadGetOsiPriorityValue(int ossPriority)
88{
89 if (ossPriority > 200) {
90 return epicsThreadPriorityMax;
91 }
92 else if (ossPriority < 100) {
93 return epicsThreadPriorityMin;
94 }
95 else {
96 return ((unsigned int)ossPriority - 100u);
97 }
98}
99int epicsThreadGetOssPriorityValue(unsigned int osiPriority)
100{
101 if (osiPriority > 99) {
102 return 200;
103 }
104 else {
105 return ((signed int)osiPriority + 100u);
106 }
107}
108#else
109/* see osdThread.c */
110#endif
111
55static void112static void
56logReset (void)113logReset (void)
57{114{
@@ -61,10 +118,12 @@
61 if (fp) {118 if (fp) {
62 char buf[80];119 char buf[80];
63 fp(buf, sizeof buf);120 fp(buf, sizeof buf);
64 errlogPrintf ("Startup after %s.\n", buf);121 //errlogPrintf ("Startup after %s.\n", buf);
122 printk ("Startup after %s.\n", buf);
65 }123 }
66 else {124 else {
67 errlogPrintf ("Startup.\n");125 //errlogPrintf ("Startup.\n");
126 printk ("Startup.\n");
68 }127 }
69}128}
70129
@@ -79,9 +138,12 @@
79static void138static void
80delayedPanic (const char *msg)139delayedPanic (const char *msg)
81{140{
141#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
142 rtems_task_wake_after (rtems_clock_get_ticks_per_second());
143#else
82 extern rtems_interval rtemsTicksPerSecond;144 extern rtems_interval rtemsTicksPerSecond;
83
84 rtems_task_wake_after (rtemsTicksPerSecond);145 rtems_task_wake_after (rtemsTicksPerSecond);
146#endif
85 rtems_panic (msg);147 rtems_panic (msg);
86}148}
87149
@@ -171,9 +233,7 @@
171}233}
172234
173#ifndef OMIT_NFS_SUPPORT235#ifndef OMIT_NFS_SUPPORT
174#if __RTEMS_MAJOR__>4 || \236#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0)
175 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \
176 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
177int237int
178nfsMount(char *uidhost, char *path, char *mntpoint)238nfsMount(char *uidhost, char *path, char *mntpoint)
179{239{
@@ -187,6 +247,13 @@
187 }247 }
188 sprintf(dev, "%s:%s", uidhost, path);248 sprintf(dev, "%s:%s", uidhost, path);
189 printf("Mount %s on %s\n", dev, mntpoint);249 printf("Mount %s on %s\n", dev, mntpoint);
250#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
251 rval = mount_and_make_target_path (
252 dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS,
253 RTEMS_FILESYSTEM_READ_WRITE, NULL );
254 if(rval)
255 perror("mount failed");
256#else
190 if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO))257 if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO))
191 printf("Warning -- unable to make directory \"%s\"\n", mntpoint);258 printf("Warning -- unable to make directory \"%s\"\n", mntpoint);
192 if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS,259 if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS,
@@ -196,6 +263,7 @@
196 else {263 else {
197 rval = 0;264 rval = 0;
198 }265 }
266#endif
199 free(dev);267 free(dev);
200 return rval;268 return rval;
201}269}
@@ -210,9 +278,7 @@
210{278{
211#ifdef OMIT_NFS_SUPPORT279#ifdef OMIT_NFS_SUPPORT
212 printf ("***** Initializing TFTP *****\n");280 printf ("***** Initializing TFTP *****\n");
213#if __RTEMS_MAJOR__>4 || \281#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0)
214 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \
215 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
216 mount_and_make_target_path(NULL,282 mount_and_make_target_path(NULL,
217 "/TFTP",283 "/TFTP",
218 RTEMS_FILESYSTEM_TYPE_TFTPFS,284 RTEMS_FILESYSTEM_TYPE_TFTPFS,
@@ -246,6 +312,7 @@
246 printf ("***** Initializing NFS *****\n");312 printf ("***** Initializing NFS *****\n");
247 NFS_INIT313 NFS_INIT
248 if (env_nfsServer && env_nfsPath && env_nfsMountPoint) {314 if (env_nfsServer && env_nfsPath && env_nfsMountPoint) {
315 printf(" bin in environment kram ...\n");
249 server_name = env_nfsServer;316 server_name = env_nfsServer;
250 server_path = env_nfsPath;317 server_path = env_nfsPath;
251 mount_point = env_nfsMountPoint;318 mount_point = env_nfsMountPoint;
@@ -309,10 +376,11 @@
309 "%[^:] : / %s",376 "%[^:] : / %s",
310 pServerName,377 pServerName,
311 pServerPath + 1u );378 pServerPath + 1u );
379
312 if ( scanfStatus == 2 ) {380 if ( scanfStatus == 2 ) {
313 pServerPath[0u]= '/';381 pServerPath[0u]= '/';
314 server_name = pServerName;382 server_name = pServerName;
315 server_path = pServerPath;383 server_path = mount_point = pServerPath;
316 }384 }
317 else {385 else {
318 free ( pServerName );386 free ( pServerName );
@@ -332,8 +400,6 @@
332 argv[1] = abspath;400 argv[1] = abspath;
333 }401 }
334 }402 }
335 errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n",
336 server_name, server_path, mount_point);
337 nfsMount(server_name, server_path, mount_point);403 nfsMount(server_name, server_path, mount_point);
338#endif404#endif
339}405}
@@ -357,7 +423,6 @@
357 perror("error: fixup_hosts stat /etc/hosts");423 perror("error: fixup_hosts stat /etc/hosts");
358 return;424 return;
359 }425 }
360
361 ret = mkdir("/etc", 0775);426 ret = mkdir("/etc", 0775);
362 if(ret!=0 && errno!=EEXIST)427 if(ret!=0 && errno!=EEXIST)
363 {428 {
@@ -374,7 +439,6 @@
374 {439 {
375 perror("error: failed to write /etc/hosts");440 perror("error: failed to write /etc/hosts");
376 }441 }
377
378 fclose(fp);442 fclose(fp);
379}443}
380444
@@ -444,11 +508,19 @@
444static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL};508static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL};
445static void heapSpaceCallFunc(const iocshArgBuf *args)509static void heapSpaceCallFunc(const iocshArgBuf *args)
446{510{
511#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
512 Heap_Information_block info;
513 double x;
514
515 malloc_info (&info);
516 x = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed);
517#else
447 rtems_malloc_statistics_t s;518 rtems_malloc_statistics_t s;
448 double x;519 double x;
449520
450 malloc_get_statistics(&s);521 malloc_get_statistics(&s);
451 x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed);522 x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed);
523#endif
452 if (x >= 1024*1024)524 if (x >= 1024*1024)
453 printf("Heap space: %.1f MB\n", x / (1024 * 1024));525 printf("Heap space: %.1f MB\n", x / (1024 * 1024));
454 else526 else
@@ -513,13 +585,14 @@
513 * Ensure that the configuration object files585 * Ensure that the configuration object files
514 * get pulled in from the library586 * get pulled in from the library
515 */587 */
516extern rtems_configuration_table Configuration;588#if RTEMS_VERSION_INT < VERSION_INT(4, 11, 99, 0)
589extern rtems_configuration_table Configuration;
517extern struct rtems_bsdnet_config rtems_bsdnet_config;590extern struct rtems_bsdnet_config rtems_bsdnet_config;
518const void *rtemsConfigArray[] = {591const void *rtemsConfigArray[] = {
519 &Configuration,592 &Configuration,
520 &rtems_bsdnet_config593 &rtems_bsdnet_config
521};594};
522595#endif
523/*596/*
524 * Hook to ensure that BSP cleanup code gets run on exit597 * Hook to ensure that BSP cleanup code gets run on exit
525 */598 */
@@ -532,13 +605,21 @@
532/*605/*
533 * RTEMS Startup task606 * RTEMS Startup task
534 */607 */
608#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
609void *
610EPICS_WITH_POSIX_Init (void *argument)
611#else
535rtems_task612rtems_task
536Init (rtems_task_argument ignored)613Init (rtems_task_argument ignored)
614#endif
537{615{
616<<<<<<< TREE
538 int result;617 int result;
618=======
619 int i;
620>>>>>>> MERGE-SOURCE
539 char *argv[3] = { NULL, NULL, NULL };621 char *argv[3] = { NULL, NULL, NULL };
540 char *cp;622 char *cp;
541 rtems_task_priority newpri;
542 rtems_status_code sc;623 rtems_status_code sc;
543 rtems_time_of_day now;624 rtems_time_of_day now;
544625
@@ -562,10 +643,20 @@
562 /*643 /*
563 * Override RTEMS configuration644 * Override RTEMS configuration
564 */645 */
565 rtems_task_set_priority (646#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
566 RTEMS_SELF,647 int policy;
567 epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh),648 struct sched_param param;
568 &newpri);649
650 if (pthread_getschedparam(pthread_self(), &policy, &param) != 0)
651 delayedPanic("pthread_getschedparam failed");
652 param.sched_priority = epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh);
653 if (pthread_setschedparam(pthread_self(), policy, &param) != 0)
654 delayedPanic("pthread_setschedparam failed");
655#else
656 rtems_task_priority newpri;
657 rtems_task_set_priority (RTEMS_SELF,
658 epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), &newpri);
659#endif
569660
570 /*661 /*
571 * Create a reasonable environment662 * Create a reasonable environment
@@ -580,6 +671,7 @@
580 printf("\n***** RTEMS Version: %s *****\n",671 printf("\n***** RTEMS Version: %s *****\n",
581 rtems_get_version_string());672 rtems_get_version_string());
582673
674 printf("\n***** RTEMS min stack size : %d\n", RTEMS_MINIMUM_STACK_SIZE);
583 /*675 /*
584 * Start network676 * Start network
585 */677 */
@@ -616,12 +708,16 @@
616 * It is very likely that other time synchronization facilities in EPICS708 * It is very likely that other time synchronization facilities in EPICS
617 * will soon override this value.709 * will soon override this value.
618 */710 */
711#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
712 if (rtems_clock_get_tod(&now) != RTEMS_SUCCESSFUL) {
713#else
619 if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) {714 if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) {
620 now.year = 2001;715#endif
621 now.month = 1;716 now.year = 2012;
622 now.day = 1;717 now.month = 4;
623 now.hour = 0;718 now.day = 14;
624 now.minute = 0;719 now.hour = 7;
720 now.minute = 23;
625 now.second = 0;721 now.second = 0;
626 now.ticks = 0;722 now.ticks = 0;
627 if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL)723 if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL)
@@ -649,7 +745,23 @@
649 }745 }
650 }746 }
651 tzset();747 tzset();
748#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
749 // osdTimeRegister() was called during C++ initialization
750#else
652 osdTimeRegister();751 osdTimeRegister();
752#endif
753
754 /*
755 * Some network diagnotics
756 */
757
758 // rtems_bsdnet_show_mbuf_stats (void);
759 rtems_bsdnet_show_if_stats ();
760 rtems_bsdnet_show_ip_stats ();
761 rtems_bsdnet_show_icmp_stats ();
762 rtems_bsdnet_show_inet_routes ();
763 //rtems_bsdnet_show_udp_stats (void);
764 //rtems_bsdnet_show_tcp_stats (void);
653765
654 /*766 /*
655 * Run the EPICS startup script767 * Run the EPICS startup script
@@ -664,5 +776,12 @@
664 result = main ((sizeof argv / sizeof argv[0]) - 1, argv);776 result = main ((sizeof argv / sizeof argv[0]) - 1, argv);
665 printf ("***** IOC application terminating *****\n");777 printf ("***** IOC application terminating *****\n");
666 epicsThreadSleep(1.0);778 epicsThreadSleep(1.0);
779<<<<<<< TREE
667 epicsExit(result);780 epicsExit(result);
781=======
782 epicsExit(0);
783#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0)
784 return NULL;
785#endif
786>>>>>>> MERGE-SOURCE
668}787}
669788
=== modified file 'src/libCom/calc/postfix.c'
--- src/libCom/calc/postfix.c 2016-05-22 12:38:18 +0000
+++ src/libCom/calc/postfix.c 2017-05-01 18:36:52 +0000
@@ -27,6 +27,10 @@
27#include "postfixPvt.h"27#include "postfixPvt.h"
28#include "shareLib.h"28#include "shareLib.h"
2929
30#ifdef USE_ALTIVEC
31#pragma GCC push_options
32#pragma GCC optimize ("O0")
33#endif
3034
31/* declarations for postfix */35/* declarations for postfix */
3236
@@ -624,3 +628,13 @@
624 }628 }
625 }629 }
626}630}
631/*
632#if __RTEMS_MAJOR__>4 || \
633 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>11) || \
634 (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==11 && __RTEMS_REVISION__==99)
635*/
636#ifdef USE_ALTIVEC
637#pragma GCC pop_options
638#endif
639/* #endif */
640
627641
=== modified file 'src/libCom/error/errlog.c'
--- src/libCom/error/errlog.c 2015-08-13 15:44:52 +0000
+++ src/libCom/error/errlog.c 2017-05-01 18:36:52 +0000
@@ -34,6 +34,10 @@
34#include "epicsStdio.h"34#include "epicsStdio.h"
35#include "epicsExit.h"35#include "epicsExit.h"
3636
37#if defined(__rtems__)
38#include <rtems/bspIo.h>
39#include <rtems.h>
40#endif
3741
38#define BUFFER_SIZE 128042#define BUFFER_SIZE 1280
39#define MAX_MESSAGE_SIZE 25643#define MAX_MESSAGE_SIZE 256
@@ -117,6 +121,7 @@
117 }121 }
118122
119 errlogInit(0);123 errlogInit(0);
124
120 isOkToBlock = epicsThreadIsOkToBlock();125 isOkToBlock = epicsThreadIsOkToBlock();
121126
122 if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {127 if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
123128
=== modified file 'src/libCom/misc/epicsUnitTest.c'
--- src/libCom/misc/epicsUnitTest.c 2016-05-22 12:38:18 +0000
+++ src/libCom/misc/epicsUnitTest.c 2017-05-01 18:36:52 +0000
@@ -248,6 +248,7 @@
248248
249void testHarness(void) {249void testHarness(void) {
250 epicsThreadOnce(&onceFlag, testOnce, NULL);250 epicsThreadOnce(&onceFlag, testOnce, NULL);
251epicsThreadShowAll(1);
251 epicsAtExit(testHarnessExit, NULL);252 epicsAtExit(testHarnessExit, NULL);
252 Harness = 1;253 Harness = 1;
253 Programs = 0;254 Programs = 0;
254255
=== modified file 'src/libCom/osi/os/Linux/osdSock.h'
--- src/libCom/osi/os/Linux/osdSock.h 2017-01-23 23:20:51 +0000
+++ src/libCom/osi/os/Linux/osdSock.h 2017-05-01 18:36:52 +0000
@@ -26,8 +26,10 @@
26#include <arpa/inet.h>26#include <arpa/inet.h>
27#include <net/if.h>27#include <net/if.h>
28#include <netdb.h>28#include <netdb.h>
29#include <ifaddrs.h> /* getifaddrs() */
29#include <unistd.h> /* close() and others */30#include <unistd.h> /* close() and others */
3031
32#define USE_IFADDRS
3133
32typedef int SOCKET;34typedef int SOCKET;
33#define INVALID_SOCKET (-1)35#define INVALID_SOCKET (-1)
3436
=== added directory 'src/libCom/osi/os/RTEMS-kernel'
=== renamed file 'src/libCom/osi/os/RTEMS/devLibVMEOSD.c' => 'src/libCom/osi/os/RTEMS-kernel/devLibVMEOSD.c'
=== renamed file 'src/libCom/osi/os/RTEMS/epicsAtomicOSD.cpp' => 'src/libCom/osi/os/RTEMS-kernel/epicsAtomicOSD.cpp'
=== renamed file 'src/libCom/osi/os/RTEMS/epicsAtomicOSD.h' => 'src/libCom/osi/os/RTEMS-kernel/epicsAtomicOSD.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdEvent.c' => 'src/libCom/osi/os/RTEMS-kernel/osdEvent.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdEvent.h' => 'src/libCom/osi/os/RTEMS-kernel/osdEvent.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdFindSymbol.c' => 'src/libCom/osi/os/RTEMS-kernel/osdFindSymbol.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdMessageQueue.c' => 'src/libCom/osi/os/RTEMS-kernel/osdMessageQueue.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdMessageQueue.h' => 'src/libCom/osi/os/RTEMS-kernel/osdMessageQueue.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdMutex.c' => 'src/libCom/osi/os/RTEMS-kernel/osdMutex.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdMutex.h' => 'src/libCom/osi/os/RTEMS-kernel/osdMutex.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdPoolStatus.c' => 'src/libCom/osi/os/RTEMS-kernel/osdPoolStatus.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdProcess.c' => 'src/libCom/osi/os/RTEMS-kernel/osdProcess.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdReadline.c' => 'src/libCom/osi/os/RTEMS-kernel/osdReadline.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdSignal.cpp' => 'src/libCom/osi/os/RTEMS-kernel/osdSignal.cpp'
=== renamed file 'src/libCom/osi/os/RTEMS/osdSock.h' => 'src/libCom/osi/os/RTEMS-kernel/osdSock.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdSpin.c' => 'src/libCom/osi/os/RTEMS-kernel/osdSpin.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdStrtod.h' => 'src/libCom/osi/os/RTEMS-kernel/osdStrtod.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdThread.c' => 'src/libCom/osi/os/RTEMS-kernel/osdThread.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdThread.h' => 'src/libCom/osi/os/RTEMS-kernel/osdThread.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osdThreadExtra.c' => 'src/libCom/osi/os/RTEMS-kernel/osdThreadExtra.c'
=== renamed file 'src/libCom/osi/os/RTEMS/osdTime.cpp' => 'src/libCom/osi/os/RTEMS-kernel/osdTime.cpp'
=== renamed file 'src/libCom/osi/os/RTEMS/osdTime.h' => 'src/libCom/osi/os/RTEMS-kernel/osdTime.h'
=== renamed file 'src/libCom/osi/os/RTEMS/osiUnistd.h' => 'src/libCom/osi/os/RTEMS-kernel/osiUnistd.h'
=== added directory 'src/libCom/osi/os/RTEMS-posix'
=== added file 'src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c'
--- src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,367 @@
1/*************************************************************************\
2* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
7* EPICS BASE is distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution.
9\*************************************************************************/
10
11/* RTEMS port by Till Straumann, <strauman@slac.stanford.edu>
12 * 3/2002
13 *
14 * Adapted to rtems4.12
15 * removed include bsp/bspExt.h
16 */
17
18#include <epicsStdio.h>
19#include <epicsExit.h>
20#include <rtems.h>
21#include <bsp.h>
22#include "devLibVME.h"
23#include <epicsInterrupt.h>
24
25#if defined(__PPC__) || defined(__mcf528x__)
26
27#if defined(__PPC__)
28#include <bsp/VME.h>
29#endif
30
31
32typedef void myISR (void *pParam);
33
34static myISR *isrFetch(unsigned vectorNumber, void **parg);
35
36/*
37 * this routine needs to be in the symbol table
38 * for this code to work correctly
39 */
40static void unsolicitedHandlerEPICS(int vectorNumber);
41
42static myISR *defaultHandlerAddr[]={
43 (myISR*)unsolicitedHandlerEPICS,
44};
45
46/*
47 * Make sure that the CR/CSR addressing mode is defined.
48 * (it may not be in some BSPs).
49 */
50#ifndef VME_AM_CSR
51# define VME_AM_CSR (0x2f)
52#endif
53
54/*
55 * we use a translation between an EPICS encoding
56 * and a vxWorks encoding here
57 * to reduce dependency of drivers on vxWorks
58 *
59 * we assume that the BSP are configured to use these
60 * address modes by default
61 */
62#define EPICSAddrTypeNoConvert -1
63int EPICStovxWorksAddrType[]
64 = {
65 VME_AM_SUP_SHORT_IO,
66 VME_AM_STD_SUP_DATA,
67 VME_AM_EXT_SUP_DATA,
68 EPICSAddrTypeNoConvert,
69 VME_AM_CSR
70 };
71
72/*
73 * maps logical address to physical address, but does not detect
74 * two device drivers that are using the same address range
75 */
76static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
77 size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
78
79/*
80 * a bus error safe "wordSize" read at the specified address which returns
81 * unsuccessful status if the device isnt present
82 */
83static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
84
85/*
86 * a bus error safe "wordSize" write at the specified address which returns
87 * unsuccessful status if the device isnt present
88 */
89static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
90
91static long rtemsDevConnectInterruptVME (
92 unsigned vectorNumber,
93 void (*pFunction)(),
94 void *parameter);
95
96static long rtemsDevDisconnectInterruptVME (
97 unsigned vectorNumber,
98 void (*pFunction)()
99);
100
101static long rtemsDevEnableInterruptLevelVME (unsigned level);
102
103static long rtemsDevDisableInterruptLevelVME (unsigned level);
104
105static int rtemsDevInterruptInUseVME (unsigned vectorNumber);
106
107/* RTEMS specific init */
108
109/*devA24Malloc and devA24Free are not implemented*/
110static void *devA24Malloc(size_t size) { return 0;}
111static void devA24Free(void *pBlock) {};
112static long rtemsDevInit(void);
113
114/*
115 * used by bind in devLib.c
116 */
117static devLibVME rtemsVirtualOS = {
118 rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe,
119 rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME,
120 rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME,
121 devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME
122};
123devLibVME *pdevLibVME = &rtemsVirtualOS;
124
125/* RTEMS specific initialization */
126static long
127rtemsDevInit(void)
128{
129 /* assume the vme bridge has been initialized by bsp */
130 /* init BSP extensions [memProbe etc.] */
131 return bspExtInit();
132}
133
134/*
135 * devConnectInterruptVME
136 *
137 * wrapper to minimize driver dependency on OS
138 */
139static long rtemsDevConnectInterruptVME (
140 unsigned vectorNumber,
141 void (*pFunction)(),
142 void *parameter)
143{
144 int status;
145
146
147 if (devInterruptInUseVME(vectorNumber)) {
148 return S_dev_vectorInUse;
149 }
150 status = BSP_installVME_isr(
151 vectorNumber,
152 pFunction,
153 parameter);
154 if (status) {
155 return S_dev_vecInstlFail;
156 }
157
158 return 0;
159}
160
161/*
162 *
163 * devDisconnectInterruptVME()
164 *
165 * wrapper to minimize driver dependency on OS
166 *
167 * The parameter pFunction should be set to the C function pointer that
168 * was connected. It is used as a key to prevent a driver from removing
169 * an interrupt handler that was installed by another driver
170 *
171 */
172static long rtemsDevDisconnectInterruptVME (
173 unsigned vectorNumber,
174 void (*pFunction)()
175)
176{
177 void (*psub)();
178 void *arg;
179 int status;
180
181 /*
182 * If pFunction not connected to this vector
183 * then they are probably disconnecting from the wrong vector
184 */
185 psub = isrFetch(vectorNumber, &arg);
186 if(psub != pFunction){
187 return S_dev_vectorNotInUse;
188 }
189
190 status = BSP_removeVME_isr(
191 vectorNumber,
192 psub,
193 arg) ||
194 BSP_installVME_isr(
195 vectorNumber,
196 (BSP_VME_ISR_t)unsolicitedHandlerEPICS,
197 (void*)vectorNumber);
198 if(status){
199 return S_dev_vecInstlFail;
200 }
201
202 return 0;
203}
204
205/*
206 * enable VME interrupt level
207 */
208static long rtemsDevEnableInterruptLevelVME (unsigned level)
209{
210 return BSP_enableVME_int_lvl(level);
211}
212
213/*
214 * disable VME interrupt level
215 */
216static long rtemsDevDisableInterruptLevelVME (unsigned level)
217{
218 return BSP_disableVME_int_lvl(level);
219}
220
221/*
222 * rtemsDevMapAddr ()
223 */
224static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
225 size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
226{
227 long status;
228
229 if (ppPhysicalAddress==NULL) {
230 return S_dev_badArgument;
231 }
232
233 if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert)
234 {
235 *ppPhysicalAddress = (void *) logicalAddress;
236 }
237 else
238 {
239 status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType],
240 logicalAddress, (unsigned long *)ppPhysicalAddress);
241 if (status) {
242 return S_dev_addrMapFail;
243 }
244 }
245
246 return 0;
247}
248
249/*
250 * a bus error safe "wordSize" read at the specified address which returns
251 * unsuccessful status if the device isnt present
252 */
253rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval);
254static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
255{
256 long status;
257
258 /*
259 * this global variable exists in the nivxi library
260 */
261 status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue);
262 if (status!=RTEMS_SUCCESSFUL) {
263 return S_dev_noDevice;
264 }
265
266 return 0;
267}
268
269/*
270 * a bus error safe "wordSize" write at the specified address which returns
271 * unsuccessful status if the device isnt present
272 */
273static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
274{
275 long status;
276
277 /*
278 * this global variable exists in the nivxi library
279 */
280 status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue);
281 if (status!=RTEMS_SUCCESSFUL) {
282 return S_dev_noDevice;
283 }
284
285 return 0;
286}
287
288/*
289 * isrFetch()
290 */
291static myISR *isrFetch(unsigned vectorNumber, void **parg)
292{
293 /*
294 * fetch the handler or C stub attached at this vector
295 */
296 return (myISR *) BSP_getVME_isr(vectorNumber,parg);
297}
298
299/*
300 * determine if a VME interrupt vector is in use
301 */
302static int rtemsDevInterruptInUseVME (unsigned vectorNumber)
303{
304 int i;
305 myISR *psub;
306 void *arg;
307
308 psub = isrFetch (vectorNumber,&arg);
309
310 if (!psub)
311 return FALSE;
312
313 /*
314 * its a C routine. Does it match a default handler?
315 */
316 for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) {
317 if (defaultHandlerAddr[i] == psub) {
318 return FALSE;
319 }
320 }
321
322 return TRUE;
323}
324
325
326/*
327 * unsolicitedHandlerEPICS()
328 * what gets called if they disconnect from an
329 * interrupt and an interrupt arrives on the
330 * disconnected vector
331 *
332 * NOTE: RTEMS may pass additional arguments - hope
333 * this doesn't disturb this handler...
334 *
335 * A cleaner way would be having a OS dependent
336 * macro to declare handler prototypes...
337 *
338 */
339static void unsolicitedHandlerEPICS(int vectorNumber)
340{
341 /*
342 * call epicInterruptContextMessage()
343 * and not errMessage()
344 * so we are certain that printf()
345 * does not get called at interrupt level
346 *
347 * NOTE: current RTEMS implementation only
348 * allows a static string to be passed
349 */
350 epicsInterruptContextMessage(
351 "Interrupt to EPICS disconnected vector"
352 );
353}
354
355#endif /* defined(__PPC__) && defined(mpc750) */
356
357/*
358 * Some vxWorks convenience routines
359 */
360void
361bcopyLongs(char *source, char *destination, int nlongs)
362{
363 const long *s = (long *)source;
364 long *d = (long *)destination;
365 while(nlongs--)
366 *d++ = *s++;
367}
0368
=== added file 'src/libCom/osi/os/RTEMS-posix/osdInterrupt.c'
--- src/libCom/osi/os/RTEMS-posix/osdInterrupt.c 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdInterrupt.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,59 @@
1/*************************************************************************\
2* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.
6* EPICS BASE is distributed subject to a Software License Agreement found
7* in file LICENSE that is included with this distribution.
8\*************************************************************************/
9/* osi/default/osdInterrupt.c */
10
11/* Author: Marty Kraimer Date: 15JUL99 */
12
13#include <stddef.h>
14#include <string.h>
15#include <stdlib.h>
16#include <stddef.h>
17#include <stdio.h>
18
19#define epicsExportSharedSymbols
20#include "epicsMutex.h"
21#include "epicsThread.h"
22#include "cantProceed.h"
23#include "errlog.h"
24#include "epicsInterrupt.h"
25
26#include <rtems/bspIo.h>
27#include <rtems.h>
28
29epicsShareFunc int epicsInterruptLock()
30{
31 rtems_interrupt_level level;
32
33 rtems_interrupt_disable (level);
34 return level;
35}
36
37epicsShareFunc void epicsInterruptUnlock(int key)
38{
39 rtems_interrupt_level level = key;
40
41 rtems_interrupt_enable (level);
42}
43
44epicsShareFunc int epicsInterruptIsInterruptContext()
45{
46 return rtems_interrupt_is_in_progress ();
47}
48
49epicsShareFunc void epicsInterruptContextMessage(const char *message)
50{
51 printk("%s", message);
52}
53
54
55
56
57
58
59
060
=== added file 'src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp'
--- src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp 2017-05-01 18:36:52 +0000
@@ -0,0 +1,163 @@
1/*************************************************************************\
2* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
7* EPICS BASE is distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution.
9\*************************************************************************/
10/*
11 * Author W. Eric Norum
12 * Heinz Junkes
13 *
14 * Adapted to rtems4.12
15 * -> posix message queues
16 * remove all internal calls (_xxx), remove e.g. Objects_Locations etc.
17 */
18
19/*
20 * We want to access information which is
21 * normally hidden from application programs.
22 */
23#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
24
25#define epicsExportSharedSymbols
26#include <assert.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <rtems.h>
31#include <rtems/error.h>
32#include "epicsMessageQueue.h"
33#include "errlog.h"
34#include <epicsAtomic.h>
35
36#include <errno.h>
37#include <mqueue.h>
38#include <fcntl.h>
39
40epicsShareFunc epicsMessageQueueId epicsShareAPI
41epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
42{
43 struct mq_attr the_attr;
44 epicsMessageQueueId id = (epicsMessageQueueId)calloc(1, sizeof(*id));
45
46 epicsAtomicIncrIntT(&id->idCnt);
47 sprintf(id->name, "MQ_%010d",epicsAtomicGetIntT(&id->idCnt));
48 the_attr.mq_maxmsg = capacity;
49 the_attr.mq_msgsize = maximumMessageSize;
50 id->id = mq_open(id->name, O_RDWR | O_CREAT | O_EXCL, 0644, &the_attr);
51 if (id->id < 0) {
52 errlogPrintf ("Can't create message queue: %s\n", strerror (errno));
53 return NULL;
54 }
55 return id;
56}
57
58epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy(
59 epicsMessageQueueId id)
60{
61 int rv;
62 rv = mq_close(id->id);
63 if( rv ) {
64 errlogPrintf("epicsMessageQueueDestroy mq_close failed: %s\n",
65 strerror(rv));
66 }
67 rv = mq_unlink(id->name);
68 if( rv ) {
69 errlogPrintf("epicsMessageQueueDestroy mq_unlink %s failed: %s\n",
70 id->name, strerror(rv));
71 }
72 free(id);
73}
74
75epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend(
76 epicsMessageQueueId id,
77 void *message,
78 unsigned int messageSize)
79{
80 struct timespec ts;
81 clock_gettime(CLOCK_REALTIME, &ts);
82 return mq_timedsend(id->id, (char const *)message, messageSize, 0, &ts);
83}
84
85epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout(
86 epicsMessageQueueId id,
87 void *message,
88 unsigned int messageSize,
89 double timeout)
90{
91 struct timespec ts;
92 unsigned long micros;
93
94 // assume timeout in sec
95 micros = (unsigned long)(timeout * 1000000.0);
96 clock_gettime(CLOCK_REALTIME, &ts);
97 ts.tv_sec += micros / 1000000L;
98 ts.tv_nsec += (micros % 1000000L) * 1000L;
99
100 return mq_timedsend (id->id, (const char *)message, messageSize, 0, &ts);
101}
102
103epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive(
104 epicsMessageQueueId id,
105 void *message,
106 unsigned int size)
107{
108 struct timespec ts;
109 clock_gettime(CLOCK_REALTIME, &ts);
110 return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
111}
112
113epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout(
114 epicsMessageQueueId id,
115 void *message,
116 unsigned int size,
117 double timeout)
118{
119 unsigned long micros;
120 struct timespec ts;
121
122 micros = (unsigned long)(timeout * 1000000.0);
123 clock_gettime(CLOCK_REALTIME, &ts);
124 ts.tv_sec += micros / 1000000L;
125 ts.tv_nsec += (micros % 1000000L) * 1000L;
126
127 return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
128}
129
130epicsShareFunc int epicsShareAPI epicsMessageQueuePending(
131 epicsMessageQueueId id)
132{
133 int rv;
134 struct mq_attr the_attr;
135
136 rv = mq_getattr(id->id, &the_attr);
137 if (rv) {
138 errlogPrintf("Epics Message queue %x (%s) get attr failed: %s\n",
139 (unsigned int)id->id, id->name, strerror(rv));
140 return -1;
141 }
142 return the_attr.mq_curmsgs;
143}
144
145epicsShareFunc void epicsShareAPI epicsMessageQueueShow(
146 epicsMessageQueueId id,
147 int level)
148{
149 int rv;
150 struct mq_attr the_attr;
151
152 rv = mq_getattr(id->id, &the_attr);
153 if (rv) {
154 errlogPrintf("Epics Message queue %x (%s) get attr failed: %s\n",
155 (unsigned int)id->id, id->id, strerror(rv));
156 }
157
158 printf("Message Queue Used:%ld Max Msg:%lu", the_attr.mq_curmsgs, the_attr.mq_maxmsg);
159 if (level >= 1)
160 printf(" Maximum size:%lu", the_attr.mq_msgsize);
161
162 printf("\n");
163}
0164
=== added file 'src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h'
--- src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h 2017-05-01 18:36:52 +0000
@@ -0,0 +1,31 @@
1/*************************************************************************\
2 * * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * * National Laboratory.
4 * * Copyright (c) 2002 The Regents of the University of California, as
5 * * Operator of Los Alamos National Laboratory.
6 * * Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
7 * * EPICS BASE is distributed subject to a Software License Agreement found
8 * * in file LICENSE that is included with this distribution.
9 * \*************************************************************************/
10/*
11 * Author W. Eric Norum
12 * Heinz Junkes
13 *
14 * Eric's note : Very thin shims around vxWorks routines
15 *
16 * Adapted to rtems4.12
17 * -> posix message queues
18 */
19
20#include <rtems.h>
21#include <mqueue.h>
22
23struct epicsMessageQueueOSD {
24 mqd_t id;
25 char name[24];
26 int idCnt;
27
28};
29
30#define epicsMessageQueueSend(q,m,l) (mq_send((q)->id, (const char*)(m), (l), 0))
31#define epicsMessageQueueReceive(q,m,s) (mq_receive((q)->id, (char*)(m), (s), NULL))
032
=== added file 'src/libCom/osi/os/RTEMS-posix/osdMutex.c'
--- src/libCom/osi/os/RTEMS-posix/osdMutex.c 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdMutex.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,6 @@
1#include <rtems.h>
2#include <rtems/error.h>
3#include <rtems/rtems/tasks.h>
4#include <rtems/score/threadimpl.h>
5
6#include "../posix/osdMutex.c"
07
=== added file 'src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c'
--- src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,34 @@
1/*************************************************************************\
2* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
7* EPICS BASE is distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution.
9\*************************************************************************/
10
11/*
12 * Heinz Junkes
13 * Adapted to rtems4.12
14 */
15
16#include <rtems.h>
17#include <rtems/malloc.h>
18#include <rtems/score/heap.h>
19#define epicsExportSharedSymbols
20#include "osiPoolStatus.h"
21
22/*
23 * osiSufficentSpaceInPool ()
24 *
25 */
26epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize )
27{
28 unsigned long n;
29 Heap_Information_block info;
30
31 malloc_info( &info );
32 n = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed);
33 return (n > (50000 + contiguousBlockSize));
34}
035
=== added file 'src/libCom/osi/os/RTEMS-posix/osdSock.h'
--- src/libCom/osi/os/RTEMS-posix/osdSock.h 1970-01-01 00:00:00 +0000
+++ src/libCom/osi/os/RTEMS-posix/osdSock.h 2017-05-01 18:36:52 +0000
@@ -0,0 +1,111 @@
1/*************************************************************************\
2* Copyright (c) 2002 The University of Saskatchewan
3* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
4* EPICS BASE is distributed subject to a Software License Agreement found
5* in file LICENSE that is included with this distribution.
6\*************************************************************************/
7/*
8 * RTEMS osdSock.h
9 * Author: W. Eric Norum
10 * Heinz Junkes
11 *
12 * Adapted to rtems4.12
13 */
14#ifndef osdSockH
15#define osdSockH
16
17#include <errno.h>
18
19#include <sys/types.h>
20#include <sys/param.h>
21#include <sys/time.h>
22#include <sys/socket.h>
23#include <sys/ioctl.h>
24#include <netinet/in.h>
25#include <netinet/tcp.h>
26#include <arpa/inet.h>
27#include <net/if.h>
28#include <netdb.h>
29#include <ifaddrs.h> /* getifaddrs() */
30#include <unistd.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
37
38#ifdef __cplusplus
39}
40#endif
41
42
43#ifndef IPPORT_USERRESERVED
44#define IPPORT_USERRESERVED 5000
45#endif
46
47#define USE_IFADDRS
48
49typedef int SOCKET;
50#define INVALID_SOCKET (-1)
51#define SOCKERRNO errno
52#define socket_ioctl(A,B,C) ioctl(A,B,C)
53typedef int osiSockIoctl_t;
54typedef socklen_t osiSocklen_t;
55
56#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
57
58#define SOCK_EWOULDBLOCK EWOULDBLOCK
59#define SOCK_ENOBUFS ENOBUFS
60#define SOCK_ECONNRESET ECONNRESET
61#define SOCK_ETIMEDOUT ETIMEDOUT
62#define SOCK_EADDRINUSE EADDRINUSE
63#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
64#define SOCK_ECONNREFUSED ECONNREFUSED
65#define SOCK_ECONNABORTED ECONNABORTED
66#define SOCK_EINPROGRESS EINPROGRESS
67#define SOCK_EISCONN EISCONN
68#define SOCK_EALREADY EALREADY
69#define SOCK_EINVAL EINVAL
70#define SOCK_EINTR EINTR
71#define SOCK_EPIPE EPIPE
72#define SOCK_EMFILE EMFILE
73#define SOCK_SHUTDOWN EPIPE
74#define SOCK_ENOTSOCK ENOTSOCK
75#define SOCK_EBADF EBADF
76
77// already defined in newlib
78//#define bzero(p,n) memset(p,0,n)
79#include <sys/time.h>
80#include <sys/types.h>
81#include <unistd.h>
82
83#ifndef INADDR_LOOPBACK
84#define INADDR_LOOPBACK (u_long)0x7F000001
85#endif
86
87#ifndef INADDR_NONE
88# define INADDR_NONE (0xffffffff)
89#endif
90
91/*
92 * For shutdown()
93 */
94#ifndef SHUT_RD
95# define SHUT_RD 0
96#endif
97
98#ifndef SHUT_WR
99# define SHUT_WR 1
100#endif
101
102#ifndef SHUT_RDWR
103# define SHUT_RDWR 2
104#endif
105
106/*
107 * Ensure that we get the right network code in default/osdNetIntf.c.
108 */
109#define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name))
110
111#endif /*osdSockH*/
0112
=== modified file 'src/libCom/osi/os/WIN32/osdNetIntf.c'
--- src/libCom/osi/os/WIN32/osdNetIntf.c 2017-02-01 17:57:04 +0000
+++ src/libCom/osi/os/WIN32/osdNetIntf.c 2017-05-01 18:36:52 +0000
@@ -3,6 +3,8 @@
3* National Laboratory.3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2015 Brookhaven Science Associates as Operator of
7* Brookhaven National Lab.
6* EPICS BASE is distributed subject to a Software License Agreement found8* EPICS BASE is distributed subject to a Software License Agreement found
7* in file LICENSE that is included with this distribution.9* in file LICENSE that is included with this distribution.
8\*************************************************************************/10\*************************************************************************/
@@ -40,214 +42,110 @@
40#include "epicsThread.h"42#include "epicsThread.h"
41#include "epicsVersion.h"43#include "epicsVersion.h"
4244
43static osiSockAddr osiLocalAddrResult;
44static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT;
45
46/*
47 * osiLocalAddr ()
48 */
49static void osiLocalAddrOnce ( void *raw )45static void osiLocalAddrOnce ( void *raw )
50{46{
51 SOCKET *psocket = raw;47int ret = -1, status, foundlo = 0;
52 osiSockAddr addr;48 SOCKET sock;
53 int status;49 unsigned nelem = 10, i;
54 INTERFACE_INFO *pIfinfo;50 INTERFACE_INFO *info = NULL;
55 INTERFACE_INFO *pIfinfoList = NULL;51 DWORD cbBytesReturned;
56 unsigned nelem;
57 DWORD numifs;
58 DWORD cbBytesReturned;
59
60 memset ( (void *) &addr, '\0', sizeof ( addr ) );
61 addr.sa.sa_family = AF_UNSPEC;
62
63 /* only valid for winsock 2 and above */
64 if ( wsaMajorVersion() < 2 ) {
65 goto fail;
66 }
67
68 nelem = 100;
69 pIfinfoList = (INTERFACE_INFO *) calloc ( nelem, sizeof (INTERFACE_INFO) );
70 if (!pIfinfoList) {
71 errlogPrintf ("calloc failed\n");
72 goto fail;
73 }
74
75 status = WSAIoctl (*psocket, SIO_GET_INTERFACE_LIST, NULL, 0,
76 (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),
77 &cbBytesReturned, NULL, NULL);
78
79 if (status != 0 || cbBytesReturned == 0) {
80 errlogPrintf ("WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
81 goto fail;
82 }
83
84 numifs = cbBytesReturned / sizeof(INTERFACE_INFO);
85 for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){
86
87 /*
88 * dont use interfaces that have been disabled
89 */
90 if (!(pIfinfo->iiFlags & IFF_UP)) {
91 continue;
92 }
93
94 /*
95 * dont use the loop back interface
96 */
97 if (pIfinfo->iiFlags & IFF_LOOPBACK) {
98 continue;
99 }
100
101 addr.sa = pIfinfo->iiAddress.Address;
102
103 /* Work around MS Winsock2 bugs */
104 if (addr.sa.sa_family == 0) {
105 addr.sa.sa_family = AF_INET;
106 }
107
108 osiLocalAddrResult = addr;
109 free ( pIfinfoList );
110 return;
111 }
112
113 errlogPrintf (
114 "osiLocalAddr(): only loopback found\n");
115fail:
116 /* fallback to loopback */
117 memset ( (void *) &addr, '\0', sizeof ( addr ) );
118 addr.ia.sin_family = AF_INET;
119 addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
120 osiLocalAddrResult = addr;
121
122 free ( pIfinfoList );
123}
124
125epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket)
126{
127 epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket);
128 return osiLocalAddrResult;
129}
130
131/*
132 * osiSockDiscoverBroadcastAddresses ()
133 */
134epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
135 (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr)
136{
137 int status;
138 INTERFACE_INFO *pIfinfo;
139 INTERFACE_INFO *pIfinfoList;
140 unsigned nelem;
141 int numifs;
142 DWORD cbBytesReturned;
143 osiSockAddrNode *pNewNode;
144
145 if ( pMatchAddr->sa.sa_family == AF_INET ) {
146 if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {
147 pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
148 if ( pNewNode == NULL ) {
149 return;
150 }
151 pNewNode->addr.ia.sin_family = AF_INET;
152 pNewNode->addr.ia.sin_port = htons ( 0 );
153 pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
154 ellAdd ( pList, &pNewNode->node );
155 return;
156 }
157 }
15852
159 /* only valid for winsock 2 and above */53 /* only valid for winsock 2 and above */
160 if (wsaMajorVersion() < 2 ) {54 if (wsaMajorVersion() < 2 ) {
161 fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n");55 fprintf(stderr, "Interface discovery not supported for winsock 1\n"
162 return;56 "Need to set EPICS_CA_AUTO_ADDR_LIST=NO\n");
163 }57 return ret;
16458 }
165 nelem = 100;59
166 pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO));60 sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
167 if(!pIfinfoList){61 if(sock==INVALID_SOCKET)
168 return;62 return ret;
169 }63
17064 info = calloc(nelem, sizeof(*info));
171 status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST,65 if(!info)
172 NULL, 0,66 goto cleanup;
173 (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),67
174 &cbBytesReturned, NULL, NULL);68 /* In future use SIO_GET_INTERFACE_LIST_EX to include IPv6 */
69
70 status = WSAIoctl (sock, SIO_GET_INTERFACE_LIST,
71 NULL, 0,
72 (LPVOID)info, nelem*sizeof(*info),
73 &cbBytesReturned, NULL, NULL);
17574
176 if (status != 0 || cbBytesReturned == 0) {75 if (status != 0 || cbBytesReturned == 0) {
177 fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());76 fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
178 free(pIfinfoList);77 goto cleanup;
179 return;78 }
180 }79
18180 nelem = cbBytesReturned/sizeof(*info);
182 numifs = cbBytesReturned/sizeof(INTERFACE_INFO);81
183 for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){82 for(i=0; i<nelem; i++)
18483 {
185 /*84 unsigned int flags;
186 * dont bother with interfaces that have been disabled85 osiInterfaceInfo *node = calloc(1, sizeof(*node));
187 */86 if(!node)
188 if (!(pIfinfo->iiFlags & IFF_UP)) {87 goto cleanup;
189 continue;88
190 }89 /* work around WS2 bug */
19190 if(info[i].iiAddress.AddressIn.sin_family==0)
192 if (pIfinfo->iiFlags & IFF_LOOPBACK) {91 info[i].iiAddress.AddressIn.sin_family = AF_INET;
193 continue;92
194 }93 if(info[i].iiAddress.AddressIn.sin_family!=AF_INET) {
19594 free(node);
196 /*95 continue;
197 * work around WS2 bug96 }
198 */97
199 if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {98 node->address.ia = info[i].iiAddress.AddressIn;
200 if (pIfinfo->iiAddress.Address.sa_family == 0) {99 node->netmask.ia = info[i].iiNetmask.AddressIn;
201 pIfinfo->iiAddress.Address.sa_family = AF_INET;100 node->endpoint.ia = info[i].iiBroadcastAddress.AddressIn;
202 }101
203 }102 flags = info[i].iiFlags;
204103
205 /*104 if(flags&IFF_UP) node->up = 1;
206 * if it isnt a wildcarded interface then look for105 if(flags&IFF_BROADCAST) node->broadcast = 1;
207 * an exact match106 if(flags&IFF_MULTICAST) node->multicast = 1;
208 */107 if(flags&IFF_LOOPBACK) node->loopback = 1;
209 if (pMatchAddr->sa.sa_family != AF_UNSPEC) {108 /* BSD sockets have IFF_POINTOPOINT while winsock has IFF_POINTTOPOINT
210 if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) {109 * Note the extra 'T'
211 continue;110 */
212 }111 if(flags&IFF_POINTTOPOINT) node->point2point = 1;
213 if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {112
214 continue;113 if(node->broadcast && node->point2point) {
215 }114 errlogPrintf("Interface %u claims both broadcast and point to point,"
216 if (pMatchAddr->sa.sa_family != AF_INET) {115 " which should not be possible. Assuming broadcast only.",
217 continue;116 i);
218 }117 node->point2point = 0;
219 if (pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY)) {118 }
220 if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr) {119
221 continue;120 if(node->loopback) foundlo = 1;
222 }121 ellAdd(pList, &node->node);
223 }122 }
224 }123
225124 if(!foundlo) {
226 pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));125 /* sometimes the loopback isn't included (WINE+mingw) */
227 if (pNewNode==NULL) {126 osiInterfaceInfo *node = calloc(1, sizeof(*node));
228 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n");127 if(!node)
229 return;128 goto cleanup;
230 }129
231130 node->up = 1;
232 if (pIfinfo->iiAddress.Address.sa_family == AF_INET &&131 node->loopback = 1;
233 pIfinfo->iiFlags & IFF_BROADCAST) {132
234 const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr;133 node->address.ia.sin_family = AF_INET;
235 const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr;134 node->address.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
236 const unsigned addr = pIfinfo->iiAddress.AddressIn.sin_addr.s_addr;135 node->address.ia.sin_port = 0;
237 unsigned result = (addr & mask) | (bcast &~mask);136
238 pNewNode->addr.ia.sin_family = AF_INET;137 node->netmask.ia.sin_family = AF_INET;
239 pNewNode->addr.ia.sin_addr.s_addr = result;138 node->netmask.ia.sin_addr.s_addr = htonl(0xff000000);
240 pNewNode->addr.ia.sin_port = htons ( 0 );139 node->netmask.ia.sin_port = 0;
241 }140
242 else {141 ellInsert(pList, NULL, &node->node);
243 pNewNode->addr.sa = pIfinfo->iiBroadcastAddress.Address;142 }
244 }143
245144 ret = 0;
246 /*145cleanup:
247 * LOCK applied externally146 if(ret)
248 */147 ellFree(pList);
249 ellAdd (pList, &pNewNode->node);148 free(info);
250 }149 epicsSocketDestroy(sock);
251150 return ret;
252 free (pIfinfoList);
253}151}
254152
=== modified file 'src/libCom/osi/os/default/osdNetIntf.c'
--- src/libCom/osi/os/default/osdNetIntf.c 2017-02-01 17:57:04 +0000
+++ src/libCom/osi/os/default/osdNetIntf.c 2017-05-01 18:36:52 +0000
@@ -3,6 +3,8 @@
3* National Laboratory.3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2015 Brookhaven Science Associates as Operator of
7* Brookhaven National Lab.
6* EPICS BASE Versions 3.13.78* EPICS BASE Versions 3.13.7
7* and higher are distributed subject to a Software License Agreement found9* and higher are distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution. 10* in file LICENSE that is included with this distribution.
@@ -19,6 +21,7 @@
19#include <stdlib.h>21#include <stdlib.h>
2022
21#define epicsExportSharedSymbols23#define epicsExportSharedSymbols
24#include "dbDefs.h"
22#include "osiSock.h"25#include "osiSock.h"
23#include "epicsAssert.h"26#include "epicsAssert.h"
24#include "errlog.h"27#include "errlog.h"
@@ -30,323 +33,155 @@
30# define ifDepenDebugPrintf(argsInParen)33# define ifDepenDebugPrintf(argsInParen)
31#endif34#endif
3235
33static osiSockAddr osiLocalAddrResult;36#ifdef USE_IFADDRS
34static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT;37
3538epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags)
36/*39{
37 * Determine the size of an ifreq structure40 int ret = -1;
38 * Made difficult by the fact that addresses larger than the structure41 struct ifaddrs *addrs = NULL, *cur;
39 * size may be returned from the kernel.42
40 */43 ellFree(pList);
41static size_t ifreqSize ( struct ifreq *pifreq )44
42{45 if(getifaddrs(&addrs))
43 size_t size;46 goto cleanup;
4447
45 size = ifreq_size ( pifreq );48 for(cur=addrs; cur; cur=cur?cur->ifa_next:NULL)
46 if ( size < sizeof ( *pifreq ) ) {49// for(cur=addrs; cur; cur=cur->ifa_next)
47 size = sizeof ( *pifreq );50 {
48 }51 unsigned int flags;
49 return size;52 osiInterfaceInfo *node = calloc(1, sizeof(*node));
50}53 if(!node)
5154 goto cleanup;
52/*55
53 * Move to the next ifreq structure56 switch(cur->ifa_addr->sa_family)
54 */57 {
55static struct ifreq * ifreqNext ( struct ifreq *pifreq )58 case AF_INET:
56{59 /*case AF_INET6:*/
57 struct ifreq *ifr;60 break;
5861 default:
59 ifr = ( struct ifreq * )( ifreqSize (pifreq) + ( char * ) pifreq );62 free(node);
60 ifDepenDebugPrintf( ("ifreqNext() pifreq %p, size 0x%x, ifr 0x%p\n", pifreq, (unsigned)ifreqSize (pifreq), ifr) );63 continue; /* ignore unknown address types */
61 return ifr;64 }
62}65
6366 //assert(cur->ifa_addr->sa_family==cur->ifa_netmask->sa_family);
6467 memcpy(&node->address.ia, cur->ifa_addr, sizeof(node->address.ia));
65/*68 memcpy(&node->netmask.ia, cur->ifa_netmask, sizeof(node->address.ia));
66 * osiSockDiscoverBroadcastAddresses ()69
67 */70 flags = cur->ifa_flags;
68epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses71
69 (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr)72 if(flags&IFF_UP) node->up = 1;
70{73 if(flags&IFF_BROADCAST) node->broadcast = 1;
71 static const unsigned nelem = 100;74 if(flags&IFF_MULTICAST) node->multicast = 1;
72 int status;75 if(flags&IFF_LOOPBACK) node->loopback = 1;
73 struct ifconf ifconf;76 if(flags&IFF_POINTOPOINT) node->point2point = 1;
74 struct ifreq *pIfreqList;77
75 struct ifreq *pIfreqListEnd;78 if(node->broadcast && node->point2point) {
76 struct ifreq *pifreq;79 errlogPrintf("Interface %s claims both broadcast and point to point,"
77 struct ifreq *pnextifreq;80 " which should not be possible. Assuming broadcast only.",
78 osiSockAddrNode *pNewNode;81 cur->ifa_name);
7982 node->point2point = 0;
80 if ( pMatchAddr->sa.sa_family == AF_INET ) {83 }
81 if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {84
82 pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );85 if(node->broadcast)
83 if ( pNewNode == NULL ) {86 memcpy(&node->endpoint.ia, cur->ifa_broadaddr, sizeof(node->address.ia));
84 errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );87 else if(node->point2point)
85 return;88 memcpy(&node->endpoint.ia, cur->ifa_dstaddr, sizeof(node->address.ia));
86 }89
87 pNewNode->addr.ia.sin_family = AF_INET;90 ellAdd(pList, &node->node);
88 pNewNode->addr.ia.sin_port = htons ( 0 );91 }
89 pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);92
90 ellAdd ( pList, &pNewNode->node );93 ret = 0;
91 return;94cleanup:
92 }95 if(ret)
93 }96 ellFree(pList);
94 97 if(addrs) freeifaddrs(addrs);
95 /*98 return ret;
96 * use pool so that we avoid using too much stack space99}
97 *100#else /* USE_IFADDRS */
98 * nelem is set to the maximum interfaces 101
99 * on one machine here102epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags)
100 */103{
101 pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pifreq) );104 SOCKET sock;
102 if (!pIfreqList) {105 int ret = -1;
103 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory to complete request\n");106 struct if_nameindex* pIndex = 0;
104 return;107 struct if_nameindex* pIndex2 = 0;
105 }108
106 109 ellFree(pList);
107 ifconf.ifc_len = nelem * sizeof(*pifreq);110
108 ifconf.ifc_req = pIfreqList;111 sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
109 status = socket_ioctl (socket, SIOCGIFCONF, &ifconf);112 if(sock==INVALID_SOCKET)
110 if (status < 0 || ifconf.ifc_len == 0) {113 return ret;
111 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration (%d)\n", status);114
112 free (pIfreqList);115 pIndex = pIndex2 = if_nameindex();
113 return;116 while ((pIndex != NULL) && (pIndex->if_name != NULL))
114 }117 {
115 118 struct ifreq req;
116 pIfreqListEnd = (struct ifreq *) (ifconf.ifc_len + (char *) pIfreqList);119 unsigned int flags;
117 pIfreqListEnd--;120 osiInterfaceInfo *node = calloc(1, sizeof(*node));
118121 if(!node)
119 for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) {122 goto cleanup;
120 uint32_t current_ifreqsize;123 strncpy(req.ifr_name, pIndex->if_name, IFNAMSIZ);
121124 if(socket_ioctl(sock, SIOCGIFADDR, &req)<0) {
122 /*125 if (errno == EADDRNOTAVAIL) {
123 * find the next ifreq126 free(node);
124 */127 ++pIndex;
125 pnextifreq = ifreqNext (pifreq);128 continue;
126 129 }
127 /* determine ifreq size */130 free(node);
128 current_ifreqsize = ifreqSize ( pifreq );131 goto cleanup;
129 /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */132 }
130 memmove(pIfreqList, pifreq, current_ifreqsize);133 memcpy(&node->address.ia, &req.ifr_addr, sizeof(node->address.ia));
131134
132 ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n",135 if(socket_ioctl(sock, SIOCGIFNETMASK, &req)<0) {
133 pIfreqList->ifr_name,136 free(node);
134 (unsigned)ifreq_size(pifreq),137 goto cleanup;
135 (unsigned)current_ifreqsize));138 }
136139 memcpy(&node->netmask.ia, &req.ifr_addr, sizeof(node->netmask.ia));
137 /*140
138 * If its not an internet interface then dont use it 141 if(socket_ioctl(sock, SIOCGIFFLAGS, &req)<0) {
139 */142 free(node);
140 if ( pIfreqList->ifr_addr.sa_family != AF_INET ) {143 goto cleanup;
141 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) );144 }
142 continue;145 flags = req.ifr_flags;
143 }146 if(flags&IFF_UP) node->up = 1;
144147 if(flags&IFF_BROADCAST) node->broadcast = 1;
145 /*148 if(flags&IFF_MULTICAST) node->multicast = 1;
146 * if it isnt a wildcarded interface then look for149 if(flags&IFF_LOOPBACK) node->loopback = 1;
147 * an exact match150 if(flags&IFF_POINTOPOINT) node->point2point = 1;
148 */151
149 if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) {152 if(node->broadcast && node->point2point) {
150 if ( pMatchAddr->sa.sa_family != AF_INET ) {153 errlogPrintf("Interface %s claims both broadcast and point to point,"
151 continue;154 " which should not be possible. Assuming broadcast only.",
152 }155 req.ifr_name);
153 if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) {156 node->point2point = 0;
154 struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr;157 }
155 if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {158 if(node->broadcast) {
156 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) );159 if(socket_ioctl(sock, SIOCGIFBRDADDR, &req)<0) {
157 continue;160 free(node);
158 }161 goto cleanup;
159 }162 }
160 }163 } else if(node->point2point) {
161164 if(socket_ioctl(sock, SIOCGIFDSTADDR, &req)<0) {
162 status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList );165 free(node);
163 if ( status ) {166 goto cleanup;
164 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name);167 }
165 continue;168 }
166 }169
167 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" flags: %x\n", pIfreqList->ifr_name, pIfreqList->ifr_flags) );170 if(node->broadcast || node->point2point) {
168171 assert(req.ifr_addr.sa_family==node->address.sa.sa_family);
169 /*172
170 * dont bother with interfaces that have been disabled173 memcpy(&node->endpoint.ia, &req.ifr_addr, sizeof(node->endpoint.ia));
171 */174 }
172 if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) {175
173 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) );176 ellAdd(pList, &node->node);
174 continue;177 ++pIndex;
175 }178 }
176179
177 /*180 ret = 0;
178 * dont use the loop back interface 181cleanup:
179 */182 if(ret)
180 if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) {183 ellFree(pList);
181 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) );184 epicsSocketDestroy(sock);
182 continue;185 return ret;
183 }186}
184187#endif /* USE_IFADRS */
185 pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
186 if ( pNewNode == NULL ) {
187 errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
188 free ( pIfreqList );
189 return;
190 }
191
192 /*
193 * If this is an interface that supports
194 * broadcast fetch the broadcast address.
195 *
196 * Otherwise if this is a point to point
197 * interface then use the destination address.
198 *
199 * Otherwise CA will not query through the
200 * interface.
201 */
202 if ( pIfreqList->ifr_flags & IFF_BROADCAST ) {
203 osiSockAddr baddr;
204 status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList);
205 if ( status ) {
206 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name);
207 free ( pNewNode );
208 continue;
209 }
210 baddr.sa = pIfreqList->ifr_broadaddr;
211 if (baddr.ia.sin_family==AF_INET && baddr.ia.sin_addr.s_addr != INADDR_ANY) {
212 pNewNode->addr.sa = pIfreqList->ifr_broadaddr;
213 ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( baddr.ia.sin_addr.s_addr ) ) );
214 } else {
215 ifDepenDebugPrintf ( ( "Ignoring broadcast addr = \n", ntohl ( baddr.ia.sin_addr.s_addr ) ) );
216 free ( pNewNode );
217 continue;
218 }
219 }
220#if defined (IFF_POINTOPOINT)
221 else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) {
222 status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList);
223 if ( status ) {
224 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) );
225 free ( pNewNode );
226 continue;
227 }
228 pNewNode->addr.sa = pIfreqList->ifr_dstaddr;
229 }
230#endif
231 else {
232 ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) );
233 free ( pNewNode );
234 continue;
235 }
236
237 ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) );
238
239 /*
240 * LOCK applied externally
241 */
242 ellAdd ( pList, &pNewNode->node );
243 }
244
245 free ( pIfreqList );
246}
247
248/*
249 * osiLocalAddr ()
250 */
251static void osiLocalAddrOnce (void *raw)
252{
253 SOCKET *psocket = raw;
254 const unsigned nelem = 100;
255 osiSockAddr addr;
256 int status;
257 struct ifconf ifconf;
258 struct ifreq *pIfreqList;
259 struct ifreq *pifreq;
260 struct ifreq *pIfreqListEnd;
261 struct ifreq *pnextifreq;
262
263 memset ( (void *) &addr, '\0', sizeof ( addr ) );
264 addr.sa.sa_family = AF_UNSPEC;
265
266 pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pIfreqList) );
267 if ( ! pIfreqList ) {
268 errlogPrintf ( "osiLocalAddr(): no memory to complete request\n" );
269 goto fail;
270 }
271
272 ifconf.ifc_len = nelem * sizeof ( *pIfreqList );
273 ifconf.ifc_req = pIfreqList;
274 status = socket_ioctl ( *psocket, SIOCGIFCONF, &ifconf );
275 if ( status < 0 || ifconf.ifc_len == 0 ) {
276 char sockErrBuf[64];
277 epicsSocketConvertErrnoToString (
278 sockErrBuf, sizeof ( sockErrBuf ) );
279 errlogPrintf (
280 "osiLocalAddr(): SIOCGIFCONF ioctl failed because \"%s\"\n",
281 sockErrBuf );
282 goto fail;
283 }
284
285 pIfreqListEnd = (struct ifreq *) ( ifconf.ifc_len + (char *) ifconf.ifc_req );
286 pIfreqListEnd--;
287
288 for ( pifreq = ifconf.ifc_req; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) {
289 osiSockAddr addrCpy;
290 uint32_t current_ifreqsize;
291
292 /*
293 * find the next if req
294 */
295 pnextifreq = ifreqNext ( pifreq );
296
297 /* determine ifreq size */
298 current_ifreqsize = ifreqSize ( pifreq );
299 /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */
300 memmove(pIfreqList, pifreq, current_ifreqsize);
301
302 if ( pIfreqList->ifr_addr.sa_family != AF_INET ) {
303 ifDepenDebugPrintf ( ("osiLocalAddr(): interface %s was not AF_INET\n", pIfreqList->ifr_name) );
304 continue;
305 }
306
307 addrCpy.sa = pIfreqList->ifr_addr;
308
309 status = socket_ioctl ( *psocket, SIOCGIFFLAGS, pIfreqList );
310 if ( status < 0 ) {
311 errlogPrintf ( "osiLocalAddr(): net intf flags fetch for %s failed\n", pIfreqList->ifr_name );
312 continue;
313 }
314
315 if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) {
316 ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s was down\n", pIfreqList->ifr_name) );
317 continue;
318 }
319
320 /*
321 * dont use the loop back interface
322 */
323 if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) {
324 ifDepenDebugPrintf ( ("osiLocalAddr(): ignoring loopback interface: %s\n", pIfreqList->ifr_name) );
325 continue;
326 }
327
328 ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s found\n", pIfreqList->ifr_name) );
329
330 osiLocalAddrResult = addrCpy;
331 free ( pIfreqList );
332 return;
333 }
334
335 errlogPrintf (
336 "osiLocalAddr(): only loopback found\n");
337fail:
338 /* fallback to loopback */
339 memset ( (void *) &addr, '\0', sizeof ( addr ) );
340 addr.ia.sin_family = AF_INET;
341 addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
342 osiLocalAddrResult = addr;
343
344 free ( pIfreqList );
345}
346
347
348epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket)
349{
350 epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, &socket);
351 return osiLocalAddrResult;
352}
353188
=== modified file 'src/libCom/osi/os/posix/osdSockAddrReuse.cpp'
--- src/libCom/osi/os/posix/osdSockAddrReuse.cpp 2016-05-22 12:38:18 +0000
+++ src/libCom/osi/os/posix/osdSockAddrReuse.cpp 2017-05-01 18:36:52 +0000
@@ -17,6 +17,12 @@
17#include "osiSock.h"17#include "osiSock.h"
18#include "errlog.h"18#include "errlog.h"
1919
20#ifdef SO_REUSEPORT
21#define OPTION SO_REUSEPORT
22#else
23#define OPTION SO_REUSEADDR
24#endif
25
20epicsShareFunc void epicsShareAPI 26epicsShareFunc void epicsShareAPI
21 epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s )27 epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s )
22{28{
@@ -33,13 +39,14 @@
3339
34/*40/*
35 * SO_REUSEPORT is not in POSIX41 * SO_REUSEPORT is not in POSIX
42 * but in RTEMS
36 */43 */
37epicsShareFunc void epicsShareAPI 44epicsShareFunc void epicsShareAPI
38 epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s )45 epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s )
39{46{
40 int yes = true;47 int yes = true;
41 int status;48 int status;
42 status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR,49 status = setsockopt ( s, SOL_SOCKET, OPTION,
43 (char *) & yes, sizeof ( yes ) );50 (char *) & yes, sizeof ( yes ) );
44 if ( status < 0 ) {51 if ( status < 0 ) {
45 errlogPrintf (52 errlogPrintf (
4653
=== modified file 'src/libCom/osi/os/posix/osdThread.c'
--- src/libCom/osi/os/posix/osdThread.c 2016-02-23 21:43:26 +0000
+++ src/libCom/osi/os/posix/osdThread.c 2017-05-01 18:36:52 +0000
@@ -4,11 +4,19 @@
4* Copyright (c) 2002 The Regents of the University of California, as4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2013 ITER Organization.6* Copyright (c) 2013 ITER Organization.
7* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft
7* EPICS BASE is distributed subject to a Software License Agreement found8* EPICS BASE is distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution. 9* in file LICENSE that is included with this distribution.
9\*************************************************************************/10\*************************************************************************/
1011
11/* Author: Marty Kraimer Date: 18JAN2000 */12/* Author: Marty Kraimer Date: 18JAN2000
13 Heinz Junkes Date: 06APR2017
14
15 once() and all called functions by once must use
16 checkStatusOnce and checkStatusQuitOnce only
17 including epicsEventCreate called by create_threadInfo
18 add epicsEventCreateOnce which can be called here
19*/
1220
13/* This is a posix implementation of epicsThread */21/* This is a posix implementation of epicsThread */
14#include <stddef.h>22#include <stddef.h>
@@ -38,6 +46,16 @@
38#include "errlog.h"46#include "errlog.h"
39#include "epicsAssert.h"47#include "epicsAssert.h"
40#include "epicsExit.h"48#include "epicsExit.h"
49#if defined(__rtems__)
50#include <rtems/bspIo.h>
51#include <rtems.h>
52#endif
53
54struct epicsEventOSD {
55 pthread_mutex_t mutex;
56 pthread_cond_t cond;
57 int isFull;
58};
4159
42epicsShareFunc void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level);60epicsShareFunc void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level);
43epicsShareFunc void osdThreadHooksRun(epicsThreadId id);61epicsShareFunc void osdThreadHooksRun(epicsThreadId id);
@@ -75,14 +93,15 @@
75} priAvailable;93} priAvailable;
76#endif94#endif
7795
78static pthread_key_t getpthreadInfo;96__thread epicsThreadOSD *tls_pthreadInfo;
97
79static pthread_mutex_t onceLock;98static pthread_mutex_t onceLock;
80static pthread_mutex_t listLock;99static pthread_mutex_t listLock;
81static ELLLIST pthreadList = ELLLIST_INIT;100static ELLLIST pthreadList = ELLLIST_INIT;
82static commonAttr *pcommonAttr = 0;101static commonAttr *pcommonAttr = 0;
83static int epicsThreadOnceCalled = 0;102static int epicsThreadInitOnceCalled = 0;
84103
85104
86static epicsThreadOSD *createImplicit(void);105static void createImplicit(void);
87106
88#define checkStatus(status,message) \107#define checkStatus(status,message) \
89if((status)) {\108if((status)) {\
@@ -90,7 +109,7 @@
90}109}
91110
92#define checkStatusQuit(status,message,method) \111#define checkStatusQuit(status,message,method) \
93if(status) { \112if((status)) { \
94 errlogPrintf("%s error %s\n",(message),strerror((status))); \113 errlogPrintf("%s error %s\n",(message),strerror((status))); \
95 cantProceed((method)); \114 cantProceed((method)); \
96}115}
@@ -99,17 +118,33 @@
99/* Until epicsThreadInit completes errlogInit will not work */118/* Until epicsThreadInit completes errlogInit will not work */
100/* It must also be used by init_threadInfo otherwise errlogInit could get */119/* It must also be used by init_threadInfo otherwise errlogInit could get */
101/* called recursively */120/* called recursively */
121#if defined (__rtems__)
122#define checkStatusOnce(status,message) \
123if((status)) {\
124 printk("%s error %s\n",(message),strerror((status))); }
125#else
102#define checkStatusOnce(status,message) \126#define checkStatusOnce(status,message) \
103if((status)) {\127if((status)) {\
104 fprintf(stderr,"%s error %s\n",(message),strerror((status))); }128 fprintf(stderr,"%s error %s\n",(message),strerror((status))); }
129#endif
105130
106#define checkStatusOnceQuit(status,message,method) \131#if defined (__rtems__)
107if(status) { \132#define checkStatusOnceQuit(status,message,method) \
133if((status)) { \
134 printk("%s error %s",(message),strerror((status))); \
135 printk(" %s\n",method); \
136 printk("epicsThreadInit cant proceed. Program exiting\n"); \
137 exit(-1);\
138}
139#else
140#define checkStatusOnceQuit(status,message,method) \
141if((status)) { \
108 fprintf(stderr,"%s error %s",(message),strerror((status))); \142 fprintf(stderr,"%s error %s",(message),strerror((status))); \
109 fprintf(stderr," %s\n",method); \143 fprintf(stderr," %s\n",method); \
110 fprintf(stderr,"epicsThreadInit cant proceed. Program exiting\n"); \144 fprintf(stderr,"epicsThreadInit cant proceed. Program exiting\n"); \
111 exit(-1);\145 exit(-1);\
112}146}
147#endif
113148
114149
115150
116epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId pthreadInfo)151epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId pthreadInfo)
@@ -153,6 +188,29 @@
153#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */188#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
154}189}
155190
156191
192
193epicsShareFunc epicsEventId epicsEventCreateOnce(epicsEventInitialState init)
194{
195 epicsEventId pevent = malloc(sizeof(*pevent));
196 if (pevent) {
197 int status = pthread_mutex_init(&pevent->mutex, 0);
198
199 pevent->isFull = (init == epicsEventFull);
200 if (status) {
201 checkStatus(status, "pthread_mutex_init");
202 } else {
203 status = pthread_cond_init(&pevent->cond, 0);
204 if (!status)
205 return pevent;
206 checkStatus(status, "pthread_cond_init");
207 status = pthread_mutex_destroy(&pevent->mutex);
208 checkStatus(status, "pthread_mutex_destroy");
209 }
210 free(pevent);
211 }
212 return NULL;
213}
214
157static epicsThreadOSD * create_threadInfo(const char *name)215static epicsThreadOSD * create_threadInfo(const char *name)
158{216{
159 epicsThreadOSD *pthreadInfo;217 epicsThreadOSD *pthreadInfo;
@@ -161,7 +219,7 @@
161 pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name));219 pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name));
162 if(!pthreadInfo)220 if(!pthreadInfo)
163 return NULL;221 return NULL;
164 pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty);222 pthreadInfo->suspendEvent = epicsEventCreateOnce(epicsEventEmpty);
165 if(!pthreadInfo->suspendEvent){223 if(!pthreadInfo->suspendEvent){
166 free(pthreadInfo);224 free(pthreadInfo);
167 return NULL;225 return NULL;
@@ -204,11 +262,13 @@
204{262{
205 int status;263 int status;
206264
207 status = mutexLock(&listLock);265 if(pthreadInfo->isOnThreadList) {
208 checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo");266 status = mutexLock(&listLock);
209 if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node);267 checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo");
210 status = pthread_mutex_unlock(&listLock);268 ellDelete(&pthreadList,&pthreadInfo->node);
211 checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo");269 status = pthread_mutex_unlock(&listLock);
270 checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo");
271 }
212 epicsEventDestroy(pthreadInfo->suspendEvent);272 epicsEventDestroy(pthreadInfo->suspendEvent);
213 status = pthread_attr_destroy(&pthreadInfo->attr);273 status = pthread_attr_destroy(&pthreadInfo->attr);
214 checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo");274 checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo");
@@ -301,13 +361,19 @@
301 arg.ok = 0;361 arg.ok = 0;
302362
303 status = pthread_create(&id, 0, find_pri_range, &arg);363 status = pthread_create(&id, 0, find_pri_range, &arg);
304 checkStatusQuit(status, "pthread_create","epicsThreadInit");364 checkStatusOnceQuit(status, "pthread_create","findPriorityRange");
305365
306 status = pthread_join(id, &dummy);366 status = pthread_join(id, &dummy);
307 checkStatusQuit(status, "pthread_join","epicsThreadInit");367 checkStatusOnceQuit(status, "pthread_join","findPriorityRange");
308368#if defined (__rtems__)
369// We are using posix map osi 0-100 to posix 100-200
370// see epicsThreadGetOsiPriorityValue(int ossPriority)
371 a_p->minPriority = 100;
372 a_p->maxPriority = 200;
373#else
309 a_p->minPriority = arg.min_pri;374 a_p->minPriority = arg.min_pri;
310 a_p->maxPriority = arg.max_pri;375 a_p->maxPriority = arg.max_pri;
376#endif
311 a_p->usePolicy = arg.ok;377 a_p->usePolicy = arg.ok;
312}378}
313#endif379#endif
@@ -315,18 +381,15 @@
315381
316static void once(void)382static void once(void)
317{383{
318 epicsThreadOSD *pthreadInfo;
319 int status;384 int status;
320
321 pthread_key_create(&getpthreadInfo,0);
322 status = pthread_mutex_init(&onceLock,0);385 status = pthread_mutex_init(&onceLock,0);
323 checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit");386 checkStatusOnceQuit(status,"pthread_mutex_init","once");
324 status = pthread_mutex_init(&listLock,0);387 status = pthread_mutex_init(&listLock,0);
325 checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit");388 checkStatusOnceQuit(status,"pthread_mutex_init","once");
326 pcommonAttr = calloc(1,sizeof(commonAttr));389 pcommonAttr = calloc(1,sizeof(commonAttr));
327 if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","epicsThreadInit");390 if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","once");
328 status = pthread_attr_init(&pcommonAttr->attr);391 status = pthread_attr_init(&pcommonAttr->attr);
329 checkStatusOnceQuit(status,"pthread_attr_init","epicsThreadInit");392 checkStatusOnceQuit(status,"pthread_attr_init","once");
330 status = pthread_attr_setdetachstate(393 status = pthread_attr_setdetachstate(
331 &pcommonAttr->attr, PTHREAD_CREATE_DETACHED);394 &pcommonAttr->attr, PTHREAD_CREATE_DETACHED);
332 checkStatusOnce(status,"pthread_attr_setdetachstate");395 checkStatusOnce(status,"pthread_attr_setdetachstate");
@@ -358,52 +421,77 @@
358 }421 }
359422
360 if (errVerbose) {423 if (errVerbose) {
424#if defined(__rtems__)
425 printk("LRT: min priority: %d max priority %d\n",
426 pcommonAttr->minPriority, pcommonAttr->maxPriority);
427#else
361 fprintf(stderr, "LRT: min priority: %d max priority %d\n",428 fprintf(stderr, "LRT: min priority: %d max priority %d\n",
362 pcommonAttr->minPriority, pcommonAttr->maxPriority);429 pcommonAttr->minPriority, pcommonAttr->maxPriority);
430#endif
363 }431 }
364432
365#else433#else
366 if(errVerbose) fprintf(stderr,"task priorities are not implemented\n");434 if(errVerbose) {
435#if defined(__rtems__)
436 printk("task priorities are not implemented\n");
437#else
438 fprintf(stderr,"task priorities are not implemented\n");
439#endif
440}
367#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */441#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
442 int policy;
443 struct sched_param param;
444 status = pthread_getschedparam(pthread_self(), &policy, &param);
445 checkStatusOnce(status, "pthread_getschedparam failed");
446// param.sched_priority is still 2 bug or feature?
447#if defined (__rtems__)
448 param.sched_priority = 191; // iocsh prio
449#endif
450 status = pthread_setschedparam(pthread_self(), policy, &param);
451 checkStatusOnce(status, "pthread_setschedparam failed");
452 status = pthread_getschedparam(pthread_self(), &policy, &param);
453 checkStatusOnce(status, "pthread_getschedparam failed");
368454
369 pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0);455#if defined (__rtems__)
370 assert(pthreadInfo!=NULL);456 tls_pthreadInfo = init_threadInfo("_main_",param.sched_priority-100,epicsThreadGetStackSize(epicsThreadStackSmall),0,0);
371 status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);457#else
372 checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit");458 tls_pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0);
459#endif
460 assert(tls_pthreadInfo!=NULL);
461 tls_pthreadInfo->tid = pthread_self();
373 status = mutexLock(&listLock);462 status = mutexLock(&listLock);
374 checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit");463 checkStatusOnceQuit(status,"pthread_mutex_lock","once");
375 ellAdd(&pthreadList,&pthreadInfo->node);464 ellAdd(&pthreadList,&tls_pthreadInfo->node);
376 pthreadInfo->isOnThreadList = 1;465 tls_pthreadInfo->isOnThreadList = 1;
377 status = pthread_mutex_unlock(&listLock);466 status = pthread_mutex_unlock(&listLock);
378 checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit");467 checkStatusOnceQuit(status,"pthread_mutex_unlock","once");
379 status = atexit(epicsExitCallAtExits);468 status = atexit(epicsExitCallAtExits);
380 checkStatusOnce(status,"atexit");469 checkStatusOnce(status,"atexit");
381 osdThreadHooksRunMain(pthreadInfo);470 osdThreadHooksRunMain(tls_pthreadInfo);
382 epicsThreadOnceCalled = 1;471 epicsThreadInitOnceCalled = 1;
383}472}
384473
385static void * start_routine(void *arg)474static void * start_routine(void *arg)
386{475{
387 epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg;
388 int status;476 int status;
389 sigset_t blockAllSig;477 sigset_t blockAllSig;
390478
479 tls_pthreadInfo = (epicsThreadOSD *)arg;
480
391 sigfillset(&blockAllSig);481 sigfillset(&blockAllSig);
392 pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL);482 pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL);
393 status = pthread_setspecific(getpthreadInfo,arg);
394 checkStatusQuit(status,"pthread_setspecific","start_routine");
395 status = mutexLock(&listLock);483 status = mutexLock(&listLock);
396 checkStatusQuit(status,"pthread_mutex_lock","start_routine");484 checkStatusQuit(status,"pthread_mutex_lock","start_routine");
397 ellAdd(&pthreadList,&pthreadInfo->node);485 ellAdd(&pthreadList,&tls_pthreadInfo->node);
398 pthreadInfo->isOnThreadList = 1;486 tls_pthreadInfo->isOnThreadList = 1;
399 status = pthread_mutex_unlock(&listLock);487 status = pthread_mutex_unlock(&listLock);
400 checkStatusQuit(status,"pthread_mutex_unlock","start_routine");488 checkStatusQuit(status,"pthread_mutex_unlock","start_routine");
401 osdThreadHooksRun(pthreadInfo);489 osdThreadHooksRun(tls_pthreadInfo);
402490
403 (*pthreadInfo->createFunc)(pthreadInfo->createArg);491 (*tls_pthreadInfo->createFunc)(tls_pthreadInfo->createArg);
404492
405 epicsExitCallAtThreadExits ();493 epicsExitCallAtThreadExits ();
406 free_threadInfo(pthreadInfo);494 free_threadInfo(tls_pthreadInfo);
407 return(0);495 return(0);
408}496}
409497
@@ -417,6 +505,9 @@
417epicsShareFunc505epicsShareFunc
418void epicsThreadRealtimeLock(void)506void epicsThreadRealtimeLock(void)
419{507{
508#if !defined(__rtems__)
509/* RTEMS defines _POSIX_MEMLOCK to 1 in features.h even if it is a non swaping OS and
510 mlockall senseless*/
420#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0511#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0
421 if (pcommonAttr->maxPriority > pcommonAttr->minPriority) {512 if (pcommonAttr->maxPriority > pcommonAttr->minPriority) {
422 int status = mlockall(MCL_CURRENT | MCL_FUTURE);513 int status = mlockall(MCL_CURRENT | MCL_FUTURE);
@@ -424,10 +515,11 @@
424 if (status) {515 if (status) {
425 fprintf(stderr, "epicsThreadRealtimeLock "516 fprintf(stderr, "epicsThreadRealtimeLock "
426 "Warning: Unable to lock the virtual address space.\n"517 "Warning: Unable to lock the virtual address space.\n"
427 "VM page faults may harm real-time performance.\n");518 "VM page fautls may harm real-time performance.\n");
428 }519 }
429 }520 }
430#endif521#endif
522#endif /* not defined __rtems__ */
431}523}
432524
433epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass)525epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass)
@@ -435,7 +527,11 @@
435#if defined (OSITHREAD_USE_DEFAULT_STACK)527#if defined (OSITHREAD_USE_DEFAULT_STACK)
436 return 0;528 return 0;
437#elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0529#elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0
530#if defined (__rtems)
531 #define STACK_SIZE(f) (f * 0x1000 * sizeof(void *))
532#else
438 #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *))533 #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *))
534#endif
439 static const unsigned stackSizeTable[epicsThreadStackBig+1] = {535 static const unsigned stackSizeTable[epicsThreadStackBig+1] = {
440 STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4)536 STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4)
441 };537 };
@@ -463,37 +559,33 @@
463559
464 epicsThreadInit();560 epicsThreadInit();
465 status = mutexLock(&onceLock);561 status = mutexLock(&onceLock);
466 if(status) {562 checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce");
467 fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n",
468 strerror(status));
469 exit(-1);
470 }
471563
472 if (*id != EPICS_THREAD_ONCE_DONE) {564 if (*id != EPICS_THREAD_ONCE_DONE) {
473 if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */565 if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */
474 *id = epicsThreadGetIdSelf(); /* mark active */566 *id = epicsThreadGetIdSelf(); /* mark active */
475 status = pthread_mutex_unlock(&onceLock);567 status = pthread_mutex_unlock(&onceLock);
476 checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");568 checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
477 func(arg);569 func(arg);
478 status = mutexLock(&onceLock);570 status = mutexLock(&onceLock);
479 checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce");571 checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce");
480 *id = EPICS_THREAD_ONCE_DONE; /* mark done */572 *id = EPICS_THREAD_ONCE_DONE; /* mark done */
481 } else if (*id == epicsThreadGetIdSelf()) {573 } else if (*id == epicsThreadGetIdSelf()) {
482 status = pthread_mutex_unlock(&onceLock);574 status = pthread_mutex_unlock(&onceLock);
483 checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");575 checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
484 cantProceed("Recursive epicsThreadOnce() initialization\n");576 cantProceed("Recursive epicsThreadOnce() initialization\n");
485 } else577 } else
486 while (*id != EPICS_THREAD_ONCE_DONE) {578 while (*id != EPICS_THREAD_ONCE_DONE) {
487 /* Another thread is in the above func(arg) call. */579 /* Another thread is in the above func(arg) call. */
488 status = pthread_mutex_unlock(&onceLock);580 status = pthread_mutex_unlock(&onceLock);
489 checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");581 checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
490 epicsThreadSleep(epicsThreadSleepQuantum());582 epicsThreadSleep(epicsThreadSleepQuantum());
491 status = mutexLock(&onceLock);583 status = mutexLock(&onceLock);
492 checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce");584 checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce");
493 }585 }
494 }586 }
495 status = pthread_mutex_unlock(&onceLock);587 status = pthread_mutex_unlock(&onceLock);
496 checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce");588 checkStatusOnceQuit(status,"pthread_mutex_unlock","epicsThreadOnce");
497}589}
498590
499epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name,591epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name,
@@ -530,6 +622,7 @@
530 return 0;622 return 0;
531 }623 }
532 status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL);624 status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL);
625//? StatusOnce? because of errlog daemon ???
533 checkStatusOnce(status,"pthread_sigmask");626 checkStatusOnce(status,"pthread_sigmask");
534 return(pthreadInfo);627 return(pthreadInfo);
535}628}
@@ -537,80 +630,64 @@
537/*630/*
538 * Create dummy context for threads not created by epicsThreadCreate().631 * Create dummy context for threads not created by epicsThreadCreate().
539 */632 */
540static epicsThreadOSD *createImplicit(void)633static void createImplicit(void)
541{634{
542 epicsThreadOSD *pthreadInfo;
543 char name[64];635 char name[64];
544 pthread_t tid;636 pthread_t tid;
545 int status;
546637
547 tid = pthread_self();638 tid = pthread_self();
548 sprintf(name, "non-EPICS_%ld", (long)tid);639 sprintf(name, "non-EPICS_%ld", (long)tid);
549 pthreadInfo = create_threadInfo(name);640 tls_pthreadInfo = create_threadInfo(name);
550 assert(pthreadInfo);641 assert(tls_pthreadInfo);
551 pthreadInfo->tid = tid;642 tls_pthreadInfo->tid = tid;
552 pthreadInfo->osiPriority = 0;643 tls_pthreadInfo->osiPriority = 0;
553644
554#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0645#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
555 {646 {
556 struct sched_param param;647 struct sched_param param;
557 int policy;648 int policy;
558 if(pthread_getschedparam(tid,&policy,&param) == 0)649 if(pthread_getschedparam(tid,&policy,&param) == 0)
559 pthreadInfo->osiPriority =650 tls_pthreadInfo->osiPriority =
560 (param.sched_priority - pcommonAttr->minPriority) * 100.0 /651 (param.sched_priority - pcommonAttr->minPriority) * 100.0 /
561 (pcommonAttr->maxPriority - pcommonAttr->minPriority + 1);652 (pcommonAttr->maxPriority - pcommonAttr->minPriority);
562 }653 }
563#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */654#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
564
565 status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
566 checkStatus(status,"pthread_setspecific createImplicit");
567 if(status){
568 free_threadInfo(pthreadInfo);
569 return NULL;
570 }
571 return pthreadInfo;
572}655}
573656
574657
575epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void)658epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void)
576{659{
577 epicsThreadOSD *pthreadInfo;
578
579 epicsThreadInit();660 epicsThreadInit();
580 pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);661 assert(tls_pthreadInfo);
581 if(pthreadInfo==NULL)662 tls_pthreadInfo->isSuspended = 1;
582 pthreadInfo = createImplicit();663 epicsEventWait(tls_pthreadInfo->suspendEvent);
583 pthreadInfo->isSuspended = 1;
584 epicsEventWait(pthreadInfo->suspendEvent);
585}664}
586665
587epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo)666epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo)
588{667{
589 assert(epicsThreadOnceCalled);668 assert(epicsThreadInitOnceCalled);
590 pthreadInfo->isSuspended = 0;669 pthreadInfo->isSuspended = 0;
591 epicsEventSignal(pthreadInfo->suspendEvent);670 epicsEventSignal(pthreadInfo->suspendEvent);
592}671}
593672
594epicsShareFunc void epicsShareAPI epicsThreadExitMain(void)673epicsShareFunc void epicsShareAPI epicsThreadExitMain(void)
595{674{
596 epicsThreadOSD *pthreadInfo;
597675
598 epicsThreadInit();676 epicsThreadInit();
599 pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);677 if(tls_pthreadInfo==NULL)
600 if(pthreadInfo==NULL)678 createImplicit();
601 pthreadInfo = createImplicit();679 if(tls_pthreadInfo->createFunc) {
602 if(pthreadInfo->createFunc) {
603 errlogPrintf("called from non-main thread\n");680 errlogPrintf("called from non-main thread\n");
604 cantProceed("epicsThreadExitMain");681 cantProceed("epicsThreadExitMain");
605 }682 }
606 else {683 else {
607 free_threadInfo(pthreadInfo);684 free_threadInfo(tls_pthreadInfo);
608 pthread_exit(0);685 pthread_exit(0);
609 }686 }
610}687}
611688
612689
613epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(epicsThreadId pthreadInfo)690epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(epicsThreadId pthreadInfo)
614{691{
615 assert(epicsThreadOnceCalled);692 assert(epicsThreadInitOnceCalled);
616 return(pthreadInfo->osiPriority);693 return(pthreadInfo->osiPriority);
617}694}
618695
@@ -626,7 +703,7 @@
626 int status;703 int status;
627#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */704#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
628705
629 assert(epicsThreadOnceCalled);706 assert(epicsThreadInitOnceCalled);
630 assert(pthreadInfo);707 assert(pthreadInfo);
631 if(!pthreadInfo->isEpicsThread) {708 if(!pthreadInfo->isEpicsThread) {
632 fprintf(stderr,"epicsThreadSetPriority called by non epics thread\n");709 fprintf(stderr,"epicsThreadSetPriority called by non epics thread\n");
@@ -637,7 +714,7 @@
637714
638#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0715#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
639 if(!pcommonAttr->usePolicy) return;716 if(!pcommonAttr->usePolicy) return;
640 pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo);717 tls_pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo);
641 status = pthread_attr_setschedparam(718 status = pthread_attr_setschedparam(
642 &pthreadInfo->attr,&pthreadInfo->schedParam);719 &pthreadInfo->attr,&pthreadInfo->schedParam);
643 if(errVerbose) checkStatus(status,"pthread_attr_setschedparam");720 if(errVerbose) checkStatus(status,"pthread_attr_setschedparam");
@@ -685,14 +762,14 @@
685762
686763
687epicsShareFunc int epicsShareAPI epicsThreadIsEqual(epicsThreadId p1, epicsThreadId p2)764epicsShareFunc int epicsShareAPI epicsThreadIsEqual(epicsThreadId p1, epicsThreadId p2)
688{765{
689 assert(epicsThreadOnceCalled);766 assert(epicsThreadInitOnceCalled);
690 assert(p1);767 assert(p1);
691 assert(p2);768 assert(p2);
692 return(pthread_equal(p1->tid,p2->tid));769 return(pthread_equal(p1->tid,p2->tid));
693}770}
694771
695epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId pthreadInfo) {772epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId pthreadInfo) {
696 assert(epicsThreadOnceCalled);773 assert(epicsThreadInitOnceCalled);
697 assert(pthreadInfo);774 assert(pthreadInfo);
698 return(pthreadInfo->isSuspended ? 1 : 0);775 return(pthreadInfo->isSuspended ? 1 : 0);
699}776}
@@ -718,14 +795,11 @@
718}795}
719796
720epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) {797epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) {
721 epicsThreadOSD *pthreadInfo;
722798
723 epicsThreadInit();799 epicsThreadInit();
724 pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);800 if(tls_pthreadInfo==NULL)
725 if(pthreadInfo==NULL)801 createImplicit();
726 pthreadInfo = createImplicit();802 return(tls_pthreadInfo);
727 assert ( pthreadInfo );
728 return(pthreadInfo);
729}803}
730804
731epicsShareFunc pthread_t epicsThreadGetPosixThreadId ( epicsThreadId threadId )805epicsShareFunc pthread_t epicsThreadGetPosixThreadId ( epicsThreadId threadId )
@@ -737,7 +811,7 @@
737 epicsThreadOSD *pthreadInfo;811 epicsThreadOSD *pthreadInfo;
738 int status;812 int status;
739813
740 assert(epicsThreadOnceCalled);814 assert(epicsThreadInitOnceCalled);
741 status = mutexLock(&listLock);815 status = mutexLock(&listLock);
742 checkStatus(status,"pthread_mutex_lock epicsThreadGetId");816 checkStatus(status,"pthread_mutex_lock epicsThreadGetId");
743 if(status)817 if(status)
@@ -755,18 +829,16 @@
755829
756epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf()830epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf()
757{831{
758 epicsThreadOSD *pthreadInfo;
759832
760 epicsThreadInit();833 epicsThreadInit();
761 pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);834 if(tls_pthreadInfo==NULL)
762 if(pthreadInfo==NULL)835 createImplicit();
763 pthreadInfo = createImplicit();836 return(tls_pthreadInfo->name);
764 return(pthreadInfo->name);
765}837}
766838
767epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size)839epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size)
768{840{
769 assert(epicsThreadOnceCalled);841 assert(epicsThreadInitOnceCalled);
770 strncpy(name, pthreadInfo->name, size-1);842 strncpy(name, pthreadInfo->name, size-1);
771 name[size-1] = '\0';843 name[size-1] = '\0';
772}844}
@@ -822,7 +894,7 @@
822 return;894 return;
823 }895 }
824 status = mutexLock(&listLock);896 status = mutexLock(&listLock);
825 checkStatus(status,"pthread_mutex_lock epicsThreadShowAll");897 checkStatus(status,"pthread_mutex_lock epicsThreadShow");
826 if(status)898 if(status)
827 return;899 return;
828 pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);900 pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
@@ -835,7 +907,7 @@
835 pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);907 pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
836 }908 }
837 status = pthread_mutex_unlock(&listLock);909 status = pthread_mutex_unlock(&listLock);
838 checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll");910 checkStatus(status,"pthread_mutex_unlock epicsThreadShow");
839 if(status) return;911 if(status) return;
840 if (!found)912 if (!found)
841 printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);913 printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);
@@ -851,7 +923,8 @@
851 if(!key)923 if(!key)
852 return NULL;924 return NULL;
853 status = pthread_key_create(key,0);925 status = pthread_key_create(key,0);
854 checkStatus(status,"pthread_key_create epicsThreadPrivateCreate");926//used from errlogInit
927 checkStatusOnce(status,"pthread_key_create epicsThreadPrivateCreate");
855 if(status)928 if(status)
856 return NULL;929 return NULL;
857 return((epicsThreadPrivateId)key);930 return((epicsThreadPrivateId)key);
@@ -862,7 +935,7 @@
862 pthread_key_t *key = (pthread_key_t *)id;935 pthread_key_t *key = (pthread_key_t *)id;
863 int status;936 int status;
864937
865 assert(epicsThreadOnceCalled);938 assert(epicsThreadInitOnceCalled);
866 status = pthread_key_delete(*key);939 status = pthread_key_delete(*key);
867 checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete");940 checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete");
868 free((void *)key);941 free((void *)key);
@@ -873,7 +946,7 @@
873 pthread_key_t *key = (pthread_key_t *)id;946 pthread_key_t *key = (pthread_key_t *)id;
874 int status;947 int status;
875948
876 assert(epicsThreadOnceCalled);949 assert(epicsThreadInitOnceCalled);
877 if(errVerbose && !value)950 if(errVerbose && !value)
878 errlogPrintf("epicsThreadPrivateSet: setting value of 0\n");951 errlogPrintf("epicsThreadPrivateSet: setting value of 0\n");
879 status = pthread_setspecific(*key,value);952 status = pthread_setspecific(*key,value);
@@ -884,7 +957,7 @@
884{957{
885 pthread_key_t *key = (pthread_key_t *)id;958 pthread_key_t *key = (pthread_key_t *)id;
886959
887 assert(epicsThreadOnceCalled);960 assert(epicsThreadInitOnceCalled);
888 return pthread_getspecific(*key);961 return pthread_getspecific(*key);
889}962}
890963
891964
=== modified file 'src/libCom/osi/os/posix/osdThreadExtra.c'
--- src/libCom/osi/os/posix/osdThreadExtra.c 2013-03-27 09:56:34 +0000
+++ src/libCom/osi/os/posix/osdThreadExtra.c 2017-05-01 18:36:52 +0000
@@ -24,22 +24,26 @@
24{24{
25 if(!pthreadInfo) {25 if(!pthreadInfo) {
26 fprintf(epicsGetStdout()," NAME EPICS ID "26 fprintf(epicsGetStdout()," NAME EPICS ID "
27 "PTHREAD ID OSIPRI OSSPRI STATE\n");27 "PTHREAD ID OSIPRI OSSPRI STATE STACKSIZE\n");
28 } else {28 } else {
29 struct sched_param param;29 struct sched_param param;
30 int policy;30 int policy;
31 int priority = 0;31 int priority = 0;
32 size_t stackSize = 0;
3233
33 if(pthreadInfo->tid) {34 if(pthreadInfo->tid) {
34 int status;35 int status;
35 status = pthread_getschedparam(pthreadInfo->tid,&policy,&param);36 status = pthread_getschedparam(pthreadInfo->tid,&policy,&param);
36 if(!status) priority = param.sched_priority;37 if(!status) priority = param.sched_priority;
38 status = pthread_attr_getstacksize( &pthreadInfo->attr,&stackSize);
39 if(status) stackSize = 0;
37 }40 }
38 fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n",41 fprintf(epicsGetStdout(),"%16.16s %14p 0x%08X %3d%8d %8.8s %9d\n",
39 pthreadInfo->name,(void *)42 pthreadInfo->name,(void *)
40 pthreadInfo,(unsigned long)pthreadInfo->tid,43 pthreadInfo,(unsigned long)pthreadInfo->tid,
41 pthreadInfo->osiPriority,priority,44 pthreadInfo->osiPriority,priority,
42 pthreadInfo->isSuspended?"SUSPEND":"OK");45 pthreadInfo->isSuspended?"SUSPEND":"OK",
46 stackSize);
43 }47 }
44}48}
4549
4650
=== modified file 'src/libCom/osi/osiSock.c'
--- src/libCom/osi/osiSock.c 2016-05-22 03:43:09 +0000
+++ src/libCom/osi/osiSock.c 2017-05-01 18:36:52 +0000
@@ -3,6 +3,8 @@
3* National Laboratory.3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.5* Operator of Los Alamos National Laboratory.
6* Copyright (c) 2015 Brookhaven Science Associates as Operator of
7* Brookhaven National Lab.
6* EPICS BASE Versions 3.13.78* EPICS BASE Versions 3.13.7
7* and higher are distributed subject to a Software License Agreement found9* and higher are distributed subject to a Software License Agreement found
8* in file LICENSE that is included with this distribution. 10* in file LICENSE that is included with this distribution.
@@ -15,12 +17,15 @@
15 */17 */
1618
17#include <stdio.h>19#include <stdio.h>
20#include <stdlib.h>
18#include <string.h>21#include <string.h>
1922
20#define epicsExportSharedSymbols23#define epicsExportSharedSymbols
21#include "epicsAssert.h"24#include "epicsAssert.h"
22#include "epicsSignal.h"25#include "epicsSignal.h"
23#include "epicsStdio.h"26#include "epicsStdio.h"
27#include "dbDefs.h"
28#include "errlog.h"
24#include "osiSock.h"29#include "osiSock.h"
2530
26#define nDigitsDottedIP 4u31#define nDigitsDottedIP 4u
@@ -187,3 +192,155 @@
187 }192 }
188}193}
189194
195epicsShareFunc void osiFreeInterfaceInfo(osiInterfaceInfo *pinfo)
196{
197 free(pinfo);
198}
199
200/*
201 * osiSockDiscoverBroadcastAddresses ()
202 */
203epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
204 (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr)
205{
206 ELLLIST infolist = ELLLIST_INIT;
207 ELLNODE *cur;
208
209 if ( pMatchAddr->sa.sa_family == AF_INET ) {
210 if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {
211 osiSockAddrNode *pNewNode = calloc (1, sizeof (*pNewNode) );
212 if ( pNewNode == NULL ) {
213 errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
214 return;
215 }
216 pNewNode->addr.ia.sin_family = AF_INET;
217 pNewNode->addr.ia.sin_port = htons ( 0 );
218 pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
219 ellAdd ( pList, &pNewNode->node );
220 return;
221 }
222 } else if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) {
223 errlogPrintf("osiSockDiscoverBroadcastAddresses(): match address must be AF_INET or AF_UNSPEC.");
224 return;
225 }
226
227 if(osiGetInterfaceInfo(&infolist, 0)) {
228 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration\n");
229 return;
230 }
231
232 if(ellCount(&infolist)==0) {
233 errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no network interfaces found\n");
234 }
235
236 for(cur=ellFirst(&infolist); cur; cur=ellNext(cur))
237 {
238 osiSockAddrNode *pNewNode;
239 osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node);
240
241 if(info->address.sa.sa_family!=AF_INET || !info->broadcast)
242 continue;
243
244 pNewNode = calloc(1, sizeof(*pNewNode));
245 if(!pNewNode)
246 break;
247
248 if(pMatchAddr->ia.sin_family==AF_INET &&
249 pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY) &&
250 pMatchAddr->ia.sin_addr.s_addr != info->address.ia.sin_addr.s_addr)
251 {
252 free(pNewNode);
253 continue;
254 }
255
256 pNewNode->addr.ia = info->endpoint.ia;
257
258 ellAdd(pList, &pNewNode->node);
259 }
260
261 ellFree2(&infolist, (FREEFUNC)osiFreeInterfaceInfo);
262}
263
264/*
265 * osiLocalAddr ()
266 */
267epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket)
268{
269 static osiSockAddr result;
270 static int init;
271
272 if(!init) {
273 ELLLIST infolist = ELLLIST_INIT;
274 ELLNODE *cur;
275 osiSockAddr addr;
276 int found = 0;
277
278 memset ( (void *) &addr, '\0', sizeof ( addr ) );
279 addr.sa.sa_family = AF_UNSPEC;
280
281 if(osiGetInterfaceInfo(&infolist, 0)) {
282 errlogPrintf ("osiLocalAddr(): unable to fetch network interface configuration\n");
283
284 } else {
285
286 for(cur=ellFirst(&infolist); cur; cur=ellNext(cur))
287 {
288 osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node);
289
290 if(info->address.sa.sa_family!=AF_INET || !info->up || info->loopback)
291 continue;
292
293 addr.ia = info->address.ia;
294 found = 1;
295 }
296
297 ellFree(&infolist);
298 }
299
300 if(!found) {
301 addr.ia.sin_family = AF_INET;
302 addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
303 addr.ia.sin_port = 0;
304 }
305
306 result = addr;
307 init = 1;
308 }
309
310 return result;
311}
312
313epicsShareFunc
314int osiGetInterfaceInfoSingle(const osiSockAddr *paddr, osiInterfaceInfo **presult, unsigned flags)
315{
316 ELLLIST infolist = ELLLIST_INIT;
317 ELLNODE *cur;
318 int found = 0;
319
320 if(paddr->sa.sa_family!=AF_INET)
321 return -1;
322
323 if(osiGetInterfaceInfo(&infolist, flags)) {
324 errlogPrintf ("osiGetInterfaceInfoSingle(): unable to fetch network interface configuration\n");
325 return -1;
326 }
327
328 for(cur=ellFirst(&infolist); cur; cur=ellNext(cur))
329 {
330 osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node);
331
332 if(info->address.ia.sin_addr.s_addr==paddr->ia.sin_addr.s_addr) {
333 if(presult) {
334 *presult = info;
335 ellDelete(&infolist, cur);
336 // caller now responsible to free
337 }
338 found = 1;
339 break;
340 }
341 }
342
343 ellFree2(&infolist, (FREEFUNC)osiFreeInterfaceInfo);
344 return found ? 0 : -1;
345}
346
190347
=== modified file 'src/libCom/osi/osiSock.h'
--- src/libCom/osi/osiSock.h 2016-05-22 03:43:09 +0000
+++ src/libCom/osi/osiSock.h 2017-05-01 18:36:52 +0000
@@ -155,6 +155,17 @@
155 osiSockAddr addr;155 osiSockAddr addr;
156} osiSockAddrNode;156} osiSockAddrNode;
157157
158typedef struct {
159 ELLNODE node;
160 unsigned int up:1;
161 unsigned int loopback:1;
162 unsigned int broadcast:1;
163 unsigned int multicast:1;
164 unsigned int point2point:1;
165 osiSockAddr address, netmask;
166 osiSockAddr endpoint; //!< broadcast or p2p destination address
167} osiInterfaceInfo;
168
158/*169/*
159 * sockAddrAreIdentical() 170 * sockAddrAreIdentical()
160 * (returns true if addresses are identical)171 * (returns true if addresses are identical)
@@ -162,6 +173,32 @@
162epicsShareFunc int epicsShareAPI sockAddrAreIdentical 173epicsShareFunc int epicsShareAPI sockAddrAreIdentical
163 ( const osiSockAddr * plhs, const osiSockAddr * prhs );174 ( const osiSockAddr * plhs, const osiSockAddr * prhs );
164175
176/* Fills the provided list with osiInterfaceInfo nodes
177 * describing the network interfaces of the host machine
178 * at the time it is called (may change later).
179 *
180 * Caller is responsible for freeing elements in the provided list with
181 * osiFreeInterfaceInfo(). This may be used individually, or in conjuction
182 * with ellFree2().
183 *
184 * flags provides for forward compatibility (eg. ipv6) and should be zero.
185 */
186epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags);
187
188/* Find the interface information to the interface having address 'paddr'.
189 * Fills in the provided 'presults' if non-NULL, in which case the caller
190 * must free with osiFreeInterfaceInfo().
191 *
192 * Returns zero on success.
193 *
194 * flags provides for forward compatibility (eg. ipv6) and should be zero.
195 */
196epicsShareFunc
197int osiGetInterfaceInfoSingle(const osiSockAddr *paddr, osiInterfaceInfo **presult, unsigned flags);
198
199
200epicsShareFunc void osiFreeInterfaceInfo(osiInterfaceInfo *pinfo);
201
165/*202/*
166 * osiSockDiscoverBroadcastAddresses ()203 * osiSockDiscoverBroadcastAddresses ()
167 * Returns the broadcast addresses of each network interface found.204 * Returns the broadcast addresses of each network interface found.
168205
=== modified file 'src/libCom/test/Makefile'
--- src/libCom/test/Makefile 2016-07-22 04:37:54 +0000
+++ src/libCom/test/Makefile 2017-05-01 18:36:52 +0000
@@ -86,6 +86,13 @@
86testHarness_SRCS += epicsSockResolveTest.c86testHarness_SRCS += epicsSockResolveTest.c
87TESTS += epicsSockResolveTest87TESTS += epicsSockResolveTest
8888
89TESTPROD_HOST += epicsNetIntfTest
90epicsNetIntfTest_SRCS += epicsNetIntfTest.c
91epicsNetIntfTest_SYS_LIBS_solaris = socket
92epicsNetIntfTest_SYS_LIBS_WIN32 = ws2_32 user32
93testHarness_SRCS += epicsNetIntfTest.c
94TESTS += epicsNetIntfTest
95
89TESTPROD_HOST += epicsStringTest96TESTPROD_HOST += epicsStringTest
90epicsStringTest_SRCS += epicsStringTest.c97epicsStringTest_SRCS += epicsStringTest.c
91testHarness_SRCS += epicsStringTest.c98testHarness_SRCS += epicsStringTest.c
9299
=== modified file 'src/libCom/test/epicsMessageQueueTest.cpp'
--- src/libCom/test/epicsMessageQueueTest.cpp 2016-05-22 12:38:18 +0000
+++ src/libCom/test/epicsMessageQueueTest.cpp 2017-05-01 18:36:52 +0000
@@ -151,7 +151,7 @@
151 testOk(q1->pending() == i, "q1->pending() == %d", i);151 testOk(q1->pending() == i, "q1->pending() == %d", i);
152 }152 }
153 testOk1(q1->pending() == 4);153 testOk1(q1->pending() == 4);
154154
155 want = 0;155 want = 0;
156 len = q1->receive(cbuf, sizeof cbuf);156 len = q1->receive(cbuf, sizeof cbuf);
157 testOk1(q1->pending() == 3);157 testOk1(q1->pending() == 3);
158158
=== added file 'src/libCom/test/epicsNetIntfTest.c'
--- src/libCom/test/epicsNetIntfTest.c 1970-01-01 00:00:00 +0000
+++ src/libCom/test/epicsNetIntfTest.c 2017-05-01 18:36:52 +0000
@@ -0,0 +1,220 @@
1/*************************************************************************\
2* Copyright (c) 2015 Brookhaven Science Associates as Operator of
3* Brookhaven National Lab.
4* EPICS BASE is distributed subject to a Software License Agreement found
5* in file LICENSE that is included with this distribution.
6\*************************************************************************/
7
8#include <stdlib.h>
9
10#include "dbDefs.h"
11#include "osiSock.h"
12#include "epicsTypes.h"
13
14#include "epicsUnitTest.h"
15#include "testMain.h"
16
17static
18void testIfInfo(void)
19{
20 int foundlo = 0, bcastok = 1;
21 ELLLIST iflist = ELLLIST_INIT;
22 ELLNODE *cur;
23 testDiag("Check interface introspection info");
24
25#ifdef USE_IFADDRS
26 testDiag("Using getifaddrs() method");
27#else
28 testDiag("Using OS default method");
29#endif
30
31 testOk1(osiGetInterfaceInfo(&iflist, 0)==0);
32
33 testOk(ellCount(&iflist)>0, "interface count %d", ellCount(&iflist));
34
35 for(cur=ellFirst(&iflist); cur; cur=ellNext(cur))
36 {
37 osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node);
38 char buf[30];
39
40 if(info->loopback) {
41 testOk(info->up, "loopback interface is up");
42 foundlo = 1;
43 }
44
45 if(info->address.sa.sa_family!=AF_INET)
46 continue;
47
48 ipAddrToDottedIP(&info->address.ia, buf, sizeof(buf));
49 testDiag("Address: %s", buf);
50 ipAddrToDottedIP(&info->netmask.ia, buf, sizeof(buf));
51 testDiag("Netmask: %s", buf);
52 if(info->broadcast) {
53 ipAddrToDottedIP(&info->endpoint.ia, buf, sizeof(buf));
54 testDiag("Broadcast: %s", buf);
55 } else if(info->point2point) {
56 ipAddrToDottedIP(&info->endpoint.ia, buf, sizeof(buf));
57 testDiag("Destination: %s", buf);
58 }
59
60 testDiag(" Up: %s", info->up?"Up":"Down");
61 testDiag(" Loopback: %s", info->loopback?"Yes":"No");
62 testDiag(" Broadcast: %s", info->broadcast?"Yes":"No");
63 testDiag(" Multicast: %s", info->multicast?"Yes":"No");
64 testDiag(" Point2Point: %s", info->point2point?"Yes":"No");
65
66 /* check consistency of address, netmask, and broadcast address */
67 if(info->broadcast) {
68 epicsUInt32 addr = ntohl(info->address.ia.sin_addr.s_addr),
69 mask = ntohl(info->netmask.ia.sin_addr.s_addr),
70 bcast = ntohl(info->endpoint.ia.sin_addr.s_addr),
71 bcast2= (addr&mask) | ~mask;
72
73 if(bcast!=bcast2) {
74 struct sockaddr_in addr;
75 addr.sin_family = AF_INET;
76 addr.sin_addr.s_addr = htonl(bcast2);
77 addr.sin_port = 0;
78 ipAddrToDottedIP(&addr, buf, sizeof(buf));
79 testDiag("Warning: expected broadcast address %s", buf);
80 bcastok = 0;
81 }
82 }
83 }
84
85 ellFree2(&iflist, (FREEFUNC)osiFreeInterfaceInfo);
86
87 testOk(foundlo, "Found loopback interface");
88 testOk(bcastok, "Broadcast addresses consistent");
89}
90
91static
92void testBroadcast(void)
93{
94 ELLLIST iflist = ELLLIST_INIT;
95 ELLNODE *cur;
96 SOCKET sock;
97 osiSockAddr match;
98
99 testDiag("Discover broadcast addresses");
100
101 sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
102 if(sock==INVALID_SOCKET)
103 testAbort("Failed to allocate socket");
104
105 match.ia.sin_family = AF_INET;
106 match.ia.sin_addr.s_addr = htonl(INADDR_ANY);
107 match.ia.sin_port = 0;
108
109 osiSockDiscoverBroadcastAddresses(&iflist, sock, &match);
110
111 testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist));
112
113 for(cur=ellFirst(&iflist); cur; cur=ellNext(cur))
114 {
115 osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node);
116 char buf[30];
117
118 ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf));
119 testDiag("Broadcast: %s", buf);
120 }
121
122 ellFree(&iflist);
123
124 testDiag("\"Discover\" loopback address");
125
126 match.ia.sin_family = AF_INET;
127 match.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
128 match.ia.sin_port = 0;
129
130 osiSockDiscoverBroadcastAddresses(&iflist, sock, &match);
131
132 testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist));
133
134 for(cur=ellFirst(&iflist); cur; cur=ellNext(cur))
135 {
136 osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node);
137 char buf[30];
138
139 ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf));
140 testDiag("Broadcast: %s", buf);
141 }
142
143 ellFree(&iflist);
144
145 epicsSocketDestroy(sock);
146}
147
148static
149void testLocal(void)
150{
151 SOCKET sock;
152 osiSockAddr addr;
153 char buf[30];
154
155 testDiag("Discover first local address");
156
157 sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
158 if(sock==INVALID_SOCKET)
159 testAbort("Failed to allocate socket");
160
161 addr = osiLocalAddr(sock);
162
163 testOk1(addr.sa.sa_family==AF_INET);
164
165 ipAddrToDottedIP(&addr.ia, buf, sizeof(buf));
166 testDiag("Address: %s", buf);
167
168 epicsSocketDestroy(sock);
169}
170
171static
172void testBroadcastMatch(void)
173{
174 SOCKET sock;
175 osiSockAddr match;
176 ELLNODE *cur;
177 ELLLIST iflist = ELLLIST_INIT;
178 char buf[30];
179
180 testDiag("Check osiSockDiscoverBroadcastAddresses() w/ matching");
181
182 sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
183 if(sock==INVALID_SOCKET)
184 testAbort("Failed to allocate socket");
185
186 match = osiLocalAddr(sock);
187
188 testOk1(match.sa.sa_family==AF_INET);
189 ipAddrToDottedIP(&match.ia, buf, sizeof(buf));
190 testDiag("Address: %s", buf);
191
192 osiSockDiscoverBroadcastAddresses(&iflist, sock, &match);
193
194 testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist));
195
196 for(cur=ellFirst(&iflist); cur; cur=ellNext(cur))
197 {
198 osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node);
199 char buf[30];
200
201 ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf));
202 testDiag("Broadcast: %s", buf);
203 }
204
205 ellFree(&iflist);
206
207 epicsSocketDestroy(sock);
208}
209
210MAIN(epicsNetIntfTest)
211{
212 testPlan(10);
213 osiSockAttach();
214 testIfInfo();
215 testBroadcast();
216 testLocal();
217 testBroadcastMatch();
218 osiSockRelease();
219 return testDone();
220}
0221
=== modified file 'src/libCom/test/epicsRunLibComTests.c'
--- src/libCom/test/epicsRunLibComTests.c 2016-07-22 04:37:54 +0000
+++ src/libCom/test/epicsRunLibComTests.c 2017-05-01 18:36:52 +0000
@@ -30,6 +30,7 @@
30int epicsMMIOTest(void);30int epicsMMIOTest(void);
31int epicsMutexTest(void);31int epicsMutexTest(void);
32int epicsSockResolveTest(void);32int epicsSockResolveTest(void);
33int epicsNetIntfTest(void);
33int epicsSpinTest(void);34int epicsSpinTest(void);
34int epicsStackTraceTest(void);35int epicsStackTraceTest(void);
35int epicsStdioTest(void);36int epicsStdioTest(void);
@@ -84,6 +85,7 @@
84 runTest(epicsMMIOTest);85 runTest(epicsMMIOTest);
85 runTest(epicsMutexTest);86 runTest(epicsMutexTest);
86 runTest(epicsSockResolveTest);87 runTest(epicsSockResolveTest);
88 runTest(epicsNetIntfTest);
87 runTest(epicsSpinTest);89 runTest(epicsSpinTest);
88 runTest(epicsStackTraceTest);90 runTest(epicsStackTraceTest);
89 runTest(epicsStdioTest);91 runTest(epicsStdioTest);
9092
=== modified file 'src/libCom/test/ringPointerTest.c'
--- src/libCom/test/ringPointerTest.c 2014-11-18 23:30:43 +0000
+++ src/libCom/test/ringPointerTest.c 2017-05-01 18:36:52 +0000
@@ -235,7 +235,6 @@
235MAIN(ringPointerTest)235MAIN(ringPointerTest)
236{236{
237 int prio = epicsThreadGetPrioritySelf();237 int prio = epicsThreadGetPrioritySelf();
238
239 testPlan(37);238 testPlan(37);
240 testSingle();239 testSingle();
241 epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityScanLow);240 epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityScanLow);

Subscribers

People subscribed via source and target branches