Merge lp:~epics-core/epics-base/add-rtems-4.12-api into lp:~epics-core/epics-base/3.16
- add-rtems-4.12-api
- Merge into 3.16
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Johnson | Needs Fixing | ||
Review via email: mp+320503@code.launchpad.net |
Commit message
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_
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.
Andrew Johnson (anj) wrote : | # |
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 nowin 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-beatnikInitial 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
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 epicsThreadShow
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.
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>
git log shows :
commit 6633ba5483732cd
Author: Heinz Junkes <email address hidden>
Date: Thu Oct 5 14:45:19 2017 +0200
add define rtems for SO_REUSEPORT etc
commit 2c707a1deebb107
Author: Heinz Junkes <email address hidden>
Date: Thu Oct 5 09:24:55 2017 +0200
RTEMS4.12
commit fdfd324fa760521
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 epicsThreadShow
>
> 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:/
> Your team EPICS Core Developers is subscribed to branch lp:~epics-core/epics-base/3.16.
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 nowin 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-beatnikInitial 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
1 | === modified file 'Makefile' |
2 | --- Makefile 2016-05-22 12:38:18 +0000 |
3 | +++ Makefile 2017-05-01 18:36:52 +0000 |
4 | @@ -8,6 +8,7 @@ |
5 | #************************************************************************* |
6 | |
7 | TOP = . |
8 | + |
9 | include $(TOP)/configure/CONFIG |
10 | |
11 | # Bootstrap resolution: tools not installed yet |
12 | |
13 | === modified file 'README' |
14 | --- README 2017-02-01 17:57:04 +0000 |
15 | +++ README 2017-05-01 18:36:52 +0000 |
16 | @@ -22,3 +22,24 @@ |
17 | websites etc. is available on the EPICS home page at |
18 | http://www.aps.anl.gov/epics/ |
19 | |
20 | +hpj: |
21 | +In configure/CONFIG_COMMON add RTEMS_XVERSION |
22 | +$(addprefix $(dir)/, os/$(OS_CLASS)$(RTEMS_XVERSION) $(POSIX_$(POSIX)) os/default )) |
23 | + |
24 | +add to $Home/configure/CONFIG_USER |
25 | + |
26 | +#FHI |
27 | +EPICS_SITE_VERSION = fhi |
28 | +# |
29 | +RTEMS_VERSION = 4.12 |
30 | +#to use new libcom osd files |
31 | +RTEMS_XVERSION = 4.12 |
32 | + |
33 | +RTEMS_BASE = /home/h1/RTEMS/rtems-$(RTEMS_VERSION) |
34 | + |
35 | +# Runs on beatnik board (MVME6100) |
36 | +CROSS_COMPILER_TARGET_ARCHS = RTEMS-beatnik |
37 | + |
38 | +ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=rtems_bsdnet_do_bootp |
39 | +ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000 |
40 | + |
41 | |
42 | === modified file 'configure/CONFIG_COMMON' |
43 | --- configure/CONFIG_COMMON 2017-02-01 17:57:04 +0000 |
44 | +++ configure/CONFIG_COMMON 2017-05-01 18:36:52 +0000 |
45 | @@ -4,7 +4,7 @@ |
46 | # Copyright (c) 2002 The Regents of the University of California, as |
47 | # Operator of Los Alamos National Laboratory. |
48 | # EPICS BASE is distributed subject to a Software License Agreement found |
49 | -# in file LICENSE that is included with this distribution. |
50 | +# in file LICENSE that is included with this distribution. |
51 | #************************************************************************* |
52 | # |
53 | # CONFIG_COMMON |
54 | @@ -136,10 +136,11 @@ |
55 | #-------------------------------------------------- |
56 | # vpath directories |
57 | POSIX_YES = os/posix |
58 | +OS_IMPL_DIRS = $(if $(OS_API),os/$(OS_CLASS)-$(OS_API),) os/$(OS_CLASS) |
59 | GENERIC_SRC_DIRS = .. $(SRC_DIRS) |
60 | -OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ |
61 | - $(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default )) |
62 | -CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ |
63 | +OS_SRC_DIRS += . $(foreach dir, $(GENERIC_SRC_DIRS), \ |
64 | + $(addprefix $(dir)/, $(OS_IMPL_DIRS) $(POSIX_$(POSIX)) os/default )) |
65 | +CMPLR_SRC_DIRS += . $(foreach dir, $(GENERIC_SRC_DIRS), \ |
66 | $(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default )) |
67 | ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS) |
68 | |
69 | @@ -261,7 +262,7 @@ |
70 | LIBRARY_SRC_CFLAGS=$($(patsubst $*,SHRLIB,$(findstring $*,$(LIBRARY_SRCS)))_CFLAGS) |
71 | |
72 | #-------------------------------------------------- |
73 | -# prefix, suffix, and ldflags for loadable shared libraries |
74 | +# prefix, suffix, and ldflags for loadable shared libraries |
75 | TARGET_LIB_LDFLAGS=$($(patsubst $*,LOADABLE_,$(findstring $*,$(LOADABLE_LIBRARY)))SHRLIB_LDFLAGS) |
76 | LOADABLE_SHRLIB_PREFIX=$(SHRLIB_PREFIX) |
77 | LOADABLE_SHRLIB_SUFFIX=$(SHRLIB_SUFFIX) |
78 | @@ -459,5 +460,5 @@ |
79 | SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) ) |
80 | SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) ) |
81 | SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) ) |
82 | - |
83 | + |
84 | endif |
85 | |
86 | === modified file 'configure/os/CONFIG.Common.RTEMS' |
87 | --- configure/os/CONFIG.Common.RTEMS 2016-05-22 12:38:18 +0000 |
88 | +++ configure/os/CONFIG.Common.RTEMS 2017-05-01 18:36:52 +0000 |
89 | @@ -91,14 +91,27 @@ |
90 | OS_CLASS = RTEMS |
91 | |
92 | #-------------------------------------------------- |
93 | +# operating system API (src/os/<os_class>-<os_api>) |
94 | +OS_API_4.7 = kernel |
95 | +OS_API_4.8 = kernel |
96 | +OS_API_4.9 = kernel |
97 | +OS_API_4.10 = kernel |
98 | +OS_API_4.11 = $(error RTEMS-4.11 is not currently supported) |
99 | +# Later RTEMS versions will use posix, no need to specify |
100 | +OS_API = $(firstword $(OS_API_$(RTEMS_SERIES)) posix) |
101 | + |
102 | +#-------------------------------------------------- |
103 | # Operating system flags |
104 | OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm |
105 | -OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \ |
106 | + |
107 | +OP_SYS_LDFLAGS_posix += -u POSIX_Init |
108 | +OP_SYS_LDFLAGS_kernel += -u Init \ |
109 | $(PROJECT_RELEASE)/lib/no-dpmem.rel \ |
110 | $(PROJECT_RELEASE)/lib/no-mp.rel \ |
111 | $(PROJECT_RELEASE)/lib/no-part.rel \ |
112 | $(PROJECT_RELEASE)/lib/no-signal.rel \ |
113 | $(PROJECT_RELEASE)/lib/no-rtmon.rel |
114 | +OP_SYS_LDFLAGS += $(CPU_CFLAGS) $(OP_SYS_LDFLAGS_$(OS_API)) |
115 | |
116 | MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib |
117 | |
118 | |
119 | === modified file 'configure/os/CONFIG.Common.RTEMS-beatnik' |
120 | --- configure/os/CONFIG.Common.RTEMS-beatnik 2016-05-21 02:27:03 +0000 |
121 | +++ configure/os/CONFIG.Common.RTEMS-beatnik 2017-05-01 18:36:52 +0000 |
122 | @@ -1,19 +1,20 @@ |
123 | -# |
124 | # CONFIG.Common.RTEMS-beatnik |
125 | +# |
126 | # Author: Dayle Kotturi <dayle@slac.stanford.edu> |
127 | # |
128 | -# All RTEMS targets use the same Makefile fragment |
129 | +# Site-specific adjustments to these settings belong |
130 | +# in the file CONFIG_SITE.Common.RTEMS-beatnik |
131 | # |
132 | + |
133 | EXE = .elf |
134 | RTEMS_TARGET_CPU = powerpc |
135 | GNU_TARGET = powerpc-rtems |
136 | -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL |
137 | + |
138 | +# Flags for *all* beatnik builds |
139 | ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD |
140 | ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 |
141 | ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 |
142 | |
143 | -OP_SYS_LDLIBS += -lbspExt |
144 | - |
145 | MUNCH_SUFFIX = .boot |
146 | MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) |
147 | define MUNCH_CMD |
148 | |
149 | === modified file 'configure/os/CONFIG.Common.RTEMS-mvme3100' |
150 | --- configure/os/CONFIG.Common.RTEMS-mvme3100 2016-05-21 02:27:03 +0000 |
151 | +++ configure/os/CONFIG.Common.RTEMS-mvme3100 2017-05-01 18:36:52 +0000 |
152 | @@ -1,18 +1,20 @@ |
153 | -# |
154 | # CONFIG.Common.RTEMS-mvme3100 |
155 | +# |
156 | # Author: W. Eric Norum <wenorum@lbl.gov> |
157 | # |
158 | -# All RTEMS targets use the same Makefile fragment |
159 | +# Site-specific adjustments to these settings belong |
160 | +# in the file CONFIG_SITE.Common.RTEMS-mvme3100 |
161 | # |
162 | EXE = .elf |
163 | RTEMS_TARGET_CPU = powerpc |
164 | GNU_TARGET = powerpc-rtems |
165 | + |
166 | ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL |
167 | ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD |
168 | ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 |
169 | ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 |
170 | |
171 | -OP_SYS_LDLIBS += -lbspExt |
172 | +# OP_SYS_LDLIBS += -lbspExt |
173 | |
174 | MUNCH_SUFFIX = .boot |
175 | MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) |
176 | |
177 | === modified file 'configure/os/CONFIG_SITE.Common.RTEMS' |
178 | --- configure/os/CONFIG_SITE.Common.RTEMS 2016-05-21 02:27:03 +0000 |
179 | +++ configure/os/CONFIG_SITE.Common.RTEMS 2017-05-01 18:36:52 +0000 |
180 | @@ -3,11 +3,29 @@ |
181 | # Site-specific information for all RTEMS targets |
182 | #------------------------------------------------------- |
183 | |
184 | +# RTEMS Series and Version |
185 | + |
186 | +#RTEMS_SERIES = 4.9 |
187 | +#RTEMS_VERSION = 4.9.2 |
188 | + |
189 | +RTEMS_SERIES = 4.10 |
190 | +RTEMS_VERSION = 4.10.2 |
191 | + |
192 | +#RTEMS_SERIES = 4.12 |
193 | +#RTEMS_VERSION = 4.12 |
194 | + |
195 | + |
196 | # Where to find RTEMS |
197 | # |
198 | +#RTEMS_BASE = /your/path/to/rtems-$(RTEMS_VERSION) |
199 | + |
200 | # APS: |
201 | -RTEMS_VERSION = 4.10.2 |
202 | RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION) |
203 | +#RTEMS_BASE = /local/anj/RTEMS/rtems-4.12 |
204 | + |
205 | +# FHI: |
206 | +#RTEMS_BASE = /home/rtems/RTEMS/rtems-$(RTEMS_VERSION) |
207 | + |
208 | |
209 | # Cross-compile toolchain in $(RTEMS_TOOLS)/bin |
210 | # |
211 | @@ -24,7 +42,7 @@ |
212 | # network configuration you must uncomment and specify your Internet |
213 | # Domain Name here |
214 | # |
215 | -#OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname> |
216 | +OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname> |
217 | |
218 | # Select the command-line-input library to use |
219 | # |
220 | |
221 | === added file 'configure/os/CONFIG_SITE.Common.RTEMS-beatnik' |
222 | --- configure/os/CONFIG_SITE.Common.RTEMS-beatnik 1970-01-01 00:00:00 +0000 |
223 | +++ configure/os/CONFIG_SITE.Common.RTEMS-beatnik 2017-05-01 18:36:52 +0000 |
224 | @@ -0,0 +1,22 @@ |
225 | +# CONFIG_SITE.Common.RTEMS-beatnik |
226 | +# |
227 | +# Site-specific overrides for RTEMS-beatnik target |
228 | +# |
229 | + |
230 | +# Any sites using the beatnik BSP on more than one kind of MVME |
231 | +# board may have difficulties with this release... |
232 | + |
233 | +# These settings are for MVME6100 boards: |
234 | +ARCH_DEP_CFLAGS += -DUSE_ALTIVEC |
235 | + |
236 | +ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=mve1 |
237 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1 |
238 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0 |
239 | + |
240 | +ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=mve2 |
241 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2 |
242 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0 |
243 | + |
244 | +# Uncomment this to link against libbspExt |
245 | +#OP_SYS_LDLIBS += -lbspExt |
246 | + |
247 | |
248 | === added file 'configure/os/CONFIG_SITE.Common.RTEMS-mvme3100' |
249 | --- configure/os/CONFIG_SITE.Common.RTEMS-mvme3100 1970-01-01 00:00:00 +0000 |
250 | +++ configure/os/CONFIG_SITE.Common.RTEMS-mvme3100 2017-05-01 18:36:52 +0000 |
251 | @@ -0,0 +1,19 @@ |
252 | +# CONFIG_SITE.Common.RTEMS-mvme3100 |
253 | +# |
254 | +# Site-specific overrides for RTEMS-mvme3100 target |
255 | +# |
256 | + |
257 | +# Any sites using the beatnik BSP on more than one kind of MVME |
258 | +# board may have difficulties with this release... |
259 | + |
260 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=? |
261 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1 |
262 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0 |
263 | + |
264 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=? |
265 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2 |
266 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0 |
267 | + |
268 | +# Uncomment this to link against libbspExt |
269 | +#OP_SYS_LDLIBS += -lbspExt |
270 | + |
271 | |
272 | === modified file 'configure/os/CONFIG_SITE.Common.RTEMS-pc386' |
273 | --- configure/os/CONFIG_SITE.Common.RTEMS-pc386 2002-08-20 16:18:05 +0000 |
274 | +++ configure/os/CONFIG_SITE.Common.RTEMS-pc386 2017-05-01 18:36:52 +0000 |
275 | @@ -1,3 +1,15 @@ |
276 | +# CONFIG_SITE.Common.RTEMS-pc386 |
277 | # |
278 | # Site-specific overrides for RTEMS-pc386 target |
279 | # |
280 | + |
281 | +# These NICs support run-time probing: |
282 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_1=fxp1 |
283 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_ATTACH_1=rtems_fxp_attach |
284 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_1=192.168.4.1 |
285 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_1=255.255.254.0 |
286 | + |
287 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_NAME_2=ep0 |
288 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_DRIVER_ATTACH_2=rtems_3c509_driver_attach |
289 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_ADDR_2=192.168.6.2 |
290 | +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_IP4_MASK_2=255.255.254.0 |
291 | |
292 | === modified file 'documentation/RELEASE_NOTES.html' |
293 | --- documentation/RELEASE_NOTES.html 2017-02-01 17:57:04 +0000 |
294 | +++ documentation/RELEASE_NOTES.html 2017-05-01 18:36:52 +0000 |
295 | @@ -21,6 +21,35 @@ |
296 | |
297 | --> |
298 | |
299 | +<h3>Support for RTEMS 4.12</h3> |
300 | + |
301 | +<p>The next major release of the RTEMS real-time OS will be version 4.12 which |
302 | +contains many changes including the ability to support SMP systems. The earlier |
303 | +EPICS support for RTEMS made use of various RTEMS-specific kernel APIs which |
304 | +cannot be used on an SMP system, so the changes here required a completely new |
305 | +port to the Posix real-time APIs that RTEMS-4.12 now recommends. A new RTEMS |
306 | +configuration variable RTEMS_SERIES has been added which should be set to the |
307 | +first two components of the OS version number, e.g. 4.9. When this is 4.12 or |
308 | +greater the new libCom/osi/os/RTEMS-posix source files will be used; the older |
309 | +API source files can now be found in libCom/osi/os/RTEMS-kernel, and those which |
310 | +are common to both installations are in libCom/osi/os/RTEMS.</p> |
311 | + |
312 | +<p>Note that EPICS Base can only be built for a single RTEMS version at a time. |
313 | + The RTEMS version number is set in the CONFIG_SITE.Common.RTEMS file and |
314 | + cannot be different for specific targets. This allows different header files |
315 | + to be used and installed for the two different APIs.</p> |
316 | + |
317 | +<h3>Support for multiple APIs in the same OS</h3> |
318 | + |
319 | +<p>The build configuration files for a particular build target may now select |
320 | +between multiple implementations with different OS APIs by setting the GNUmake |
321 | +variable <tt>OS_API</tt>. This changes the search path used for OS-specific |
322 | +source files, inserting a directory <tt>os/$(OS_CLASS)-$(OS_API)</tt> before |
323 | +the existing <tt>os/$(OS_CLASS)</tt> directory. Note though that the include |
324 | +file search path does not change, so OS-specific header files must be able to |
325 | +handle both APIs simultaneously, and their source files should go in the |
326 | +<tt>os/$(OS_CLASS)</tt> directory.</p> |
327 | + |
328 | <h3>Echoless comments in iocsh</h3> |
329 | |
330 | <p>The way comments are parsed by the iocsh interpreter has changed. The |
331 | |
332 | === modified file 'src/ioc/rsrv/caservertask.c' |
333 | --- src/ioc/rsrv/caservertask.c 2016-08-30 14:36:51 +0000 |
334 | +++ src/ioc/rsrv/caservertask.c 2017-05-01 18:36:52 +0000 |
335 | @@ -308,13 +308,17 @@ |
336 | } |
337 | #ifdef IP_ADD_MEMBERSHIP |
338 | { |
339 | +#if defined(__rtems__) |
340 | + char flag = 1; |
341 | +#else |
342 | int flag = 1; |
343 | +#endif |
344 | if (setsockopt(beaconSocket, IPPROTO_IP, IP_MULTICAST_LOOP, |
345 | (char *)&flag, sizeof(flag))<0) { |
346 | char sockErrBuf[64]; |
347 | epicsSocketConvertErrnoToString ( |
348 | sockErrBuf, sizeof ( sockErrBuf ) ); |
349 | - errlogPrintf("rsrv: failed to set mcast loopback\n"); |
350 | + errlogPrintf("rsrv: failed to set mcast loopback (%d:%s)\n", errno, sockErrBuf); |
351 | } |
352 | } |
353 | #endif |
354 | |
355 | === modified file 'src/libCom/RTEMS/Makefile' |
356 | --- src/libCom/RTEMS/Makefile 2011-11-14 23:42:50 +0000 |
357 | +++ src/libCom/RTEMS/Makefile 2017-05-01 18:36:52 +0000 |
358 | @@ -9,6 +9,8 @@ |
359 | TOP=../../.. |
360 | include $(TOP)/configure/CONFIG |
361 | |
362 | +SRC_DIRS += ../$(OS_API) |
363 | + |
364 | INC += epicsRtemsInitHooks.h |
365 | |
366 | rtemsCom_SRCS += rtems_init.c |
367 | |
368 | === added directory 'src/libCom/RTEMS/kernel' |
369 | === renamed file 'src/libCom/RTEMS/rtems_config.c' => 'src/libCom/RTEMS/kernel/rtems_config.c' |
370 | --- src/libCom/RTEMS/rtems_config.c 2016-05-22 12:38:18 +0000 |
371 | +++ src/libCom/RTEMS/kernel/rtems_config.c 2017-05-01 18:36:52 +0000 |
372 | @@ -1,17 +1,17 @@ |
373 | /*************************************************************************\ |
374 | * Copyright (c) 2002 The University of Saskatchewan |
375 | -* EPICS BASE Versions 3.13.7 |
376 | -* and higher are distributed subject to a Software License Agreement found |
377 | -* in file LICENSE that is included with this distribution. |
378 | +* EPICS BASE is distributed subject to a Software License Agreement found |
379 | +* in file LICENSE that is included with this distribution. |
380 | \*************************************************************************/ |
381 | /* |
382 | * RTEMS configuration for EPICS |
383 | * Author: W. Eric Norum |
384 | - * norume@aps.anl.gov |
385 | - * (630) 252-4793 |
386 | */ |
387 | |
388 | #include <rtems.h> |
389 | +#include <epicsVersion.h> |
390 | +#define RTEMS_VERSION_INT \ |
391 | + VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, __RTEMS_REVISION__, 0) |
392 | |
393 | /* |
394 | *********************************************************************** |
395 | @@ -20,7 +20,7 @@ |
396 | */ |
397 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE |
398 | |
399 | -#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) |
400 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0) |
401 | # define CONFIGURE_UNIFIED_WORK_AREAS |
402 | #else |
403 | # define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024) |
404 | |
405 | === renamed file 'src/libCom/RTEMS/rtems_netconfig.c' => 'src/libCom/RTEMS/kernel/rtems_netconfig.c' |
406 | --- src/libCom/RTEMS/rtems_netconfig.c 2016-05-22 12:38:18 +0000 |
407 | +++ src/libCom/RTEMS/kernel/rtems_netconfig.c 2017-05-01 18:36:52 +0000 |
408 | @@ -19,55 +19,70 @@ |
409 | extern void rtems_bsdnet_loopattach(); |
410 | static struct rtems_bsdnet_ifconfig loopback_config = { |
411 | "lo0", /* name */ |
412 | - (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach, /* attach function */ |
413 | - NULL, /* link to next interface */ |
414 | + (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach, |
415 | + NULL, /* last interface */ |
416 | "127.0.0.1", /* IP address */ |
417 | "255.0.0.0", /* IP net mask */ |
418 | }; |
419 | |
420 | +#define stringOf(x) #x |
421 | +#define STRING(x) stringOf(x) |
422 | + |
423 | /* |
424 | - * The following conditionals select the network interface card. |
425 | - * |
426 | - * On RTEMS-pc386 targets all network drivers which support run-time |
427 | - * probing are linked. |
428 | - * On other targets the network interface specified by the board-support |
429 | - * package is used. |
430 | - * To use a different NIC for a particular application, copy this file to the |
431 | - * application directory and make the appropriate changes. |
432 | + * The following configures up to 2 network interface card(s) using |
433 | + * settings in either configure/os/CONFIG_SITE.Common.RTEMS or in a |
434 | + * BSP-specific configure/os/CONFIG_SITE.Common.RTEMS-<bsp> file. |
435 | + * If no settings are provided, it uses the BSP's defaults instead. |
436 | */ |
437 | -#if defined(__i386__) |
438 | -extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int); |
439 | -static struct rtems_bsdnet_ifconfig fxp_driver_config = { |
440 | - "fxp1", /* name */ |
441 | - rtems_fxp_attach, /* attach function */ |
442 | - &loopback_config, /* link to next interface */ |
443 | -}; |
444 | -extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int); |
445 | -static struct rtems_bsdnet_ifconfig e3c509_driver_config = { |
446 | - "ep0", /* name */ |
447 | - rtems_3c509_driver_attach, /* attach function */ |
448 | - &fxp_driver_config, /* link to next interface */ |
449 | -}; |
450 | -#define FIRST_DRIVER_CONFIG &e3c509_driver_config |
451 | -#else |
452 | - |
453 | -# if defined(__PPC) |
454 | - /* |
455 | - * FIXME: This really belongs in the BSP |
456 | - */ |
457 | -# ifndef RTEMS_BSP_NETWORK_DRIVER_NAME |
458 | -# define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1" |
459 | -# endif |
460 | -# ifndef RTEMS_BSP_NETWORK_DRIVER_ATTACH |
461 | -# define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach |
462 | - extern int rtems_dec21140_driver_attach(); |
463 | -# endif |
464 | -# endif |
465 | - |
466 | + |
467 | +#if defined(RTEMS_NETWORK_DRIVER_NAME_1) |
468 | + |
469 | + #if defined(RTEMS_NETWORK_DRIVER_NAME_2) |
470 | + static struct rtems_bsdnet_ifconfig netdriver_config_2 = { |
471 | + STRING(RTEMS_NETWORK_DRIVER_NAME_2), |
472 | + #if defined(RTEMS_NETWORK_DRIVER_ATTACH_2) |
473 | + RTEMS_NETWORK_DRIVER_ATTACH_2, /* specific attach function */ |
474 | + #else |
475 | + RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */ |
476 | + #endif |
477 | + &loopback_config, /* loopback interface */ |
478 | + #if defined(RTEMS_NETWORK_IP4_ADDR_2) |
479 | + STRING(RTEMS_NETWORK_IP4_ADDR_2), |
480 | + #if defined(RTEMS_NETWORK_IP4_MASK_2) |
481 | + STRING(RTEMS_NETWORK_IP4_MASK_2), |
482 | + #endif |
483 | + #endif |
484 | + }; |
485 | + #endif /* RTEMS_NETWORK_DRIVER_NAME_2 */ |
486 | + |
487 | + static struct rtems_bsdnet_ifconfig netdriver_config = { |
488 | + STRING(RTEMS_NETWORK_DRIVER_NAME_1), |
489 | + #if defined(RTEMS_NETWORK_DRIVER_ATTACH_1) |
490 | + RTEMS_NETWORK_DRIVER_ATTACH_1, /* specific attach function */ |
491 | + #else |
492 | + RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */ |
493 | + #endif |
494 | + #if defined(RTEMS_NETWORK_DRIVER_NAME_2) |
495 | + &netdriver_config_2, /* link to next interface */ |
496 | + #else |
497 | + &loopback_config, /* loopback interface */ |
498 | + #endif |
499 | + #if defined(RTEMS_NETWORK_IP4_ADDR_1) |
500 | + STRING(RTEMS_NETWORK_IP4_ADDR_1), |
501 | + #if defined(RTEMS_NETWORK_IP4_MASK_1) |
502 | + STRING(RTEMS_NETWORK_IP4_MASK_1), |
503 | + #endif |
504 | + #endif |
505 | + }; |
506 | + #define FIRST_DRIVER_CONFIG &netdriver_config |
507 | + |
508 | +#else /* RTEMS_NETWORK_DRIVER_NAME_1 */ |
509 | + |
510 | +/* Use the BSP-provided standard macros */ |
511 | static struct rtems_bsdnet_ifconfig bsp_driver_config = { |
512 | RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ |
513 | RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ |
514 | - &loopback_config, /* link to next interface */ |
515 | + &loopback_config, /* loopback interface */ |
516 | }; |
517 | #define FIRST_DRIVER_CONFIG &bsp_driver_config |
518 | |
519 | @@ -77,9 +92,7 @@ |
520 | * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name |
521 | */ |
522 | #ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME |
523 | -# define XSTR(x) STR(x) |
524 | -# define STR(x) #x |
525 | -# define MY_DOMAINNAME XSTR(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME) |
526 | +# define MY_DOMAINNAME STRING(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME) |
527 | #else |
528 | # define MY_DOMAINNAME NULL |
529 | #endif |
530 | |
531 | === added directory 'src/libCom/RTEMS/posix' |
532 | === added file 'src/libCom/RTEMS/posix/rtems_config.c' |
533 | --- src/libCom/RTEMS/posix/rtems_config.c 1970-01-01 00:00:00 +0000 |
534 | +++ src/libCom/RTEMS/posix/rtems_config.c 2017-05-01 18:36:52 +0000 |
535 | @@ -0,0 +1,88 @@ |
536 | +/*************************************************************************\ |
537 | +* Copyright (c) 2002 The University of Saskatchewan |
538 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschafto* EPICS |
539 | +* BASE is distributed subject to a Software License Agreement found |
540 | +* * in file LICENSE that is included with this distribution. |
541 | +\*************************************************************************/ |
542 | +/* |
543 | + * RTEMS configuration for EPICS |
544 | + * Author: W. Eric Norum |
545 | + * Heinz Junkes |
546 | + * |
547 | + * Version for RTEMS-4.12 |
548 | + */ |
549 | + |
550 | +#include <rtems.h> |
551 | + |
552 | +/* |
553 | + *********************************************************************** |
554 | + * RTEMS CONFIGURATION * |
555 | + *********************************************************************** |
556 | + */ |
557 | + |
558 | +extern void *EPICS_WITH_POSIX_Init(void *argument); |
559 | + |
560 | +#define CONFIGURE_POSIX_INIT_THREAD_TABLE |
561 | +#define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT EPICS_WITH_POSIX_Init |
562 | +/* |
563 | + * nfs is using rtems tasks |
564 | + */ |
565 | +#define CONFIGURE_MAXIMUM_TASKS 5 |
566 | +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5 |
567 | +#define CONFIGURE_MAXIMUM_SEMAPHORES 5 |
568 | +#define CONFIGURE_MAXIMUM_EVENTS 5 |
569 | + |
570 | +#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 300 |
571 | +#define CONFIGURE_MAXIMUM_POSIX_THREADS 200 |
572 | +#define CONFIGURE_MAXIMUM_POSIX_KEYS 200 |
573 | +#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 200 |
574 | +#define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS 100 |
575 | +#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 300 |
576 | +#define CONFIGURE_MAXIMUM_POSIX_TIMERS 100 |
577 | +#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 100 |
578 | +#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 300 |
579 | + |
580 | +#define CONFIGURE_UNIFIED_WORK_AREAS |
581 | + |
582 | +#define CONFIGURE_MAXIMUM_PERIODS 5 |
583 | +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 |
584 | +#define CONFIGURE_MALLOC_STATISTICS 1 |
585 | +/* MINIMUM_STACK_SIZE == 8K */ |
586 | +#define CONFIGURE_EXTRA_TASK_STACKS (1000 * RTEMS_MINIMUM_STACK_SIZE) |
587 | + |
588 | +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER |
589 | +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER |
590 | + |
591 | +#define CONFIGURE_FILESYSTEM_DEVFS |
592 | +#define CONFIGURE_FILESYSTEM_TFTPFS |
593 | +#define CONFIGURE_FILESYSTEM_NFS |
594 | +#define CONFIGURE_FILESYSTEM_IMFS |
595 | +#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM |
596 | +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150 |
597 | + |
598 | +#define CONFIGURE_MAXIMUM_NFS_MOUNTS 3 |
599 | +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 5 |
600 | + |
601 | +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (64*1024) |
602 | + |
603 | +#define CONFIGURE_MAXIMUM_DRIVERS 8 |
604 | + |
605 | +//#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension } |
606 | + |
607 | +#define CONFIGURE_INIT |
608 | + |
609 | + |
610 | +/* |
611 | + * This should be made BSP dependent, not CPU dependent but I know of no |
612 | + * appropriate conditionals to use. |
613 | + * The new general time support makes including the RTC driverr less important. |
614 | + */ |
615 | +#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && \ |
616 | + !defined(mpc7455) && !defined(__arm__) && !defined(__nios2__) |
617 | + /* don't have RTC code */ |
618 | +#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER |
619 | +#endif |
620 | + |
621 | + |
622 | +#include <bsp.h> |
623 | +#include <rtems/confdefs.h> |
624 | |
625 | === added file 'src/libCom/RTEMS/posix/rtems_netconfig.c' |
626 | --- src/libCom/RTEMS/posix/rtems_netconfig.c 1970-01-01 00:00:00 +0000 |
627 | +++ src/libCom/RTEMS/posix/rtems_netconfig.c 2017-05-01 18:36:52 +0000 |
628 | @@ -0,0 +1,126 @@ |
629 | +/*************************************************************************\ |
630 | +* Copyright (c) 2002 The University of Saskatchewan |
631 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
632 | +* EPICS BASE is distributed subject to a Software License Agreement found |
633 | +* in file LICENSE that is included with this distribution. |
634 | +\*************************************************************************/ |
635 | +/* |
636 | + * RTEMS network configuration for EPICS |
637 | + * Author: W. Eric Norum |
638 | + * Heinz Junkes |
639 | + * |
640 | + * Version for RTEMS-4.12 |
641 | + * |
642 | + * This file can be copied to an application source dirctory |
643 | + * and modified to override the values shown below. |
644 | + */ |
645 | +#include <stdio.h> |
646 | +#include <bsp.h> |
647 | +#include <rtems/rtems_bsdnet.h> |
648 | + |
649 | +#define stringOf(x) #x |
650 | +#define STRING(x) stringOf(x) |
651 | + |
652 | +/* |
653 | + * The following configures up to 2 network interface card(s) using |
654 | + * settings in either configure/os/CONFIG_SITE.Common.RTEMS or in a |
655 | + * BSP-specific configure/os/CONFIG_SITE.Common.RTEMS-<bsp> file. |
656 | + * If no settings are provided, it uses the BSP's defaults instead. |
657 | + */ |
658 | + |
659 | +#if defined(RTEMS_NETWORK_DRIVER_NAME_1) |
660 | + |
661 | + #if defined(RTEMS_NETWORK_DRIVER_NAME_2) |
662 | + static struct rtems_bsdnet_ifconfig netdriver_config_2 = { |
663 | + STRING(RTEMS_NETWORK_DRIVER_NAME_2), |
664 | + #if defined(RTEMS_NETWORK_DRIVER_ATTACH_2) |
665 | + RTEMS_NETWORK_DRIVER_ATTACH_2, /* specific attach function */ |
666 | + #else |
667 | + RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */ |
668 | + #endif |
669 | + NULL, /* last interface */ |
670 | + #if defined(RTEMS_NETWORK_IP4_ADDR_2) |
671 | + STRING(RTEMS_NETWORK_IP4_ADDR_2), |
672 | + #if defined(RTEMS_NETWORK_IP4_MASK_2) |
673 | + STRING(RTEMS_NETWORK_IP4_MASK_2), |
674 | + #endif |
675 | + #endif |
676 | + }; |
677 | + #endif /* RTEMS_NETWORK_DRIVER_NAME_2 */ |
678 | + |
679 | + static struct rtems_bsdnet_ifconfig netdriver_config = { |
680 | + STRING(RTEMS_NETWORK_DRIVER_NAME_1), |
681 | + #if defined(RTEMS_NETWORK_DRIVER_ATTACH_1) |
682 | + RTEMS_NETWORK_DRIVER_ATTACH_1, /* specific attach function */ |
683 | + #else |
684 | + RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* default attach function */ |
685 | + #endif |
686 | + #if defined(RTEMS_NETWORK_DRIVER_NAME_2) |
687 | + &netdriver_config_2, /* link to next interface */ |
688 | + #else |
689 | + NULL, /* last interface */ |
690 | + #endif |
691 | + #if defined(RTEMS_NETWORK_IP4_ADDR_1) |
692 | + STRING(RTEMS_NETWORK_IP4_ADDR_1), |
693 | + #if defined(RTEMS_NETWORK_IP4_MASK_1) |
694 | + STRING(RTEMS_NETWORK_IP4_MASK_1), |
695 | + #endif |
696 | + #endif |
697 | + }; |
698 | + #define FIRST_DRIVER_CONFIG &netdriver_config |
699 | + |
700 | +#else /* RTEMS_NETWORK_DRIVER_NAME_1 */ |
701 | + |
702 | +/* Use the BSP-provided standard macros */ |
703 | +static struct rtems_bsdnet_ifconfig bsp_driver_config = { |
704 | + RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ |
705 | + RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ |
706 | + NULL, /* last interface */ |
707 | +}; |
708 | +#define FIRST_DRIVER_CONFIG &bsp_driver_config |
709 | + |
710 | +#endif |
711 | + |
712 | +/* |
713 | + * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name |
714 | + */ |
715 | +#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME |
716 | +# define MY_DOMAINNAME STRING(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME) |
717 | +#else |
718 | +# define MY_DOMAINNAME NULL |
719 | +#endif |
720 | + |
721 | +/* |
722 | + * Allow non-BOOTP network configuration |
723 | + */ |
724 | +#ifndef MY_DO_BOOTP |
725 | +# define MY_DO_BOOTP rtems_bsdnet_do_bootp |
726 | +#endif |
727 | + |
728 | +/* |
729 | + * Allow site- and BSP-specific network buffer space configuration. |
730 | + * The macro values are specified in KBytes. |
731 | + */ |
732 | +#ifndef RTEMS_NETWORK_CONFIG_MBUF_SPACE |
733 | +# define RTEMS_NETWORK_CONFIG_MBUF_SPACE 180 |
734 | +#endif |
735 | +#ifndef RTEMS_NETWORK_CONFIG_CLUSTER_SPACE |
736 | +# define RTEMS_NETWORK_CONFIG_CLUSTER_SPACE 350 |
737 | +#endif |
738 | + |
739 | +/* |
740 | + * Network configuration |
741 | + */ |
742 | +struct rtems_bsdnet_config rtems_bsdnet_config = { |
743 | + FIRST_DRIVER_CONFIG, /* Link to next interface */ |
744 | + MY_DO_BOOTP, /* How to find network config */ |
745 | + 10, /* If 0 then the network daemons will run at a */ |
746 | + /* priority just less than the lowest-priority */ |
747 | + /* EPICS scan thread. */ |
748 | + /* If non-zero then the network daemons will run */ |
749 | + /* at this *RTEMS* priority */ |
750 | + RTEMS_NETWORK_CONFIG_MBUF_SPACE*1024, |
751 | + RTEMS_NETWORK_CONFIG_CLUSTER_SPACE*1024, |
752 | + NULL, /* Host name */ |
753 | + MY_DOMAINNAME, /* Domain name */ |
754 | +}; |
755 | |
756 | === modified file 'src/libCom/RTEMS/rtems_init.c' |
757 | --- src/libCom/RTEMS/rtems_init.c 2017-02-01 17:57:04 +0000 |
758 | +++ src/libCom/RTEMS/rtems_init.c 2017-05-01 18:36:52 +0000 |
759 | @@ -25,12 +25,19 @@ |
760 | #include <netinet/in.h> |
761 | #include <arpa/inet.h> |
762 | #include <rtems.h> |
763 | +#include <epicsVersion.h> |
764 | +#define RTEMS_VERSION_INT \ |
765 | + VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, __RTEMS_REVISION__, 0) |
766 | #include <rtems/malloc.h> |
767 | #include <rtems/error.h> |
768 | #include <rtems/stackchk.h> |
769 | #include <rtems/rtems_bsdnet.h> |
770 | #include <rtems/imfs.h> |
771 | #include <librtemsNfs.h> |
772 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
773 | +#include <rtems/libio.h> |
774 | +#include <sys/stat.h> |
775 | +#endif |
776 | #include <bsp.h> |
777 | |
778 | #include "epicsThread.h" |
779 | @@ -44,6 +51,13 @@ |
780 | #include "osdTime.h" |
781 | |
782 | #include "epicsRtemsInitHooks.h" |
783 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
784 | +#include <rtems/malloc.h> |
785 | +#include <rtems/score/heap.h> |
786 | +#include <pthread.h> |
787 | +#include <assert.h> |
788 | +#define rtems_test_assert(_a) assert(_a) |
789 | +#endif |
790 | |
791 | /* |
792 | * Prototypes for some functions not in header files |
793 | @@ -52,6 +66,49 @@ |
794 | int fileno(FILE *); |
795 | int main(int argc, char **argv); |
796 | |
797 | +//Helper function must be made useful |
798 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
799 | + |
800 | +static int get_current_prio( pthread_t thread ) |
801 | +{ |
802 | +rtems_status_code sc; |
803 | +rtems_task_priority prio; |
804 | +int max; |
805 | + |
806 | +sc = rtems_task_set_priority( thread, RTEMS_CURRENT_PRIORITY, &prio ); |
807 | +rtems_test_assert( sc == RTEMS_SUCCESSFUL ); |
808 | + |
809 | +max = sched_get_priority_max( SCHED_FIFO ); |
810 | + |
811 | +return max + 1 - (int) prio; |
812 | +} |
813 | + |
814 | +//We are using posix map osi 0-100 to posix 100-200 |
815 | +int epicsThreadGetOsiPriorityValue(int ossPriority) |
816 | +{ |
817 | + if (ossPriority > 200) { |
818 | + return epicsThreadPriorityMax; |
819 | + } |
820 | + else if (ossPriority < 100) { |
821 | + return epicsThreadPriorityMin; |
822 | + } |
823 | + else { |
824 | + return ((unsigned int)ossPriority - 100u); |
825 | + } |
826 | +} |
827 | +int epicsThreadGetOssPriorityValue(unsigned int osiPriority) |
828 | +{ |
829 | + if (osiPriority > 99) { |
830 | + return 200; |
831 | + } |
832 | + else { |
833 | + return ((signed int)osiPriority + 100u); |
834 | + } |
835 | +} |
836 | +#else |
837 | +/* see osdThread.c */ |
838 | +#endif |
839 | + |
840 | static void |
841 | logReset (void) |
842 | { |
843 | @@ -61,10 +118,12 @@ |
844 | if (fp) { |
845 | char buf[80]; |
846 | fp(buf, sizeof buf); |
847 | - errlogPrintf ("Startup after %s.\n", buf); |
848 | + //errlogPrintf ("Startup after %s.\n", buf); |
849 | + printk ("Startup after %s.\n", buf); |
850 | } |
851 | else { |
852 | - errlogPrintf ("Startup.\n"); |
853 | + //errlogPrintf ("Startup.\n"); |
854 | + printk ("Startup.\n"); |
855 | } |
856 | } |
857 | |
858 | @@ -79,9 +138,12 @@ |
859 | static void |
860 | delayedPanic (const char *msg) |
861 | { |
862 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
863 | + rtems_task_wake_after (rtems_clock_get_ticks_per_second()); |
864 | +#else |
865 | extern rtems_interval rtemsTicksPerSecond; |
866 | - |
867 | rtems_task_wake_after (rtemsTicksPerSecond); |
868 | +#endif |
869 | rtems_panic (msg); |
870 | } |
871 | |
872 | @@ -171,9 +233,7 @@ |
873 | } |
874 | |
875 | #ifndef OMIT_NFS_SUPPORT |
876 | -#if __RTEMS_MAJOR__>4 || \ |
877 | - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ |
878 | - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) |
879 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0) |
880 | int |
881 | nfsMount(char *uidhost, char *path, char *mntpoint) |
882 | { |
883 | @@ -187,6 +247,13 @@ |
884 | } |
885 | sprintf(dev, "%s:%s", uidhost, path); |
886 | printf("Mount %s on %s\n", dev, mntpoint); |
887 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
888 | + rval = mount_and_make_target_path ( |
889 | + dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS, |
890 | + RTEMS_FILESYSTEM_READ_WRITE, NULL ); |
891 | + if(rval) |
892 | + perror("mount failed"); |
893 | +#else |
894 | if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO)) |
895 | printf("Warning -- unable to make directory \"%s\"\n", mntpoint); |
896 | if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS, |
897 | @@ -196,6 +263,7 @@ |
898 | else { |
899 | rval = 0; |
900 | } |
901 | +#endif |
902 | free(dev); |
903 | return rval; |
904 | } |
905 | @@ -210,9 +278,7 @@ |
906 | { |
907 | #ifdef OMIT_NFS_SUPPORT |
908 | printf ("***** Initializing TFTP *****\n"); |
909 | -#if __RTEMS_MAJOR__>4 || \ |
910 | - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ |
911 | - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) |
912 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 9, 99, 0) |
913 | mount_and_make_target_path(NULL, |
914 | "/TFTP", |
915 | RTEMS_FILESYSTEM_TYPE_TFTPFS, |
916 | @@ -246,6 +312,7 @@ |
917 | printf ("***** Initializing NFS *****\n"); |
918 | NFS_INIT |
919 | if (env_nfsServer && env_nfsPath && env_nfsMountPoint) { |
920 | + printf(" bin in environment kram ...\n"); |
921 | server_name = env_nfsServer; |
922 | server_path = env_nfsPath; |
923 | mount_point = env_nfsMountPoint; |
924 | @@ -309,10 +376,11 @@ |
925 | "%[^:] : / %s", |
926 | pServerName, |
927 | pServerPath + 1u ); |
928 | + |
929 | if ( scanfStatus == 2 ) { |
930 | pServerPath[0u]= '/'; |
931 | server_name = pServerName; |
932 | - server_path = pServerPath; |
933 | + server_path = mount_point = pServerPath; |
934 | } |
935 | else { |
936 | free ( pServerName ); |
937 | @@ -332,8 +400,6 @@ |
938 | argv[1] = abspath; |
939 | } |
940 | } |
941 | - errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n", |
942 | - server_name, server_path, mount_point); |
943 | nfsMount(server_name, server_path, mount_point); |
944 | #endif |
945 | } |
946 | @@ -357,7 +423,6 @@ |
947 | perror("error: fixup_hosts stat /etc/hosts"); |
948 | return; |
949 | } |
950 | - |
951 | ret = mkdir("/etc", 0775); |
952 | if(ret!=0 && errno!=EEXIST) |
953 | { |
954 | @@ -374,7 +439,6 @@ |
955 | { |
956 | perror("error: failed to write /etc/hosts"); |
957 | } |
958 | - |
959 | fclose(fp); |
960 | } |
961 | |
962 | @@ -444,11 +508,19 @@ |
963 | static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL}; |
964 | static void heapSpaceCallFunc(const iocshArgBuf *args) |
965 | { |
966 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
967 | + Heap_Information_block info; |
968 | + double x; |
969 | + |
970 | + malloc_info (&info); |
971 | + x = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed); |
972 | +#else |
973 | rtems_malloc_statistics_t s; |
974 | double x; |
975 | |
976 | malloc_get_statistics(&s); |
977 | x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); |
978 | +#endif |
979 | if (x >= 1024*1024) |
980 | printf("Heap space: %.1f MB\n", x / (1024 * 1024)); |
981 | else |
982 | @@ -513,13 +585,14 @@ |
983 | * Ensure that the configuration object files |
984 | * get pulled in from the library |
985 | */ |
986 | -extern rtems_configuration_table Configuration; |
987 | +#if RTEMS_VERSION_INT < VERSION_INT(4, 11, 99, 0) |
988 | +extern rtems_configuration_table Configuration; |
989 | extern struct rtems_bsdnet_config rtems_bsdnet_config; |
990 | const void *rtemsConfigArray[] = { |
991 | &Configuration, |
992 | &rtems_bsdnet_config |
993 | }; |
994 | - |
995 | +#endif |
996 | /* |
997 | * Hook to ensure that BSP cleanup code gets run on exit |
998 | */ |
999 | @@ -532,13 +605,21 @@ |
1000 | /* |
1001 | * RTEMS Startup task |
1002 | */ |
1003 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
1004 | +void * |
1005 | +EPICS_WITH_POSIX_Init (void *argument) |
1006 | +#else |
1007 | rtems_task |
1008 | Init (rtems_task_argument ignored) |
1009 | +#endif |
1010 | { |
1011 | +<<<<<<< TREE |
1012 | int result; |
1013 | +======= |
1014 | + int i; |
1015 | +>>>>>>> MERGE-SOURCE |
1016 | char *argv[3] = { NULL, NULL, NULL }; |
1017 | char *cp; |
1018 | - rtems_task_priority newpri; |
1019 | rtems_status_code sc; |
1020 | rtems_time_of_day now; |
1021 | |
1022 | @@ -562,10 +643,20 @@ |
1023 | /* |
1024 | * Override RTEMS configuration |
1025 | */ |
1026 | - rtems_task_set_priority ( |
1027 | - RTEMS_SELF, |
1028 | - epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), |
1029 | - &newpri); |
1030 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
1031 | + int policy; |
1032 | + struct sched_param param; |
1033 | + |
1034 | + if (pthread_getschedparam(pthread_self(), &policy, ¶m) != 0) |
1035 | + delayedPanic("pthread_getschedparam failed"); |
1036 | + param.sched_priority = epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh); |
1037 | + if (pthread_setschedparam(pthread_self(), policy, ¶m) != 0) |
1038 | + delayedPanic("pthread_setschedparam failed"); |
1039 | +#else |
1040 | + rtems_task_priority newpri; |
1041 | + rtems_task_set_priority (RTEMS_SELF, |
1042 | + epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), &newpri); |
1043 | +#endif |
1044 | |
1045 | /* |
1046 | * Create a reasonable environment |
1047 | @@ -580,6 +671,7 @@ |
1048 | printf("\n***** RTEMS Version: %s *****\n", |
1049 | rtems_get_version_string()); |
1050 | |
1051 | + printf("\n***** RTEMS min stack size : %d\n", RTEMS_MINIMUM_STACK_SIZE); |
1052 | /* |
1053 | * Start network |
1054 | */ |
1055 | @@ -616,12 +708,16 @@ |
1056 | * It is very likely that other time synchronization facilities in EPICS |
1057 | * will soon override this value. |
1058 | */ |
1059 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
1060 | + if (rtems_clock_get_tod(&now) != RTEMS_SUCCESSFUL) { |
1061 | +#else |
1062 | if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) { |
1063 | - now.year = 2001; |
1064 | - now.month = 1; |
1065 | - now.day = 1; |
1066 | - now.hour = 0; |
1067 | - now.minute = 0; |
1068 | +#endif |
1069 | + now.year = 2012; |
1070 | + now.month = 4; |
1071 | + now.day = 14; |
1072 | + now.hour = 7; |
1073 | + now.minute = 23; |
1074 | now.second = 0; |
1075 | now.ticks = 0; |
1076 | if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL) |
1077 | @@ -649,7 +745,23 @@ |
1078 | } |
1079 | } |
1080 | tzset(); |
1081 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
1082 | + // osdTimeRegister() was called during C++ initialization |
1083 | +#else |
1084 | osdTimeRegister(); |
1085 | +#endif |
1086 | + |
1087 | + /* |
1088 | + * Some network diagnotics |
1089 | + */ |
1090 | + |
1091 | + // rtems_bsdnet_show_mbuf_stats (void); |
1092 | + rtems_bsdnet_show_if_stats (); |
1093 | + rtems_bsdnet_show_ip_stats (); |
1094 | + rtems_bsdnet_show_icmp_stats (); |
1095 | + rtems_bsdnet_show_inet_routes (); |
1096 | + //rtems_bsdnet_show_udp_stats (void); |
1097 | + //rtems_bsdnet_show_tcp_stats (void); |
1098 | |
1099 | /* |
1100 | * Run the EPICS startup script |
1101 | @@ -664,5 +776,12 @@ |
1102 | result = main ((sizeof argv / sizeof argv[0]) - 1, argv); |
1103 | printf ("***** IOC application terminating *****\n"); |
1104 | epicsThreadSleep(1.0); |
1105 | +<<<<<<< TREE |
1106 | epicsExit(result); |
1107 | +======= |
1108 | + epicsExit(0); |
1109 | +#if RTEMS_VERSION_INT >= VERSION_INT(4, 11, 99, 0) |
1110 | + return NULL; |
1111 | +#endif |
1112 | +>>>>>>> MERGE-SOURCE |
1113 | } |
1114 | |
1115 | === modified file 'src/libCom/calc/postfix.c' |
1116 | --- src/libCom/calc/postfix.c 2016-05-22 12:38:18 +0000 |
1117 | +++ src/libCom/calc/postfix.c 2017-05-01 18:36:52 +0000 |
1118 | @@ -27,6 +27,10 @@ |
1119 | #include "postfixPvt.h" |
1120 | #include "shareLib.h" |
1121 | |
1122 | +#ifdef USE_ALTIVEC |
1123 | +#pragma GCC push_options |
1124 | +#pragma GCC optimize ("O0") |
1125 | +#endif |
1126 | |
1127 | /* declarations for postfix */ |
1128 | |
1129 | @@ -624,3 +628,13 @@ |
1130 | } |
1131 | } |
1132 | } |
1133 | +/* |
1134 | +#if __RTEMS_MAJOR__>4 || \ |
1135 | + (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>11) || \ |
1136 | + (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==11 && __RTEMS_REVISION__==99) |
1137 | +*/ |
1138 | +#ifdef USE_ALTIVEC |
1139 | +#pragma GCC pop_options |
1140 | +#endif |
1141 | +/* #endif */ |
1142 | + |
1143 | |
1144 | === modified file 'src/libCom/error/errlog.c' |
1145 | --- src/libCom/error/errlog.c 2015-08-13 15:44:52 +0000 |
1146 | +++ src/libCom/error/errlog.c 2017-05-01 18:36:52 +0000 |
1147 | @@ -34,6 +34,10 @@ |
1148 | #include "epicsStdio.h" |
1149 | #include "epicsExit.h" |
1150 | |
1151 | +#if defined(__rtems__) |
1152 | +#include <rtems/bspIo.h> |
1153 | +#include <rtems.h> |
1154 | +#endif |
1155 | |
1156 | #define BUFFER_SIZE 1280 |
1157 | #define MAX_MESSAGE_SIZE 256 |
1158 | @@ -117,6 +121,7 @@ |
1159 | } |
1160 | |
1161 | errlogInit(0); |
1162 | + |
1163 | isOkToBlock = epicsThreadIsOkToBlock(); |
1164 | |
1165 | if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { |
1166 | |
1167 | === modified file 'src/libCom/misc/epicsUnitTest.c' |
1168 | --- src/libCom/misc/epicsUnitTest.c 2016-05-22 12:38:18 +0000 |
1169 | +++ src/libCom/misc/epicsUnitTest.c 2017-05-01 18:36:52 +0000 |
1170 | @@ -248,6 +248,7 @@ |
1171 | |
1172 | void testHarness(void) { |
1173 | epicsThreadOnce(&onceFlag, testOnce, NULL); |
1174 | +epicsThreadShowAll(1); |
1175 | epicsAtExit(testHarnessExit, NULL); |
1176 | Harness = 1; |
1177 | Programs = 0; |
1178 | |
1179 | === modified file 'src/libCom/osi/os/Linux/osdSock.h' |
1180 | --- src/libCom/osi/os/Linux/osdSock.h 2017-01-23 23:20:51 +0000 |
1181 | +++ src/libCom/osi/os/Linux/osdSock.h 2017-05-01 18:36:52 +0000 |
1182 | @@ -26,8 +26,10 @@ |
1183 | #include <arpa/inet.h> |
1184 | #include <net/if.h> |
1185 | #include <netdb.h> |
1186 | +#include <ifaddrs.h> /* getifaddrs() */ |
1187 | #include <unistd.h> /* close() and others */ |
1188 | |
1189 | +#define USE_IFADDRS |
1190 | |
1191 | typedef int SOCKET; |
1192 | #define INVALID_SOCKET (-1) |
1193 | |
1194 | === added directory 'src/libCom/osi/os/RTEMS-kernel' |
1195 | === renamed file 'src/libCom/osi/os/RTEMS/devLibVMEOSD.c' => 'src/libCom/osi/os/RTEMS-kernel/devLibVMEOSD.c' |
1196 | === renamed file 'src/libCom/osi/os/RTEMS/epicsAtomicOSD.cpp' => 'src/libCom/osi/os/RTEMS-kernel/epicsAtomicOSD.cpp' |
1197 | === renamed file 'src/libCom/osi/os/RTEMS/epicsAtomicOSD.h' => 'src/libCom/osi/os/RTEMS-kernel/epicsAtomicOSD.h' |
1198 | === renamed file 'src/libCom/osi/os/RTEMS/osdEvent.c' => 'src/libCom/osi/os/RTEMS-kernel/osdEvent.c' |
1199 | === renamed file 'src/libCom/osi/os/RTEMS/osdEvent.h' => 'src/libCom/osi/os/RTEMS-kernel/osdEvent.h' |
1200 | === renamed file 'src/libCom/osi/os/RTEMS/osdFindSymbol.c' => 'src/libCom/osi/os/RTEMS-kernel/osdFindSymbol.c' |
1201 | === renamed file 'src/libCom/osi/os/RTEMS/osdMessageQueue.c' => 'src/libCom/osi/os/RTEMS-kernel/osdMessageQueue.c' |
1202 | === renamed file 'src/libCom/osi/os/RTEMS/osdMessageQueue.h' => 'src/libCom/osi/os/RTEMS-kernel/osdMessageQueue.h' |
1203 | === renamed file 'src/libCom/osi/os/RTEMS/osdMutex.c' => 'src/libCom/osi/os/RTEMS-kernel/osdMutex.c' |
1204 | === renamed file 'src/libCom/osi/os/RTEMS/osdMutex.h' => 'src/libCom/osi/os/RTEMS-kernel/osdMutex.h' |
1205 | === renamed file 'src/libCom/osi/os/RTEMS/osdPoolStatus.c' => 'src/libCom/osi/os/RTEMS-kernel/osdPoolStatus.c' |
1206 | === renamed file 'src/libCom/osi/os/RTEMS/osdProcess.c' => 'src/libCom/osi/os/RTEMS-kernel/osdProcess.c' |
1207 | === renamed file 'src/libCom/osi/os/RTEMS/osdReadline.c' => 'src/libCom/osi/os/RTEMS-kernel/osdReadline.c' |
1208 | === renamed file 'src/libCom/osi/os/RTEMS/osdSignal.cpp' => 'src/libCom/osi/os/RTEMS-kernel/osdSignal.cpp' |
1209 | === renamed file 'src/libCom/osi/os/RTEMS/osdSock.h' => 'src/libCom/osi/os/RTEMS-kernel/osdSock.h' |
1210 | === renamed file 'src/libCom/osi/os/RTEMS/osdSpin.c' => 'src/libCom/osi/os/RTEMS-kernel/osdSpin.c' |
1211 | === renamed file 'src/libCom/osi/os/RTEMS/osdStrtod.h' => 'src/libCom/osi/os/RTEMS-kernel/osdStrtod.h' |
1212 | === renamed file 'src/libCom/osi/os/RTEMS/osdThread.c' => 'src/libCom/osi/os/RTEMS-kernel/osdThread.c' |
1213 | === renamed file 'src/libCom/osi/os/RTEMS/osdThread.h' => 'src/libCom/osi/os/RTEMS-kernel/osdThread.h' |
1214 | === renamed file 'src/libCom/osi/os/RTEMS/osdThreadExtra.c' => 'src/libCom/osi/os/RTEMS-kernel/osdThreadExtra.c' |
1215 | === renamed file 'src/libCom/osi/os/RTEMS/osdTime.cpp' => 'src/libCom/osi/os/RTEMS-kernel/osdTime.cpp' |
1216 | === renamed file 'src/libCom/osi/os/RTEMS/osdTime.h' => 'src/libCom/osi/os/RTEMS-kernel/osdTime.h' |
1217 | === renamed file 'src/libCom/osi/os/RTEMS/osiUnistd.h' => 'src/libCom/osi/os/RTEMS-kernel/osiUnistd.h' |
1218 | === added directory 'src/libCom/osi/os/RTEMS-posix' |
1219 | === added file 'src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c' |
1220 | --- src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c 1970-01-01 00:00:00 +0000 |
1221 | +++ src/libCom/osi/os/RTEMS-posix/devLibVMEOSD.c 2017-05-01 18:36:52 +0000 |
1222 | @@ -0,0 +1,367 @@ |
1223 | +/*************************************************************************\ |
1224 | +* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne |
1225 | +* National Laboratory. |
1226 | +* Copyright (c) 2002 The Regents of the University of California, as |
1227 | +* Operator of Los Alamos National Laboratory. |
1228 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
1229 | +* EPICS BASE is distributed subject to a Software License Agreement found |
1230 | +* in file LICENSE that is included with this distribution. |
1231 | +\*************************************************************************/ |
1232 | + |
1233 | +/* RTEMS port by Till Straumann, <strauman@slac.stanford.edu> |
1234 | + * 3/2002 |
1235 | + * |
1236 | + * Adapted to rtems4.12 |
1237 | + * removed include bsp/bspExt.h |
1238 | + */ |
1239 | + |
1240 | +#include <epicsStdio.h> |
1241 | +#include <epicsExit.h> |
1242 | +#include <rtems.h> |
1243 | +#include <bsp.h> |
1244 | +#include "devLibVME.h" |
1245 | +#include <epicsInterrupt.h> |
1246 | + |
1247 | +#if defined(__PPC__) || defined(__mcf528x__) |
1248 | + |
1249 | +#if defined(__PPC__) |
1250 | +#include <bsp/VME.h> |
1251 | +#endif |
1252 | + |
1253 | + |
1254 | +typedef void myISR (void *pParam); |
1255 | + |
1256 | +static myISR *isrFetch(unsigned vectorNumber, void **parg); |
1257 | + |
1258 | +/* |
1259 | + * this routine needs to be in the symbol table |
1260 | + * for this code to work correctly |
1261 | + */ |
1262 | +static void unsolicitedHandlerEPICS(int vectorNumber); |
1263 | + |
1264 | +static myISR *defaultHandlerAddr[]={ |
1265 | + (myISR*)unsolicitedHandlerEPICS, |
1266 | +}; |
1267 | + |
1268 | +/* |
1269 | + * Make sure that the CR/CSR addressing mode is defined. |
1270 | + * (it may not be in some BSPs). |
1271 | + */ |
1272 | +#ifndef VME_AM_CSR |
1273 | +# define VME_AM_CSR (0x2f) |
1274 | +#endif |
1275 | + |
1276 | +/* |
1277 | + * we use a translation between an EPICS encoding |
1278 | + * and a vxWorks encoding here |
1279 | + * to reduce dependency of drivers on vxWorks |
1280 | + * |
1281 | + * we assume that the BSP are configured to use these |
1282 | + * address modes by default |
1283 | + */ |
1284 | +#define EPICSAddrTypeNoConvert -1 |
1285 | +int EPICStovxWorksAddrType[] |
1286 | + = { |
1287 | + VME_AM_SUP_SHORT_IO, |
1288 | + VME_AM_STD_SUP_DATA, |
1289 | + VME_AM_EXT_SUP_DATA, |
1290 | + EPICSAddrTypeNoConvert, |
1291 | + VME_AM_CSR |
1292 | + }; |
1293 | + |
1294 | +/* |
1295 | + * maps logical address to physical address, but does not detect |
1296 | + * two device drivers that are using the same address range |
1297 | + */ |
1298 | +static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, |
1299 | + size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); |
1300 | + |
1301 | +/* |
1302 | + * a bus error safe "wordSize" read at the specified address which returns |
1303 | + * unsuccessful status if the device isnt present |
1304 | + */ |
1305 | +static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); |
1306 | + |
1307 | +/* |
1308 | + * a bus error safe "wordSize" write at the specified address which returns |
1309 | + * unsuccessful status if the device isnt present |
1310 | + */ |
1311 | +static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); |
1312 | + |
1313 | +static long rtemsDevConnectInterruptVME ( |
1314 | + unsigned vectorNumber, |
1315 | + void (*pFunction)(), |
1316 | + void *parameter); |
1317 | + |
1318 | +static long rtemsDevDisconnectInterruptVME ( |
1319 | + unsigned vectorNumber, |
1320 | + void (*pFunction)() |
1321 | +); |
1322 | + |
1323 | +static long rtemsDevEnableInterruptLevelVME (unsigned level); |
1324 | + |
1325 | +static long rtemsDevDisableInterruptLevelVME (unsigned level); |
1326 | + |
1327 | +static int rtemsDevInterruptInUseVME (unsigned vectorNumber); |
1328 | + |
1329 | +/* RTEMS specific init */ |
1330 | + |
1331 | +/*devA24Malloc and devA24Free are not implemented*/ |
1332 | +static void *devA24Malloc(size_t size) { return 0;} |
1333 | +static void devA24Free(void *pBlock) {}; |
1334 | +static long rtemsDevInit(void); |
1335 | + |
1336 | +/* |
1337 | + * used by bind in devLib.c |
1338 | + */ |
1339 | +static devLibVME rtemsVirtualOS = { |
1340 | + rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe, |
1341 | + rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME, |
1342 | + rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME, |
1343 | + devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME |
1344 | +}; |
1345 | +devLibVME *pdevLibVME = &rtemsVirtualOS; |
1346 | + |
1347 | +/* RTEMS specific initialization */ |
1348 | +static long |
1349 | +rtemsDevInit(void) |
1350 | +{ |
1351 | + /* assume the vme bridge has been initialized by bsp */ |
1352 | + /* init BSP extensions [memProbe etc.] */ |
1353 | + return bspExtInit(); |
1354 | +} |
1355 | + |
1356 | +/* |
1357 | + * devConnectInterruptVME |
1358 | + * |
1359 | + * wrapper to minimize driver dependency on OS |
1360 | + */ |
1361 | +static long rtemsDevConnectInterruptVME ( |
1362 | + unsigned vectorNumber, |
1363 | + void (*pFunction)(), |
1364 | + void *parameter) |
1365 | +{ |
1366 | + int status; |
1367 | + |
1368 | + |
1369 | + if (devInterruptInUseVME(vectorNumber)) { |
1370 | + return S_dev_vectorInUse; |
1371 | + } |
1372 | + status = BSP_installVME_isr( |
1373 | + vectorNumber, |
1374 | + pFunction, |
1375 | + parameter); |
1376 | + if (status) { |
1377 | + return S_dev_vecInstlFail; |
1378 | + } |
1379 | + |
1380 | + return 0; |
1381 | +} |
1382 | + |
1383 | +/* |
1384 | + * |
1385 | + * devDisconnectInterruptVME() |
1386 | + * |
1387 | + * wrapper to minimize driver dependency on OS |
1388 | + * |
1389 | + * The parameter pFunction should be set to the C function pointer that |
1390 | + * was connected. It is used as a key to prevent a driver from removing |
1391 | + * an interrupt handler that was installed by another driver |
1392 | + * |
1393 | + */ |
1394 | +static long rtemsDevDisconnectInterruptVME ( |
1395 | + unsigned vectorNumber, |
1396 | + void (*pFunction)() |
1397 | +) |
1398 | +{ |
1399 | + void (*psub)(); |
1400 | + void *arg; |
1401 | + int status; |
1402 | + |
1403 | + /* |
1404 | + * If pFunction not connected to this vector |
1405 | + * then they are probably disconnecting from the wrong vector |
1406 | + */ |
1407 | + psub = isrFetch(vectorNumber, &arg); |
1408 | + if(psub != pFunction){ |
1409 | + return S_dev_vectorNotInUse; |
1410 | + } |
1411 | + |
1412 | + status = BSP_removeVME_isr( |
1413 | + vectorNumber, |
1414 | + psub, |
1415 | + arg) || |
1416 | + BSP_installVME_isr( |
1417 | + vectorNumber, |
1418 | + (BSP_VME_ISR_t)unsolicitedHandlerEPICS, |
1419 | + (void*)vectorNumber); |
1420 | + if(status){ |
1421 | + return S_dev_vecInstlFail; |
1422 | + } |
1423 | + |
1424 | + return 0; |
1425 | +} |
1426 | + |
1427 | +/* |
1428 | + * enable VME interrupt level |
1429 | + */ |
1430 | +static long rtemsDevEnableInterruptLevelVME (unsigned level) |
1431 | +{ |
1432 | + return BSP_enableVME_int_lvl(level); |
1433 | +} |
1434 | + |
1435 | +/* |
1436 | + * disable VME interrupt level |
1437 | + */ |
1438 | +static long rtemsDevDisableInterruptLevelVME (unsigned level) |
1439 | +{ |
1440 | + return BSP_disableVME_int_lvl(level); |
1441 | +} |
1442 | + |
1443 | +/* |
1444 | + * rtemsDevMapAddr () |
1445 | + */ |
1446 | +static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, |
1447 | + size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) |
1448 | +{ |
1449 | + long status; |
1450 | + |
1451 | + if (ppPhysicalAddress==NULL) { |
1452 | + return S_dev_badArgument; |
1453 | + } |
1454 | + |
1455 | + if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) |
1456 | + { |
1457 | + *ppPhysicalAddress = (void *) logicalAddress; |
1458 | + } |
1459 | + else |
1460 | + { |
1461 | + status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType], |
1462 | + logicalAddress, (unsigned long *)ppPhysicalAddress); |
1463 | + if (status) { |
1464 | + return S_dev_addrMapFail; |
1465 | + } |
1466 | + } |
1467 | + |
1468 | + return 0; |
1469 | +} |
1470 | + |
1471 | +/* |
1472 | + * a bus error safe "wordSize" read at the specified address which returns |
1473 | + * unsuccessful status if the device isnt present |
1474 | + */ |
1475 | +rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval); |
1476 | +static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) |
1477 | +{ |
1478 | + long status; |
1479 | + |
1480 | + /* |
1481 | + * this global variable exists in the nivxi library |
1482 | + */ |
1483 | + status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue); |
1484 | + if (status!=RTEMS_SUCCESSFUL) { |
1485 | + return S_dev_noDevice; |
1486 | + } |
1487 | + |
1488 | + return 0; |
1489 | +} |
1490 | + |
1491 | +/* |
1492 | + * a bus error safe "wordSize" write at the specified address which returns |
1493 | + * unsuccessful status if the device isnt present |
1494 | + */ |
1495 | +static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) |
1496 | +{ |
1497 | + long status; |
1498 | + |
1499 | + /* |
1500 | + * this global variable exists in the nivxi library |
1501 | + */ |
1502 | + status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue); |
1503 | + if (status!=RTEMS_SUCCESSFUL) { |
1504 | + return S_dev_noDevice; |
1505 | + } |
1506 | + |
1507 | + return 0; |
1508 | +} |
1509 | + |
1510 | +/* |
1511 | + * isrFetch() |
1512 | + */ |
1513 | +static myISR *isrFetch(unsigned vectorNumber, void **parg) |
1514 | +{ |
1515 | + /* |
1516 | + * fetch the handler or C stub attached at this vector |
1517 | + */ |
1518 | + return (myISR *) BSP_getVME_isr(vectorNumber,parg); |
1519 | +} |
1520 | + |
1521 | +/* |
1522 | + * determine if a VME interrupt vector is in use |
1523 | + */ |
1524 | +static int rtemsDevInterruptInUseVME (unsigned vectorNumber) |
1525 | +{ |
1526 | + int i; |
1527 | + myISR *psub; |
1528 | + void *arg; |
1529 | + |
1530 | + psub = isrFetch (vectorNumber,&arg); |
1531 | + |
1532 | + if (!psub) |
1533 | + return FALSE; |
1534 | + |
1535 | + /* |
1536 | + * its a C routine. Does it match a default handler? |
1537 | + */ |
1538 | + for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) { |
1539 | + if (defaultHandlerAddr[i] == psub) { |
1540 | + return FALSE; |
1541 | + } |
1542 | + } |
1543 | + |
1544 | + return TRUE; |
1545 | +} |
1546 | + |
1547 | + |
1548 | +/* |
1549 | + * unsolicitedHandlerEPICS() |
1550 | + * what gets called if they disconnect from an |
1551 | + * interrupt and an interrupt arrives on the |
1552 | + * disconnected vector |
1553 | + * |
1554 | + * NOTE: RTEMS may pass additional arguments - hope |
1555 | + * this doesn't disturb this handler... |
1556 | + * |
1557 | + * A cleaner way would be having a OS dependent |
1558 | + * macro to declare handler prototypes... |
1559 | + * |
1560 | + */ |
1561 | +static void unsolicitedHandlerEPICS(int vectorNumber) |
1562 | +{ |
1563 | + /* |
1564 | + * call epicInterruptContextMessage() |
1565 | + * and not errMessage() |
1566 | + * so we are certain that printf() |
1567 | + * does not get called at interrupt level |
1568 | + * |
1569 | + * NOTE: current RTEMS implementation only |
1570 | + * allows a static string to be passed |
1571 | + */ |
1572 | + epicsInterruptContextMessage( |
1573 | + "Interrupt to EPICS disconnected vector" |
1574 | + ); |
1575 | +} |
1576 | + |
1577 | +#endif /* defined(__PPC__) && defined(mpc750) */ |
1578 | + |
1579 | +/* |
1580 | + * Some vxWorks convenience routines |
1581 | + */ |
1582 | +void |
1583 | +bcopyLongs(char *source, char *destination, int nlongs) |
1584 | +{ |
1585 | + const long *s = (long *)source; |
1586 | + long *d = (long *)destination; |
1587 | + while(nlongs--) |
1588 | + *d++ = *s++; |
1589 | +} |
1590 | |
1591 | === added file 'src/libCom/osi/os/RTEMS-posix/osdInterrupt.c' |
1592 | --- src/libCom/osi/os/RTEMS-posix/osdInterrupt.c 1970-01-01 00:00:00 +0000 |
1593 | +++ src/libCom/osi/os/RTEMS-posix/osdInterrupt.c 2017-05-01 18:36:52 +0000 |
1594 | @@ -0,0 +1,59 @@ |
1595 | +/*************************************************************************\ |
1596 | +* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne |
1597 | +* National Laboratory. |
1598 | +* Copyright (c) 2002 The Regents of the University of California, as |
1599 | +* Operator of Los Alamos National Laboratory. |
1600 | +* EPICS BASE is distributed subject to a Software License Agreement found |
1601 | +* in file LICENSE that is included with this distribution. |
1602 | +\*************************************************************************/ |
1603 | +/* osi/default/osdInterrupt.c */ |
1604 | + |
1605 | +/* Author: Marty Kraimer Date: 15JUL99 */ |
1606 | + |
1607 | +#include <stddef.h> |
1608 | +#include <string.h> |
1609 | +#include <stdlib.h> |
1610 | +#include <stddef.h> |
1611 | +#include <stdio.h> |
1612 | + |
1613 | +#define epicsExportSharedSymbols |
1614 | +#include "epicsMutex.h" |
1615 | +#include "epicsThread.h" |
1616 | +#include "cantProceed.h" |
1617 | +#include "errlog.h" |
1618 | +#include "epicsInterrupt.h" |
1619 | + |
1620 | +#include <rtems/bspIo.h> |
1621 | +#include <rtems.h> |
1622 | + |
1623 | +epicsShareFunc int epicsInterruptLock() |
1624 | +{ |
1625 | + rtems_interrupt_level level; |
1626 | + |
1627 | + rtems_interrupt_disable (level); |
1628 | + return level; |
1629 | +} |
1630 | + |
1631 | +epicsShareFunc void epicsInterruptUnlock(int key) |
1632 | +{ |
1633 | + rtems_interrupt_level level = key; |
1634 | + |
1635 | + rtems_interrupt_enable (level); |
1636 | +} |
1637 | + |
1638 | +epicsShareFunc int epicsInterruptIsInterruptContext() |
1639 | +{ |
1640 | + return rtems_interrupt_is_in_progress (); |
1641 | +} |
1642 | + |
1643 | +epicsShareFunc void epicsInterruptContextMessage(const char *message) |
1644 | +{ |
1645 | + printk("%s", message); |
1646 | +} |
1647 | + |
1648 | + |
1649 | + |
1650 | + |
1651 | + |
1652 | + |
1653 | + |
1654 | |
1655 | === added file 'src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp' |
1656 | --- src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp 1970-01-01 00:00:00 +0000 |
1657 | +++ src/libCom/osi/os/RTEMS-posix/osdMessageQueue.cpp 2017-05-01 18:36:52 +0000 |
1658 | @@ -0,0 +1,163 @@ |
1659 | +/*************************************************************************\ |
1660 | +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1661 | +* National Laboratory. |
1662 | +* Copyright (c) 2002 The Regents of the University of California, as |
1663 | +* Operator of Los Alamos National Laboratory. |
1664 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
1665 | +* EPICS BASE is distributed subject to a Software License Agreement found |
1666 | +* in file LICENSE that is included with this distribution. |
1667 | +\*************************************************************************/ |
1668 | +/* |
1669 | + * Author W. Eric Norum |
1670 | + * Heinz Junkes |
1671 | + * |
1672 | + * Adapted to rtems4.12 |
1673 | + * -> posix message queues |
1674 | + * remove all internal calls (_xxx), remove e.g. Objects_Locations etc. |
1675 | + */ |
1676 | + |
1677 | +/* |
1678 | + * We want to access information which is |
1679 | + * normally hidden from application programs. |
1680 | + */ |
1681 | +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 |
1682 | + |
1683 | +#define epicsExportSharedSymbols |
1684 | +#include <assert.h> |
1685 | +#include <stdio.h> |
1686 | +#include <stdlib.h> |
1687 | +#include <string.h> |
1688 | +#include <rtems.h> |
1689 | +#include <rtems/error.h> |
1690 | +#include "epicsMessageQueue.h" |
1691 | +#include "errlog.h" |
1692 | +#include <epicsAtomic.h> |
1693 | + |
1694 | +#include <errno.h> |
1695 | +#include <mqueue.h> |
1696 | +#include <fcntl.h> |
1697 | + |
1698 | +epicsShareFunc epicsMessageQueueId epicsShareAPI |
1699 | +epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize) |
1700 | +{ |
1701 | + struct mq_attr the_attr; |
1702 | + epicsMessageQueueId id = (epicsMessageQueueId)calloc(1, sizeof(*id)); |
1703 | + |
1704 | + epicsAtomicIncrIntT(&id->idCnt); |
1705 | + sprintf(id->name, "MQ_%010d",epicsAtomicGetIntT(&id->idCnt)); |
1706 | + the_attr.mq_maxmsg = capacity; |
1707 | + the_attr.mq_msgsize = maximumMessageSize; |
1708 | + id->id = mq_open(id->name, O_RDWR | O_CREAT | O_EXCL, 0644, &the_attr); |
1709 | + if (id->id < 0) { |
1710 | + errlogPrintf ("Can't create message queue: %s\n", strerror (errno)); |
1711 | + return NULL; |
1712 | + } |
1713 | + return id; |
1714 | +} |
1715 | + |
1716 | +epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy( |
1717 | + epicsMessageQueueId id) |
1718 | +{ |
1719 | + int rv; |
1720 | + rv = mq_close(id->id); |
1721 | + if( rv ) { |
1722 | + errlogPrintf("epicsMessageQueueDestroy mq_close failed: %s\n", |
1723 | + strerror(rv)); |
1724 | + } |
1725 | + rv = mq_unlink(id->name); |
1726 | + if( rv ) { |
1727 | + errlogPrintf("epicsMessageQueueDestroy mq_unlink %s failed: %s\n", |
1728 | + id->name, strerror(rv)); |
1729 | + } |
1730 | + free(id); |
1731 | +} |
1732 | + |
1733 | +epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend( |
1734 | + epicsMessageQueueId id, |
1735 | + void *message, |
1736 | + unsigned int messageSize) |
1737 | +{ |
1738 | + struct timespec ts; |
1739 | + clock_gettime(CLOCK_REALTIME, &ts); |
1740 | + return mq_timedsend(id->id, (char const *)message, messageSize, 0, &ts); |
1741 | +} |
1742 | + |
1743 | +epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( |
1744 | + epicsMessageQueueId id, |
1745 | + void *message, |
1746 | + unsigned int messageSize, |
1747 | + double timeout) |
1748 | +{ |
1749 | + struct timespec ts; |
1750 | + unsigned long micros; |
1751 | + |
1752 | + // assume timeout in sec |
1753 | + micros = (unsigned long)(timeout * 1000000.0); |
1754 | + clock_gettime(CLOCK_REALTIME, &ts); |
1755 | + ts.tv_sec += micros / 1000000L; |
1756 | + ts.tv_nsec += (micros % 1000000L) * 1000L; |
1757 | + |
1758 | + return mq_timedsend (id->id, (const char *)message, messageSize, 0, &ts); |
1759 | +} |
1760 | + |
1761 | +epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive( |
1762 | + epicsMessageQueueId id, |
1763 | + void *message, |
1764 | + unsigned int size) |
1765 | +{ |
1766 | + struct timespec ts; |
1767 | + clock_gettime(CLOCK_REALTIME, &ts); |
1768 | + return mq_timedreceive(id->id, (char *)message, size, NULL, &ts); |
1769 | +} |
1770 | + |
1771 | +epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( |
1772 | + epicsMessageQueueId id, |
1773 | + void *message, |
1774 | + unsigned int size, |
1775 | + double timeout) |
1776 | +{ |
1777 | + unsigned long micros; |
1778 | + struct timespec ts; |
1779 | + |
1780 | + micros = (unsigned long)(timeout * 1000000.0); |
1781 | + clock_gettime(CLOCK_REALTIME, &ts); |
1782 | + ts.tv_sec += micros / 1000000L; |
1783 | + ts.tv_nsec += (micros % 1000000L) * 1000L; |
1784 | + |
1785 | + return mq_timedreceive(id->id, (char *)message, size, NULL, &ts); |
1786 | +} |
1787 | + |
1788 | +epicsShareFunc int epicsShareAPI epicsMessageQueuePending( |
1789 | + epicsMessageQueueId id) |
1790 | +{ |
1791 | + int rv; |
1792 | + struct mq_attr the_attr; |
1793 | + |
1794 | + rv = mq_getattr(id->id, &the_attr); |
1795 | + if (rv) { |
1796 | + errlogPrintf("Epics Message queue %x (%s) get attr failed: %s\n", |
1797 | + (unsigned int)id->id, id->name, strerror(rv)); |
1798 | + return -1; |
1799 | + } |
1800 | + return the_attr.mq_curmsgs; |
1801 | +} |
1802 | + |
1803 | +epicsShareFunc void epicsShareAPI epicsMessageQueueShow( |
1804 | + epicsMessageQueueId id, |
1805 | + int level) |
1806 | +{ |
1807 | + int rv; |
1808 | + struct mq_attr the_attr; |
1809 | + |
1810 | + rv = mq_getattr(id->id, &the_attr); |
1811 | + if (rv) { |
1812 | + errlogPrintf("Epics Message queue %x (%s) get attr failed: %s\n", |
1813 | + (unsigned int)id->id, id->id, strerror(rv)); |
1814 | + } |
1815 | + |
1816 | + printf("Message Queue Used:%ld Max Msg:%lu", the_attr.mq_curmsgs, the_attr.mq_maxmsg); |
1817 | + if (level >= 1) |
1818 | + printf(" Maximum size:%lu", the_attr.mq_msgsize); |
1819 | + |
1820 | + printf("\n"); |
1821 | +} |
1822 | |
1823 | === added file 'src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h' |
1824 | --- src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h 1970-01-01 00:00:00 +0000 |
1825 | +++ src/libCom/osi/os/RTEMS-posix/osdMessageQueue.h 2017-05-01 18:36:52 +0000 |
1826 | @@ -0,0 +1,31 @@ |
1827 | +/*************************************************************************\ |
1828 | + * * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1829 | + * * National Laboratory. |
1830 | + * * Copyright (c) 2002 The Regents of the University of California, as |
1831 | + * * Operator of Los Alamos National Laboratory. |
1832 | + * * Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
1833 | + * * EPICS BASE is distributed subject to a Software License Agreement found |
1834 | + * * in file LICENSE that is included with this distribution. |
1835 | + * \*************************************************************************/ |
1836 | +/* |
1837 | + * Author W. Eric Norum |
1838 | + * Heinz Junkes |
1839 | + * |
1840 | + * Eric's note : Very thin shims around vxWorks routines |
1841 | + * |
1842 | + * Adapted to rtems4.12 |
1843 | + * -> posix message queues |
1844 | + */ |
1845 | + |
1846 | +#include <rtems.h> |
1847 | +#include <mqueue.h> |
1848 | + |
1849 | +struct epicsMessageQueueOSD { |
1850 | + mqd_t id; |
1851 | + char name[24]; |
1852 | + int idCnt; |
1853 | + |
1854 | +}; |
1855 | + |
1856 | +#define epicsMessageQueueSend(q,m,l) (mq_send((q)->id, (const char*)(m), (l), 0)) |
1857 | +#define epicsMessageQueueReceive(q,m,s) (mq_receive((q)->id, (char*)(m), (s), NULL)) |
1858 | |
1859 | === added file 'src/libCom/osi/os/RTEMS-posix/osdMutex.c' |
1860 | --- src/libCom/osi/os/RTEMS-posix/osdMutex.c 1970-01-01 00:00:00 +0000 |
1861 | +++ src/libCom/osi/os/RTEMS-posix/osdMutex.c 2017-05-01 18:36:52 +0000 |
1862 | @@ -0,0 +1,6 @@ |
1863 | +#include <rtems.h> |
1864 | +#include <rtems/error.h> |
1865 | +#include <rtems/rtems/tasks.h> |
1866 | +#include <rtems/score/threadimpl.h> |
1867 | + |
1868 | +#include "../posix/osdMutex.c" |
1869 | |
1870 | === added file 'src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c' |
1871 | --- src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c 1970-01-01 00:00:00 +0000 |
1872 | +++ src/libCom/osi/os/RTEMS-posix/osdPoolStatus.c 2017-05-01 18:36:52 +0000 |
1873 | @@ -0,0 +1,34 @@ |
1874 | +/*************************************************************************\ |
1875 | +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1876 | +* National Laboratory. |
1877 | +* Copyright (c) 2002 The Regents of the University of California, as |
1878 | +* Operator of Los Alamos National Laboratory. |
1879 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
1880 | +* EPICS BASE is distributed subject to a Software License Agreement found |
1881 | +* in file LICENSE that is included with this distribution. |
1882 | +\*************************************************************************/ |
1883 | + |
1884 | +/* |
1885 | + * Heinz Junkes |
1886 | + * Adapted to rtems4.12 |
1887 | + */ |
1888 | + |
1889 | +#include <rtems.h> |
1890 | +#include <rtems/malloc.h> |
1891 | +#include <rtems/score/heap.h> |
1892 | +#define epicsExportSharedSymbols |
1893 | +#include "osiPoolStatus.h" |
1894 | + |
1895 | +/* |
1896 | + * osiSufficentSpaceInPool () |
1897 | + * |
1898 | + */ |
1899 | +epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) |
1900 | +{ |
1901 | + unsigned long n; |
1902 | + Heap_Information_block info; |
1903 | + |
1904 | + malloc_info( &info ); |
1905 | + n = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed); |
1906 | + return (n > (50000 + contiguousBlockSize)); |
1907 | +} |
1908 | |
1909 | === added file 'src/libCom/osi/os/RTEMS-posix/osdSock.h' |
1910 | --- src/libCom/osi/os/RTEMS-posix/osdSock.h 1970-01-01 00:00:00 +0000 |
1911 | +++ src/libCom/osi/os/RTEMS-posix/osdSock.h 2017-05-01 18:36:52 +0000 |
1912 | @@ -0,0 +1,111 @@ |
1913 | +/*************************************************************************\ |
1914 | +* Copyright (c) 2002 The University of Saskatchewan |
1915 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
1916 | +* EPICS BASE is distributed subject to a Software License Agreement found |
1917 | +* in file LICENSE that is included with this distribution. |
1918 | +\*************************************************************************/ |
1919 | +/* |
1920 | + * RTEMS osdSock.h |
1921 | + * Author: W. Eric Norum |
1922 | + * Heinz Junkes |
1923 | + * |
1924 | + * Adapted to rtems4.12 |
1925 | + */ |
1926 | +#ifndef osdSockH |
1927 | +#define osdSockH |
1928 | + |
1929 | +#include <errno.h> |
1930 | + |
1931 | +#include <sys/types.h> |
1932 | +#include <sys/param.h> |
1933 | +#include <sys/time.h> |
1934 | +#include <sys/socket.h> |
1935 | +#include <sys/ioctl.h> |
1936 | +#include <netinet/in.h> |
1937 | +#include <netinet/tcp.h> |
1938 | +#include <arpa/inet.h> |
1939 | +#include <net/if.h> |
1940 | +#include <netdb.h> |
1941 | +#include <ifaddrs.h> /* getifaddrs() */ |
1942 | +#include <unistd.h> |
1943 | + |
1944 | +#ifdef __cplusplus |
1945 | +extern "C" { |
1946 | +#endif |
1947 | + |
1948 | +int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); |
1949 | + |
1950 | +#ifdef __cplusplus |
1951 | +} |
1952 | +#endif |
1953 | + |
1954 | + |
1955 | +#ifndef IPPORT_USERRESERVED |
1956 | +#define IPPORT_USERRESERVED 5000 |
1957 | +#endif |
1958 | + |
1959 | +#define USE_IFADDRS |
1960 | + |
1961 | +typedef int SOCKET; |
1962 | +#define INVALID_SOCKET (-1) |
1963 | +#define SOCKERRNO errno |
1964 | +#define socket_ioctl(A,B,C) ioctl(A,B,C) |
1965 | +typedef int osiSockIoctl_t; |
1966 | +typedef socklen_t osiSocklen_t; |
1967 | + |
1968 | +#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE) |
1969 | + |
1970 | +#define SOCK_EWOULDBLOCK EWOULDBLOCK |
1971 | +#define SOCK_ENOBUFS ENOBUFS |
1972 | +#define SOCK_ECONNRESET ECONNRESET |
1973 | +#define SOCK_ETIMEDOUT ETIMEDOUT |
1974 | +#define SOCK_EADDRINUSE EADDRINUSE |
1975 | +#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL |
1976 | +#define SOCK_ECONNREFUSED ECONNREFUSED |
1977 | +#define SOCK_ECONNABORTED ECONNABORTED |
1978 | +#define SOCK_EINPROGRESS EINPROGRESS |
1979 | +#define SOCK_EISCONN EISCONN |
1980 | +#define SOCK_EALREADY EALREADY |
1981 | +#define SOCK_EINVAL EINVAL |
1982 | +#define SOCK_EINTR EINTR |
1983 | +#define SOCK_EPIPE EPIPE |
1984 | +#define SOCK_EMFILE EMFILE |
1985 | +#define SOCK_SHUTDOWN EPIPE |
1986 | +#define SOCK_ENOTSOCK ENOTSOCK |
1987 | +#define SOCK_EBADF EBADF |
1988 | + |
1989 | +// already defined in newlib |
1990 | +//#define bzero(p,n) memset(p,0,n) |
1991 | +#include <sys/time.h> |
1992 | +#include <sys/types.h> |
1993 | +#include <unistd.h> |
1994 | + |
1995 | +#ifndef INADDR_LOOPBACK |
1996 | +#define INADDR_LOOPBACK (u_long)0x7F000001 |
1997 | +#endif |
1998 | + |
1999 | +#ifndef INADDR_NONE |
2000 | +# define INADDR_NONE (0xffffffff) |
2001 | +#endif |
2002 | + |
2003 | +/* |
2004 | + * For shutdown() |
2005 | + */ |
2006 | +#ifndef SHUT_RD |
2007 | +# define SHUT_RD 0 |
2008 | +#endif |
2009 | + |
2010 | +#ifndef SHUT_WR |
2011 | +# define SHUT_WR 1 |
2012 | +#endif |
2013 | + |
2014 | +#ifndef SHUT_RDWR |
2015 | +# define SHUT_RDWR 2 |
2016 | +#endif |
2017 | + |
2018 | +/* |
2019 | + * Ensure that we get the right network code in default/osdNetIntf.c. |
2020 | + */ |
2021 | +#define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name)) |
2022 | + |
2023 | +#endif /*osdSockH*/ |
2024 | |
2025 | === modified file 'src/libCom/osi/os/WIN32/osdNetIntf.c' |
2026 | --- src/libCom/osi/os/WIN32/osdNetIntf.c 2017-02-01 17:57:04 +0000 |
2027 | +++ src/libCom/osi/os/WIN32/osdNetIntf.c 2017-05-01 18:36:52 +0000 |
2028 | @@ -3,6 +3,8 @@ |
2029 | * National Laboratory. |
2030 | * Copyright (c) 2002 The Regents of the University of California, as |
2031 | * Operator of Los Alamos National Laboratory. |
2032 | +* Copyright (c) 2015 Brookhaven Science Associates as Operator of |
2033 | +* Brookhaven National Lab. |
2034 | * EPICS BASE is distributed subject to a Software License Agreement found |
2035 | * in file LICENSE that is included with this distribution. |
2036 | \*************************************************************************/ |
2037 | @@ -40,214 +42,110 @@ |
2038 | #include "epicsThread.h" |
2039 | #include "epicsVersion.h" |
2040 | |
2041 | -static osiSockAddr osiLocalAddrResult; |
2042 | -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; |
2043 | - |
2044 | -/* |
2045 | - * osiLocalAddr () |
2046 | - */ |
2047 | static void osiLocalAddrOnce ( void *raw ) |
2048 | { |
2049 | - SOCKET *psocket = raw; |
2050 | - osiSockAddr addr; |
2051 | - int status; |
2052 | - INTERFACE_INFO *pIfinfo; |
2053 | - INTERFACE_INFO *pIfinfoList = NULL; |
2054 | - unsigned nelem; |
2055 | - DWORD numifs; |
2056 | - DWORD cbBytesReturned; |
2057 | - |
2058 | - memset ( (void *) &addr, '\0', sizeof ( addr ) ); |
2059 | - addr.sa.sa_family = AF_UNSPEC; |
2060 | - |
2061 | - /* only valid for winsock 2 and above */ |
2062 | - if ( wsaMajorVersion() < 2 ) { |
2063 | - goto fail; |
2064 | - } |
2065 | - |
2066 | - nelem = 100; |
2067 | - pIfinfoList = (INTERFACE_INFO *) calloc ( nelem, sizeof (INTERFACE_INFO) ); |
2068 | - if (!pIfinfoList) { |
2069 | - errlogPrintf ("calloc failed\n"); |
2070 | - goto fail; |
2071 | - } |
2072 | - |
2073 | - status = WSAIoctl (*psocket, SIO_GET_INTERFACE_LIST, NULL, 0, |
2074 | - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), |
2075 | - &cbBytesReturned, NULL, NULL); |
2076 | - |
2077 | - if (status != 0 || cbBytesReturned == 0) { |
2078 | - errlogPrintf ("WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); |
2079 | - goto fail; |
2080 | - } |
2081 | - |
2082 | - numifs = cbBytesReturned / sizeof(INTERFACE_INFO); |
2083 | - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ |
2084 | - |
2085 | - /* |
2086 | - * dont use interfaces that have been disabled |
2087 | - */ |
2088 | - if (!(pIfinfo->iiFlags & IFF_UP)) { |
2089 | - continue; |
2090 | - } |
2091 | - |
2092 | - /* |
2093 | - * dont use the loop back interface |
2094 | - */ |
2095 | - if (pIfinfo->iiFlags & IFF_LOOPBACK) { |
2096 | - continue; |
2097 | - } |
2098 | - |
2099 | - addr.sa = pIfinfo->iiAddress.Address; |
2100 | - |
2101 | - /* Work around MS Winsock2 bugs */ |
2102 | - if (addr.sa.sa_family == 0) { |
2103 | - addr.sa.sa_family = AF_INET; |
2104 | - } |
2105 | - |
2106 | - osiLocalAddrResult = addr; |
2107 | - free ( pIfinfoList ); |
2108 | - return; |
2109 | - } |
2110 | - |
2111 | - errlogPrintf ( |
2112 | - "osiLocalAddr(): only loopback found\n"); |
2113 | -fail: |
2114 | - /* fallback to loopback */ |
2115 | - memset ( (void *) &addr, '\0', sizeof ( addr ) ); |
2116 | - addr.ia.sin_family = AF_INET; |
2117 | - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
2118 | - osiLocalAddrResult = addr; |
2119 | - |
2120 | - free ( pIfinfoList ); |
2121 | -} |
2122 | - |
2123 | -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) |
2124 | -{ |
2125 | - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket); |
2126 | - return osiLocalAddrResult; |
2127 | -} |
2128 | - |
2129 | -/* |
2130 | - * osiSockDiscoverBroadcastAddresses () |
2131 | - */ |
2132 | -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses |
2133 | - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) |
2134 | -{ |
2135 | - int status; |
2136 | - INTERFACE_INFO *pIfinfo; |
2137 | - INTERFACE_INFO *pIfinfoList; |
2138 | - unsigned nelem; |
2139 | - int numifs; |
2140 | - DWORD cbBytesReturned; |
2141 | - osiSockAddrNode *pNewNode; |
2142 | - |
2143 | - if ( pMatchAddr->sa.sa_family == AF_INET ) { |
2144 | - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { |
2145 | - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); |
2146 | - if ( pNewNode == NULL ) { |
2147 | - return; |
2148 | - } |
2149 | - pNewNode->addr.ia.sin_family = AF_INET; |
2150 | - pNewNode->addr.ia.sin_port = htons ( 0 ); |
2151 | - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); |
2152 | - ellAdd ( pList, &pNewNode->node ); |
2153 | - return; |
2154 | - } |
2155 | - } |
2156 | +int ret = -1, status, foundlo = 0; |
2157 | + SOCKET sock; |
2158 | + unsigned nelem = 10, i; |
2159 | + INTERFACE_INFO *info = NULL; |
2160 | + DWORD cbBytesReturned; |
2161 | |
2162 | /* only valid for winsock 2 and above */ |
2163 | if (wsaMajorVersion() < 2 ) { |
2164 | - fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n"); |
2165 | - return; |
2166 | - } |
2167 | - |
2168 | - nelem = 100; |
2169 | - pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO)); |
2170 | - if(!pIfinfoList){ |
2171 | - return; |
2172 | - } |
2173 | - |
2174 | - status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST, |
2175 | - NULL, 0, |
2176 | - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), |
2177 | - &cbBytesReturned, NULL, NULL); |
2178 | + fprintf(stderr, "Interface discovery not supported for winsock 1\n" |
2179 | + "Need to set EPICS_CA_AUTO_ADDR_LIST=NO\n"); |
2180 | + return ret; |
2181 | + } |
2182 | + |
2183 | + sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); |
2184 | + if(sock==INVALID_SOCKET) |
2185 | + return ret; |
2186 | + |
2187 | + info = calloc(nelem, sizeof(*info)); |
2188 | + if(!info) |
2189 | + goto cleanup; |
2190 | + |
2191 | + /* In future use SIO_GET_INTERFACE_LIST_EX to include IPv6 */ |
2192 | + |
2193 | + status = WSAIoctl (sock, SIO_GET_INTERFACE_LIST, |
2194 | + NULL, 0, |
2195 | + (LPVOID)info, nelem*sizeof(*info), |
2196 | + &cbBytesReturned, NULL, NULL); |
2197 | |
2198 | if (status != 0 || cbBytesReturned == 0) { |
2199 | fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); |
2200 | - free(pIfinfoList); |
2201 | - return; |
2202 | - } |
2203 | - |
2204 | - numifs = cbBytesReturned/sizeof(INTERFACE_INFO); |
2205 | - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ |
2206 | - |
2207 | - /* |
2208 | - * dont bother with interfaces that have been disabled |
2209 | - */ |
2210 | - if (!(pIfinfo->iiFlags & IFF_UP)) { |
2211 | - continue; |
2212 | - } |
2213 | - |
2214 | - if (pIfinfo->iiFlags & IFF_LOOPBACK) { |
2215 | - continue; |
2216 | - } |
2217 | - |
2218 | - /* |
2219 | - * work around WS2 bug |
2220 | - */ |
2221 | - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { |
2222 | - if (pIfinfo->iiAddress.Address.sa_family == 0) { |
2223 | - pIfinfo->iiAddress.Address.sa_family = AF_INET; |
2224 | - } |
2225 | - } |
2226 | - |
2227 | - /* |
2228 | - * if it isnt a wildcarded interface then look for |
2229 | - * an exact match |
2230 | - */ |
2231 | - if (pMatchAddr->sa.sa_family != AF_UNSPEC) { |
2232 | - if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) { |
2233 | - continue; |
2234 | - } |
2235 | - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { |
2236 | - continue; |
2237 | - } |
2238 | - if (pMatchAddr->sa.sa_family != AF_INET) { |
2239 | - continue; |
2240 | - } |
2241 | - if (pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY)) { |
2242 | - if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr) { |
2243 | - continue; |
2244 | - } |
2245 | - } |
2246 | - } |
2247 | - |
2248 | - pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); |
2249 | - if (pNewNode==NULL) { |
2250 | - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n"); |
2251 | - return; |
2252 | - } |
2253 | - |
2254 | - if (pIfinfo->iiAddress.Address.sa_family == AF_INET && |
2255 | - pIfinfo->iiFlags & IFF_BROADCAST) { |
2256 | - const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr; |
2257 | - const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr; |
2258 | - const unsigned addr = pIfinfo->iiAddress.AddressIn.sin_addr.s_addr; |
2259 | - unsigned result = (addr & mask) | (bcast &~mask); |
2260 | - pNewNode->addr.ia.sin_family = AF_INET; |
2261 | - pNewNode->addr.ia.sin_addr.s_addr = result; |
2262 | - pNewNode->addr.ia.sin_port = htons ( 0 ); |
2263 | - } |
2264 | - else { |
2265 | - pNewNode->addr.sa = pIfinfo->iiBroadcastAddress.Address; |
2266 | - } |
2267 | - |
2268 | - /* |
2269 | - * LOCK applied externally |
2270 | - */ |
2271 | - ellAdd (pList, &pNewNode->node); |
2272 | - } |
2273 | - |
2274 | - free (pIfinfoList); |
2275 | + goto cleanup; |
2276 | + } |
2277 | + |
2278 | + nelem = cbBytesReturned/sizeof(*info); |
2279 | + |
2280 | + for(i=0; i<nelem; i++) |
2281 | + { |
2282 | + unsigned int flags; |
2283 | + osiInterfaceInfo *node = calloc(1, sizeof(*node)); |
2284 | + if(!node) |
2285 | + goto cleanup; |
2286 | + |
2287 | + /* work around WS2 bug */ |
2288 | + if(info[i].iiAddress.AddressIn.sin_family==0) |
2289 | + info[i].iiAddress.AddressIn.sin_family = AF_INET; |
2290 | + |
2291 | + if(info[i].iiAddress.AddressIn.sin_family!=AF_INET) { |
2292 | + free(node); |
2293 | + continue; |
2294 | + } |
2295 | + |
2296 | + node->address.ia = info[i].iiAddress.AddressIn; |
2297 | + node->netmask.ia = info[i].iiNetmask.AddressIn; |
2298 | + node->endpoint.ia = info[i].iiBroadcastAddress.AddressIn; |
2299 | + |
2300 | + flags = info[i].iiFlags; |
2301 | + |
2302 | + if(flags&IFF_UP) node->up = 1; |
2303 | + if(flags&IFF_BROADCAST) node->broadcast = 1; |
2304 | + if(flags&IFF_MULTICAST) node->multicast = 1; |
2305 | + if(flags&IFF_LOOPBACK) node->loopback = 1; |
2306 | + /* BSD sockets have IFF_POINTOPOINT while winsock has IFF_POINTTOPOINT |
2307 | + * Note the extra 'T' |
2308 | + */ |
2309 | + if(flags&IFF_POINTTOPOINT) node->point2point = 1; |
2310 | + |
2311 | + if(node->broadcast && node->point2point) { |
2312 | + errlogPrintf("Interface %u claims both broadcast and point to point," |
2313 | + " which should not be possible. Assuming broadcast only.", |
2314 | + i); |
2315 | + node->point2point = 0; |
2316 | + } |
2317 | + |
2318 | + if(node->loopback) foundlo = 1; |
2319 | + ellAdd(pList, &node->node); |
2320 | + } |
2321 | + |
2322 | + if(!foundlo) { |
2323 | + /* sometimes the loopback isn't included (WINE+mingw) */ |
2324 | + osiInterfaceInfo *node = calloc(1, sizeof(*node)); |
2325 | + if(!node) |
2326 | + goto cleanup; |
2327 | + |
2328 | + node->up = 1; |
2329 | + node->loopback = 1; |
2330 | + |
2331 | + node->address.ia.sin_family = AF_INET; |
2332 | + node->address.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
2333 | + node->address.ia.sin_port = 0; |
2334 | + |
2335 | + node->netmask.ia.sin_family = AF_INET; |
2336 | + node->netmask.ia.sin_addr.s_addr = htonl(0xff000000); |
2337 | + node->netmask.ia.sin_port = 0; |
2338 | + |
2339 | + ellInsert(pList, NULL, &node->node); |
2340 | + } |
2341 | + |
2342 | + ret = 0; |
2343 | +cleanup: |
2344 | + if(ret) |
2345 | + ellFree(pList); |
2346 | + free(info); |
2347 | + epicsSocketDestroy(sock); |
2348 | + return ret; |
2349 | } |
2350 | |
2351 | === modified file 'src/libCom/osi/os/default/osdNetIntf.c' |
2352 | --- src/libCom/osi/os/default/osdNetIntf.c 2017-02-01 17:57:04 +0000 |
2353 | +++ src/libCom/osi/os/default/osdNetIntf.c 2017-05-01 18:36:52 +0000 |
2354 | @@ -3,6 +3,8 @@ |
2355 | * National Laboratory. |
2356 | * Copyright (c) 2002 The Regents of the University of California, as |
2357 | * Operator of Los Alamos National Laboratory. |
2358 | +* Copyright (c) 2015 Brookhaven Science Associates as Operator of |
2359 | +* Brookhaven National Lab. |
2360 | * EPICS BASE Versions 3.13.7 |
2361 | * and higher are distributed subject to a Software License Agreement found |
2362 | * in file LICENSE that is included with this distribution. |
2363 | @@ -19,6 +21,7 @@ |
2364 | #include <stdlib.h> |
2365 | |
2366 | #define epicsExportSharedSymbols |
2367 | +#include "dbDefs.h" |
2368 | #include "osiSock.h" |
2369 | #include "epicsAssert.h" |
2370 | #include "errlog.h" |
2371 | @@ -30,323 +33,155 @@ |
2372 | # define ifDepenDebugPrintf(argsInParen) |
2373 | #endif |
2374 | |
2375 | -static osiSockAddr osiLocalAddrResult; |
2376 | -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; |
2377 | - |
2378 | -/* |
2379 | - * Determine the size of an ifreq structure |
2380 | - * Made difficult by the fact that addresses larger than the structure |
2381 | - * size may be returned from the kernel. |
2382 | - */ |
2383 | -static size_t ifreqSize ( struct ifreq *pifreq ) |
2384 | -{ |
2385 | - size_t size; |
2386 | - |
2387 | - size = ifreq_size ( pifreq ); |
2388 | - if ( size < sizeof ( *pifreq ) ) { |
2389 | - size = sizeof ( *pifreq ); |
2390 | - } |
2391 | - return size; |
2392 | -} |
2393 | - |
2394 | -/* |
2395 | - * Move to the next ifreq structure |
2396 | - */ |
2397 | -static struct ifreq * ifreqNext ( struct ifreq *pifreq ) |
2398 | -{ |
2399 | - struct ifreq *ifr; |
2400 | - |
2401 | - ifr = ( struct ifreq * )( ifreqSize (pifreq) + ( char * ) pifreq ); |
2402 | - ifDepenDebugPrintf( ("ifreqNext() pifreq %p, size 0x%x, ifr 0x%p\n", pifreq, (unsigned)ifreqSize (pifreq), ifr) ); |
2403 | - return ifr; |
2404 | -} |
2405 | - |
2406 | - |
2407 | -/* |
2408 | - * osiSockDiscoverBroadcastAddresses () |
2409 | - */ |
2410 | -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses |
2411 | - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) |
2412 | -{ |
2413 | - static const unsigned nelem = 100; |
2414 | - int status; |
2415 | - struct ifconf ifconf; |
2416 | - struct ifreq *pIfreqList; |
2417 | - struct ifreq *pIfreqListEnd; |
2418 | - struct ifreq *pifreq; |
2419 | - struct ifreq *pnextifreq; |
2420 | - osiSockAddrNode *pNewNode; |
2421 | - |
2422 | - if ( pMatchAddr->sa.sa_family == AF_INET ) { |
2423 | - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { |
2424 | - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); |
2425 | - if ( pNewNode == NULL ) { |
2426 | - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); |
2427 | - return; |
2428 | - } |
2429 | - pNewNode->addr.ia.sin_family = AF_INET; |
2430 | - pNewNode->addr.ia.sin_port = htons ( 0 ); |
2431 | - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); |
2432 | - ellAdd ( pList, &pNewNode->node ); |
2433 | - return; |
2434 | - } |
2435 | - } |
2436 | - |
2437 | - /* |
2438 | - * use pool so that we avoid using too much stack space |
2439 | - * |
2440 | - * nelem is set to the maximum interfaces |
2441 | - * on one machine here |
2442 | - */ |
2443 | - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pifreq) ); |
2444 | - if (!pIfreqList) { |
2445 | - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory to complete request\n"); |
2446 | - return; |
2447 | - } |
2448 | - |
2449 | - ifconf.ifc_len = nelem * sizeof(*pifreq); |
2450 | - ifconf.ifc_req = pIfreqList; |
2451 | - status = socket_ioctl (socket, SIOCGIFCONF, &ifconf); |
2452 | - if (status < 0 || ifconf.ifc_len == 0) { |
2453 | - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration (%d)\n", status); |
2454 | - free (pIfreqList); |
2455 | - return; |
2456 | - } |
2457 | - |
2458 | - pIfreqListEnd = (struct ifreq *) (ifconf.ifc_len + (char *) pIfreqList); |
2459 | - pIfreqListEnd--; |
2460 | - |
2461 | - for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { |
2462 | - uint32_t current_ifreqsize; |
2463 | - |
2464 | - /* |
2465 | - * find the next ifreq |
2466 | - */ |
2467 | - pnextifreq = ifreqNext (pifreq); |
2468 | - |
2469 | - /* determine ifreq size */ |
2470 | - current_ifreqsize = ifreqSize ( pifreq ); |
2471 | - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ |
2472 | - memmove(pIfreqList, pifreq, current_ifreqsize); |
2473 | - |
2474 | - ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n", |
2475 | - pIfreqList->ifr_name, |
2476 | - (unsigned)ifreq_size(pifreq), |
2477 | - (unsigned)current_ifreqsize)); |
2478 | - |
2479 | - /* |
2480 | - * If its not an internet interface then dont use it |
2481 | - */ |
2482 | - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { |
2483 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) ); |
2484 | - continue; |
2485 | - } |
2486 | - |
2487 | - /* |
2488 | - * if it isnt a wildcarded interface then look for |
2489 | - * an exact match |
2490 | - */ |
2491 | - if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) { |
2492 | - if ( pMatchAddr->sa.sa_family != AF_INET ) { |
2493 | - continue; |
2494 | - } |
2495 | - if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) { |
2496 | - struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr; |
2497 | - if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) { |
2498 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) ); |
2499 | - continue; |
2500 | - } |
2501 | - } |
2502 | - } |
2503 | - |
2504 | - status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList ); |
2505 | - if ( status ) { |
2506 | - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name); |
2507 | - continue; |
2508 | - } |
2509 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" flags: %x\n", pIfreqList->ifr_name, pIfreqList->ifr_flags) ); |
2510 | - |
2511 | - /* |
2512 | - * dont bother with interfaces that have been disabled |
2513 | - */ |
2514 | - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { |
2515 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) ); |
2516 | - continue; |
2517 | - } |
2518 | - |
2519 | - /* |
2520 | - * dont use the loop back interface |
2521 | - */ |
2522 | - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { |
2523 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) ); |
2524 | - continue; |
2525 | - } |
2526 | - |
2527 | - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); |
2528 | - if ( pNewNode == NULL ) { |
2529 | - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); |
2530 | - free ( pIfreqList ); |
2531 | - return; |
2532 | - } |
2533 | - |
2534 | - /* |
2535 | - * If this is an interface that supports |
2536 | - * broadcast fetch the broadcast address. |
2537 | - * |
2538 | - * Otherwise if this is a point to point |
2539 | - * interface then use the destination address. |
2540 | - * |
2541 | - * Otherwise CA will not query through the |
2542 | - * interface. |
2543 | - */ |
2544 | - if ( pIfreqList->ifr_flags & IFF_BROADCAST ) { |
2545 | - osiSockAddr baddr; |
2546 | - status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList); |
2547 | - if ( status ) { |
2548 | - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name); |
2549 | - free ( pNewNode ); |
2550 | - continue; |
2551 | - } |
2552 | - baddr.sa = pIfreqList->ifr_broadaddr; |
2553 | - if (baddr.ia.sin_family==AF_INET && baddr.ia.sin_addr.s_addr != INADDR_ANY) { |
2554 | - pNewNode->addr.sa = pIfreqList->ifr_broadaddr; |
2555 | - ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); |
2556 | - } else { |
2557 | - ifDepenDebugPrintf ( ( "Ignoring broadcast addr = \n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); |
2558 | - free ( pNewNode ); |
2559 | - continue; |
2560 | - } |
2561 | - } |
2562 | -#if defined (IFF_POINTOPOINT) |
2563 | - else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) { |
2564 | - status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList); |
2565 | - if ( status ) { |
2566 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) ); |
2567 | - free ( pNewNode ); |
2568 | - continue; |
2569 | - } |
2570 | - pNewNode->addr.sa = pIfreqList->ifr_dstaddr; |
2571 | - } |
2572 | -#endif |
2573 | - else { |
2574 | - ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) ); |
2575 | - free ( pNewNode ); |
2576 | - continue; |
2577 | - } |
2578 | - |
2579 | - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) ); |
2580 | - |
2581 | - /* |
2582 | - * LOCK applied externally |
2583 | - */ |
2584 | - ellAdd ( pList, &pNewNode->node ); |
2585 | - } |
2586 | - |
2587 | - free ( pIfreqList ); |
2588 | -} |
2589 | - |
2590 | -/* |
2591 | - * osiLocalAddr () |
2592 | - */ |
2593 | -static void osiLocalAddrOnce (void *raw) |
2594 | -{ |
2595 | - SOCKET *psocket = raw; |
2596 | - const unsigned nelem = 100; |
2597 | - osiSockAddr addr; |
2598 | - int status; |
2599 | - struct ifconf ifconf; |
2600 | - struct ifreq *pIfreqList; |
2601 | - struct ifreq *pifreq; |
2602 | - struct ifreq *pIfreqListEnd; |
2603 | - struct ifreq *pnextifreq; |
2604 | - |
2605 | - memset ( (void *) &addr, '\0', sizeof ( addr ) ); |
2606 | - addr.sa.sa_family = AF_UNSPEC; |
2607 | - |
2608 | - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pIfreqList) ); |
2609 | - if ( ! pIfreqList ) { |
2610 | - errlogPrintf ( "osiLocalAddr(): no memory to complete request\n" ); |
2611 | - goto fail; |
2612 | - } |
2613 | - |
2614 | - ifconf.ifc_len = nelem * sizeof ( *pIfreqList ); |
2615 | - ifconf.ifc_req = pIfreqList; |
2616 | - status = socket_ioctl ( *psocket, SIOCGIFCONF, &ifconf ); |
2617 | - if ( status < 0 || ifconf.ifc_len == 0 ) { |
2618 | - char sockErrBuf[64]; |
2619 | - epicsSocketConvertErrnoToString ( |
2620 | - sockErrBuf, sizeof ( sockErrBuf ) ); |
2621 | - errlogPrintf ( |
2622 | - "osiLocalAddr(): SIOCGIFCONF ioctl failed because \"%s\"\n", |
2623 | - sockErrBuf ); |
2624 | - goto fail; |
2625 | - } |
2626 | - |
2627 | - pIfreqListEnd = (struct ifreq *) ( ifconf.ifc_len + (char *) ifconf.ifc_req ); |
2628 | - pIfreqListEnd--; |
2629 | - |
2630 | - for ( pifreq = ifconf.ifc_req; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { |
2631 | - osiSockAddr addrCpy; |
2632 | - uint32_t current_ifreqsize; |
2633 | - |
2634 | - /* |
2635 | - * find the next if req |
2636 | - */ |
2637 | - pnextifreq = ifreqNext ( pifreq ); |
2638 | - |
2639 | - /* determine ifreq size */ |
2640 | - current_ifreqsize = ifreqSize ( pifreq ); |
2641 | - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ |
2642 | - memmove(pIfreqList, pifreq, current_ifreqsize); |
2643 | - |
2644 | - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { |
2645 | - ifDepenDebugPrintf ( ("osiLocalAddr(): interface %s was not AF_INET\n", pIfreqList->ifr_name) ); |
2646 | - continue; |
2647 | - } |
2648 | - |
2649 | - addrCpy.sa = pIfreqList->ifr_addr; |
2650 | - |
2651 | - status = socket_ioctl ( *psocket, SIOCGIFFLAGS, pIfreqList ); |
2652 | - if ( status < 0 ) { |
2653 | - errlogPrintf ( "osiLocalAddr(): net intf flags fetch for %s failed\n", pIfreqList->ifr_name ); |
2654 | - continue; |
2655 | - } |
2656 | - |
2657 | - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { |
2658 | - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s was down\n", pIfreqList->ifr_name) ); |
2659 | - continue; |
2660 | - } |
2661 | - |
2662 | - /* |
2663 | - * dont use the loop back interface |
2664 | - */ |
2665 | - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { |
2666 | - ifDepenDebugPrintf ( ("osiLocalAddr(): ignoring loopback interface: %s\n", pIfreqList->ifr_name) ); |
2667 | - continue; |
2668 | - } |
2669 | - |
2670 | - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s found\n", pIfreqList->ifr_name) ); |
2671 | - |
2672 | - osiLocalAddrResult = addrCpy; |
2673 | - free ( pIfreqList ); |
2674 | - return; |
2675 | - } |
2676 | - |
2677 | - errlogPrintf ( |
2678 | - "osiLocalAddr(): only loopback found\n"); |
2679 | -fail: |
2680 | - /* fallback to loopback */ |
2681 | - memset ( (void *) &addr, '\0', sizeof ( addr ) ); |
2682 | - addr.ia.sin_family = AF_INET; |
2683 | - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
2684 | - osiLocalAddrResult = addr; |
2685 | - |
2686 | - free ( pIfreqList ); |
2687 | -} |
2688 | - |
2689 | - |
2690 | -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) |
2691 | -{ |
2692 | - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, &socket); |
2693 | - return osiLocalAddrResult; |
2694 | -} |
2695 | +#ifdef USE_IFADDRS |
2696 | + |
2697 | +epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags) |
2698 | +{ |
2699 | + int ret = -1; |
2700 | + struct ifaddrs *addrs = NULL, *cur; |
2701 | + |
2702 | + ellFree(pList); |
2703 | + |
2704 | + if(getifaddrs(&addrs)) |
2705 | + goto cleanup; |
2706 | + |
2707 | + for(cur=addrs; cur; cur=cur?cur->ifa_next:NULL) |
2708 | +// for(cur=addrs; cur; cur=cur->ifa_next) |
2709 | + { |
2710 | + unsigned int flags; |
2711 | + osiInterfaceInfo *node = calloc(1, sizeof(*node)); |
2712 | + if(!node) |
2713 | + goto cleanup; |
2714 | + |
2715 | + switch(cur->ifa_addr->sa_family) |
2716 | + { |
2717 | + case AF_INET: |
2718 | + /*case AF_INET6:*/ |
2719 | + break; |
2720 | + default: |
2721 | + free(node); |
2722 | + continue; /* ignore unknown address types */ |
2723 | + } |
2724 | + |
2725 | + //assert(cur->ifa_addr->sa_family==cur->ifa_netmask->sa_family); |
2726 | + memcpy(&node->address.ia, cur->ifa_addr, sizeof(node->address.ia)); |
2727 | + memcpy(&node->netmask.ia, cur->ifa_netmask, sizeof(node->address.ia)); |
2728 | + |
2729 | + flags = cur->ifa_flags; |
2730 | + |
2731 | + if(flags&IFF_UP) node->up = 1; |
2732 | + if(flags&IFF_BROADCAST) node->broadcast = 1; |
2733 | + if(flags&IFF_MULTICAST) node->multicast = 1; |
2734 | + if(flags&IFF_LOOPBACK) node->loopback = 1; |
2735 | + if(flags&IFF_POINTOPOINT) node->point2point = 1; |
2736 | + |
2737 | + if(node->broadcast && node->point2point) { |
2738 | + errlogPrintf("Interface %s claims both broadcast and point to point," |
2739 | + " which should not be possible. Assuming broadcast only.", |
2740 | + cur->ifa_name); |
2741 | + node->point2point = 0; |
2742 | + } |
2743 | + |
2744 | + if(node->broadcast) |
2745 | + memcpy(&node->endpoint.ia, cur->ifa_broadaddr, sizeof(node->address.ia)); |
2746 | + else if(node->point2point) |
2747 | + memcpy(&node->endpoint.ia, cur->ifa_dstaddr, sizeof(node->address.ia)); |
2748 | + |
2749 | + ellAdd(pList, &node->node); |
2750 | + } |
2751 | + |
2752 | + ret = 0; |
2753 | +cleanup: |
2754 | + if(ret) |
2755 | + ellFree(pList); |
2756 | + if(addrs) freeifaddrs(addrs); |
2757 | + return ret; |
2758 | +} |
2759 | +#else /* USE_IFADDRS */ |
2760 | + |
2761 | +epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags) |
2762 | +{ |
2763 | + SOCKET sock; |
2764 | + int ret = -1; |
2765 | + struct if_nameindex* pIndex = 0; |
2766 | + struct if_nameindex* pIndex2 = 0; |
2767 | + |
2768 | + ellFree(pList); |
2769 | + |
2770 | + sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); |
2771 | + if(sock==INVALID_SOCKET) |
2772 | + return ret; |
2773 | + |
2774 | + pIndex = pIndex2 = if_nameindex(); |
2775 | + while ((pIndex != NULL) && (pIndex->if_name != NULL)) |
2776 | + { |
2777 | + struct ifreq req; |
2778 | + unsigned int flags; |
2779 | + osiInterfaceInfo *node = calloc(1, sizeof(*node)); |
2780 | + if(!node) |
2781 | + goto cleanup; |
2782 | + strncpy(req.ifr_name, pIndex->if_name, IFNAMSIZ); |
2783 | + if(socket_ioctl(sock, SIOCGIFADDR, &req)<0) { |
2784 | + if (errno == EADDRNOTAVAIL) { |
2785 | + free(node); |
2786 | + ++pIndex; |
2787 | + continue; |
2788 | + } |
2789 | + free(node); |
2790 | + goto cleanup; |
2791 | + } |
2792 | + memcpy(&node->address.ia, &req.ifr_addr, sizeof(node->address.ia)); |
2793 | + |
2794 | + if(socket_ioctl(sock, SIOCGIFNETMASK, &req)<0) { |
2795 | + free(node); |
2796 | + goto cleanup; |
2797 | + } |
2798 | + memcpy(&node->netmask.ia, &req.ifr_addr, sizeof(node->netmask.ia)); |
2799 | + |
2800 | + if(socket_ioctl(sock, SIOCGIFFLAGS, &req)<0) { |
2801 | + free(node); |
2802 | + goto cleanup; |
2803 | + } |
2804 | + flags = req.ifr_flags; |
2805 | + if(flags&IFF_UP) node->up = 1; |
2806 | + if(flags&IFF_BROADCAST) node->broadcast = 1; |
2807 | + if(flags&IFF_MULTICAST) node->multicast = 1; |
2808 | + if(flags&IFF_LOOPBACK) node->loopback = 1; |
2809 | + if(flags&IFF_POINTOPOINT) node->point2point = 1; |
2810 | + |
2811 | + if(node->broadcast && node->point2point) { |
2812 | + errlogPrintf("Interface %s claims both broadcast and point to point," |
2813 | + " which should not be possible. Assuming broadcast only.", |
2814 | + req.ifr_name); |
2815 | + node->point2point = 0; |
2816 | + } |
2817 | + if(node->broadcast) { |
2818 | + if(socket_ioctl(sock, SIOCGIFBRDADDR, &req)<0) { |
2819 | + free(node); |
2820 | + goto cleanup; |
2821 | + } |
2822 | + } else if(node->point2point) { |
2823 | + if(socket_ioctl(sock, SIOCGIFDSTADDR, &req)<0) { |
2824 | + free(node); |
2825 | + goto cleanup; |
2826 | + } |
2827 | + } |
2828 | + |
2829 | + if(node->broadcast || node->point2point) { |
2830 | + assert(req.ifr_addr.sa_family==node->address.sa.sa_family); |
2831 | + |
2832 | + memcpy(&node->endpoint.ia, &req.ifr_addr, sizeof(node->endpoint.ia)); |
2833 | + } |
2834 | + |
2835 | + ellAdd(pList, &node->node); |
2836 | + ++pIndex; |
2837 | + } |
2838 | + |
2839 | + ret = 0; |
2840 | +cleanup: |
2841 | + if(ret) |
2842 | + ellFree(pList); |
2843 | + epicsSocketDestroy(sock); |
2844 | + return ret; |
2845 | +} |
2846 | +#endif /* USE_IFADRS */ |
2847 | |
2848 | === modified file 'src/libCom/osi/os/posix/osdSockAddrReuse.cpp' |
2849 | --- src/libCom/osi/os/posix/osdSockAddrReuse.cpp 2016-05-22 12:38:18 +0000 |
2850 | +++ src/libCom/osi/os/posix/osdSockAddrReuse.cpp 2017-05-01 18:36:52 +0000 |
2851 | @@ -17,6 +17,12 @@ |
2852 | #include "osiSock.h" |
2853 | #include "errlog.h" |
2854 | |
2855 | +#ifdef SO_REUSEPORT |
2856 | +#define OPTION SO_REUSEPORT |
2857 | +#else |
2858 | +#define OPTION SO_REUSEADDR |
2859 | +#endif |
2860 | + |
2861 | epicsShareFunc void epicsShareAPI |
2862 | epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) |
2863 | { |
2864 | @@ -33,13 +39,14 @@ |
2865 | |
2866 | /* |
2867 | * SO_REUSEPORT is not in POSIX |
2868 | + * but in RTEMS |
2869 | */ |
2870 | epicsShareFunc void epicsShareAPI |
2871 | epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) |
2872 | { |
2873 | int yes = true; |
2874 | int status; |
2875 | - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, |
2876 | + status = setsockopt ( s, SOL_SOCKET, OPTION, |
2877 | (char *) & yes, sizeof ( yes ) ); |
2878 | if ( status < 0 ) { |
2879 | errlogPrintf ( |
2880 | |
2881 | === modified file 'src/libCom/osi/os/posix/osdThread.c' |
2882 | --- src/libCom/osi/os/posix/osdThread.c 2016-02-23 21:43:26 +0000 |
2883 | +++ src/libCom/osi/os/posix/osdThread.c 2017-05-01 18:36:52 +0000 |
2884 | @@ -4,11 +4,19 @@ |
2885 | * Copyright (c) 2002 The Regents of the University of California, as |
2886 | * Operator of Los Alamos National Laboratory. |
2887 | * Copyright (c) 2013 ITER Organization. |
2888 | +* Copyright (c) 2017 Fritz-Haber-Institut der Max-Planck-Gesellschaft |
2889 | * EPICS BASE is distributed subject to a Software License Agreement found |
2890 | * in file LICENSE that is included with this distribution. |
2891 | \*************************************************************************/ |
2892 | |
2893 | -/* Author: Marty Kraimer Date: 18JAN2000 */ |
2894 | +/* Author: Marty Kraimer Date: 18JAN2000 |
2895 | + Heinz Junkes Date: 06APR2017 |
2896 | + |
2897 | + once() and all called functions by once must use |
2898 | + checkStatusOnce and checkStatusQuitOnce only |
2899 | + including epicsEventCreate called by create_threadInfo |
2900 | + add epicsEventCreateOnce which can be called here |
2901 | +*/ |
2902 | |
2903 | /* This is a posix implementation of epicsThread */ |
2904 | #include <stddef.h> |
2905 | @@ -38,6 +46,16 @@ |
2906 | #include "errlog.h" |
2907 | #include "epicsAssert.h" |
2908 | #include "epicsExit.h" |
2909 | +#if defined(__rtems__) |
2910 | +#include <rtems/bspIo.h> |
2911 | +#include <rtems.h> |
2912 | +#endif |
2913 | + |
2914 | +struct epicsEventOSD { |
2915 | + pthread_mutex_t mutex; |
2916 | + pthread_cond_t cond; |
2917 | + int isFull; |
2918 | +}; |
2919 | |
2920 | epicsShareFunc void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level); |
2921 | epicsShareFunc void osdThreadHooksRun(epicsThreadId id); |
2922 | @@ -75,14 +93,15 @@ |
2923 | } priAvailable; |
2924 | #endif |
2925 | |
2926 | -static pthread_key_t getpthreadInfo; |
2927 | +__thread epicsThreadOSD *tls_pthreadInfo; |
2928 | + |
2929 | static pthread_mutex_t onceLock; |
2930 | static pthread_mutex_t listLock; |
2931 | static ELLLIST pthreadList = ELLLIST_INIT; |
2932 | static commonAttr *pcommonAttr = 0; |
2933 | -static int epicsThreadOnceCalled = 0; |
2934 | +static int epicsThreadInitOnceCalled = 0; |
2935 | |
2936 | |
2937 | -static epicsThreadOSD *createImplicit(void); |
2938 | +static void createImplicit(void); |
2939 | |
2940 | #define checkStatus(status,message) \ |
2941 | if((status)) {\ |
2942 | @@ -90,7 +109,7 @@ |
2943 | } |
2944 | |
2945 | #define checkStatusQuit(status,message,method) \ |
2946 | -if(status) { \ |
2947 | +if((status)) { \ |
2948 | errlogPrintf("%s error %s\n",(message),strerror((status))); \ |
2949 | cantProceed((method)); \ |
2950 | } |
2951 | @@ -99,17 +118,33 @@ |
2952 | /* Until epicsThreadInit completes errlogInit will not work */ |
2953 | /* It must also be used by init_threadInfo otherwise errlogInit could get */ |
2954 | /* called recursively */ |
2955 | +#if defined (__rtems__) |
2956 | +#define checkStatusOnce(status,message) \ |
2957 | +if((status)) {\ |
2958 | + printk("%s error %s\n",(message),strerror((status))); } |
2959 | +#else |
2960 | #define checkStatusOnce(status,message) \ |
2961 | if((status)) {\ |
2962 | fprintf(stderr,"%s error %s\n",(message),strerror((status))); } |
2963 | +#endif |
2964 | |
2965 | -#define checkStatusOnceQuit(status,message,method) \ |
2966 | -if(status) { \ |
2967 | +#if defined (__rtems__) |
2968 | +#define checkStatusOnceQuit(status,message,method) \ |
2969 | +if((status)) { \ |
2970 | + printk("%s error %s",(message),strerror((status))); \ |
2971 | + printk(" %s\n",method); \ |
2972 | + printk("epicsThreadInit cant proceed. Program exiting\n"); \ |
2973 | + exit(-1);\ |
2974 | +} |
2975 | +#else |
2976 | +#define checkStatusOnceQuit(status,message,method) \ |
2977 | +if((status)) { \ |
2978 | fprintf(stderr,"%s error %s",(message),strerror((status))); \ |
2979 | fprintf(stderr," %s\n",method); \ |
2980 | fprintf(stderr,"epicsThreadInit cant proceed. Program exiting\n"); \ |
2981 | exit(-1);\ |
2982 | } |
2983 | +#endif |
2984 | |
2985 | |
2986 | |
2987 | epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId pthreadInfo) |
2988 | @@ -153,6 +188,29 @@ |
2989 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
2990 | } |
2991 | |
2992 | |
2993 | + |
2994 | +epicsShareFunc epicsEventId epicsEventCreateOnce(epicsEventInitialState init) |
2995 | +{ |
2996 | + epicsEventId pevent = malloc(sizeof(*pevent)); |
2997 | + if (pevent) { |
2998 | + int status = pthread_mutex_init(&pevent->mutex, 0); |
2999 | + |
3000 | + pevent->isFull = (init == epicsEventFull); |
3001 | + if (status) { |
3002 | + checkStatus(status, "pthread_mutex_init"); |
3003 | + } else { |
3004 | + status = pthread_cond_init(&pevent->cond, 0); |
3005 | + if (!status) |
3006 | + return pevent; |
3007 | + checkStatus(status, "pthread_cond_init"); |
3008 | + status = pthread_mutex_destroy(&pevent->mutex); |
3009 | + checkStatus(status, "pthread_mutex_destroy"); |
3010 | + } |
3011 | + free(pevent); |
3012 | + } |
3013 | + return NULL; |
3014 | +} |
3015 | + |
3016 | static epicsThreadOSD * create_threadInfo(const char *name) |
3017 | { |
3018 | epicsThreadOSD *pthreadInfo; |
3019 | @@ -161,7 +219,7 @@ |
3020 | pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name)); |
3021 | if(!pthreadInfo) |
3022 | return NULL; |
3023 | - pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty); |
3024 | + pthreadInfo->suspendEvent = epicsEventCreateOnce(epicsEventEmpty); |
3025 | if(!pthreadInfo->suspendEvent){ |
3026 | free(pthreadInfo); |
3027 | return NULL; |
3028 | @@ -204,11 +262,13 @@ |
3029 | { |
3030 | int status; |
3031 | |
3032 | - status = mutexLock(&listLock); |
3033 | - checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo"); |
3034 | - if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node); |
3035 | - status = pthread_mutex_unlock(&listLock); |
3036 | - checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo"); |
3037 | + if(pthreadInfo->isOnThreadList) { |
3038 | + status = mutexLock(&listLock); |
3039 | + checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo"); |
3040 | + ellDelete(&pthreadList,&pthreadInfo->node); |
3041 | + status = pthread_mutex_unlock(&listLock); |
3042 | + checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo"); |
3043 | + } |
3044 | epicsEventDestroy(pthreadInfo->suspendEvent); |
3045 | status = pthread_attr_destroy(&pthreadInfo->attr); |
3046 | checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo"); |
3047 | @@ -301,13 +361,19 @@ |
3048 | arg.ok = 0; |
3049 | |
3050 | status = pthread_create(&id, 0, find_pri_range, &arg); |
3051 | - checkStatusQuit(status, "pthread_create","epicsThreadInit"); |
3052 | + checkStatusOnceQuit(status, "pthread_create","findPriorityRange"); |
3053 | |
3054 | status = pthread_join(id, &dummy); |
3055 | - checkStatusQuit(status, "pthread_join","epicsThreadInit"); |
3056 | - |
3057 | + checkStatusOnceQuit(status, "pthread_join","findPriorityRange"); |
3058 | +#if defined (__rtems__) |
3059 | +// We are using posix map osi 0-100 to posix 100-200 |
3060 | +// see epicsThreadGetOsiPriorityValue(int ossPriority) |
3061 | + a_p->minPriority = 100; |
3062 | + a_p->maxPriority = 200; |
3063 | +#else |
3064 | a_p->minPriority = arg.min_pri; |
3065 | a_p->maxPriority = arg.max_pri; |
3066 | +#endif |
3067 | a_p->usePolicy = arg.ok; |
3068 | } |
3069 | #endif |
3070 | @@ -315,18 +381,15 @@ |
3071 | |
3072 | static void once(void) |
3073 | { |
3074 | - epicsThreadOSD *pthreadInfo; |
3075 | int status; |
3076 | - |
3077 | - pthread_key_create(&getpthreadInfo,0); |
3078 | status = pthread_mutex_init(&onceLock,0); |
3079 | - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); |
3080 | + checkStatusOnceQuit(status,"pthread_mutex_init","once"); |
3081 | status = pthread_mutex_init(&listLock,0); |
3082 | - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); |
3083 | + checkStatusOnceQuit(status,"pthread_mutex_init","once"); |
3084 | pcommonAttr = calloc(1,sizeof(commonAttr)); |
3085 | - if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","epicsThreadInit"); |
3086 | + if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","once"); |
3087 | status = pthread_attr_init(&pcommonAttr->attr); |
3088 | - checkStatusOnceQuit(status,"pthread_attr_init","epicsThreadInit"); |
3089 | + checkStatusOnceQuit(status,"pthread_attr_init","once"); |
3090 | status = pthread_attr_setdetachstate( |
3091 | &pcommonAttr->attr, PTHREAD_CREATE_DETACHED); |
3092 | checkStatusOnce(status,"pthread_attr_setdetachstate"); |
3093 | @@ -358,52 +421,77 @@ |
3094 | } |
3095 | |
3096 | if (errVerbose) { |
3097 | +#if defined(__rtems__) |
3098 | + printk("LRT: min priority: %d max priority %d\n", |
3099 | + pcommonAttr->minPriority, pcommonAttr->maxPriority); |
3100 | +#else |
3101 | fprintf(stderr, "LRT: min priority: %d max priority %d\n", |
3102 | pcommonAttr->minPriority, pcommonAttr->maxPriority); |
3103 | +#endif |
3104 | } |
3105 | |
3106 | #else |
3107 | - if(errVerbose) fprintf(stderr,"task priorities are not implemented\n"); |
3108 | + if(errVerbose) { |
3109 | +#if defined(__rtems__) |
3110 | + printk("task priorities are not implemented\n"); |
3111 | +#else |
3112 | + fprintf(stderr,"task priorities are not implemented\n"); |
3113 | +#endif |
3114 | +} |
3115 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
3116 | + int policy; |
3117 | + struct sched_param param; |
3118 | + status = pthread_getschedparam(pthread_self(), &policy, ¶m); |
3119 | + checkStatusOnce(status, "pthread_getschedparam failed"); |
3120 | +// param.sched_priority is still 2 bug or feature? |
3121 | +#if defined (__rtems__) |
3122 | + param.sched_priority = 191; // iocsh prio |
3123 | +#endif |
3124 | + status = pthread_setschedparam(pthread_self(), policy, ¶m); |
3125 | + checkStatusOnce(status, "pthread_setschedparam failed"); |
3126 | + status = pthread_getschedparam(pthread_self(), &policy, ¶m); |
3127 | + checkStatusOnce(status, "pthread_getschedparam failed"); |
3128 | |
3129 | - pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); |
3130 | - assert(pthreadInfo!=NULL); |
3131 | - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); |
3132 | - checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit"); |
3133 | +#if defined (__rtems__) |
3134 | + tls_pthreadInfo = init_threadInfo("_main_",param.sched_priority-100,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); |
3135 | +#else |
3136 | + tls_pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); |
3137 | +#endif |
3138 | + assert(tls_pthreadInfo!=NULL); |
3139 | + tls_pthreadInfo->tid = pthread_self(); |
3140 | status = mutexLock(&listLock); |
3141 | - checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit"); |
3142 | - ellAdd(&pthreadList,&pthreadInfo->node); |
3143 | - pthreadInfo->isOnThreadList = 1; |
3144 | + checkStatusOnceQuit(status,"pthread_mutex_lock","once"); |
3145 | + ellAdd(&pthreadList,&tls_pthreadInfo->node); |
3146 | + tls_pthreadInfo->isOnThreadList = 1; |
3147 | status = pthread_mutex_unlock(&listLock); |
3148 | - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit"); |
3149 | + checkStatusOnceQuit(status,"pthread_mutex_unlock","once"); |
3150 | status = atexit(epicsExitCallAtExits); |
3151 | checkStatusOnce(status,"atexit"); |
3152 | - osdThreadHooksRunMain(pthreadInfo); |
3153 | - epicsThreadOnceCalled = 1; |
3154 | + osdThreadHooksRunMain(tls_pthreadInfo); |
3155 | + epicsThreadInitOnceCalled = 1; |
3156 | } |
3157 | |
3158 | static void * start_routine(void *arg) |
3159 | { |
3160 | - epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg; |
3161 | int status; |
3162 | sigset_t blockAllSig; |
3163 | |
3164 | + tls_pthreadInfo = (epicsThreadOSD *)arg; |
3165 | + |
3166 | sigfillset(&blockAllSig); |
3167 | pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL); |
3168 | - status = pthread_setspecific(getpthreadInfo,arg); |
3169 | - checkStatusQuit(status,"pthread_setspecific","start_routine"); |
3170 | status = mutexLock(&listLock); |
3171 | checkStatusQuit(status,"pthread_mutex_lock","start_routine"); |
3172 | - ellAdd(&pthreadList,&pthreadInfo->node); |
3173 | - pthreadInfo->isOnThreadList = 1; |
3174 | + ellAdd(&pthreadList,&tls_pthreadInfo->node); |
3175 | + tls_pthreadInfo->isOnThreadList = 1; |
3176 | status = pthread_mutex_unlock(&listLock); |
3177 | checkStatusQuit(status,"pthread_mutex_unlock","start_routine"); |
3178 | - osdThreadHooksRun(pthreadInfo); |
3179 | + osdThreadHooksRun(tls_pthreadInfo); |
3180 | |
3181 | - (*pthreadInfo->createFunc)(pthreadInfo->createArg); |
3182 | + (*tls_pthreadInfo->createFunc)(tls_pthreadInfo->createArg); |
3183 | |
3184 | epicsExitCallAtThreadExits (); |
3185 | - free_threadInfo(pthreadInfo); |
3186 | + free_threadInfo(tls_pthreadInfo); |
3187 | return(0); |
3188 | } |
3189 | |
3190 | @@ -417,6 +505,9 @@ |
3191 | epicsShareFunc |
3192 | void epicsThreadRealtimeLock(void) |
3193 | { |
3194 | +#if !defined(__rtems__) |
3195 | +/* RTEMS defines _POSIX_MEMLOCK to 1 in features.h even if it is a non swaping OS and |
3196 | + mlockall senseless*/ |
3197 | #if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 |
3198 | if (pcommonAttr->maxPriority > pcommonAttr->minPriority) { |
3199 | int status = mlockall(MCL_CURRENT | MCL_FUTURE); |
3200 | @@ -424,10 +515,11 @@ |
3201 | if (status) { |
3202 | fprintf(stderr, "epicsThreadRealtimeLock " |
3203 | "Warning: Unable to lock the virtual address space.\n" |
3204 | - "VM page faults may harm real-time performance.\n"); |
3205 | + "VM page fautls may harm real-time performance.\n"); |
3206 | } |
3207 | } |
3208 | #endif |
3209 | +#endif /* not defined __rtems__ */ |
3210 | } |
3211 | |
3212 | epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) |
3213 | @@ -435,7 +527,11 @@ |
3214 | #if defined (OSITHREAD_USE_DEFAULT_STACK) |
3215 | return 0; |
3216 | #elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0 |
3217 | +#if defined (__rtems) |
3218 | + #define STACK_SIZE(f) (f * 0x1000 * sizeof(void *)) |
3219 | +#else |
3220 | #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) |
3221 | +#endif |
3222 | static const unsigned stackSizeTable[epicsThreadStackBig+1] = { |
3223 | STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) |
3224 | }; |
3225 | @@ -463,37 +559,33 @@ |
3226 | |
3227 | epicsThreadInit(); |
3228 | status = mutexLock(&onceLock); |
3229 | - if(status) { |
3230 | - fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n", |
3231 | - strerror(status)); |
3232 | - exit(-1); |
3233 | - } |
3234 | + checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); |
3235 | |
3236 | if (*id != EPICS_THREAD_ONCE_DONE) { |
3237 | if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ |
3238 | *id = epicsThreadGetIdSelf(); /* mark active */ |
3239 | status = pthread_mutex_unlock(&onceLock); |
3240 | - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3241 | + checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3242 | func(arg); |
3243 | status = mutexLock(&onceLock); |
3244 | - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); |
3245 | + checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); |
3246 | *id = EPICS_THREAD_ONCE_DONE; /* mark done */ |
3247 | } else if (*id == epicsThreadGetIdSelf()) { |
3248 | status = pthread_mutex_unlock(&onceLock); |
3249 | - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3250 | + checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3251 | cantProceed("Recursive epicsThreadOnce() initialization\n"); |
3252 | } else |
3253 | while (*id != EPICS_THREAD_ONCE_DONE) { |
3254 | /* Another thread is in the above func(arg) call. */ |
3255 | status = pthread_mutex_unlock(&onceLock); |
3256 | - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3257 | + checkStatusOnceQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); |
3258 | epicsThreadSleep(epicsThreadSleepQuantum()); |
3259 | status = mutexLock(&onceLock); |
3260 | - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); |
3261 | + checkStatusOnceQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); |
3262 | } |
3263 | } |
3264 | status = pthread_mutex_unlock(&onceLock); |
3265 | - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); |
3266 | + checkStatusOnceQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); |
3267 | } |
3268 | |
3269 | epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name, |
3270 | @@ -530,6 +622,7 @@ |
3271 | return 0; |
3272 | } |
3273 | status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL); |
3274 | +//? StatusOnce? because of errlog daemon ??? |
3275 | checkStatusOnce(status,"pthread_sigmask"); |
3276 | return(pthreadInfo); |
3277 | } |
3278 | @@ -537,80 +630,64 @@ |
3279 | /* |
3280 | * Create dummy context for threads not created by epicsThreadCreate(). |
3281 | */ |
3282 | -static epicsThreadOSD *createImplicit(void) |
3283 | +static void createImplicit(void) |
3284 | { |
3285 | - epicsThreadOSD *pthreadInfo; |
3286 | char name[64]; |
3287 | pthread_t tid; |
3288 | - int status; |
3289 | |
3290 | tid = pthread_self(); |
3291 | sprintf(name, "non-EPICS_%ld", (long)tid); |
3292 | - pthreadInfo = create_threadInfo(name); |
3293 | - assert(pthreadInfo); |
3294 | - pthreadInfo->tid = tid; |
3295 | - pthreadInfo->osiPriority = 0; |
3296 | + tls_pthreadInfo = create_threadInfo(name); |
3297 | + assert(tls_pthreadInfo); |
3298 | + tls_pthreadInfo->tid = tid; |
3299 | + tls_pthreadInfo->osiPriority = 0; |
3300 | |
3301 | #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 |
3302 | { |
3303 | struct sched_param param; |
3304 | int policy; |
3305 | if(pthread_getschedparam(tid,&policy,¶m) == 0) |
3306 | - pthreadInfo->osiPriority = |
3307 | + tls_pthreadInfo->osiPriority = |
3308 | (param.sched_priority - pcommonAttr->minPriority) * 100.0 / |
3309 | - (pcommonAttr->maxPriority - pcommonAttr->minPriority + 1); |
3310 | + (pcommonAttr->maxPriority - pcommonAttr->minPriority); |
3311 | } |
3312 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
3313 | - |
3314 | - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); |
3315 | - checkStatus(status,"pthread_setspecific createImplicit"); |
3316 | - if(status){ |
3317 | - free_threadInfo(pthreadInfo); |
3318 | - return NULL; |
3319 | - } |
3320 | - return pthreadInfo; |
3321 | } |
3322 | |
3323 | |
3324 | epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void) |
3325 | { |
3326 | - epicsThreadOSD *pthreadInfo; |
3327 | - |
3328 | epicsThreadInit(); |
3329 | - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); |
3330 | - if(pthreadInfo==NULL) |
3331 | - pthreadInfo = createImplicit(); |
3332 | - pthreadInfo->isSuspended = 1; |
3333 | - epicsEventWait(pthreadInfo->suspendEvent); |
3334 | + assert(tls_pthreadInfo); |
3335 | + tls_pthreadInfo->isSuspended = 1; |
3336 | + epicsEventWait(tls_pthreadInfo->suspendEvent); |
3337 | } |
3338 | |
3339 | epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo) |
3340 | { |
3341 | - assert(epicsThreadOnceCalled); |
3342 | + assert(epicsThreadInitOnceCalled); |
3343 | pthreadInfo->isSuspended = 0; |
3344 | epicsEventSignal(pthreadInfo->suspendEvent); |
3345 | } |
3346 | |
3347 | epicsShareFunc void epicsShareAPI epicsThreadExitMain(void) |
3348 | { |
3349 | - epicsThreadOSD *pthreadInfo; |
3350 | |
3351 | epicsThreadInit(); |
3352 | - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); |
3353 | - if(pthreadInfo==NULL) |
3354 | - pthreadInfo = createImplicit(); |
3355 | - if(pthreadInfo->createFunc) { |
3356 | + if(tls_pthreadInfo==NULL) |
3357 | + createImplicit(); |
3358 | + if(tls_pthreadInfo->createFunc) { |
3359 | errlogPrintf("called from non-main thread\n"); |
3360 | cantProceed("epicsThreadExitMain"); |
3361 | } |
3362 | else { |
3363 | - free_threadInfo(pthreadInfo); |
3364 | + free_threadInfo(tls_pthreadInfo); |
3365 | pthread_exit(0); |
3366 | } |
3367 | } |
3368 | |
3369 | |
3370 | epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(epicsThreadId pthreadInfo) |
3371 | { |
3372 | - assert(epicsThreadOnceCalled); |
3373 | + assert(epicsThreadInitOnceCalled); |
3374 | return(pthreadInfo->osiPriority); |
3375 | } |
3376 | |
3377 | @@ -626,7 +703,7 @@ |
3378 | int status; |
3379 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
3380 | |
3381 | - assert(epicsThreadOnceCalled); |
3382 | + assert(epicsThreadInitOnceCalled); |
3383 | assert(pthreadInfo); |
3384 | if(!pthreadInfo->isEpicsThread) { |
3385 | fprintf(stderr,"epicsThreadSetPriority called by non epics thread\n"); |
3386 | @@ -637,7 +714,7 @@ |
3387 | |
3388 | #if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 |
3389 | if(!pcommonAttr->usePolicy) return; |
3390 | - pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); |
3391 | + tls_pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); |
3392 | status = pthread_attr_setschedparam( |
3393 | &pthreadInfo->attr,&pthreadInfo->schedParam); |
3394 | if(errVerbose) checkStatus(status,"pthread_attr_setschedparam"); |
3395 | @@ -685,14 +762,14 @@ |
3396 | |
3397 | |
3398 | epicsShareFunc int epicsShareAPI epicsThreadIsEqual(epicsThreadId p1, epicsThreadId p2) |
3399 | { |
3400 | - assert(epicsThreadOnceCalled); |
3401 | + assert(epicsThreadInitOnceCalled); |
3402 | assert(p1); |
3403 | assert(p2); |
3404 | return(pthread_equal(p1->tid,p2->tid)); |
3405 | } |
3406 | |
3407 | epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId pthreadInfo) { |
3408 | - assert(epicsThreadOnceCalled); |
3409 | + assert(epicsThreadInitOnceCalled); |
3410 | assert(pthreadInfo); |
3411 | return(pthreadInfo->isSuspended ? 1 : 0); |
3412 | } |
3413 | @@ -718,14 +795,11 @@ |
3414 | } |
3415 | |
3416 | epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) { |
3417 | - epicsThreadOSD *pthreadInfo; |
3418 | |
3419 | epicsThreadInit(); |
3420 | - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); |
3421 | - if(pthreadInfo==NULL) |
3422 | - pthreadInfo = createImplicit(); |
3423 | - assert ( pthreadInfo ); |
3424 | - return(pthreadInfo); |
3425 | + if(tls_pthreadInfo==NULL) |
3426 | + createImplicit(); |
3427 | + return(tls_pthreadInfo); |
3428 | } |
3429 | |
3430 | epicsShareFunc pthread_t epicsThreadGetPosixThreadId ( epicsThreadId threadId ) |
3431 | @@ -737,7 +811,7 @@ |
3432 | epicsThreadOSD *pthreadInfo; |
3433 | int status; |
3434 | |
3435 | - assert(epicsThreadOnceCalled); |
3436 | + assert(epicsThreadInitOnceCalled); |
3437 | status = mutexLock(&listLock); |
3438 | checkStatus(status,"pthread_mutex_lock epicsThreadGetId"); |
3439 | if(status) |
3440 | @@ -755,18 +829,16 @@ |
3441 | |
3442 | epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf() |
3443 | { |
3444 | - epicsThreadOSD *pthreadInfo; |
3445 | |
3446 | epicsThreadInit(); |
3447 | - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); |
3448 | - if(pthreadInfo==NULL) |
3449 | - pthreadInfo = createImplicit(); |
3450 | - return(pthreadInfo->name); |
3451 | + if(tls_pthreadInfo==NULL) |
3452 | + createImplicit(); |
3453 | + return(tls_pthreadInfo->name); |
3454 | } |
3455 | |
3456 | epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size) |
3457 | { |
3458 | - assert(epicsThreadOnceCalled); |
3459 | + assert(epicsThreadInitOnceCalled); |
3460 | strncpy(name, pthreadInfo->name, size-1); |
3461 | name[size-1] = '\0'; |
3462 | } |
3463 | @@ -822,7 +894,7 @@ |
3464 | return; |
3465 | } |
3466 | status = mutexLock(&listLock); |
3467 | - checkStatus(status,"pthread_mutex_lock epicsThreadShowAll"); |
3468 | + checkStatus(status,"pthread_mutex_lock epicsThreadShow"); |
3469 | if(status) |
3470 | return; |
3471 | pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); |
3472 | @@ -835,7 +907,7 @@ |
3473 | pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); |
3474 | } |
3475 | status = pthread_mutex_unlock(&listLock); |
3476 | - checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll"); |
3477 | + checkStatus(status,"pthread_mutex_unlock epicsThreadShow"); |
3478 | if(status) return; |
3479 | if (!found) |
3480 | printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread); |
3481 | @@ -851,7 +923,8 @@ |
3482 | if(!key) |
3483 | return NULL; |
3484 | status = pthread_key_create(key,0); |
3485 | - checkStatus(status,"pthread_key_create epicsThreadPrivateCreate"); |
3486 | +//used from errlogInit |
3487 | + checkStatusOnce(status,"pthread_key_create epicsThreadPrivateCreate"); |
3488 | if(status) |
3489 | return NULL; |
3490 | return((epicsThreadPrivateId)key); |
3491 | @@ -862,7 +935,7 @@ |
3492 | pthread_key_t *key = (pthread_key_t *)id; |
3493 | int status; |
3494 | |
3495 | - assert(epicsThreadOnceCalled); |
3496 | + assert(epicsThreadInitOnceCalled); |
3497 | status = pthread_key_delete(*key); |
3498 | checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete"); |
3499 | free((void *)key); |
3500 | @@ -873,7 +946,7 @@ |
3501 | pthread_key_t *key = (pthread_key_t *)id; |
3502 | int status; |
3503 | |
3504 | - assert(epicsThreadOnceCalled); |
3505 | + assert(epicsThreadInitOnceCalled); |
3506 | if(errVerbose && !value) |
3507 | errlogPrintf("epicsThreadPrivateSet: setting value of 0\n"); |
3508 | status = pthread_setspecific(*key,value); |
3509 | @@ -884,7 +957,7 @@ |
3510 | { |
3511 | pthread_key_t *key = (pthread_key_t *)id; |
3512 | |
3513 | - assert(epicsThreadOnceCalled); |
3514 | + assert(epicsThreadInitOnceCalled); |
3515 | return pthread_getspecific(*key); |
3516 | } |
3517 | |
3518 | |
3519 | === modified file 'src/libCom/osi/os/posix/osdThreadExtra.c' |
3520 | --- src/libCom/osi/os/posix/osdThreadExtra.c 2013-03-27 09:56:34 +0000 |
3521 | +++ src/libCom/osi/os/posix/osdThreadExtra.c 2017-05-01 18:36:52 +0000 |
3522 | @@ -24,22 +24,26 @@ |
3523 | { |
3524 | if(!pthreadInfo) { |
3525 | fprintf(epicsGetStdout()," NAME EPICS ID " |
3526 | - "PTHREAD ID OSIPRI OSSPRI STATE\n"); |
3527 | + "PTHREAD ID OSIPRI OSSPRI STATE STACKSIZE\n"); |
3528 | } else { |
3529 | struct sched_param param; |
3530 | int policy; |
3531 | int priority = 0; |
3532 | + size_t stackSize = 0; |
3533 | |
3534 | if(pthreadInfo->tid) { |
3535 | int status; |
3536 | status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m); |
3537 | if(!status) priority = param.sched_priority; |
3538 | + status = pthread_attr_getstacksize( &pthreadInfo->attr,&stackSize); |
3539 | + if(status) stackSize = 0; |
3540 | } |
3541 | - fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n", |
3542 | + fprintf(epicsGetStdout(),"%16.16s %14p 0x%08X %3d%8d %8.8s %9d\n", |
3543 | pthreadInfo->name,(void *) |
3544 | pthreadInfo,(unsigned long)pthreadInfo->tid, |
3545 | pthreadInfo->osiPriority,priority, |
3546 | - pthreadInfo->isSuspended?"SUSPEND":"OK"); |
3547 | + pthreadInfo->isSuspended?"SUSPEND":"OK", |
3548 | + stackSize); |
3549 | } |
3550 | } |
3551 | |
3552 | |
3553 | === modified file 'src/libCom/osi/osiSock.c' |
3554 | --- src/libCom/osi/osiSock.c 2016-05-22 03:43:09 +0000 |
3555 | +++ src/libCom/osi/osiSock.c 2017-05-01 18:36:52 +0000 |
3556 | @@ -3,6 +3,8 @@ |
3557 | * National Laboratory. |
3558 | * Copyright (c) 2002 The Regents of the University of California, as |
3559 | * Operator of Los Alamos National Laboratory. |
3560 | +* Copyright (c) 2015 Brookhaven Science Associates as Operator of |
3561 | +* Brookhaven National Lab. |
3562 | * EPICS BASE Versions 3.13.7 |
3563 | * and higher are distributed subject to a Software License Agreement found |
3564 | * in file LICENSE that is included with this distribution. |
3565 | @@ -15,12 +17,15 @@ |
3566 | */ |
3567 | |
3568 | #include <stdio.h> |
3569 | +#include <stdlib.h> |
3570 | #include <string.h> |
3571 | |
3572 | #define epicsExportSharedSymbols |
3573 | #include "epicsAssert.h" |
3574 | #include "epicsSignal.h" |
3575 | #include "epicsStdio.h" |
3576 | +#include "dbDefs.h" |
3577 | +#include "errlog.h" |
3578 | #include "osiSock.h" |
3579 | |
3580 | #define nDigitsDottedIP 4u |
3581 | @@ -187,3 +192,155 @@ |
3582 | } |
3583 | } |
3584 | |
3585 | +epicsShareFunc void osiFreeInterfaceInfo(osiInterfaceInfo *pinfo) |
3586 | +{ |
3587 | + free(pinfo); |
3588 | +} |
3589 | + |
3590 | +/* |
3591 | + * osiSockDiscoverBroadcastAddresses () |
3592 | + */ |
3593 | +epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses |
3594 | + (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) |
3595 | +{ |
3596 | + ELLLIST infolist = ELLLIST_INIT; |
3597 | + ELLNODE *cur; |
3598 | + |
3599 | + if ( pMatchAddr->sa.sa_family == AF_INET ) { |
3600 | + if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { |
3601 | + osiSockAddrNode *pNewNode = calloc (1, sizeof (*pNewNode) ); |
3602 | + if ( pNewNode == NULL ) { |
3603 | + errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); |
3604 | + return; |
3605 | + } |
3606 | + pNewNode->addr.ia.sin_family = AF_INET; |
3607 | + pNewNode->addr.ia.sin_port = htons ( 0 ); |
3608 | + pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); |
3609 | + ellAdd ( pList, &pNewNode->node ); |
3610 | + return; |
3611 | + } |
3612 | + } else if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) { |
3613 | + errlogPrintf("osiSockDiscoverBroadcastAddresses(): match address must be AF_INET or AF_UNSPEC."); |
3614 | + return; |
3615 | + } |
3616 | + |
3617 | + if(osiGetInterfaceInfo(&infolist, 0)) { |
3618 | + errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration\n"); |
3619 | + return; |
3620 | + } |
3621 | + |
3622 | + if(ellCount(&infolist)==0) { |
3623 | + errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no network interfaces found\n"); |
3624 | + } |
3625 | + |
3626 | + for(cur=ellFirst(&infolist); cur; cur=ellNext(cur)) |
3627 | + { |
3628 | + osiSockAddrNode *pNewNode; |
3629 | + osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node); |
3630 | + |
3631 | + if(info->address.sa.sa_family!=AF_INET || !info->broadcast) |
3632 | + continue; |
3633 | + |
3634 | + pNewNode = calloc(1, sizeof(*pNewNode)); |
3635 | + if(!pNewNode) |
3636 | + break; |
3637 | + |
3638 | + if(pMatchAddr->ia.sin_family==AF_INET && |
3639 | + pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY) && |
3640 | + pMatchAddr->ia.sin_addr.s_addr != info->address.ia.sin_addr.s_addr) |
3641 | + { |
3642 | + free(pNewNode); |
3643 | + continue; |
3644 | + } |
3645 | + |
3646 | + pNewNode->addr.ia = info->endpoint.ia; |
3647 | + |
3648 | + ellAdd(pList, &pNewNode->node); |
3649 | + } |
3650 | + |
3651 | + ellFree2(&infolist, (FREEFUNC)osiFreeInterfaceInfo); |
3652 | +} |
3653 | + |
3654 | +/* |
3655 | + * osiLocalAddr () |
3656 | + */ |
3657 | +epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) |
3658 | +{ |
3659 | + static osiSockAddr result; |
3660 | + static int init; |
3661 | + |
3662 | + if(!init) { |
3663 | + ELLLIST infolist = ELLLIST_INIT; |
3664 | + ELLNODE *cur; |
3665 | + osiSockAddr addr; |
3666 | + int found = 0; |
3667 | + |
3668 | + memset ( (void *) &addr, '\0', sizeof ( addr ) ); |
3669 | + addr.sa.sa_family = AF_UNSPEC; |
3670 | + |
3671 | + if(osiGetInterfaceInfo(&infolist, 0)) { |
3672 | + errlogPrintf ("osiLocalAddr(): unable to fetch network interface configuration\n"); |
3673 | + |
3674 | + } else { |
3675 | + |
3676 | + for(cur=ellFirst(&infolist); cur; cur=ellNext(cur)) |
3677 | + { |
3678 | + osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node); |
3679 | + |
3680 | + if(info->address.sa.sa_family!=AF_INET || !info->up || info->loopback) |
3681 | + continue; |
3682 | + |
3683 | + addr.ia = info->address.ia; |
3684 | + found = 1; |
3685 | + } |
3686 | + |
3687 | + ellFree(&infolist); |
3688 | + } |
3689 | + |
3690 | + if(!found) { |
3691 | + addr.ia.sin_family = AF_INET; |
3692 | + addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
3693 | + addr.ia.sin_port = 0; |
3694 | + } |
3695 | + |
3696 | + result = addr; |
3697 | + init = 1; |
3698 | + } |
3699 | + |
3700 | + return result; |
3701 | +} |
3702 | + |
3703 | +epicsShareFunc |
3704 | +int osiGetInterfaceInfoSingle(const osiSockAddr *paddr, osiInterfaceInfo **presult, unsigned flags) |
3705 | +{ |
3706 | + ELLLIST infolist = ELLLIST_INIT; |
3707 | + ELLNODE *cur; |
3708 | + int found = 0; |
3709 | + |
3710 | + if(paddr->sa.sa_family!=AF_INET) |
3711 | + return -1; |
3712 | + |
3713 | + if(osiGetInterfaceInfo(&infolist, flags)) { |
3714 | + errlogPrintf ("osiGetInterfaceInfoSingle(): unable to fetch network interface configuration\n"); |
3715 | + return -1; |
3716 | + } |
3717 | + |
3718 | + for(cur=ellFirst(&infolist); cur; cur=ellNext(cur)) |
3719 | + { |
3720 | + osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node); |
3721 | + |
3722 | + if(info->address.ia.sin_addr.s_addr==paddr->ia.sin_addr.s_addr) { |
3723 | + if(presult) { |
3724 | + *presult = info; |
3725 | + ellDelete(&infolist, cur); |
3726 | + // caller now responsible to free |
3727 | + } |
3728 | + found = 1; |
3729 | + break; |
3730 | + } |
3731 | + } |
3732 | + |
3733 | + ellFree2(&infolist, (FREEFUNC)osiFreeInterfaceInfo); |
3734 | + return found ? 0 : -1; |
3735 | +} |
3736 | + |
3737 | |
3738 | === modified file 'src/libCom/osi/osiSock.h' |
3739 | --- src/libCom/osi/osiSock.h 2016-05-22 03:43:09 +0000 |
3740 | +++ src/libCom/osi/osiSock.h 2017-05-01 18:36:52 +0000 |
3741 | @@ -155,6 +155,17 @@ |
3742 | osiSockAddr addr; |
3743 | } osiSockAddrNode; |
3744 | |
3745 | +typedef struct { |
3746 | + ELLNODE node; |
3747 | + unsigned int up:1; |
3748 | + unsigned int loopback:1; |
3749 | + unsigned int broadcast:1; |
3750 | + unsigned int multicast:1; |
3751 | + unsigned int point2point:1; |
3752 | + osiSockAddr address, netmask; |
3753 | + osiSockAddr endpoint; //!< broadcast or p2p destination address |
3754 | +} osiInterfaceInfo; |
3755 | + |
3756 | /* |
3757 | * sockAddrAreIdentical() |
3758 | * (returns true if addresses are identical) |
3759 | @@ -162,6 +173,32 @@ |
3760 | epicsShareFunc int epicsShareAPI sockAddrAreIdentical |
3761 | ( const osiSockAddr * plhs, const osiSockAddr * prhs ); |
3762 | |
3763 | +/* Fills the provided list with osiInterfaceInfo nodes |
3764 | + * describing the network interfaces of the host machine |
3765 | + * at the time it is called (may change later). |
3766 | + * |
3767 | + * Caller is responsible for freeing elements in the provided list with |
3768 | + * osiFreeInterfaceInfo(). This may be used individually, or in conjuction |
3769 | + * with ellFree2(). |
3770 | + * |
3771 | + * flags provides for forward compatibility (eg. ipv6) and should be zero. |
3772 | + */ |
3773 | +epicsShareFunc int osiGetInterfaceInfo(ELLLIST *pList, unsigned flags); |
3774 | + |
3775 | +/* Find the interface information to the interface having address 'paddr'. |
3776 | + * Fills in the provided 'presults' if non-NULL, in which case the caller |
3777 | + * must free with osiFreeInterfaceInfo(). |
3778 | + * |
3779 | + * Returns zero on success. |
3780 | + * |
3781 | + * flags provides for forward compatibility (eg. ipv6) and should be zero. |
3782 | + */ |
3783 | +epicsShareFunc |
3784 | +int osiGetInterfaceInfoSingle(const osiSockAddr *paddr, osiInterfaceInfo **presult, unsigned flags); |
3785 | + |
3786 | + |
3787 | +epicsShareFunc void osiFreeInterfaceInfo(osiInterfaceInfo *pinfo); |
3788 | + |
3789 | /* |
3790 | * osiSockDiscoverBroadcastAddresses () |
3791 | * Returns the broadcast addresses of each network interface found. |
3792 | |
3793 | === modified file 'src/libCom/test/Makefile' |
3794 | --- src/libCom/test/Makefile 2016-07-22 04:37:54 +0000 |
3795 | +++ src/libCom/test/Makefile 2017-05-01 18:36:52 +0000 |
3796 | @@ -86,6 +86,13 @@ |
3797 | testHarness_SRCS += epicsSockResolveTest.c |
3798 | TESTS += epicsSockResolveTest |
3799 | |
3800 | +TESTPROD_HOST += epicsNetIntfTest |
3801 | +epicsNetIntfTest_SRCS += epicsNetIntfTest.c |
3802 | +epicsNetIntfTest_SYS_LIBS_solaris = socket |
3803 | +epicsNetIntfTest_SYS_LIBS_WIN32 = ws2_32 user32 |
3804 | +testHarness_SRCS += epicsNetIntfTest.c |
3805 | +TESTS += epicsNetIntfTest |
3806 | + |
3807 | TESTPROD_HOST += epicsStringTest |
3808 | epicsStringTest_SRCS += epicsStringTest.c |
3809 | testHarness_SRCS += epicsStringTest.c |
3810 | |
3811 | === modified file 'src/libCom/test/epicsMessageQueueTest.cpp' |
3812 | --- src/libCom/test/epicsMessageQueueTest.cpp 2016-05-22 12:38:18 +0000 |
3813 | +++ src/libCom/test/epicsMessageQueueTest.cpp 2017-05-01 18:36:52 +0000 |
3814 | @@ -151,7 +151,7 @@ |
3815 | testOk(q1->pending() == i, "q1->pending() == %d", i); |
3816 | } |
3817 | testOk1(q1->pending() == 4); |
3818 | - |
3819 | + |
3820 | want = 0; |
3821 | len = q1->receive(cbuf, sizeof cbuf); |
3822 | testOk1(q1->pending() == 3); |
3823 | |
3824 | === added file 'src/libCom/test/epicsNetIntfTest.c' |
3825 | --- src/libCom/test/epicsNetIntfTest.c 1970-01-01 00:00:00 +0000 |
3826 | +++ src/libCom/test/epicsNetIntfTest.c 2017-05-01 18:36:52 +0000 |
3827 | @@ -0,0 +1,220 @@ |
3828 | +/*************************************************************************\ |
3829 | +* Copyright (c) 2015 Brookhaven Science Associates as Operator of |
3830 | +* Brookhaven National Lab. |
3831 | +* EPICS BASE is distributed subject to a Software License Agreement found |
3832 | +* in file LICENSE that is included with this distribution. |
3833 | +\*************************************************************************/ |
3834 | + |
3835 | +#include <stdlib.h> |
3836 | + |
3837 | +#include "dbDefs.h" |
3838 | +#include "osiSock.h" |
3839 | +#include "epicsTypes.h" |
3840 | + |
3841 | +#include "epicsUnitTest.h" |
3842 | +#include "testMain.h" |
3843 | + |
3844 | +static |
3845 | +void testIfInfo(void) |
3846 | +{ |
3847 | + int foundlo = 0, bcastok = 1; |
3848 | + ELLLIST iflist = ELLLIST_INIT; |
3849 | + ELLNODE *cur; |
3850 | + testDiag("Check interface introspection info"); |
3851 | + |
3852 | +#ifdef USE_IFADDRS |
3853 | + testDiag("Using getifaddrs() method"); |
3854 | +#else |
3855 | + testDiag("Using OS default method"); |
3856 | +#endif |
3857 | + |
3858 | + testOk1(osiGetInterfaceInfo(&iflist, 0)==0); |
3859 | + |
3860 | + testOk(ellCount(&iflist)>0, "interface count %d", ellCount(&iflist)); |
3861 | + |
3862 | + for(cur=ellFirst(&iflist); cur; cur=ellNext(cur)) |
3863 | + { |
3864 | + osiInterfaceInfo *info = CONTAINER(cur, osiInterfaceInfo, node); |
3865 | + char buf[30]; |
3866 | + |
3867 | + if(info->loopback) { |
3868 | + testOk(info->up, "loopback interface is up"); |
3869 | + foundlo = 1; |
3870 | + } |
3871 | + |
3872 | + if(info->address.sa.sa_family!=AF_INET) |
3873 | + continue; |
3874 | + |
3875 | + ipAddrToDottedIP(&info->address.ia, buf, sizeof(buf)); |
3876 | + testDiag("Address: %s", buf); |
3877 | + ipAddrToDottedIP(&info->netmask.ia, buf, sizeof(buf)); |
3878 | + testDiag("Netmask: %s", buf); |
3879 | + if(info->broadcast) { |
3880 | + ipAddrToDottedIP(&info->endpoint.ia, buf, sizeof(buf)); |
3881 | + testDiag("Broadcast: %s", buf); |
3882 | + } else if(info->point2point) { |
3883 | + ipAddrToDottedIP(&info->endpoint.ia, buf, sizeof(buf)); |
3884 | + testDiag("Destination: %s", buf); |
3885 | + } |
3886 | + |
3887 | + testDiag(" Up: %s", info->up?"Up":"Down"); |
3888 | + testDiag(" Loopback: %s", info->loopback?"Yes":"No"); |
3889 | + testDiag(" Broadcast: %s", info->broadcast?"Yes":"No"); |
3890 | + testDiag(" Multicast: %s", info->multicast?"Yes":"No"); |
3891 | + testDiag(" Point2Point: %s", info->point2point?"Yes":"No"); |
3892 | + |
3893 | + /* check consistency of address, netmask, and broadcast address */ |
3894 | + if(info->broadcast) { |
3895 | + epicsUInt32 addr = ntohl(info->address.ia.sin_addr.s_addr), |
3896 | + mask = ntohl(info->netmask.ia.sin_addr.s_addr), |
3897 | + bcast = ntohl(info->endpoint.ia.sin_addr.s_addr), |
3898 | + bcast2= (addr&mask) | ~mask; |
3899 | + |
3900 | + if(bcast!=bcast2) { |
3901 | + struct sockaddr_in addr; |
3902 | + addr.sin_family = AF_INET; |
3903 | + addr.sin_addr.s_addr = htonl(bcast2); |
3904 | + addr.sin_port = 0; |
3905 | + ipAddrToDottedIP(&addr, buf, sizeof(buf)); |
3906 | + testDiag("Warning: expected broadcast address %s", buf); |
3907 | + bcastok = 0; |
3908 | + } |
3909 | + } |
3910 | + } |
3911 | + |
3912 | + ellFree2(&iflist, (FREEFUNC)osiFreeInterfaceInfo); |
3913 | + |
3914 | + testOk(foundlo, "Found loopback interface"); |
3915 | + testOk(bcastok, "Broadcast addresses consistent"); |
3916 | +} |
3917 | + |
3918 | +static |
3919 | +void testBroadcast(void) |
3920 | +{ |
3921 | + ELLLIST iflist = ELLLIST_INIT; |
3922 | + ELLNODE *cur; |
3923 | + SOCKET sock; |
3924 | + osiSockAddr match; |
3925 | + |
3926 | + testDiag("Discover broadcast addresses"); |
3927 | + |
3928 | + sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); |
3929 | + if(sock==INVALID_SOCKET) |
3930 | + testAbort("Failed to allocate socket"); |
3931 | + |
3932 | + match.ia.sin_family = AF_INET; |
3933 | + match.ia.sin_addr.s_addr = htonl(INADDR_ANY); |
3934 | + match.ia.sin_port = 0; |
3935 | + |
3936 | + osiSockDiscoverBroadcastAddresses(&iflist, sock, &match); |
3937 | + |
3938 | + testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist)); |
3939 | + |
3940 | + for(cur=ellFirst(&iflist); cur; cur=ellNext(cur)) |
3941 | + { |
3942 | + osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node); |
3943 | + char buf[30]; |
3944 | + |
3945 | + ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf)); |
3946 | + testDiag("Broadcast: %s", buf); |
3947 | + } |
3948 | + |
3949 | + ellFree(&iflist); |
3950 | + |
3951 | + testDiag("\"Discover\" loopback address"); |
3952 | + |
3953 | + match.ia.sin_family = AF_INET; |
3954 | + match.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
3955 | + match.ia.sin_port = 0; |
3956 | + |
3957 | + osiSockDiscoverBroadcastAddresses(&iflist, sock, &match); |
3958 | + |
3959 | + testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist)); |
3960 | + |
3961 | + for(cur=ellFirst(&iflist); cur; cur=ellNext(cur)) |
3962 | + { |
3963 | + osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node); |
3964 | + char buf[30]; |
3965 | + |
3966 | + ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf)); |
3967 | + testDiag("Broadcast: %s", buf); |
3968 | + } |
3969 | + |
3970 | + ellFree(&iflist); |
3971 | + |
3972 | + epicsSocketDestroy(sock); |
3973 | +} |
3974 | + |
3975 | +static |
3976 | +void testLocal(void) |
3977 | +{ |
3978 | + SOCKET sock; |
3979 | + osiSockAddr addr; |
3980 | + char buf[30]; |
3981 | + |
3982 | + testDiag("Discover first local address"); |
3983 | + |
3984 | + sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); |
3985 | + if(sock==INVALID_SOCKET) |
3986 | + testAbort("Failed to allocate socket"); |
3987 | + |
3988 | + addr = osiLocalAddr(sock); |
3989 | + |
3990 | + testOk1(addr.sa.sa_family==AF_INET); |
3991 | + |
3992 | + ipAddrToDottedIP(&addr.ia, buf, sizeof(buf)); |
3993 | + testDiag("Address: %s", buf); |
3994 | + |
3995 | + epicsSocketDestroy(sock); |
3996 | +} |
3997 | + |
3998 | +static |
3999 | +void testBroadcastMatch(void) |
4000 | +{ |
4001 | + SOCKET sock; |
4002 | + osiSockAddr match; |
4003 | + ELLNODE *cur; |
4004 | + ELLLIST iflist = ELLLIST_INIT; |
4005 | + char buf[30]; |
4006 | + |
4007 | + testDiag("Check osiSockDiscoverBroadcastAddresses() w/ matching"); |
4008 | + |
4009 | + sock = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); |
4010 | + if(sock==INVALID_SOCKET) |
4011 | + testAbort("Failed to allocate socket"); |
4012 | + |
4013 | + match = osiLocalAddr(sock); |
4014 | + |
4015 | + testOk1(match.sa.sa_family==AF_INET); |
4016 | + ipAddrToDottedIP(&match.ia, buf, sizeof(buf)); |
4017 | + testDiag("Address: %s", buf); |
4018 | + |
4019 | + osiSockDiscoverBroadcastAddresses(&iflist, sock, &match); |
4020 | + |
4021 | + testOk(ellCount(&iflist)>0, "broadcast count %d", ellCount(&iflist)); |
4022 | + |
4023 | + for(cur=ellFirst(&iflist); cur; cur=ellNext(cur)) |
4024 | + { |
4025 | + osiSockAddrNode *info = CONTAINER(cur, osiSockAddrNode, node); |
4026 | + char buf[30]; |
4027 | + |
4028 | + ipAddrToDottedIP(&info->addr.ia, buf, sizeof(buf)); |
4029 | + testDiag("Broadcast: %s", buf); |
4030 | + } |
4031 | + |
4032 | + ellFree(&iflist); |
4033 | + |
4034 | + epicsSocketDestroy(sock); |
4035 | +} |
4036 | + |
4037 | +MAIN(epicsNetIntfTest) |
4038 | +{ |
4039 | + testPlan(10); |
4040 | + osiSockAttach(); |
4041 | + testIfInfo(); |
4042 | + testBroadcast(); |
4043 | + testLocal(); |
4044 | + testBroadcastMatch(); |
4045 | + osiSockRelease(); |
4046 | + return testDone(); |
4047 | +} |
4048 | |
4049 | === modified file 'src/libCom/test/epicsRunLibComTests.c' |
4050 | --- src/libCom/test/epicsRunLibComTests.c 2016-07-22 04:37:54 +0000 |
4051 | +++ src/libCom/test/epicsRunLibComTests.c 2017-05-01 18:36:52 +0000 |
4052 | @@ -30,6 +30,7 @@ |
4053 | int epicsMMIOTest(void); |
4054 | int epicsMutexTest(void); |
4055 | int epicsSockResolveTest(void); |
4056 | +int epicsNetIntfTest(void); |
4057 | int epicsSpinTest(void); |
4058 | int epicsStackTraceTest(void); |
4059 | int epicsStdioTest(void); |
4060 | @@ -84,6 +85,7 @@ |
4061 | runTest(epicsMMIOTest); |
4062 | runTest(epicsMutexTest); |
4063 | runTest(epicsSockResolveTest); |
4064 | + runTest(epicsNetIntfTest); |
4065 | runTest(epicsSpinTest); |
4066 | runTest(epicsStackTraceTest); |
4067 | runTest(epicsStdioTest); |
4068 | |
4069 | === modified file 'src/libCom/test/ringPointerTest.c' |
4070 | --- src/libCom/test/ringPointerTest.c 2014-11-18 23:30:43 +0000 |
4071 | +++ src/libCom/test/ringPointerTest.c 2017-05-01 18:36:52 +0000 |
4072 | @@ -235,7 +235,6 @@ |
4073 | MAIN(ringPointerTest) |
4074 | { |
4075 | int prio = epicsThreadGetPrioritySelf(); |
4076 | - |
4077 | testPlan(37); |
4078 | testSingle(); |
4079 | epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityScanLow); |
Various inline comments and questions.