Compare commits

...

106 Commits

Author SHA1 Message Date
Marty Kraimer
89a6d17353 Added argument verbose to dbPvdDump 1995-08-22 12:23:37 +00:00
Jeff Hill
d9666a8f30 added cvs style mod log 1995-08-22 00:27:59 +00:00
Jeff Hill
7cb76ae9e4 dont recompute connection time outs if the time stamp doesnt change 1995-08-22 00:25:22 +00:00
Jeff Hill
46e00da251 recompute the current time variable after waiting in a semaphore
(instead of select)
1995-08-22 00:24:38 +00:00
Jeff Hill
39d98562fc dont recompute connection timers if the time stamp hasnt changed 1995-08-22 00:23:36 +00:00
Jeff Hill
8624be05d4 Dont wait for itsy bitsy delays to expire 1995-08-22 00:22:52 +00:00
Jeff Hill
c0da182217 Dont recompute connection timers if the time stamp hasnt changed 1995-08-22 00:22:07 +00:00
Jeff Hill
6dab97f8e7 added KLUDGE def of S_db_Pending 1995-08-22 00:20:27 +00:00
Jeff Hill
1abcc71e71 use current time var to init time stamp in a beacon hash entry 1995-08-22 00:19:21 +00:00
Jeff Hill
f8f17eeb33 comments changed 1995-08-22 00:17:11 +00:00
Jeff Hill
db50e1bdd7 Added test of the duration of ca_pend_event() 1995-08-22 00:16:34 +00:00
Jeff Hill
96605d4439 Use 1.0/USEC_PER_SEC and not 1.0e-6
Check for S_db_Pending when calling dbPutNotify()
1995-08-22 00:15:19 +00:00
Jeff Hill
593bc413bf *** empty log message *** 1995-08-22 00:12:07 +00:00
Marty Kraimer
3e20abece8 When initing new card wait yp to 3 seconds to read old values. 1995-08-18 17:59:09 +00:00
Marty Kraimer
79c01170e8 db_post_event had illegal arg for val field 1995-08-18 15:22:28 +00:00
Marty Kraimer
6c21758d23 fixed 2nd arg of db_post_event for clcv 1995-08-18 15:11:35 +00:00
Marty Kraimer
d2347c497c Changes for ansi c 1995-08-18 15:07:32 +00:00
Marty Kraimer
099f63fb20 Made changes for ansi c 1995-08-18 13:19:37 +00:00
Jeff Hill
665a5134d3 send flush message when we see a new client 1995-08-18 00:30:07 +00:00
Jim Kowalkowski
e1b04e69bb fixed all the -pendantic errors (pain) 1995-08-17 20:35:09 +00:00
Janet B. Anderson
8375a2cf18 Moved bldEnvData,blderrSymTbl, makeStatTbl to libCom dir 1995-08-17 20:22:13 +00:00
Janet B. Anderson
300f38584b Added base/tools scripts functionality to base/Makefile, removed scripts
Moved base/tools/MakeRelease to base dir.
1995-08-17 20:15:03 +00:00
Janet B. Anderson
b9a5acc88c Fixed comment that broke during previous commit 1995-08-17 19:49:52 +00:00
Jim Kowalkowski
2ff81c09f0 Completed the accurate time stamp change. event number 0 is current time
updated at 60HZ, event -1 is the best time that can be provided (1000Hz in
the APS event system).  The vxWorks time is now correct (1970 instead of
1900).
1995-08-17 19:43:04 +00:00
Janet B. Anderson
63eefd2ba8 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:43:34 +00:00
Janet B. Anderson
f9f8e55035 Moved cvtBpt.c to db dir so libCom builds without record header dependancies 1995-08-17 15:39:10 +00:00
Janet B. Anderson
0f8f36c4bb Makefile now uses library build rule from RULES.Vx
Moved cvtBpt.c to db dir so libCom builds without record header dependancies
1995-08-17 15:38:03 +00:00
Janet B. Anderson
fd6e666256 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:33:47 +00:00
Janet B. Anderson
d492d665fc Moved cvtBpt.c from libCom so libCom now has no record header dependancies 1995-08-17 15:31:42 +00:00
Janet B. Anderson
6b659e8404 Makefile now uses library build rule from RULES.Vx.
Moved cvtBpt.c from libCom so libCom now has no record header dependancies
1995-08-17 15:31:24 +00:00
Janet B. Anderson
43ecde53f3 Makefile now uses library build rule from RULES.Vx,removed redundant rules. 1995-08-17 15:28:32 +00:00
Janet B. Anderson
e6ffa71c54 Removed redundant rules. 1995-08-17 15:27:11 +00:00
Janet B. Anderson
be6ecdfe24 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:25:45 +00:00
Marty Kraimer
e6bec6af38 mrk committed for dalesio 1995-08-17 14:51:53 +00:00
Marty Kraimer
59a2f10867 Initialize oval properly 1995-08-17 14:50:43 +00:00
Marty Kraimer
00abe6b876 Removed recSwitch 1995-08-17 14:50:17 +00:00
Marty Kraimer
b0e9cc9fba Made changes so that it doesnt call dbCalloc 1995-08-17 14:48:02 +00:00
Marty Kraimer
6eb04984bd Removed epicsSetEnvParams 1995-08-17 14:47:40 +00:00
Marty Kraimer
d9a05d6051 added abConfigScanListAscii and abConfigAuto 1995-08-17 14:45:57 +00:00
Marty Kraimer
d9233e4864 ansi changes 1995-08-17 14:43:49 +00:00
Marty Kraimer
34bd710ffa Removed INITHOOKafterSetEnvParams 1995-08-17 14:42:43 +00:00
Marty Kraimer
438f00a708 Changes to make more ansi compatible 1995-08-17 14:42:12 +00:00
Marty Kraimer
622a225308 Changed hash algorithm to allow larger table sizes 1995-08-17 14:41:05 +00:00
Marty Kraimer
1c14ac4941 post_event and scanOnce no longer give error message storms for ring buffer overflows.
Made changes so that casts are ANSI C compatible
1995-08-17 14:39:46 +00:00
Marty Kraimer
df2ce01069 Made change for new putNotify 1995-08-17 14:36:54 +00:00
Marty Kraimer
f7aa394524 Changed algorithm for computing lock sets.
No longer calls epicsSetEnvParams.
1995-08-17 14:36:29 +00:00
Marty Kraimer
ed6047ec51 Many changes. It should now work in all cases( I hope). 1995-08-17 14:35:47 +00:00
Marty Kraimer
a3573cd384 If record should be processed because of put and record is active and TPRO is true then print active message.
Fixed some casts so that they are ANSI compatible
putStringUshort converts to float first then to ushort
putStringUlong converts to double first then to unsigned long
1995-08-17 14:34:55 +00:00
Marty Kraimer
81deb4fceb Use new hash algorirthm. New variable dbPvdHashTableSize can be set after ld < iocCore 1995-08-17 14:33:55 +00:00
Marty Kraimer
b7378bbc62 Added -Wall -pedantic -ansi 1995-08-17 14:33:18 +00:00
Marty Kraimer
bdffdb0369 If asSetFilename is given NULL argument then next call to asInit turns off access security.
Allow character '-' in pvnames.
1995-08-17 14:31:52 +00:00
Ned Arnold
98809f8141 made QUEUE_SIZE a global variable so users could control mallocing 1995-08-16 20:53:26 +00:00
Jim Kowalkowski
8a0f66cb9b Corrected multiple card bug. 1995-08-16 19:15:07 +00:00
Jim Kowalkowski
0462aed01d Many updates. Added GPS ability and adjusted the printf's. 1995-08-16 19:03:21 +00:00
Jim Kowalkowski
ea279855da Allow for ~ in both pv name and value. 1995-08-16 18:16:43 +00:00
Jeff Hill
66210afed7 epicsAPI => epicsShareAPI 1995-08-14 19:26:15 +00:00
Jeff Hill
c13d342680 fixed compilation error 1995-08-14 16:08:08 +00:00
Jeff Hill
549a4ba978 func proto added 1995-08-12 01:20:36 +00:00
Jeff Hill
cf7fe3deb4 force double alignment of the protocol buffer 1995-08-12 01:18:28 +00:00
Jeff Hill
ef8abaa44f keep trying 1995-08-12 01:17:38 +00:00
Jeff Hill
5624aaefe1 fetch the server's port number 1995-08-12 01:16:26 +00:00
Jeff Hill
2b7e4ff84d dont quit if client unreachable 1995-08-12 01:15:08 +00:00
Jeff Hill
fb2c2f0925 dont reuse res id 1995-08-12 01:14:22 +00:00
Jeff Hill
55dae7db1c no dbg lib 1995-08-12 01:13:30 +00:00
Jeff Hill
524da0d2df doc 1995-08-12 01:12:37 +00:00
Jeff Hill
93c191ffe9 windows NT changes 1995-08-12 01:11:53 +00:00
Jeff Hill
0dc2be41d3 dont allow res id reuse 1995-08-12 01:10:57 +00:00
Jeff Hill
11af4456c7 dont return (and leak memory) 1995-08-12 01:10:25 +00:00
Jeff Hill
f232999d32 dont print if the format is NULL 1995-08-12 01:04:11 +00:00
Jeff Hill
ca13bfdff9 dont call vprintf if pformat is NULL 1995-08-12 01:03:17 +00:00
Jeff Hill
21cbea930a added casdef.h 1995-08-12 01:02:39 +00:00
Jeff Hill
8b06e22907 added return to print func 1995-08-12 01:02:11 +00:00
Jeff Hill
f3dcfd60bb dont allow reallocation of the same res id
use std EPICS status
1995-08-12 01:01:20 +00:00
Jeff Hill
1b33e449c6 use $log in header 1995-08-12 01:00:07 +00:00
Jeff Hill
afa208a5e1 use $log in header 1995-08-12 00:59:11 +00:00
Jeff Hill
5903ff0cdb use arch independent types 1995-08-12 00:48:21 +00:00
Jeff Hill
51d44c6200 use epicsApi 1995-08-12 00:44:13 +00:00
Jeff Hill
a362731044 use const in proto 1995-08-12 00:43:41 +00:00
Jeff Hill
0e225a4335 use epicsEntry 1995-08-12 00:42:23 +00:00
Jeff Hill
8c0527c25a dont allow res id reuse 1995-08-12 00:41:52 +00:00
Jeff Hill
92f91ee2cc allow multiple servers on one machine 1995-08-12 00:40:58 +00:00
Jeff Hill
1bd52dfef9 discover loss of client by connecting UDP sockets 1995-08-12 00:37:28 +00:00
Jeff Hill
c7005b4783 dont muck with signal handlers already installed 1995-08-12 00:31:37 +00:00
Jeff Hill
d9e3f09760 win NT changes 1995-08-12 00:30:24 +00:00
Jeff Hill
07a265d299 added const 1995-08-12 00:29:39 +00:00
Jeff Hill
feb73d85b3 bumbed CA minor version to 5 1995-08-12 00:28:58 +00:00
Jeff Hill
f18238a8b9 added shareLib.h and const to proto 1995-08-12 00:28:10 +00:00
Jeff Hill
8ff5572e6c linux changes 1995-08-12 00:27:24 +00:00
Jeff Hill
865e69d7d3 added const to func proto 1995-08-12 00:26:26 +00:00
Jeff Hill
38f82f342d new ca_pend_event() duration test 1995-08-12 00:25:34 +00:00
Jeff Hill
20fd27263a sped up ca_pend_event() poll 1995-08-12 00:24:58 +00:00
Jeff Hill
7760d16956 better fp test 1995-08-12 00:24:26 +00:00
Jeff Hill
3fab82780b check for res id in use, epicsEntry, dont wait for itsy bitsy delay
in ca_pend_event(), better clean up when monitor is deleted and
we are disconnected
1995-08-12 00:23:32 +00:00
Jeff Hill
fd679234dd doc 1995-08-12 00:18:59 +00:00
Ned Arnold
7f949f441b Corrected bug of not allocating space for .dola : Multiple records with DOLN's did not work. 1995-08-07 15:36:37 +00:00
John Winans
48640936f5 Changed the parameter table and associated support routines to support
buffer length specifications of size long instead of short.
1995-07-31 19:44:18 +00:00
John Winans
1e2d258c66 first release 1995-07-27 14:23:02 +00:00
John Winans
83d4ee2313 Changed the way send() is called to account for structure padding. 1995-05-30 14:45:44 +00:00
Jeff Hill
67324dc7b7 use DBR_STRING parameter instead of just zero 1995-05-23 20:45:08 +00:00
Jim Kowalkowski
47843d49a0 updates to allow direct read of time stamps from event systems 1995-05-22 15:21:39 +00:00
John Winans
d27f70a883 Aded logic to handle the new BdtEof protocol state. 1995-05-16 15:39:27 +00:00
Jim Kowalkowski
bcde03d0a0 new functions to support the bulk data transfer 1995-05-11 02:10:50 +00:00
Andrew Johnson
1887fbd7f8 Added CONFIG_SITE_ENV, changed envData to .c file 1995-05-04 09:49:18 +00:00
Andrew Johnson
f3e0f33d15 Fixed port4_5 / port6_7 swap in bo_driver 1995-05-01 17:16:23 +00:00
cvs2svn
09e1c40650 This commit was manufactured by cvs2svn to create tag 'R3.12.1'. 1995-04-26 14:17:01 +00:00
cvs2svn
0de34c3162 This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta13'. 1995-04-26 14:17:00 +00:00
110 changed files with 5821 additions and 3033 deletions

125
MakeRelease Executable file
View File

@@ -0,0 +1,125 @@
#!/bin/sh
#
# $Id$
#
# Make Release - Creates an EPICS release
# By Matthew Needes and Bob Zieman
#
# MakeRelease [-b]
#
# [-b] - For fully built release
#
# $Log$
# Revision 1.14 1994/12/19 18:42:08 tang
# Make the args length compatible for HP and SUN.
#
# Revision 1.13 1994/12/15 19:19:18 tang
# Replace -I opt by cat and xargs for tar for HP compatibility.
#
# Revision 1.12 1994/12/14 23:57:55 tang
# Take out \< and \> pair for hp compatible
#
# Revision 1.11 1994/10/31 21:44:17 jba
# Moved print stmnt, added cd $(EPICS)
#
# Revision 1.10 1994/10/05 18:29:34 jba
# Renamed version.h to epicsVersion.h
#
# Revision 1.9 1994/09/22 01:41:47 mcn
# MakeRelease - MAJOR bug fix. GetVar / MakeDirs - minor fix.
#
# Revision 1.8 1994/09/07 20:59:15 mcn
# Revamped GetVar, modified scripts for new GetVar.
#
# Revision 1.7 1994/09/02 20:58:00 mcn
# minor change.
#
# Revision 1.6 1994/08/21 00:56:41 mcn
# New Stuff
#
# Revision 1.5 1994/08/02 18:36:29 mcn
# Support new configuration.
#
# Revision 1.4 1994/07/14 22:13:32 mcn
# Now include SDR Makefile/Headers
#
#
EPICS=${1};
if [ ! -d include -o ! -d src ]; then
echo "Cannot find src or include, are you at the top of EPICS base ?"
exit 1
fi
cd $EPICS/base
FULLY_BUILT=NO
if [ "${2}" = "-b" ]; then
FULLY_BUILT=YES
shift
fi
# Retrieve EPICS release string from include/epicsVersion.h
grep EPICS_VERSION_STRING include/epicsVersion.h > /dev/null 2>&1 || ERR=1;
if [ "$ERR" = "1" ];
then
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
exit 1;
fi
RELS=`grep "EPICS_VERSION_STRING" include/epicsVersion.h \
| sed -e 's-.*Version--' \
-e 's-[ ][ ]*--g' \
-e 's-".*--' \
-e 's-\.0$--'`;
if [ -z "${RELS}" ];
then
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
exit 1;
fi
RELS="R${RELS}";
echo TOP: Creating ../${RELS}.Tar;
if [ -f ${RELS}.Tar* ];
then
echo "TOP: This release has already been created.";
echo "TOP: Remove Tar file or edit include/epicsVersion.h.";
exit 1;
fi
# Create list of files and dirs to include in Tar file
cd $EPICS
ls base/README* | xargs tar cvf ${RELS}.Tar
ls base/Makefile* > /tmp/make_release.out.$$;
find config base/include base/man base/tools -name CVS -prune -o \
! -type d -print >> /tmp/make_release.out.$$;
# binary / library / default.dctsdr / <rec>Record.h / etc.
if [ $FULLY_BUILT = "YES" ];
then
find base/bin -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
find base/lib -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
find base/rec -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
fi
find base/src -name CVS -prune -o -name SCCS -prune -o ! -type d -print \
| grep -v '/O\..*$' >> /tmp/make_release.out.$$
cat /tmp/make_release.out.$$ | xargs tar rvf ${RELS}.Tar
rm /tmp/make_release.out.$$

View File

