Compare commits

...

104 Commits

Author SHA1 Message Date
54117d5371 Don't use build-ids. We don't build debug packages and it causes conflics for the copied over compatibility libraris readelf etc
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 2s
Base / Cross linux-aarch64 (push) Failing after 1s
Base / Cross linux-arm gnueabihf (push) Failing after 1s
Base / Cross linux-arm gnueabi (push) Failing after 2s
Base / CentOS-7 (push) Failing after 2s
Base / Fedora-33 (push) Failing after 1s
Base / Fedora-latest (push) Failing after 2s
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
2024-06-12 15:37:41 +02:00
cc134d4649 work around rpmbuild's problems to find internal perl modules 2024-06-07 17:20:12 +02:00
012c4c73f1 fix LD_LIBRARY_PATH for VxWorks license manager 2024-06-07 17:19:09 +02:00
96864abb6c Simplify cross build targets. In particular avoid rpath because that annoys rpmbuild 2024-06-07 17:19:01 +02:00
ad00947d48 use our own wine on RHEL9 2024-05-06 09:02:11 +02:00
2db99d46a7 need INSTALL_LOCATION realclean to properly clean up 2024-05-03 13:44:12 +02:00
11661455f1 move module pcas into local file 2024-05-02 16:20:01 +02:00
ecb02803c8 use versioned libraries from now on for all architectures 2024-05-02 16:20:01 +02:00
fcb720275a bump RPM version 2024-05-02 16:20:01 +02:00
87d492bffd Merge branch '7.0' into PSI-7.0 2024-04-30 14:40:00 +02:00
Érico Nogueira
1a9dc993c1 Fix gmtime messages in epicsTimeZoneTest. 2024-04-29 15:10:47 -07:00
b379c6f3a5 fix problems with LD_LIBRARY_PATH when not installing to final location (e.g. when building RPMs)
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 1s
Base / Cross linux-aarch64 (push) Failing after 2s
Base / Fedora-33 (push) Failing after 2s
Base / Fedora-latest (push) Failing after 1s
Base / Cross linux-arm gnueabi (push) Failing after 1s
Base / Cross linux-arm gnueabihf (push) Failing after 2s
Base / CentOS-7 (push) Failing after 1s
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2024-04-25 14:33:25 +02:00
da010afde9 fix rpath-link when FINAL_LOCATION is set 2024-04-25 14:33:25 +02:00
cb710920d0 fix bug that left ':'s behind and put only current (which is highest) EPICS version in PATH 2024-04-25 14:33:24 +02:00
87dea74dcd fix linking the caRepeater.service 2024-04-25 14:33:24 +02:00
d35c7fe5eb fix which files belong to which rpm and their dependencies 2024-04-25 14:33:24 +02:00
c5469efca1 change default permissions because rpmbuild likes the files owner-writable 2024-04-25 14:33:24 +02:00
fd436c40e8 fix problem removing broken links 2024-04-25 14:33:24 +02:00
8557d8adce fix permission of caGateway.service 2024-04-25 14:33:24 +02:00
a0c55f597b do not kill the caRepeater on update because that would kill dependent services like caCateways 2024-04-25 14:33:24 +02:00
9090f54f45 Re-added SHRLIB_SUFFIX change which avoids shared library version numbers
for older RHEL7 versions because of backward compatibility problems with RPM.
Remove the exception in CONFIG_SITE.Common.linuxCommon for release 7.0.8!
Create links with full version shared library names to allow programs built
against previous rpm version to run.
2024-04-25 14:33:13 +02:00
6085f9eb0b git ignore bpmbuild products 2024-04-23 11:55:52 +02:00
a1de706d2c update sub-submodules too 2024-04-23 11:55:52 +02:00
0b12a0cf7e fix Obsoletes: caRepeater version 2024-04-23 11:55:45 +02:00
Michael Davidsaver
cb1571783b link.h wrong type
Change to unsigned incorrectly increased size.

e88a186fc3
2024-04-02 08:35:25 -07:00
Freddie Akeroyd
5dfc6caf3c Accept should return SOCKET rather than int 2024-03-06 09:48:26 -06:00
Ralph Lange
cb49bd0133 Update ci-scripts to 3.4.1
Builds on AppVeyor (VS2019) started to fail
because of the Python version/distutils
2024-03-01 18:00:40 +01:00
Freddie Akeroyd
4720b61c1f Move call to setThreadName()
The call to setThreadName() is moved to avoid a race condition that
can happen with very short lived processes. If the process terminates
very quickly e.g. is a google test runner or the msi.exe command
called from a Makefile during a build, then very occasionally a
crash can occur during process termination if setThreadName() when called
from the newly created thread. This looks to be becauae the DLL it is
trying to call gets unloaded between it getting a handle to the DLL
and making the call. Moving the setThreadName() call to the creating
thread avoids this problem. The issue was only ever seen with statically
linked epics executables, I am unsure if the way a DLL based epics
program unloads might avoid this, or just make it less likely but
still possible. As mentioned above, the issue will only ever occur
to threads that are created during process termination and so would
not affect running IOCs
2024-02-21 09:59:36 -06:00
4383cf291e allow macros with defaults in dbLoadRecords without substitutions 2024-02-21 09:50:03 -06:00
Simon Rose
a6977ae731 Fix issue where VSCode makefile extension can delete files
The problem is that VSCode's make extension, in order to determine
some information about the project, runs
```
make --dry-run --always-make
```
which despite its name will actually try to remake the configure/*
files. Running `installEpics.pl` on these will delete them first,
then try copy them, resulting in an error.
2024-02-21 09:45:14 -06:00
e9dcdd8936 do not set EPICS_BASE as that changes the default EPICS version chosen by iocsh and takes precedence over the /usr/local/epics/base link
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 1s
Base / Cross linux-aarch64 (push) Failing after 2s
Base / Cross linux-arm gnueabi (push) Failing after 1s
Base / Cross linux-arm gnueabihf (push) Failing after 2s
Base / CentOS-7 (push) Failing after 1s
Base / Fedora-33 (push) Failing after 2s
Base / Fedora-latest (push) Failing after 1s
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2024-01-29 17:07:43 +01:00
Michael Davidsaver
07cbf00187 posix: warn on epicsSocketCreate() without osiSockAttach() 2023-12-22 10:26:28 -08:00
Michael Davidsaver
c75b9ad0be add dbRecordNode::order
Keep track of parse order of record instances.
2023-12-22 10:26:28 -08:00
Michael Davidsaver
87acb98d1e ca: remove hostname length limit when parsing address lists 2023-12-22 10:26:28 -08:00
Michael Davidsaver
403e203325 quieting clang-tidy, use unsigned
places where we shouldn't be negative anyway
2023-12-22 10:26:28 -08:00
Michael Davidsaver
a7a56912eb default/epicsMessageQueue: initialize threadNode 2023-12-22 10:26:28 -08:00
Michael Davidsaver
fe4a32e425 default/epicsMessageQueue: avoid volatile flag
Only one place where eventSent was accessed
without locking.  Move this load earlier.
2023-12-22 10:26:28 -08:00
Michael Davidsaver
823386573f ipAddrToAsciiGlobal::run() keep scratch buffer as local 2023-12-22 10:26:28 -08:00
Michael Davidsaver
ea8247586f adjustToWorstCaseAlignment() simplify
Add some STATIC_ASSERT to check assumptions.

Only in-tree use is freeListLib to ensure chunks in
a malloc()'d block are aligned.
2023-12-22 10:26:28 -08:00
Michael Davidsaver
e88a186fc3 make link::flags bit field unsigned 2023-12-22 10:26:28 -08:00
Michael Davidsaver
20f32068c3 gha add workflow_dispatch 2023-12-22 10:26:28 -08:00
Andrew Johnson
8998341588 Update version numbers and submodules after release 2023-12-15 13:03:57 -06:00
Andrew Johnson
448fde0671 Set release version numbers
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 2s
Base / Cross linux-aarch64 (push) Failing after 1s
Base / Cross linux-arm gnueabi (push) Failing after 2s
Base / Cross linux-arm gnueabihf (push) Failing after 1s
Base / CentOS-7 (push) Failing after 2s
Base / Fedora-33 (push) Failing after 1s
Base / Fedora-latest (push) Failing after 2s
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2023-12-14 16:42:10 -06:00
Andrew Johnson
477e36b1f0 Update submodules to tagged versions 2023-12-14 16:42:10 -06:00
Andrew Johnson
fad830bd14 Remove example sub-module 2023-12-14 16:42:10 -06:00
Andrew Johnson
331df3d7e4 UNRELEASED => 7.0.8 2023-12-14 16:42:10 -06:00
Andrew Johnson
4a53713f37 Update Release Procedures/Checklist 2023-12-14 16:31:42 -06:00
Andrew Johnson
2e6fd505d2 Use epicsSnprintf() for old MSVC compilers 2023-12-14 11:31:36 -06:00
Andrew Johnson
5ecf7d18a8 Clean up Clang 15 sprintf() warnings in libcom and ca 2023-12-13 13:34:25 -06:00
Andrew Johnson
56dbc949ff Add declarations to flex, cleans up Clang 15 warnings. 2023-12-12 13:44:08 -06:00
e2bb42d8d3 obsolete caRepeater rpm
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 2s
Base / Cross linux-aarch64 (push) Failing after 1s
Base / Cross linux-arm gnueabi (push) Failing after 2s
Base / Cross linux-arm gnueabihf (push) Failing after 1s
Base / CentOS-7 (push) Failing after 2s
Base / Fedora-33 (push) Failing after 1s
Base / Fedora-latest (push) Failing after 2s
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2023-12-10 13:47:17 +01:00
abcada0d85 add rpm specfile and profile script
Some checks failed
Check EditorConfig / editorconfig (push) Failing after 1s
Base / Cross linux-aarch64 (push) Failing after 2s
Base / Cross linux-arm gnueabi (push) Failing after 1s
Base / Cross linux-arm gnueabihf (push) Failing after 2s
Base / CentOS-7 (push) Failing after 1s
Base / Fedora-33 (push) Failing after 2s
Base / Fedora-latest (push) Failing after 1s
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 unsigned char (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-22 gcc-12 c++20 Werror (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2023-12-08 15:32:20 +01:00
2c35d60a64 silent wine errors 2023-12-08 11:38:38 +01:00
af1b77eb0f fix rpath when FINAL_LOCATION is set 2023-12-07 16:07:02 +01:00
93947eb027 prevents using make -j2 2023-12-06 14:24:56 +01:00
Simon Rose
6a369acd0b Add newline to help text 2023-12-05 08:05:12 -08:00
961671259f Add support for RHEL9 2023-12-04 16:00:24 +01:00
Michael Davidsaver
db2482117d rationalize osdMutex
Avoids split allocation.
Eliminates special case free-list.

win32: eliminate pre-XP
rtems-score: eliminate non-fast
2023-12-04 11:04:51 +01:00
a66caa5985 move cross compilers away from AFS 2023-12-04 10:08:47 +01:00
4803aae904 re-enable alternative PowerPMAC archs 2023-12-01 16:52:41 +01:00
427be18e2e upgrade cross windows build to use mvsc 2019 on Linux archs that support it 2023-12-01 16:52:41 +01:00
fff690a449 skip Microsoft noise in rc 2023-12-01 16:52:41 +01:00
428b836500 switch to 64 bit raspbian cross compiler 2023-12-01 16:52:41 +01:00
6c74507b11 all our current host OS can build nilrt7-armv7a 2023-12-01 16:52:40 +01:00
122ca4e1d3 change PROC to ASL0 2023-12-01 16:51:49 +01:00
Simon Rose
d9d35a4eab Allow auto-declarations for dbdExpand.pl 2023-12-01 09:19:03 -06:00
Ralph Lange
116881ad87 Use split() for fetching last tag with darcs
(setting $/='' breaks reading multi-line into an array)
2023-11-29 09:53:24 -06:00
96857d92bc fix problem with commands returning multiple trailing newlines 2023-11-29 09:53:24 -06:00
Érico Nogueira
0cf8c934f9 Set ASL0 for mbboDirect Bx fields.
Since the record's VAL field is ASL0, it doesn't make sense to gate
writes into the Bx fields with ASL1.
2023-11-29 09:44:03 -06:00
Michael Davidsaver
69d05fe5b0 Add ERROR to error messages 2023-11-26 15:25:09 -08:00
Michael Davidsaver
511bf1ffca const-ify dbLink arrays
external code really should never be modifying pamaplinkType[]
2023-11-25 14:52:16 -08:00
Uchenna Ezeobi
7a7028de56 Config: Fixed Hard coded LDFLAGS in MVME2500 2023-11-17 15:20:32 -06:00
Michael Davidsaver
7a65c001ce update submodules 2023-11-15 07:31:53 -08:00
Michael Davidsaver
0bc6ff3d4c release notes 2023-11-07 16:00:46 -08:00
Michael Davidsaver
f2fe9d1203 bi "Raw Soft Channel" use MASK
If set, apply MASK to value read into RVAL.
2023-11-07 15:53:41 -08:00
Michael Davidsaver
ffc2d0f23a incorrect error check on GetStdHandle()
Likely inconsequential as GetConsoleMode() should
return 0 when given an invalid handle.
2023-11-07 15:53:41 -08:00
Michael Davidsaver
a352865df9 print ANSI escapes to stderr
unconditionally print ANSI some escapes (to colorize errors)
to the stderr stream.
2023-11-07 15:53:22 -08:00
Michael Davidsaver
63740f2edd colorize more errlog messages 2023-11-07 15:53:22 -08:00
Jeremy Lorelli
f4be9daf4d Null check callback function in callbackRequest
Previously, calling callbackRequest(pcallback), where pcallback->callback
is NULL, would result in a crash on one of the callback threads.
2023-11-07 15:17:04 -08:00
Michael Davidsaver
3fa1932345 update ci-scripts 2023-11-07 15:14:09 -08:00
Michael Davidsaver
95bd5453d9 dbRecordField() add "did you mean..." hint for unknown field 2023-11-01 09:52:32 -05:00
Michael Davidsaver
eb3f8a004c const-ify dbCopyEntry() and dbCopyEntryContents() 2023-11-01 09:52:32 -05:00
Michael Davidsaver
9f868a1074 avoid hang during concurrent db_cancel_event()
cf. fab8fd7102
2023-11-01 09:24:44 -05:00
Michael Davidsaver
b41787b6bf doc 2023-10-22 17:42:36 -07:00
19b232545c gha: turn most warnings into errors in github build 2023-10-22 17:42:36 -07:00
Michael Davidsaver
2ca70d3aa2 iocsh: keep history file 2023-10-22 17:42:36 -07:00
JJL772
395015aac4 Com: Make STATIC_ASSERT macro typedefs unique 2023-10-22 17:42:36 -07:00
Michael Davidsaver
92cae86ff2 dbRecordsOnceOnly allow append only with "*"
with

> record(ai, "myrec") {}

dbRecordsOnceOnly!=0 currently disallows appending fields with either form:

> record("*", "myrec") {} # error
> record(ai, "myrec") {}  # error

Change the meaning such that dbRecordsOnceOnly!=0
allways allows appending when explicitly intended (rtype "*").

> record("*", "myrec") {} # allowed
> record(ai, "myrec") {}  # error

Also clearly label this parse error.
2023-10-22 17:42:36 -07:00
Jack Harper
49ea46ee5e iocsh: add comment to cvtArg explaining default iocsharg behaviour 2023-10-22 17:42:36 -07:00
Michael Davidsaver
df908f299b remove unused local 2023-10-22 17:42:36 -07:00
AlexWells
6dec68554c iocsh: Add underline separator between help outputs
Also tweaks the overall format of the message a bit.
Add tests for new help output format
2023-10-22 17:42:36 -07:00
Michael Davidsaver
badd8f518d update modules/pvData 2023-10-22 17:42:35 -07:00
Michael Davidsaver
766c9906b5 update ci-scripts 2023-10-22 14:46:28 -07:00
Jeremy Lorelli
60fa2d31da libCom: Fix buggy pointer dereference in postfix() 2023-09-26 09:52:13 -07:00
Michael Davidsaver
88ea1507f4 Fix compile w/ vs2012 2023-09-22 08:20:27 -07:00
Emilio Perez
8c08c57247 Allow adding error symbols after early initialization
This was acomplished by making errSymbolAdd add the error symbol directly
into the global hash table and removing errnumlist which is not needed
anymore.

Unit tests were added for checking the following cases:
- Adding a valid symbol and checking that it exists (fixed by this change)
- Getting an existing error symbol
- Getting a non existing error symbol
- Adding an invalid error symbol (fixed by this change)
- Adding an error symbol with a code that already
  exists (fixed by this change)

Therefore, issue #268 was fixed

error: statically allocate error symbol hash table

This will allow calling errSymbolAdd before errSymBld, therefore, a
function adding error symbols can now be run before iocInit or errlogInit

error: add a constant for the minimum module number

Make adding an identical error symbol not fail

A test case was also added which test that adding an error symbol
with same error code and message as one added before will not fail

Add locking to error symbol table

This protects the cases of:
- simultaneously adding and requesting of an error symbol
- simultaneously adding many error symbols

Update release notes regarding adding error symbols
2023-09-22 08:20:19 -07:00
Michael Davidsaver
45b3bce515 epicsThreadShow() zombies
Flag when the thread has returned, but the tracking
struct is still around.  eg. in need of joining.
2023-09-22 08:19:25 -07:00
Érico Nogueira
7c4a21eab4 libCom: detect support for backtrace() with __has_include.
This is necessary in order to build epics-base with musl libc, for
example, and any other C libraries which don't include this
functionality. In order to not regress builds with older compilers, we
still support the uclibc check. Furthermore, it has been checked that
uclibc-ng (the maintained version of uclibc) doesn't install the
<execinfo.h> header when the functionality is disabled [1] [2].

To avoid repetition, we don't define HAS_EXECINFO to 0 when it is not
available.

[1] https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/Makefile.in?id=cdb07d2cd52af39feb425e6d36c02b30916b9f0a#n224
[2] https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/Makefile.in?id=cdb07d2cd52af39feb425e6d36c02b30916b9f0a#n277
2023-09-21 08:18:49 -07:00
Michael Davidsaver
fab8fd7102 dbEvent: handle multiple db_event_cancel()
Allow for multiple db_event_cancel() (concurrent or
self-cancel) prior to event_task wakeup.

In db_event_cancel(), immediate free() only if idle
(not queued or in progress).  Otherwise, defer free()
to event task.  Avoids need to immediately expunge
canceled event from queue.  Allow event task to
process canceled events as normal (except no user_sub)
until npend==0.
2023-09-21 08:18:49 -07:00
Michael Davidsaver
3d25756065 privatize evSubscrip 2023-09-21 08:18:49 -07:00
Michael Davidsaver
5aca4c684c dbEvent minor 2023-09-14 08:54:40 +02:00
Michael Davidsaver
39b5c01c5d minor 2023-09-14 08:54:40 +02:00
Michael Davidsaver
3b22e5f710 doc dbLock.h 2023-09-14 08:54:40 +02:00
Michael Davidsaver
9f660f2238 add initHookAtPrepare 2023-09-05 08:54:48 +02:00
113 changed files with 1334 additions and 831 deletions

View File

@@ -29,6 +29,7 @@ on:
- '.gitattributes'
- '**/*.html'
- '**/*.md'
workflow_dispatch:
env:
SETUP_PATH: .ci-local:.ci

4
.gitignore vendored
View File

@@ -18,3 +18,7 @@ O.*/
.*.swp
.DS_Store
.iocsh_history
RPMS
SRPMS
BUILDROOT
*.rpm

View File

@@ -30,3 +30,6 @@ copysrc:
tar:
tar cfjP epics_base-$(EPICS_VERSION_NUMBER).tar.bz2 $(INSTALL_LOCATION)
rpm:
rpmbuild -bb epics-base.spec

View File

@@ -48,7 +48,7 @@ EPICS_VERSION = 7
EPICS_REVISION = 0
# EPICS_MODIFICATION must be a number >=0 and <256
EPICS_MODIFICATION = 7
EPICS_MODIFICATION = 8
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included in the official EPICS version number if zero

View File

@@ -2,7 +2,7 @@
EPICS_CA_MAJOR_VERSION = 4
EPICS_CA_MINOR_VERSION = 14
EPICS_CA_MAINTENANCE_VERSION = 3
EPICS_CA_MAINTENANCE_VERSION = 4
# Development flag, set to zero for release versions

View File

@@ -422,10 +422,10 @@ INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS)))
#---------------------------------------------------------------
# Installed file permissions
BIN_PERMISSIONS = 555
LIB_PERMISSIONS = 444
SHRLIB_PERMISSIONS = 555
INSTALL_PERMISSIONS = 444
BIN_PERMISSIONS = 755
LIB_PERMISSIONS = 644
SHRLIB_PERMISSIONS = 755
INSTALL_PERMISSIONS = 644
#---------------------------------------------------------------
#

View File

@@ -1,7 +1,7 @@
# Version number for the database APIs and shared library
EPICS_DATABASE_MAJOR_VERSION = 3
EPICS_DATABASE_MINOR_VERSION = 22
EPICS_DATABASE_MINOR_VERSION = 23
EPICS_DATABASE_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions

View File

@@ -1,7 +1,7 @@
# Version number for the libcom APIs and shared library
EPICS_LIBCOM_MAJOR_VERSION = 3
EPICS_LIBCOM_MINOR_VERSION = 22
EPICS_LIBCOM_MINOR_VERSION = 23
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions

View File

@@ -514,6 +514,13 @@ ifneq (,$(strip $(SHRLIB_VERSION)))
@$(RM) $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
ln -s $< $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
endif # SHRLIB_VERSION
else # SHRLIB_SUFFIX
ifeq ($(BUILD_CLASS),HOST)
ifneq (,$(strip $(SHRLIB_VERSION)))
@$(RM) $@.$(SHRLIB_VERSION)
ln -s $< $@.$(SHRLIB_VERSION)
endif # HOST
endif # SHRLIB_VERSION
endif # SHRLIB_SUFFIX
ifneq ($(INSTALL_TCLLIB),$(INSTALL_BIN))
@@ -545,11 +552,11 @@ endif # LOADABLE_SHRLIB_SUFFIX
ifneq ($(INSTALL_CONFIGS),)
$(INSTALL_CONFIG)/%: %
$(ECHO) "Installing config file $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D))
$(INSTALL_CONFIG)/%: ../%
$(ECHO) "Installing config file $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D))
endif
$(INSTALL_INCLUDE)/%: $(COMMON_DIR)/%

View File

@@ -1,6 +1,8 @@
# Include definitions common to linux pentium targets
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
BUILD_CLASS = HOST
TOOLSET_LOCATION = /opt/rh
TOOLSET = devtoolset-12
STD_CXXFLAGS = -std=c++20

View File

@@ -1 +1,3 @@
include $(CONFIG)/os/CONFIG.Common.linux-clang
BUILD_CLASS = HOST

View File

@@ -1,6 +1,8 @@
# Include definitions common to linux pentium targets
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
BUILD_CLASS = HOST
TOOLSET_LOCATION = /opt/rh
TOOLSET = gcc-toolset-12
STD_CXXFLAGS = -std=c++20

View File

@@ -1,3 +1,5 @@
include $(CONFIG)/os/CONFIG.Common.linux-clang
BUILD_CLASS = HOST
STD_CXXFLAGS = -std=c++2a

View File

@@ -0,0 +1,20 @@
# Include definitions common to linux pentium targets
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
BUILD_CLASS = HOST
TOOLSET_LOCATION = /opt/rh
TOOLSET = gcc-toolset-12
STD_CXXFLAGS = -std=c++20
# Fix bug in gcc-toolset-11 calling the old assembler
ifneq ($(filter %-11,$(TOOLSET)),)
TARGET_CPPFLAGS += $(TOOLSET_DIR:%=-B$(SYSROOT)%/bin)
TARGET_LDFLAGS += $(TOOLSET_DIR:%=-B$(SYSROOT)%/bin)
endif
ifneq (($(TOOLSET)),)
# Perl requests (native) annobin incompatible with the annobin from any TOOLSET
# Disable Perl specific CFLAGS
override Cap5_CFLAGS=
endif

View File

@@ -0,0 +1,5 @@
include $(CONFIG)/os/CONFIG.Common.linux-clang
BUILD_CLASS = HOST
STD_CXXFLAGS = -std=c++2a

View File

@@ -1,6 +1,6 @@
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
VXWORKS_VERSION = 5.5.1
WIND_BASE = /afs/psi.ch/project/vxworks/Tornado2.2.1
WIND_BASE = /opt/VxWorks/Tornado2.2.1
#there is a problem with our ccppc and optimization
# -O0 works, -O and -O1 and higher are buggy

View File

@@ -1,3 +1,3 @@
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32
VXWORKS_VERSION = 6.9
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
#export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH:%=%:)$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib

View File

@@ -1,6 +1,6 @@
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
VXWORKS_VERSION = 6.9
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
#export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH:%=%:)($(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
# -fno-implicit-fp causes error: "unable to find a register to spill in class 'FLOAT_REGS'"
ARCH_DEP_CFLAGS = -mcpu=604 -mstrict-align

View File

@@ -5,18 +5,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
ARCH_CLASS = x86_64
LDLIBS_SHARED_YES=LDLIBS
SDK = gcc
SDK_DIR = /opt/xgcc/gcc-8.3.0-deb10
GNU_ARCH = x86_64-deb10-linux-gnu
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
GNU_DIR = $(SDK_DIR)
GNU_BIN = $(GNU_DIR)/bin/
GNU_TARGET_INCLUDE_DIR =
GNU_TARGET=x86_64-deb10-linux-gnu
ARCH_DEP_CPPFLAGS =
AS=$(GNU_BIN)/$(GNU_TARGET)-as
GNU_DIR = /opt/xgcc/gcc-8.3.0-deb10
GNU_TARGET = x86_64-deb10-linux-gnu
STD_CXXFLAGS = -std=c++17

View File

@@ -5,17 +5,10 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
ARCH_CLASS = ppc
SDK = gcc
SDK_DIR = /opt/xgcc/gcc-8.5.0
GNU_ARCH = powerpc-ppmac-linux-gnu
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
GNU_DIR = $(SDK_DIR)
GNU_BIN = $(GNU_DIR)/bin/
GNU_TARGET_INCLUDE_DIR =
GNU_TARGET=powerpc-ppmac-linux-gnu
GNU_DIR = /opt/xgcc/gcc-8.5.0
GNU_TARGET = powerpc-ppmac-linux-gnu
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
ARCH_DEP_LDFLAGS+=-Wl,-rpath,/opt/xgcc/gcc-8.5.0/$(GNU_ARCH)/lib
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/lib/powerpc-linux-gnu/
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/usr/lib/powerpc-linux-gnu/
AS=$(GNU_BIN)/$(GNU_TARGET)-as
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(GNU_DIR)/$(GNU_TARGET)/sys-root/lib/powerpc-linux-gnu
STD_CXXFLAGS = -std=c++17

View File

@@ -24,13 +24,13 @@ STATIC_LDFLAGS_NO=
STATIC_LDLIBS_YES= -Wl,-Bdynamic
# Set runtime path for shared libraries if LINKER_USE_RPATH=YES
SHRLIBDIR_RPATH_LDFLAGS_YES = $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%)
SHRLIBDIR_RPATH_LDFLAGS_YES = $(subst $(abspath $(LINKER_ORIGIN_ROOT)),$(FINAL_LOCATION),$(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%)) $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)
SHRLIBDIR_RPATH_LDFLAGS_ORIGIN = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(SHRLIB_DEPLIB_DIRS))
SHRLIBDIR_LDFLAGS += \
$(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH))
# Set runtime path for products if LINKER_USE_RPATH=YES
PRODDIR_RPATH_LDFLAGS_YES = $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%)
PRODDIR_RPATH_LDFLAGS_YES = $(subst $(abspath $(LINKER_ORIGIN_ROOT)),$(FINAL_LOCATION),$(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%)) $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)
PRODDIR_RPATH_LDFLAGS_ORIGIN = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(PROD_DEPLIB_DIRS))
PRODDIR_LDFLAGS += \
$(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH))

View File

@@ -3,10 +3,9 @@
# Include definitions common to all Linux ARM targets
include $(CONFIG)/os/CONFIG.Common.linux-arm
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/arm-linux-4.4.2-v4
GNU_DIR=/opt/moxa/arm-linux-4.4.2-v4
GNU_TARGET=arm
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(GNU_DIR)/arm-none-linux-gnueabi/lib
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
COMMANDLINE_LIBRARY = READLINE_NCURSES

View File

@@ -7,7 +7,7 @@ COMMANDLINE_LIBRARY = READLINE_CURSES
ARCH_CLASS = xscale
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/xscale_be/armv5teb-montavista-linuxeabi
GNU_DIR=/opt/moxa/xscale_be/armv5teb-montavista-linuxeabi
ARCH_DEP_CFLAGS += -funwind-tables

View File

@@ -1,4 +1,5 @@
# National Instruments CompactRIO running LabView RT 19.5.1
# requires RPM gcc-c++-arm-linux-gnu
# Include definitions common to all Linux targets
include $(CONFIG)/os/CONFIG.Common.linuxCommon
@@ -8,10 +9,13 @@ ARCH_CLASS = arm
GNU_TARGET = arm-linux-gnu
SYSROOT = /opt/LabVIEW-RT-19.5.1/arm/sysroots/armv7a-vfp-neon-nilrt-linux-gnueabi
GNU_BIN = /bin
GNU_BIN = /opt/RHEL7/bin
# Needed on RHEL9:
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)/usr/$$LIB:/opt/RHEL7/$$LIB
ARCH_DEP_CPPFLAGS += -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon
ARCH_DEP_CXXFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/arm-nilrt-linux-gnueabi/
ARCH_DEP_CXXFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/
ARCH_DEP_CXXFLAGS += -I=/usr/include/c++/4.7.2/arm-nilrt-linux-gnueabi
ARCH_DEP_CXXFLAGS += -I=/usr/include/c++/4.7.2
COMMANDLINE_LIBRARY = READLINE_NCURSES

View File

@@ -10,13 +10,13 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
# Due to missing/messed up libs in the toolchain, readline needs copies of
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
# /lib/arm-linux-gnueabihf/ to the toolchain, e.g.
# $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
# $(SDK_DIR)/$(SDK_TARGET)/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
# and manually created links libtinfo.so.5 and libreadline.so.
# For gcc-linaro-arm-linux-gnueabihf-raspbian, an existing incompatible
# libtinfo.so.5 is in the way. Remove it.
# (Built with glibc 2.16 like installed on Raspbian 9 but toolchain uses glibc 2.13.)
# Also copy /usr/include/readline/ directory from some readline 6 installation
# to $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/usr/include/
# to $(SDK_DIR)/$(SDK_TARGET)/arm-linux-gnueabihf/libc/usr/include/
ARCH_CLASS = arm
@@ -25,10 +25,10 @@ SDK_DIR = /opt/raspberrypi/arm-bcm2708
# Available SDK_TARGETs:
# gcc 4.8.3 for 32 bit hosts with GLIBC 2.3 or higher
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
# gcc 4.8.3 for 64 bit hosts with GLIBC 2.14 or higher
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
# gcc 4.7.1 for 64 bit hosts with GLIBC 2.8 or higher
# SDK_TARGET = arm-linux-gnueabihf
@@ -37,5 +37,8 @@ SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
# SDK_TARGET = arm-bcm2708hardfp-linux-gnueabi
# SDK_TARGET = arm-bcm2708-linux-gnueabi
# gcc 4.9.3 for 64 bit hosts
# arm-rpi-4.9.3-linux-gnueabihf
GNU_DIR = $(SDK_DIR)/$(SDK_TARGET)
GNU_TARGET = $(if $(filter arm-bcm2708%,SDK_TARGET),$(SDK_TARGET),arm-linux-gnueabihf)

View File

@@ -2,5 +2,9 @@ include $(CONFIG)/os/CONFIG.windows-x64.windows-x64
VALID_BUILDS = Ioc Command
PATH := /opt/wine-msvc-2017/bin/x64:$(PATH)
MSVC_VERSION ?= 2019
PATH := /opt/gfa-wine/bin:/opt/wine-msvc-$(MSVC_VERSION)/bin/x64:$(PATH)
export WINEPREFIX = $(HOME)/.wine-$(EPICS_HOST_ARCH)
export WINEDEBUG=fixme-all
export WINEDLLOVERRIDES="mscoree,mshtml="
export WINE = wine64

View File

@@ -1 +1,3 @@
# MSVC_VERSION 2019 in wine 4 for on RHEL7 would require winetricks
MSVC_VERSION = 2017
include $(CONFIG)/os/CONFIG.Linux.windows-x64

View File

@@ -12,7 +12,10 @@ include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
SYSROOT = /opt/RHEL7
# "Cross" TOOLSET progs need to find their libraries
LD_LIBRARY_PATH = $(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB)
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB)
# The linker has problems to find indirectly referenced libraries
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
# These programs have library problems when using them
# from SYSROOT but without TOOLSET.

View File

@@ -1 +0,0 @@
GNU_BIN = /opt/RHEL7/bin

View File

@@ -0,0 +1,3 @@
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
#Include definitions common to linux hosts
include $(CONFIG)/os/CONFIG.linux-x86_64.Common

View File