@@ -12,6 +12,9 @@
# install because the release.% syntax is illegal.
#
# $Log$
# Revision 1.23 1995/02/13 15:00:09 jba
# Changed include file from CONFIG_SITE to CONFIG
#
# Revision 1.22 1994/11/14 23:12:17 tang
# Replace ARCH_TYPE with .
#
@@ -74,21 +77,27 @@ depends:
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
clean:
@(for ARCH in ${BUILD_ARCHS}; \
do \
ARCH_TYPE=$$ARCH \
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
uninstall:
@(for ARCH in ${BUILD_ARCHS}; \
do \
ARCH_TYPE=$$ARCH \
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
release:
@echo TOP: Creating Release...
@tools/MakeRelease
@./MakeRelease ${EPICS}
built_release: install
@echo TOP: Creating Fully Built Release...
@tools/MakeRelease -b
clean:
@echo "TOP: Cleaning"
@tools/Clean
uninstall:
rm -rf bin/* lib/* rec.bak
rm -f rec/default.dctsdr rec/default.sdrSum rec/*.h
@./MakeRelease ${EPICS} -b
# Notes for single architecture build rules:
# CheckArch only has to be run for dirs.% . That
@@ -107,20 +116,15 @@ uninstall:
# some things may be included on a per architecture
# basis.
dirs.%:
@tools/CheckArch $*
@echo $*: Creating Directories
@tools/MakeDirs $*
build.%: dirs.%
build.%:
@echo $*: Building
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs build
install.%: dirs.%
install.%:
@echo $*: Installing
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs install
depends.%: dirs.%
depends.%:
@echo $*: Performing Make Depends
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs depends
@@ -133,11 +137,10 @@ release.%:
@echo
uninstall.%:
@echo
@echo "The uninstall.arch syntax is not supported by this build."
@echo
@echo "TOP: Uninstalling $* "
@rm -rf ./bin/$* ./lib/$* rec.bak rec
clean.%:
@echo "$*: Cleaning"
@tools/Clean $*
@echo "TOP: Cleaning $* "
@find src -type d -name "O.$*" -prune -exec rm -rf {} \;

View File

@@ -5,6 +5,9 @@
# by Matthew Needes and Mike Bordua
#
# $Log$
# Revision 1.13 1994/09/09 17:32:29 jba
# Cleanup of files
#
# Revision 1.12 1994/09/08 17:25:41 mcn
# Changed clean to tools/Clean. Added "uninstall" dependency.
#
@@ -27,7 +30,7 @@ include $(EPICS)/config/CONFIG_BASE
all: build
build:
build: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -35,7 +38,7 @@ build:
cd $$TMP; \
done)
install:
install: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -43,7 +46,7 @@ install:
cd $$TMP; \
done)
depends:
depends: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -51,3 +54,23 @@ depends:
cd $$TMP; \
done)
dirs:
@echo ${T_A}: Creating Directories
@for DIR in ${DIRS}; \
do \
TMP=`pwd`; \
cd $$DIR ; \
if [ -f Makefile.${BUILD_TYPE} ] ; then \
test -d O.${T_A} || \
mkdir O.${T_A}; \
test -f O.${T_A}/Makefile || \
ln -s ../Makefile.${BUILD_TYPE} O.${T_A}/Makefile \
> /dev/null 2> /dev/null; \
test -f O.${T_A}/Target.include || \
echo "T_A=${T_A}" > O.${T_A}/Target.include; \
test -f O.${T_A}/.DEPENDS || \
touch O.${T_A}/.DEPENDS; \
fi ; \
cd $$TMP; \
done

2
README
View File

@@ -74,7 +74,7 @@ gmake
be complete before this can be issued).
NOTES:
1. tools/MakeRelease will create tar files in the directory ABOVE
1. base/MakeRelease will create tar files in the directory ABOVE
base. These tar files are then meant to be untarred at that level.
This release will include the "epics/config" directory.

View File

@@ -5,8 +5,8 @@ include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
SRCS.c = ../asDbLib.c ../asCa.c asLib.c
OBJS = asDbLib.o asCa.o asLib.o
PROD = asLibrary
LIBOBJS = asDbLib.o asCa.o asLib.o
LIBNAME = asLibrary
include $(EPICS)/config/RULES.Vx
@@ -18,7 +18,4 @@ asLib.o: asLib_lex.c ../asLibRoutines.c
clean::
@$(RM) asLib_lex.c asLib.c
asLibrary : $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -148,13 +148,16 @@ static long asInitCommon(void)
long status;
char buffer[BUF_SIZE];
if(!pacf) return(0);
if(asLockInit) {
FASTLOCKINIT(&asLock);
asLockInit = FALSE;
}
FASTLOCK(&asLock);
if(asActive)asCaStop();
if(!pacf) {
asActive = FALSE;
return(0);
}
buffer[0] = 0;
my_buffer = buffer;
my_buffer_ptr = my_buffer;

View File

@@ -1,6 +1,6 @@
integer [0-9]
name [a-zA-Z0-9_\.]
pvname [a-zA-Z0-9_:\.\[\]<>;]
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$]
%{

18
src/bdt/Makefile Normal file
View File

@@ -0,0 +1,18 @@
#
# $Id$
#
# Base Lowest Level Directroy Makefile
# by Janet Anderson
#
# $Log$
# Revision 1.1 1994/09/07 19:26:22 jba
# New file
#
#
EPICS=../../..
include $(EPICS)/config/CONFIG_BASE
include $(EPICS)/config/RULES_ARCHS

10
src/bdt/Makefile.Unix Normal file
View File

@@ -0,0 +1,10 @@
EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
LIBOBJS += bdt.o
LIBNAME = libBdt.a
include $(EPICS)/config/RULES.Unix

21
src/bdt/Makefile.Vx Normal file
View File

@@ -0,0 +1,21 @@
EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
SRCS.c += ../bdt.c
SRCS.c += ../bdtServ.c
SRCS.c += ../bdtServName.c
SRCS.c += ../bdtServPv.c
OBJS += bdt.o
OBJS += bdtServ.o
OBJS += bdtServName.o
OBJS += bdtServPv.o
PROD = bdt
include $(EPICS)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

701
src/bdt/bdt.c Normal file
View File

@@ -0,0 +1,701 @@
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef linux
#include <sys/resource.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <selectLib.h>
#else
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include "bdt.h"
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#ifdef linux
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BdtServerClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BdtMakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#ifdef linux
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* ------------------------------------------ */
/* unimplemented channel access open function */
/* ------------------------------------------ */
BDT* BdtPvOpen(char *IocName, char* PvName)
{
BDT *bdt;
if((bdt = BdtIpOpen(IocName, BDT_TCP_PORT)) == NULL)
{
fprintf(stderr,"open of address %s failed\n", IocName);
return(NULL);
}
if(BdtServiceConnect(bdt, BDT_SERVICE_PV, PvName) < 0)
{
fprintf(stderr,"connect to PV %s failed\n", PvName);
BdtClose(bdt);
return(NULL);
}
return(bdt);
}
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BDT* BdtIpOpen(char* address, int Port)
{
struct hostent *pHostent;
struct sockaddr_in tsin;
unsigned long addr;
int osoc;
BDT *bdt;
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(address[0]))
#endif
addr=inet_addr(address);
#ifndef vxWorks
else
{
if ((pHostent = gethostbyname (address)) == NULL)
return(NULL);
bcopy (pHostent->h_addr, (char *) &addr, sizeof(addr));
printf("Converting name >%s< to IP number %08.8X\n", address, addr);
}
#endif
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtIpOpen: create socket failed");
return (BDT*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtIpOpen: local address bind failed");
return (BDT*)NULL;
}
tsin.sin_port=htons(Port);
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
{
perror("BdtIpOpen: connect failed");
close(osoc);
return (BDT*)NULL;
}
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=osoc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtUnbound;
#ifndef vxWorks
{
int j;
j = fcntl(bdt->soc, F_GETFL, 0);
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
}
#endif
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BdtWrite(int soc,void* buffer,int size)
{
int rc;
int total;
unsigned char* data;
fd_set fds;
struct timeval to;
data=(unsigned char*)buffer;
total=size;
to.tv_sec = 5;
to.tv_usec = 0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, NULL, &fds, NULL, &to) != 1)
{
printf("BdtWrite: timeout waiting to write data\n");
return(-1);
}
/* send block of data */
if((rc=send(soc,&data[size-total],total,0))<0)
{
if(errno == EINTR)
rc = 0;
else
perror("BdtWrite: Send to remote failed");
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BDT socket */
/* --------------------------------------- */
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
{
BdtMsgHead buf;
if(bdt->state!=BdtIdle)
{
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BdtSData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BDT socket */
/* ------------------------------------------- */
int BdtSendData(BDT* bdt,void* buffer,int size)
{
int len;
int remaining;
int rc;
if(bdt->state!=BdtSData)
{
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
bdt->state=BdtBad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"WARNING -- BdtSendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
if (BdtWrite(bdt->soc, buffer, len) < 0)
return -1;
bdt->remaining_send-=len;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BdtSendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BdtIdle;
return len;
}
int BdtFlushOutput(BDT* bdt)
{
#ifdef vxWorks
ioctl(bdt->soc, FIOWFLUSH, 0);
#endif
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BdtRead(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
fd_set fds;
struct timeval to;
to.tv_sec = 5;
to.tv_usec = 0;
data=(unsigned char*)buffer;
total=size;
do
{
#if 1
/* wait for data chunk */
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
{
printf("BdtRead: timeout waiting for data\n");
return(-1);
}
#endif
if((rc=recv(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
{
printf("BdtRead: EINTR");
rc=0;
}
else
{
perror("BdtRead: Receive data chunk failed");
}
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
{
BdtMsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BdtEof)
return -1;
if(bdt->state != BdtIdle)
{
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BdtRData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BdtReceiveData(BDT* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BdtRData: break;
case BdtIdle: return 0;
default:
fprintf(stderr,"BdtReceiveData: bad receive state\n");
bdt->state=BdtBad;
break;
}
if (bdt->remaining_recv < size)
size = bdt->remaining_recv;
if(BdtRead(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BdtReceiveData: Read failed\n");
bdt->state = BdtEof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BdtReceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BdtIdle;
return size;
}
/* ------------------------------------------------------ */
/* connect to a process variable, useful if raw open used */
/* ------------------------------------------------------ */
int BdtServiceConnect(BDT* bdt, char* Name, char *Args)
{
int len;
int rc;
int size;
int verb;
unsigned char NameLen;
unsigned char ArgLen;
if(bdt->state!=BdtUnbound)
{
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
return -1;
}
bdt->state=BdtIdle;
NameLen = strlen(Name)+1;
if (Args != NULL)
ArgLen = strlen(Args)+1;
else
ArgLen = 0;
/* send out connect message */
if(BdtSendHeader(bdt, BDT_Connect, NameLen+ArgLen) < 0)
{
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
bdt->state=BdtUnbound;
return -1;
}
NameLen--;
ArgLen--;
/* send out the process variable to connect to */
if((BdtSendData(bdt, &NameLen, 1) < 0) || (BdtSendData(bdt, Name, NameLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
if (ArgLen > 0)
{
if ((BdtSendData(bdt, &ArgLen, 1) < 0) || (BdtSendData(bdt, Args, ArgLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
}
rc=0;
/* wait for response from connect to process variable */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* check response */
switch(verb)
{
case BDT_Ok:
rc=0;
break;
case BDT_Error:
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
bdt->state=BdtUnbound;
rc=-1;
break;
default:
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
bdt->state=BdtUnbound;
rc=-1;
break;
}
return rc;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BdtClose(BDT* bdt)
{
int verb,size,done;
/* send a close message out */
if(BdtSendHeader(bdt,BDT_Close,0)<0)
{
fprintf(stderr,"BdtClose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtClose: Close message response error\n");
return -1;
}
switch(verb)
{
case BDT_Ok:
done=1;
break;
case BDT_Error:
fprintf(stderr,"BdtClose: Close rejected\n");
return -1;
break;
default: break;
}
}
while(done==0);
bdt->state=BdtUnbound;
free(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BdtOpenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
{
perror("BdtOpenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BdtOpenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset (&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtOpenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BDT from a socket - simple */
/* ------------------------------- */
BDT* BdtMakeBDT(int soc)
{
BDT* bdt;
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=soc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtIdle;
return bdt;
}
/* --------------------------- */
/* free a BDT and close socket */
/* --------------------------- */
int BdtFreeBDT(BDT* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements,
unsigned long ElementSize)
{
int Verb;
int Size;
unsigned long BufSize;
BufSize = NumElements * ElementSize;
if (BdtSendHeader(bdt, BDT_Put, 6 + BufSize) != 0)
return(-1);
if (BdtSendData(bdt, &DbrType, 2) < 0)
return(-1);
if (BdtSendData(bdt, &NumElements, 4) < 0)
return(-1);
if (BdtSendData(bdt, Buf, BufSize) < 0)
return(-1);
if (BdtReceiveHeader(bdt, &Verb, &Size) != 0)
return(-1);
if (Verb != BDT_Ok)
return(-1);
return(0);
}

392
src/bdt/bdtServ.c Normal file
View File

@@ -0,0 +1,392 @@
/*
*
* Author: John Winans
* Date: 95-05-22
*
* $Log$
*/
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <sysSymTbl.h>
#include <string.h>
#include "bdt.h"
#define BDT_TASK_PRIO 200
#define BDT_TASK_OPTIONS VX_FP_TASK
#define BDT_TASK_STACK 5000
#define STATIC static
/* used for debugging */
STATIC char *BdtNames[] = {
"BDT_Ok",
"BDT_Connect",
"BDT_Error",
"BDT_Get",
"BDT_Put",
"BDT_Close",
"BDT_Monitor",
"BDT_Value",
"BDT_Delta",
"BDT_Add",
"BDT_Delete",
"BDT_Ping"
};
STATIC int HexDump(char *ReadBuffer, int rbytes);
/*****************************************************************************
*
* A debugging routine that hex-dumps a message to the console.
*
*****************************************************************************/
void BDT_DumpMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
HexDump(Buf, RecvLen);
}
}
/*****************************************************************************
*
* Throw away a message.
*
****************************************************************************/
void BDT_DiscardMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
}
}
/*****************************************************************************
*
* Process a single Connect message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcessConnect(BDT *Bdt)
{
SYM_TYPE Type;
unsigned char length;
char Buf[50];
char HandlerName[70];
if (Bdt->remaining_recv > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message too long %d\n", Bdt->remaining_recv);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->remaining_recv < 2)
{
printf("BDT_ProcessConnect Connect Message w/missing service name\n");
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &length, 1);
if (length > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message service name too long %d\n", length);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, Buf, length);
Buf[length] = '\0';
sprintf(HandlerName, "_BDT_ServiceHandler_%s", Buf);
printf("BDT_ProcessConnect NAME service (%s)\n", HandlerName);
/*Bdt->pHandlers = (BdthandlerFunc *)(&BDT_NameServicehandlers);*/
if (symFindByName(sysSymTbl, HandlerName, (char **)&(Bdt->pHandlers), &Type) != OK)
{
printf("BDT_ProcessConnect Connect to unknown service (%s)\n", Buf);
BdtSendHeader(Bdt, BDT_Error, 0);
}
else
{
Bdt->Name = (char *)malloc(strlen(Buf)+1);
strcpy(Bdt->Name, Buf);
if (Bdt->pHandlers[BDT_Connect] != NULL)
return((*(Bdt->pHandlers[BDT_Connect]))(Bdt));
else
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
}
}
return(0);
}
/*****************************************************************************
*
* Process a single message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcMessage(BDT *Bdt, unsigned short Command)
{
int RecvLen;
if (Command > BDT_LAST_VERB)
{
printf("BDT: %s Invalid command %d, length = %d\n", Bdt->Name, Command, Bdt->remaining_recv);
BDT_DumpMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->pHandlers == NULL)
{
if (Command == BDT_Connect)
BDT_ProcessConnect(Bdt);
else
{
printf("BDT_ProcMessage: %s got %s before connect\n", Bdt->Name, BdtNames[Command]);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
}
return(0);
}
if (Bdt->pHandlers[Command] == NULL)
{
printf("BDT_ProcMessage: service %s got %s... invalid\n", Bdt->Name, BdtNames[Command]);
}
return((*(Bdt->pHandlers[Command]))(Bdt));
}
/*****************************************************************************
*
* Wait on a socket read for a message. When one arrives, read the header,
* decode it, and call the message handler routine to process and respond to it.
*
******************************************************************************/
STATIC void BDT_ReceiverTask(int Sock)
{
int Verb;
int Size;
BDT Bdt;
int MonitorLockTimeout = (BDT_PING_INTERVAL*sysClkRateGet())/2;
static char *NoBdtName = "(No Name)";
fd_set FdSet;
struct timeval TimeVal;
int PollStatus;
int SocketState;
Bdt.soc = Sock;
Bdt.pMonitor = NULL;
Bdt.WriteLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.MonitorLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.state = BdtIdle;
Bdt.pHandlers = NULL;
Bdt.Name = NoBdtName;
printf("BDT_ReceiverTask(%d) started\n", Sock);
TimeVal.tv_sec = BDT_CONENCTION_TIMEOUT;
TimeVal.tv_usec = 0;
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
SocketState = 0;
while (((PollStatus = select(FD_SETSIZE, &FdSet, NULL, NULL, &TimeVal)) > 0) && (BdtReceiveHeader(&Bdt, &Verb, &Size) == 0))
{
semTake(Bdt.WriteLock, WAIT_FOREVER);
SocketState = BDT_ProcMessage(&Bdt, Verb);
if (SocketState != 0)
break;
#if 0
if (semTake(Bdt.MonitorLock, MonitorLockTimeout) == OK)
{
/* Check for delta flag and send if so */
/* Change this to run thru a delta-message linked list */
if (Bdt.pMonitor != NULL)
{
/* Send delta notifier */
}
semGive(Bdt.WriteLock); /* Order important for BDT_SendDelta */
semGive(Bdt.MonitorLock);
}
else
{
printf("BDT_ReceiverTask timeout on monitor semaphore. Monitors are stuck!\n");
semGive(Bdt.WriteLock);
}
#else
semGive(Bdt.WriteLock);
#endif
BdtFlushOutput(&Bdt);
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
}
if (SocketState == 0)
{
if (PollStatus == 0)
printf("BDT_ReceiverTask(%d) exiting on client timeout\n", Sock);
else
printf("BDT_ReceiverTask(%d) exiting on I/O error talking to Client\n", Sock);
}
else
printf("BDT_ReceiverTask(%d) received close from client\n", Sock);
/* Free up resources */
if (Bdt.Name != NoBdtName)
free(Bdt.Name);
close(Sock);
semDelete(Bdt.WriteLock);
semDelete(Bdt.MonitorLock);
return;
}
/*****************************************************************************
*
******************************************************************************/
#if 0
int BDT_SendDelta(int Socket, char *Message)
{
semTake (DeltaFlagLock, WAIT_FOREVER);
if (if (semTake(SocketWriteLock, no wait) == failed)
{
/* Reader task is busy... Post message for future transmission */
Bdt.pending_delta = 1;
}
else
{
write(Message); /* This COULD block */
semGive(SocketWriteLock);
}
semGive(DeltaFlagLock);
return (0);
}
#endif
/*****************************************************************************
*
* This task listens on a port for new connections. When one is made, it
* spawns a task to manage it.
*
******************************************************************************/
void BDT_ListenerTask(int Port)
{
/* Open a socket to listen on */
struct sockaddr_in ListenerAddr;
struct sockaddr_in ClientAddr;
int ListenerSock;
int ClientSock;
int ClientAddrLen;
int SockAddrSize = sizeof(struct sockaddr_in);
if (Port == 0)
Port = BDT_TCP_PORT;
printf("BDT_Listener(%d) started\n", Port);
if ((ListenerSock = BdtOpenListenerTCP(Port)) < 0)
{
printf("BDT_ListenerTask(%d) can't start listener\n", Port);
return;
}
while (1)
{
ClientAddrLen = sizeof(ClientAddr);
if((ClientSock = accept(ListenerSock, (struct sockaddr*)&ClientAddr, &ClientAddrLen)) < 0)
{
if(errno!=EINTR)
{
printf("BDT_ListenerTask(%d) accept() failed\n", Port);
}
}
else
{
/* Spawn a task to handle the new connection */
printf("Accepted a connection\n");
taskSpawn("BDT", BDT_TASK_PRIO, BDT_TASK_OPTIONS, BDT_TASK_STACK, (FUNCPTR)BDT_ReceiverTask, ClientSock, 2,3,4,5,6,7,8,9,0);
}
}
/* Never reached */
}
/*****************************************************************************
*
* A handy routine to assist in debugging.
*
******************************************************************************/
STATIC int HexDump(char *ReadBuffer, int rbytes)
{
int c = 0;
int i = 0;
int firsttime;
char ascii[20]; /* To hold printable portion of string */
if (!rbytes)
return(0);
firsttime = 1;
while(c < rbytes)
{
if ((c % 16) == 0)
{
if (!firsttime)
{
ascii[i] = '\0';
printf(" *%s*\n", ascii);
}
firsttime=0;
i = 0;
}
printf(" %02.2X", ReadBuffer[c] & 0xff);
ascii[i] = ReadBuffer[c];
if (!isprint(ascii[i]))
ascii[i] = '.';
++i;
++c;
}
while (c%16)
{
fputs(" ", stdout);
++c;
}
ascii[i] = '\0';
printf(" *%s*\n", ascii);
return(0);
}

129
src/bdt/bdtServName.c Normal file
View File

@@ -0,0 +1,129 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
*****************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include "bdt.h"
#define STATIC static
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceOk(BDT *Bdt)
{
printf("BDT_NameServiceOk \n");
return(0);
}
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceConnect(BDT *Bdt)
{
printf("BDT_NameServiceConnect \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceError(BDT *Bdt)
{
printf("BDT_NameServiceError \n");
return(0);
}
STATIC int BDT_NameServiceGet(BDT *Bdt)
{
printf("BDT_NameServiceGet \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePut(BDT *Bdt)
{
printf("BDT_NameServicePut \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceClose(BDT *Bdt)
{
printf("BDT_NameServiceClose \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceMonitor(BDT *Bdt)
{
printf("BDT_NameServiceMonitor \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceValue(BDT *Bdt)
{
printf("BDT_NameServiceValue \n");
return(0);
}
STATIC int BDT_NameServiceDelta(BDT *Bdt)
{
printf("BDT_NameServiceDelta \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceAdd(BDT *Bdt)
{
printf("BDT_NameServiceAdd \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceDelete(BDT *Bdt)
{
printf("BDT_NameServiceDelete \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePing(BDT *Bdt)
{
printf("BDT_NameServicePing \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_name =
{
BDT_NameServiceOk,
BDT_NameServiceConnect,
BDT_NameServiceError,
BDT_NameServiceGet,
BDT_NameServicePut,
BDT_NameServiceClose,
BDT_NameServiceMonitor,
BDT_NameServiceValue,
BDT_NameServiceDelta,
BDT_NameServiceAdd,
BDT_NameServiceDelete,
BDT_NameServicePing
};

377
src/bdt/bdtServPv.c Normal file
View File

@@ -0,0 +1,377 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
******************************************************************************/
#include <vxWorks.h>
#include <semLib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <dbCommon.h>
#include <dbAccess.h>
#include "bdt.h"
#define STATIC static
#define MESSAGE_PREFIX "BDT PV server:"
/*****************************************************************************
*
* These conversion finctions take care of one of the most insane parts
* of dealing with database access... having two different interfaces that
* have the same named enumerators in two seperate header files... that
* therefore can not be both included in the same file.
*
* This is so bad, I wanted to vomit when typing it in.
*
******************************************************************************/
STATIC int DbrOld2New(int Old)
{
switch (Old)
{
case 0: return(DBR_STRING);
case 1: return(DBR_SHORT);
case 2: return(DBR_FLOAT);
case 3: return(DBR_ENUM);
case 4: return(DBR_CHAR);
case 5: return(DBR_LONG);
case 6: return(DBR_DOUBLE);
default:
return(-1);
}
}
STATIC int DbrNew2Old(int New)
{
switch (New)
{
case DBR_STRING: return(0);
case DBR_CHAR: return(4);
case DBR_UCHAR: return(4);
case DBR_SHORT: return(1);
case DBR_USHORT: return(1);
case DBR_LONG: return(5);
case DBR_ULONG: return(5);
case DBR_FLOAT: return(2);
case DBR_DOUBLE: return(6);
case DBR_ENUM: return(3);
default:
return(-1);
}
}
/*****************************************************************************
*
* Handle the receipt of an OK message.
*
* The OK message is received as a confirmation of the last operation. It is
* not normally responded to.
*
*****************************************************************************/
STATIC int BDT_ServiceOk(BDT *Bdt)
{
printf("%s got a Ok message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Connect message.
*
* The Connect is received when a new connection is first made.
* Any arguments left in the message body have not yet been read.
*
*****************************************************************************/
STATIC int BDT_ServiceConnect(BDT *Bdt)
{
unsigned char Length;
char Buf[100];
struct dbAddr *pDbAddr;
Buf[0] = '\0';
if (Bdt->remaining_recv > 0)
{
BdtReceiveData(Bdt, &Length, 1);
if (Length <= sizeof(Buf))
{
BdtReceiveData(Bdt, Buf, Length);
Buf[Length] = '\0';
}
else
{
printf("%s Connect message argument list too long\n", MESSAGE_PREFIX);
BDT_DiscardMessage(Bdt);
return(-1);
}
}
#ifdef DEBUG_VERBOSE
printf("%s got Connect >%s<\n", MESSAGE_PREFIX, Buf);
#endif
/* Find the PV in the database */
Bdt->pService = malloc(sizeof(struct dbAddr));
pDbAddr = (struct dbAddr *)(Bdt->pService);
if (dbNameToAddr(Buf, pDbAddr))
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
{
if (pDbAddr->dbr_field_type != pDbAddr->field_type)
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
BdtSendHeader(Bdt, BDT_Ok, 0);
}
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Error message.
*
*****************************************************************************/
STATIC int BDT_ServiceError(BDT *Bdt)
{
printf("%s got a Error message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Get message.
*
* The response to a Get message is either an Error or a Value:
*
* Value message body format:
* SHORT EPICS data type enumerator (in old format)
* LONG Number of elements
* CHAR[] Value image
*
*
*****************************************************************************/
STATIC int BDT_ServiceGet(BDT *Bdt)
{
void *Buf;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
long NumElements;
long Size;
long l;
short OldType;
int stat;
#ifdef DEBUG_VERBOSE
printf("%s got a Get message\n", MESSAGE_PREFIX);
printf("field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
#endif
OldType = DbrNew2Old(pDbAddr->field_type);
if (OldType < 0)
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Allocate a buffer to hold the response message data */
Buf = malloc(pDbAddr->field_size * pDbAddr->no_elements);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for get request to %s\n",
pDbAddr->field_size * pDbAddr->no_elements,
pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Get the response message data */
NumElements = pDbAddr->no_elements;
if (stat=dbGetField(pDbAddr, pDbAddr->field_type, Buf, 0, &NumElements, NULL))
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
#if 0
/* Test hack to transfer HUGE buffers */
NumElements = pDbAddr->no_elements;
#endif
/* Send the response message */
Size = NumElements * pDbAddr->field_size;
BdtSendHeader(Bdt, BDT_Value, Size + sizeof(long) + sizeof(short));
BdtSendData(Bdt, &OldType, sizeof(short));
BdtSendData(Bdt, &NumElements, sizeof(long));
if (Size)
BdtSendData(Bdt, Buf, Size);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Put message.
*
* Put message body format:
* SHORT EPICS data type enumerator
* LONG Number of elements
* CHAR[] Value image
*
*****************************************************************************/
STATIC int BDT_ServicePut(BDT *Bdt)
{
long Size;
void *Buf;
short DbrType;
long NumElements;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
#ifdef DEBUG_VERBOSE
printf("%s got a Put message\n", MESSAGE_PREFIX);
#endif
if (BdtGetResidualRead(Bdt) < 6)
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (BdtGetResidualRead(Bdt) == 6)
{ /* Do data contents, just toss it */
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
Buf = malloc(BdtGetResidualRead(Bdt) - 6);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for put request to %s\n",
BdtGetResidualRead(Bdt), pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &DbrType, 2);
BdtReceiveData(Bdt, &NumElements, 4);
#ifdef DEBUG_VERBOSE
printf("record field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
printf("message field type=%d, field size=%d, elements=%d total %d\n", DbrType, pDbAddr->field_type ,NumElements, BdtGetResidualRead(Bdt));
#endif
BdtReceiveData(Bdt, Buf, BdtGetResidualRead(Bdt));
DbrType = DbrOld2New(DbrType);
if (DbrType < 0)
BdtSendHeader(Bdt, BDT_Error, 0);
else if (dbPutField(pDbAddr, DbrType, Buf, NumElements))
BdtSendHeader(Bdt, BDT_Error, 0);
else
BdtSendHeader(Bdt, BDT_Ok, 0);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Close message.
*
*****************************************************************************/
STATIC int BDT_ServiceClose(BDT *Bdt)
{
printf("%s got a Close message\n", MESSAGE_PREFIX);
free(Bdt->pService);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(1);
}
/*****************************************************************************
*
* Handle the receipt of a Monitor message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceMonitor(BDT *Bdt)
{
printf("%s got a Monitor message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Value message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceValue(BDT *Bdt)
{
printf("%s got a Value message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delta message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelta(BDT *Bdt)
{
printf("%s got a Delta message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Add message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceAdd(BDT *Bdt)
{
printf("%s got a Add message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delete message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelete(BDT *Bdt)
{
printf("%s got a Delete message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Ping message.
*
*****************************************************************************/
STATIC int BDT_ServicePing(BDT *Bdt)
{
printf("%s got a Ping message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_pv =
{
BDT_ServiceOk,
BDT_ServiceConnect,
BDT_ServiceError,
BDT_ServiceGet,
BDT_ServicePut,
BDT_ServiceClose,
BDT_ServiceMonitor,
BDT_ServiceValue,
BDT_ServiceDelta,
BDT_ServiceAdd,
BDT_ServiceDelete,
BDT_ServicePing
};

View File

@@ -5,11 +5,10 @@ $!
$! Purpose : To build the CHANNEL_ACCESS library and test programs for
$! VAX/VMS. This procedure assumes the following:
$! - You have copied *.c and *.h from the Epics channel access
$! source directory (.../src/ca) into this VMS directory
$! - You have copied envSubr.c, ellLib.c, and bucketLib.c
$! from the Epics
$! source directory (base/src/ca) into this VMS directory
$! - You have copied *.c and *.h from the Epics
$! libCom directory into this VMS directory
$! - You have copied *.h from the /src/epicsH directory into this
$! - You have copied *.h from the base/include directory into this
$! VMS directory
$! - You are using Multinet for TCP/IP access. If not, the logical
$! name definitions below will need to be changed

View File

@@ -34,13 +34,7 @@ include $(EPICS)/config/RULES.Unix
acctst: acctst.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
acctst.o: ../acctst.c
$(COMPILE.c) $<
catime: catime.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
catime.o: ../catime.c
$(COMPILE.c) $<

View File

@@ -8,21 +8,11 @@ SRCS.c = \
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c \
../catime.c
OBJS = \
LIBOBJS = \
iocinf.o access.o test_event.o service.o flow_control.o \
repeater.o conn.o syncgrp.o if_depen.o bsd_depen.o vxWorks_depen.o
PROD = caLib
LIBNAME = caLib
include $(EPICS)/config/RULES.Vx
caLib: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)
acctst.o: ../acctst.c
$(COMPILE.c) $<
catime.o: ../catime.c
$(COMPILE.c) $<

View File

@@ -92,7 +92,24 @@
/* 011394 joh fixed bucketLib level memory leak (vxWorks) */
/* 020494 joh Added user name protocol */
/* 022294 joh fixed recv task id verify at exit (vxWorks) */
/* */
/* 072895 joh fixed problem resulting from unsigned long */
/* tv_sec var in struct timeval in sys/time.h */
/* under HPUX */
/************************************************************************/
/*
* $Log$
* Revision 1.74 1995/08/22 00:12:07 jhill
* *** empty log message ***
*
* Revision 1.73 1995/08/14 19:26:10 jhill
* epicsAPI => epicsShareAPI
*
* Revision 1.72 1995/08/12 00:23:32 jhill
* check for res id in use, epicsEntry, dont wait for itsy bitsy delay
* in ca_pend_event(), better clean up when monitor is deleted and
* we are disconnected
*
*/
/*_begin */
/************************************************************************/
/* */
@@ -443,7 +460,7 @@ LOCAL void cac_add_msg (IIU *piiu)
/*
* CA_TASK_INITIALIZE
*/
int APIENTRY ca_task_initialize(void)
int epicsShareAPI ca_task_initialize(void)
{
int status;
struct ca_static *ca_temp;
@@ -566,6 +583,7 @@ LOCAL void create_udp_fd()
status = create_net_chan(
&ca_static->ca_piiuCast,
NULL,
ca_static->ca_server_port,
IPPROTO_UDP);
if (~status & CA_M_SUCCESS) {
ca_static->ca_piiuCast = NULL;
@@ -620,7 +638,7 @@ LOCAL void create_udp_fd()
* Modify or override the default
* client host name.
*/
int APIENTRY ca_modify_host_name(char *pHostName)
int epicsShareAPI ca_modify_host_name(char *pHostName)
{
char *pTmp;
unsigned size;
@@ -675,7 +693,7 @@ int APIENTRY ca_modify_host_name(char *pHostName)
* Modify or override the default
* client user name.
*/
int APIENTRY ca_modify_user_name(char *pClientName)
int epicsShareAPI ca_modify_user_name(char *pClientName)
{
char *pTmp;
unsigned size;
@@ -730,7 +748,7 @@ int APIENTRY ca_modify_user_name(char *pClientName)
* call this routine if you wish to free resources prior to task
* exit- ca_task_exit() is also executed routinely at task exit.
*/
int APIENTRY ca_task_exit (void)
int epicsShareAPI ca_task_exit (void)
{
/*
* This indirectly calls ca_process_exit() below
@@ -858,10 +876,10 @@ void ca_process_exit()
/*
* free hash tables
*/
status = bucketFree(ca_static->ca_pSlowBucket);
assert(status == BUCKET_SUCCESS);
status = bucketFree(ca_static->ca_pFastBucket);
assert(status == BUCKET_SUCCESS);
status = bucketFree (ca_static->ca_pSlowBucket);
assert (status == S_bucket_success);
status = bucketFree (ca_static->ca_pFastBucket);
assert (status == S_bucket_success);
/*
* free beacon hash table
@@ -880,7 +898,7 @@ void ca_process_exit()
*
* backwards compatible entry point to ca_search_and_connect()
*/
int APIENTRY ca_build_and_connect
int epicsShareAPI ca_build_and_connect
(
char *name_str,
chtype get_type,
@@ -905,7 +923,7 @@ int APIENTRY ca_build_and_connect
*
*
*/
int APIENTRY ca_search_and_connect
int epicsShareAPI ca_search_and_connect
(
char *name_str,
chid *chixptr,
@@ -1010,13 +1028,20 @@ int APIENTRY ca_search_and_connect
}
LOCK;
chix->cid = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId(pSlowBucket, &chix->cid, chix);
if(status != BUCKET_SUCCESS){
do {
chix->cid = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId (pSlowBucket,
&chix->cid, chix);
} while (status == S_bucket_idInUse);
if (status != S_bucket_success) {
*chixptr = (chid) NULL;
free((char *) chix);
UNLOCK;
return ECA_ALLOCMEM;
if (status == S_bucket_noMemory) {
return ECA_ALLOCMEM;
}
return ECA_INTERNAL;
}
chix->puser = puser;
@@ -1127,7 +1152,7 @@ int reply_type
*
*
*/
int APIENTRY ca_array_get
int epicsShareAPI ca_array_get
(
chtype type,
unsigned long count,
@@ -1195,8 +1220,10 @@ void *pvalue
}
else {
LOCK;
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
}
UNLOCK;
}
}
@@ -1212,7 +1239,7 @@ void *pvalue
/*
* CA_ARRAY_GET_CALLBACK()
*/
int APIENTRY ca_array_get_callback
int epicsShareAPI ca_array_get_callback
(
chtype type,
unsigned long count,
@@ -1273,8 +1300,10 @@ void *arg
status = issue_get_callback (monix, IOC_READ_NOTIFY);
if (status != ECA_NORMAL) {
LOCK;
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
}
UNLOCK;
}
}
@@ -1305,12 +1334,15 @@ LOCAL evid caIOBlockCreate(void)
}
if (pIOBlock) {
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
status = bucketAddItemUnsignedId(
pFastBucket,
&pIOBlock->id,
pIOBlock);
if(status != BUCKET_SUCCESS){
do {
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
status = bucketAddItemUnsignedId(
pFastBucket,
&pIOBlock->id,
pIOBlock);
} while (status == S_bucket_idInUse);
if(status != S_bucket_success){
free(pIOBlock);
pIOBlock = NULL;
}
@@ -1333,7 +1365,7 @@ void caIOBlockFree(evid pIOBlock)
status = bucketRemoveItemUnsignedId(
ca_static->ca_pFastBucket,
&pIOBlock->id);
assert (status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
pIOBlock->id = ~0U; /* this id always invalid */
ellAdd (&free_event_list, &pIOBlock->node);
UNLOCK;
@@ -1433,7 +1465,7 @@ LOCAL int issue_get_callback(evid monix, unsigned cmmd)
* CA_ARRAY_PUT_CALLBACK()
*
*/
int APIENTRY ca_array_put_callback
int epicsShareAPI ca_array_put_callback
(
chtype type,
unsigned long count,
@@ -1537,7 +1569,7 @@ void *usrarg
}
status = dbPutNotify(&ppn->dbPutNotify);
UNLOCK;
if(status){
if(status && status != S_db_Pending){
if(status==S_db_Blocked){
return ECA_PUTCBINPROG;
}
@@ -1577,8 +1609,10 @@ void *usrarg
pvalue);
if(status != ECA_NORMAL){
LOCK;
ellDelete (&pend_write_list, &monix->node);
caIOBlockFree(monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_write_list, &monix->node);
caIOBlockFree(monix);
}
UNLOCK;
return status;
}
@@ -1642,7 +1676,7 @@ LOCAL void ca_put_notify_action(PUTNOTIFY *ppn)
*
*
*/
int APIENTRY ca_array_put (
int epicsShareAPI ca_array_put (
chtype type,
unsigned long count,
chid chix,
@@ -1883,7 +1917,7 @@ LOCAL void free_put_convert(void *pBuf)
* Specify an event subroutine to be run for connection events
*
*/
int APIENTRY ca_change_connection_event
int epicsShareAPI ca_change_connection_event
(
chid chix,
void (*pfunc)(struct connection_handler_args)
@@ -1915,7 +1949,7 @@ void (*pfunc)(struct connection_handler_args)
/*
* ca_replace_access_rights_event
*/
int APIENTRY ca_replace_access_rights_event(
int epicsShareAPI ca_replace_access_rights_event(
chid chan,
void (*pfunc)(struct access_rights_handler_args))
{
@@ -1943,7 +1977,7 @@ void (*pfunc)(struct access_rights_handler_args))
* Specify an event subroutine to be run for asynch exceptions
*
*/
int APIENTRY ca_add_exception_event
int epicsShareAPI ca_add_exception_event
(
void (*pfunc)(struct exception_handler_args),
void *arg
@@ -1975,7 +2009,7 @@ void *arg
* Undocumented entry for the VAX OPI which may vanish in the future.
*
*/
int APIENTRY ca_add_io_event
int epicsShareAPI ca_add_io_event
(
void (*ast)(),
void *astarg
@@ -2010,7 +2044,7 @@ void *astarg
*
*
*/
int APIENTRY ca_add_masked_array_event
int epicsShareAPI ca_add_masked_array_event
(
chtype type,
unsigned long count,
@@ -2140,8 +2174,10 @@ long mask
status = ca_request_event(monix);
if (status != ECA_NORMAL) {
LOCK;
ellDelete (&chix->eventq, &monix->node);
caIOBlockFree(monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&chix->eventq, &monix->node);
caIOBlockFree(monix);
}
UNLOCK
}
return status;
@@ -2373,7 +2409,7 @@ void *pfl
* after leaving this routine.
*
*/
int APIENTRY ca_clear_event (evid monix)
int epicsShareAPI ca_clear_event (evid monix)
{
int status;
chid chix = monix->chan;
@@ -2448,6 +2484,7 @@ int APIENTRY ca_clear_event (evid monix)
else{
LOCK;
ellDelete(&monix->chan->eventq, &monix->node);
caIOBlockFree(monix);
UNLOCK;
status = ECA_NORMAL;
}
@@ -2471,7 +2508,7 @@ int APIENTRY ca_clear_event (evid monix)
* (from this source) after leaving this routine.
*
*/
int APIENTRY ca_clear_channel (chid chix)
int epicsShareAPI ca_clear_channel (chid chix)
{
int status;
evid monix;
@@ -2614,7 +2651,7 @@ void clearChannelResources(unsigned id)
ellDelete (&piiu->chidlist, &chix->node);
status = bucketRemoveItemUnsignedId (
ca_static->ca_pSlowBucket, &chix->cid);
assert (status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
free (chix);
if (piiu!=piiuCast && !piiu->chidlist.count){
TAG_CONN_DOWN(piiu);
@@ -2633,7 +2670,7 @@ void clearChannelResources(unsigned id)
/* IO completes. */
/* ca_flush_io() is called by this routine. */
/************************************************************************/
int APIENTRY ca_pend(ca_real timeout, int early)
int epicsShareAPI ca_pend (ca_real timeout, int early)
{
struct timeval beg_time;
ca_real delay;
@@ -2648,13 +2685,12 @@ int APIENTRY ca_pend(ca_real timeout, int early)
return ECA_EVDISALLOW;
}
cac_gettimeval (&ca_static->currentTime);
/*
* Flush the send buffers
* (guarantees that we wait for all send buffer to be
* flushed even if this requires blocking)
*
* Also takes care of outstanding recvs
* for single threaded clients
*/
ca_flush_io();
@@ -2662,10 +2698,6 @@ int APIENTRY ca_pend(ca_real timeout, int early)
return ECA_NORMAL;
}
/*
* the current time set iderectly within ca_flush_io()
* above.
*/
beg_time = ca_static->currentTime;
delay = 0.0;
while(TRUE){
@@ -2681,29 +2713,46 @@ int APIENTRY ca_pend(ca_real timeout, int early)
}
else{
remaining = timeout-delay;
if(remaining<=0.0){
if(early){
ca_pend_io_cleanup();
}
ca_flush_io();
return ECA_TIMEOUT;
}
/*
* Allow for CA background labor
*/
remaining = min(SELECT_POLL, remaining);
}
tmo.tv_sec = (long) remaining;
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_io_completion(&tmo);
/*
* the current time set within cac_block_for_io_completion()
* above.
* If we are no longer waiting any significant
* delay then return
* (dont wait forever for an itsy bitsy
* delay which will no be updated if
* select is called with no delay)
*
* current time is only updated by
* cac_select_io() if we specify
* at least 1 usec to wait
*
*/
if (remaining <= (1.0/USEC_PER_SEC)) {
if(early){
ca_pend_io_cleanup();
ca_flush_io();
}
/*
* be certain that we processed
* recv backlog at least once
*/
tmo.tv_sec = 0L;
tmo.tv_usec = 0L;
cac_block_for_io_completion (&tmo);
return ECA_TIMEOUT;
}
tmo.tv_sec = (long) remaining;
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_io_completion (&tmo);
if (timeout != 0.0) {
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
delay = cac_time_diff (&ca_static->currentTime,
&beg_time);
}
}
}
@@ -2714,20 +2763,31 @@ int APIENTRY ca_pend(ca_real timeout, int early)
*/
ca_real cac_time_diff (ca_time *pTVA, ca_time *pTVB)
{
ca_real delay;
ca_real delay;
ca_real udelay;
if(pTVA->tv_usec>pTVB->tv_usec){
delay = pTVA->tv_sec - pTVB->tv_sec;
delay += (pTVA->tv_usec - pTVB->tv_usec) /
(ca_real)(USEC_PER_SEC);
}
else{
delay = pTVA->tv_sec - pTVB->tv_sec - 1L;
delay += (USEC_PER_SEC - pTVB->tv_usec + pTVA->tv_usec) /
(ca_real)(USEC_PER_SEC);
}
/*
* works with unsigned tv_sec in struct timeval
* under HPUX
*/
if (pTVA->tv_sec>pTVB->tv_sec) {
delay = pTVA->tv_sec - pTVB->tv_sec;
}
else {
delay = pTVB->tv_sec - pTVA->tv_sec;
delay = -delay;
}
return delay;
if(pTVA->tv_usec>pTVB->tv_usec){
udelay = pTVA->tv_usec - pTVB->tv_usec;
}
else{
delay -= 1.0;
udelay = (USEC_PER_SEC - pTVB->tv_usec) + pTVA->tv_usec;
}
delay += udelay / USEC_PER_SEC;
return delay;
}
@@ -2791,28 +2851,19 @@ LOCAL void ca_pend_io_cleanup()
/*
* CA_FLUSH_IO()
*
* Flush the send buffer
* flush the send buffer
*
*/
int APIENTRY ca_flush_io()
int epicsShareAPI ca_flush_io()
{
struct ioc_in_use *piiu;
struct timeval timeout;
int pending;
unsigned long bytesPending;
INITCHK;
pending = TRUE;
timeout.tv_usec = 0;
timeout.tv_sec = 0;
while(pending){
/*
* perform socket io
* and process recv backlog
*/
cac_mux_io(&timeout);
while (TRUE) {
int pending;
/*
* wait for all buffers to flush
@@ -2837,7 +2888,16 @@ int APIENTRY ca_flush_io()
}
UNLOCK;
if (!pending) {
break;
}
/*
* perform socket io
* and process recv backlog
*/
LD_CA_TIME (SELECT_POLL, &timeout);
cac_mux_io (&timeout);
}
return ECA_NORMAL;
@@ -2848,7 +2908,7 @@ int APIENTRY ca_flush_io()
* CA_TEST_IO ()
*
*/
int APIENTRY ca_test_io()
int epicsShareAPI ca_test_io()
{
if(pndrecvcnt<1){
return ECA_IODONE;
@@ -2864,7 +2924,7 @@ int APIENTRY ca_test_io()
*
*
*/
void APIENTRY ca_signal(long ca_status,char *message)
void epicsShareAPI ca_signal(long ca_status,char *message)
{
ca_signal_with_file_and_lineno(ca_status, message, NULL, 0);
}
@@ -2873,7 +2933,7 @@ void APIENTRY ca_signal(long ca_status,char *message)
/*
* ca_signal_with_file_and_lineno()
*/
void APIENTRY ca_signal_with_file_and_lineno(
void epicsShareAPI ca_signal_with_file_and_lineno(
long ca_status,
char *message,
char *pfilenm,
@@ -3236,7 +3296,7 @@ LOCAL void ca_default_exception_handler(struct exception_handler_args args)
* (for a manager of the select system call under UNIX)
*
*/
int APIENTRY ca_add_fd_registration(CAFDHANDLER *func, void *arg)
int epicsShareAPI ca_add_fd_registration(CAFDHANDLER *func, void *arg)
{
fd_register_func = func;
fd_register_arg = arg;
@@ -3267,7 +3327,7 @@ int ca_defunct()
* currently implemented as a function
* (may be implemented as a MACRO in the future)
*/
char * APIENTRY ca_host_name_function(chid chix)
char * epicsShareAPI ca_host_name_function(chid chix)
{
IIU *piiu;
@@ -3283,7 +3343,7 @@ char * APIENTRY ca_host_name_function(chid chix)
/*
* ca_v42_ok(chid chan)
*/
int APIENTRY ca_v42_ok(chid chan)
int epicsShareAPI ca_v42_ok(chid chan)
{
int v42;
IIU *piiu;
@@ -3360,10 +3420,12 @@ int ca_channel_status(int tid)
/*
* ca_replace_printf_handler ()
*/
int APIENTRY ca_replace_printf_handler (
int epicsShareAPI ca_replace_printf_handler (
int (*ca_printf_func)(const char *pformat, va_list args)
)
{
INITCHK;
if (ca_printf_func) {
ca_static->ca_printf_func = ca_printf_func;
}

View File

@@ -5,6 +5,10 @@
static char *sccsId = "@(#) $Id$";
/*
* $Log$
*/
#ifdef VMS
#include <LIB$ROUTINES.H>
#endif
@@ -19,7 +23,7 @@ static char *sccsId = "@(#) $Id$";
#include "os_depen.h"
#include <epicsAssert.h>
#include <assert.h>
#include <cadef.h>
#define EVENT_ROUTINE null_event
@@ -27,7 +31,11 @@ static char *sccsId = "@(#) $Id$";
#define NUM 1
int conn_get_cb_count;
int conn_cb_count;
#ifndef min
#define min(A,B) ((A)>(B)?(B):(A))
#endif
int doacctst(char *pname);
void test_sync_groups(chid chix);
@@ -35,9 +43,22 @@ void multiple_sg_requests(chid chix, CA_SYNC_GID gid);
void null_event(struct event_handler_args args);
void write_event(struct event_handler_args args);
void conn(struct connection_handler_args args);
void conn_cb(struct event_handler_args args);
void get_cb(struct event_handler_args args);
void accessSecurity_cb(struct access_rights_handler_args args);
void doubleTest(
chid chan,
dbr_double_t beginValue,
dbr_double_t increment,
dbr_double_t epsilon,
unsigned iterations);
void floatTest(
chid chan,
dbr_float_t beginValue,
dbr_float_t increment,
dbr_float_t epsilon,
unsigned iterations);
#ifdef vxWorks
int acctst(char *pname)
@@ -92,13 +113,33 @@ int doacctst(char *pname)
SEVCHK(ca_task_initialize(), "Unable to initialize");
conn_get_cb_count = 0;
conn_cb_count = 0;
printf("begin\n");
#ifdef VMS
lib$init_timer();
#endif /*VMS*/
{
TS_STAMP end_time;
TS_STAMP start_time;
double delay;
double request = 0.5;
double accuracy;
tsLocalTime(&start_time);
status = ca_pend_event(request);
if (status != ECA_TIMEOUT) {
SEVCHK(status, NULL);
}
tsLocalTime(&end_time);
TsDiffAsDouble(&delay,&end_time,&start_time);
accuracy = 100.0*(delay-request)/request;
printf("CA pend event delay accuracy = %f %%\n",
accuracy);
assert (abs(accuracy) < 10.0);
}
ptr = (struct dbr_gr_float *)
malloc(dbr_size_n(DBR_GR_FLOAT, NUM));
@@ -213,34 +254,74 @@ int doacctst(char *pname)
ca_read_access(chix1),
ca_write_access(chix1));
#if 0
/*
* Verify that we can write and then read back
* the same value
* the same analog value
*/
if( (ca_field_type(chix1)==DBR_FLOAT ||
ca_field_type(chix1)==DBR_DOUBLE) &&
ca_read_access(chix1) &&
ca_write_access(chix1)){
double dval = 3.3;
float fval = -8893.3;
double dret = DBL_MAX;
float fret = FLT_MAX;
double incr;
double epsil;
double base;
unsigned long iter;
status = ca_put(DBR_DOUBLE, chix1, &dval);
SEVCHK(status, NULL);
status = ca_get(DBR_DOUBLE, chix1, &dret);
SEVCHK(status, NULL);
ca_pend_io(30.0);
assert( fabs(dval-dret) < DBL_EPSILON*4);
printf ("float test ...");
fflush(stdout);
epsil = FLT_EPSILON*4;
base = FLT_MIN;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
base = FLT_MAX;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = - ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
base = - FLT_MAX;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
printf ("done\n");
status = ca_put(DBR_FLOAT, chix1, &fval);
SEVCHK(status, NULL);
status = ca_get(DBR_FLOAT, chix1, &fret);
SEVCHK(status, NULL);
ca_pend_io(30.0);
assert( fabs(fval-fret) < FLT_EPSILON*4);
printf ("double test ...");
fflush(stdout);
epsil = DBL_EPSILON*4;
base = DBL_MIN;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
base = DBL_MAX;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = - ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
base = - DBL_MAX;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
printf ("done\n");
}
#endif
/*
* verify we dont jam up on many uninterrupted
@@ -475,13 +556,13 @@ int doacctst(char *pname)
SEVCHK(ca_modify_user_name("Willma"), NULL);
SEVCHK(ca_modify_host_name("Bed Rock"), NULL);
if (conn_get_cb_count != 3){
if (conn_cb_count != 3){
printf ("!!!! Connect cb count = %d expected = 3 !!!!\n",
conn_get_cb_count);
conn_cb_count);
}
printf("-- Put/Gets done- waiting for Events --\n");
status = ca_pend_event(10.0);
status = ca_pend_event(1000.0);
if (status != ECA_TIMEOUT) {
SEVCHK(status, NULL);
}
@@ -505,7 +586,59 @@ int doacctst(char *pname)
return(0);
}
void floatTest(
chid chan,
dbr_float_t beginValue,
dbr_float_t increment,
dbr_float_t epsilon,
unsigned iterations)
{
unsigned i;
dbr_float_t fval;
dbr_float_t fretval;
int status;
fval = beginValue;
for (i=0; i<iterations; i++) {
fretval = FLT_MAX;
status = ca_put (DBR_FLOAT, chan, &fval);
SEVCHK (status, NULL);
status = ca_get (DBR_FLOAT, chan, &fretval);
SEVCHK (status, NULL);
status = ca_pend_io (100.0);
SEVCHK (status, NULL);
assert (fabs(fval-fretval) < epsilon);
fval += increment;
}
}
void doubleTest(
chid chan,
dbr_double_t beginValue,
dbr_double_t increment,
dbr_double_t epsilon,
unsigned iterations)
{
unsigned i;
dbr_double_t fval;
dbr_double_t fretval;
int status;
fval = beginValue;
for (i=0; i<iterations; i++) {
fretval = DBL_MAX;
status = ca_put (DBR_DOUBLE, chan, &fval);
SEVCHK (status, NULL);
status = ca_get (DBR_DOUBLE, chan, &fretval);
SEVCHK (status, NULL);
status = ca_pend_io (100.0);
SEVCHK (status, NULL);
assert (fabs(fval-fretval) < epsilon);
fval += increment;
}
}
void null_event(struct event_handler_args args)
{
@@ -544,15 +677,15 @@ void conn(struct connection_handler_args args)
else
printf("Ukn conn ev\n");
ca_get_callback(DBR_GR_FLOAT, args.chid, conn_cb, NULL);
ca_get_callback(DBR_GR_FLOAT, args.chid, get_cb, NULL);
}
void conn_cb(struct event_handler_args args)
void get_cb(struct event_handler_args args)
{
if(!(args.status & CA_M_SUCCESS)){
printf("Get cb failed because \"%s\"\n", ca_message(args.status));
}
conn_get_cb_count++;
conn_cb_count++;
}

View File

@@ -115,7 +115,13 @@ int cac_select_io(struct timeval *ptimeout, int flags)
&autoTimeOut);
# endif
cac_gettimeval (&ca_static->currentTime);
/*
* get a new time stamp if we have been waiting
* for any significant length of time
*/
if (ptimeout->tv_sec || ptimeout->tv_usec) {
cac_gettimeval (&ca_static->currentTime);
}
if (status<0) {
if (MYERRNO == EINTR) {

View File

@@ -59,6 +59,7 @@ LOCAL void test (
unsigned iterations
);
LOCAL tf test_pend;
LOCAL tf test_search;
LOCAL tf test_free;
LOCAL tf test_wait;
@@ -82,7 +83,7 @@ int main(int argc, char **argv)
catime(pname);
}
else{
printf("usage: %s <channel name>", argv[0]);
printf("usage: %s <channel name>\n", argv[0]);
return -1;
}
return 0;
@@ -119,6 +120,9 @@ int catime (char *channelName)
ca_field_type(itemList[0].chix),
ca_element_count(itemList[0].chix));
printf ("\tpend event test\n");
timeIt (test_pend, NULL, 100);
for (i=0; i<NELEMENTS(itemList); i++) {
itemList[i].val.fltval = 0.0;
itemList[i].type = DBR_FLOAT;
@@ -183,14 +187,56 @@ void timeIt(
unsigned inlineIter;
status = tsLocalTime(&start_time);
#if 0
assert (status == S_ts_OK);
#endif
(*pfunc) (pItems, iterations, &inlineIter);
status = tsLocalTime(&end_time);
#if 0
assert (status == S_ts_OK);
#endif
TsDiffAsDouble(&delay,&end_time,&start_time);
printf ("Elapsed Per Item = %f\n", delay/(iterations*inlineIter));
}
/*
* test_search ()
*/
LOCAL void test_pend(
ti *pItems,
unsigned iterations,
unsigned *pInlineIter
)
{
unsigned i;
int status;
for (i=0; i<iterations; i++) {
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
}
*pInlineIter = 5;
}
/*
* test_search ()

View File

@@ -1,5 +1,6 @@
/* $Id$ */
/************************************************************************/
/* */
/* */
/* L O S A L A M O S */
/* Los Alamos National Laboratory */
/* Los Alamos, New Mexico 87545 */
@@ -28,6 +29,7 @@
/* .12 110194 joh improved search scheduling */
/* (dont send all chans in a block) */
/* */
/* $Log$ */
/*_begin */
/************************************************************************/
/* */
@@ -349,7 +351,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno)
/*
* MARK_SERVER_AVAILABLE
*/
void mark_server_available(struct in_addr *pnet_addr)
void mark_server_available(const struct in_addr *pnet_addr)
{
chid chan;
ca_real currentPeriod;
@@ -502,7 +504,7 @@ void mark_server_available(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr)
{
bhe *pBHE;
unsigned index;
@@ -535,7 +537,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
* start the average at zero
*/
pBHE->averagePeriod = 0.0;
cac_gettimeval(&pBHE->timeStamp);
pBHE->timeStamp = ca_static->currentTime;
/*
* install in the hash table
@@ -552,7 +554,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
bhe *lookupBeaconInetAddr (const struct in_addr *pnet_addr)
{
bhe *pBHE;
unsigned index;
@@ -579,7 +581,7 @@ bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
void removeBeaconInetAddr (struct in_addr *pnet_addr)
void removeBeaconInetAddr (const struct in_addr *pnet_addr)
{
bhe *pBHE;
bhe **ppBHE;

View File

@@ -94,8 +94,9 @@ LOCAL char *getToken(char **ppString);
*
*/
int alloc_ioc(
struct in_addr *pnet_addr,
struct ioc_in_use **ppiiu
const struct in_addr *pnet_addr,
int port,
struct ioc_in_use **ppiiu
)
{
int status;
@@ -127,6 +128,7 @@ struct ioc_in_use **ppiiu
status = create_net_chan(
ppiiu,
pnet_addr,
port,
IPPROTO_TCP);
if(status == ECA_NORMAL){
pBHE->piiu = *ppiiu;
@@ -145,7 +147,8 @@ struct ioc_in_use **ppiiu
*/
int create_net_chan(
struct ioc_in_use **ppiiu,
struct in_addr *pnet_addr, /* only used by TCP connections */
const struct in_addr *pnet_addr, /* only used by TCP connections */
int port,
int net_proto
)
{
@@ -190,8 +193,7 @@ int net_proto
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
pNode->destAddr.inetAddr.sin_family = AF_INET;
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
pNode->destAddr.inetAddr.sin_port =
htons (ca_static->ca_server_port);
pNode->destAddr.inetAddr.sin_port = htons (port);
ellAdd(&piiu->destAddr, &pNode->node);
piiu->recvBytes = tcp_recv_msg;
piiu->sendBytes = cac_tcp_send_msg_piiu;
@@ -593,7 +595,7 @@ void notify_ca_repeater()
status = sendto(
piiuCast->sock_chan,
(char *)&msg, /* UCX requires a valid address here */
(char *)&msg,
len,
0,
(struct sockaddr *)&saddr,
@@ -601,11 +603,16 @@ void notify_ca_repeater()
if(status < 0){
if( MYERRNO != EINTR &&
MYERRNO != ENOBUFS &&
MYERRNO != EWOULDBLOCK){
MYERRNO != EWOULDBLOCK &&
/*
* This is returned from Linux when
* the repeater isnt running
*/
MYERRNO != ECONNREFUSED
){
ca_printf(
"send error => %s\n",
strerror(MYERRNO));
assert(0);
"CAC: error sending to repeater is \"%s\"\n",
strerror(MYERRNO));
}
}
else{
@@ -659,29 +666,24 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
0,
&pNode->destAddr.sockAddr,
sizeof(pNode->destAddr.sockAddr));
if(status<0){
if(status>=0){
actualSendCnt = (unsigned long) status;
assert (actualSendCnt == sendCnt);
pNode = (caAddrNode *) pNode->node.next;
}
else {
int localErrno;
localErrno = MYERRNO;
if( localErrno == EWOULDBLOCK &&
localErrno == ENOBUFS &&
localErrno == EINTR){
UNLOCK;
return;
}
else {
if( localErrno != EWOULDBLOCK &&
localErrno != ENOBUFS &&
localErrno != EINTR){
ca_printf(
"CAC: error on socket send() %s\n",
"CAC: UDP send error = \"%s\"\n",
strerror(localErrno));
}
TAG_CONN_DOWN(piiu);
break;
}
actualSendCnt = (unsigned long) status;
assert (actualSendCnt == sendCnt);
pNode = (caAddrNode *) pNode->node.next;
}
/*
@@ -1043,7 +1045,6 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu)
return;
}
ca_printf("Unexpected UDP failure %s\n", strerror(MYERRNO));
TAG_CONN_DOWN(piiu);
}
else if(status > 0){
unsigned long bytesActual;

View File

@@ -1,3 +1,4 @@
/* $Id */
/************************************************************************/
/* */
/* L O S A L A M O S */
@@ -28,6 +29,7 @@
/* .17 121892 joh added TCP send buf size var */
/* .18 122192 joh added outstanding ack var */
/* .19 012094 joh added minor version (for each server) */
/* $Log$ */
/* */
/*_begin */
/************************************************************************/
@@ -86,6 +88,7 @@ HDRVERSIONID(iocinfh, "$Id$")
#include <limits.h>
#include <stdarg.h>
#include <shareLib.h>
/*
* OS dependent includes
@@ -511,7 +514,7 @@ void issue_client_host_name(struct ioc_in_use *piiu);
int ca_defunct(void);
int ca_printf(char *pformat, ...);
void manage_conn(int silent);
void mark_server_available(struct in_addr *pnet_addr);
void mark_server_available(const struct in_addr *pnet_addr);
void flow_control(struct ioc_in_use *piiu);
int broadcast_addr(struct in_addr *pcastaddr);
void ca_repeater(void);
@@ -521,18 +524,19 @@ void ca_sg_init(void);
void ca_sg_shutdown(struct ca_static *ca_temp);
int cac_select_io(struct timeval *ptimeout, int flags);
void caHostFromInetAddr(
struct in_addr *pnet_addr,
char *pBuf,
unsigned size
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size
);
int post_msg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
char *pInBuf,
unsigned long blockSize
);
int alloc_ioc(
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
int port,
struct ioc_in_use **ppiiu
);
unsigned long cacRingBufferWrite(
@@ -565,7 +569,8 @@ char *localHostName(void);
int create_net_chan(
struct ioc_in_use **ppiiu,
struct in_addr *pnet_addr, /* only used by TCP connections */
const struct in_addr *pnet_addr, /* only used by TCP connections */
int port,
int net_proto
);
@@ -576,9 +581,9 @@ void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port);
int ca_os_independent_init (void);
void freeBeaconHash(struct ca_static *ca_temp);
void removeBeaconInetAddr(struct in_addr *pnet_addr);
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr);
bhe *createBeaconHashEntry(struct in_addr *pnet_addr);
void removeBeaconInetAddr(const struct in_addr *pnet_addr);
bhe *lookupBeaconInetAddr(const struct in_addr *pnet_addr);
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr);
void close_ioc(IIU *piiu);
void notify_ca_repeater(void);
void cac_clean_iiu_list(void);
@@ -613,5 +618,6 @@ void caSetDefaultPrintfHandler ();
*/
#define M_dbAccess (501 <<16) /*Database Access Routines */
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
#define S_db_Pending (M_dbAccess|37) /*Request is pending*/
#endif /* this must be the last line in this file */

View File

@@ -31,23 +31,26 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
/* TCP/UDP port number (bumped each protocol change) */
#define CA_PROTOCOL_VERSION 4
#define CA_MINOR_VERSION 4
#define CA_MINOR_VERSION 5
#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */
#if CA_PROTOCOL_VERSION == 4
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1)
#define CA_V42(MAJOR,MINOR) ((MINOR)>=2)
#define CA_V43(MAJOR,MINOR) ((MINOR)>=3)
#define CA_V44(MAJOR,MINOR) ((MINOR)>=4)
#define CA_V45(MAJOR,MINOR) ((MINOR)>=5)
#elif CA_PROTOCOL_VERSION > 4
#define CA_V41(MAJOR,MINOR) ( 1 )
#define CA_V42(MAJOR,MINOR) ( 1 )
#define CA_V43(MAJOR,MINOR) ( 1 )
#define CA_V44(MAJOR,MINOR) ( 1 )
#define CA_V45(MAJOR,MINOR) ( 1 )
#else
#define CA_V41(MAJOR,MINOR) ( 0 )
#define CA_V42(MAJOR,MINOR) ( 0 )
#define CA_V43(MAJOR,MINOR) ( 0 )
#define CA_V44(MAJOR,MINOR) ( 0 )
#define CA_V45(MAJOR,MINOR) ( 0 )
#endif
/*
@@ -72,7 +75,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
typedef unsigned short ca_uint16_t;
typedef unsigned int ca_uint32_t;
typedef float ca_float32_t;
typedef ca_uint32_t caResId;
/* values for m_cmmd */
#define IOC_NOOP 0 /* do nothing, but verify TCP */
@@ -169,4 +172,5 @@ struct monops { /* monitor req opi to ioc */
struct mon_info m_info;
};
#endif
#endif /* __IOCMSG__ */

View File

@@ -38,7 +38,7 @@ static char *sccsId = "@(#) $Id$";
#include <stdio.h>
#include <string.h>
#ifdef _WINDOWS
#ifdef WIN32
# include <winsock.h>
#else
# include <sys/types.h>
@@ -54,7 +54,10 @@ static char *sccsId = "@(#) $Id$";
/*
* caHostFromInetAddr()
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size)
{
char *pString;
struct hostent *ent;

View File

@@ -51,6 +51,9 @@ static char *os_depenhSccsId = "$Id$";
# include <netinet/tcp.h>
# include <net/if.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <sys/filio.h>
# include <sys/sockio.h>
# define CA_OS_CONFIGURED
#endif
@@ -123,16 +126,16 @@ static char *os_depenhSccsId = "$Id$";
# define CA_OS_CONFIGURED
#endif /*VMS*/
#ifdef _WINDOWS
#ifdef WIN32
# include <errno.h>
# include <time.h>
# include <windows.h>
# include <winsock.h>
# define CA_OS_CONFIGURED
#endif /*_WINDOWS*/
#endif /*WIN32*/
#ifndef CA_OS_CONFIGURED
#error Please define one of vxWorks, UNIX VMS, or _WINDOWS
#error Please define one of vxWorks, UNIX, VMS, or WIN32
#endif
/*
@@ -213,6 +216,13 @@ static char *os_depenhSccsId = "$Id$";
#define DELAYTICKS 50L /* (adjust units below) */
#define TICKSPERSEC 1000L /* mili sec per sec */
/*
* BSD prototypes missing from SUNOS4, MULTINET and
* perhaps other environments
*/
#include <epicsTypes.h>
#include <bsdProto.h>
/*
* order of ops is important here
*
@@ -290,7 +300,7 @@ static char *os_depenhSccsId = "$Id$";
# define INVALID_SOCKET (-1)
#endif
#ifdef _WINDOWS
#ifdef WIN32
# define LOCK
# define UNLOCK
# define LOCKEVENTS
@@ -308,7 +318,7 @@ static char *os_depenhSccsId = "$Id$";
# define MYERRNO WSAGetLastError()
# define POST_IO_EV
# define SYSFREQ 1000000L /* 1 MHz */
#endif /*_WINDOWS*/
#endif /*WIN32*/
#endif

View File

@@ -28,6 +28,7 @@
*
* Modification Log:
* -----------------
* $Log$
*
*/
@@ -70,6 +71,11 @@ void cac_mux_io(struct timeval *ptimeout)
cac_clean_iiu_list();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout = *ptimeout;
do{
count = cac_select_io(
@@ -77,12 +83,6 @@ void cac_mux_io(struct timeval *ptimeout)
CA_DO_RECVS | CA_DO_SENDS);
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
@@ -95,7 +95,15 @@ void cac_mux_io(struct timeval *ptimeout)
*/
void cac_block_for_io_completion(struct timeval *pTV)
{
cac_mux_io(pTV);
cac_mux_io (pTV);
}
/*
* cac_block_for_sg_completion()
*/
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
cac_mux_io (pTV);
}
@@ -117,12 +125,6 @@ void os_specific_sg_delete(CASG *pcasg)
{
}
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
cac_mux_io(pTV);
}
/*
* CAC_ADD_TASK_VARIABLE()
@@ -140,17 +142,36 @@ int cac_add_task_variable(struct ca_static *ca_temp)
int cac_os_depen_init(struct ca_static *pcas)
{
int status;
struct sigaction sa;
ca_static = pcas;
/*
* dont allow disconnect to terminate process
* when running in UNIX enviroment
* when running in UNIX environment
*
* allow error to be returned to sendto()
* instead of handling disconnect at interrupt
*/
signal(SIGPIPE,SIG_IGN);
status = sigaction(SIGPIPE, NULL, &sa);
if (status==0) {
if (sa.sa_handler == SIG_DFL) {
sa.sa_handler = SIG_IGN;
status = sigaction(SIGPIPE, &sa, NULL);
if (status) {
ca_printf(
"%s: Error from signal replace was \"%s\"\n",
__FILE__,
strerror(MYERRNO));
}
}
}
else {
ca_printf(
"%s: Error from signal query was \"%s\"\n",
__FILE__,
strerror(MYERRNO));
}
status = ca_os_independent_init ();

View File

@@ -29,7 +29,7 @@
* PURPOSE:
* Broadcasts fan out over the LAN, but UDP does not allow
* two processes on the same machine to get the same broadcast.
* This code takes extends the broadcast model from the net to within
* This code extends the broadcast model from the net to within
* the OS.
*
* NOTES:
@@ -57,29 +57,37 @@
* .06 120492 joh removed unnecessary includes
* .07 120992 joh now uses dll list routines
* .08 102993 joh toggle set sock opt to set
*
* .09 070195 joh discover client has vanished by connecting its
* datagram socket (and watching for ECONNREFUSED)
*/
static char *sccsId = "@(#)$Id$";
#include "iocinf.h"
/*
* one socket per client so we will get the ECONNREFUSED
* error code (and then delete the client)
*/
struct one_client{
ELLNODE node;
struct sockaddr_in from;
SOCKET sock;
};
/*
* these can be external since there is only one instance
* per machine so we dont care about reentrancy
*/
struct one_client{
ELLNODE node;
struct sockaddr_in from;
};
static ELLLIST client_list;
static char buf[MAX_UDP];
LOCAL int clean_client(struct one_client *pclient);
LOCAL void register_new_client(SOCKET sock, struct sockaddr_in *pLocal,
LOCAL void register_new_client(struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom);
#define PORT_ANY 0
LOCAL int makeSocket(int port);
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize);
/*
@@ -93,13 +101,9 @@ void ca_repeater()
int status;
int size;
SOCKET sock;
int true = 1;
struct sockaddr_in from;
struct sockaddr_in bd;
struct sockaddr_in local;
int from_size = sizeof from;
struct one_client *pclient;
struct one_client *pnxtclient;
short port;
port = caFetchPortConfig(
@@ -108,37 +112,20 @@ void ca_repeater()
ellInit(&client_list);
/* allocate a socket */
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
assert(sock != INVALID_SOCKET);
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(port);
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status<0){
if(MYERRNO != EADDRINUSE){
ca_printf("CA Repeater: unexpected bind fail %s\n",
strerror(MYERRNO));
sock = makeSocket(port);
if (sock==INVALID_SOCKET) {
/*
* test for server was already started
*/
if (MYERRNO==EADDRINUSE) {
exit(0);
}
socket_close(sock);
ca_printf("%s: Unable to create repeater socket because \"%s\"\n",
__FILE__,
strerror(MYERRNO));
exit(0);
}
status = setsockopt( sock,
SOL_SOCKET,
SO_REUSEADDR,
(char *)&true,
sizeof(true));
if(status<0){
ca_printf( "%s: set socket option failed\n",
__FILE__);
}
status = local_addr(sock, &local);
if(status != OK){
ca_printf(
@@ -164,78 +151,131 @@ void ca_repeater()
if(size < 0){
ca_printf("CA Repeater: recv err %s\n",
strerror(MYERRNO));
continue;
}
pMsg = (struct extmsg *) buf;
/*
* both zero leng message and a registartion message
* both zero length message and a registration message
* will register a new client
*/
if(size >= sizeof(*pMsg)){
if(ntohs(pMsg->m_cmmd) == REPEATER_REGISTER){
register_new_client(sock, &local, &from);
register_new_client(&local, &from);
/*
* strip register client message
*/
pMsg++;
size -= sizeof(*pMsg);
if (size==0) {
continue;
}
}
}
else if(size == 0){
register_new_client(sock, &local, &from);
register_new_client(&local, &from);
continue;
}
fanOut(&from, (char *) pMsg, size);
}
}
/*
* fanOut()
*/
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize)
{
ELLLIST theClients;
struct one_client *pclient;
int status;
ellInit(&theClients);
while (pclient=(struct one_client *)ellGet(&client_list)) {
ellAdd(&theClients, &pclient->node);
/*
* size may have been adjusted above
* Dont reflect back to sender
*/
if(size){
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = (struct one_client *)
pclient->node.next){
if(pFrom->sin_port == pclient->from.sin_port &&
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr){
continue;
}
/*
* Dont reflect back to sender
*/
if(from.sin_port == pclient->from.sin_port &&
from.sin_addr.s_addr ==
pclient->from.sin_addr.s_addr){
continue;
}
status = sendto(
sock,
(char *)pMsg,
size,
0,
(struct sockaddr *)&pclient->from,
sizeof pclient->from);
if(status < 0){
ca_printf("CA Repeater: fanout err %s\n",
strerror(MYERRNO));
}
status = send(
pclient->sock,
(char *)pMsg,
msgSize,
0);
if (status>=0) {
#ifdef DEBUG
ca_printf("Sent\n");
ca_printf("Sent to %d\n",
pclient->from.sin_port);
#endif
}
if(status < 0){
if (MYERRNO == ECONNREFUSED) {
#ifdef DEBUG
ca_printf("Deleted client %d\n",
pclient->from.sin_port);
#endif
ellDelete(&theClients,
&pclient->node);
socket_close(pclient->sock);
free(pclient);
}
else {
ca_printf(
"CA Repeater: fan out err was \"%s\"\n",
strerror(MYERRNO));
}
}
/*
* remove any dead wood prior to pending
*/
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = pnxtclient){
/* do it now in case item deleted */
pnxtclient = (struct one_client *)
pclient->node.next;
clean_client(pclient);
}
}
ellConcat(&client_list, &theClients);
}
/*
* makeSocket()
*/
LOCAL int makeSocket(int port)
{
int status;
struct sockaddr_in bd;
int sock;
int true = 1;
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if (sock == INVALID_SOCKET) {
return sock;
}
status = setsockopt( sock,
SOL_SOCKET,
SO_REUSEADDR,
(char *)&true,
sizeof(true));
if(status<0){
ca_printf( "%s: set socket option failed\n",
__FILE__);
}
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(port);
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status<0){
socket_close(sock);
return INVALID_SOCKET;
}
return sock;
}
@@ -243,17 +283,17 @@ void ca_repeater()
* register_new_client()
*/
LOCAL void register_new_client(
SOCKET sock,
struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom)
{
int status;
struct one_client *pclient;
struct extmsg confirm;
struct extmsg noop;
for( pclient = (struct one_client *) client_list.node.next;
for( pclient = (struct one_client *) ellFirst(&client_list);
pclient;
pclient = (struct one_client *) pclient->node.next){
pclient = (struct one_client *) ellNext(&pclient->node)){
if( pFrom->sin_port == pclient->from.sin_port &&
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr)
@@ -262,101 +302,73 @@ struct sockaddr_in *pFrom)
if(!pclient){
pclient = (struct one_client *)calloc (1, sizeof(*pclient));
if(pclient){
pclient->from = *pFrom;
ellAdd (&client_list, &pclient->node);
#ifdef DEBUG
ca_printf (
"Added %d\n",
pFrom->sin_port);
#endif
if(!pclient){
ca_printf("%s: no memory for new client\n",
__FILE__);
return;
}
pclient->sock = makeSocket(PORT_ANY);
if (!pclient->sock) {
free(pclient);
ca_printf("%s: no client sock because \"%s\"\n",
__FILE__,
strerror(MYERRNO));
return;
}
status = connect(pclient->sock,
(struct sockaddr *)pFrom,
sizeof(*pFrom));
if (status<0) {
socket_close(pclient->sock);
free(pclient);
ca_printf("%s: unable to connect client sock\n",
__FILE__);
return;
}
pclient->from = *pFrom;
ellAdd (&client_list, &pclient->node);
#ifdef DEBUG
ca_printf (
"Added %d\n",
pFrom->sin_port);
#endif
}
memset((char *)&confirm, 0, sizeof confirm);
memset((char *)&confirm, '\0', sizeof(confirm));
confirm.m_cmmd = htons(REPEATER_CONFIRM);
confirm.m_available = pLocal->sin_addr.s_addr;
status = sendto(
sock,
status = send(
pclient->sock,
(char *)&confirm,
sizeof(confirm),
0,
(struct sockaddr *)pFrom, /* back to sender */
sizeof(*pFrom));
if(status != sizeof(confirm)){
ca_printf("CA Repeater: confirm err %s\n",
strerror(MYERRNO));
0);
if(status >= 0){
assert(status == sizeof(confirm));
}
}
/*
*
* check to see if this client is still around
*
* NOTE:
* This closes the socket only whenever we are
* able to bind so that we free the port.
*/
LOCAL int clean_client(struct one_client *pclient)
{
static int sockExists;
static SOCKET sock;
int port = pclient->from.sin_port;
struct sockaddr_in bd;
int status;
int present = FALSE;
/*
* allocate a socket
* (no lock required because this is implemented with
* a single thread)
*/
if(!sockExists){
sock = socket(
AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if(sock != INVALID_SOCKET){
sockExists = TRUE;
}
else{
ca_printf("CA Repeater: no bind test sock err %s\n",
strerror(MYERRNO));
return OK;
}
}
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = port;
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status>=0){
socket_close (sock);
sockExists = FALSE;
}
else{
if(MYERRNO == EADDRINUSE){
present = TRUE;
}
else{
ca_printf("CA Repeater: client cleanup err %s\n",
strerror(MYERRNO));
ca_printf("CA Repeater: sock=%d family=%d addr=%x port=%d\n",
sock, bd.sin_family, bd.sin_addr.s_addr,
bd.sin_port);
}
}
if(!present){
else if (MYERRNO == ECONNREFUSED){
#ifdef DEBUG
ca_printf("Deleted %d\n", pclient->from.sin_port);
ca_printf("Deleted repeater client=%d sending ack\n",
pFrom->sin_port);
#endif
ellDelete(&client_list, &pclient->node);
socket_close(pclient->sock);
free(pclient);
}
else {
ca_printf("CA Repeater: confirm err was \"%s\"\n",
strerror(MYERRNO));
}
return OK;
/*
* send a noop message to all other clients so that we dont
* accumulate sockets when there are no beacons
*/
memset((char *)&noop, '\0', sizeof(noop));
confirm.m_cmmd = htons(IOC_NOOP);
fanOut(pFrom, (char *)&noop, sizeof(noop));
}

View File

@@ -81,12 +81,12 @@ chid chan
LOCAL int cacMsg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
);
LOCAL void perform_claim_channel(
IIU *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
);
#ifdef CONVERSION_REQUIRED
@@ -103,7 +103,7 @@ extern CACVRTFUNC *cac_dbr_cvrt[];
*/
int post_msg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
char *pInBuf,
unsigned long blockSize
)
@@ -236,7 +236,7 @@ unsigned long blockSize
*/
LOCAL int cacMsg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
)
{
evid monix;
@@ -293,9 +293,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_write_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
@@ -366,8 +365,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_read_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
}
@@ -398,8 +397,8 @@ struct in_addr *pnet_addr
if (!piiu->curMsg.m_postsize) {
LOCK;
ellDelete(&monix->chan->eventq, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
}
@@ -509,8 +508,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_read_list, &pIOBlock->node);
UNLOCK;
caIOBlockFree(pIOBlock);
UNLOCK;
break;
}
case IOC_SEARCH:
@@ -548,6 +547,7 @@ struct in_addr *pnet_addr
case IOC_ERROR:
{
ELLLIST *pList = NULL;
evid monix;
char nameBuf[64];
char context[255];
@@ -584,32 +584,30 @@ struct in_addr *pnet_addr
*/
monix = NULL;
args.addr = NULL;
LOCK;
switch (ntohs(req->m_cmmd)) {
case IOC_READ_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
pList = &pend_read_list;
op = CA_OP_GET;
break;
case IOC_READ:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
if(monix){
args.addr = monix->usr_arg;
}
pList = &pend_read_list;
op = CA_OP_GET;
break;
case IOC_WRITE_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
pList = &pend_write_list;
op = CA_OP_PUT;
break;
case IOC_WRITE:
@@ -619,19 +617,18 @@ struct in_addr *pnet_addr
op = CA_OP_SEARCH;
break;
case IOC_EVENT_ADD:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_ADD_EVENT;
if (monix) {
pList = &monix->chan->eventq;
}
break;
case IOC_EVENT_CANCEL:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_CLEAR_EVENT;
break;
default:
@@ -640,10 +637,15 @@ struct in_addr *pnet_addr
}
if (monix) {
if (pList) {
ellDelete(pList, &monix->node);
}
else {
printf ("CAC - Protocol err - no list for IO blk\n");
}
caIOBlockFree(monix);
}
LOCK;
args.chid = bucketLookupItemUnsignedId
(pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
@@ -728,16 +730,18 @@ struct in_addr *pnet_addr
*/
LOCAL void perform_claim_channel(
IIU *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
)
{
int v42;
int port;
char rej[64];
chid chan;
int status;
IIU *allocpiiu;
IIU *chpiiu;
unsigned short *pMinorVersion;
unsigned minorVersion;
/*
* ignore broadcast replies for deleted channels
@@ -792,8 +796,31 @@ struct in_addr *pnet_addr
return;
}
status = alloc_ioc(pnet_addr, &allocpiiu);
switch(status){
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
* This value is ignored by earlier clients.
*/
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
pMinorVersion = (unsigned short *)(piiu->pCurData);
minorVersion = ntohs(*pMinorVersion);
}
else{
minorVersion = CA_UKN_MINOR_VERSION;
}
/*
* the type field is abused to carry the port number
* so that we can have multiple servers on one host
*/
if (CA_V45 (CA_PROTOCOL_VERSION,minorVersion)) {
port = piiu->curMsg.m_type;
}
else {
port = ca_static->ca_server_port;
}
status = alloc_ioc (pnet_addr, port, &allocpiiu);
switch (status) {
case ECA_NORMAL:
break;
@@ -818,22 +845,11 @@ struct in_addr *pnet_addr
}
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
* This value is ignored by earlier clients.
*/
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
pMinorVersion = (unsigned short *)(piiu->pCurData);
allocpiiu->minor_version_number = ntohs(*pMinorVersion);
}
else{
allocpiiu->minor_version_number = CA_UKN_MINOR_VERSION;
}
allocpiiu->minor_version_number = minorVersion;
ellDelete(&chpiiu->chidlist, &chan->node);
ellDelete (&chpiiu->chidlist, &chan->node);
chan->piiu = allocpiiu;
ellAdd(&allocpiiu->chidlist, &chan->node);
ellAdd (&allocpiiu->chidlist, &chan->node);
ca_static->ca_search_responses++;
/*
@@ -842,7 +858,7 @@ struct in_addr *pnet_addr
* the client's name to the server.
* (CA V4.1 or higher)
*/
if(ellCount(&allocpiiu->chidlist)==1){
if (ellCount(&allocpiiu->chidlist)==1) {
issue_identify_client(allocpiiu);
issue_client_host_name(allocpiiu);
}

View File

@@ -28,6 +28,7 @@
*
* Modification Log:
* -----------------
* $Log$
*
* NOTES:
* 1) Need to fix if the OP is on a FD that
@@ -97,7 +98,7 @@ void ca_sg_shutdown(struct ca_static *ca_temp)
/*
* ca_sg_create()
*/
int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid)
{
int status;
CASG *pcasg;
@@ -130,29 +131,38 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
*/
memset((char *)pcasg,0,sizeof(*pcasg));
pcasg->magic = CASG_MAGIC;
pcasg->id = CLIENT_SLOW_ID_ALLOC;
pcasg->opPendCount = 0;
pcasg->seqNo = 0;
os_specific_sg_create(pcasg);
status = bucketAddItemUnsignedId(pSlowBucket, &pcasg->id, pcasg);
if(status == BUCKET_SUCCESS){
do {
pcasg->id = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId (pSlowBucket,
&pcasg->id, pcasg);
} while (status == S_bucket_idInUse);
if (status == S_bucket_success) {
/*
* place it on the active sync group list
*/
ellAdd(&ca_static->activeCASG, &pcasg->node);
* place it on the active sync group list
*/
ellAdd (&ca_static->activeCASG, &pcasg->node);
}
else{
else {
/*
* place it back on the free sync group list
*/
ellAdd(&ca_static->freeCASG, &pcasg->node);
ellAdd (&ca_static->freeCASG, &pcasg->node);
UNLOCK;
if (status == S_bucket_noMemory) {
return ECA_ALLOCMEM;
}
else {
return ECA_INTERNAL;
}
}
UNLOCK;
if(status != BUCKET_SUCCESS){
return ECA_ALLOCMEM;
}
*(WRITEABLE_CA_SYNC_GID *)pgid = pcasg->id;
return ECA_NORMAL;
@@ -162,7 +172,7 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
/*
* ca_sg_delete()
*/
int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_delete(CA_SYNC_GID gid)
{
int status;
CASG *pcasg;
@@ -183,7 +193,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
}
status = bucketRemoveItemUnsignedId(pSlowBucket, &gid);
assert(status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
os_specific_sg_delete(pcasg);
@@ -200,7 +210,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
/*
* ca_sg_block()
*/
int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
int epicsShareAPI ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
{
struct timeval beg_time;
ca_real delay;
@@ -237,16 +247,11 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
UNLOCK;
/*
* always flush and take care
* of connection management
* at least once.
* always flush at least once.
*/
ca_flush_io();
/*
* the current time set within ca_flush_io()
* above.
*/
cac_gettimeval (&ca_static->currentTime);
beg_time = ca_static->currentTime;
delay = 0.0;
@@ -257,9 +262,23 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
/*
* Exit if the timeout has expired
* (dont wait forever for an itsy bitsy
* delay which will no be updated if
* select is called with no delay)
*
* current time is only updated by
* cac_select_io() if we specify
* at least 1 usec to wait
*/
remaining = timeout-delay;
if (remaining<=0.0) {
if (remaining<=(1.0/USEC_PER_SEC)) {
/*
* Make sure that we take care of
* recv backlog at least once
*/
tmo.tv_sec = 0L;
tmo.tv_usec = 0L;
cac_mux_io (&tmo);
status = ECA_TIMEOUT;
break;
}
@@ -276,10 +295,6 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_sg_completion (pcasg, &tmo);
/*
* the current time set within cac_block_for_sg_completion()
* above.
*/
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
}
pcasg->opPendCount = 0;
@@ -291,7 +306,7 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
/*
* ca_sg_reset
*/
int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_reset(CA_SYNC_GID gid)
{
CASG *pcasg;
@@ -313,7 +328,7 @@ int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
/*
* ca_sg_test
*/
int APIENTRY ca_sg_test(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_test(CA_SYNC_GID gid)
{
CASG *pcasg;
@@ -339,7 +354,7 @@ int APIENTRY ca_sg_test(CA_SYNC_GID gid)
/*
* ca_sg_array_put()
*/
int APIENTRY ca_sg_array_put(
int epicsShareAPI ca_sg_array_put(
CA_SYNC_GID gid,
chtype type,
unsigned long count,
@@ -404,7 +419,7 @@ void *pvalue)
/*
* ca_sg_array_get()
*/
int APIENTRY ca_sg_array_get(
int epicsShareAPI ca_sg_array_get(
CA_SYNC_GID gid,
chtype type,
unsigned long count,

View File

@@ -19,7 +19,7 @@ static char *sccsId = "$Id$";
#include "iocinf.h"
void APIENTRY ca_test_event(struct event_handler_args args)
void epicsShareAPI ca_test_event(struct event_handler_args args)
{
ca_printf("CAC: ~~~### in test event for [%s] ###~~~\n",args.chid+1);
ca_printf("CAC: User argument\t%x\n", args.usr);

View File

@@ -28,6 +28,7 @@
*
* Modification Log:
* -----------------
* $Log$
*
*/
@@ -72,6 +73,11 @@ void cac_mux_io(struct timeval *ptimeout)
cac_clean_iiu_list();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout = *ptimeout;
do{
count = cac_select_io(
@@ -80,11 +86,6 @@ void cac_mux_io(struct timeval *ptimeout)
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
@@ -286,7 +287,8 @@ void ca_spawn_repeater()
* gethostbyaddr(). This makes gethostbyaddr()
* hang when it is called from AST level.
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(const struct in_addr *pnet_addr,
char *pBuf, unsigned size)
{
char *pString;

View File

@@ -28,6 +28,7 @@
*
* Modification Log:
* -----------------
* $Log$
*
*/
@@ -144,6 +145,12 @@ void cac_block_for_io_completion(struct timeval *pTV)
ticks = min(LOCALTICKS, ticks);
semTake(io_done_sem, ticks);
/*
* force a time update because we are not
* going to get one with a nill timeout in
* ca_mux_io()
*/
cac_gettimeval (&ca_static->currentTime);
#endif
}
@@ -206,6 +213,12 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
ticks = min(LOCALTICKS, ticks);
semTake (pcasg->sem, ticks);
/*
* force a time update because we are not
* going to get one with a nill timeout in
* ca_mux_io()
*/
cac_gettimeval (&ca_static->currentTime);
#endif
}
@@ -601,7 +614,10 @@ char *localUserName()
/*
* caHostFromInetAddr()
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size)
{
char str[INET_ADDR_LEN];

View File

@@ -29,6 +29,7 @@
*
* Modification Log:
* -----------------
* $Log$
*
*/
@@ -39,8 +40,8 @@
#include "iocinf.h"
#ifndef _WINDOWS
#error This source is specific to DOS/WINDOS
#ifndef WIN32
#error This source is specific to WIN32
#endif
static int get_subnet_mask ( char SubNetMaskStr[256]);
@@ -79,6 +80,11 @@ void cac_mux_io(struct timeval *ptimeout)
cac_clean_iiu_list();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout = *ptimeout;
do{
count = cac_select_io(
@@ -87,11 +93,6 @@ void cac_mux_io(struct timeval *ptimeout)
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
@@ -434,7 +435,7 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
int status;
WSADATA WsaData;
@@ -445,11 +446,13 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
if ((status = WSAStartup(MAKEWORD(1,1), &WsaData)) != 0)
return FALSE;
#if _DEBUG
if (AllocConsole()) {
SetConsoleTitle("Channel Access Status");
freopen( "CONOUT$", "a", stderr );
fprintf(stderr, "Process attached to ca.dll R12\n");
}
#endif
break;
case DLL_PROCESS_DETACH:

View File

@@ -2,27 +2,25 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -ansi
VX_WARN_YES = -Wall -pedantic
SRCS.c = \
../dbAccess.c ../dbBkpt.c ../dbFastLinkConv.c ../dbLink.c \
../dbNotify.c ../dbStaticLib.c ../iocInit.c ../drvTS.c ../dbScan.c \
../dbEvent.c ../dbTest.c ../dbls.c ../db_access.c \
../db_test.c ../recGbl.c ../callback.c ../taskwd.c \
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c ../cvtBpt.c
OBJSdbLib = \
LIBOBJS = \
dbAccess.o dbBkpt.o dbFastLinkConv.o dbLink.o dbNotify.o \
dbStaticLib.o iocInit.o drvTS.o dbScan.o dbEvent.o dbTest.o dbls.o \
db_access.o db_test.o recGbl.o callback.o taskwd.o dbCaLink.o \
dbCaDblink.o devLib.o
dbCaDblink.o devLib.o cvtBpt.o
PROD = initHooks.o
PROD = initHooks.o dbLib
LIBNAME = dbLib
include $(EPICS)/config/RULES.Vx
dbLib: $(OBJSdbLib)
$(RM) $@
$(LINK.c) $@ $(OBJSdbLib) $(LDLIBS)

View File

@@ -112,7 +112,7 @@ words:
else if((p=strstr($2,".PP.NMS"))) {p[0]=' ';p[3]=' ';}
else if((p=strstr($2,".NPP.MS"))) {p[0]=' ';p[4]=' ';}
else if((p=strstr($2,".NPP.NMS"))) {p[0]=' ';p[4]=' ';}
else if(strlen(curr_value)>0) { strcat(curr_value," "); }
else if(strlen(curr_value)>(size_t)0) { strcat(curr_value," "); }
strcat(curr_value,$2);
}
;

View File

@@ -1,6 +1,6 @@
/* $Id$ */
/* cvtBpt.c - Convert using breakpoint table
/* cvtBpt.c - Convert using breakpoint table */
/*
* Author: Janet Anderson
* Date: 9-19-91

View File

@@ -94,6 +94,7 @@
#include <errMdef.h>
#include <recSup.h>
#include <special.h>
#include <asLib.h>
extern struct dbBase *pdbBase;
extern long lset_stack_not_empty;
@@ -297,8 +298,6 @@ long dbProcess(struct dbCommon *precord)
static char trace=0;
static int trace_lset=0;
int set_trace=FALSE;
long options=0;
long nRequest=1;
/*
* Note that it is likely that if any changes are made
@@ -377,7 +376,7 @@ long dbProcess(struct dbCommon *precord)
/*take care of caching and notifyCompletion*/
precord->rpro = FALSE;
if (precord->ppn)
dbNotifyCompletion(precord->ppn);
dbNotifyCompletion(precord);
/* raise disable alarm */
if (precord->stat==DISABLE_ALARM)
@@ -681,7 +680,7 @@ long dbFastLinkPut(
}
}
else if (special == SPC_AS) {
asChangeGroup(&pdest->asp, pdest->asg);
asChangeGroup((ASMEMBERPVT *)&pdest->asp, pdest->asg);
}
}
else {

View File

@@ -87,6 +87,7 @@
#include <errMdef.h>
#include <recSup.h>
#include <special.h>
#include <asLib.h>
extern struct dbBase *pdbBase;
@@ -186,6 +187,7 @@ long dbPutField(
if((paddr->pfield==(void *)&precord->proc)
||(pfldDes->process_passive && precord->scan==0 && dbrType<DBR_PUT_ACKT)) {
if(precord->pact) {
if(precord->tpro) printf("active: %s\n",precord->name);
precord->rpro = TRUE;
} else {
/*indicate that dbPutField called dbProcess*/
@@ -2810,7 +2812,7 @@ void *pflin
memset(pbuffer,'\0',dbr_units_size);
*options = (*options) ^ DBR_UNITS; /*Turn off DBR_UNITS*/
}
pbuffer += dbr_units_size;
pbuffer = (char *)pbuffer + dbr_units_size;
}
if( (*options) & DBR_PRECISION ) {
struct dbr_precision *pdbr_precision=( struct dbr_precision *)pbuffer;
@@ -2823,7 +2825,7 @@ void *pflin
memset(pbuffer,'\0',dbr_precision_size);
*options = (*options) ^ DBR_PRECISION; /*Turn off DBR_PRECISION*/
}
pbuffer += dbr_precision_size;
pbuffer = (char *)pbuffer + dbr_precision_size;
}
if( (*options) & DBR_TIME ) {
if(pfl!=NULL) {
@@ -2961,7 +2963,7 @@ choice_common:
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
break;
}
*ppbuffer += dbr_enumStrs_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
return;
}
@@ -2986,7 +2988,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_grLong_size);
*options = (*options) ^ DBR_GR_LONG; /*Turn off option*/
}
*ppbuffer += dbr_grLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size;
}
if( (*options) & (DBR_GR_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -2999,7 +3001,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_grDouble_size);
*options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_grDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size;
}
return;
}
@@ -3025,7 +3027,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_ctrlLong_size);
*options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/
}
*ppbuffer += dbr_ctrlLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size;
}
if( (*options) & (DBR_CTRL_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -3038,7 +3040,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_ctrlDouble_size);
*options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_ctrlDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size;
}
return;
}
@@ -3066,7 +3068,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_alLong_size);
*options = (*options) ^ DBR_AL_LONG; /*Turn off option*/
}
*ppbuffer += dbr_alLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_alLong_size;
}
if( (*options) & (DBR_AL_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -3081,7 +3083,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_alDouble_size);
*options = (*options) ^ DBR_AL_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_alDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_alDouble_size;
}
return;
}
@@ -3227,19 +3229,21 @@ long no_elements;
long offset;
{
unsigned short *pdest=(unsigned short *)paddr->pfield;
unsigned short value;
float value;
/*Convert to float first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned short as float*/
if(nRequest==1 && offset==0) {
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
return(0);
}
else return(-1);
}
pdest += offset;
while (nRequest) {
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
} else {
return(-1);
}
@@ -3295,19 +3299,21 @@ long no_elements;
long offset;
{
unsigned long *pdest=(unsigned long *)paddr->pfield;
unsigned long value;
double value;
/*Convert to double first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned long as double*/
if(nRequest==1 && offset==0) {
if(sscanf(pbuffer,"%lu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%lf",&value) == 1) {
*pdest = (unsigned long)value;
return(0);
}
else return(-1);
}
pdest += offset;
while (nRequest) {
if(sscanf(pbuffer,"%lu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%lf",&value) == 1) {
*pdest = (unsigned long)value;
} else {
return(-1);
}
@@ -5675,7 +5681,6 @@ long no_elements;
long offset;
{
struct dbCommon *precord=(struct dbCommon *)(paddr->precord);
unsigned short acks=precord->acks;
if(*pbuffer >= precord->acks) {
precord->acks = 0;
@@ -5831,7 +5836,7 @@ long dbPut(
if(special==SPC_SCAN) {
scanAdd(precord);
} else if(special==SPC_AS) {
asChangeGroup(&precord->asp,precord->asg);
asChangeGroup((ASMEMBERPVT *)&precord->asp,precord->asg);
}
}
else {

View File

@@ -35,7 +35,10 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <semLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <fast_lock.h>
@@ -45,185 +48,325 @@
#include <dbScan.h>
#include <dbCommon.h>
#include <errMdef.h>
#include <ellLib.h>
/*NODE structure attached to ppnn field of each record in list*/
typedef struct {
ELLNODE node;
struct dbCommon *precord;
} PNWAITNODE;
/*Local routines*/
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom);
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn);
static long putNotify(PUTNOTIFY *ppn);
static void notifyCallback(CALLBACK *pcallback);
static void notifyCancel(PUTNOTIFY *ppn);
static void issueCallback(PUTNOTIFY *ppn);
/*callbackState values */
typedef enum {
callbackNotActive,callbackActive,callbackCanceled}callbackState;
static void notifyCallback(CALLBACK *pcallback)
{
PUTNOTIFY *ppn=NULL;
long status;
/* This module provides code to handle put notify. If a put causes a record to
* be processed, then a user supplied callback is called when that record
* and all records processed because of that record complete processing.
* For asynchronous records completion means completion of the asyn phase.
*
* User code calls dbPutNotify and dbNotifyCancel.
*
* The other global routines (dbNotifyAdd and dbNotifyCompletion) are called by:
*
* dbAccess.c
* dbScanPassive and dbScanLink
* call dbNotifyAdd just before calling dbProcess
* dbProcess
* Calls dbNotifyCompletion if record is disabled.
* recGbl
* recGblFwdLink calls dbNotifyCompletion
*/
callbackGetUser(ppn,pcallback);
if(ppn->cmd==notifyCmdRepeat) {
status = dbPutNotify(ppn);
} else if(ppn->cmd==notifyCmdCallUser) {
ppn->cmd = notifyUserCalled;
(ppn->userCallback)(ppn);
} else {/*illegal request*/
recGblRecordError(-1,ppn->paddr->precord,
"dbNotifyCompletion: illegal callback request");
}
}
static void notifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
while(precord) {
void *pnext;
if(precord->rpro) {
precord->rpro = FALSE;
scanOnce(precord);
}
precord->ppn = NULL;
pnext = precord->ppnn;
precord->ppnn = NULL;
precord = pnext;
}
ppn->list = NULL;
}
void dbNotifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
if(!precord) return;
dbScanLock(precord);
notifyCancel(ppn);
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
/*Bad lets try one time to wait*/
dbScanUnlock(precord);
taskDelay(10);
dbScanLock(precord);
}
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
epicsPrintf("dbNotifyCancel called while callback requested"
" but not called\n");
}
dbScanUnlock(precord);
}
static void issueCallback(PUTNOTIFY *ppn, notifyCmd cmd)
{
if(ppn->cmd!=notifyCmdNull) return;
ppn->cmd = cmd;
notifyCancel(ppn);
callbackRequest(&ppn->callback);
}
/* Two fields in dbCommon are used for put notify.
* ppn
* If a record is part of a put notify group,
* This field is tha address of the associated PUTNOTIFY.
* As soon as a record completes processing the field is set NULL
* ppnn
* Address of an PNWAITNODE for keeping list of records in a
* put notify group. Once an PNWAITNODE is allocated for a record,
* it is never freed under the assumption that once a record
* becomes part of a put notify group it is likely to become
* one again in the future.
*/
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom)
{
ppnfrom->restartNode.ppn = ppnfrom;
ppnfrom->restartNode.ppnrestartList = ppnto;
ppnfrom->restart = TRUE;
ellAdd(&ppnto->restartList,&ppnfrom->restartNode.node);
}
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn)
{
PNWAITNODE *ppnnode;
if(!precord->ppnn) precord->ppnn = dbCalloc(1,sizeof(PNWAITNODE));
ppnnode = (PNWAITNODE *)precord->ppnn;
ppnnode->precord = precord;
precord->ppn = ppn;
ellAdd(&ppn->waitList,&ppnnode->node);
}
long dbPutNotify(PUTNOTIFY *ppn)
{
long status;
struct dbCommon *precord = ppn->paddr->precord;
dbScanLock(precord);
ellInit(&ppn->restartList);
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
status = putNotify(ppn);
dbScanUnlock(precord);
return(status);
}
static long putNotify(PUTNOTIFY *ppn)
{
struct dbAddr *paddr = ppn->paddr;
short dbrType = ppn->dbrType;
void *pbuffer = ppn->pbuffer;
long nRequest = ppn->nRequest;
long status=0;
short dbrType = ppn->dbrType;
void *pbuffer = ppn->pbuffer;
long nRequest = ppn->nRequest;
long status=0;
struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes);
struct dbCommon *precord = (struct dbCommon *)(paddr->precord);
if(precord->ppn == ppn) {
return(S_db_Blocked);
}
/*Initialize everything in PUTNOTIFY except restart list and node*/
callbackSetCallback(notifyCallback,&ppn->callback);
callbackSetUser(ppn,&ppn->callback);
callbackSetPriority(priorityLow,&ppn->callback);
ppn->status = 0;
ppn->restart = FALSE;
ppn->callbackState = callbackNotActive;
ellInit(&ppn->waitList);
/*check for putField disabled*/
if(precord->disp) {
if((void *)(&precord->disp) != paddr->pfield) {
ppn->status = S_db_putDisabled;
issueCallback(ppn,notifyCmdCallUser);
return(S_db_putDisabled);
issueCallback(ppn);
goto ret_pending;
}
}
ppn->status = 0;
ppn->cmd = notifyCmdNull;
ppn->nwaiting = 1;
ppn->rescan = FALSE;
dbScanLock(precord);
if(precord->ppn) {/*Another put notify is in progress*/
restartAdd(precord->ppn,ppn);
goto ret_pending;
}
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
precord->ppn = ppn;
waitAdd(precord,ppn);
restartAdd(precord->ppn,ppn);
goto ret_pending;
}
status=dbPut(paddr,dbrType,pbuffer,nRequest);
ppn->status = status;
if(status==0){
if((paddr->pfield==(void *)&precord->proc)
||(pfldDes->process_passive && precord->scan==0)) {
if(precord->ppn) {
/*record already has attached ppn. Blocked*/
ppn->status = status = S_db_Blocked;
dbScanUnlock(precord);
return(status);
}
precord->ppn = ppn;
precord->ppnn = NULL;
ppn->list = precord;
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
ppn->rescan = TRUE;
dbScanUnlock(precord);
return(S_db_Pending);
}
status=dbProcess(precord);
if(status!=0) {
ppn->status = status;
issueCallback(ppn,notifyCmdCallUser);
}
} else { /*Make callback immediately*/
issueCallback(ppn,notifyCmdCallUser);
}
if(status) {
ppn->status = status;
issueCallback(ppn);
goto ret_pending;
}
/*check for no processing required*/
if(!(paddr->pfield==(void *)&precord->proc)
&& (!pfldDes->process_passive || precord->scan!=0)) {
issueCallback(ppn);
goto ret_pending;
}
dbScanUnlock(precord);
/*Add record to waitlist*/
waitAdd(precord,ppn);
status=dbProcess(precord);
if(status!=0) {
ppn->status = status;
issueCallback(ppn);
}
ret_pending:
return(S_db_Pending);
}
void dbNotifyCompletion(PUTNOTIFY *ppn)
static void notifyCallback(CALLBACK *pcallback)
{
PUTNOTIFY *ppn=NULL;
struct dbCommon *precord;
if(ppn->status!=0) {
issueCallback(ppn,notifyCmdCallUser);
callbackGetUser(ppn,pcallback);
precord = ppn->paddr->precord;
dbScanLock(precord);
if(ppn->callbackState==callbackCanceled) {
dbScanUnlock(precord);
ppn->restart = FALSE;
ppn->callbackState = callbackNotActive;
semGive((SEM_ID)ppn->waitForCallback);
return;
}
/*decrement number of records being waited on*/
if(ppn->nwaiting<=0) {
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: nwaiting<-0 LOGIC");
return;
}
if(--ppn->nwaiting == 0) {/*original request completed*/
if(ppn->rescan) {
issueCallback(ppn,notifyCmdRepeat);
if(ppn->callbackState==callbackActive) {
if(ppn->restart) {
putNotify(ppn);
dbScanUnlock(precord);
} else {
issueCallback(ppn,notifyCmdCallUser);
dbScanUnlock(precord);
(ppn->userCallback)(ppn);
}
}
}
/*Remove all nonactive records from put notify list*/
void cleanPpList(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
struct dbCommon *pnext;
struct dbCommon *pprev=NULL;
while(precord) {
pnext = precord->ppnn;
if(!precord->pact) {
if(!pprev) ppn->list = pnext; else pprev->ppnn = pnext;
precord->ppn = NULL;
precord->ppnn = NULL;
} else {
pprev = precord;
static void issueCallback(PUTNOTIFY *ppn)
{
notifyCancel(ppn);
ppn->callbackState = callbackActive;
callbackRequest(&ppn->callback);
}
void dbNotifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->paddr->precord;;
dbScanLock(precord);
notifyCancel(ppn);
if(ppn->callbackState == callbackActive) {
ppn->waitForCallback = (void *)semBCreate(SEM_Q_FIFO,SEM_FULL);
ppn->callbackState = callbackCanceled;
dbScanUnlock(precord);
if(semTake((SEM_ID)ppn->waitForCallback,sysClkRateGet()*10)!=OK) {
errMessage(0,"dbNotifyCancel had semTake timeout");
ppn->callbackState = callbackNotActive;
}
precord = pnext;
semDelete((SEM_ID)ppn->waitForCallback);
} else {
dbScanUnlock(precord);
}
}
static void notifyCancel(PUTNOTIFY *ppn)
{
PNWAITNODE *ppnnode;
struct dbCommon *precord;
PNRESTARTNODE *pfirst;
/*Remove everything on waitList*/
while(ppnnode = (PNWAITNODE *)ellLast(&ppn->waitList)) {
precord = ppnnode->precord;
precord->ppn = NULL;
ellDelete(&ppn->waitList,&ppnnode->node);
}
/*If on restartList remove it*/
if(ppn->restartNode.ppnrestartList)
ellDelete(&ppn->restartNode.ppnrestartList->restartList,
&ppn->restartNode.node);
/*If this ppn has a restartList move it */
if(pfirst = (PNRESTARTNODE *)ellFirst(&ppn->restartList)) {
PNRESTARTNODE *pnext;
PUTNOTIFY *pfirstppn;
pfirstppn = pfirst->ppn;
ellConcat(&pfirstppn->restartList,&ppn->restartList);
pnext = (PNRESTARTNODE *)ellFirst(&pfirstppn->restartList);
while(pnext) {
pnext->ppnrestartList = pfirstppn;
pnext = (PNRESTARTNODE *)ellNext(&pnext->node);
}
pfirstppn->restart = TRUE;
pfirstppn->callbackState = callbackActive;
callbackRequest(&pfirstppn->callback);
}
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
}
void dbNotifyCompletion(struct dbCommon *precord)
{
PUTNOTIFY *ppn = (PUTNOTIFY *)precord->ppn;
PNWAITNODE *ppnnode = (PNWAITNODE *)precord->ppnn;;
ellDelete(&ppn->waitList,&ppnnode->node);
precord->ppn = NULL;
if((ppn->status!=0) || (ellCount(&ppn->waitList)==0))
issueCallback(ppn);
}
void dbNotifyAdd(struct dbCommon *pfrom, struct dbCommon *pto)
{
PUTNOTIFY *ppn = pfrom->ppn;
PUTNOTIFY *pfromppn = (PUTNOTIFY *)pfrom->ppn;
PUTNOTIFY *ppn=NULL;
if(pto->ppn) cleanPpList(pto->ppn); /* clean list before giving up*/
if(pto->ppn == pfrom->ppn) return; /*Aready in same set*/
if (pto->ppn) { /*already being used. Abandon request*/
ppn->status = S_db_Blocked;
dbNotifyCompletion(ppn);
notifyCancel(pfrom->ppn);
restartAdd(pto->ppn,pfromppn);
return;
} else {
ppn->nwaiting++;
pto->ppn = pfrom->ppn;
pto->ppnn = ppn->list;
ppn->list = pto;
/*If already active must redo*/
if(pto->pact) ppn->rescan = TRUE;
/*If already active must redo*/
if(pto->pact) {
ppn = pfrom->ppn;
notifyCancel(pfrom->ppn);
waitAdd(pto,ppn);
restartAdd(pto->ppn,ppn);
} else {
waitAdd(pto,pfrom->ppn);
}
}
}
static void dbtpnCallback(PUTNOTIFY *ppn)
{
DBADDR *pdbaddr = ppn->paddr;
long status = ppn->status;
if(status==S_db_Blocked)
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord->name);
else if(status==0)
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord->name);
else
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
free((void *)pdbaddr);
free(ppn);
}
long dbtpn(char *pname,char *pvalue)
{
long status;
DBADDR *pdbaddr=NULL;
PUTNOTIFY *ppn=NULL;
char *psavevalue;
int len;
len = strlen(pvalue);
/*allocate space for value immediately following DBADDR*/
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
psavevalue = (char *)(pdbaddr + 1);
strcpy(psavevalue,pvalue);
status = dbNameToAddr(pname,pdbaddr);
if(status) {
errMessage(status, "dbtpn: dbNameToAddr");
free((void *)pdbaddr);
return(-1);
}
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
ppn->paddr = pdbaddr;
ppn->pbuffer = psavevalue;
ppn->nRequest = 1;
ppn->dbrType = DBR_STRING;
ppn->userCallback = dbtpnCallback;
status = dbPutNotify(ppn);
if(status==S_db_Pending) {
printf("dbtpn: Pending nwaiting=%d\n",ellCount(&ppn->waitList));
return(0);
}
if(status==S_db_Blocked) {
printf("dbtpn: blocked record=%s\n",pname);
} else if(status) {
errMessage(status, "dbtpn");
}
return(0);
}

View File

@@ -66,7 +66,6 @@
#include <dbStaticLib.h>
extern struct dbBase *pdbBase;
extern volatile int interruptAccept;
/* SCAN ONCE */
#define ONCE_QUEUE_SIZE 256
@@ -146,7 +145,7 @@ long scanInit()
void post_event(int event)
{
unsigned char evnt;
int status;
static int newOverflow=TRUE;
if (!interruptAccept) return; /* not awake yet */
if(event<0 || event>=MAX_EVENTS) {
@@ -156,14 +155,13 @@ void post_event(int event)
evnt = (unsigned)event;
/*multiple writers can exist. Thus if evnt is ever changed to use*/
/*something bigger than a character interrupts will have to be blocked*/
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char))
errMessage(0,"rngBufPut overflow in post_event");
if((status=semGive(eventSem))!=OK){
/*semGive randomly returns garbage value*/
/*
errMessage(0,"semGive returned error in post_event");
*/
}
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char)) {
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
newOverflow = FALSE;
} else {
newOverflow = TRUE;
}
semGive(eventSem);
}
@@ -382,8 +380,14 @@ void scanIoRequest(IOSCANPVT pioscanpvt)
void scanOnce(void *precord)
{
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord))
errMessage(0,"rngBufPut overflow in scanOnce");
static int newOverflow=TRUE;
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord)) {
if(newOverflow)errMessage(0,"rngBufPut overflow in scanOnce");
newOverflow = FALSE;
}else {
newOverflow = TRUE;
}
semGive(onceSem);
}
@@ -598,7 +602,7 @@ static void printList(struct scan_list *psl,char *message)
struct scan_element *pse;
FASTLOCK(&psl->lock);
(void *)pse = ellFirst(&psl->list);
pse = (struct scan_element *)ellFirst(&psl->list);
FASTUNLOCK(&psl->lock);
if(pse==NULL) return;
printf("%s\n",message);
@@ -610,7 +614,7 @@ static void printList(struct scan_list *psl,char *message)
printf("Returning because list changed while processing.");
return;
}
(void *)pse = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
}
}
@@ -624,9 +628,9 @@ static void scanList(struct scan_list *psl)
FASTLOCK(&psl->lock);
psl->modified = FALSE;
(void *)pse = ellFirst(&psl->list);
pse = (struct scan_element *)ellFirst(&psl->list);
prev = NULL;
(void *)next = ellNext((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
while(pse!=NULL) {
struct dbCommon *precord = pse->precord;
@@ -637,27 +641,27 @@ static void scanList(struct scan_list *psl)
FASTLOCK(&psl->lock);
if(!psl->modified) {
prev = pse;
(void *)pse = ellNext((void *)pse);
if(pse!=NULL) (void *)next = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
} else if (pse->pscan_list==psl) {
/*This scan element is still in same scan list*/
prev = pse;
(void *)pse = ellNext((void *)pse);
if(pse!=NULL) (void *)next = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else if (prev!=NULL && prev->pscan_list==psl) {
/*Previous scan element is still in same scan list*/
(void *)pse = ellNext((void *)prev);
pse = (struct scan_element *)ellNext((void *)prev);
if(pse!=NULL) {
(void *)prev = ellPrevious((void *)pse);
(void *)next = ellNext((void *)pse);
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
}
psl->modified = FALSE;
} else if (next!=NULL && next->pscan_list==psl) {
/*Next scan element is still in same scan list*/
pse = next;
(void *)prev = ellPrevious((void *)pse);
(void *)next = ellNext((void *)pse);
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else {
/*Too many changes. Just wait till next period*/
@@ -703,17 +707,17 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
if(pse==NULL) {
pse = dbCalloc(1,sizeof(struct scan_element));
precord->spvt = (void *)pse;
(void *)pse->precord = precord;
pse->precord = precord;
}
pse ->pscan_list = psl;
(void *)ptemp = ellFirst(&psl->list);
ptemp = (struct scan_element *)ellFirst(&psl->list);
while(ptemp!=NULL) {
if(ptemp->precord->phas>precord->phas) {
ellInsert(&psl->list,
ellPrevious((void *)ptemp),(void *)pse);
break;
}
(void *)ptemp = ellNext((void *)ptemp);
ptemp = (struct scan_element *)ellNext((void *)ptemp);
}
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
psl->modified = TRUE;

View File

@@ -57,6 +57,15 @@
#define messagesize 100
#define RPCL_LEN 184
#if defined(EPICS_LITTLE_ENDIAN)
#define BYTE_SWAP_4(A) \
( (((A) & 0xFF) << 24 ) | \
(((A) & 0xFF00) << 8) | \
(((A) & 0xFF0000) >> 8) | \
(((A) & 0xFF000000) >> 24) )
#endif
long postfix(char *pinfix, char *ppostfix,short *perror);
static char *ppstring[2]={"NPP","PP"};
@@ -740,7 +749,7 @@ char *precordName;
struct recLoc *precLoc = NULL;
short rec_size;
if(strlen(precordName)>PVNAME_SZ) return(S_dbLib_nameLength);
if(strlen(precordName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
/* clear callers entry */
zeroDbentry(pdbentry);
if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists);
@@ -938,7 +947,7 @@ char *newName;
long status;
DBENTRY dbentry;
if(strlen(newName)>PVNAME_SZ) return(S_dbLib_nameLength);
if(strlen(newName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
if(!precnode) return(S_dbLib_recNotFound);
dbInitEntry(pdbentry->pdbbase,&dbentry);
status = dbFindRecord(&dbentry,newName);
@@ -1008,15 +1017,23 @@ char *pfieldName;
bottom = 0;
test = (top + bottom) / 2;
while (1) {
unsigned int t1, t2;
/* check the field name */
if (sortFldName[test] == *(unsigned long *) pconvName) {
t1 = (unsigned int) sortFldName[ test];
t2 = (unsigned int) *(unsigned int*)pconvName;
#if defined(EPICS_LITTLE_ENDIAN)
t1 = BYTE_SWAP_4( t1);
t2 = BYTE_SWAP_4( t2);
#endif
if(t1 == t2) {
if(!(pflddes=GET_PFLDDES(precTypDes,sortFldInd[test])))
return(S_dbLib_recdesNotFound);
pdbentry->pflddes = pflddes;
pdbentry->pfield = precord + pflddes->offset;
pdbentry->indfield = sortFldInd[test];
return (0);
} else if (sortFldName[test] > *(unsigned long *) pconvName) {
} else if (t1 > t2) {
top = test - 1;
if (top < bottom) return (S_dbLib_fieldNotFound);
test = (top + bottom) / 2;
@@ -1591,7 +1608,7 @@ char *pstring;
if (!(pchoice = pdevChoiceSet->papDevChoice[i]->pchoice))
continue;
if (strcmp(pchoice, pstring) == 0) {
long link_type,status;
long link_type;
link_type = pdevChoiceSet->papDevChoice[i]->link_type;
/*If no INP or OUT OK */
@@ -1623,7 +1640,7 @@ char *pstring;
if(pstr[ind]!=' ' && pstr[ind]!='\t') break;
pstr[ind] = '\0';
}
if(!pstr || strlen(pstr)<=0 ) {
if(!pstr || strlen(pstr)==0 ) {
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
if(plink->type!=CONSTANT) return(S_dbLib_badField);
return(0);
@@ -1689,12 +1706,18 @@ char *pstring;
if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.n);
if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.a);
if(!(end = strchr(pstr,'F'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.f);
if(!(end = strchr(pstr,'A'))) {
plink->value.camacio.a = 0;
} else {
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.a);
}
if(!(end = strchr(pstr,'F'))) {
plink->value.camacio.f = 0;
} else {
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.f);
}
plink->value.camacio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
@@ -4127,16 +4150,29 @@ FILE *fp;
}
/* Beginning of Process Variable Directory Routines*/
#define HASH_NO 512 /* number of hash table entries */
int dbPvdHashTableSize = 512;
static int dbPvdHashTableShift;
#define NTABLESIZES 9
static struct {
unsigned int tablesize;
int shift;
}hashTableParms[9] = {
{256,0},
{512,1},
{1024,2},
{2048,3},
{4096,4},
{8192,5},
{16384,6},
{32768,7},
{65536,8}
};
/*The hash algorithm is a modification of the algorithm described in */
/* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */
/* Communications of the ACM, June 1990 */
/* The modifications were desdigned by Marty Kraimer and Ben Chin Cha */
/* The mods were implemented and tested by Ben Chin Cha */
/* The modifications were designed by Marty Kraimer */
static unsigned char T0[256] = {
static unsigned char T[256] = {
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
@@ -4155,45 +4191,24 @@ static unsigned char T0[256] = {
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47
};
static unsigned char T1[256] = {
9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124,
254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187,
45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253,
42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14,
182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23,
189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105,
102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142,
220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91,
214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43,
11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231,
111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238,
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47,
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51,
};
#ifdef __STDC__
static unsigned short hash( char *pname, int length)
#else
static unsigned short hash( pname, length)
char *pname;
int length;
#endif /*__STDC__*/
{
unsigned short h=0;
unsigned short hret;
unsigned char *h0=(unsigned char *)&h;
unsigned char *h1= h0 + 1;
unsigned char h0=0;
unsigned char h1=0;
unsigned short ind0,ind1;
int even = TRUE;
unsigned char c;
int i;
for(i=0; i<length; i+=2, pname+=2) {
*h0 = T0[*h0 ^ *pname];
*h1 = T1[*h1 ^ *(pname+1)];
for(i=0; i<length; i++, pname++) {
c = *pname;
if(even) {h0 = T[h0^c]; even = FALSE;}
else {h1 = T[h1^c]; even = TRUE;}
}
hret = *h0;
return(hret + *h1);
ind0 = (unsigned short)h0;
ind1 = (unsigned short)h1;
return((ind1<<dbPvdHashTableShift) ^ ind0);
}
#ifdef __STDC__
@@ -4203,9 +4218,19 @@ void dbPvdInitPvt(pdbbase)
DBBASE *pdbbase;
#endif /*__STDC__*/
{
ELLLIST **ppvd;
ELLLIST **ppvd;
int i;
ppvd = dbCalloc(HASH_NO, sizeof(ELLLIST *));
for(i=0; i< NTABLESIZES; i++) {
if((i==NTABLESIZES-1)
||((dbPvdHashTableSize>=hashTableParms[i].tablesize)
&& (dbPvdHashTableSize<hashTableParms[i+1].tablesize))) {
dbPvdHashTableSize = hashTableParms[i].tablesize;
dbPvdHashTableShift = hashTableParms[i].shift;
break;
}
}
ppvd = dbCalloc(dbPvdHashTableSize, sizeof(ELLLIST *));
pdbbase->ppvd = (void *) ppvd;
return;
}
@@ -4315,7 +4340,7 @@ DBBASE *pdbbase;
PVDENTRY *next;
if (ppvd == NULL) return;
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
if(ppvd[hashInd] == NULL) continue;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
@@ -4331,10 +4356,11 @@ DBBASE *pdbbase;
}
#ifdef __STDC__
void dbPvdDump(DBBASE *pdbbase)
void dbPvdDump(DBBASE *pdbbase,int verbose)
#else
void dbPvdDump(pdbbase)
void dbPvdDump(pdbbase,verbose)
DBBASE *pdbbase;
int verbose;
#endif /*__STDC__*/
{
unsigned short hashInd;
@@ -4344,14 +4370,16 @@ DBBASE *pdbbase;
int number;
if (ppvd == NULL) return;
printf("Process Variable Directory\n");
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
printf("Process Variable Directory ");
printf("dbPvdHashTableSize %d dbPvdHashTableShift %d\n",
dbPvdHashTableSize,dbPvdHashTableShift);
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
if(ppvd[hashInd] == NULL) continue;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
printf(" %3.3hd=%3.3d\n",hashInd,ellCount(ppvdlist));
printf("\n%3.3hd=%3.3d ",hashInd,ellCount(ppvdlist));
number=0;
while(ppvdNode) {
while(ppvdNode && verbose) {
printf(" %s",(char *)ppvdNode->precnode->precord);
if(number++ ==2) {number=0;printf("\n ");}
ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode);

View File

@@ -40,6 +40,7 @@
* .09 09-24-93 jbk adjusted dbpr to print vxi links correctly
* .10 02-02-94 mrk added dbtpn (test dbPutNotify)
* .11 03-18-94 mcn added dbgrep and timing routines.
* .12 08-14-95 mrk Moved dbtpn to dbNotify
*/
/* Global Database Test Routines - All can be invoked via vxWorks shell
@@ -76,10 +77,6 @@
* char *pname;
* char *pvalue
*
* dbtpn(pname,pvalue) test put notify
* char *pname;
* char *pvalue
*
* dbior(pname,type) io_report
* char *pname Driver name. If null all drivers
* int type <0,1> => <short, full> report
@@ -292,8 +289,6 @@ long dbgrep(char *pmask)
int rectype, beg, end;
struct recLoc *precLoc;
struct dbCommon *precord;
char *pstr;
char name[PVNAME_SZ+1];
struct recType *precType;
struct recHeader *precHeader;
RECNODE *precNode;
@@ -699,59 +694,6 @@ long dbtpf(char *pname,char *pvalue)
return(0);
}
static void dbtpnCallback(PUTNOTIFY *ppn)
{
DBADDR *pdbaddr = ppn->paddr;
long status = ppn->status;
if(status==S_db_Blocked)
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord);
else if(status==0)
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord);
else
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
free((void *)pdbaddr);
free(ppn);
}
long dbtpn(char *pname,char *pvalue)
{
long status;
DBADDR *pdbaddr=NULL;
PUTNOTIFY *ppn=NULL;
char *psavevalue;
int len;
len = strlen(pvalue);
/*allocate space for value immediately following DBADDR*/
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
psavevalue = (char *)(pdbaddr + 1);
strcpy(psavevalue,pvalue);
status = dbNameToAddr(pname,pdbaddr);
if(status) {
errMessage(status, "dbtpn: dbNameToAddr");
free((void *)pdbaddr);
return(-1);
}
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
ppn->paddr = pdbaddr;
ppn->pbuffer = psavevalue;
ppn->nRequest = 1;
ppn->dbrType = DBR_STRING;
ppn->userCallback = dbtpnCallback;
status = dbPutNotify(ppn);
if(status==S_db_Pending) {
printf("dbtpn: Pending nwaiting=%d\n",ppn->nwaiting);
return(0);
}
if(status==S_db_Blocked) {
printf("dbtpn: blocked record=%s\n",pname);
} else if(status) {
errMessage(status, "dbtpn");
}
return(0);
}
long dbior(char *pdrvName,int type)
{
int i,j;
@@ -914,7 +856,7 @@ static void printBuffer(
pdbr_status->status, pdbr_status->severity);
} else
printf("status and severity not returned\n");
pbuffer += dbr_status_size;
pbuffer = (char *)pbuffer + dbr_status_size;
}
if (reqOptions & DBR_UNITS) {
if (retOptions & DBR_UNITS) {
@@ -924,7 +866,7 @@ static void printBuffer(
}else{
printf("units not returned\n");
}
pbuffer += dbr_units_size;
pbuffer = (char *)pbuffer + dbr_units_size;
}
if (reqOptions & DBR_PRECISION) {
precision = *((long *) pbuffer);
@@ -935,7 +877,7 @@ static void printBuffer(
}else{
printf("precision not returned\n");
}
pbuffer += dbr_precision_size;
pbuffer = (char *)pbuffer + dbr_precision_size;
}
if (reqOptions & DBR_TIME) {
if (retOptions & DBR_TIME) {
@@ -946,7 +888,7 @@ static void printBuffer(
}else{
printf("time not returned\n");
}
pbuffer += dbr_time_size;
pbuffer = (char *)pbuffer + dbr_time_size;
}
if (reqOptions & DBR_ENUM_STRS) {
if (retOptions & DBR_ENUM_STRS) {
@@ -957,7 +899,7 @@ static void printBuffer(
printf("%s\n",&pdbr_enumStrs->strs[i][0]);
} else
printf("enum strings not returned\n");
pbuffer += dbr_enumStrs_size;
pbuffer = (char *)pbuffer + dbr_enumStrs_size;
}
if (reqOptions & DBR_GR_LONG) {
if (retOptions & DBR_GR_LONG) {
@@ -968,7 +910,7 @@ static void printBuffer(
}else{
printf("DBRgrLong not returned\n");
}
pbuffer += dbr_grLong_size;
pbuffer = (char *)pbuffer + dbr_grLong_size;
}
if (reqOptions & DBR_GR_DOUBLE) {
if (retOptions & DBR_GR_DOUBLE) {
@@ -979,7 +921,7 @@ static void printBuffer(
}else{
printf("DBRgrDouble not returned\n");
}
pbuffer += dbr_grDouble_size;
pbuffer = (char *)pbuffer + dbr_grDouble_size;
}
if (reqOptions & DBR_CTRL_LONG) {
if (retOptions & DBR_CTRL_LONG){
@@ -990,7 +932,7 @@ static void printBuffer(
}else{
printf("DBRctrlLong not returned\n");
}
pbuffer += dbr_ctrlLong_size;
pbuffer = (char *)pbuffer + dbr_ctrlLong_size;
}
if (reqOptions & DBR_CTRL_DOUBLE) {
if (retOptions & DBR_CTRL_DOUBLE) {
@@ -1001,7 +943,7 @@ static void printBuffer(
}else{
printf("DBRctrlDouble not returned\n");
}
pbuffer += dbr_ctrlDouble_size;
pbuffer = (char *)pbuffer + dbr_ctrlDouble_size;
}
if (reqOptions & DBR_AL_LONG) {
if (retOptions & DBR_AL_LONG) {
@@ -1013,7 +955,7 @@ static void printBuffer(
}else{
printf("DBRalLong not returned\n");
}
pbuffer += dbr_alLong_size;
pbuffer = (char *)pbuffer + dbr_alLong_size;
}
if (reqOptions & DBR_AL_DOUBLE) {
if (retOptions & DBR_AL_DOUBLE) {
@@ -1025,7 +967,7 @@ static void printBuffer(
}else{
printf("DBRalDouble not returned\n");
}
pbuffer += dbr_alDouble_size;
pbuffer = (char *)pbuffer + dbr_alDouble_size;
}
/* Now print values */
if (no_elements == 0) return;
@@ -1044,7 +986,7 @@ static void printBuffer(
sprintf(pmsg, " %s", (char *)pbuffer);
dbpr_msgOut(pMsgBuff, tab_size);
}
pbuffer += MAX_STRING_SIZE;
pbuffer = (char *)pbuffer + MAX_STRING_SIZE;
}
break;
case (DBR_CHAR):
@@ -1059,7 +1001,7 @@ static void printBuffer(
svalue = *(char *) pbuffer;
sprintf(pmsg, "%-9d 0x%-9x", svalue,svalue);
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 1;
pbuffer = (char *)pbuffer + 1;
}
break;
case (DBR_UCHAR):
@@ -1074,7 +1016,7 @@ static void printBuffer(
usvalue = *(unsigned char *) pbuffer;
sprintf(pmsg, "%-9d 0x%-9x", usvalue,usvalue);
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 1;
pbuffer = (char *)pbuffer + 1;
}
break;
case (DBR_SHORT):
@@ -1088,7 +1030,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9d 0x%-9x", *((short *) pbuffer), *((short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(short);
}
break;
case (DBR_USHORT):
@@ -1102,7 +1044,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9u 0x%-9x",*((unsigned short *) pbuffer),*((unsigned short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(unsigned short);
}
break;
case (DBR_LONG):
@@ -1116,7 +1058,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9ld 0x%-9lx", *((long *) pbuffer), *((long *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(long);
}
break;
case (DBR_ULONG):
@@ -1130,7 +1072,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9ld 0x%-9lx",*((unsigned long *) pbuffer),*((unsigned long *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(unsigned long);
}
break;
case (DBR_FLOAT):
@@ -1144,7 +1086,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-13.6g", *((float *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(float);
}
break;
case (DBR_DOUBLE):
@@ -1158,7 +1100,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-13.6g", *((double *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 8;
pbuffer = (char *)pbuffer + sizeof(double);
}
break;
case (DBR_ENUM):
@@ -1172,7 +1114,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9u", *((unsigned short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(unsigned short);
}
break;
default:
@@ -1819,4 +1761,56 @@ char *record_name;
return(0);
}
int dbllsdblinks(int lset)
{
int i,link;
struct recLoc *precLoc;
struct recDes *precDes;
struct recTypDes *precTypDes;
struct recHeader *precHeader;
RECNODE *precNode;
struct fldDes *pfldDes;
struct dbCommon *precord;
struct link *plink;
if(!(precHeader = pdbBase->precHeader)) return(-1);
if(!(precDes = pdbBase->precDes)) return(-1);
for(i=0; i< (precHeader->number); i++) {
if(!(precLoc = precHeader->papRecLoc[i]))continue;
if(!precLoc->preclist) continue;
precTypDes = precDes->papRecTypDes[i];
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
precord = precNode->precord;
/* If NAME is null then skip this record*/
if(!(precord->name[0])) continue;
if(precord->lset != lset) continue;
printf("%s\n",precord->name);
for(link=0; (link<precTypDes->no_links) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
/*
* Find link structure, which is at an offset in the record
*/
plink = (struct link *)((char *)precord + pfldDes->offset);
/* Ignore link if type is constant, channel access, or hardware specific */
if(plink->type != DB_LINK) continue;
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
if(pfldDes->field_type==DBF_INLINK) {
printf("\t INLINK");
} else if(pfldDes->field_type==DBF_OUTLINK) {
printf("\tOUTLINK");
} else if(pfldDes->field_type==DBF_FWDLINK) {
printf("\tFWDLINK");
}
printf(" %s %s",
((plink->value.db_link.process_passive)?" PP":"NPP"),
((plink->value.db_link.maximize_sevr)?" MS":"NMS"));
printf(" %s\n",pdbAddr->precord->name);
}
}
}
return(0);
}

View File

@@ -68,9 +68,9 @@ short index;
}
printf(" Record Name: %s\n",pname);
printf(" Record Type: %d\n",addr.record_type);
printf("Record Address: 0x%x\n",addr.precord);
printf("Record Address: 0x%p\n",addr.precord);
printf(" Field Type: %d\n",addr.field_type);
printf(" Field Address: 0x%x\n",addr.pfield);
printf(" Field Address: 0x%p\n",addr.pfield);
printf(" Field Size: %d\n",addr.field_size);
printf(" No Elements: %d\n",addr.no_elements);
number_elements =
@@ -128,9 +128,9 @@ short index;
}
printf(" Record Name: %s\n",pname);
printf(" Record Type: %d\n",addr.record_type);
printf("Record Address: 0x%x\n",addr.precord);
printf("Record Address: 0x%p\n",addr.precord);
printf(" Field Type: %d\n",addr.field_type);
printf(" Field Address: 0x%x\n",addr.pfield);
printf(" Field Address: 0x%p\n",addr.pfield);
printf(" Field Size: %d\n",addr.field_size);
printf(" No Elements: %d\n",addr.no_elements);
if (db_put_field(paddr,DBR_STRING,pvalue,1) < 0) printf("\n\t failed ");
@@ -312,7 +312,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_sts_long *pvalue
= (struct dbr_sts_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d",pvalue->status,pvalue->severity);
if(count==1) printf("\tValue: ");
for (i = 0; i < count; i++,plong++){
@@ -395,7 +395,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_time_long *pvalue
= (struct dbr_time_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d",pvalue->status,pvalue->severity);
printf("\tTimeStamp: %lx %lx",
pvalue->stamp.secPastEpoch, pvalue->stamp.nsec);
@@ -495,7 +495,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_gr_long *pvalue
= (struct dbr_gr_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
pvalue->units);
printf("\n\t%8d %8d %8d %8d %8d %8d",
@@ -596,7 +596,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_ctrl_long *pvalue
= (struct dbr_ctrl_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
pvalue->units);
printf("\n\t%8d %8d %8d %8d %8d %8d",

View File

@@ -120,7 +120,7 @@ if (strcmp(dbl_option,"-1") == 0)
ntype = dbl_dbGetRecTypes(pdbbase);
else {
if (strlen(dbl_option) > 1) DBL_OPTION = 2;
if (strlen(dbl_option) > (size_t)1) DBL_OPTION = 2;
else if (strcmp(dbl_option,"1") == 0) DBL_OPTION = 1;
else if (strcmp(dbl_option,"2") == 0) DBL_OPTION = 3;
else DBL_OPTION = 0;

View File

@@ -318,17 +318,17 @@ DbRecType(fp, fflag)
if(!(precType=pdbBase->precType)) return;
sprintf(buffer, "\n\ndbls: listing the precType structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precType-> recType", &precType, precType);
sprintf(buffer, "%p[%p] precType-> recType", &precType, precType);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t number\t [ %d ]\t/* number of types */",
sprintf(buffer, "%p\t number\t [ %d ]\t/* number of types */",
&precType->number, precType->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papName\t\t /* pap to record type */",
sprintf(buffer, "%p[%p] **papName\t\t /* pap to record type */",
&precType->papName, precType->papName);
bufOut(fp, fflag);
for (i = 0; i < precType->number; i++) {
if (precType->papName[i]) {
sprintf(buffer, "%8x[%8x] papName->[%d]->\t\"%s\"",
sprintf(buffer, "%p[%p] papName->[%d]->\t\"%s\"",
&precType->papName[i],
precType->papName[i],
i, precType->papName[i]);
@@ -349,33 +349,33 @@ ChoiceGbl(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceGbl structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
sprintf(buffer, "%p[%p] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
&pchoiceGbl->number,
pchoiceGbl->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papChoiceSet -> choiceSet",
sprintf(buffer, "%p[%p]\t**papChoiceSet -> choiceSet",
&pchoiceGbl->papChoiceSet,
pchoiceGbl->papChoiceSet);
bufOut(fp, fflag);
for (i = 0; i < pchoiceGbl->number; i++) {
if (pchoiceGbl->papChoiceSet[i]) {
sprintf(buffer, "%8x[%8x]\t papChoiceSet->[%d]\tINDEX[%d]",
sprintf(buffer, "%p[%p]\t papChoiceSet->[%d]\tINDEX[%d]",
&pchoiceGbl->papChoiceSet[i],
pchoiceGbl->papChoiceSet[i], i, i);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number [%d]\t\t/* number of choices */",
sprintf(buffer, "%p\t\t number [%d]\t\t/* number of choices */",
&pchoiceGbl->papChoiceSet[i]->number,
pchoiceGbl->papChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papChoice -> \t\"choice string\"",
sprintf(buffer, "%p[%p]\t **papChoice -> \t\"choice string\"",
&pchoiceGbl->papChoiceSet[i]->papChoice,
pchoiceGbl->papChoiceSet[i]->papChoice);
bufOut(fp, fflag);
for (j = 0; j < pchoiceGbl->papChoiceSet[i]->number; j++) {
if (pchoiceGbl->papChoiceSet[i]->papChoice[j]) {
sprintf(buffer, "%8x[%8x]\t\t papChoice->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\t papChoice->[%d]\t\"%s\"",
&pchoiceGbl->papChoiceSet[i]->papChoice[j],
pchoiceGbl->papChoiceSet[i]->papChoice[j],
j,
@@ -402,41 +402,41 @@ ChoiceDev(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the choiceDev structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
sprintf(buffer, "%p[%p]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t number\t[%d]\t\t\t/* number of devChoiceSet */",
sprintf(buffer, "%p\t number\t[%d]\t\t\t/* number of devChoiceSet */",
&pchoiceDev->number, pchoiceDev->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDevChoiceSet -> devChoiceSet ",
sprintf(buffer, "%p[%p] **papDevChoiceSet -> devChoiceSet ",
&pchoiceDev->papDevChoiceSet,
pchoiceDev->papDevChoiceSet);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pchoiceDev->papDevChoiceSet[i]) {
sprintf(buffer, "\n%8x[%8x]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
sprintf(buffer, "\n%p[%p]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
&pchoiceDev->papDevChoiceSet[i],
pchoiceDev->papDevChoiceSet[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t\t/*number of choices */ ",
sprintf(buffer, "%p\t\t number\t[%d]\t\t/*number of choices */ ",
&pchoiceDev->papDevChoiceSet[i]->number,
pchoiceDev->papDevChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papDevChoice -> devChoice",
sprintf(buffer, "%p[%p]\t **papDevChoice -> devChoice",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice);
bufOut(fp, fflag);
for (j = 0; j < pchoiceDev->papDevChoiceSet[i]->number; j++) {
if (pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]) {
sprintf(buffer, "%8x[%8x]\t papDevChoice[%d]",
sprintf(buffer, "%p[%p]\t papDevChoice[%d]",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j],
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t link_type [%d]",
sprintf(buffer, "%p\t\t link_type [%d]",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\t*pchoice\t\t\"%s\"",
sprintf(buffer, "%p[%p]\t\t*pchoice\t\t\"%s\"",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice);
@@ -459,18 +459,18 @@ ChoiceCvt(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceCvt structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
sprintf(buffer, "%p[%p] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
bufOut(fp, fflag);
sprintf(buffer, "%8x number\t [ %d ]\t/* number of choices */",
sprintf(buffer, "%p number\t [ %d ]\t/* number of choices */",
&pchoiceCvt->number, pchoiceCvt->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papChoice -> \"choice string\"",
sprintf(buffer, "%p[%p] **papChoice -> \"choice string\"",
&pchoiceCvt->papChoice, pchoiceCvt->papChoice);
bufOut(fp, fflag);
for (i = 0; i < pchoiceCvt->number; i++)
if (pchoiceCvt->papChoice[i]) {
sprintf(buffer, "%8x[%8x] papChoice[%d]\t\"%s\" ",
sprintf(buffer, "%p[%p] papChoice[%d]\t\"%s\" ",
&pchoiceCvt->papChoice[i], pchoiceCvt->papChoice[i], i,
pchoiceCvt->papChoice[i]);
bufOut(fp, fflag);
@@ -523,55 +523,55 @@ CvtTable(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the pcvtTable structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
sprintf(buffer, "%p[%p] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
bufOut(fp, fflag);
sprintf(buffer, "%8x number\t [ %d ]\t/* number of break tables */",
sprintf(buffer, "%p number\t [ %d ]\t/* number of break tables */",
&pcvtTable->number, pcvtTable->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papBrkTable -> brkTable",
sprintf(buffer, "%p[%p] **papBrkTable -> brkTable",
&pcvtTable->papBrkTable, pcvtTable->papBrkTable);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pcvtTable->papBrkTable[i]) {
sprintf(buffer, "%8x[%8x] papBrkTable[%d] ",
sprintf(buffer, "%p[%p] papBrkTable[%d] ",
&pcvtTable->papBrkTable[i], pcvtTable->papBrkTable[i], i);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *name\t\t\t\"%s\"",
sprintf(buffer, "%p[%p]\t *name\t\t\t\"%s\"",
&pcvtTable->papBrkTable[i]->name,
pcvtTable->papBrkTable[i]->name,
pcvtTable->papBrkTable[i]->name);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number [ %d ]\t/* number of brkInt in this table */ ",
sprintf(buffer, "%p\t\t number [ %d ]\t/* number of brkInt in this table */ ",
&pcvtTable->papBrkTable[i]->number,
pcvtTable->papBrkTable[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rawLow\t\t\t%-d",
sprintf(buffer, "%p\t\t rawLow\t\t\t%-d",
&pcvtTable->papBrkTable[i]->rawLow,
pcvtTable->papBrkTable[i]->rawLow);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rawHigh\t\t\t%-d",
sprintf(buffer, "%p\t\t rawHigh\t\t\t%-d",
&pcvtTable->papBrkTable[i]->rawHigh,
pcvtTable->papBrkTable[i]->rawHigh);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papBrkInt",
sprintf(buffer, "%p[%p]\t**papBrkInt",
&pcvtTable->papBrkTable[i]->papBrkInt,
pcvtTable->papBrkTable[i]->papBrkInt);
bufOut(fp, fflag);
for (j = 0; j < pcvtTable->papBrkTable[i]->number; j++) {
if (pcvtTable->papBrkTable[i]->papBrkInt[j]) {
sprintf(buffer, "%8x[%8x]\t papBrkInt[%d] -> brkInt",
sprintf(buffer, "%p[%p]\t papBrkInt[%d] -> brkInt",
&pcvtTable->papBrkTable[i]->papBrkInt[j],
pcvtTable->papBrkTable[i]->papBrkInt[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t raw\t\t\t%-d",
sprintf(buffer, "%p\t\t raw\t\t\t%-d",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->raw,
pcvtTable->papBrkTable[i]->papBrkInt[j]->raw);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t slope\t\t\t%-.5f",
sprintf(buffer, "%p\t\t slope\t\t\t%-.5f",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->slope,
pcvtTable->papBrkTable[i]->papBrkInt[j]->slope);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t eng\t\t\t%-.5f",
sprintf(buffer, "%p\t\t eng\t\t\t%-.5f",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->eng,
pcvtTable->papBrkTable[i]->papBrkInt[j]->eng);
bufOut(fp, fflag);
@@ -596,42 +596,42 @@ DevSup(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the devSup structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precDevSup -> recDevSup ", &precDevSup, precDevSup);
sprintf(buffer, "%p[%p] precDevSup -> recDevSup ", &precDevSup, precDevSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t/* number of record types */",
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t/* number of record types */",
&precDevSup->number, precDevSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDevSup -> precDevSup ",
sprintf(buffer, "%p[%p] **papDevSup -> precDevSup ",
&precDevSup->papDevSup, precDevSup->papDevSup);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precDevSup->papDevSup[i]) {
sprintf(buffer, "%8x[%8x] papDevSup->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p] papDevSup->[%d]\t\"%s\"",
&precDevSup->papDevSup[i],
precDevSup->papDevSup[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */",
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */",
&precDevSup->papDevSup[i]->number,
precDevSup->papDevSup[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDsetName",
sprintf(buffer, "%p[%p] **papDsetName",
&precDevSup->papDevSup[i]->papDsetName,
precDevSup->papDevSup[i]->papDsetName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDset",
sprintf(buffer, "%p[%p] **papDset",
&precDevSup->papDevSup[i]->papDset,
precDevSup->papDevSup[i]->papDset);
bufOut(fp, fflag);
for (j = 0; j < precDevSup->papDevSup[i]->number; j++) {
if (precDevSup->papDevSup[i]->papDsetName[j]) {
sprintf(buffer, "%8x[%8x]\t\tpapDsetName[%d]\t%s",
sprintf(buffer, "%p[%p]\t\tpapDsetName[%d]\t%s",
&precDevSup->papDevSup[i]->papDsetName[j],
precDevSup->papDevSup[i]->papDsetName[j],
j,
precDevSup->papDevSup[i]->papDsetName[j]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\tpapDset[%d]",
sprintf(buffer, "%p[%p]\t\tpapDset[%d]",
&precDevSup->papDevSup[i]->papDset[j],
precDevSup->papDevSup[i]->papDset[j], j);
bufOut(fp, fflag);
@@ -652,24 +652,24 @@ DrvSup(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the drvSup structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
sprintf(buffer, "%p[%p] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
sprintf(buffer, "%p[%p] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
&pdrvSup->papDrvName, pdrvSup->papDrvName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDrvet-> drvet \t/* pArr ptr to drvet */",
sprintf(buffer, "%p[%p] **papDrvet-> drvet \t/* pArr ptr to drvet */",
&pdrvSup->papDrvet, pdrvSup->papDrvet);
bufOut(fp, fflag);
for (i = 0; i < pdrvSup->number; i++) {
if (pdrvSup->papDrvName[i])
sprintf(buffer, "%8x[%8x]\t papDrvName->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t papDrvName->[%d]\t\"%s\"",
&pdrvSup->papDrvName[i],
pdrvSup->papDrvName[i],
i, pdrvSup->papDrvName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t papDrvet->[%d] /* reserved ptr to drvet */",
sprintf(buffer, "%p[%p]\t papDrvet->[%d] /* reserved ptr to drvet */",
&pdrvSup->papDrvet[i],
pdrvSup->papDrvet[i], i);
bufOut(fp, fflag);
@@ -703,7 +703,7 @@ DbRecDes(fp, fflag)
for (j = 0; j < endNumJ; j++) {
printf("%3d %4.4s",
precDes->papRecTypDes[begNumI]->sortFldInd[j],
&precDes->papRecTypDes[begNumI]->sortFldName[j]);
(char *)&precDes->papRecTypDes[begNumI]->sortFldName[j]);
if (!((j + 1) % 8))
printf("\n");
}
@@ -723,48 +723,48 @@ DbRecDes(fp, fflag)
sprintf(buffer, "\n\ndbls: listing the precDes structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precDes-> recDes", &precDes, precDes);
sprintf(buffer, "%p[%p] precDes-> recDes", &precDes, precDes);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber [%d] \t/* number of recTypDes */",
sprintf(buffer, "%p\t\tnumber [%d] \t/* number of recTypDes */",
&precDes->number, precDes->number);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precDes->papRecTypDes[i]) {
sprintf(buffer, "\n%8x[%8x] **papRecTypDes-> recTypDes\t\"%s\"",
sprintf(buffer, "\n%p[%p] **papRecTypDes-> recTypDes\t\"%s\"",
&precDes->papRecTypDes,
precDes->papRecTypDes,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rec_size [%d]",
sprintf(buffer, "%p\t\t rec_size [%d]",
&precDes->papRecTypDes[i]->rec_size,
precDes->papRecTypDes[i]->rec_size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_fields [%d]",
sprintf(buffer, "%p\t\t no_fields [%d]",
&precDes->papRecTypDes[i]->no_fields,
precDes->papRecTypDes[i]->no_fields);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_prompt [%d]",
sprintf(buffer, "%p\t\t no_prompt [%d]",
&precDes->papRecTypDes[i]->no_prompt,
precDes->papRecTypDes[i]->no_prompt);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_links [%d]",
sprintf(buffer, "%p\t\t no_links [%d]",
&precDes->papRecTypDes[i]->no_links,
precDes->papRecTypDes[i]->no_links);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *link_ind",
sprintf(buffer, "%p[%p]\t *link_ind",
&precDes->papRecTypDes[i]->link_ind,
precDes->papRecTypDes[i]->link_ind);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *sortFldName",
sprintf(buffer, "%p[%p]\t *sortFldName",
&precDes->papRecTypDes[i]->sortFldName,
precDes->papRecTypDes[i]->sortFldName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *sortFldInd",
sprintf(buffer, "%p[%p]\t *sortFldInd",
&precDes->papRecTypDes[i]->sortFldInd,
precDes->papRecTypDes[i]->sortFldInd);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papFldDes-> fldDes",
sprintf(buffer, "%p[%p]\t **papFldDes-> fldDes",
&precDes->papRecTypDes[i]->papFldDes,
precDes->papRecTypDes[i]->papFldDes);
bufOut(fp, fflag);
@@ -773,7 +773,7 @@ DbRecDes(fp, fflag)
endNumJ = precDes->papRecTypDes[i]->no_fields;
/* expand *link_ind */
for (j = 0; j < precDes->papRecTypDes[i]->no_links; j++) {
sprintf(buffer,"%8x\tlink_ind[%d] offset=[%d]",
sprintf(buffer,"%p\tlink_ind[%d] offset=[%d]",
&precDes->papRecTypDes[i]->link_ind[j],
j,
precDes->papRecTypDes[i]->link_ind[j]);
@@ -782,7 +782,7 @@ DbRecDes(fp, fflag)
/* expand *sortFldName and *sortFldInd */
ptemp = (char *) precDes->papRecTypDes[i]->sortFldName;
for (j = 0; j < precDes->papRecTypDes[i]->no_fields; j++) {
sprintf(buffer,"[%8x] sortFldName[%2d]=%4.4s [%8x] sortFldInd=%2d",
sprintf(buffer,"[%p] sortFldName[%2d]=%4.4s [%p] sortFldInd=%2d",
ptemp,
j,
ptemp,
@@ -796,89 +796,89 @@ DbRecDes(fp, fflag)
for (j = begNumJ; j < endNumJ; j++) {
sprintf(buffer, "\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papFldDes->fldDes[%d]",
sprintf(buffer, "%p[%p]\t **papFldDes->fldDes[%d]",
&precDes->papRecTypDes[i]->papFldDes[j],
precDes->papRecTypDes[i]->papFldDes[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tprompt\t\t\"%s\"",
sprintf(buffer, "%p\t\t\tprompt\t\t\"%s\"",
precDes->papRecTypDes[i]->papFldDes[j]->prompt,
precDes->papRecTypDes[i]->papFldDes[j]->prompt);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tfldname\t\t\"%4.4s\"",
sprintf(buffer, "%p\t\t\tfldname\t\t\"%4.4s\"",
precDes->papRecTypDes[i]->papFldDes[j]->fldname,
precDes->papRecTypDes[i]->papFldDes[j]->fldname);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\toffset [%d]",
sprintf(buffer, "%p\t\t\toffset [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->offset,
precDes->papRecTypDes[i]->papFldDes[j]->offset);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tsize [%d]",
sprintf(buffer, "%p\t\t\tsize [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->size,
precDes->papRecTypDes[i]->papFldDes[j]->size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tspecial [%d]",
sprintf(buffer, "%p\t\t\tspecial [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->special,
precDes->papRecTypDes[i]->papFldDes[j]->special);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tfield_type [%d]",
sprintf(buffer, "%p\t\t\tfield_type [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->field_type,
precDes->papRecTypDes[i]->papFldDes[j]->field_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tprocess_passive [%d]",
sprintf(buffer, "%p\t\t\tprocess_passive [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->process_passive,
precDes->papRecTypDes[i]->papFldDes[j]->process_passive);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tchoice_set [%d]",
sprintf(buffer, "%p\t\t\tchoice_set [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->choice_set,
precDes->papRecTypDes[i]->papFldDes[j]->choice_set);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tcvt_type [%d]",
sprintf(buffer, "%p\t\t\tcvt_type [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->cvt_type,
precDes->papRecTypDes[i]->papFldDes[j]->cvt_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tpromptflag [%d]",
sprintf(buffer, "%p\t\t\tpromptflag [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->promptflag,
precDes->papRecTypDes[i]->papFldDes[j]->promptflag);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tlowfl [%d]",
sprintf(buffer, "%p\t\t\tlowfl [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->lowfl,
precDes->papRecTypDes[i]->papFldDes[j]->lowfl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\thighfl [%d]",
sprintf(buffer, "%p\t\t\thighfl [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->highfl,
precDes->papRecTypDes[i]->papFldDes[j]->highfl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tinterest [%d]",
sprintf(buffer, "%p\t\t\tinterest [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->interest,
precDes->papRecTypDes[i]->papFldDes[j]->interest);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tas_level [%d]",
sprintf(buffer, "%p\t\t\tas_level [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->as_level,
precDes->papRecTypDes[i]->papFldDes[j]->as_level);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->initial, 8);
sprintf(buffer, "%8x[%8x][%8x]\tinitial",
sprintf(buffer, "%p[%8x][%8x]\tinitial",
&precDes->papRecTypDes[i]->papFldDes[j]->initial,
buff[0], buff[1]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\trange1.fldnum [%d]",
sprintf(buffer, "%p\t\t\trange1.fldnum [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum,
precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range1.value, 8);
sprintf(buffer, "%8x[%8x][%8x]\trange1.value",
sprintf(buffer, "%p[%8x][%8x]\trange1.value",
&precDes->papRecTypDes[i]->papFldDes[j]->range1.value,
buff[0], buff[1]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\trange2.fldnum [%d]",
sprintf(buffer, "%p\t\t\trange2.fldnum [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum,
precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range2.value, 8);
sprintf(buffer, "%8x[%8x][%8x]\trange2.value",
sprintf(buffer, "%p[%8x][%8x]\trange2.value",
&precDes->papRecTypDes[i]->papFldDes[j]->range2.value,
buff[0], buff[1]);
bufOut(fp, fflag);
@@ -935,48 +935,48 @@ ChoiceRec(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceRec structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
sprintf(buffer, "%p[%p] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
sprintf(buffer, "%p\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papArrChoiceSet -> arrChoiceSet",
sprintf(buffer, "%p[%p]\t**papArrChoiceSet -> arrChoiceSet",
&pchoiceRec->papArrChoiceSet,
pchoiceRec->papArrChoiceSet);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pchoiceRec->papArrChoiceSet[i]) {
sprintf(buffer, "%8x[%8x]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
sprintf(buffer, "%p[%p]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
&pchoiceRec->papArrChoiceSet[i],
pchoiceRec->papArrChoiceSet[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
&pchoiceRec->papArrChoiceSet[i]->number,
pchoiceRec->papArrChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papChoiceSet",
sprintf(buffer, "%p[%p]\t **papChoiceSet",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet);
bufOut(fp, fflag);
for (j = 0; j < pchoiceRec->papArrChoiceSet[i]->number; j++) {
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]) {
sprintf(buffer, "%8x[%8x]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
sprintf(buffer, "%p[%p]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j],
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j], j, j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
sprintf(buffer, "%p\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\t**papChoice -> \"string\"",
sprintf(buffer, "%p[%p]\t\t**papChoice -> \"string\"",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice);
bufOut(fp, fflag);
for (k = 0; k < pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number; k++) {
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]) {
sprintf(buffer, "%8x[%8x]\t\tpapChoice[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\tpapChoice[%d]\t\"%s\"",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k],
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k], k,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]);
@@ -1003,28 +1003,28 @@ DbErrDes(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the dbErrDes structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
sprintf(buffer, "%p[%p] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t /* dim of err modules */",
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t /* dim of err modules */",
&dbErrDes->number, dbErrDes->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papErrSet -> errSet ",
sprintf(buffer, "%p[%p] **papErrSet -> errSet ",
&dbErrDes->papErrSet, dbErrDes->papErrSet);
bufOut(fp, fflag);
for (i = 0; i < dbErrDes->number; i++) {
if (dbErrDes->papErrSet[i]) {
sprintf(buffer, "%8x[%8x] papErrSet->[%d]\tmodule[%d]",
sprintf(buffer, "%p[%p] papErrSet->[%d]\tmodule[%d]",
&dbErrDes->papErrSet[i],
dbErrDes->papErrSet[i], i,
i + 501);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* dim of errSet */",
sprintf(buffer, "%p\t\t number\t[%d]\t/* dim of errSet */",
&dbErrDes->papErrSet[i]->number,
dbErrDes->papErrSet[i]->number);
bufOut(fp, fflag);
for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) {
if (dbErrDes->papErrSet[i]->papName[j]) {
sprintf(buffer, "%8x[%8x]\t\tpapName[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\tpapName[%d]\t\"%s\"",
&dbErrDes->papErrSet[i]->papName[j],
dbErrDes->papErrSet[i]->papName[j],
j,
@@ -1055,30 +1055,30 @@ DbRecords(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the precHeader structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precHeader -> recHeader", &precHeader, precHeader);
sprintf(buffer, "%p[%p] precHeader -> recHeader", &precHeader, precHeader);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
&precHeader->number,
precHeader->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papRecLoc -> recLoc",
sprintf(buffer, "%p[%p]\t**papRecLoc -> recLoc",
&precHeader->papRecLoc,
precHeader->papRecLoc);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precHeader->papRecLoc[i]) {
sprintf(buffer, "%8x[%8x]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
sprintf(buffer, "%p[%p]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
&precHeader->papRecLoc[i],
precHeader->papRecLoc[i],
i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rec_size [%d]\t\t/* rec_size in bytes */",
sprintf(buffer, "%p\t\t rec_size [%d]\t\t/* rec_size in bytes */",
&precHeader->papRecLoc[i]->rec_size,
precHeader->papRecLoc[i]->rec_size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t record_type [%d]\t\t/* record_type in bytes */",
sprintf(buffer, "%p\t\t record_type [%d]\t\t/* record_type in bytes */",
&precHeader->papRecLoc[i]->record_type,
precHeader->papRecLoc[i]->record_type);
bufOut(fp, fflag);
@@ -1102,84 +1102,84 @@ RecSup(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the recSup structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precSup -> precSup", &precSup, precSup);
sprintf(buffer, "%p[%p] precSup -> precSup", &precSup, precSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
&precSup->number,
precSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papRset -> rset",
sprintf(buffer, "%p[%p] **papRset -> rset",
&precSup->papRset,
precSup->papRset);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precSup->papRset[i]) {
sprintf(buffer, "%8x[%8x]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
sprintf(buffer, "%p[%p]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
&precSup->papRset[i],
precSup->papRset[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t number\t\t/*number of support routines */",
sprintf(buffer, "%p[%d]\t number\t\t/*number of support routines */",
&precSup->papRset[i]->number,
precSup->papRset[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t report\t\t/*print report */",
sprintf(buffer, "%p[%p]\t report\t\t/*print report */",
&precSup->papRset[i]->report,
precSup->papRset[i]->report);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t init\t\t/*init support */",
sprintf(buffer, "%p[%p]\t init\t\t/*init support */",
&precSup->papRset[i]->init,
precSup->papRset[i]->init);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t init_record\t/*init record */",
sprintf(buffer, "%p[%p]\t init_record\t/*init record */",
&precSup->papRset[i]->init_record,
precSup->papRset[i]->init_record);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t process\t\t/*process record */",
sprintf(buffer, "%p[%p]\t process\t\t/*process record */",
&precSup->papRset[i]->process,
precSup->papRset[i]->process);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t special\t\t/*special processing */",
sprintf(buffer, "%p[%p]\t special\t\t/*special processing */",
&precSup->papRset[i]->special,
precSup->papRset[i]->special);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_precision\t/* get_precision of this type */",
sprintf(buffer, "%p[%p]\t get_precision\t/* get_precision of this type */",
&precSup->papRset[i]->get_precision,
precSup->papRset[i]->get_precision);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_value\t\t/*get value field */",
sprintf(buffer, "%p[%p]\t get_value\t\t/*get value field */",
&precSup->papRset[i]->get_value,
precSup->papRset[i]->get_value);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t cvt_dbaddr\t\t/*cvt dbAddr */",
sprintf(buffer, "%p[%p]\t cvt_dbaddr\t\t/*cvt dbAddr */",
&precSup->papRset[i]->cvt_dbaddr,
precSup->papRset[i]->cvt_dbaddr);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_array_info\t/* get_array_info of this type */",
sprintf(buffer, "%p[%p]\t get_array_info\t/* get_array_info of this type */",
&precSup->papRset[i]->get_array_info,
precSup->papRset[i]->get_array_info);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t put_array_info\t/* put_array_info of this type */",
sprintf(buffer, "%p[%p]\t put_array_info\t/* put_array_info of this type */",
&precSup->papRset[i]->put_array_info,
precSup->papRset[i]->put_array_info);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_enum_str\t/*get string from enum item*/",
sprintf(buffer, "%p[%p]\t get_enum_str\t/*get string from enum item*/",
&precSup->papRset[i]->get_enum_str,
precSup->papRset[i]->get_enum_str);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_units \t\t/* get_units of this type */",
sprintf(buffer, "%p[%p]\t get_units \t\t/* get_units of this type */",
&precSup->papRset[i]->get_units,
precSup->papRset[i]->get_units);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_graphic_double /* get_graphic_double of this type */",
sprintf(buffer, "%p[%p]\t get_graphic_double /* get_graphic_double of this type */",
&precSup->papRset[i]->get_graphic_double,
precSup->papRset[i]->get_graphic_double);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_control_double /* get_control_double of this type */",
sprintf(buffer, "%p[%p]\t get_control_double /* get_control_double of this type */",
&precSup->papRset[i]->get_control_double,
precSup->papRset[i]->get_control_double);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_enum_strs\t/*get all enum strings */",
sprintf(buffer, "%p[%p]\t get_enum_strs\t/*get all enum strings */",
&precSup->papRset[i]->get_enum_strs,
precSup->papRset[i]->get_enum_strs);
bufOut(fp, fflag);

File diff suppressed because it is too large Load Diff

View File

@@ -55,8 +55,6 @@ int callNumber;
switch (callNumber) {
case INITHOOKatBeginning :
break;
case INITHOOKafterSetEnvParams :
break;
case INITHOOKafterGetResources :
break;
case INITHOOKafterLogInit :

View File

@@ -98,6 +98,8 @@
#include <envDefs.h>
#include <dbStaticLib.h>
#include <initHooks.h>
#include <drvTS.h>
#include <asLib.h>
/*This module will declare and initilize module_type variables*/
#define MODULE_TYPES_INIT 1
@@ -106,10 +108,11 @@
LOCAL int initialized=FALSE;
/* The following is for use by interrupt routines */
int interruptAccept=FALSE;
volatile int interruptAccept=FALSE;
struct dbBase *pdbBase=NULL;
/* added for Channel Access Links */
long dbCommonInit();
@@ -120,7 +123,8 @@ LOCAL long initDevSup(void);
LOCAL long finishDevSup(void);
LOCAL long initDatabase(void);
LOCAL void createLockSets(void);
LOCAL short makeSameSet(struct dbAddr *paddr,short set);
LOCAL void createLockSetsExtraPass(int *anyChange);
LOCAL short makeSameSet(struct dbAddr *paddr,short set,int *anyChange);
LOCAL long initialProcess(void);
LOCAL long getResources(char *fname);
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
@@ -165,15 +169,6 @@ int iocInit(char * pResourceFilename)
* Print out version of iocCore
*/
coreRelease();
/*
* Read EPICS environment
*/
epicsSetEnvParams();
/* Hook after environment has been set */
if (pinitHooks) (*pinitHooks)(INITHOOKafterSetEnvParams);
/*
* Read EPICS resources.
*/
@@ -829,17 +824,6 @@ LOCAL long initDatabase(void)
return(status);
}
/*
* Create lock sets for records
* A lock set is a set of records that must be locked
* with a semaphore so as to prevent mutual exclusion
* hazards. Lock sets are determined by examining the
* links interconnecting the records. If a link connecting
* two records is not an NPP/NMS single-valued input link,
* then the two records are considered part of the same
* lock set. Records connected by forward links are
* definately considered part of the same lockset.
*/
LOCAL void createLockSets(void)
{
int i,link;
@@ -853,6 +837,7 @@ LOCAL void createLockSets(void)
struct link *plink;
short nset,maxnset,newset;
int again;
int anyChange;
nset = 0;
if(!(precHeader = pdbBase->precHeader)) return;
@@ -873,7 +858,6 @@ LOCAL void createLockSets(void)
* We shall see later if this assumption is incorrect.
*/
precord->lset = maxnset = ++nset;
/*
* Use the process active flag to eliminate traversing
* cycles in the database "graph"
@@ -881,7 +865,7 @@ LOCAL void createLockSets(void)
precord->pact = TRUE; again = TRUE;
while(again) {
again = FALSE;
for(link=0; link<precTypDes->no_links; link++) {
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
@@ -910,7 +894,7 @@ LOCAL void createLockSets(void)
* Combine the lock sets of the current record with the
* remote record pointed to by the link. (recursively)
*/
newset = makeSameSet(pdbAddr,precord->lset);
newset = makeSameSet(pdbAddr,precord->lset,&anyChange);
/*
* Perform an iteration of the while-loop again
@@ -930,10 +914,70 @@ LOCAL void createLockSets(void)
precord->pact = FALSE;
}
}
anyChange = TRUE;
while(anyChange) {
anyChange = FALSE;
createLockSetsExtraPass(&anyChange);
}
dbScanLockInit(nset);
}
LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
LOCAL void createLockSetsExtraPass(int *anyChange)
{
int i,link;
struct recLoc *precLoc;
struct recDes *precDes;
struct recTypDes *precTypDes;
struct recHeader *precHeader;
RECNODE *precNode;
struct fldDes *pfldDes;
struct dbCommon *precord;
struct link *plink;
int again;
if(!(precHeader = pdbBase->precHeader)) return;
if(!(precDes = pdbBase->precDes)) return;
for(i=0; i< (precHeader->number); i++) {
if(!(precLoc = precHeader->papRecLoc[i]))continue;
if(!precLoc->preclist) continue;
precTypDes = precDes->papRecTypDes[i];
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
precord = precNode->precord;
if(!(precord->name[0])) continue;
/*Prevent cycles in database graph*/
precord->pact = TRUE; again = TRUE;
while(again) {
short newset;
again = FALSE;
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
plink = (struct link *)((char *)precord + pfldDes->offset);
if(plink->type != DB_LINK) continue;
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
if (pfldDes->field_type==DBF_INLINK
&& ( !(plink->value.db_link.process_passive)
&& !(plink->value.db_link.maximize_sevr))
&& pdbAddr->no_elements<=1) continue;
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
if (newset!=precord->lset) {
precord->lset = newset;
*anyChange = TRUE;
again = TRUE;
break;
}
}
}
precord->pact = FALSE;
}
}
}
LOCAL short makeSameSet(struct dbAddr *paddr, short lset,int *anyChange)
{
struct dbCommon *precord = paddr->precord;
short link;
@@ -943,12 +987,7 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
struct recDes *precDes;
int again;
/*
* Use the process active flag to eliminate traversing
* cycles in the database "graph." Effectively converts
* the arbitrary database "graph" (where edges are
* defined as links) into a tree structure.
*/
/*Prevent cycles in database graph*/
if(precord->pact) return(((precord->lset<lset) ? precord->lset : lset));
/*
@@ -988,10 +1027,11 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
&& ( !(plink->value.db_link.process_passive)
&& !(plink->value.db_link.maximize_sevr) )
&& pdbAddr->no_elements<=1) continue;
newset = makeSameSet(pdbAddr,precord->lset);
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
if(newset != precord->lset) {
precord->lset = newset;
again = TRUE;
*anyChange = TRUE;
break;
}
}

View File

@@ -328,10 +328,8 @@ void recGblFwdLink(void *precord)
dbScanPassive(precord,paddr->precord);
}
/*Handle dbPutFieldNotify record completions*/
if(pdbc->ppn) {
/*Note: dbNotifyCancel also handles rpro*/
dbNotifyCompletion(pdbc->ppn);
} else if(pdbc->rpro) {
if(pdbc->ppn) dbNotifyCompletion(pdbc);
if(pdbc->rpro) {
/*If anyone requested reprocessing do it*/
pdbc->rpro = FALSE;
scanOnce(pdbc);
@@ -344,7 +342,6 @@ void recGblFwdLink(void *precord)
void recGblGetTimeStamp(void* prec)
{
struct dbCommon* pr = (struct dbCommon*)prec;
long status;
long nRequest=1;
long options=0;

View File

@@ -38,6 +38,7 @@
#include <stdio.h>
#include <ellLib.h>
#include <taskLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <errMdef.h>
@@ -166,7 +167,7 @@ static void taskwdTask(void)
pname = taskName(pt->id.tid);
if(!pt->suspended) {
struct task_list *ptany,*anynext;
struct task_list *ptany;
pt->suspended = TRUE;
sprintf(message,"task %x %s suspended",pt->id.tid,pname);
@@ -205,7 +206,7 @@ static struct task_list *allocList(void)
FASTLOCK(&alloclock);
if(freeHead) {
(void *)pt = (void *)freeHead;
pt = (struct task_list *)freeHead;
freeHead = freeHead->next;
} else pt = calloc(1,sizeof(struct task_list));
if(pt==NULL) {

View File

@@ -9,9 +9,9 @@ LEXOPT = -L
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
dbLoadRecords_lex.c dbLoadRecords.c
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
PROD = dbSubs
LIBNAME = dbSubs
include $(EPICS)/config/RULES.Vx
@@ -29,7 +29,4 @@ clean::
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
dbLoadRecords.c
dbSubs: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -1,5 +1,5 @@
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
pvname [a-zA-Z0-9_~\-:\.\[\]<>;]
value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
%{

View File

@@ -1,5 +1,5 @@
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
value [a-zA-Z0-9_~\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
word [a-zA-Z0-9_\.\^~/\*#\[\]%:;!|\-&\$\(\)@\?\+<>]
par [\"\']

View File

@@ -106,113 +106,109 @@ SRCS.c += ../devABBINARY.c
SRCS.c += ../devABStatus.c
SRCS.c += ../devMpc.c
# OBJS += devAaiCamac.o
# OBJS += devAiCamac.o
OBJS += devAiDvx2502.o
OBJS += devAiKscV215.o
OBJS += devAiSoft.o
OBJS += devAiSoftRaw.o
OBJS += devAiSymb.o
OBJS += devAiTestAsyn.o
OBJS += devAiXy566Di.o
OBJS += devAiXy566DiL.o
OBJS += devAiXy566Se.o
# OBJS += devAaoCamac.o
# OBJS += devAoCamac.o
OBJS += devAoSoft.o
OBJS += devAoSoftRaw.o
OBJS += devAoSymb.o
OBJS += devAoTestAsyn.o
OBJS += devAoVmiVme4100.o
OBJS += devApsEg.o
OBJS += devApsEr.o
OBJS += devAt5Vxi.o
OBJS += devAt8Fp.o
OBJS += devAvme9440.o
# OBJS += devBiCamac.o
OBJS += devBiMpv910.o
OBJS += devBiSoft.o
OBJS += devBiSoftRaw.o
OBJS += devBiTestAsyn.o
OBJS += devBiXVme210.o
# OBJS += devBoCamac.o
OBJS += devBoMpv902.o
OBJS += devBoSoft.o
OBJS += devBoSoftRaw.o
OBJS += devBoTestAsyn.o
OBJS += devBoXVme220.o
OBJS += devCommonGpib.o
OBJS += devEventSoft.o
OBJS += devEventTestIoEvent.o
OBJS += devHistogramSoft.o
OBJS += devHistogramTestAsyn.o
OBJS += devHpe1368a.o
# OBJS += devLiCamac.o
OBJS += devLiSoft.o
OBJS += devLiSymb.o
# OBJS += devLoCamac.o
OBJS += devLoSoft.o
OBJS += devLoSymb.o
# OBJS += devMbbiCamac.o
# OBJS += devMbbiDirectCamac.o
OBJS += devMbbiDirectMpv910.o
OBJS += devMbbiDirectSoft.o
OBJS += devMbbiDirectSoftRaw.o
OBJS += devMbbiDirectXVme210.o
OBJS += devMbbiMpv910.o
OBJS += devMbbiSoft.o
OBJS += devMbbiSoftRaw.o
OBJS += devMbbiTestAsyn.o
OBJS += devMbbiXVme210.o
# OBJS += devMbboCamac.o
# OBJS += devMbboDirectCamac.o
OBJS += devMbboDirectMpv902.o
OBJS += devMbboDirectSoft.o
OBJS += devMbboDirectSoftRaw.o
OBJS += devMbboDirectXVme220.o
OBJS += devMbboMpv902.o
OBJS += devMbboSoft.o
OBJS += devMbboSoftRaw.o
OBJS += devMbboTestAsyn.o
OBJS += devMbboXVme220.o
OBJS += devMz8310.o
OBJS += devPtSoft.o
OBJS += devSASoft.o
OBJS += devSiSoft.o
OBJS += devSiSymb.o
OBJS += devSiTestAsyn.o
OBJS += devSmCompumotor1830.o
OBJS += devSmOms6Axis.o
OBJS += devSoSoft.o
OBJS += devSoSymb.o
OBJS += devSoTestAsyn.o
OBJS += devSysmon.o
OBJS += devTimerMz8310.o
OBJS += devVxiTDM.o
# OBJS += devWfCamac.o
OBJS += devWfComet.o
OBJS += devWfDvx2502.o
OBJS += devWfJoergerVtr1.o
OBJS += devWfSoft.o
OBJS += devWfTestAsyn.o
OBJS += devWfXy566Sc.o
OBJS += devWfPentek4261.o
OBJS += devXy240.o
OBJS += devAB1771IFE.o
OBJS += devAB1771IL.o
OBJS += devAB1771IR.o
OBJS += devAB1771IXE.o
OBJS += devAB1771OFE.o
OBJS += devABBINARY.o
OBJS += devABStatus.o
OBJS += devMpc.o
# LIBOBJS += devAaiCamac.o
# LIBOBJS += devAiCamac.o
LIBOBJS += devAiDvx2502.o
LIBOBJS += devAiKscV215.o
LIBOBJS += devAiSoft.o
LIBOBJS += devAiSoftRaw.o
LIBOBJS += devAiSymb.o
LIBOBJS += devAiTestAsyn.o
LIBOBJS += devAiXy566Di.o
LIBOBJS += devAiXy566DiL.o
LIBOBJS += devAiXy566Se.o
# LIBOBJS += devAaoCamac.o
# LIBOBJS += devAoCamac.o
LIBOBJS += devAoSoft.o
LIBOBJS += devAoSoftRaw.o
LIBOBJS += devAoSymb.o
LIBOBJS += devAoTestAsyn.o
LIBOBJS += devAoVmiVme4100.o
LIBOBJS += devApsEg.o
LIBOBJS += devApsEr.o
LIBOBJS += devAt5Vxi.o
LIBOBJS += devAt8Fp.o
LIBOBJS += devAvme9440.o
# LIBOBJS += devBiCamac.o
LIBOBJS += devBiMpv910.o
LIBOBJS += devBiSoft.o
LIBOBJS += devBiSoftRaw.o
LIBOBJS += devBiTestAsyn.o
LIBOBJS += devBiXVme210.o
# LIBOBJS += devBoCamac.o
LIBOBJS += devBoMpv902.o
LIBOBJS += devBoSoft.o
LIBOBJS += devBoSoftRaw.o
LIBOBJS += devBoTestAsyn.o
LIBOBJS += devBoXVme220.o
LIBOBJS += devCommonGpib.o
LIBOBJS += devEventSoft.o
LIBOBJS += devEventTestIoEvent.o
LIBOBJS += devHistogramSoft.o
LIBOBJS += devHistogramTestAsyn.o
LIBOBJS += devHpe1368a.o
# LIBOBJS += devLiCamac.o
LIBOBJS += devLiSoft.o
LIBOBJS += devLiSymb.o
# LIBOBJS += devLoCamac.o
LIBOBJS += devLoSoft.o
LIBOBJS += devLoSymb.o
# LIBOBJS += devMbbiCamac.o
# LIBOBJS += devMbbiDirectCamac.o
LIBOBJS += devMbbiDirectMpv910.o
LIBOBJS += devMbbiDirectSoft.o
LIBOBJS += devMbbiDirectSoftRaw.o
LIBOBJS += devMbbiDirectXVme210.o
LIBOBJS += devMbbiMpv910.o
LIBOBJS += devMbbiSoft.o
LIBOBJS += devMbbiSoftRaw.o
LIBOBJS += devMbbiTestAsyn.o
LIBOBJS += devMbbiXVme210.o
# LIBOBJS += devMbboCamac.o
# LIBOBJS += devMbboDirectCamac.o
LIBOBJS += devMbboDirectMpv902.o
LIBOBJS += devMbboDirectSoft.o
LIBOBJS += devMbboDirectSoftRaw.o
LIBOBJS += devMbboDirectXVme220.o
LIBOBJS += devMbboMpv902.o
LIBOBJS += devMbboSoft.o
LIBOBJS += devMbboSoftRaw.o
LIBOBJS += devMbboTestAsyn.o
LIBOBJS += devMbboXVme220.o
LIBOBJS += devMz8310.o
LIBOBJS += devPtSoft.o
LIBOBJS += devSASoft.o
LIBOBJS += devSiSoft.o
LIBOBJS += devSiSymb.o
LIBOBJS += devSiTestAsyn.o
LIBOBJS += devSmCompumotor1830.o
LIBOBJS += devSmOms6Axis.o
LIBOBJS += devSoSoft.o
LIBOBJS += devSoSymb.o
LIBOBJS += devSoTestAsyn.o
LIBOBJS += devSysmon.o
LIBOBJS += devTimerMz8310.o
LIBOBJS += devVxiTDM.o
# LIBOBJS += devWfCamac.o
LIBOBJS += devWfComet.o
LIBOBJS += devWfDvx2502.o
LIBOBJS += devWfJoergerVtr1.o
LIBOBJS += devWfSoft.o
LIBOBJS += devWfTestAsyn.o
LIBOBJS += devWfXy566Sc.o
LIBOBJS += devWfPentek4261.o
LIBOBJS += devXy240.o
LIBOBJS += devAB1771IFE.o
LIBOBJS += devAB1771IL.o
LIBOBJS += devAB1771IR.o
LIBOBJS += devAB1771IXE.o
LIBOBJS += devAB1771OFE.o
LIBOBJS += devABBINARY.o
LIBOBJS += devABStatus.o
LIBOBJS += devMpc.o
PROD = devSup
LIBNAME = devSup
include $(EPICS)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -137,8 +137,8 @@ LOCAL long init_1771Ofe(struct aoRecord *prec)
"devAiAb1771Ife (init_record) startScan");
break;
}
/*wait for up to 1 seconds*/
for(failed=0; failed<10; failed++) {
/*wait for up to 3 seconds*/
for(failed=0; failed<30; failed++) {
taskDelay(vxTicksPerSecond/10);
drvStatus = (*pabDrv->getStatus)(drvPvt);
if(drvStatus==abSuccess) {

View File

@@ -3,6 +3,9 @@
/*
* $Log$
* Revision 1.24 1995/03/10 16:55:40 winans
* Added waveform writing support
*
* Revision 1.23 1995/01/06 16:55:52 winans
* Added the log parameter to the doc
*
@@ -1302,13 +1305,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1353,13 +1350,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_aiGpibFinish(pdpvt); /* and finish the processing */
@@ -1404,13 +1395,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1452,13 +1437,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1489,13 +1468,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1540,13 +1513,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_liGpibFinish(pdpvt); /* and finish the processing */
@@ -1590,13 +1557,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1638,13 +1599,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1671,13 +1626,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else /* interpret response that came back */
{
@@ -1720,13 +1669,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_biGpibFinish(pdpvt); /* and finish the processing */
@@ -1773,13 +1716,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1821,14 +1758,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1856,13 +1786,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1907,13 +1831,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_mbbiGpibFinish(pdpvt); /* and finish the processing */
@@ -1960,13 +1878,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -2009,14 +1921,8 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
return(IDLE);
}
@@ -2046,13 +1952,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -2097,13 +1997,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_stringinGpibFinish(pdpvt); /* and finish the processing */
@@ -2139,13 +2033,7 @@ struct gpibDpvt *pdpvt;
psi->val[40] = '\0';
psi->udf = FALSE;
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -2185,14 +2073,8 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
return(IDLE);
}
@@ -2225,7 +2107,7 @@ unsigned short val; /* used for EFAST operations only */
bbnode = pdpvt->head.bitBusDpvt->txMsg.node;
/*
* check to see if this node has timed out within last 10 sec
* check to see if this node has timed out within last <timeWindow> ticks
*/
if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) )
{
@@ -2679,8 +2561,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}

View File

@@ -195,6 +195,7 @@ struct card {
int word_clock;
unsigned long clock_freq;
int soc;
IOSCANPVT ioscanpvt;
};
typedef struct card CARD;
@@ -231,7 +232,6 @@ struct pvt_area {
typedef struct pvt_area PVT_AREA;
static long dev_report(int level);
static long dev_init(int after);
static long dev_init_rec(struct waveformRecord* pr);
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt);
static long dev_read(struct waveformRecord* pr);
@@ -256,9 +256,9 @@ typedef struct {
} ADC_DSET;
ADC_DSET devWfPentek4261=
{6,dev_report,dev_init,dev_init_rec,dev_ioint_info,dev_read,NULL};
{6,dev_report,NULL,dev_init_rec,dev_ioint_info,dev_read,NULL};
static IOSCANPVT ioscanpvt;
/* this is a bug! there should be one per card! */
static CARD** cards=0;
static void callback(CALLBACK* cback)
@@ -311,14 +311,6 @@ static long dev_report(int level)
return 0;
}
static long dev_init(int after)
{
if(after) return(0);
scanIoInit(&ioscanpvt);
return 0;
}
static long dev_init_rec(struct waveformRecord* pr)
{
volatile ADC* adc_regs;
@@ -524,7 +516,7 @@ static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt)
else /* CMD_DELETED */
buffer_reset(pvt); /* ensure that we are in a good state */
*iopvt=ioscanpvt;
*iopvt=(cards[pvt->card])->ioscanpvt;
return 0;
}
@@ -711,7 +703,7 @@ static void irq_func(void* v)
pvt->adc_regs->trigger=trig|0x02; /* force reset run FF */
if(pr->scan==SCAN_IO_EVENT)
scanIoRequest(ioscanpvt); /* scan EPICS record */
scanIoRequest((cards[pvt->card])->ioscanpvt); /* scan EPICS records */
else
callbackRequest(cb);
}
@@ -754,5 +746,6 @@ void ConfigurePentekADC( int card,
/* card not really present */
cards[card]->in_use=1;
}
scanIoInit(&(cards[card]->ioscanpvt));
}

View File

@@ -15,22 +15,20 @@ SRCS.c += ../devXxDc5009Gpib.c
SRCS.c += ../devXxK263Gpib.c
SRCS.c += ../devXxSkeletonGpib.c
OBJS += devAnalytekGpib.o
OBJS += devXxDg535Gpib.o
OBJS += devBBInteract.o
OBJS += devGpibInteract.o
OBJS += devXxSr620Gpib.o
OBJS += devK486Gpib.o
OBJS += devXxK196Gpib.o
OBJS += devXxDc5009Gpib.o
OBJS += devXxK263Gpib.o
OBJS += devXxSkeletonGpib.o
LIBOBJS += devAnalytekGpib.o
LIBOBJS += devXxDg535Gpib.o
LIBOBJS += devBBInteract.o
LIBOBJS += devGpibInteract.o
LIBOBJS += devXxSr620Gpib.o
LIBOBJS += devK486Gpib.o
LIBOBJS += devXxK196Gpib.o
LIBOBJS += devXxDc5009Gpib.o
LIBOBJS += devXxK263Gpib.o
LIBOBJS += devXxSkeletonGpib.o
PROD = devLibOpt $(OBJS)
LIBNAME = devLibOpt
PROD = $(LIBOBJS)
include $(EPICS)/config/RULES.Vx
devLibOpt: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -253,6 +253,7 @@ typedef struct {
unsigned short baud_rate;
unsigned short int_vector;
unsigned short int_level;
unsigned short autoconfig;
unsigned short scan_list_len;
unsigned char scan_list[64];
} ab_config;
@@ -740,6 +741,7 @@ LOCAL void config_init(ab_link *plink)
p6008 += plink->link;
pconfig->base_address = (void *)p6008;
pconfig->baud_rate = DEF_RATE;
pconfig->autoconfig = FALSE;
pconfig->int_vector = AB_VEC_BASE + plink->link;
pconfig->int_level = AB_INT_LEVEL;
pconfig->scan_list_len = 8;
@@ -763,6 +765,7 @@ int abConfigVme(int link, int base, int vector, int level)
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -778,6 +781,7 @@ int abConfigBaud(int link, int baud)
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -785,13 +789,28 @@ int abConfigBaud(int link, int baud)
else pconfig->baud_rate = FAST_RATE;
return(0);
}
int abConfigAuto(int link)
{
ab_link *plink;
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
pconfig->autoconfig = TRUE;
return(0);
}
int abConfigScanList(int link, int scan_list_len, char *scan_list)
{
ab_link *plink;
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -800,6 +819,49 @@ int abConfigScanList(int link, int scan_list_len, char *scan_list)
memcpy(pconfig->scan_list,scan_list,scan_list_len);
return(0);
}
int abConfigScanListAscii(int link, char *filename,int setRackSize)
{
FILE *fp;
char *scan_list;
char buf[80];
unsigned rack,group,size;
int nItemsRead,nCharsRead,scan_list_len;
scan_list = abCalloc(64,sizeof(char));
fp = fopen(filename,"r");
scan_list_len = 0;
while(fgets(buf,80,fp)) {
if(buf[0] == '#') continue;
nItemsRead = sscanf(buf,"%u %u %n",&rack,&group,&nCharsRead);
if(nItemsRead!=2) {
printf("abConfigScanListAscii: Illegal line %d %s\n",
scan_list_len,buf);
fclose(fp);
return(0);
}
if(!setRackSize) {
size = 0x00;
} else if(strstr(&buf[nCharsRead],"1/4")) {
size = 0x00;
} else if(strstr(&buf[nCharsRead],"1/2")) {
size = 0x40;
} else if(strstr(&buf[nCharsRead],"3/4")) {
size = 0x80;
} else if(strstr(&buf[nCharsRead],"Full")) {
size = 0xc0;
} else {
printf("abConfigScanListAscii: Illegal line %d %s\n",
scan_list_len,buf);
fclose(fp);
return(0);
}
scan_list[scan_list_len] = size | (rack<<2) | group;
scan_list_len++;
}
fclose(fp);
return(abConfigScanList(link,scan_list_len,scan_list));
}
LOCAL int ab_driver_init()
{
@@ -811,6 +873,7 @@ LOCAL int ab_driver_init()
int vxstatus;
long status;
int got_one;
char task_name[50];
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
/* check if any of the cards are there */
@@ -865,7 +928,8 @@ LOCAL int ab_driver_init()
continue;
}
plink->initialized = TRUE;
vxstatus = taskSpawn(ABSCAN_NAME,ABSCAN_PRI,ABSCAN_OPT,
sprintf(task_name,"%s%2.2d",ABSCAN_NAME,link);
vxstatus = taskSpawn(task_name,ABSCAN_PRI,ABSCAN_OPT,
ABSCAN_STACK,(FUNCPTR)abScanTask,(int)plink,
0,0,0,0,0,0,0,0,0);
if(vxstatus < 0){
@@ -874,7 +938,8 @@ LOCAL int ab_driver_init()
}
plink->abScanId = vxstatus;
taskwdInsert(plink->abScanId,NULL,NULL);
vxstatus = taskSpawn(ABDONE_NAME,ABDONE_PRI,ABDONE_OPT,
sprintf(task_name,"%s%2.2d",ABDONE_NAME,link);
vxstatus = taskSpawn(task_name,ABDONE_PRI,ABDONE_OPT,
ABDONE_STACK,(FUNCPTR)abDoneTask,(int)plink,
0,0,0,0,0,0,0,0,0);
if(vxstatus < 0){
@@ -967,7 +1032,19 @@ LOCAL int link_init(ab_link *plink)
not nice, but for now we'll have to assume that all
adapters are needed and put them all in the scan list. */
/* set scan list*/
for(ntry=0; ntry<maxCmdTrys; ntry++) {
if(pconfig->autoconfig) for(ntry=0; ntry<maxCmdTrys; ntry++) {
status = sc_lock(plink);
if(status) continue;
pmb->command = AUTO_CONF;
pmb->data_len = 0;
status = sc_waitcmd(plink);
if(status) continue;
if(pmb->conf_stat != 0) {
sc_conferr(plink);
continue;
}
break;
}else for(ntry=0; ntry<maxCmdTrys; ntry++) {
status = sc_lock(plink);
if(status) continue;
pmb->command = SCAN_LIST;
@@ -983,7 +1060,7 @@ LOCAL int link_init(ab_link *plink)
break;
}
if(ntry>=maxCmdTrys) {
printf("abDrv: SCAN_LIST failed link %hu\n",plink->link);
printf("abDrv: AUTO_CONFIG or SCAN_LIST failed link %hu\n",plink->link);
return(ERROR);
}
sc_unlock(plink);
@@ -1718,6 +1795,7 @@ LOCAL abStatus cardStatus(
plink = pab_links[link];
if(!plink || !plink->initialized) return(abFailure);
padapter = plink->papadapter[adapter];
if(!padapter->adapter_online) return(abAdapterDown);
pcard = padapter->papcard[card];
if(!pcard) return(abNoCard);
if(!padapter->adapter_online) return(abAdapterDown);

View File

@@ -87,5 +87,7 @@ int abConfigNlinks(int nlinks);
int abConfigVme(int link, int base, int vector, int level);
int abConfigBaud(int link, int baud);
int abConfigScanList(int link, int scan_list_len, char *scan_list);
int abConfigScanListAscii(int link, char *filename,int setRackSize);
int abConfigAuto(int link);
#endif /*INCdrvAbh*/

View File

@@ -71,8 +71,8 @@ epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
struct hpe1368a_config{
FAST_LOCK lock; /* mutual exclusion */
unsigned short pending; /* switch position pending int */
unsigned short shadow; /* shadow of actual switch pos */
uint16_t pending; /* switch position pending int */
uint16_t shadow; /* shadow of actual switch pos */
int busy; /* relays active */
IOSCANPVT ioscanpvt;
};

View File

@@ -1044,7 +1044,7 @@ unsigned long npoints
double dacPeakAmplitude;
double dacOffset;
double *pwf;
unsigned short *pdata_port;
uint16_t *pdata_port;
pdata_port = (unsigned short *) epvxiA24Base(la);
pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port));

View File

@@ -308,6 +308,10 @@ int smRespId; /* task id */
/* interrupt buffers */
unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ];
unsigned short counts[MAX_COMPU_MOTORS];
/* counts for debugging */
long dbicounts; /* counts number of times through interrupt routine */
long dbrcounts; /* counts number of times through response routine */
long dbscounts; /* counts number of times through send routine */
/* VME memory Short Address Space is set up in gta_init */
static int *compu_addr;
@@ -392,6 +396,7 @@ compu_resp_task()
FOREVER {
/* wait for somebody to wake us up */
semTake (smRespSem, WAIT_FOREVER);
(dbrcounts < 0xFFFF ? dbrcounts++: 0);
/* the response buffer contains: */
/* 0 - motor number */
/* 1 - the command which solicited this response */
@@ -522,7 +527,12 @@ register int mdnum;
/* pointer to the compumotor card interface */
pmtr = pcompu_motors[mdnum];
if (pmtr == 0)
{
intUnlock(key);
return(0);
};
(dbicounts < 0xFFFF ? dbicounts++: 0);
/* place the response byte into the appropriate response buffer */
sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb;
counts[mdnum]++;
@@ -545,6 +555,7 @@ register int mdnum;
}
intUnlock(key);
return(0);
}
/*
@@ -621,17 +632,18 @@ short trigger = 0;
*
* driver interface to the database library layer
*/
compu_driver(card,value_flag,arg1,arg2)
compu_driver(card, channel, value_flag,arg1,arg2)
register short card;
short channel;
short value_flag;
register int arg1;
register int arg2;
{
register int *pint;
register short *pshort;
short j,i;
short i;
char compu_msg[20];
i = 0;
/* verify the stepper motor driver card is present */
if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card]))
return (-1);
@@ -661,144 +673,16 @@ register int arg2;
case (SM_MOVE):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(0);
i = 0;
switch (trigger){
case (0):
/* move the motor */
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (1): /* test sequnce buffer */
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (2): /* test move buffer */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (3): /* test sequence buffer with move buffer */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (4): /* test sequence buffer with move buffer and trigger */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
/* move the motor */
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = compu_motor_data_array[card].velocity;
i += 4;
pint++;
*pint = compu_motor_data_array[card].accel;
i += 4;
pint++;
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x2c; /* wait for trigger */
compu_msg[i++] = 1; /*trigger 1 */
compu_msg[i++] = 1; /* don't care about state */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
}
for (j = 0; j < i; j++){
printf("%x ",compu_msg[j]);
}
/* compu_send_msg(pcompu_motors[card],compu_msg,i);
*/
/* set the motor to active */
compu_motor_array[card].active = TRUE;
@@ -884,6 +768,7 @@ register struct compumotor *pmotor;
register char *pmsg;
register short count;
{
(dbscounts < 0xFFFF ? dbscounts++: 0);
/* write out this command one byte at a time */
while (count){
@@ -969,4 +854,3 @@ VOID compu_sm_reset()
}
}
}

View File

@@ -59,6 +59,9 @@
*
*
* $Log$
* Revision 1.3 1995/04/25 15:32:23 winans
* Changed name of HiDEOS link configuration command/function.
*
* Revision 1.2 1995/04/12 19:31:41 winans
* Added support for the HiDEOS system as a GPIB bus transport agent.
*
@@ -974,12 +977,36 @@ char *buffer; /* data to transfer */
int length; /* number of bytes to transfer */
int time; /* time to wait on the DMA operation */
{
int status;
short cnt;
register struct ibregs *b;
char w_imr2;
int temp_addr;
int tmoTmp;
int status = ERROR;
unsigned short cnt;
struct ibregs *b;
char w_imr2;
int temp_addr;
int tmoTmp;
#ifdef NI_GPIB_LOOP_LENGTH
#define NI_GPIB_CHUNKSIZE 0x0ffff
while (length > 0)
{
if (length > NI_GPIB_CHUNKSIZE)
{
cnt = NI_GPIB_CHUNKSIZE;
length -= NI_GPIB_CHUNKSIZE;
}
else
{
cnt = length;
length = 0;
}
#else
cnt = length;
if (cnt > 0x0fffe)
{
errMessage(S_IB_SIZE, "NI-1014 max length (65535) exceeded");
return(ERROR);
}
#endif
if (pNiLink[link]->A24BounceBuffer == NULL)
{
@@ -993,25 +1020,24 @@ int time; /* time to wait on the DMA operation */
logMsg("Got a bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
}
if (pNiLink[link]->A24BounceSize < length)
if (pNiLink[link]->A24BounceSize < cnt)
{ /* Reallocate a larger bounce buffer */
devLibA24Free(pNiLink[link]->A24BounceBuffer); /* Loose the old one */
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(length)) == NULL)
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(cnt)) == NULL)
{
errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!");
pNiLink[link]->A24BounceSize = 0;
pNiLink[link]->A24BounceBuffer = NULL;
return(ERROR);
}
pNiLink[link]->A24BounceSize = length;
pNiLink[link]->A24BounceSize = cnt;
if(ibDebug > 5)
logMsg("Got a new bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
}
b = pNiLink[link]->ibregs;
cnt = length;
b->auxmr = AUX_GTS; /* go to standby mode */
b->ch1.ccr = D_SAB; /* halt channel activity */
@@ -1049,7 +1075,7 @@ int time; /* time to wait on the DMA operation */
else /* (dir == READ) */
{
/* We will be writing, copy data into the bounce buffer */
memcpy(pNiLink[link]->A24BounceBuffer, buffer, length);
memcpy(pNiLink[link]->A24BounceBuffer, buffer, cnt);
if (cnt != 1)
pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */
@@ -1231,9 +1257,13 @@ int time; /* time to wait on the DMA operation */
if (dir == READ)
{ /* Copy data from the bounce buffer to the user's buffer */
memcpy(buffer, pNiLink[link]->A24BounceBuffer, length);
memcpy(buffer, pNiLink[link]->A24BounceBuffer, cnt);
}
#ifdef NI_GPIB_LOOP_LENGTH
buffer += NI_GPIB_CHUNKSIZE;
}
#endif
return (status);
}

View File

@@ -338,13 +338,13 @@ register unsigned int val;
/* use structure to handle high and low short swap */
/* get current output */
work = (dio[card].dptr->port6_7 << 16)
+ dio[card].dptr->port4_5;
work = (dio[card].dptr->port4_5 << 16)
+ dio[card].dptr->port6_7;
work = (work & ~mask) | (val & mask);
dio[card].dptr->port6_7 = (unsigned short)(work >> 16);
dio[card].dptr->port4_5 = (unsigned short)work;
dio[card].dptr->port4_5 = (unsigned short)(work >> 16);
dio[card].dptr->port6_7 = (unsigned short)work;
return OK;
}

View File

@@ -9,6 +9,7 @@ SRCS.c += ../calcPerform.c
SRCS.c += ../cvtFast.c
SRCS.c += ../ellLib.c
SRCS.c += ../envSubr.c
SRCS.c += envData.c
SRCS.c += ../errInc.c
SRCS.c += ../errMtst.c
SRCS.c += ../errPrintfUNIX.c
@@ -29,6 +30,7 @@ LIBOBJS += calcPerform.o
LIBOBJS += cvtFast.o
LIBOBJS += ellLib.o
LIBOBJS += envSubr.o
LIBOBJS += envData.o
LIBOBJS += errMtst.o
LIBOBJS += errPrintfUNIX.o
LIBOBJS += errSymLib.o
@@ -54,11 +56,11 @@ errSymTbl.o: errSymTbl.c errInc.o
errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl;
@../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
$(EPICS)/config/CONFIG_SITE_ENV
../bldEnvData $(EPICS)
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c
@@ -67,5 +69,5 @@ tsTest: tsSubr.o
$(LINK.c) -o $@ tsSubr.o -lCom -lDb -lCom -lm -s
clean::
@$(RM) errInc.c errSymTbl.c envData.h
@$(RM) errInc.c errSymTbl.c envData.c

View File

@@ -3,12 +3,12 @@ include Target.include
include $(EPICS)/config/CONFIG_BASE
SRCS.c += ../calcPerform.c
SRCS.c += ../cvtBpt.c
SRCS.c += ../cvtFast.c
SRCS.c += ../gpHashLib.c
SRCS.c += ../freeListLib.c
SRCS.c += ../ellLib.c
SRCS.c += ../envSubr.c
SRCS.c += envData.c
SRCS.c += ../errSymLib.c
SRCS.c += ../nextFieldSubr.c
SRCS.c += ../postfix.c
@@ -21,45 +21,41 @@ SRCS.c += errSymTbl.c
SRCS.c += ../errPrintfVX.c
SRCS.c += ../assertVX.c
OBJS += calcPerform.o
OBJS += cvtBpt.o
OBJS += cvtFast.o
OBJS += ellLib.o
OBJS += envSubr.o
OBJS += errSymLib.o
OBJS += errSymTbl.o
OBJS += nextFieldSubr.o
OBJS += postfix.o
OBJS += bucketLib.o
OBJS += tsSubr.o
OBJS += gpHashLib.o
OBJS += freeListLib.o
OBJS += pal.o
OBJS += paldef.o
OBJS += errPrintfVX.o
OBJS += assertVX.o
LIBOBJS += calcPerform.o
LIBOBJS += cvtFast.o
LIBOBJS += ellLib.o
LIBOBJS += envData.o
LIBOBJS += envSubr.o
LIBOBJS += errSymLib.o
LIBOBJS += errSymTbl.o
LIBOBJS += nextFieldSubr.o
LIBOBJS += postfix.o
LIBOBJS += bucketLib.o
LIBOBJS += tsSubr.o
LIBOBJS += gpHashLib.o
LIBOBJS += freeListLib.o
LIBOBJS += pal.o
LIBOBJS += paldef.o
LIBOBJS += errPrintfVX.o
LIBOBJS += assertVX.o
PROD = libCom
LIBNAME = libCom
include $(EPICS)/config/RULES.Vx
clean::
@$(RM) errInc.c errSymTbl.c envData.h
@$(RM) errInc.c errSymTbl.c envData.c
build: errSymTbl.o errInc.o
errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl
../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
$(EPICS)/config/CONFIG_SITE_ENV
../bldEnvData $(EPICS)
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c
libCom: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -26,6 +26,7 @@
*
* Modification Log:
* -----------------
* $Log$
*/
#include <stdlib.h>
@@ -58,7 +59,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
"Please contact the author of this software or else send the text of\n");
epicsPrintf (
"this message to \"tech_talk@aps.anl.gov\"\n");
"this message to \"tech-talk@aps.anl.gov\"\n");
abort ();
}

View File

@@ -26,6 +26,7 @@
*
* Modification Log:
* -----------------
* $Log$
***************************************************************************
*/
@@ -64,7 +65,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
taskId);
epicsPrintf (
"to the author or \"tech_talk@aps.anl.gov\"\n");
"to the author or \"tech-talk@aps.anl.gov\"\n");
taskSuspend (taskId);
}

613
src/libCom/bdt.c Normal file
View File

@@ -0,0 +1,613 @@
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef linux
#include <sys/resource.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include "bdt.h"
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#ifdef linux
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BdtServerClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BdtMakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#ifdef linux
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* ------------------------------------------ */
/* unimplemented channel access open function */
/* ------------------------------------------ */
BDT* BdtPvOpen(char* name)
{
return (BDT*)NULL;
}
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BDT* BdtIpOpen(char* address, int Port)
{
struct sockaddr_in tsin;
unsigned long addr;
int osoc;
BDT* bdt;
/* request the process variables (bulk data?) */
addr=inet_addr(address);
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtIpOpen: create socket failed");
return (BDT*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtIpOpen: local address bind failed");
return (BDT*)NULL;
}
tsin.sin_port=htons(Port);
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
{
perror("BdtIpOpen: connect failed");
close(osoc);
return (BDT*)NULL;
}
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=osoc;
bdt->pending_delta=0;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtUnbound;
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BdtWrite(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
data=(unsigned char*)buffer;
total=size;
do
{
/* send block of data */
if((rc=send(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
rc=0;
else
{ perror("BdtWrite: Send to remote failed"); }
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BDT socket */
/* --------------------------------------- */
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
{
BdtMsgHead buf;
if(bdt->state!=BdtIdle)
{
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BdtSData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BDT socket */
/* ------------------------------------------- */
int BdtSendData(BDT* bdt,void* buffer,int size)
{
int len,remaining,rc;
if(bdt->state!=BdtSData)
{
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
bdt->state=BdtBad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"BdtSendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
/* this function should loop until size bytes is sent */
/* send out the chunk */
if((rc=send(bdt->soc,(char*)buffer,len,0))<0)
{
perror("BdtSendData: Send data chunk to remote failed");
return -1;
}
bdt->remaining_send-=rc;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BdtSendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BdtIdle;
return rc;
}
/* ------------------------------------------------------------------------
report if data is pending from remote
clear the pending data condition
------------------------------------------------------------------------ */
int BdtPvDeltaPending(BDT* bdt)
{
int rc = bdt->pending_delta;
bdt->pending_delta=0;
return rc;
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BdtRead(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
data=(unsigned char*)buffer;
total=size;
do
{
/* wait for data chunk */
if((rc=recv(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
rc=0;
else
{ perror("BdtRead: Receive data chunk failed"); }
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
{
BdtMsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BdtEof)
return -1;
if(bdt->state != BdtIdle)
{
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BdtRData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BdtReceiveData(BDT* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BdtRData: break;
case BdtIdle: return 0;
default:
fprintf(stderr,"BdtReceiveData: bad receive state\n");
bdt->state=BdtBad;
break;
}
if(BdtRead(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BdtReceiveData: Read failed\n");
bdt->state = BdtEof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BdtReceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BdtIdle;
return size;
}
/* ------------------------------------------------------ */
/* connect to a process variable, useful if raw open used */
/* ------------------------------------------------------ */
int BdtServiceConnect(BDT* bdt, char* service_name)
{
int len,rc,size,verb;
if(bdt->state!=BdtUnbound)
{
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
return -1;
}
bdt->state=BdtIdle;
len=strlen(service_name)+1;
/* send out connect message */
if(BdtSendHeader(bdt,BDT_Connect,len)<0)
{
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* send out the process variable to connect to */
if(BdtSendData(bdt,service_name,len)<0)
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
rc=0;
/* wait for response from connect to process variable */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* check response */
switch(verb)
{
case BDT_Ok:
rc=0;
break;
case BDT_Error:
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
bdt->state=BdtUnbound;
rc=-1;
break;
default:
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
bdt->state=BdtUnbound;
rc=-1;
break;
}
return rc;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BdtClose(BDT* bdt)
{
int verb,size,done;
/* send a close message out */
if(BdtSendHeader(bdt,BDT_Close,0)<0)
{
fprintf(stderr,"BdtClose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtClose: Close message response error\n");
return -1;
}
switch(verb)
{
case BDT_Ok:
done=1;
break;
case BDT_Error:
fprintf(stderr,"BdtClose: Close rejected\n");
return -1;
break;
default: break;
}
}
while(done==0);
bdt->state=BdtUnbound;
free(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BdtOpenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
{
perror("BdtOpenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BdtOpenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset (&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtOpenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BDT from a socket - simple */
/* ------------------------------- */
BDT* BdtMakeBDT(int soc)
{
BDT* bdt;
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=soc;
bdt->pending_delta=0;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtIdle;
return bdt;
}
/* --------------------------- */
/* free a BDT and close socket */
/* --------------------------- */
int BdtFreeBDT(BDT* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
/* ------------------------------------------------- */
/* connect to a generic service on the remote server */
/* ------------------------------------------------- */
int BdtPvConnect(BDT* bdt, char* pv_name)
{
char* data;
int len,rc;
len=strlen(pv_name)+strlen(BDT_PV_SERVICE)+2;
data=(char*)malloc(len);
sprintf(data,"%s %s",BDT_PV_SERVICE,pv_name);
rc=BdtServiceConnect(bdt,data);
free(data);
return rc;
}

105
src/libCom/bldEnvData Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/sh
#
# base/tools $Id$
# Author: Andrew Johnson (RGO)
# Date: 14-Mar-95
#
# Experimental Physics and Industrial Control System (EPICS)
#
# $Log$
# Revision 1.3 1995/08/14 19:27:24 jhill
# extern => epicsShareExtern
#
# Revision 1.2 1995/05/04 09:49:24 anj
# Added CONFIG_SITE_ENV, changed envData to .c file
#
# Revision 1.1 1995/04/24 16:02:29 anj
# Moved environment parameter defaults to config/CONFIG_ENV
#
#
# tool to build envData.c from envDefs.h and config/CONFIG*ENV
# Usage bldEnvData
HERE=`/bin/pwd`
cd $1
EPICS=`/bin/pwd`
cd ${HERE}
SRC=${EPICS}/base/include/envDefs.h
ENV_DATA=${EPICS}/config/CONFIG_ENV
SITE_DATA=${EPICS}/config/CONFIG_SITE_ENV
OBJ=envData.c
TOOL=`basename $0`
# Start by creating a list of the ENV_PARAM declarations
PARAMS=`sed -n -e 's/;//' \
-e 's/^[ ]*epicsShareExtern[ ][ ]*ENV_PARAM[ ][ ]*//p' \
${SRC}`
# Create a new header file
rm -rf ${OBJ}
cat >${OBJ} <<!EOF
/* ${HERE}/${OBJ}
*
* created by ${TOOL}
*
* from:
* ${SRC}
* ${ENV_DATA}
* ${SITE_DATA}
*
* `date`
*
*/
#include <envDefs.h>
!EOF
# Make sure no corresponding shell environment variables
unset ${PARAMS}
# Read the default values from the config file into shell variables
. ${ENV_DATA}
. ${SITE_DATA}
# Scan through the parameters to create the definition
for ENV in ${PARAMS}
do
# Get the default, complain if not present
if [ `set | grep -c ${ENV}=` = 0 ];
then
echo No default value for ${ENV}
DEFAULT=""
else
VAR='$'${ENV}
DEFAULT=`eval echo ${VAR}`
fi
# Add this definition to the header file
# echo ${ENV} = ${DEFAULT}
echo ENV_PARAM ${ENV}'={"'${ENV}'","'${DEFAULT}'"};' >>${OBJ}
done
# Now create an array pointing to all parameters
cat >>${OBJ} <<!EOF
ENV_PARAM* env_param_list[] = {
!EOF
# Contents are the addresses of each parameter
for ENV in ${PARAMS}
do
echo ' &'${ENV}, >>${OBJ}
done
# Finally finish list with 0
cat >>${OBJ} <<!EOF
0
};
!EOF
exit 0

118
src/libCom/blderrSymTbl Executable file
View File

@@ -0,0 +1,118 @@
#!/bin/sh
#
# base/tools $Id$
# Author: Robert Zieman (ANL)
# Date: 6/03/91
#
# Experimental Physics and Industrial Control System (EPICS)
#
# Copyright 1991, the Regents of the University of California,
# and the University of Chicago Board of Governors.
#
# This software was produced under U.S. Government contracts:
# (W-7405-ENG-36) at the Los Alamos National Laboratory,
# and (W-31-109-ENG-38) at Argonne National Laboratory.
#
# Initial development by:
# The Controls and Automation Group (AT-8)
# Ground Test Accelerator
# Accelerator Technology Division
# Los Alamos National Laboratory
#
# Co-developed with
# The Controls and Computing Group
# Accelerator Systems Division
# Advanced Photon Source
# Argonne National Laboratory
#
# Modification Log:
# -----------------
# .00 mm-dd-yy iii Comment
# .01 05-04-94 pg HPUX port modifications.
# .02 08-25-94 mda use makedepend for HP or Alpha if no GCC
# .03 04-28-95 anj use GetVar and case for host arch
# ...
#
# tool to rebuild errSymTbl.c when errInc.c or it's depends change
# Usage blderrSymTbl EPICS HOST_ARCH MAKE VXLIST - IOC and commmon
# Usage blderrSymTbl EPICS HOST_ARCH MAKE - just common
if [ "x" = "x$4" ]; then
DEF="XXX"
else
DEF="${4}"
fi
TMPMAKEFILE=/tmp/tmpmakefile
SFILES=/tmp/sfiles
EPICS=$1
HOST_ARCH=$2
MAKE=$3
case $HOST_ARCH in
alpha | hp700)
# Use gcc if it can be found, or makedepend
GCC=`which gcc`
if [ -x "$GCC" ]; then
FILES=`"$GCC" -M -D$DEF -I../../../include \
errInc.c 2>/dev/null \
| sed -e 's/errInc\.o.*: errInc\.c//' -e 's/\\\//'`
else
MAKEDEPEND=`which makedepend`
if [ -x "$MAKEDEPEND" ]; then
FILES=`"$MAKEDEPEND" -f- -D$DEF -I../../../include \
errInc.c 2>/dev/null | sed -e 's/errInc.o://' -e 's/\\\//'`
else
echo Neither GCC or MAKEDEPEND found.
exit 1
fi
fi
;;
solaris)
# use -xM option of ACC to list dependencies
CC=`$EPICS/base/tools/GetVar $EPICS ACC $HOST_ARCH`
FILES=`$CC -xM -D$DEF -I../../../include errInc.c \
| grep "errInc.o" | grep -v "errInc.c" \
| sed -e 's/errInc\.o://'`
;;
sun4)
# use -M option of Sun compiler to list make dependencies
FILES=`cc -M -D$DEF -I../../../include errInc.c 2>/dev/null \
| grep "errInc.o" | grep -v "errInc.c" \
| sed -e 's/errInc\.o://'`
;;
*)
# Unrecognised host architecture
echo $0: host architecture not supported
exit 1
esac
# files with S_ defines
grep "^#define[ ]*S_" $FILES /dev/null \
| sed -e 's-:.*--' | sort -u >$SFILES
# create a tmpmakefile
cat $SFILES | (awk '
BEGIN {print "errInc.o : errInc.c \\"}
{print " "$0" \\" }
END {print " ../../../include/errMdef.h"}
') > $TMPMAKEFILE
cat >> $TMPMAKEFILE <<!addon
/bin/rm -f errSymTbl.c
../makeStatTbl \`cat $SFILES\` >errSymTbl.c
/bin/rm -f errInc.o
touch errInc.o
!addon
$MAKE -f $TMPMAKEFILE
/bin/rm -f $TMPMAKEFILE $SFILES
exit 0

View File

@@ -119,17 +119,17 @@ main()
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
return -1;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
start = clock();
for(i=0; i<LOOPS; i++){
@@ -166,7 +166,7 @@ main()
bucketShow(pb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
#endif
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
pb->hashIdNBits = nbits;
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
if (!pb->pTable) {
free (pb);
return NULL;
}
return pb;
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
* bucketFree()
*/
#ifdef __STDC__
int bucketFree(BUCKET *prb)
int bucketFree (BUCKET *prb)
#else
int bucketFree(prb)
int bucketFree (prb)
BUCKET *prb;
#endif
{
@@ -389,7 +389,7 @@ BUCKET *prb;
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
assert(prb->nInUse==0);
assert (prb->nInUse==0);
/*
* free the free list
@@ -400,10 +400,10 @@ BUCKET *prb;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
free (prb->pTable);
free (prb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM **ppi;
ITEM **ppiExists;
ITEM *pi;
/*
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
prb->pFreeItems = pi->pItem;
}
else {
pi = (ITEM *) malloc(sizeof(ITEM));
pi = (ITEM *) malloc (sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
return S_bucket_noMemory;
}
}
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
assert ((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
/*
* Dont reuse a resource id !
*/
ppiExists = (*pBSET->pCompare) (ppi, pId);
if (ppiExists) {
return S_bucket_idInUse;
}
pi->pItem = *ppi;
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
return S_bucket_uknId;
}
prb->nInUse--;
pi = *ppi;
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
@@ -611,7 +621,7 @@ BUCKET *pb;
stdDev,
maxEntries);
return BUCKET_SUCCESS;
return S_bucket_success;
}

View File

@@ -119,17 +119,17 @@ main()
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
return -1;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
start = clock();
for(i=0; i<LOOPS; i++){
@@ -166,7 +166,7 @@ main()
bucketShow(pb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
#endif
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
pb->hashIdNBits = nbits;
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
if (!pb->pTable) {
free (pb);
return NULL;
}
return pb;
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
* bucketFree()
*/
#ifdef __STDC__
int bucketFree(BUCKET *prb)
int bucketFree (BUCKET *prb)
#else
int bucketFree(prb)
int bucketFree (prb)
BUCKET *prb;
#endif
{
@@ -389,7 +389,7 @@ BUCKET *prb;
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
assert(prb->nInUse==0);
assert (prb->nInUse==0);
/*
* free the free list
@@ -400,10 +400,10 @@ BUCKET *prb;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
free (prb->pTable);
free (prb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM **ppi;
ITEM **ppiExists;
ITEM *pi;
/*
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
prb->pFreeItems = pi->pItem;
}
else {
pi = (ITEM *) malloc(sizeof(ITEM));
pi = (ITEM *) malloc (sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
return S_bucket_noMemory;
}
}
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
assert ((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
/*
* Dont reuse a resource id !
*/
ppiExists = (*pBSET->pCompare) (ppi, pId);
if (ppiExists) {
return S_bucket_idInUse;
}
pi->pItem = *ppi;
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
return S_bucket_uknId;
}
prb->nInUse--;
pi = *ppi;
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
@@ -611,7 +621,7 @@ BUCKET *pb;
stdDev,
maxEntries);
return BUCKET_SUCCESS;
return S_bucket_success;
}

View File

@@ -31,6 +31,7 @@
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
* vars under vxWorks
* .05 04-20-95 anj changes to use CONFIG_ENV
* .06 05-24-95 joh added return stmnt to epicsPrtEnvParams()
*
* make options
* -DvxWorks makes a version for VxWorks
@@ -67,7 +68,7 @@
#include <stdlib.h>
#include <string.h>
#ifdef _WINDOWS
#ifdef WIN32
# include <winsock.h>
#else
# include <sys/types.h>
@@ -81,9 +82,13 @@
#endif
#include <envDefs.h>
#include "envData.h"
#include <errMdef.h>
/*
* for VMS
*/
unsigned long inet_addr (char *);
/*+/subr**********************************************************************
* NAME envGetConfigParam - get value of a configuration parameter
@@ -243,7 +248,7 @@ struct in_addr *pAddr; /* O pointer to struct to receive inet addr */
ptext = envGetConfigParam(pParam, sizeof text, text);
if (ptext) {
status = inet_addr(text);
status = inet_addr (text);
if (status != -1) {
pAddr->s_addr = status;
return 0;
@@ -422,14 +427,6 @@ char *value; /* I pointer to value string */
#endif
}
/* epicsSetEnvParams not required any more - do not use */
int epicsSetEnvParams()
{
return 0;
}
/*+/subr**********************************************************************
* NAME epicsPrtEnvParams - print value of all configuration parameters
*
@@ -454,5 +451,7 @@ epicsPrtEnvParams()
while (*ppParam != NULL)
envPrtConfigParam(*(ppParam++));
return 0;
}

View File

@@ -31,6 +31,7 @@
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
* vars under vxWorks
* .05 04-20-95 anj changes to use CONFIG_ENV
* .06 05-24-95 joh added return stmnt to epicsPrtEnvParams()
*
* make options
* -DvxWorks makes a version for VxWorks
@@ -67,7 +68,7 @@
#include <stdlib.h>
#include <string.h>
#ifdef _WINDOWS
#ifdef WIN32
# include <winsock.h>
#else
# include <sys/types.h>
@@ -81,9 +82,13 @@
#endif
#include <envDefs.h>
#include "envData.h"
#include <errMdef.h>
/*
* for VMS
*/
unsigned long inet_addr (char *);
/*+/subr**********************************************************************
* NAME envGetConfigParam - get value of a configuration parameter
@@ -243,7 +248,7 @@ struct in_addr *pAddr; /* O pointer to struct to receive inet addr */
ptext = envGetConfigParam(pParam, sizeof text, text);
if (ptext) {
status = inet_addr(text);
status = inet_addr (text);
if (status != -1) {
pAddr->s_addr = status;
return 0;
@@ -422,14 +427,6 @@ char *value; /* I pointer to value string */
#endif
}
/* epicsSetEnvParams not required any more - do not use */
int epicsSetEnvParams()
{
return 0;
}
/*+/subr**********************************************************************
* NAME epicsPrtEnvParams - print value of all configuration parameters
*
@@ -454,5 +451,7 @@ epicsPrtEnvParams()
while (*ppParam != NULL)
envPrtConfigParam(*(ppParam++));
return 0;
}

View File

@@ -18,6 +18,7 @@
#include "dbStaticLib.h"
#include "drvEpvxi.h"
#include "devLib.h"
#include "casdef.h"
#include "errMdef.h"
#ifdef VXLIST
/* epics vxWorks only*/

View File

@@ -77,7 +77,9 @@ void errPrintf(long status, const char *pFileName,
printf("%s ",name);
}
}
vprintf(pformat,pvar);
if (pformat) {
vprintf(pformat,pvar);
}
printf("\n");
}

View File

@@ -257,6 +257,10 @@ LOCAL int vmprintf (const char *pFormat, va_list pvar)
int s0;
int s1;
if (!pFormat) {
return 0;
}
s0 = vfprintf(stdout,pFormat,pvar);
fflush(stdout);
s1 = vfprintf(iocLogFile,pFormat,pvar);

View File

@@ -68,6 +68,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <ellLib.h>
#include <dbDefs.h>
@@ -137,17 +138,25 @@ int errSymBld()
unsigned short hashInd;
if(initialized) return(0);
hashtable = (ERRNUMNODE**)dbCalloc(NHASH, sizeof(ERRNUMNODE*));
hashtable = (ERRNUMNODE**)calloc(NHASH, sizeof(ERRNUMNODE*));
if(!hashtable) {
printf("errSymBld: Can't allocate storage\n");
#ifdef vxWorks
taskSuspend(0);
#else
abort();
#endif
}
for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) {
modnum = errArray->errNum >> 16;
if (modnum < 501) {
printf("errSymBld: ERROR - Module number in errSymTbl < 501\n");
return (-1);
printf("errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%x Name=%s\n",
errArray->errNum, errArray->name);
continue;
}
if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) {
printf("errSymBld: ERROR - errSymbolAdd() failed \n");
return (-1);
continue;
}
}
perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist);
@@ -206,7 +215,15 @@ char *name;
ELLLIST *perrnumlist = &errnumlist;
ERRNUMNODE *pNew;
pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE));
pNew = (ERRNUMNODE*)calloc(1, sizeof(ERRNUMNODE));
if(!pNew) {
printf("errSymbolAdd: Can't allocate storage\n");
#ifdef vxWorks
taskSuspend(0);
#else
abort();
#endif
}
pNew->errNum = errNum;
pNew->message = name;
ellAdd(perrnumlist,(ELLNODE*)pNew);

View File

@@ -68,6 +68,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <ellLib.h>
#include <dbDefs.h>
@@ -137,17 +138,25 @@ int errSymBld()
unsigned short hashInd;
if(initialized) return(0);
hashtable = (ERRNUMNODE**)dbCalloc(NHASH, sizeof(ERRNUMNODE*));
hashtable = (ERRNUMNODE**)calloc(NHASH, sizeof(ERRNUMNODE*));
if(!hashtable) {
printf("errSymBld: Can't allocate storage\n");
#ifdef vxWorks
taskSuspend(0);
#else
abort();
#endif
}
for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) {
modnum = errArray->errNum >> 16;
if (modnum < 501) {
printf("errSymBld: ERROR - Module number in errSymTbl < 501\n");
return (-1);
printf("errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%x Name=%s\n",
errArray->errNum, errArray->name);
continue;
}
if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) {
printf("errSymBld: ERROR - errSymbolAdd() failed \n");
return (-1);
continue;
}
}
perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist);
@@ -206,7 +215,15 @@ char *name;
ELLLIST *perrnumlist = &errnumlist;
ERRNUMNODE *pNew;
pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE));
pNew = (ERRNUMNODE*)calloc(1, sizeof(ERRNUMNODE));
if(!pNew) {
printf("errSymbolAdd: Can't allocate storage\n");
#ifdef vxWorks
taskSuspend(0);
#else
abort();
#endif
}
pNew->errNum = errNum;
pNew->message = name;
ellAdd(perrnumlist,(ELLNODE*)pNew);

View File

@@ -66,6 +66,10 @@
* problem (send call back discarded when fdmgr pend
* event time out expires even if the send call back
* has not been called at least once).
* .18 joh 051995 Changed the semantics of alarm create/delete
* routines in a backwards compatible way so that
* we eliminate delete ambiguity (chance of the same
* being reused).
*
* NOTES:
*
@@ -73,22 +77,7 @@
* with the lower likelyhood of select blocking
* on a fd write.
*
* .02 joh 012093 **** WARNING ****
* Assume that a timer id returned by fdmgr_add_timeout()
* will be reused (and returned from a subsequent call to
* fdmgr_add_timeout()) after either of the following two
* circumstances occur:
* 1) You delete the timer referenced by the timer id with
* fdmgr_clear_timeout()
* 2) The timer expires (and the handler which you
* have established for the timer id is executed)
* Take care not to attempt to delete a timer which
* has already expired (and therefore executed your timer
* expiration handler subroutine). Attempting to
* delete a timer which has already expired could
* result in deletion of the wrong timer.
*
* .03 joh 012193 terse DOCUMENTATION has been added to the header file
* .02 joh 012193 terse DOCUMENTATION has been added to the header file
* share/epicsH/fdmgr.h
*
*/
@@ -102,7 +91,19 @@ static char *pSccsId = "@(#) $Id$";
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
/*
* Yuk
*/
#if defined (MULTINET)
# define select_errno socket_errno
#elif defined (WINTCP)
# define select_errno uerrno
extern int uerrno;
#else
# include <errno.h>
# define select_errno errno
#endif
#ifdef vxWorks
#include <vxWorks.h>
@@ -116,6 +117,10 @@ static char *pSccsId = "@(#) $Id$";
#include <epicsAssert.h>
#include <fdmgr.h>
#include <epicsTypes.h>
#define NOBSDNETPROTO
#include <bsdProto.h>
#ifndef TRUE
#define TRUE 1
@@ -151,6 +156,15 @@ typedef struct{
int delete_pending;
}fdentry;
typedef struct{
ELLNODE node;
struct timeval t;
void (*func)(void *pParam);
void *param;
enum alarm_list_type alt;
unsigned id;
}fdmgrAlarm;
#if defined(vxWorks)
# define LOCK(PFDCTX) assert(semTake((PFDCTX)->lock, WAIT_FOREVER)==OK);
# define UNLOCK(PFDCTX) assert(semGive((PFDCTX)->lock)==OK);
@@ -169,7 +183,7 @@ typedef struct{
# define UNLOCK_FD_HANDLER(PFDCTX) \
assert(semGive((PFDCTX)->fd_handler_lock)==OK);
#elif defined(UNIX) || defined(VMS) || defined(_WIN32)
#elif defined(UNIX) || defined(VMS) || defined(WIN32)
# define LOCK(PFDCTX)
# define UNLOCK(PFDCTX)
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
@@ -228,6 +242,16 @@ fdctx *fdmgr_init(void)
fdctx *pfdctx;
pfdctx = (fdctx *) calloc(1, sizeof(fdctx));
if (!pfdctx) {
return pfdctx;
}
pfdctx->pAlarmBucket = bucketCreate (1024);
if (!pfdctx->pAlarmBucket) {
free (pfdctx);
return NULL;
}
# if defined(vxWorks)
pfdctx->lock = semMCreate (SEM_DELETE_SAFE);
if (pfdctx->lock == NULL){
@@ -248,6 +272,7 @@ fdctx *fdmgr_init(void)
pfdctx->clk_rate = sysClkRateGet();
pfdctx->last_tick_count = tickGet();
# endif
ellInit(&pfdctx->fdentry_list);
ellInit(&pfdctx->fdentry_in_use_list);
ellInit(&pfdctx->fdentry_free_list);
@@ -255,6 +280,7 @@ fdctx *fdmgr_init(void)
ellInit(&pfdctx->expired_alarm_list);
ellInit(&pfdctx->free_alarm_list);
/*
* returns NULL if unsuccessful
*/
@@ -269,7 +295,9 @@ fdctx *fdmgr_init(void)
*/
int fdmgr_delete(fdctx *pfdctx)
{
int status;
int status;
fdmgrAlarm *palarm;
fdmgrAlarm *pnext;
if(!pfdctx){
return ERROR;
@@ -289,7 +317,17 @@ int fdmgr_delete(fdctx *pfdctx)
ellFree(&pfdctx->fdentry_list);
ellFree(&pfdctx->fdentry_in_use_list);
ellFree(&pfdctx->fdentry_free_list);
ellFree(&pfdctx->alarm_list);
for ( palarm = (fdmgrAlarm *) ellFirst (&pfdctx->alarm_list);
palarm;
palarm = pnext) {
pnext = (fdmgrAlarm *) ellNext (&palarm->node);
status = bucketRemoveItemUnsignedId(
pfdctx->pAlarmBucket,
&palarm->id);
assert (status == S_bucket_success);
free (palarm);
}
bucketFree (pfdctx->pAlarmBucket);
ellFree(&pfdctx->expired_alarm_list);
ellFree(&pfdctx->free_alarm_list);
@@ -300,26 +338,26 @@ int fdmgr_delete(fdctx *pfdctx)
/*
* fdmgr_add_timeout()
*/
fdmgrAlarm *fdmgr_add_timeout(
fdmgrAlarmId fdmgr_add_timeout(
fdctx *pfdctx,
struct timeval *ptimeout,
void (*func)(void *),
void *param
)
{
fdmgrAlarm *palarm=NULL;
fdmgrAlarm *pa;
fdmgrAlarm *palarm=NULL;
fdmgrAlarm *pa;
struct timeval t;
int status;
if(ptimeout->tv_sec < 0)
return NULL;
return fdmgrNoAlarm;
if(ptimeout->tv_usec < 0)
return NULL;
return fdmgrNoAlarm;
status = fdmgr_gettimeval(pfdctx, &t);
if(status < 0)
return NULL;
return fdmgrNoAlarm;
LOCK(pfdctx);
palarm = (fdmgrAlarm *) ellGet(&pfdctx->free_alarm_list);
@@ -327,14 +365,33 @@ void *param
if(!palarm){
palarm = (fdmgrAlarm *) malloc(sizeof(fdmgrAlarm));
if(!palarm){
return NULL;
return fdmgrNoAlarm;
}
}
/*
* force all fields to a known state
*/
memset((char *)palarm, 0, sizeof(*palarm));
memset ((char *)palarm, 0, sizeof(*palarm));
do {
pfdctx->nextAlarmId++;
palarm->id = pfdctx->nextAlarmId;
status = bucketAddItemUnsignedId (
pfdctx->pAlarmBucket,
&palarm->id,
palarm);
if (status == S_bucket_noMemory) {
free (palarm);
return fdmgrNoAlarm;
}
} while (status == S_bucket_idInUse);
if (status != S_bucket_success) {
free (palarm);
errMessage (status, "Alarm installation failed");
return fdmgrNoAlarm;
}
ptimeout->tv_sec += ptimeout->tv_usec/USEC_PER_SEC;
ptimeout->tv_usec = ptimeout->tv_usec%USEC_PER_SEC;
@@ -364,7 +421,10 @@ void *param
}
}
if(pa){
ellInsert(&pfdctx->alarm_list, pa->node.previous, &palarm->node);
ellInsert (
&pfdctx->alarm_list,
pa->node.previous,
&palarm->node);
}
else{
ellAdd(&pfdctx->alarm_list, &palarm->node);
@@ -372,22 +432,33 @@ void *param
palarm->alt = alt_alarm;
UNLOCK(pfdctx);
return (void *) palarm;
return pfdctx->nextAlarmId;
}
/*
*
* fdmgr_clear_timeout()
*
*/
int fdmgr_clear_timeout(
fdctx *pfdctx,
fdmgrAlarm *palarm
fdmgrAlarmId id
)
{
int status;
enum alarm_list_type alt;
fdmgrAlarm *palarm;
palarm = bucketLookupItemUnsignedId (
pfdctx->pAlarmBucket,
&id);
if (!palarm) {
return ERROR;
}
status = bucketRemoveItemUnsignedId(
pfdctx->pAlarmBucket,
&id);
assert (status == S_bucket_success);
status = ERROR;
@@ -657,7 +728,7 @@ struct timeval *ptimeout
{
int status;
struct timeval t;
fdmgrAlarm *palarm;
fdmgrAlarmId alarmId;
lockFDMGRPendEvent(pfdctx);
@@ -673,22 +744,22 @@ struct timeval *ptimeout
/*
* silence gcc warnings
*/
palarm = NULL;
alarmId = fdmgrNoAlarm;
}
else{
pfdctx->select_tmo = FALSE;
palarm = fdmgr_add_timeout(
alarmId = fdmgr_add_timeout(
pfdctx,
ptimeout,
select_alarm,
pfdctx);
if(!palarm){
if (alarmId==fdmgrNoAlarm) {
return ERROR;
}
process_alarm_queue(pfdctx, &t);
}
while(TRUE){
while (TRUE) {
status = fdmgr_select(pfdctx, &t);
process_alarm_queue(pfdctx, &t);
if(status){
@@ -698,8 +769,8 @@ struct timeval *ptimeout
break;
}
if(pfdctx->select_tmo==FALSE)
fdmgr_clear_timeout(pfdctx, palarm);
if(pfdctx->select_tmo==FALSE && alarmId != fdmgrNoAlarm)
fdmgr_clear_timeout(pfdctx, alarmId);
UNLOCK_FDMGR_PEND_EVENT(pfdctx);
@@ -745,7 +816,7 @@ struct timeval *ptimeout
taskSafe();
# endif
# if defined (__hpux)
status = select(
status = select (
pfdctx->maxfd,
(int *)&pfdctx->readch,
(int *)&pfdctx->writech,
@@ -766,9 +837,9 @@ struct timeval *ptimeout
return labor_performed;
}
else if(status < 0){
if(errno == EINTR)
if(select_errno == EINTR)
;
else if(errno == EINVAL)
else if(select_errno == EINVAL)
fdmgrPrintf(
"fdmgr: bad select args ? %d %d %d\n",
pfdctx->maxfd,
@@ -777,7 +848,7 @@ struct timeval *ptimeout
else
fdmgrPrintf(
"fdmgr: error from select %s\n",
strerror(errno));
strerror(select_errno));
return labor_performed;
}
@@ -888,6 +959,10 @@ struct timeval *poffset
ellDelete(&pfdctx->alarm_list, &pa->node);
ellAdd(&pfdctx->expired_alarm_list, &pa->node);
pa->alt = alt_expired;
status = bucketRemoveItemUnsignedId(
pfdctx->pAlarmBucket,
&pa->id);
assert (status == S_bucket_success);
}
UNLOCK(pfdctx);
@@ -984,7 +1059,7 @@ struct timeval *pt
{
struct timezone tz;
return gettimeofday(pt, &tz);
return gettimeofday (pt, &tz);
}
#endif
@@ -996,7 +1071,7 @@ struct timeval *pt
*
*
*/
#ifdef _WIN32
#ifdef WIN32
LOCAL int fdmgr_gettimeval(
fdctx *pfdctx,
struct timeval *pt
@@ -1004,8 +1079,7 @@ struct timeval *pt
{
SYSTEMTIME st;
GetSystemTime(&st);
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 + (long)st.wHour*360
0;
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 + (long)st.wHour*3600;
pt->tv_usec = st.wMilliseconds*1000;
return 0;

75
src/libCom/makeStatTbl Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/sh
#
# makeStatTbl
# share/src/misc $Id$
# makeStatTbl - Create Error Symbol Table
#
# modification history
# --------------------
# 17-JUL-90 mrk Modified vxWorks makeStatTbl
#
# SYNOPSIS
# createErrSymTbl hdir [...] >errSymTbl.c
#
# DESCRIPTION
# This tool creates a symbol table (ERRSYMTAB) structure which contains the
# names and values of all the status codes defined in the .h files in the
# specified directory(s). The status codes must be prefixed with "S_"
# in order to be included in this table.
# A "err.h" file must exist in each hdir which defines the module
# numbers, eg. "M_". The table is created on standard output.
#
# This tool's primary use is for creating an error status table used
# by errPrint, and errSymFind.
#
# FILES
# errMdef.h module number file for each h directory
#
# SEE ALSO: errnoLib(1), symLib(1)
#*/
tmp=/tmp/mstt$$
trap "rm -f $tmp ; exit" 0 1 2 3 15
cat </dev/null >$tmp
cat $* | egrep "^#define[ ]*S_" >>$tmp
echo "/* status code symbol table */
/* CREATED BY makeStatTbl"
echo " * FROM `pwd`"
echo " * ON `date`
*/
"'
#include "errMdef.h"
#include "errSymTbl.h"
'
echo
cat $tmp
echo '
LOCAL ERRSYMBOL symbols[] =
{'
sed -e 's/^.*define[ ]*\(S_[a-zA-Z0-9_]*\).*\/\*\(.*\)\*\/.*/ {"\2", (long) \1},/' \
$tmp
echo " };
LOCAL ERRSYMTAB symTbl =
{
NELEMENTS (symbols), /* current number of symbols in table */
symbols, /* ptr to symbol array */
};
ERRSYMTAB_ID errSymTbl = &symTbl;"
exit 0

View File

@@ -39,7 +39,11 @@
* .10 05-04-94 pg HPUX cpp changes. (elif to else and if)
* .11 01-09-95 joh fixed ts min west out of range test
* .12 02-24-95 joh fixed TScurrentTimeStamp() => tsLocalTime ()
* return status mapping prob introduced by .09 above
* return status mapping prob introduced by .09 above
* .13 05-26-95 joh TsAddDouble() macro isnt portable so it becomes
* a subroutine - oops - discovered tsAddDouble()
* so I left TsAddDouble() code - which works -
* at the end of the file but commented it out
*
* make options
* -DvxWorks makes a version for VxWorks
@@ -115,19 +119,18 @@
#include <ctype.h>
#include <string.h>
#ifdef vxWorks
#if defined(vxWorks)
# include <vxWorks.h>
# include <stdioLib.h>
# include <strLib.h>
#else
#if VMS
#elif defined(VMS)
# include <sys/time.h>
#elif defined(WIN32)
# include <windows.h>
# include <time.h>
#else
# include <sys/time.h>
#if 0
# include <strings.h>
#endif
#endif
#endif
#include <epicsAssert.h>
@@ -597,25 +600,36 @@ TS_STAMP *pStamp; /* O pointer to time stamp buffer */
{
long retStat=S_ts_OK;/* return status to caller */
#ifdef vxWorks
retStat = TScurrentTimeStamp((struct timespec*)pStamp);
if (retStat == 0) {
return S_ts_OK;
}
else {
return S_ts_sysTimeError;
}
#else
struct timeval curtime;
assert(pStamp != NULL);
assert(pStamp != NULL);
if (gettimeofday(&curtime, (struct timezone *)NULL) == -1)
retStat = S_ts_sysTimeError;
else {
pStamp->nsec = ( curtime.tv_usec/1000 ) * 1000000;
pStamp->secPastEpoch = curtime.tv_sec - TS_EPOCH_SEC_PAST_1970;
}
#endif
{
# if defined(vxWorks)
retStat = TScurrentTimeStamp((struct timespec*)pStamp);
if (retStat == 0) {
return S_ts_OK;
}
else {
return S_ts_sysTimeError;
}
# elif defined(WIN32)
SYSTEMTIME st; /* utc */
pStamp->secPastEpoch = time(NULL) - TS_EPOCH_SEC_PAST_1970;
GetSystemTime(&st);
pStamp->nsec = st.wMilliseconds * 1000000;
# else
struct timeval curtime;
assert(pStamp != NULL);
if (gettimeofday(&curtime, (struct timezone *)NULL) == -1)
retStat = S_ts_sysTimeError;
else {
pStamp->nsec = ( curtime.tv_usec/1000 ) * 1000000;
pStamp->secPastEpoch = curtime.tv_sec -
TS_EPOCH_SEC_PAST_1970;
}
# endif
}
pStamp->nsec = pStamp->nsec - (pStamp->nsec % TS_TRUNC);
return retStat;
@@ -1465,3 +1479,4 @@ char **pText; /* IO ptr to ptr to string containing time and date */
*pStamp = stamp;
return retStat;
}

View File

@@ -5,15 +5,9 @@ include $(EPICS)/config/CONFIG_BASE
SRCS.c = ../iocLogClient.c ../veclist.c
OBJS = veclist.o iocLogClient.o
LIBOBJS = veclist.o iocLogClient.o
PROD = vxComLib
LIBNAME = vxComLib
include $(EPICS)/config/RULES.Vx
clean::
@$(RM) vxComLib
vxComLib: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -1,15 +1,17 @@
/*
* $Id$
* @(#)veclist.c 1.10
*
* list fuctions attached to the interrupt vector table
*
* Created 28Mar89 Jeffrey O. Hill
* hill@atdiv.lanl.gov
* johill@lanl.gov
* (505) 665 1831
*
* .01 010393 Applied fix for zero C ISR param causes incorrect
* identification as MACRO ISR problem.
* .02 022195 Compiler warnings fixed
* $Log$
*/
/*

View File

@@ -4,12 +4,9 @@ include $(EPICS)/config/CONFIG_BASE
SRCS.c = ../epicsRelease.c
OBJS = epicsRelease.o
LIBOBJS = epicsRelease.o
PROD = miscLib
LIBNAME = miscLib
include $(EPICS)/config/RULES.Vx
miscLib: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -42,61 +42,55 @@ SRCS.c += ../recStringin.c
SRCS.c += ../recStringout.c
SRCS.c += ../recSub.c
SRCS.c += ../recSubArray.c
# SRCS.c += ../recSwitch.c
SRCS.c += ../recTimer.c
SRCS.c += ../recWait.c
SRCS.c += ../recWaitCa.c
SRCS.c += ../recWaveform.c
# OBJS += recAai.o
# OBJS += recAao.o
OBJS += recAi.o
OBJS += recAo.o
OBJS += recBi.o
OBJS += recBo.o
OBJS += recCalc.o
OBJS += recCompress.o
OBJS += recDfanout.o
OBJS += recEg.o
OBJS += recEgevent.o
OBJS += recEr.o
OBJS += recErevent.o
OBJS += recEvent.o
OBJS += recFanout.o
# OBJS += recGsub.o
OBJS += recHistogram.o
OBJS += recLongin.o
OBJS += recLongout.o
OBJS += recMbbi.o
OBJS += recMbbiDirect.o
OBJS += recMbbo.o
OBJS += recMbboDirect.o
# OBJS += recPal.o
OBJS += recPermissive.o
OBJS += recPid.o
OBJS += recPulseCounter.o
OBJS += recPulseDelay.o
OBJS += recPulseTrain.o
OBJS += recScan.o
OBJS += recSel.o
OBJS += recSeq.o
OBJS += recState.o
OBJS += recSteppermotor.o
OBJS += recStringin.o
OBJS += recStringout.o
OBJS += recSub.o
OBJS += recSubArray.o
# OBJS += recSwitch.o
OBJS += recTimer.o
OBJS += recWait.o
OBJS += recWaitCa.o
OBJS += recWaveform.o
# LIBOBJS += recAai.o
# LIBOBJS += recAao.o
LIBOBJS += recAi.o
LIBOBJS += recAo.o
LIBOBJS += recBi.o
LIBOBJS += recBo.o
LIBOBJS += recCalc.o
LIBOBJS += recCompress.o
LIBOBJS += recDfanout.o
LIBOBJS += recEg.o
LIBOBJS += recEgevent.o
LIBOBJS += recEr.o
LIBOBJS += recErevent.o
LIBOBJS += recEvent.o
LIBOBJS += recFanout.o
# LIBOBJS += recGsub.o
LIBOBJS += recHistogram.o
LIBOBJS += recLongin.o
LIBOBJS += recLongout.o
LIBOBJS += recMbbi.o
LIBOBJS += recMbbiDirect.o
LIBOBJS += recMbbo.o
LIBOBJS += recMbboDirect.o
# LIBOBJS += recPal.o
LIBOBJS += recPermissive.o
LIBOBJS += recPid.o
LIBOBJS += recPulseCounter.o
LIBOBJS += recPulseDelay.o
LIBOBJS += recPulseTrain.o
LIBOBJS += recScan.o
LIBOBJS += recSel.o
LIBOBJS += recSeq.o
LIBOBJS += recState.o
LIBOBJS += recSteppermotor.o
LIBOBJS += recStringin.o
LIBOBJS += recStringout.o
LIBOBJS += recSub.o
LIBOBJS += recSubArray.o
LIBOBJS += recTimer.o
LIBOBJS += recWait.o
LIBOBJS += recWaitCa.o
LIBOBJS += recWaveform.o
PROD = recSup
LIBNAME = recSup
include $(EPICS)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -220,7 +220,7 @@ static long init_record(pao,pass)
break;
}
}
pao->pval = pao->val;
pao->oval = pao->pval = pao->val;
return(0);
}

View File

@@ -267,7 +267,7 @@ static void monitor(pdfanout)
monitor_mask = recGblResetAlarms(pdfanout);
monitor_mask |= (DBE_LOG|DBE_VALUE);
if(monitor_mask)
db_post_events(pdfanout,pdfanout->val,monitor_mask);
db_post_events(pdfanout,&pdfanout->val,monitor_mask);
/* check for value change */
delta = pdfanout->mlst - pdfanout->val;

View File

@@ -256,7 +256,7 @@ static void monitor(pmbbiDirect)
monitor_mask = recGblResetAlarms(pmbbiDirect);
monitor_mask |= (DBE_LOG|DBE_VALUE);
if(monitor_mask)
db_post_events(pmbbiDirect,pmbbiDirect->val,monitor_mask);
db_post_events(pmbbiDirect,&pmbbiDirect->val,monitor_mask);
/* check for value change */
if (pmbbiDirect->mlst != pmbbiDirect->val) {

View File

@@ -1,751 +0,0 @@
/* recSwitch.c */
/* base/src/rec $Id$ */
/* recSwitch.c - Record Support Routines for Switch records */
/*
* Author: Matthew Needes
* Date: 9-21-93
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#include <vxWorks.h>
#include <types.h>
#include <stdioLib.h>
#include <lstLib.h>
#include <string.h>
#include <wdLib.h>
#include <alarm.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <recSup.h>
#include <special.h>
#include <callback.h>
#include <switchRecord.h>
/* RSET - Record Support Entry Table */
#define report NULL
#define initialize NULL
static long init_record();
static long process();
static long special();
static long get_value();
#define cvt_dbaddr NULL
#define get_array_info NULL
#define put_array_info NULL
#define get_units NULL
static long get_precision();
static long get_enum_str();
static long get_enum_strs();
#define put_enum_str NULL
#define get_graphic_double NULL
#define get_control_double NULL
#define get_alarm_double NULL
struct rset switchRSET = {
RSETNUMBER,
report,
initialize,
init_record,
process,
special,
get_value,
cvt_dbaddr,
get_array_info,
put_array_info,
get_units,
get_precision,
get_enum_str,
get_enum_strs,
put_enum_str,
get_graphic_double,
get_control_double,
get_alarm_double };
static long init_state();
static long output_and_watch();
static long check_readback();
static void monitor();
static void callback();
static void watchdog();
/* defs for initialization choices */
#define INIT_RESET 0
#define INIT_SET 1
#define INIT_READBACK 2
/* defs for readback set threshold */
#define ABOVE 0
#define BELOW 1
/* defs for transition fail action choices */
#define FAIL_FOLLOW_RDBK 0
#define FAIL_KEEP_VALUE 1
/* state definitions for switch */
#define UNINITIALIZED 0
#define SET 1
#define RESET 2
#define RESET_TO_SET 3
#define SET_TO_RESET 4
/* states above this number signify transition */
#define TRANS_STATE 2
/* number of strings */
#define STRING_COUNT 5
/*
* Bitmask to check to see if the switch
* is set or in the process of setting.
*/
#define TO_SET 0x01
/* private structure in record */
struct PVT {
CALLBACK callback;
WDOG_ID watchdog;
};
/* post an event on a field */
#define MON_FIELD(CUR,PREV) \
if ((CUR) != (PREV)) { \
db_post_events(pswitch, &(CUR), DBE_VALUE); \
(PREV) = (CUR); }
/* initialize record */
static long init_record(
struct switchRecord *pswitch,
int pass
)
{
long status;
/* ignore second pass */
if (!pass)
return(0);
/* initialize readback input link */
status = recGblInitFastInLink(&pswitch->rbkl, (void *) pswitch, DBR_DOUBLE, "RBKV");
if (status)
return(status);
/* initialize master reset link */
status = recGblInitFastInLink(&pswitch->mrsl, (void *) pswitch, DBR_UCHAR, "MRSV");
if (status)
return(status);
/* initialize master set link */
status = recGblInitFastInLink(&pswitch->mstl, (void *) pswitch, DBR_UCHAR, "MSTV");
if (status)
return(status);
/* initialize reset link */
status = recGblInitFastInLink(&pswitch->rstl, (void *) pswitch, DBR_UCHAR, "RSTV");
if (status)
return(status);
/* initialize set link */
status = recGblInitFastInLink(&pswitch->setl, (void *) pswitch, DBR_UCHAR, "SETV");
if (status)
return(status);
/* initialize toggle link */
status = recGblInitFastInLink(&pswitch->togl, (void *) pswitch, DBR_UCHAR, "TOGV");
if (status)
return(status);
/* clear alarm severity */
pswitch->sevr = NO_ALARM;
/*
* Allocate private structure
*/
pswitch->pvt = (void *) malloc(sizeof(struct PVT));
if (!pswitch->pvt)
return(S_rec_outMem);
/*
* Create watchdog
*/
((struct PVT *)pswitch->pvt)->watchdog = (void *) wdCreate();
if (!((struct PVT *)pswitch->pvt)->watchdog)
return(S_rec_outMem);
/*
* Initialize EPICS callback
*/
callbackSetCallback(callback, &((struct PVT *)pswitch->pvt)->callback);
callbackSetUser(pswitch, &((struct PVT *)pswitch->pvt)->callback);
callbackSetPriority(pswitch->prio, &((struct PVT *)pswitch->pvt)->callback);
return(0);
}
/* initialize record's state */
static long init_state(struct switchRecord *pswitch)
{
long status = 0;
/* set initial state */
switch (pswitch->ini) {
case INIT_RESET:
pswitch->val = SET_TO_RESET;
pswitch->pint = RESET;
pswitch->outv = pswitch->offv;
status = output_and_watch(pswitch);
if (status)
return(status);
break;
case INIT_SET:
pswitch->val = RESET_TO_SET;
pswitch->pint = SET;
pswitch->outv = pswitch->onv;
status = output_and_watch(pswitch);
if (status)
return(status);
break;
case INIT_READBACK:
/*
* If uninitialized, get state from readback
*/
status = recGblGetFastLink(&pswitch->rbkl, (void *) pswitch,
&pswitch->rbkv);
if (status)
return(status);
if (pswitch->dthr == BELOW)
pswitch->pint = pswitch->val = (pswitch->rbkv <= pswitch->rthr) ? SET : RESET;
else
pswitch->pint = pswitch->val = (pswitch->rbkv >= pswitch->rthr) ? SET : RESET;
pswitch->outv = (pswitch->val == SET) ? pswitch->onv : pswitch->offv;
/*
* Drive output
*/
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
break;
default:
return(0);
break;
}
pswitch->udf = FALSE;
pswitch->intn = 0;
return(0);
}
/* process record */
static long process(struct switchRecord *pswitch)
{
long status = 0;
unsigned char value = 0;
pswitch->pact = TRUE;
/* initialize record if not already initialized */
if (pswitch->val == UNINITIALIZED)
status = init_state(pswitch);
/*
* Check master set and reset links.
*/
status = recGblGetFastLink(&pswitch->mrsl, (void *) pswitch,
&pswitch->mrsv);
if (status)
return(status);
MON_FIELD(pswitch->mrsv, pswitch->lmrs);
status = recGblGetFastLink(&pswitch->mstl, (void *) pswitch,
&pswitch->mstv);
if (status)
return(status);
MON_FIELD(pswitch->mstv, pswitch->lmst);
/* Check master reset value */
if (pswitch->mrsv) {
pswitch->pint = RESET;
if (pswitch->val & TO_SET) {
if (pswitch->val > TRANS_STATE) {
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
}
pswitch->val = SET_TO_RESET;
pswitch->outv = pswitch->offv;
status = output_and_watch(pswitch);
if (status)
return(status);
}
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
pswitch->outv = pswitch->offv;
pswitch->nsta = pswitch->nsev = 0;
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
}
else {
/*
* Check master set link
*/
if (pswitch->mstv) {
pswitch->pint = SET;
if (!(pswitch->val & TO_SET)) {
if (pswitch->val > TRANS_STATE) {
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
}
pswitch->val = RESET_TO_SET;
pswitch->outv = pswitch->onv;
status = output_and_watch(pswitch);
if (status)
return(status);
}
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
pswitch->outv = pswitch->onv;
pswitch->nsta = pswitch->nsev = 0;
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
}
/*
* Check input links if record is in closed loop mode
*/
else {
if (pswitch->omsl == CLOSED_LOOP) {
/*
* Check set/reset/toggle input links - and check monitor
*/
status = recGblGetFastLink(&pswitch->rstl, (void *) pswitch, &pswitch->rstv);
if (status)
return(status);
MON_FIELD(pswitch->rstv, pswitch->lrst);
status = recGblGetFastLink(&pswitch->setl, (void *) pswitch, &pswitch->setv);
if (status)
return(status);
MON_FIELD(pswitch->setv, pswitch->lsst);
status = recGblGetFastLink(&pswitch->togl, (void *) pswitch, &pswitch->togv);
if (status)
return(status);
MON_FIELD(pswitch->togv, pswitch->ltog);
pswitch->intn = 1;
}
/*
* If "intention" is set, a non-master switch has been
* modified (by a put, for example). Check the switches.
*/
if (pswitch->intn) {
/*
* Ignore command if in transition state and ignore flag set
*/
if (!((pswitch->val > TRANS_STATE) && pswitch->iti)) {
if (pswitch->rstv) {
/* reset */
pswitch->pint = RESET;
if (pswitch->val & TO_SET) {
if (pswitch->val > TRANS_STATE) {
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
}
pswitch->val = SET_TO_RESET;
pswitch->outv = pswitch->offv;
status = output_and_watch(pswitch);
}
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
pswitch->outv = pswitch->offv;
pswitch->nsta = pswitch->nsev = 0;
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
}
else if (pswitch->setv) {
/* set */
pswitch->pint = SET;
if (!(pswitch->val & TO_SET)) {
if (pswitch->val > TRANS_STATE) {
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
}
pswitch->val = RESET_TO_SET;
pswitch->outv = pswitch->onv;
status = output_and_watch(pswitch);
}
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
pswitch->outv = pswitch->onv;
pswitch->nsta = pswitch->nsev = 0;
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
}
else if (pswitch->togv) {
/* toggle */
if (pswitch->val > TRANS_STATE) {
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
}
if (pswitch->val & TO_SET) {
pswitch->pint = RESET;
pswitch->val = SET_TO_RESET;
pswitch->outv = pswitch->offv;
}
else {
pswitch->pint = SET;
pswitch->val = RESET_TO_SET;
pswitch->outv = pswitch->onv;
}
status = output_and_watch(pswitch);
}
if (status)
return(status);
}
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
/*
* Intention resets when setv, rstv, togv are activated,
* and only after mstv/mrsv are cleared
*/
pswitch->intn = 0;
}
}
}
/*
* Do not check readback if the link isn't specified or
* if a watchdog is in existence.
*/
if (pswitch->rbkl.type != CONSTANT && pswitch->val <= TRANS_STATE) {
status = check_readback(pswitch);
if (status)
return(status);
}
/* store time in record */
recGblGetTimeStamp(pswitch);
/* alarm checking is done in check_readback */
/*
* check event list - though some monitors are
* performed in other areas of the code.
*/
monitor(pswitch);
/* process forward link */
recGblFwdLink(pswitch);
pswitch->pact = FALSE;
return(status);
}
/* special processing */
static long special(
struct dbAddr *paddr,
int after
)
{
if (after && ((struct switchRecord *) paddr->precord)->omsl == SUPERVISORY) {
((struct switchRecord *) paddr->precord)->intn = 1;
}
return(0);
}
/* monitor fields */
static void monitor(struct switchRecord *pswitch)
{
int monitor_mask = 0;
short stat, sevr, nsta, nsev;
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
monitor_mask = recGblResetAlarms(pswitch);
}
else {
/*
* recGblResetAlarms() is not used here, because alarm resets
* are not supposed to be done when this record is processed.
* (i.e. nsta and nsev are not set to zero) However, these
* alarms are reset in check_readback().
*/
stat = pswitch->stat; sevr = pswitch->sevr; nsta = pswitch->nsta;
nsev = pswitch->nsev; pswitch->stat = nsta; pswitch->sevr = nsev;
/*
* Check alarm condition -
* normally done automatically by recGblResetAlarms()
*/
if (stat != nsta || sevr != nsev) {
monitor_mask |= DBE_ALARM;
db_post_events(pswitch, &pswitch->stat, DBE_VALUE);
db_post_events(pswitch, &pswitch->sevr, DBE_VALUE);
}
}
/* check value */
if (pswitch->val != pswitch->mlst) {
/* trigger monitor on value */
monitor_mask |= (DBE_VALUE | DBE_LOG);
pswitch->mlst = pswitch->val;
}
if (monitor_mask) {
db_post_events(pswitch, &pswitch->val, monitor_mask);
}
/* check outv */
MON_FIELD(pswitch->outv, pswitch->lout);
}
/* get state */
static long get_value(
struct switchRecord *pswitch,
struct valueDes *pvdes
)
{
pvdes->field_type = DBF_ENUM;
pvdes->no_elements = 1;
(unsigned short *)(pvdes->pvalue) = &pswitch->val;
return(0);
}
/* get precision */
static long get_precision(
struct dbAddr *paddr,
long *precision
)
{
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
if (paddr->pfield == &pswitch->xtim)
*precision = pswitch->prec;
else
*precision = 0;
return(0);
}
/* get state string */
static long get_enum_str(
struct dbAddr *paddr,
char *dest
)
{
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
char *string;
if (pswitch->val < STRING_COUNT-1) {
string = pswitch->ssi + (pswitch->val * sizeof(pswitch->ssi));
strncpy(dest, string, sizeof(pswitch->ssi));
}
else {
strcpy(dest, "Illegal Value");
}
return(0);
}
/* get all strings */
static long get_enum_strs(
struct dbAddr *paddr,
struct dbr_enumStrs *pes
)
{
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
char *string;
int i;
short count = 0;
memset(pes->strs, '\0', sizeof(pes->strs));
string = pswitch->ssi;
for (i=0; i<STRING_COUNT; i++) {
strncpy(pes->strs[i], string, sizeof(pswitch->ssi));
if (*string)
count = i + 1;
string += sizeof(pswitch->ssi);
}
pes->no_str = count;
return(0);
}
/* output to "switch" link, and set watchdog */
static long output_and_watch(struct switchRecord *pswitch)
{
long status;
/* Process switch forward link */
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
if (pswitch->rbkl.type == CONSTANT) {
pswitch->val = (pswitch->val == SET_TO_RESET) ? RESET : SET;
}
else {
if (pswitch->xtim) {
/* activate watchdog */
wdStart((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog,
(int) pswitch->xtim * sysClkRateGet(),
(FUNCPTR) watchdog, (int) pswitch);
}
else {
/* check readback immediately */
status = check_readback(pswitch);
if (status)
return(status);
}
}
return(0);
}
/* check readback value */
static long check_readback(struct switchRecord *pswitch)
{
long status;
int condition;
/* get readback */
status = recGblGetFastLink(&pswitch->rbkl, (void *) pswitch, &pswitch->rbkv);
if (status)
return(status);
/* choose which condition to check */
condition = (pswitch->dthr == BELOW) ? (pswitch->rbkv <= pswitch->rthr) : (pswitch->rbkv >= pswitch->rthr);
/* check readback value */
if (condition) {
if (pswitch->pint == SET) {
/* Switch set properly */
pswitch->val = SET;
pswitch->nsta = pswitch->nsev = 0;
}
else {
/* SET ALARM - Was supposed to be reset, but was found to be set */
recGblSetSevr(pswitch, STATE_ALARM, pswitch->srfs);
pswitch->val = SET;
}
/* Drive output to what it should be given readback, if FOLLOW RDBK set */
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
if (pswitch->outv != pswitch->onv) {
pswitch->outv = pswitch->onv;
/* drive output */
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
pswitch->pint = SET;
}
}
else {
if (pswitch->pint == RESET) {
/* switch reset properly */
pswitch->val = RESET;
pswitch->nsta = pswitch->nsev = 0;
}
else {
/* SET ALARM - Was supposed to be set, but was found to be reset */
recGblSetSevr(pswitch, STATE_ALARM, pswitch->rsfs);
pswitch->val = RESET;
}
/* Drive output to what it should be given readback, if FOLLOW RDBK set */
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
if (pswitch->outv != pswitch->offv) {
pswitch->outv = pswitch->offv;
/* drive output */
if (pswitch->swtc.type == DB_LINK) {
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
}
}
pswitch->pint = RESET;
}
}
return(0);
}
/* callback */
static void callback(CALLBACK *pcallback)
{
struct switchRecord *pswitch;
/*
* Retrieve pointer to record from callback structure.
* This value is fixed at initialization, and will
* not be changed, so the database does not have to
* be locked for this actiion.
*/
callbackGetUser((void *) pswitch, pcallback);
/* lock the database */
dbScanLock((struct dbCommon *) pswitch);
/* check the readback value */
check_readback(pswitch);
/* monitor any changes */
monitor(pswitch);
/* unlock database */
dbScanUnlock((struct dbCommon *) pswitch);
}
/* watchdog process adds callback to queue */
static void watchdog(struct switchRecord *pswitch)
{
callbackRequest(&((struct PVT *)pswitch->pvt)->callback);
}

View File

@@ -44,11 +44,13 @@
* 2.00 02-20-95 nda added queuing to SCAN_IO_EVENT mode so no transitions of data
* would be missed. Can put back to cached mode by setting
* recWaitCacheMode (effects all wait records !)
* 2.01 08-07-95 nda Multiple records with DOLN's didn't work,
* added calloc for dola structure.
*
*
*/
#define VERSION 2.00
#define VERSION 2.01
@@ -229,6 +231,7 @@ static long init_record(pwait,pass)
pwait->inka = calloc(1,sizeof(struct dbAddr));
pwait->inla = calloc(1,sizeof(struct dbAddr));
pwait->outa = calloc(1,sizeof(struct dbAddr));
pwait->dola = calloc(1,sizeof(struct dbAddr));
pwait->cbst = calloc(1,sizeof(struct cbStruct));
@@ -555,7 +558,7 @@ static long special(paddr,after)
db_post_events(pwait,&pwait->clcv,DBE_VALUE);
memcpy(pwait->rpcl,rpbuf,sizeof(pwait->rpcl));
db_post_events(pwait,pwait->calc,DBE_VALUE);
db_post_events(pwait,pwait->clcv,DBE_VALUE);
db_post_events(pwait,&pwait->clcv,DBE_VALUE);
return(0);
break;
default:
@@ -766,10 +769,10 @@ static void reqOutput(pwait)
void execOutput(pcbst)
struct cbStruct *pcbst;
{
static long status;
static long nRequest = 1;
static long options = 0;
static double oldDold;
long status;
long nRequest = 1;
long options = 0;
double oldDold;
/* if output link is valid , decide between VAL and DOL */
if(!pcbst->pwait->outv) {

View File

@@ -1,3 +1,10 @@
/*
* 07-27-95 nda made QUEUE_SIZE a global variable so it could
* be changed at boot time for LOTS OF WAIT records
*
*
*/
#include <vxWorks.h>
#include <taskLib.h>
#include <string.h>
@@ -18,7 +25,8 @@
extern int interruptAccept;
#define QUEUE_SIZE 256
int recWaitCaQsize = 256;
LOCAL int taskid=0;
LOCAL RING_ID ringQ;;
LOCAL FAST_LOCK lock;
@@ -50,7 +58,7 @@ LOCAL void eventCallback(struct event_handler_args eha)
LOCAL void recWaitCaStart(void)
{
FASTLOCKINIT(&lock);
if((ringQ = rngCreate(sizeof(void *) * QUEUE_SIZE)) == NULL) {
if((ringQ = rngCreate(sizeof(void *) * recWaitCaQsize)) == NULL) {
errMessage(0,"recWaitCaStart failed");
exit(1);
}

View File

@@ -1,3 +1,4 @@
EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
@@ -12,14 +13,10 @@ OBJS = \
caserverio.o caservertask.o camsgtask.o camessage.o \
rsrv_init.o cast_server.o online_notify.o globalsource.o
PROD = dbgLib rsrvLib
PROD = rsrvLib
include $(EPICS)/config/RULES.Vx
dbgLib: $(OBJS) globalsource.o
$(RM) $@
$(LINK.c) $@ $(OBJS) globalsource.o $(LDLIBS)
rsrvLib: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -187,7 +187,6 @@ struct db_addr *pAddr,
unsigned cid
);
LOCAL unsigned bucketID;
/*
@@ -1215,7 +1214,8 @@ struct client *client
FASTLOCK(&rsrv_free_addrq_lck);
status = bucketRemoveItemUnsignedId (pCaBucket, &pciu->sid);
if(status != BUCKET_SUCCESS){
if(status != S_bucket_success){
errMessage (status, "Bad resource id during channel clear");
logBadId(client, mp);
}
ellAdd(&rsrv_free_addrq, &pciu->node);
@@ -1623,7 +1623,7 @@ struct client *client
if (CA_V44(CA_PROTOCOL_VERSION,htons(mp->m_count))) {
sid = ~0U;
count = 0;
type = -1;
type = ca_server_port;
}
else {
struct channel_in_use *pchannel;
@@ -1685,9 +1685,9 @@ struct db_addr *pAddr,
unsigned cid
)
{
static unsigned bucketID;
unsigned *pCID;
struct channel_in_use *pchannel;
unsigned sid;
int status;
/* get block off free list if possible */
@@ -1715,23 +1715,37 @@ unsigned cid
/*
* allocate a server id and enter the channel pointer
* in the table
*
* NOTE: This detects the case where the PV id wraps
* around and we attempt to have two resources on the same id.
* The lock is applied here because on some architectures the
* ++ operator isnt atomic.
*/
FASTLOCK(&rsrv_free_addrq_lck);
sid = bucketID++;
/*
* bypass read only warning
*/
pCID = (unsigned *) &pchannel->sid;
*pCID = sid;
status = bucketAddItemUnsignedId (
pCaBucket,
&pchannel->sid,
pchannel);
do {
/*
* bypass read only warning
*/
pCID = (unsigned *) &pchannel->sid;
*pCID = bucketID++;
/*
* Verify that this id is not in use
*/
status = bucketAddItemUnsignedId (
pCaBucket,
&pchannel->sid,
pchannel);
} while (status != S_bucket_success);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(status!=BUCKET_SUCCESS){
if(status!=S_bucket_success){
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
errMessage (status, "Unable to allocate server id");
return NULL;
}
@@ -1984,7 +1998,7 @@ struct client *pc
*
* used to be a macro
*/
LOCAL struct channel_in_use *MPTOPCIU(struct extmsg *mp)
LOCAL struct channel_in_use *MPTOPCIU (struct extmsg *mp)
{
struct channel_in_use *pciu;
const unsigned id = mp->m_cid;

View File

@@ -111,22 +111,37 @@ int lock_needed;
anerrno = errnoGet();
if( (anerrno!=ECONNABORTED&&
anerrno!=ECONNRESET&&
anerrno!=EPIPE&&
anerrno!=ETIMEDOUT)||
CASDEBUG>2){
if(pclient->proto == IPPROTO_TCP) {
if( (anerrno!=ECONNABORTED&&
anerrno!=ECONNRESET&&
anerrno!=EPIPE&&
anerrno!=ETIMEDOUT)||
CASDEBUG>2){
logMsg(
"CAS: client unreachable \"%s\"\n",
(int)strerror(anerrno),
NULL,
NULL,
NULL,
NULL,
NULL);
logMsg(
"CAS: TCP send failed because \"%s\"\n",
(int)strerror(anerrno),
NULL,
NULL,
NULL,
NULL,
NULL);
}
pclient->disconnect = TRUE;
}
else if (pclient->proto == IPPROTO_UDP) {
logMsg(
"CAS: UDP send failed because \"%s\"\n",
(int)strerror(anerrno),
NULL,
NULL,
NULL,
NULL,
NULL);
}
else {
assert (0);
}
pclient->disconnect = TRUE;
}
else{
logMsg(

View File

@@ -88,11 +88,10 @@ int req_server(void)
struct sockaddr_in serverAddr; /* server's address */
int status;
int i;
short port;
taskwdInsert((int)taskIdCurrent,NULL,NULL);
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
ca_server_port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
if (IOC_sock != 0 && IOC_sock != ERROR)
if ((status = close(IOC_sock)) == ERROR)
@@ -122,7 +121,7 @@ int req_server(void)
/* Zero the sock_addr structure */
bfill((char *)&serverAddr, sizeof(serverAddr), 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_port = htons(ca_server_port);
/* get server's Internet address */
if (bind(IOC_sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == ERROR) {
@@ -322,15 +321,13 @@ LOCAL int terminate_one_client(struct client *client)
pCaBucket,
&pciu->sid);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(status != BUCKET_SUCCESS){
logMsg(
"%s: Bad id=%d at close",
(int)__FILE__,
pciu->sid,
NULL,
NULL,
NULL,
NULL);
if(status != S_bucket_success){
errPrintf (
status,
__FILE__,
__LINE__,
"Bad id=%d at close",
pciu->sid);
}
status = asRemoveClient(&pciu->asClientPVT);
if(status!=0 && status != S_asLib_asNotActive){
@@ -469,7 +466,7 @@ int client_stat(void)
if(pCaBucket){
printf( "The server's resource id conversion table:\n");
FASTLOCK(&rsrv_free_addrq_lck);
bucketShow(pCaBucket);
bucketShow (pCaBucket);
FASTUNLOCK(&rsrv_free_addrq_lck);
}

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