@@ -0,0 +1,18 @@
# Include common linux definitions
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
# "Cross compile" for RHEL7-x86_64
# Expects RHEL7 RPMs c++ and readline-devel installed
# in $(SYSROOT)
# This can be installed on RHEL7 with:
# yum install --installroot=$(SYSROOT) <packages>
# (Assuming $(SYSROOT) is on a shared network volume.)
# Optionally use a newer TOOLSET (installed on $(SYSROOT)).
SYSROOT = /opt/RHEL7
# "Cross" TOOLSET progs need to find their libraries
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(TOOLSET_DIR:%=$(SYSROOT)%/usr/$$LIB:)/usr/$$LIB:$(SYSROOT)/usr/$$LIB
# The linker has problems to find indirectly referenced libraries
PROD_LDLIBS += $(LDLIBS)

View File

@@ -0,0 +1,22 @@
# Include common linux definitions
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
# "Cross compile" for RHEL8-x86_64
# Expects RHEL8 RPMs gcc-toolset-12-gcc-c++ and readline-devel
# to be installed in $(SYSROOT)
# These can be installed on RHEL8 with:
# yum install --installroot=$(SYSROOT) <packages>
# (Assuming $(SYSROOT) is on a shared network volume.)
SYSROOT = /opt/RHEL8
# "Cross" TOOLSET progs need to find their libraries.
# But linker gets confused with LD_LIBRARY_PATH.
# Thus only wrap the compiler.
WRAPPER = -wrapper env,LD_LIBRARY_PATH=$(TOOLSET_DIR:%=$(SYSROOT)%/usr/lib64:)/usr/lib64:$(SYSROOT)/usr/lib64
TARGET_CPPFLAGS += $(WRAPPER)
# These programs as cross tools would also need LD_LIBRARY_PATH.
# But but our host versions work just fine.
AR = ar -rc
RANLIB = ranlib

View File

@@ -0,0 +1,2 @@
# Include common linux definitions
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86

View File

@@ -0,0 +1 @@
include $(CONFIG)/os/CONFIG.Linux.windows-x64

View File

@@ -16,7 +16,7 @@ OPT_WHOLE_PROGRAM = YES
WINLINK = link
RCCMD = rc -l 0x409 $(INCLUDES) -fo $@ $<
RCCMD = rc -nologo -l 0x409 $(INCLUDES) -fo $@ $<
ARCMD = lib -nologo -verbose -out:$@ $(LIB_OPT_LDFLAGS) $(LIBRARY_LD_OBJS)

View File

@@ -1,2 +0,0 @@
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)

View File

@@ -87,11 +87,14 @@ CODE_CXXFLAGS =
#WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
#WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION)
WIND_BASE = /afs/psi.ch/project/vxworks/VxWorks$(VXWORKS_VERSION)
WIND_BASE = /opt/VxWorks/VxWorks$(VXWORKS_VERSION)
#--------------------------------------------------
# Modules we cannot build with old compiler
# For the license counter
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
PV_MODULES = pv% normativeTypes
SKIP_BUILDS_5 = $(PV_MODULES)
SKIP_BUILDS_OLD = $(PV_MODULES)

View File

@@ -3,8 +3,3 @@ include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
# Improved error checking with clang
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64-clang
CROSS_COMPILER_RUNTEST_ARCHS += RHEL7-x86_64-clang
# NI Linux Real-Time 7.x
# requires RPM gcc-c++-arm-linux-gnu
# Not available on RHEL8
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a

View File

@@ -5,7 +5,3 @@ CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64-clang
# Build for old RHEL7 64 bit
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64
# NI Linux Real-Time 7.x
# requires RPM gcc-c++-arm-linux-gnu
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a

View File

@@ -0,0 +1,10 @@
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
# Improved error checking with clang
CROSS_COMPILER_TARGET_ARCHS += RHEL9-x86_64-clang
# Build for old RHEL8 64 bit
CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64
# Build for old RHEL7 64 bit
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64

View File

@@ -0,0 +1,5 @@
# Make sure hosts tools find their libraries during build
# even if FINAL_LOCATION differs from INSTALL_LOCATION
ifneq ($(FINAL_LOCATION:$(INSTALL_LOCATION)=),)
export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH:%=%:)$(INSTALL_HOST_LIB)
endif

View File

@@ -11,10 +11,6 @@ INSTALL_LOCATION=/usr/local/epics/base-$(EPICS_VERSION).$(EPICS_REVISION).$(EPIC
GNU_HOST_ARCH=i686
GNU_HOST_OS=linux
# set LD_LIBRARY_PATH may cause problems for eldk53-ppc4xxFP
# not exported LD_LIBRARY_PATH causes problem for RHEL7 cross compilation
export LD_LIBRARY_PATH=
# vxWorks for MVxxxx boards
#CROSS_COMPILER_TARGET_ARCHS += T2-ppc604
#CROSS_COMPILER_TARGET_ARCHS += V67-ppc604
@@ -38,7 +34,7 @@ CROSS_COMPILER_TARGET_ARCHS += eldk52-e500v2
# DeltaTau PowerPMAC
CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
#CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
# Test other vxWorks versions
#CROSS_COMPILER_TARGET_ARCHS += V66-ppc603
@@ -48,9 +44,6 @@ CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
# (No PVA because of old compiler)
#CROSS_COMPILER_TARGET_ARCHS += V62-ppc604
# Raspberry Pi
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
# RTEMS (Can only have 1 RTEMS major version in 1 EPICS installation
# because they overwrite their header files.)
#CROSS_COMPILER_TARGET_ARCHS += RTEMS49-pc386

View File

@@ -4,5 +4,5 @@
#-------------------------------------------------------
# Needed by gcc
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH):$(RTEMS_BASE)/lib
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH:%=%:)$(RTEMS_BASE)/lib

View File

@@ -25,4 +25,10 @@ CROSS_COMPILER_TARGET_ARCHS += yocto40-aarch64
CROSS_COMPILER_TARGET_ARCHS += deb10-x86_64
# Newer DeltaTau PowerPMAC
#CROSS_COMPILER_TARGET_ARCHS += gcc8-ppc4xxFP
CROSS_COMPILER_TARGET_ARCHS += gcc8-ppc4xxFP
# Raspberry Pi
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
# NI Linux Real-Time 7.x
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a

View File

@@ -20,7 +20,68 @@ should also be read to understand what has changed since earlier releases:
**This version of EPICS has not been released yet.**
## Changes made on the 7.0 branch since 7.0.7
## Changes made on the 7.0 branch since 7.0.8
-----
## EPICS Release 7.0.8
### bi "Raw Soft Channel" use MASK
If MASK is non-zero, The raw device support will now apply MASK to the
value read into RVAL.
eg. allows extraction of a bit from an input integer.
```
record(longin, "integer") {
field(VAL, "0xff")
}
record(bi, "bit1") {
field(DESC, "extract bit 1")
field(DTYP, "Raw Soft Channel")
field(INP , "integer")
field(MASK, "0x2")
field(ZNAM, "Clear")
field(ONAM, "Set")
}
```
### ANSI escapes in stderr
ANSI escape charactor sequences may now be printed to the stderr stream.
These escapes will appear in logs captured from that stream.
Tools which parse and/or render these logs may need to be adjusted to
either strip out the escapes, or to translate them into markup.
(see [ansi2html](https://pypi.org/project/ansi2html/) for example)
### Allow explicit append with `dbRecordsOnceOnly!=0`
Previously setting `dbRecordsOnceOnly!=0` prevented any further changes to a record via a .db file. eg.
```
record(ai, "myrec") {}
```
`dbRecordsOnceOnly!=0` previously disallowed appending fields with either form:
```
record("*", "myrec") {} # error
record(ai, "myrec") {} # error
```
Beginning with this release, `dbRecordsOnceOnly!=0` allows appending when explicitly intended (when record type is `"*"`).
```
record("*", "myrec") {} # allowed
record(ai, "myrec") {} # error
```
### PROC field changed to ASL0
The PROC field has been changed from access security level ASL1 to ASL0.
This allows users to trigger processing a record without having the rights
to reconfigure the records.
### bi "Raw Soft Channel" use MASK

View File

@@ -48,14 +48,14 @@ everything that has to be done since it's so easy to miss steps.</p>
<p>The following roles are used below:</p>
<dl>
<dt><strong>Release Manager</strong> ()</dt>
<dt><strong>Release Manager</strong></dt>
<dd>Responsible for managing and tagging the release</dd>
<dt><strong>Platform Developers</strong> (informal)</dt>
<dd>Responsible for individual operating system platforms</dd>
<dt><strong>Core Developers</strong></dt>
<dd>Responsible for maintaining the EPICS software</dd>
<dt><strong>Application Developers</strong></dt>
<dd>Responsible for support modules that depend on EPICS Base.</dd>
<dt><strong>APS Website Editor</strong> (Andrew Johnson)</dt>
<dd>Responsible for the APS EPICS website</dd>
<dt><strong>Website Editors</strong></dt>
<dd>Responsible for the EPICS websites</dd>
</dl>
<form>
@@ -72,23 +72,22 @@ everything that has to be done since it's so easy to miss steps.</p>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Email all developers about the upcoming release and ask for a list
of remaining tasks that must be finished.</td>
<td>Notify core developers about the upcoming release and ask about any
remaining tasks that must be finished.</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>All developers</td>
<td>Check the bug tracker for any outstanding items and handle
appropriately. All bugs that have been fixed should have been marked
as Fix Committed.</td>
appropriately.</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Set the Feature Freeze date, by which time all Git commits for
enhancements and new functionality should have been completed. After
this date, commits should only be made to fix problems that show up
during testing.</td>
<td>Set a Feature Freeze date, by which time all Git branches for
enhancements and new functionality should have been merged. After this
date, commits and merges should only be made to fix problems that show
up during testing.</td>
</tr>
<tr>
<td>&nbsp;</td>
@@ -97,6 +96,7 @@ everything that has to be done since it's so easy to miss steps.</p>
<td>Ensure that documentation will be updated before the release date:
<ul>
<li>Release Notes</li>
<li>Doxygen annotations</li>
<li>Other documents</li>
</ul>
</td>
@@ -104,13 +104,8 @@ everything that has to be done since it's so easy to miss steps.</p>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Review and update this checklist for the upcoming release.</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Create a release milestone on Launchpad. If a target release date is
known set "Date Targeted" to the expected release date.</td>
<td>Review and update this checklist for the upcoming release.
Update the release version number in the tags and messages below.</td>
</tr>
<tr>
<th colspan="3">Testing</th>
@@ -118,7 +113,7 @@ everything that has to be done since it's so easy to miss steps.</p>
<tr>
<td>&nbsp;</td>
<td>Platform Developers</td>
<td>Run the built-in test programs on all available host platforms using
<td>Run the internal test programs on all available host platforms using
<blockquote><tt>
make -s runtests
</tt></blockquote></td>
@@ -156,6 +151,7 @@ everything that has to be done since it's so easy to miss steps.</p>
<td>Check that documentation has been updated:
<ul>
<li>Release Notes</li>
<li>Doxygen annotations</li>
<li>Other documents</li>
</ul>
</td>
@@ -167,8 +163,8 @@ everything that has to be done since it's so easy to miss steps.</p>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Obtain a positive <q>Ok to release</q> from developers.</td>
<td>Core Developers</td>
<td>Reach a consensus that the software is ready to release.</td>
</tr>
<tr>
<th colspan="3">Creating the final release version</th>
@@ -191,27 +187,29 @@ everything that has to be done since it's so easy to miss steps.</p>
cd base-7.0/modules/&lt;module&gt;/documentation<br />
pandoc -f gfm -t html -o RELEASE_NOTES.html RELEASE_NOTES.md
</tt></blockquote>
Commit changes (don't push).</li>
Commit these changes (don't push).</li>
<li>Edit the module's release version file
<tt>configure/CONFIG_<i>module</i>_VERSION</tt> and its top-level
<tt>Doxyfile</tt>; set the <tt>DEVELOPMENT_FLAG</tt> value to 0 and
remove <tt>-dev</tt> from the <tt>PROJECT_NUMBER</tt> string.
Commit changes (don't push).</li>
<tt>configure/CONFIG_<i>module</i>_VERSION</tt> and the
<tt>Doxyfile</tt>s in the top-level and/or documentation
directories. In these, set <tt>DEVELOPMENT_FLAG</tt> to 0 and remove
<tt>-dev</tt> from the <tt>PROJECT_NUMBER</tt> string. Commit these
changes (don't push).</li>
<li>Tag the module:
<blockquote><tt>
git tag -m 'ANJ: Tag for EPICS 7.0.7' &lt;module-version&gt;
git tag -m 'ANJ: Tag for EPICS 7.0.8' &lt;module-version&gt;
</tt></blockquote>
</li>
<li>Update the git submodule on the Base-7.0 branch to the
newly-tagged version, but don't commit yet:
newly-tagged version, check the module's status matches the tag:
<blockquote><tt>
cd base-7.0/modules<br />
git add &lt;module&gt;<br />
git submodule status --cached
</tt></blockquote>
Don't commit the submodule updates yet.
</li>
<li>Edit the module's release version file
@@ -221,7 +219,8 @@ everything that has to be done since it's so easy to miss steps.</p>
<tt>PROJECT_NUMBER</tt> string, appending <tt>-dev</tt> to the new
module version number. Commit changes.</li>
<li>Push commits and the new tag to the submodule's GitHub repository:
<li>Push commits and the new tag to the submodule's GitHub repository
(assumed to be the <tt>upstream</tt> remote):
<blockquote><tt>
cd base-7.0/modules/&lt;module&gt;<br />
git push --follow-tags upstream master
@@ -270,10 +269,9 @@ everything that has to be done since it's so easy to miss steps.</p>
<td>Tag the epics-base module in Git:
<blockquote><tt>
cd base-7.0<br />
git tag -m 'ANJ: Tagged for release' R7.0.7
git tag -m 'ANJ: Tagged for release' R7.0.8
</tt></blockquote>
<p>Don't push anything to the Launchpad repository
yet.</p>
<p>Don't push to GitHub yet.</p>
</td>
</tr>
<tr>
@@ -305,12 +303,12 @@ everything that has to be done since it's so easy to miss steps.</p>
files and directories that are only used for continuous integration:
<blockquote><tt>
cd base-7.0<br />
./.tools/make-tar.sh R7.0.7 ../base-7.0.7.tar.gz base-7.0.7/
./.tools/make-tar.sh R7.0.8 ../base-7.0.8.tar.gz base-7.0.8/
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
cd ..<br />
gpg --armor --sign --detach-sig base-7.0.7.tar.gz
gpg --armor --sign --detach-sig base-7.0.8.tar.gz
</tt></blockquote>
</td>
</tr>
@@ -318,8 +316,9 @@ everything that has to be done since it's so easy to miss steps.</p>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Test the tar file by extracting its contents and building it on at
least one supported platform. When this succeeds the commits and new git
tag can be pushed to the Launchpad repository:
least one supported platform. If this succeeds the commits and new git
tag can be pushed to the GitHub repository's 7.0 branch (assumed to be
the <tt>upstream</tt> remote):
<blockquote><tt>
git push --follow-tags upstream 7.0
</tt></blockquote>
@@ -367,7 +366,7 @@ everything that has to be done since it's so easy to miss steps.</p>
</tr>
<tr>
<th colspan="3">Publish to epics-controls</th>
<th colspan="3">Publish to epics-controls.org</th>
</tr>
<tr>
<td><input type="checkbox"></td>
@@ -375,7 +374,7 @@ everything that has to be done since it's so easy to miss steps.</p>
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
epics-controls web-server.
<blockquote><tt>
scp base-7.0.7.tar.gz base-7.0.7.tar.gz.asc epics-controls:download/base<br />
scp base-7.0.8.tar.gz base-7.0.8.tar.gz.asc epics-controls:download/base<br />
</tt></blockquote>
</td>
</tr>
@@ -392,22 +391,22 @@ everything that has to be done since it's so easy to miss steps.</p>
</tr>
<tr>
<th colspan="3">Publish to Launchpad</th>
<th colspan="3">Publish to GitHub</th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Go to the Launchpad milestone for this release. Click the Create
release button and add the release date. Put a URL for the release page
in the Release notes box, and click the Create release button. Upload
the tar file and its <tt>.asc</tt> signature file to the new Launchpad
release page.</td>
<td>Go to the GitHub
<a href="https://github.com/epics-base/epics-base/releases/new?tag=R7.0.8">
Create release from tag R7.0.8</a> page.
Upload the tar file and its <tt>.asc</tt> signature file to the new
GitHub release page.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Find all Launchpad bug reports with the status Fix Committed which
have been fixed in this release and mark them Fix Released.</td>
<td>We used to close out bug reports in Launchpad at release-time, this
would be the time to do that if we have an equivalent on GitHub.</td>
</tr>
<tr>

6
epics-base.sh Normal file
View File

@@ -0,0 +1,6 @@
_OLD_EXTGLOB=$(shopt -p extglob)
shopt -s extglob
test -n "$EPICS_HOST_ARCH" || export EPICS_HOST_ARCH=$(/bin/sed "s%cpe:/o:redhat:enterprise_linux:\([0-9]*\).*%RHEL\1-`/bin/uname -m`%" /etc/system-release-cpe)
PATH=${PATH//?(:)\/usr\/local\/epics\/base-+([0-9]).+([0-9]).+([0-9])\/bin\/$EPICS_HOST_ARCH}:$EPICS_BASE/bin/$EPICS_HOST_ARCH
eval $_OLD_EXTGLOB
unset _OLD_EXTGLOB

486
epics-base.spec Normal file
View File

@@ -0,0 +1,486 @@
# Always make sure EpicsVersion.Version-Release matches the git tag!
%define EpicsVersion 7.0.8
Name: epics-base-%{EpicsVersion}
Summary: EPICS Base %{EpicsVersion}
Version: 1
Release: 0%{?dist}
License: EPICS Open License
Group: Development/Languages
URL: https://git.psi.ch/epics_base/base-7.0
Obsoletes: caRepeater = 1
%define module_name %{name}
%define prog_folder /usr/local/epics/base-%{EpicsVersion}
%define debug_package %{nil}
%define _build_id_links none
# do not strip libraries
%global __strip /bin/true
%undefine __brp_strip
%undefine __brp_mangle_shebangs
%undefine __brp_ldconfig
%define _binaries_in_noarch_packages_terminate_build 0
%if %{defined rhel}
%global epics_host_arch RHEL%{rhel}-%{_host_cpu}
%endif
# else define epics_host_arch as suitable
%description
EPICS is a set of Open Source software tools, libraries and applications
developed collaboratively and used worldwide to create distributed soft
real-time control systems for scientific instruments such as a particle
accelerators, telescopes and other large scientific experiments.
This RPM is a binary-only package.
###########################################
%package host-devel
Requires: make >= 3.80
BuildRequires: make >= 3.80
BuildRequires: gfa-cross-compiler-links
%if %{?rhel} >= 9
BuildRequires: gfa-wine
%else
BuildRequires: wine
%endif
Summary: Minimal stuff needed to build EPICS host apps
Requires: %{name} = %{version}-%{release}
# This EPICS installation uses the toolset 12 compiler
%if 0%{?rhel} == 7
Requires: devtoolset-12-gcc-c++
BuildRequires: devtoolset-12-gcc-c++
%endif
%if 0%{?rhel} >= 8
Requires: gcc-toolset-12-gcc-c++
BuildRequires: gcc-toolset-12-gcc-c++
%endif
# The perl stuff we need
Requires: perl-interpreter >= 5.10.1
BuildRequires: perl-interpreter >= 5.10.1
%if 0%{?rhel} >= 7
Requires: perl-File-Path perl-Getopt-Long perl-Pod-Usage perl-Time-HiRes perl-Data-Dumper perl-Scalar-List-Utils
BuildRequires: perl-File-Path perl-Getopt-Long perl-Pod-Usage perl-Time-HiRes perl-Data-Dumper perl-Scalar-List-Utils
%endif
%if 0%{?rhel} >= 8
Requires: perl-Text-Tabs+Wrap
BuildRequires: perl-Text-Tabs+Wrap
%endif
%if 0%{?rhel} >= 9
Requires: perl-File-Find perl-File-Basename perl-File-Copy perl-FindBin perl-Getopt-Std perl-POSIX
BuildRequires: perl-File-Find perl-File-Basename perl-File-Copy perl-FindBin perl-Getopt-Std perl-POSIX
%endif
# Perl auto-detection is broken
# It does not find all EPICS internal packages
%global __requires_exclude_from ^%{prog_folder}/bin/.*\\.pl$
%description host-devel
Contains headers etc to build EPICS host applications.
###########################################
%package compat
Summary: EPICS base %{EpicsVersion} for other RHEL versions
Requires: %{name} = %{version}-%{release}
AutoReqProv: no
%description compat
Contains EPICS binaries that run on other RHEL versions.
###########################################
%package wine
Summary: EPICS base %{EpicsVersion} for wine
Requires: %{name} = %{version}-%{release}
%if %{?rhel} >= 9
Requires: gfa-wine
%else
Requires: wine
%endif
%description wine
Allows to run EPICS in wine.
###########################################
%package boot
Summary: EPICS base %{EpicsVersion} for boot servers
BuildArch: noarch
AutoReqProv: no
Prefix: /usr/local/epics
%description boot
Contains files needed on NFS server to boot EPICS targets from.
This package can be relocated.
###########################################
%package devel
Summary: EPICS base %{EpicsVersion} for development environments
Requires: %{name} = %{version}-%{release}
Requires: %{name}-host-devel = %{version}-%{release}
Requires: gfa-cross-compiler-links
BuildArch: noarch
AutoReqProv: no
%description devel
All what is needed to develop EPICS for different target architectures.
###########################################
%package devel-static
Summary: EPICS base %{EpicsVersion} for development environments including static libraries
Requires: %{name}-devel = %{version}-%{release}
BuildArch: noarch
AutoReqProv: no
%description devel-static
Contains the static libraries (*.a) for EPICS development systems.
Only needed to build statically linked applications.
###########################################
%package src
Summary: Sources code of EPICS base %{EpicsVersion}
BuildArch: noarch
AutoReqProv: no
Prefix: /usr/local/epics
%description src
The source code of EPICS base %{EpicsVersion}.
May help when debugging
###########################################
%package doc
Summary: EPICS base %{EpicsVersion} documentation
BuildArch: noarch
AutoReqProv: no
Prefix: /usr/local/epics
%description doc
The documentation of EPICS base %{EpicsVersion}.
###########################################
# Our sources are locally in this directory
# and here we also build
# RPMS will be stored here, too
%define _topdir %(pwd)
%define _sourcedir %{_topdir}
%define _builddir %{_topdir}
%prep
%{__rm} -rf %{buildroot}/usr/lib
%{__rm} -f modules/RELEASE.*.local
git submodule update --init --recursive modules
%{__mkdir_p} RPMS
%build
%if %{defined epics_host_arch}
export EPICS_HOST_ARCH=%{epics_host_arch}
%endif
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} FINAL_LOCATION=%{prog_folder}
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} copysrc
# remove files we do not need
shopt -s extglob
%{__rm} -f %{buildroot}%{prog_folder}/bin/{V,RTEMS}*/{*Harness,softIoc,softIocPVA}
%{__rm} -f %{buildroot}%{prog_folder}/bin/RTEMS*/TEMP.*
# fix permissions of caRepeater.service
%{__chmod} 644 %{buildroot}%{prog_folder}/bin/*/caRepeater.service
# install the profile script
/bin/sed 's!\$EPICS_BASE!%{prog_folder}!' epics-base.sh > %{buildroot}%{prog_folder}/bin/epics-base.sh
# copy over old libraries for compatibility
%if %{?rhel} > 7
%{__cp} /opt/RHEL7/lib64/libreadline.so.6 %{buildroot}%{prog_folder}/lib/RHEL7-x86_64
%endif
%if %{?rhel} > 8
%{__cp} /opt/RHEL7/lib64/libtinfo.so.5 %{buildroot}%{prog_folder}/lib/RHEL7-x86_64
%{__cp} /opt/RHEL8/lib64/libreadline.so.7 %{buildroot}%{prog_folder}/lib/RHEL8-x86_64
%endif
# Do not use install section because build already installed
# and install will delete our buildroot!
%clean
%{__make} INSTALL_LOCATION=%{buildroot}%{prog_folder} realclean
%{__rm} -f modules/RELEASE.*.local
%{__rm} -rf %{buildroot}
%{__cp} %{_rpmdir}/*/%{name}*%{version}-%{release}.*.rpm %{_sourcedir}
# Link caRepeater and profile script to highest installed EPICS version after install and uninstall
%post
shopt -s extglob
%{__rm} -f /etc/profile.d/epics-base.sh
%{__ln_s} "$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/epics-base.sh | /usr/bin/head -n1)" /etc/profile.d/
SYSTEMD_DIR=$(pkg-config systemd --variable=systemdsystemunitdir)
if [ -n "$SYSTEMD_DIR" ]
then
%{__rm} -f $SYSTEMD_DIR/caRepeater.service
LATEST_REPEATER=$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/%{epics_host_arch}/caRepeater.service | /usr/bin/head -n1)
%{__ln_s} $LATEST_REPEATER $SYSTEMD_DIR/
systemctl daemon-reload
systemctl reenable caRepeater.service
systemctl start caRepeater.service
fi
%postun
shopt -s extglob
%{__rm} -f /etc/profile.d/epics-base.sh
%{__ln_s} "$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/epics-base.sh 2>/dev/null | /usr/bin/head -n1)" /etc/profile.d/ 2>/dev/null
SYSTEMD_DIR=$(pkg-config systemd --variable=systemdsystemunitdir)
if [ -n "$SYSTEMD_DIR" ]
then
LATEST_REPEATER=$(/usr/bin/ls -dvr1 /usr/local/epics/base-+([0-9]).+([0-9]).+([0-9])/bin/%{epics_host_arch}/caRepeater.service 2>/dev/null | /usr/bin/head -n1)
if [ -z "$LATEST_REPEATER" ]
then
systemctl disable caRepeater.service
# Do not stop or restart caRepeater.service
# because EPICS clients cannot handle that.
# Next reboot will take care of this.
fi
%{__rm} -f $SYSTEMD_DIR/caRepeater.service
if [ -n "$LATEST_REPEATER" ]
then
%{__ln_s} $LATEST_REPEATER $SYSTEMD_DIR/ 2>/dev/null
systemctl reenable caRepeater.service
fi
systemctl daemon-reload
fi
%files
%defattr(-,root,root,-)
%dir %{prog_folder}
%dir %{prog_folder}/configure
%{prog_folder}/configure/CONFIG_BASE_VERSION
%dir %{prog_folder}/dbd
%{prog_folder}/dbd/softIoc*.dbd
%dir %{prog_folder}/bin
%dir %{prog_folder}/lib
%{prog_folder}/db
%{prog_folder}/bin/epics-base.sh
%{prog_folder}/lib/perl/EpicsHostArch.pl
%{prog_folder}/lib/perl/CA.pm
%dir %{prog_folder}/lib/perl
%dir %{prog_folder}/lib/perl/*
%dir %{prog_folder}/lib/perl/*/*-linux-thread-multi
%{prog_folder}/lib/perl/*/*-linux-thread-multi/libCap5.so
# Install host binaries but avoid installing *.pl scripts
# and other development tools
%dir %{prog_folder}/bin/%{epics_host_arch}*
%{prog_folder}/bin/%{epics_host_arch}*/[Scips]*[^.]??
%{prog_folder}/bin/%{epics_host_arch}*/p2p
%{prog_folder}/bin/%{epics_host_arch}*/msi
%dir %{prog_folder}/lib/%{epics_host_arch}*
%{prog_folder}/lib/%{epics_host_arch}*/*.so*
###########################################
%files compat
%if %{?rhel} > 7
%dir %{prog_folder}/bin/RHEL7*
%{prog_folder}/bin/RHEL7*/[Scips]*[^.]??
%{prog_folder}/bin/RHEL7*/p2p
%{prog_folder}/bin/RHEL7*/msi
%dir %{prog_folder}/lib/RHEL7*
%{prog_folder}/lib/RHEL7*/*.so*
%endif
%if %{?rhel} > 8
%dir %{prog_folder}/bin/RHEL8*
%{prog_folder}/bin/RHEL8*/[Scips]*[^.]??
%{prog_folder}/bin/RHEL8*/p2p
%{prog_folder}/bin/RHEL8*/msi
%dir %{prog_folder}/lib/RHEL8*
%{prog_folder}/lib/RHEL8*/*.so*
%endif
%if %{?rhel} > 9
%dir %{prog_folder}/bin/RHEL9*
%{prog_folder}/bin/RHEL9*/[Scips]*[^.]??
%{prog_folder}/bin/RHEL9*/p2p
%{prog_folder}/bin/RHEL9*/msi
%dir %{prog_folder}/lib/RHEL9*
%{prog_folder}/lib/RHEL9*/*.so*
%endif
###########################################
%files wine
%{prog_folder}/bin/win*
###########################################
%files boot
%defattr(-,root,root,-)
%dir %{prog_folder}
%dir %{prog_folder}/configure
%{prog_folder}/configure/CONFIG_BASE_VERSION
%dir %{prog_folder}/dbd
%{prog_folder}/dbd/softIoc*.dbd
%{prog_folder}/db
%dir %{prog_folder}/lib
# avoid pulling in pkgconfig and perl
%dir %{prog_folder}/lib/[a-z]*-*
%{prog_folder}/lib/[a-z]*-*/*.so*
%dir %{prog_folder}/bin
# avoid pulling in host files again
# but get all cross architectures (mostly lower case)
# including all Windows dlls (hence listed twice: here and in wine)
%dir %{prog_folder}/bin/[a-z]*
%{prog_folder}/bin/[a-z]*/[Scips]*[^.]??
%{prog_folder}/bin/[a-z]*/msi*
%{prog_folder}/bin/[a-z]*/acctst*
%{prog_folder}/bin/[a-z]*/*.dll
# vxWorks and RTEMS
%dir %{prog_folder}/bin/V*
%{prog_folder}/bin/V*/*.munch
%{prog_folder}/bin/V*/*.o
%dir %{prog_folder}/bin/RTEMS*
%{prog_folder}/bin/RTEMS*/*.boot
###########################################
%files host-devel
%defattr(-,root,root,-)
%dir %{prog_folder}/include
%{prog_folder}/include/*.h
%{prog_folder}/include/compiler
%dir %{prog_folder}/include/os
%{prog_folder}/include/os/Linux/
%{prog_folder}/include/os/WIN32/
%{prog_folder}/include/pv/
%{prog_folder}/include/pva/
%{prog_folder}/include/valgrind/
%{prog_folder}/include/flex.skel.static
%{prog_folder}/templates
%dir %{prog_folder}/cfg
%{prog_folder}/cfg/CONFIG*
%{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.%{epics_host_arch}*
%{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.win*
%dir %{prog_folder}/configure
%{prog_folder}/configure/RELEASE
%{prog_folder}/configure/CONFIG*
%{prog_folder}/configure/RULES*
%dir %{prog_folder}/configure/os
%{prog_folder}/configure/os/CONFIG.Common.UnixCommon
%{prog_folder}/configure/os/CONFIG.Common.linuxCommon
%{prog_folder}/configure/os/CONFIG.Common.linux-clang
%{prog_folder}/configure/os/CONFIG.Common.linux-%{_host_cpu}*
%{prog_folder}/configure/os/CONFIG.Common.%{epics_host_arch}*
%{prog_folder}/configure/os/CONFIG.UnixCommon.Common
%{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.Common
%{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.%{epics_host_arch}*
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.Common
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.linux-%{__isa_name}*
%{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.win*
%{prog_folder}/configure/os/CONFIG.Linux.win*
%{prog_folder}/configure/os/CONFIG.win*.win*
%{prog_folder}/configure/os/CONFIG_SITE.Common.linuxCommon
%{prog_folder}/configure/os/CONFIG_SITE.Common.linux-%{__isa_name}*
%{prog_folder}/configure/os/CONFIG_SITE.%{epics_host_arch}*.Common
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.Common
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.UnixCommon
%{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.linux-%{__isa_name}*
%{prog_folder}/bin/%{epics_host_arch}*/[^Scips]*[^.]??
%{prog_folder}/bin/%{epics_host_arch}*/*.??
%dir %{prog_folder}/lib/pkgconfig
%{prog_folder}/lib/pkgconfig/epics-base.pc
%{prog_folder}/lib/pkgconfig/epics-base-%{epics_host_arch}*.pc
%{prog_folder}/lib/perl/EPICS
%{prog_folder}/lib/perl/DBD*
%{prog_folder}/dbd
###########################################
%files devel
%defattr(-,root,root,-)
%{prog_folder}/include/os/vxWorks/
%{prog_folder}/include/os/RTEMS/
%exclude %{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.%{epics_host_arch}*
%exclude %{prog_folder}/cfg/TOOLCHAIN.%{epics_host_arch}*.win*
%{prog_folder}/cfg/TOOLCHAIN.*
%exclude %{prog_folder}/configure/os/CONFIG.Common.%{epics_host_arch}*
%exclude %{prog_folder}/configure/os/CONFIG.Common.UnixCommon
%exclude %{prog_folder}/configure/os/CONFIG.Common.linuxCommon
%exclude %{prog_folder}/configure/os/CONFIG.Common.linux-clang
%exclude %{prog_folder}/configure/os/CONFIG.Common.linux-%{_host_cpu}*
%exclude %{prog_folder}/configure/os/CONFIG.UnixCommon.Common
%exclude %{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.Common
%exclude %{prog_folder}/configure/os/CONFIG.%{epics_host_arch}*.%{epics_host_arch}*
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.Common
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.linux-%{__isa_name}*
%exclude %{prog_folder}/configure/os/CONFIG.linux-%{__isa_name}*.win*
%exclude %{prog_folder}/configure/os/CONFIG.Linux.win*
%exclude %{prog_folder}/configure/os/CONFIG.win*.win*
%exclude %{prog_folder}/configure/os/CONFIG_SITE.Common.linuxCommon
%exclude %{prog_folder}/configure/os/CONFIG_SITE.Common.linux-%{__isa_name}*
%exclude %{prog_folder}/configure/os/CONFIG_SITE.%{epics_host_arch}*.Common
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.Common
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.UnixCommon
%exclude %{prog_folder}/configure/os/CONFIG_SITE.linux-%{__isa_name}*.linux-%{__isa_name}*
%{prog_folder}/configure/os/
%exclude %{prog_folder}/lib/pkgconfig/epics-base.pc
%exclude %{prog_folder}/lib/pkgconfig/epics-base-%{epics_host_arch}*.pc
%{prog_folder}/lib/pkgconfig/
%exclude %{prog_folder}/bin/%{epics_host_arch}*/[^Scips]*[^.]??
%exclude %{prog_folder}/bin/%{epics_host_arch}*/*.??
%exclude %{prog_folder}/bin/*/[^Scips]*[^.]??
%exclude %{prog_folder}/bin/*/*.??
# VxWorks and RTEMS need static libs
%{prog_folder}/lib/V*
%{prog_folder}/lib/RTEMS*
%{prog_folder}/lib/win*
###########################################
%files devel-static
%defattr(-,root,root,-)
# Install bulky static libs for Linux targets only on request
%dir %{prog_folder}/lib/RHEL*
%{prog_folder}/lib/RHEL*/*.a
%dir %{prog_folder}/lib/[a-z]*
%{prog_folder}/lib/[a-z]*/*.a
###########################################
%files src
%defattr(-,root,root,-)
%dir %{prog_folder}
%{prog_folder}/modules
###########################################
%files doc
%defattr(-,root,root,-)
%dir %{prog_folder}
%docdir %{prog_folder}/html
%{prog_folder}/html

View File

@@ -34,12 +34,6 @@ pvDatabase_DEPEND_DIRS = pvAccess
SUBMODULES += pva2pva
pva2pva_DEPEND_DIRS = pvAccess
SUBMODULES += example
example_DEPEND_DIRS = pva2pva pvaClient
SUBMODULES += pcas
pcas_DEPEND_DIRS = ca
# Allow sites to add extra submodules
-include Makefile.local

2
modules/Makefile.local Normal file
View File

@@ -0,0 +1,2 @@
SUBMODULES += pcas
pcas_DEPEND_DIRS = ca

View File

@@ -2575,7 +2575,8 @@ void monitorUpdateTest ( chid chan, unsigned interestLevel )
SEVCHK ( ca_get ( DBR_FLOAT, chan, &temp ), NULL );
SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL );
/* printf ( "flow control bypassed %u events\n", flowCtrlCount ); */
if (0)
printf ( "flow control bypassed %u events\n", flowCtrlCount );
showProgressEnd ( interestLevel );
}

View File

@@ -25,6 +25,7 @@
#include <stdexcept>
#include <string> // vxWorks 6.0 requires this include
#include "epicsStdio.h"
#include "dbDefs.h"
#include "epicsGuard.h"
#include "epicsVersion.h"
@@ -1008,7 +1009,7 @@ bool cac::defaultExcep (
char buf[512];
char hostName[64];
iiu.getHostName ( guard, hostName, sizeof ( hostName ) );
sprintf ( buf, "host=%s ctx=%.400s", hostName, pCtx );
epicsSnprintf( buf, sizeof(buf), "host=%s ctx=%.400s", hostName, pCtx );
this->notify.exception ( guard, status, buf, 0, 0u );
return true;
}
@@ -1312,7 +1313,7 @@ void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
const char * pChannelName, const char * pAcc, const char * pRej )
{
char buf[256];
sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s",
epicsSnprintf( buf, sizeof(buf), "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s",
pChannelName, pAcc, pRej );
{
callbackManager mgr ( this->notify, this->cbMutex );

View File

@@ -21,6 +21,9 @@
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include <vector>
#include <exception>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
@@ -28,6 +31,7 @@
#include "envDefs.h"
#include "epicsAssert.h"
#include "epicsString.h"
#include "epicsStdioRedirect.h"
#include "errlog.h"
#include "osiWireFormat.h"
@@ -35,39 +39,6 @@
#include "addrList.h"
#include "iocinf.h"
/*
* getToken()
*/
static char *getToken ( const char **ppString, char *pBuf, unsigned bufSIze )
{
bool tokenFound = false;
const char *pToken;
unsigned i;
pToken = *ppString;
while ( isspace (*pToken) && *pToken ){
pToken++;
}
for ( i=0u; i<bufSIze; i++ ) {
if ( isspace (pToken[i]) || pToken[i]=='\0' ) {
pBuf[i] = '\0';
*ppString = &pToken[i];
if ( i != 0 ) {
tokenFound = true;
}
break;
}
pBuf[i] = pToken[i];
}
if ( tokenFound ) {
pBuf[bufSIze-1] = '\0';
return pBuf;
}
return NULL;
}
/*
* addAddrToChannelAccessAddressList ()
*/
@@ -77,9 +48,7 @@ extern "C" int epicsStdCall addAddrToChannelAccessAddressList
{
osiSockAddrNode *pNewNode;
const char *pStr;
const char *pToken;
struct sockaddr_in addr;
char buf[256u]; /* large enough to hold an IP address or hostname */
int status, ret = -1;
pStr = envGetConfigParamPtr (pEnv);
@@ -87,31 +56,45 @@ extern "C" int epicsStdCall addAddrToChannelAccessAddressList
return ret;
}
while ( ( pToken = getToken (&pStr, buf, sizeof (buf) ) ) ) {
status = aToIPAddr ( pToken, port, &addr );
if (status<0) {
fprintf ( stderr, "%s: Parsing '%s'\n", __FILE__, pEnv->name);
fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken);
continue;
try {
std::vector<char> scratch(pStr, pStr+strlen(pStr)+1); // copy chars and trailing nil
char *save = NULL;
for(const char *pToken = epicsStrtok_r(&scratch[0], " \t\n\r", &save);
pToken;
pToken = epicsStrtok_r(NULL, " \t\n\r", &save))
{
if(!pToken[0]) {
continue;
}
status = aToIPAddr ( pToken, port, &addr );
if (status<0) {
fprintf ( stderr, "%s: Parsing '%s'\n", __FILE__, pEnv->name);
fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken);
continue;
}
if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) {
continue;
}
pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
if (pNewNode==NULL) {
fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n");
break;
}
pNewNode->addr.ia = addr;
/*
* LOCK applied externally
*/
ellAdd (pList, &pNewNode->node);
ret = 0; /* success if anything is added to the list */
}
if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) {
continue;
}
pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
if (pNewNode==NULL) {
fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n");
break;
}
pNewNode->addr.ia = addr;
/*
* LOCK applied externally
*/
ellAdd (pList, &pNewNode->node);
ret = 0; /* success if anything is added to the list */
} catch(std::exception&) { // only bad_alloc currently possible
ret = -1;
}
return ret;

View File

@@ -90,7 +90,7 @@ static const iocshFuncDef asprulesFuncDef = {
"asprules",1,asprulesArgs,
"List rules of an Access Security Group.\n"
"If no Group is specified then list the rules for all groups\n"
"Example: asprules mygroup"
"Example: asprules mygroup\n"
};
static void asprulesCallFunc(const iocshArgBuf *args)
{

View File

@@ -240,6 +240,7 @@ The B<SPVT> field is for internal use by the scanning system.
}
field(PROC,DBF_UCHAR) {
prompt("Force Processing")
asl(ASL0)
pp(TRUE)
interest(3)
}

View File

@@ -50,6 +50,7 @@ void testdbPrepare(void)
{
if(!testEvtLock)
testEvtLock = epicsMutexMustCreate();
initHookAnnounce(initHookAfterPrepareDatabase);
}
void testdbReadDatabase(const char* file,
@@ -94,6 +95,7 @@ void testIocShutdownOk(void)
void testdbCleanup(void)
{
initHookAnnounce(initHookBeforeCleanupDatabase);
dbFreeBase(pdbbase);
db_cleanup_events();
initHookFree();

View File

@@ -118,6 +118,10 @@ typedef struct dbRecordNode {
char *recordname;
ELLLIST infoList; /*LIST head of info nodes*/
int flags;
/** Parse order of this record()
* @since UNRELEASED
*/
unsigned order;
struct dbRecordNode *aliasedRecnode; /* NULL unless flags|DBRN_FLAGS_ISALIAS */
}dbRecordNode;
@@ -184,5 +188,9 @@ typedef struct dbBase {
struct gphPvt *pgpHash;
short ignoreMissingMenus;
short loadCdefs;
/** Total number of records.
* @since UNRELEASED
*/
unsigned no_records;
}dbBase;
#endif

View File

@@ -247,23 +247,23 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
}
my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
freeListInitPvt(&freeListPvt,sizeof(tempListNode),100);
if(substitutions) {
if(macCreateHandle(&macHandle,NULL)) {
epicsPrintf("macCreateHandle error\n");
status = -1;
goto cleanup;
}
macParseDefns(macHandle,(char *)substitutions,&macPairs);
if(macPairs ==NULL) {
macDeleteHandle(macHandle);
macHandle = NULL;
} else {
macInstallMacros(macHandle,macPairs);
free((void *)macPairs);
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
}
macSuppressWarning(macHandle,dbQuietMacroWarnings);
if (substitutions == NULL)
substitutions = "";
if(macCreateHandle(&macHandle,NULL)) {
epicsPrintf("macCreateHandle error\n");
status = -1;
goto cleanup;
}
macParseDefns(macHandle,substitutions,&macPairs);
if(macPairs == NULL) {
macDeleteHandle(macHandle);
macHandle = NULL;
} else {
macInstallMacros(macHandle,macPairs);
free(macPairs);
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
}
macSuppressWarning(macHandle,dbQuietMacroWarnings);
pinputFile = dbCalloc(1,sizeof(inputFile));
if (filename) {
pinputFile->filename = macEnvExpand(filename);

View File

@@ -193,7 +193,7 @@ struct lset;
struct link {
struct dbCommon *precord; /* Pointer to record owning link */
short type;
short flags;
unsigned short flags;
struct lset *lset;
char *text; /* Raw link text */
union value value;

View File

@@ -61,8 +61,8 @@ this chapter for information on soft device support.
If the record gets its values from hardware or uses the C<Raw Soft Channel>
device support, the device support routines place the value in the RVAL
field.
(Since UNRELEASED) If the MASK field is non-zero, then this MASK is applied to RVAL.
The value of RVAL is then converted using the process described in the
(Since 7.0.8) If the MASK field is non-zero, then this MASK is applied to RVAL.
The value from RVAL is then converted using the process described in the
next section.
=fields INP, DTYP, ZNAM, ONAM, RVAL, VAL

View File

@@ -158,7 +158,7 @@ CEIL: Ceiling (unary)
FLOOR: Floor (unary)
=item *
FMOD: Floating point modulo (binary) Added in UNRELEASED
FMOD: Floating point modulo (binary) Added in 7.0.8
=item *
LOG: Log base 10 (unary)

View File

@@ -184,7 +184,7 @@ CEIL: Ceiling (unary)
FLOOR: Floor (unary)
=item *
FMOD: Floating point modulo (binary) Added in UNRELEASED
FMOD: Floating point modulo (binary) Added in 7.0.8
=item *
LOG: Log base 10 (unary)

View File

@@ -85,7 +85,7 @@ for information on the format of hardware addresses and database links.
=head4 Menu longoutOOPT
The OOPT field was added in EPICS UNRELEASED.
The OOPT field was added in EPICS 7.0.8.
It determines the condition that causes the output link to be
written to. It's a menu field that has six choices:
@@ -119,7 +119,7 @@ VAL is non-zero and last value was zero.
=head4 Changes in OUT field when OOPT = On Change
The OOCH field was added in EPICS UNRELEASED.
The OOCH field was added in EPICS 7.0.8.
If OOCH is C<YES> (its default value) and the OOPT field is C<On Change>,
the record will write to the device support the first time the record gets

View File

@@ -20,10 +20,14 @@ use EPICS::Getopts;
use EPICS::Readfile;
use EPICS::macLib;
our ($opt_D, @opt_I, @opt_S, $opt_o);
our ($opt_D, $opt_A, @opt_I, @opt_S, $opt_o);
getopts('DI@S@o:') or
die "Usage: dbdExpand [-D] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ...";
getopts('DAI@S@o:') or
die "Usage: dbdExpand [-D] [-A] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ...";
if ($opt_A) {
$DBD::Parser::allowAutoDeclarations = 1;
}
my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32?
my $macros = EPICS::macLib->new(@opt_S);

View File

@@ -366,7 +366,7 @@ long epicsStdCall asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt,
{
ASGMEMBER *pasgmember = asMemberPvt;
ASGCLIENT *pasgclient;
int len, i;
size_t len, i;
long status;
if(!asActive) return(S_asLib_asNotActive);
@@ -394,7 +394,7 @@ long epicsStdCall asChangeClient(
{
ASGCLIENT *pasgclient = asClientPvt;
long status;
int len, i;
size_t len, i;
if(!asActive) return(S_asLib_asNotActive);
if(!pasgclient) return(S_asLib_badClient);

View File

@@ -222,7 +222,7 @@ extern "C" {
* - n parameter minimum value: min(a, b, ...)
* - Square root: sqr(a) or sqrt(a)
* - Floating point modulo: fmod(num, den)
* \since The fmod() function was added in UNRELEASED
* \since The fmod() function was added in 7.0.8
*
* -# ***Trigonometric Functions***
* Standard circular trigonometric functions, with angles expressed in radians:

View File

@@ -180,8 +180,8 @@ LIBCOM_API void errlogAddListener(errlogListener listener, void *pPrivate);
* \param listener Function pointer of type ::errlogListener
* \param pPrivate This will be passed as the first argument of listener()
*
* \since UNRELEASED Safe to call from a listener callback.
* \until UNRELEASED Self-removal from a listener callback caused corruption.
* \since 7.0.8 Safe to call from a listener callback.
* \until 7.0.8 Self-removal from a listener callback caused corruption.
*/
LIBCOM_API int errlogRemoveListeners(errlogListener listener,
void *pPrivate);

View File

@@ -19,7 +19,7 @@ parse_CPPFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE)
INC += flex.skel.static
# flex.c is included in parse.c
# flex.c, scan.c and yylex.c are #included by parse.c
e_flex_SRCS += ccl.c
e_flex_SRCS += dfa.c
e_flex_SRCS += ecs.c

View File

@@ -132,7 +132,6 @@ void cclnegate(int cclp)
void list_character_set(FILE *file, int cset[])
{
int i;
char *readable_form();
putc( '[', file );

View File

@@ -188,7 +188,6 @@ int main(int argc, char *argv[])
void flexend(int status)
{
int tblsiz;
char *flex_gettime();
if ( skelfile != NULL )
{
@@ -382,7 +381,7 @@ void flexend(int status)
void flexinit(int argc, char **argv)
{
int i, sawcmpflag;
char *arg, *flex_gettime(), *mktemp();
char *arg;
printstats = syntaxerror = trace = spprdflt = interactive = caseins = false;
backtrack_report = performance_report = ddebug = fulltbl = fullspd = false;

View File

@@ -567,8 +567,8 @@ extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
extern int num_backtracking, bol_needed;
void *allocate_array(int size, int element_size);
void *reallocate_array(void *array, int size, int element_size);
extern void *allocate_array(int size, int element_size);
extern void *reallocate_array(void *array, int size, int element_size);
#define allocate_integer_array(size) \
(int *) allocate_array( size, sizeof( int ) )
@@ -677,10 +677,20 @@ extern int all_upper (Char *);
/* bubble sort an integer array */
extern void bubble (int [], int);
/* replace upper-case letter to lower-case */
extern Char clower(int c);
/* returns copy of a string */
extern char *copy_string(char *str);
/* returns copy of a (potentially) unsigned string */
extern Char *copy_unsigned_string(Char *str);
/* shell sort a character array */
extern void cshell (Char [], int, int);
extern void dataend (void); /* finish up a block of data declarations */
/* finish up a block of data declarations */
extern void dataend (void);
/* report an error message and terminate */
extern void flexerror (char[]) NORETURN;
@@ -688,6 +698,9 @@ extern void flexerror (char[]) NORETURN;
/* report a fatal error message and terminate */
extern void flexfatal (char[]);
/* return current time */
extern char *flex_gettime();
/* report an error message formatted with one integer argument */
extern void lerrif (char[], int);
@@ -700,11 +713,18 @@ extern void line_directive_out (FILE*);
/* generate a data statment for a two-dimensional array */
extern void mk2data (int);
extern void mkdata (int); /* generate a data statement */
/* generate a data statement */
extern void mkdata (int);
/* return the integer represented by a string of digits */
extern int myctoi (Char []);
/* return character corresponding to escape sequence */
extern Char myesc(Char *array);
/* return the the human-readable form of a character */
extern char *readable_form(int c);
/* write out one section of the skeleton file */
extern void skelout (void);
@@ -784,8 +804,14 @@ extern void cclinstal (Char [], int);
/* lookup the number associated with character class */
extern int ccllookup (Char []);
extern void ndinstal (char[], Char[]); /* install a name definition */
extern void scinstal (char[], int); /* make a start condition */
/* install a name definition */
extern void ndinstal (char[], Char[]);
/* lookup a name definition */
extern Char *ndlookup(char *nd);
/* make a start condition */
extern void scinstal (char[], int);
/* lookup the number associated with a start condition */
extern int sclookup (char[]);

View File

@@ -217,7 +217,6 @@ void genecs(void)
int i, j;
static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n";
int numrows;
Char clower();
if ( numecs < csize )
printf( C_char_decl, "YY_CHAR", "yy_ec", csize );
@@ -237,8 +236,6 @@ void genecs(void)
if ( trace )
{
char *readable_form();
fputs( "\n\nEquivalence Classes:\n\n", stderr );
numrows = csize / 8;

View File

@@ -34,11 +34,18 @@
int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
Char clower();
static int madeany = false; /* whether we've made the '.' character class */
int previous_continued_action; /* whether the previous rule's action was '|' */
/* forward declarations */
void build_eof_action( void );
void synerr( char str[] );
void format_pinpoint_message( char msg[], char arg[] );
void pinpoint_message( char str[] );
void yyerror( char msg[] );
%}
%%
@@ -626,7 +633,7 @@ string : string CHAR
* conditions
*/
void build_eof_action()
void build_eof_action( void )
{
int i;
@@ -652,8 +659,7 @@ void build_eof_action()
/* synerr - report a syntax error */
void synerr( str )
char str[];
void synerr( char str[] )
{
syntaxerror = true;
@@ -665,8 +671,7 @@ char str[];
* pinpointing its location
*/
void format_pinpoint_message( msg, arg )
char msg[], arg[];
void format_pinpoint_message( char msg[], char arg[] )
{
char errmsg[MAXLINE];
@@ -678,8 +683,7 @@ char msg[], arg[];
/* pinpoint_message - write out a message, pinpointing its location */
void pinpoint_message( str )
char str[];
void pinpoint_message( char str[] )
{
fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str );
@@ -690,8 +694,7 @@ char str[];
* currently, messages are ignore
*/
void yyerror( msg )
char msg[];
void yyerror( char msg[] )
{
}

View File

@@ -953,6 +953,7 @@ void yy_load_buffer_state ( void );
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
void yy_delete_buffer ( YY_BUFFER_STATE b );
void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
void set_input_file( char *file );
#define yy_new_buffer yy_create_buffer
@@ -966,7 +967,7 @@ YY_DECL
static int bracelevel, didadef;
int i, indented_code = false, checking_used = false, new_xlation = false;
int doing_codeblock = false;
Char nmdef[MAXLINE], myesc();
Char nmdef[MAXLINE];
if ( yy_init )
@@ -1488,7 +1489,6 @@ case 65:
# line 333 "scan.l"
{
Char *nmdefptr;
Char *ndlookup();
(void) strcpy( nmstr, (char *) yytext );
nmstr[yyleng - 1] = '\0'; /* chop trailing brace */
@@ -2230,8 +2230,7 @@ int yywrap()
/* set_input_file - open the given file (if NULL, stdin) for scanning */
void set_input_file( file )
char *file;
void set_input_file( char *file )
{
if ( file )

View File

@@ -108,8 +108,6 @@ void cclinstal(Char *ccltxt, int cclnum)
/* we don't bother checking the return status because we are not called
* unless the symbol is new
*/
Char *copy_unsigned_string();
(void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum,
ccltab, CCL_HASH_SIZE );
}
@@ -191,9 +189,6 @@ int hashfunct(char *str, int hash_size)
void ndinstal(char *nd, Char *def)
{
char *copy_string();
Char *copy_unsigned_string();
if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0,
ndtbl, NAME_TABLE_HASH_SIZE ) )
synerr( "name defined twice" );
@@ -227,8 +222,6 @@ Char *ndlookup(char *nd)
void scinstal(char *str, int xcluflg)
{
char *copy_string();
/* bit of a hack. We know how the default start-condition is
* declared, and don't put out a define for it, because it
* would come out as "#define 0 1"

View File

@@ -63,7 +63,7 @@ GPHENTRY * epicsStdCall gphFindParse(gphPvt *pgphPvt, const char *name, size_t l
ELLLIST **paplist;
ELLLIST *gphlist;
GPHENTRY *pgphNode;
int hash;
unsigned hash;
if (pgphPvt == NULL) return NULL;
paplist = pgphPvt->paplist;
@@ -99,7 +99,7 @@ GPHENTRY * epicsStdCall gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
ELLLIST **paplist;
ELLLIST *plist;
GPHENTRY *pgphNode;
int hash;
unsigned hash;
if (pgphPvt == NULL) return NULL;
paplist = pgphPvt->paplist;
@@ -144,7 +144,7 @@ void epicsStdCall gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid)
ELLLIST **paplist;
ELLLIST *plist = NULL;
GPHENTRY *pgphNode;
int hash;
unsigned hash;
if (pgphPvt == NULL) return;
paplist = pgphPvt->paplist;

View File

@@ -139,6 +139,9 @@ const char *initHookName(int state)
"initHookBeforeFree",
"initHookAfterShutdown",
"initHookAfterPrepareDatabase",
"initHookBeforeCleanupDatabase",
"initHookAfterInterruptAccept",
"initHookAtEnd"
};

View File

@@ -71,6 +71,7 @@ extern "C" {
* if the IOC is later paused and restarted.
*/
typedef enum {
// iocInit() begins
initHookAtIocBuild = 0, /**< Start of iocBuild() / iocInit() */
initHookAtBeginning, /**< Database sanity checks passed */
@@ -110,7 +111,7 @@ typedef enum {
*/
initHookAfterCloseLinks,
/** \brief Scan tasks stopped.
* \since UNRELEASED Triggered during normal IOC shutdown
* \since 7.0.8 Triggered during normal IOC shutdown
* \since 7.0.3.1 Added, triggered only by unittest code.
*/
initHookAfterStopScan,
@@ -119,7 +120,7 @@ typedef enum {
*/
initHookAfterStopCallback,
/** \brief CA links stopped.
* \since UNRELEASED Triggered during normal IOC shutdown
* \since 7.0.8 Triggered during normal IOC shutdown
* \since 7.0.3.1 Added, triggered only by unittest code.
*/
initHookAfterStopLinks,
@@ -133,6 +134,17 @@ typedef enum {
initHookAfterShutdown,
// iocShutdown() ends
/** \brief Called during testdbPrepare()
* Use this hook to repeat actions each time an empty test database is initialized.
* \since 7.0.8 Added, triggered only by unittest code.
*/
initHookAfterPrepareDatabase,
/** \brief Called during testdbCleanup()
* Use this hook to perform cleanup each time before a test database is free()'d.
* \since 7.0.8 Added, triggered only by unittest code.
*/
initHookBeforeCleanupDatabase,
/* Deprecated states: */
/** Only announced once. Deprecated in favor of initHookAfterDatabaseRunning */
initHookAfterInterruptAccept,

View File

@@ -66,12 +66,16 @@ typedef enum {
iocshArgPdbbase,
iocshArgArgv,
iocshArgPersistentString,
/** Equivalent to iocshArgString with a hint for tab completion as a record name.
* @since UNRELEASED
/**
* Equivalent to iocshArgString with a hint for tab completion that the
* argument is a record name.
* @since 7.0.8
*/
iocshArgStringRecord,
/** Equivalent to iocshArgString with a hint for tab completion as a file system path.
* @since UNRELEASED
/**
* Equivalent to iocshArgString with a hint for tab completion that the
* argument is a file system path.
* @since 7.0.8
*/
iocshArgStringPath,
}iocshArgType;

View File

@@ -193,7 +193,7 @@ static const iocshFuncDef epicsEnvShowFuncDef = {"epicsEnvShow",1,epicsEnvShowAr
" (default) - show all environment variables\n"
" name - show value of specific environment variable\n"
"Example: epicsEnvShow\n"
"Example: epicsEnvShow PATH"};
"Example: epicsEnvShow PATH\n"};
static void epicsEnvShowCallFunc(const iocshArgBuf *args)
{
epicsEnvShow (args[0].sval);

View File

@@ -43,7 +43,7 @@ static char ioc_log_file_command[256];
struct iocLogClient {
int insock;
SOCKET insock;
struct ioc_log_server *pserver;
size_t nChar;
char recvbuf[1024];

View File

@@ -15,40 +15,25 @@
#include <stdlib.h>
#include <stddef.h>
/* Up to now epicsShareThings have been declared as imports
* (Appropriate for other stuff)
* After setting the following they will be declared as exports
* (Appropriate for what we implement)
*/
#include <epicsAssert.h>
#include "adjustment.h"
LIBCOM_API size_t adjustToWorstCaseAlignment(size_t size)
size_t adjustToWorstCaseAlignment(size_t size)
{
int align_size, adjust;
struct test_long_word { char c; long lw; };
struct test_double { char c; double d; };
struct test_ptr { char c; void *p; };
int test_long_size = sizeof(struct test_long_word) - sizeof(long);
int test_double_size = sizeof(struct test_double) - sizeof(double);
int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *);
size_t adjusted_size = size;
union aline {
/* largest primative types (so far...) */
double dval;
size_t uval;
char *ptr;
};
/*
* Use Jeff's alignment tests to determine worst case of long,
* double or pointer alignment requirements.
*/
align_size = test_long_size > test_ptr_size ?
test_long_size : test_ptr_size;
/* assert that alignment size is a power of 2 */
STATIC_ASSERT((sizeof(union aline) & (sizeof(union aline)-1))==0);
align_size = align_size > test_double_size ?
align_size : test_double_size;
/* round up to aligment size */
size--;
size |= sizeof(union aline)-1;
size++;
/*
* Increase the size to fit worst case alignment if not already
* properly aligned.
*/
adjust = align_size - size%align_size;
if (adjust != align_size) adjusted_size += adjust;
return (adjusted_size);
return size;
}

View File

@@ -35,8 +35,6 @@
#include "cantProceed.h"
#include "epicsExit.h"
void epicsMutexCleanup(void);
typedef struct exitNode {
ELLNODE node;
epicsExitFunc func;
@@ -115,8 +113,6 @@ LIBCOM_API void epicsExitCallAtExits(void)
epicsExitCallAtExitsPvt ( pep );
destroyExitPvt ( pep );
}
/* Handle specially to avoid circular reference */
epicsMutexCleanup();
}
LIBCOM_API void epicsExitCallAtThreadExits(void)

View File

@@ -17,6 +17,7 @@
#include <climits>
#include <stdexcept>
#include <cstdio>
#include <vector>
//#define EPICS_FREELIST_DEBUG
#define EPICS_PRIVATE_API
@@ -82,7 +83,6 @@ struct ipAddrToAsciiGlobal : public epicsThreadRunable {
virtual void run ();
char nameTmp [1024];
tsFreeList
< ipAddrToAsciiTransactionPrivate, 0x80 >
transactionFreeList;
@@ -297,6 +297,8 @@ ipAddrToAsciiTransaction & ipAddrToAsciiEnginePrivate::createTransaction ()
void ipAddrToAsciiGlobal::run ()
{
std::vector<char> nameTmp(1024);
epicsGuard < epicsMutex > guard ( this->mutex );
while ( ! this->exitFlag ) {
{
@@ -313,14 +315,13 @@ void ipAddrToAsciiGlobal::run ()
if ( this->exitFlag )
{
sockAddrToDottedIP ( & addr.sa, this->nameTmp,
sizeof ( this->nameTmp ) );
sockAddrToDottedIP ( & addr.sa, &nameTmp[0], nameTmp.size() );
}
else {
epicsGuardRelease < epicsMutex > unguard ( guard );
// depending on DNS configuration, this could take a very long time
// so we release the lock
sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) );
sockAddrToA ( &addr.sa, &nameTmp[0], nameTmp.size() );
}
// the ipAddrToAsciiTransactionPrivate destructor is allowed to
@@ -339,7 +340,7 @@ void ipAddrToAsciiGlobal::run ()
{
epicsGuardRelease < epicsMutex > unguard ( guard );
// don't call callback with lock applied
pCur->pCB->transactionComplete ( this->nameTmp );
pCur->pCB->transactionComplete ( &nameTmp[0] );
}
this->callbackInProgress = false;

View File

@@ -26,30 +26,23 @@
#include <stdio.h>
#include <string.h>
#include "dbDefs.h"
#include "epicsStdio.h"
#include "epicsThread.h"
#include "valgrind/valgrind.h"
#include "ellLib.h"
#include "errlog.h"
#include "epicsMutex.h"
#include "epicsMutexImpl.h"
#include "epicsThread.h"
#include "cantProceed.h"
static epicsThreadOnceId epicsMutexOsiOnce = EPICS_THREAD_ONCE_INIT;
static ELLLIST mutexList;
static ELLLIST freeList;
struct epicsMutexParm {
ELLNODE node;
epicsMutexOSD * id;
# ifdef LOG_LAST_OWNER
epicsThreadId lastOwner;
# endif
const char *pFileName;
int lineno;
};
static epicsMutexOSD * epicsMutexGlobalLock;
static ELLLIST mutexList = ELLLIST_INIT;
/* Specially initialized to bootstrap initialization.
* When supported (posix and !rtems) use statically initiallized mutex.
* Otherwise, initialize via epicsMutexOsdSetup().
*/
struct epicsMutexParm epicsMutexGlobalLock = {ELLNODE_INIT, __FILE__, __LINE__};
// vxWorks 5.4 gcc fails during compile when I use std::exception
using namespace std;
@@ -76,176 +69,82 @@ const char * epicsMutex::invalidMutex::what () const throw ()
return "epicsMutex::invalidMutex()";
}
static void epicsMutexOsiInit(void *) {
ellInit(&mutexList);
ellInit(&freeList);
VALGRIND_CREATE_MEMPOOL(&freeList, 0, 0);
epicsMutexGlobalLock = epicsMutexOsdCreate();
}
epicsMutexId epicsStdCall epicsMutexOsiCreate(
const char *pFileName,int lineno)
{
epicsMutexOSD * id;
epicsMutexOsdSetup();
epicsThreadOnce(&epicsMutexOsiOnce, epicsMutexOsiInit, NULL);
epicsMutexId ret = (epicsMutexId)calloc(1, sizeof(*ret));
if(ret) {
ret->pFileName = pFileName;
ret->lineno = lineno;
if(!epicsMutexOsdPrepare(ret)) {
epicsMutexMustLock(&epicsMutexGlobalLock);
ellAdd(&mutexList, &ret->node);
(void)epicsMutexUnlock(&epicsMutexGlobalLock);
} else {
free(ret);
ret = NULL;
}
id = epicsMutexOsdCreate();
if(!id) {
return 0;
}
epicsMutexLockStatus lockStat =
epicsMutexOsdLock(epicsMutexGlobalLock);
assert ( lockStat == epicsMutexLockOK );
epicsMutexParm *pmutexNode =
reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) );
if(pmutexNode) {
ellDelete(&freeList,&pmutexNode->node);
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
} else {
pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) );
}
VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm));
pmutexNode->id = id;
# ifdef LOG_LAST_OWNER
pmutexNode->lastOwner = 0;
# endif
pmutexNode->pFileName = pFileName;
pmutexNode->lineno = lineno;
ellAdd(&mutexList,&pmutexNode->node);
epicsMutexOsdUnlock(epicsMutexGlobalLock);
return(pmutexNode);
return ret;
}
epicsMutexId epicsStdCall epicsMutexOsiMustCreate(
const char *pFileName,int lineno)
{
epicsMutexId id = epicsMutexOsiCreate(pFileName,lineno);
assert(id);
return(id );
if(!id) {
cantProceed("epicsMutexOsiMustCreate() fails at %s:%d\n",
pFileName, lineno);
}
return id;
}
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
{
epicsMutexLockStatus lockStat =
epicsMutexOsdLock(epicsMutexGlobalLock);
assert ( lockStat == epicsMutexLockOK );
ellDelete(&mutexList,&pmutexNode->node);
epicsMutexOsdDestroy(pmutexNode->id);
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node));
ellAdd(&freeList,&pmutexNode->node);
epicsMutexOsdUnlock(epicsMutexGlobalLock);
}
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
{
epicsMutexOsdUnlock(pmutexNode->id);
}
epicsMutexLockStatus epicsStdCall epicsMutexLock(
epicsMutexId pmutexNode)
{
epicsMutexLockStatus status =
epicsMutexOsdLock(pmutexNode->id);
# ifdef LOG_LAST_OWNER
if ( status == epicsMutexLockOK ) {
pmutexNode->lastOwner = epicsThreadGetIdSelf();
}
# endif
return status;
}
epicsMutexLockStatus epicsStdCall epicsMutexTryLock(
epicsMutexId pmutexNode)
{
epicsMutexLockStatus status =
epicsMutexOsdTryLock(pmutexNode->id);
# ifdef LOG_LAST_OWNER
if ( status == epicsMutexLockOK ) {
pmutexNode->lastOwner = epicsThreadGetIdSelf();
}
# endif
return status;
}
/* Empty the freeList.
* Called from epicsExit.c, but not via epicsAtExit()
* to avoid the possibility of a circular reference.
*/
extern "C"
void epicsMutexCleanup(void)
{
ELLNODE *cur;
epicsMutexLockStatus lockStat =
epicsMutexOsdLock(epicsMutexGlobalLock);
assert ( lockStat == epicsMutexLockOK );
while((cur=ellGet(&freeList))!=NULL) {
VALGRIND_MEMPOOL_FREE(&freeList, cur);
free(cur);
if(pmutexNode) {
epicsMutexMustLock(&epicsMutexGlobalLock);
ellDelete(&mutexList, &pmutexNode->node);
(void)epicsMutexUnlock(&epicsMutexGlobalLock);
epicsMutexOsdCleanup(pmutexNode);
free(pmutexNode);
}
epicsMutexOsdUnlock(epicsMutexGlobalLock);
}
void epicsStdCall epicsMutexShow(
epicsMutexId pmutexNode, unsigned int level)
{
# ifdef LOG_LAST_OWNER
char threadName [255];
if ( pmutexNode->lastOwner ) {
# error currently not safe to fetch name for stale thread
epicsThreadGetName ( pmutexNode->lastOwner,
threadName, sizeof ( threadName ) );
}
else {
strcpy ( threadName, "<not used>" );
}
printf("epicsMutexId %p last owner \"%s\" source %s line %d\n",
(void *)pmutexNode, threadName,
pmutexNode->pFileName, pmutexNode->lineno);
# else
printf("epicsMutexId %p source %s line %d\n",
(void *)pmutexNode, pmutexNode->pFileName,
pmutexNode->lineno);
# endif
printf("epicsMutexId %p source %s line %d\n",
(void *)pmutexNode, pmutexNode->pFileName,
pmutexNode->lineno);
if ( level > 0 ) {
epicsMutexOsdShow(pmutexNode->id,level-1);
epicsMutexOsdShow(pmutexNode,level-1);
}
}
void epicsStdCall epicsMutexShowAll(int onlyLocked,unsigned int level)
{
epicsMutexParm *pmutexNode;
epicsMutexOsdSetup();
if (epicsMutexOsiOnce == EPICS_THREAD_ONCE_INIT)
return;
printf("ellCount(&mutexList) %d ellCount(&freeList) %d\n",
ellCount(&mutexList),ellCount(&freeList));
printf("ellCount(&mutexList) %d\n", ellCount(&mutexList));
epicsMutexOsdShowAll();
epicsMutexLockStatus lockStat =
epicsMutexOsdLock(epicsMutexGlobalLock);
assert ( lockStat == epicsMutexLockOK );
pmutexNode = reinterpret_cast < epicsMutexParm * > ( ellFirst(&mutexList) );
while(pmutexNode) {
epicsMutexMustLock(&epicsMutexGlobalLock);
for(ELLNODE *cur =ellFirst(&mutexList); cur; cur = ellNext(cur)) {
epicsMutexParm *lock = CONTAINER(cur, epicsMutexParm, node);
if(onlyLocked) {
epicsMutexLockStatus status;
status = epicsMutexOsdTryLock(pmutexNode->id);
if(status==epicsMutexLockOK) {
epicsMutexOsdUnlock(pmutexNode->id);
pmutexNode =
reinterpret_cast < epicsMutexParm * >
( ellNext(&pmutexNode->node) );
continue;
// cycle through to test state
if(epicsMutexTryLock(lock)==epicsMutexLockOK) {
epicsMutexUnlock(lock);
continue; // was not locked, skip
}
}
epicsMutexShow(pmutexNode, level);
pmutexNode =
reinterpret_cast < epicsMutexParm * > ( ellNext(&pmutexNode->node) );
epicsMutexShow(lock, level);
}
epicsMutexOsdUnlock(epicsMutexGlobalLock);
epicsMutexUnlock(&epicsMutexGlobalLock);
}
#if !defined(__GNUC__) || __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<8)

View File

@@ -247,21 +247,6 @@ LIBCOM_API void epicsStdCall epicsMutexShow(
LIBCOM_API void epicsStdCall epicsMutexShowAll(
int onlyLocked,unsigned int level);
/**@privatesection
* The following are interfaces to the OS dependent
* implementation and should NOT be called directly by
* user code.
*/
struct epicsMutexOSD * epicsMutexOsdCreate(void);
void epicsMutexOsdDestroy(struct epicsMutexOSD *);
void epicsMutexOsdUnlock(struct epicsMutexOSD *);
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *);
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *);
void epicsMutexOsdShow(struct epicsMutexOSD *,unsigned int level);
#ifdef EPICS_PRIVATE_API
void epicsMutexOsdShowAll(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,66 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* Copyright (c) 2023 Michael Davidsaver
* SPDX-License-Identifier: EPICS
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* Only include from osdMutex.c */
#ifndef epicsMutexImpl_H
#define epicsMutexImpl_H
#if defined(vxWorks)
# include <vxWorks.h>
# include <semLib.h>
#elif defined(_WIN32)
# define VC_EXTRALEAN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#elif defined(__rtems__)
# include <rtems.h>
# include <rtems/score/cpuopts.h>
#else
# include <pthread.h>
#endif
#include "ellLib.h"
#ifdef __cplusplus
extern "C" {
#endif
struct epicsMutexParm {
/* global list of mutex */
ELLNODE node;
/* location where mutex was allocated */
const char *pFileName;
int lineno;
#if defined(vxWorks)
SEM_ID osd;
#elif defined(_WIN32)
CRITICAL_SECTION osd;
#elif defined(__RTEMS_MAJOR__) && __RTEMS_MAJOR__<5
Semaphore_Control *osd;
#else
pthread_mutex_t osd;
#endif
};
void epicsMutexOsdSetup(void);
long epicsMutexOsdPrepare(struct epicsMutexParm *);
void epicsMutexOsdCleanup(struct epicsMutexParm *);
void epicsMutexOsdShow(struct epicsMutexParm *,unsigned int level);
void epicsMutexOsdShowAll(void);
extern struct epicsMutexParm epicsMutexGlobalLock;
#ifdef __cplusplus
} // extern "C
#endif
#endif // epicsMutexImpl_H

View File

@@ -238,7 +238,7 @@ size_t epicsStdCall epicsTimeToStrftime (char *pBuff, size_t bufLength, const ch
// convert nanosecs to integer of correct range
frac /= div[fracWid];
char fracFormat[32];
sprintf ( fracFormat, "%%0%lulu", fracWid );
epicsSnprintf ( fracFormat, sizeof ( fracFormat ), "%%0%lulu", fracWid );
int status = epicsSnprintf ( pBufCur, bufLenLeft, fracFormat, frac );
if ( status > 0 ) {
unsigned long nChar = static_cast < unsigned long > ( status );

View File

@@ -26,6 +26,7 @@
#include "epicsEvent.h"
#include "epicsThread.h"
#include "rtemsNamePvt.h"
#include "errlog.h"
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
@@ -48,11 +49,9 @@ epicsEventCreate(epicsEventInitialState initialState)
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
static char c3 = 'a';
static uint32_t name;
sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1),
sc = rtems_semaphore_create (next_rtems_name ('B', &name),
initialState,
RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
@@ -62,26 +61,6 @@ epicsEventCreate(epicsEventInitialState initialState)
errlogPrintf ("Can't create binary semaphore: %s\n", rtems_status_text (sc));
return NULL;
}
rtems_interrupt_disable (level);
if (c1 == 'z') {
if (c2 == 'z') {
if (c3 == 'z') {
c3 = 'a';
}
else {
c3++;
}
c2 = 'a';
}
else {
c2++;
}
c1 = 'a';
}
else {
c1++;
}
rtems_interrupt_enable (level);
return (epicsEventId)sid;
}

View File

@@ -19,6 +19,7 @@
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <rtems.h>
#include <rtems/error.h>
@@ -26,97 +27,84 @@
#include "epicsStdio.h"
#include "epicsMutex.h"
#include "epicsMutexImpl.h"
#include "rtemsNamePvt.h"
#include "epicsEvent.h"
#include "errlog.h"
#define RTEMS_FAST_MUTEX
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
/*
* Some performance tuning instrumentation
*/
#ifdef EPICS_RTEMS_SEMAPHORE_STATS
unsigned long semMstat[4];
#define SEMSTAT(i) semMstat[i]++;
#else
#define SEMSTAT(i)
#endif
uint32_t next_rtems_name(char prefix, uint32_t* counter)
{
uint32_t next;
rtems_interrupt_level level;
char a, b, c;
struct epicsMutexOSD *
epicsMutexOsdCreate(void)
rtems_interrupt_disable (level);
next = *counter;
*counter = (next+1)%(26u*26u*26u);
rtems_interrupt_enable (level);
a = 'a' + (next % 26u);
next /= 26u;
b = 'a' + (next % 26u);
next /= 26u;
c = 'a' + (next % 26u); // modulo should be redundant, but ... paranoia
return rtems_build_name(prefix, a, b, c);
}
void epicsMutexOsdSetup(void)
{
// TODO: use RTEMS_SYSINIT_ITEM() ?
if(!epicsMutexGlobalLock.osd) {
epicsMutexOsdPrepare(&epicsMutexGlobalLock);
}
}
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
{
rtems_status_code sc;
rtems_id sid;
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
static char c3 = 'a';
static uint32_t name;
sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1),
sc = rtems_semaphore_create (next_rtems_name ('M', &name),
1,
RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
0,
&sid);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc));
return NULL;
return ENOMEM;
}
rtems_interrupt_disable (level);
if (c1 == 'z') {
if (c2 == 'z') {
if (c3 == 'z') {
c3 = 'a';
}
else {
c3++;
}
c2 = 'a';
}
else {
c2++;
}
c1 = 'a';
}
else {
c1++;
}
rtems_interrupt_enable (level);
#ifdef RTEMS_FAST_MUTEX
{
Semaphore_Control *the_semaphore;
Objects_Locations location;
Objects_Locations location;
the_semaphore = _Semaphore_Get( sid, &location );
_Thread_Enable_dispatch();
mutex->osd = _Semaphore_Get( sid, &location );
_Thread_Enable_dispatch(); /* _Semaphore_Get() disables */
return (struct epicsMutexOSD *)the_semaphore;
return 0;
}
#endif
return (struct epicsMutexOSD *)sid;
}
void epicsMutexOsdDestroy(struct epicsMutexOSD * id)
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
{
rtems_status_code sc;
rtems_id sid;
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
Semaphore_Control *the_semaphore = mutex->osd;
sid = the_semaphore->Object.id;
#else
sid = (rtems_id)id;
#endif
sc = rtems_semaphore_delete (sid);
if (sc == RTEMS_RESOURCE_IN_USE) {
rtems_semaphore_release (sid);
sc = rtems_semaphore_delete (sid);
}
if (sc != RTEMS_SUCCESSFUL)
errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n", id, (unsigned long)sid, rtems_status_text (sc));
errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n",
mutex, (unsigned long)sid, rtems_status_text (sc));
}
void epicsMutexOsdUnlock(struct epicsMutexOSD * id)
void epicsMutexUnlock(struct epicsMutexParm *mutex)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
Semaphore_Control *the_semaphore = mutex->osd;
_Thread_Disable_dispatch();
_CORE_mutex_Surrender (
&the_semaphore->Core_control.mutex,
@@ -124,18 +112,13 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * id)
NULL
);
_Thread_Enable_dispatch();
#else
epicsEventSignal (id);
#endif
}
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id)
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm *mutex)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
Semaphore_Control *the_semaphore = mutex->osd;
ISR_Level level;
SEMSTAT(0)
_ISR_Disable( level );
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
@@ -148,19 +131,12 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id)
return epicsMutexLockOK;
else
return epicsMutexLockError;
#else
SEMSTAT(0)
return((epicsEventWait (id) == epicsEventWaitOK)
?epicsMutexLockOK : epicsMutexLockError);
#endif
}
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm *mutex)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
Semaphore_Control *the_semaphore = mutex->osd;
ISR_Level level;
SEMSTAT(2)
_ISR_Disable( level );
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
@@ -175,25 +151,12 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
return epicsMutexLockTimeout;
else
return epicsMutexLockError;
#else
epicsEventWaitStatus status;
SEMSTAT(2)
status = epicsEventTryWait(id);
return((status==epicsEventWaitOK
? epicsMutexLockOK
: (status==epicsEventWaitTimeout)
? epicsMutexLockTimeout
: epicsMutexLockError));
#endif
}
LIBCOM_API void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level)
LIBCOM_API void epicsMutexOsdShow(struct epicsMutexParm *mutex,unsigned int level)
{
#ifdef RTEMS_FAST_MUTEX
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
id = (struct epicsMutexOSD *)the_semaphore->Object.id;
#endif
epicsEventShow ((epicsEventId)id,level);
Semaphore_Control *the_semaphore = mutex->osd;
epicsEventShow ((epicsEventId)the_semaphore->Object.id,level);
}
void epicsMutexOsdShowAll(void) {}

View File

@@ -31,6 +31,7 @@
#include "epicsStdio.h"
#include "errlog.h"
#include "epicsMutex.h"
#include "epicsMutexImpl.h"
#include "epicsString.h"
#include "epicsThread.h"
#include "cantProceed.h"
@@ -59,7 +60,7 @@ struct taskVar {
unsigned int threadVariableCapacity;
void **threadVariables;
};
static struct epicsMutexOSD *taskVarMutex;
static struct epicsMutexParm taskVarMutex = {ELLNODE_INIT, __FILE__, __LINE__};
static struct taskVar *taskVarHead;
#define RTEMS_NOTEPAD_TASKVAR 11
@@ -67,15 +68,7 @@ static struct taskVar *taskVarHead;
* Support for `once-only' execution
*/
static volatile int initialized = 0; /* strictly speaking 'volatile' is not enough here, but it shouldn't hurt */
static struct epicsMutexOSD *onceMutex;
static
void epicsMutexOsdMustLock(struct epicsMutexOSD * L)
{
while(epicsMutexOsdLock(L)!=epicsMutexLockOK) {
cantProceed("epicsThreadOnce() mutex error");
}
}
static struct epicsMutexParm onceMutex = {ELLNODE_INIT, __FILE__, __LINE__};
/*
* Just map osi 0 to 99 into RTEMS 199 to 100
@@ -161,13 +154,13 @@ epicsThreadGetStackSize (epicsThreadStackSizeClass size)
static void
taskVarLock (void)
{
epicsMutexOsdMustLock (taskVarMutex);
epicsMutexMustLock (&taskVarMutex);
}
static void
taskVarUnlock (void)
{
epicsMutexOsdUnlock (taskVarMutex);
epicsMutexUnlock (&taskVarMutex);
}
static
@@ -243,7 +236,7 @@ setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr,
v->threadVariables = NULL;
v->isRunning = 1;
if (joinable) {
char c[3];
char c[3] = {0,0,0};
strncpy(c, v->name, 3);
sc = rtems_barrier_create(rtems_build_name('~', c[0], c[1], c[2]),
RTEMS_BARRIER_AUTOMATIC_RELEASE | RTEMS_LOCAL,
@@ -288,10 +281,8 @@ epicsThreadInit (void)
rtems_task_priority old;
rtems_task_set_priority (RTEMS_SELF, epicsThreadGetOssPriorityValue(99), &old);
onceMutex = epicsMutexOsdCreate();
taskVarMutex = epicsMutexOsdCreate();
if (!onceMutex || !taskVarMutex)
cantProceed("epicsThreadInit() can't create global mutexes\n");
epicsMutexOsdPrepare(&taskVarMutex);
epicsMutexOsdPrepare(&onceMutex);
rtems_task_ident (RTEMS_SELF, 0, &tid);
if(setThreadInfo (tid, "_main_", NULL, NULL, 0) != RTEMS_SUCCESSFUL)
cantProceed("epicsThreadInit() unable to setup _main_");
@@ -317,7 +308,7 @@ epicsThreadCreateOpt (
unsigned int stackSize;
rtems_id tid;
rtems_status_code sc;
char c[4];
char c[4] = {0,0,0,0};
if (!initialized)
epicsThreadInit();
@@ -612,26 +603,26 @@ void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg)
#define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1
if (!initialized) epicsThreadInit();
epicsMutexOsdMustLock(onceMutex);
epicsMutexMustLock(&onceMutex);
if (*id != EPICS_THREAD_ONCE_DONE) {
if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */
*id = epicsThreadGetIdSelf(); /* mark active */
epicsMutexOsdUnlock(onceMutex);
epicsMutexUnlock(&onceMutex);
func(arg);
epicsMutexOsdMustLock(onceMutex);
epicsMutexMustLock(&onceMutex);
*id = EPICS_THREAD_ONCE_DONE; /* mark done */
} else if (*id == epicsThreadGetIdSelf()) {
epicsMutexOsdUnlock(onceMutex);
epicsMutexUnlock(&onceMutex);
cantProceed("Recursive epicsThreadOnce() initialization\n");
} else
while (*id != EPICS_THREAD_ONCE_DONE) {
/* Another thread is in the above func(arg) call. */
epicsMutexOsdUnlock(onceMutex);
epicsMutexUnlock(&onceMutex);
epicsThreadSleep(epicsThreadSleepQuantum());
epicsMutexOsdMustLock(onceMutex);
epicsMutexMustLock(&onceMutex);
}
}
epicsMutexOsdUnlock(onceMutex);
epicsMutexUnlock(&onceMutex);
}
/*

View File

@@ -0,0 +1,20 @@
/*************************************************************************\
* Copyright (c) 2023 Michael Davidsaver
* SPDX-License-Identifier: EPICS
* EPICS Base is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef RTEMSNAMEPVT_H
#define RTEMSNAMEPVT_H
#include <stdint.h>
/* Compute rtems_build_name(prefix, A, B, C) where A, B, C are the letters a-z.
* eg. "Qaaa"
*
* 'counter' is incremented atomically during each call.
*/
uint32_t next_rtems_name(char prefix, uint32_t* counter);
#endif // RTEMSNAMEPVT_H

View File

@@ -20,147 +20,59 @@
#include <stdio.h>
#include <limits.h>
#define VC_EXTRALEAN
#define STRICT
#include <windows.h>
#if _WIN32_WINNT < 0x0501
# error Minimum supported is Windows XP
#endif
#define EPICS_PRIVATE_API
#include "libComAPI.h"
#include "epicsMutex.h"
#include "epicsMutexImpl.h"
#include "epicsThread.h"
#include "epicsAssert.h"
#include "epicsStdio.h"
typedef struct epicsMutexOSD {
union {
HANDLE mutex;
CRITICAL_SECTION criticalSection;
} os;
} epicsMutexOSD;
static BOOL thisIsNT = FALSE;
static LONG weHaveInitialized = 0;
/*
* epicsMutexCreate ()
*/
epicsMutexOSD * epicsMutexOsdCreate ( void )
static epicsThreadOnceId epicsMutexOsdOnce = EPICS_THREAD_ONCE_INIT;
static void epicsMutexOsdInit(void* unused)
{
epicsMutexOSD * pSem;
if ( ! weHaveInitialized ) {
BOOL status;
OSVERSIONINFO osInfo;
osInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO );
status = GetVersionEx ( & osInfo );
thisIsNT = status && ( osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT );
weHaveInitialized = 1;
}
pSem = malloc ( sizeof (*pSem) );
if ( pSem ) {
if ( thisIsNT ) {
InitializeCriticalSection ( &pSem->os.criticalSection );
}
else {
pSem->os.mutex = CreateMutex ( NULL, FALSE, NULL );
if ( pSem->os.mutex == 0 ) {
free ( pSem );
pSem = 0;
}
}
}
return pSem;
(void)unused;
InitializeCriticalSection(&epicsMutexGlobalLock.osd);
}
/*
* epicsMutexOsdDestroy ()
*/
void epicsMutexOsdDestroy ( epicsMutexOSD * pSem )
void epicsMutexOsdSetup()
{
if ( thisIsNT ) {
DeleteCriticalSection ( &pSem->os.criticalSection );
}
else {
CloseHandle ( pSem->os.mutex );
}
free ( pSem );
epicsThreadOnce(&epicsMutexOsdOnce, &epicsMutexOsdInit, NULL);
}
/*
* epicsMutexOsdUnlock ()
*/
void epicsMutexOsdUnlock ( epicsMutexOSD * pSem )
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
{
if ( thisIsNT ) {
LeaveCriticalSection ( &pSem->os.criticalSection );
}
else {
BOOL success = ReleaseMutex ( pSem->os.mutex );
assert ( success );
}
InitializeCriticalSection(&mutex->osd);
return 0;
}
/*
* epicsMutexOsdLock ()
*/
epicsMutexLockStatus epicsMutexOsdLock ( epicsMutexOSD * pSem )
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
{
if ( thisIsNT ) {
EnterCriticalSection ( &pSem->os.criticalSection );
}
else {
DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE );
if ( status != WAIT_OBJECT_0 ) {
return epicsMutexLockError;
}
}
DeleteCriticalSection(&mutex->osd);
}
void epicsStdCall epicsMutexUnlock ( struct epicsMutexParm *mutex )
{
LeaveCriticalSection ( &mutex->osd );
}
epicsMutexLockStatus epicsStdCall epicsMutexLock ( struct epicsMutexParm *mutex )
{
EnterCriticalSection ( &mutex->osd );
return epicsMutexLockOK;
}
/*
* epicsMutexOsdTryLock ()
*/
epicsMutexLockStatus epicsMutexOsdTryLock ( epicsMutexOSD * pSem )
epicsMutexLockStatus epicsStdCall epicsMutexTryLock ( struct epicsMutexParm *mutex )
{
if ( thisIsNT ) {
if ( TryEnterCriticalSection ( &pSem->os.criticalSection ) ) {
return epicsMutexLockOK;
}
else {
return epicsMutexLockTimeout;
}
}
else {
DWORD status = WaitForSingleObject ( pSem->os.mutex, 0 );
if ( status != WAIT_OBJECT_0 ) {
if (status == WAIT_TIMEOUT) {
return epicsMutexLockTimeout;
}
else {
return epicsMutexLockError;
}
}
}
return epicsMutexLockOK;
return TryEnterCriticalSection ( &mutex->osd ) ? epicsMutexLockOK : epicsMutexLockTimeout;
}
/*
* epicsMutexOsdShow ()
*/
void epicsMutexOsdShow ( epicsMutexOSD * pSem, unsigned level )
void epicsMutexOsdShow ( struct epicsMutexParm *mutex, unsigned level )
{
if ( thisIsNT ) {
printf ("epicsMutex: win32 critical section at %p\n",
(void * ) & pSem->os.criticalSection );
}
else {
printf ( "epicsMutex: win32 mutex at %p\n",
( void * ) pSem->os.mutex );
}
(void)level;
printf ("epicsMutex: win32 critical section at %p\n",
(void * ) & mutex->osd );
}
void epicsMutexOsdShowAll(void) {}

View File

@@ -119,8 +119,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
return socket ( domain, type, protocol );
}
LIBCOM_API int epicsStdCall epicsSocketAccept (
int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
LIBCOM_API SOCKET epicsStdCall epicsSocketAccept (
SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
{
return accept ( sock, pAddr, addrlen );
}

View File

@@ -500,8 +500,6 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter )
BOOL success;
if ( pGbl ) {
setThreadName ( pParm->id, pParm->pName );
success = FlsSetValue ( pGbl->flsIndexThreadLibraryEPICS, pParm );
if ( success ) {
osdThreadHooksRun ( ( epicsThreadId ) pParm );
@@ -659,6 +657,7 @@ epicsThreadId epicsThreadCreateOpt (
pParmWIN32->id = ( DWORD ) threadId ;
}
setThreadName ( pParmWIN32->id, pParmWIN32->pName );
osdPriority = epicsThreadGetOsdPriorityValue (opts->priority);
bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority );
if (!bstat) {

View File

@@ -215,6 +215,7 @@ void currentTime :: startPLL ()
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
& this->threadId );
assert ( this->threadHandle );
setThreadName ( this->threadId, "EPICS Time PLL" );
BOOL bstat = SetThreadPriority (
this->threadHandle, THREAD_PRIORITY_HIGHEST );
assert ( bstat );
@@ -496,7 +497,6 @@ static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn )
{
currentTime * pCT =
reinterpret_cast < currentTime * > ( pCurrentTimeIn );
setThreadName ( pCT->threadId, "EPICS Time PLL" );
while ( ! pCT->threadShutdownCmd ) {
Sleep ( currentTime :: pllDelay * 1000 /* mS */ );
pCT->updatePLL ();

View File

@@ -40,7 +40,16 @@ struct threadNode {
struct eventNode *evp;
void *buf;
unsigned int size;
volatile bool eventSent;
bool eventSent;
inline
threadNode()
:evp(NULL)
,buf(NULL)
,size(0u)
,eventSent(false)
{
memset(&link, 0, sizeof(link));
}
};
/*
@@ -366,9 +375,10 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size,
freeEventNode(pmsg, threadNode.evp, status);
bool wasSent = threadNode.eventSent;
epicsMutexUnlock(pmsg->mutex);
if (threadNode.eventSent && (threadNode.size <= size))
if (wasSent && (threadNode.size <= size))
return threadNode.size;
return -1;
}

View File

@@ -24,18 +24,19 @@
#include <unistd.h>
#include <pthread.h>
#include <ctype.h>
#include <envDefs.h>
#define EPICS_PRIVATE_API
#define epicsStdioStdStreams
#define epicsStdioStdPrintfEtc
#include "epicsMutex.h"
#include "epicsMutexImpl.h"
#include "osdPosixMutexPriv.h"
#include "epicsThread.h"
#include "cantProceed.h"
#include "epicsTime.h"
#include "errlog.h"
#include "epicsStdio.h"
#include "epicsAssert.h"
#include "envDefs.h"
#define checkStatus(status,message) \
if((status)) { \
@@ -128,62 +129,62 @@ static int mutexLock(pthread_mutex_t *id)
return status;
}
typedef struct epicsMutexOSD {
pthread_mutex_t lock;
} epicsMutexOSD;
/* used if OS does not support statically allocated mutex */
static pthread_once_t epicsMutexOsdOnce = PTHREAD_ONCE_INIT;
epicsMutexOSD * epicsMutexOsdCreate(void) {
epicsMutexOSD *pmutex;
int status;
pmutex = calloc(1, sizeof(*pmutex));
if(!pmutex)
return NULL;
status = osdPosixMutexInit(&pmutex->lock, PTHREAD_MUTEX_RECURSIVE);
if (!status)
return pmutex;
free(pmutex);
return NULL;
static void epicsMutexOsdInit(void)
{
int ret = pthread_mutex_init(&epicsMutexGlobalLock.osd, NULL);
if(ret) {
/* something has gone wrong early. Not much can be done...*/
fprintf(stderr, "osdMutex early init failure %d.\n", ret);
abort();
}
}
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
void epicsMutexOsdSetup()
{
int status;
status = pthread_mutex_destroy(&pmutex->lock);
checkStatusQuit(status, "pthread_mutex_destroy", "epicsMutexOsdDestroy");
free(pmutex);
int ret = pthread_once(&epicsMutexOsdOnce, &epicsMutexOsdInit);
if(ret) {
/* ditto...*/
fprintf(stderr, "osdMutex early once failure %d.\n", ret);
abort();
}
}
void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
{
int status;
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
long epicsMutexOsdPrepare(struct epicsMutexParm *pmutex) {
return osdPosixMutexInit(&pmutex->osd, PTHREAD_MUTEX_RECURSIVE);
}
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
void epicsMutexOsdCleanup(struct epicsMutexParm *pmutex)
{
int status;
int status = pthread_mutex_destroy(&pmutex->osd);
checkStatus(status, "pthread_mutex_destroy");
}
status = mutexLock(&pmutex->lock);
void epicsMutexUnlock(struct epicsMutexParm * pmutex)
{
int status = pthread_mutex_unlock(&pmutex->osd);
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock");
}
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm * pmutex)
{
int status = mutexLock(&pmutex->osd);
if (status == EINVAL) return epicsMutexLockError;
if(status) {
errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n");
errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexLock\n");
return epicsMutexLockError;
}
return epicsMutexLockOK;
}
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm * pmutex)
{
int status;
if (!pmutex) return epicsMutexLockError;
status = pthread_mutex_trylock(&pmutex->lock);
status = pthread_mutex_trylock(&pmutex->osd);
if (status == EINVAL) return epicsMutexLockError;
if (status == EBUSY) return epicsMutexLockTimeout;
if(status) {
@@ -193,12 +194,13 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
return epicsMutexLockOK;
}
void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level)
void epicsMutexOsdShow(struct epicsMutexParm * pmutex, unsigned int level)
{
(void)level;
/* GLIBC w/ NTPL is passing the &lock.__data.__lock as the first argument (UADDR)
* of the futex() syscall. __lock is at offset 0 of the enclosing structures.
*/
printf(" pthread_mutex_t* uaddr=%p\n", &pmutex->lock);
epicsStdoutPrintf(" pthread_mutex_t* uaddr=%p\n", &pmutex->osd);
}
void epicsMutexOsdShowAll(void)
@@ -207,11 +209,11 @@ void epicsMutexOsdShowAll(void)
int proto = -1;
int ret = pthread_mutexattr_getprotocol(&globalAttrRecursive, &proto);
if(ret) {
printf("PI maybe not enabled: %d\n", ret);
epicsStdoutPrintf("PI maybe not enabled: %d\n", ret);
} else {
printf("PI is%s enabled\n", proto==PTHREAD_PRIO_INHERIT ? "" : " not");
epicsStdoutPrintf("PI is%s enabled\n", proto==PTHREAD_PRIO_INHERIT ? "" : " not");
}
#else
printf("PI not supported\n");
epicsStdoutPrintf("PI not supported\n");
#endif
}

View File

@@ -27,6 +27,7 @@
#include "osiSock.h"
#include "epicsAssert.h"
#include "errlog.h"
#include "epicsAtomic.h"
/* Linux and *BSD (at least) specific way to atomically set O_CLOEXEC.
* RTEMS 5.1 provides SOCK_CLOEXEC, but doesn't implement accept4()
@@ -60,19 +61,18 @@ static void unlockInfo (void)
epicsMutexUnlock (infoMutex);
}
/*
* NOOP
*/
static size_t nAttached;
int osiSockAttach()
{
epicsAtomicIncrSizeT(&nAttached);
return 1;
}
/*
* NOOP
*/
void osiSockRelease()
{
epicsAtomicDecrSizeT(&nAttached);
}
/*
@@ -83,6 +83,11 @@ void osiSockRelease()
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
int domain, int type, int protocol )
{
static unsigned char warnAttached;
if(!epicsAtomicGetSizeT(&nAttached) && !warnAttached) {
warnAttached = 1;
errlogPrintf(ERL_WARNING ": epicsSocketCreate() without osiSockAttach() is not portable\n");
}
SOCKET sock = socket ( domain, type | SOCK_CLOEXEC, protocol );
if ( sock < 0 ) {
sock = INVALID_SOCKET;
@@ -119,8 +124,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
return sock;
}
LIBCOM_API int epicsStdCall epicsSocketAccept (
int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
LIBCOM_API SOCKET epicsStdCall epicsSocketAccept (
SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
{
#ifndef HAVE_SOCK_CLOEXEC
int newSock = accept ( sock, pAddr, addrlen );

View File

@@ -13,6 +13,7 @@
#include <vxWorks.h>
#include <semLib.h>
#include <errno.h>
#include <time.h>
#include <objLib.h>
#include <sysLib.h>
@@ -23,30 +24,47 @@ int sysClkRateGet(void);
#define EPICS_PRIVATE_API
#include "epicsMutex.h"
struct epicsMutexOSD * epicsMutexOsdCreate(void)
#include "epicsMutexImpl.h"
void epicsMutexOsdSetup(void)
{
return((struct epicsMutexOSD *)
semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY));
if(!epicsMutexGlobalLock.osd) {
epicsMutexOsdPrepare(&epicsMutexGlobalLock);
}
}
void epicsMutexOsdDestroy(struct epicsMutexOSD * id)
long epicsMutexOsdPrepare(struct epicsMutexParm *mutex)
{
semDelete((SEM_ID)id);
mutex->osd = semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY);
return mutex->osd ? 0 : ENOMEM;
}
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id)
void epicsMutexOsdCleanup(struct epicsMutexParm *mutex)
{
int status;
status = semTake((SEM_ID)id,NO_WAIT);
semDelete(mutex->osd);
}
epicsMutexLockStatus epicsMutexLock(struct epicsMutexParm *mutex)
{
return semTake(mutex->osd,WAIT_FOREVER)==OK ? epicsMutexLockOK : epicsMutexLockError;
}
epicsMutexLockStatus epicsMutexTryLock(struct epicsMutexParm *mutex)
{
int status = semTake(mutex->osd,NO_WAIT);
if(status==OK) return(epicsMutexLockOK);
if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsMutexLockTimeout);
return(epicsMutexLockError);
}
void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level)
void epicsMutexUnlock(struct epicsMutexParm *mutex)
{
semShow((SEM_ID)id,level);
semGive(mutex->osd);
}
void epicsMutexOsdShow(struct epicsMutexParm *mutex,unsigned int level)
{
semShow(mutex->osd,level);
}
void epicsMutexOsdShowAll(void) {}

Some files were not shown because too many files have changed in this diff Show More