Compare commits

..

81 Commits

Author SHA1 Message Date
Janet B. Anderson
d4f720482b Added $(RM) line and removed chmod line in vxWorks rules 1994-12-21 16:03:11 +00:00
Marty Kraimer
8f3b1cce16 get_enum_strs has no_strs=2 if no strings defined so CA clients work 1994-12-21 14:58:01 +00:00
Marty Kraimer
a94db92c29 get_enum_strs MUST set no_strs=2 if no strings defined 1994-12-21 14:19:44 +00:00
Marty Kraimer
b6a46820e9 If calink has MS or PP then issue error message only in errVerbose=TRUE 1994-12-21 14:16:59 +00:00
John Winans
cf7307f399 Added the devXxSkeletonGpib.c file to the build list. This is to insure that
it is a buildable module.
1994-12-20 15:31:45 +00:00
Marty Kraimer
fb0a164de1 Added FFO option 1994-12-19 18:25:51 +00:00
Marty Kraimer
8d9d7a126a In init_record mask is shifted not set equal to 1994-12-19 18:25:16 +00:00
cvs2svn
67378ebaa1 This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta4'. 1994-12-16 16:11:27 +00:00
John Winans
0859173047 Added debug flag guards to ALL printing. The default debug level is set
to 1 -- this provides the same output as the old version.
1994-12-16 16:11:26 +00:00
John Winans
0f1c9c357a Changed error message in the event system error handler & added a conditional
based on a debug flag to print it... defaults to off.  (Per request from MRK.)
1994-12-16 15:51:21 +00:00
Janet B. Anderson
a4cfb43ba1 Now installs individual objects and devLibOpt 1994-12-15 19:44:44 +00:00
cvs2svn
6c620894f5 This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta3'. 1994-12-15 16:12:45 +00:00
Marty Kraimer
b7451c7a5d Allow iocInit to continue even if getResources fails 1994-12-15 16:12:44 +00:00
John Winans
a2331c9d0e Changed a printf to logMsg and added a printing delay to use when
the ibDebug flag is set so things come out closer to the proper order.
1994-12-14 22:43:48 +00:00
John Winans
f44ce3dbb0 Changed printf to logMsg in the A24Malloc code and added a few more
debug statements.
1994-12-14 22:41:06 +00:00
John Winans
d9066673ef Removed DMAC command chaining structure(s) from the ibLink
structure so they can be malloc'd seperately.  This keeps
the usage of A24 space restricted to ONLY those structures
that have to be there.
1994-12-14 22:29:14 +00:00
Janet B. Anderson
82867f0684 Now installs individual objects instead of devLibOpt 1994-12-14 15:00:16 +00:00
John Winans
6fb928ea9d Updated the GPIB request header. 1994-12-12 19:59:45 +00:00
John Winans
ad41921414 Rewrote the init code so that it always returns a zero (don't kill the
startup.cmd file.)  It is possible that this could cause some confusion
to the database, should it decide to then use a link that did not init
properly.
1994-12-12 16:03:00 +00:00
cvs2svn
17c54db7f7 This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta2'. 1994-12-07 15:11:14 +00:00
John Winans
a60cba8671 Fixed array index for temerature reading. 1994-12-07 15:11:13 +00:00
Jeff Hill
1066acd60c doc 1994-12-07 00:34:41 +00:00
Jeff Hill
4c546a0299 allow event thread to finish at exit() by temp unlock 1994-12-07 00:33:24 +00:00
Jeff Hill
d6fe343a88 sync group leak fix 1994-12-07 00:31:59 +00:00
Jeff Hill
94c6314dc9 little endian no MIT float byte swap 1994-12-07 00:31:13 +00:00
Jeff Hill
1657a97783 removed debug 1994-12-07 00:30:44 +00:00
Jeff Hill
36fb04f13a removed debug stuff 1994-12-07 00:29:03 +00:00
Jeff Hill
2ea3005498 . 1994-12-07 00:28:18 +00:00
Jeff Hill
885e9e829f send prior to calling select() opt and vxWorks td() safe 1994-12-07 00:27:29 +00:00
Jeff Hill
5f53ebb4c2 no change 1994-12-07 00:20:58 +00:00
Jeff Hill
6bc97431bc *** empty log message *** 1994-12-07 00:19:11 +00:00
Marty Kraimer
0b50562f67 Moved code to src/libCom/envSubr 1994-12-05 14:45:34 +00:00
Marty Kraimer
523c0c37c6 Moved code for src/misc/epicsEnvParams to envSubr 1994-12-05 14:44:21 +00:00
Marty Kraimer
52eba44ac4 Print arg of yy_error 1994-12-05 14:42:41 +00:00
cvs2svn
d6aa5a4dac This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta1'. 1994-11-30 15:17:08 +00:00
Janet B. Anderson
d0d1a39c57 Removed unbundled products apCreateShadow and apStatusSync 1994-11-30 15:17:07 +00:00
John Winans
622c4f8382 Added IRQ mode stuff 1994-11-30 15:10:23 +00:00
Jeff Hill
da47b297d2 new env var 1994-11-29 22:41:46 +00:00
Jeff Hill
53b2a77378 no tiny buckets 1994-11-29 22:41:12 +00:00
Jeff Hill
81de80789c added new EPICS env var
fixed delete of cast iiu when all disconn chan deleted
1994-11-29 22:40:22 +00:00
Marty Kraimer
d32a6bb770 Fix for ctl/L 1994-11-29 22:37:17 +00:00
Johnny Tang
5d341aed37 atdb.c is included in atdb_yacc.c 1994-11-29 21:37:18 +00:00
Jeff Hill
3fee3eceff fixed vx exit handler problems 1994-11-23 21:03:41 +00:00
Johnny Tang
ded5d21444 Use elex and antelope instead of lex and yacc. 1994-11-23 20:17:11 +00:00
Janet B. Anderson
02310d0bd4 Converted from flex and yacc to e_flex and antelope. 1994-11-23 19:48:14 +00:00
Johnny Tang
2fb0212252 Included main.c scan.c and yylex.c into parse.y 1994-11-23 19:33:09 +00:00
Johnny Tang
2e16f3a6d7 Comment out flexdef.h 1994-11-23 19:31:39 +00:00
Johnny Tang
47fa7a4fa4 include scan.c yylex.c and main.c 1994-11-23 19:30:54 +00:00
Marty Kraimer
0a1c03c8d4 Added omod field sp that monitors to oval properly posted 1994-11-23 15:33:36 +00:00
Marty Kraimer
8815ca1008 emoved simulation fields 1994-11-23 15:30:55 +00:00
Marty Kraimer
c1b65bad02 Dont build pal and switch 1994-11-23 15:30:20 +00:00
Jeff Hill
a8c8dc89d9 fixed use of bogus broadcast var pointer in conn.c prior to first search 1994-11-18 00:34:06 +00:00
John Winans
3ce0670ba8 Turned off the debugging system (it consumed an additional 30% of CPU) 1994-11-17 21:15:26 +00:00
Jeff Hill
bc89526dff more fixes for use of defunct task var under vxWorks 1994-11-17 21:12:23 +00:00
John Winans
1c7a4ef3db Major restructuring of init code. 1994-11-17 21:11:58 +00:00
Marty Kraimer
a7333f554d add asLib.h 1994-11-17 20:27:35 +00:00
Jeff Hill
c2484d675b sccs %W%W => CVS $Id$ 1994-11-17 19:11:06 +00:00
Jeff Hill
589ccacc3d Fixed vxWorks exit handler used wrong task variable 1994-11-17 19:09:55 +00:00
Jeff Hill
9d3ce3aedd dont alloc chan in response to search message 1994-11-16 03:42:07 +00:00
Jeff Hill
a88293bbbb dont alloc channel in response to search request changes 1994-11-16 03:41:25 +00:00
Marty Kraimer
46e1cdf441 In non-syc mode return 2 for no convert 1994-11-15 21:46:35 +00:00
Marty Kraimer
1a826583e7 On ca_puts changed check for illegal type (needed for alarm ack) 1994-11-15 20:25:48 +00:00
Janet B. Anderson
99434dfe06 Added gsd_sync_subr.c and USR_LDFLAGS 1994-11-15 16:24:27 +00:00
Johnny Tang
5db7f418d4 Update README.hp700_alpha 1994-11-14 23:32:52 +00:00
Janet B. Anderson
70e2716ff0 One file per line again, commented out drvCaenV265.c 1994-11-14 23:22:15 +00:00
Johnny Tang
51eb05d411 replace install with cp and chmod. 1994-11-14 23:21:51 +00:00
Johnny Tang
754dd841eb Replace ARCH_TYPE with . 1994-11-14 23:12:17 +00:00
Marty Kraimer
f2d167920c Fixed get so it doesnt try ACK request types 1994-11-14 21:01:53 +00:00
Johnny Tang
4ae4145b9e Replace ARCH_TYPE with . 1994-11-14 19:26:16 +00:00
Jeff Hill
d453191f25 added windows_depen.c 1994-11-14 19:04:57 +00:00
Jeff Hill
0c2699c85b added drvCaenV265.c 1994-11-14 18:59:31 +00:00
Jeff Hill
ea9d141a54 dded caenV265 1994-11-14 18:48:45 +00:00
Jeff Hill
7bb451bb74 updated for changes in bucketLib.c 1994-11-14 18:47:18 +00:00
Jeff Hill
0ba3898e81 Improved bucketLib.c & portability changes 1994-11-14 18:45:25 +00:00
Jeff Hill
547ca9d02d Changes for NT, ALPHA/OSF, and VAX/VMS port 1994-11-14 18:43:05 +00:00
Marty Kraimer
348f4c0e8d One line per module 1994-11-14 16:20:22 +00:00
Marty Kraimer
2fddb398b2 Allow white space in parm field 1994-11-14 16:18:53 +00:00
Janet B. Anderson
688f766622 Bug fix for pes->no_str calculation 1994-11-14 15:59:10 +00:00
Janet B. Anderson
c0892857eb Changed ARCH to T_A 1994-11-03 21:08:44 +00:00
Janet B. Anderson
a1458c0c58 Added conditional for hp700 -- lie about being SCO_UNIX 1994-11-03 21:00:35 +00:00
cvs2svn
15d6708cec This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta0'. 1994-11-01 14:55:16 +00:00
98 changed files with 6989 additions and 3258 deletions

View File

@@ -1,5 +1,4 @@
#
# $Id$
#
# Top Level EPICS Makefile
# by Matthew Needes and Mike Bordua
@@ -13,8 +12,8 @@
# install because the release.% syntax is illegal.
#
# $Log$
# Revision 1.19 1994/10/31 21:47:02 jba
# Removed depends dependancy in release and built_release rules
# Revision 1.1.1.1 1994/11/09 01:08:53 epics
# Import of R3.12.0Beta
#
# Revision 1.18 1994/10/13 19:44:34 mda
# Introduce temporary symbol (ARCH_TYPE=$$ARCH) and use in later targets/rules
@@ -72,7 +71,7 @@ depends:
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
release:
release:
@echo TOP: Creating Release...
@tools/MakeRelease
@@ -85,8 +84,8 @@ clean:
@tools/Clean
uninstall:
@rm -rf bin/* lib/* rec.bak
@rm -f rec/default.dctsdr rec/default.sdrSum rec/*.h
rm -rf bin/* lib/* rec.bak
rm -f rec/default.dctsdr rec/default.sdrSum rec/*.h
# Notes for single architecture build rules:
# CheckArch only has to be run for dirs.% . That
@@ -106,25 +105,21 @@ uninstall:
# basis.
dirs.%:
@tools/CheckArch $(ARCH_TYPE)
@echo $(ARCH_TYPE): Creating Directories
@tools/MakeDirs $(ARCH_TYPE)
@tools/CheckArch $*
@echo $*: Creating Directories
@tools/MakeDirs $*
build.%: dirs.%
@echo $(ARCH_TYPE): Building
@${MAKE} ${MFLAGS} T_A=$(ARCH_TYPE) -f Makefile.subdirs build
@echo $*: Building
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs build
install.%: dirs.%
@echo $(ARCH_TYPE): Installing
@${MAKE} ${MFLAGS} T_A=$(ARCH_TYPE) -f Makefile.subdirs install
@echo $*: Installing
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs install
depends.%: dirs.%
@echo $(ARCH_TYPE): Performing Make Depends
@${MAKE} ${MFLAGS} T_A=$(ARCH_TYPE) -f Makefile.subdirs depends
clean.%: dirs.%
@echo $(ARCH_TYPE): Cleaning
@${MAKE} ${MFLAGS} T_A=$(ARCH_TYPE) -f Makefile.subdirs clean
@echo $*: Performing Make Depends
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs depends
# Illegal Syntax
@@ -138,15 +133,8 @@ uninstall.%:
@echo
@echo "The uninstall.arch syntax is not supported by this build."
@echo
# Clean RULE syntax: make clean.arch
# e.g.: make clean.mv167
#
# Clean files for a particular architecture
#
clean.%:
@echo "$(ARCH_TYPE): Cleaning"
@tools/Clean $(ARCH_TYPE)
@echo "$*: Cleaning"
@tools/Clean $*

View File

@@ -1,7 +1,7 @@
#
# supplement README for HP700 and Alpha OSF/1 builds
#
#
# M. Anderson and J. Tang
- EPICS environment variable - set by hand prior to build
@@ -32,7 +32,7 @@
For example:
% make HOST_ARCH=alpha
% make HOST_ARCH=hp700
Also, directory permissions may not be correct across multiple machines,
@@ -41,3 +41,5 @@
% chmod -R ugo+rw base extensions
might be necessary.
- bsdinstall is written to replace install for hp.

View File

@@ -14,18 +14,24 @@ SRCS.c = \
../iocinf.c ../access.c ../test_event.c ../service.c \
../flow_control.c ../repeater.c ../conn.c ../acctst.c \
../syncgrp.c ../if_depen.c ../netdb_depen.c ../bsd_depen.c \
../gsd_sync_subr.c ../posix_depen.c ../caRepeater.c
../posix_depen.c ../caRepeater.c ../acctst.c
OBJS = caRepeater.o
OBJS = caRepeater.o
LIBOBJS = \
iocinf.o access.o test_event.o service.o flow_control.o repeater.o \
conn.o syncgrp.o if_depen.o netdb_depen.o \
gsd_sync_subr.o bsd_depen.o posix_depen.o
bsd_depen.o posix_depen.o
LIBNAME = libca.a
PROD = caRepeater
PROD = caRepeater
include $(EPICS)/config/RULES.Unix
acctst: acctst.o $(DEPLIBS_BASE)/libCom.a libca.a
acctst.o: ../acctst.c
$(COMPILE.c) $<

View File

@@ -7,13 +7,13 @@ USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
SRCS.c = \
../iocinf.c ../access.c ../test_event.c ../service.c \
../flow_control.c ../repeater.c ../conn.c ../syncgrp.c \
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c
OBJS = \
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
repeater.o conn.o syncgrp.o if_depen.o bsd_depen.o vxWorks_depen.o
PROD = caLib
PROD = caLib
include $(EPICS)/config/RULES.Vx

View File

@@ -1,5 +1,5 @@
static char *sccsId = "$Id$";
static char *sccsId = "@(#)V5_vxWorks_patch.c 1.2\t7/27/92";
#include <taskLib.h>
#include <taskVarLib.h>

File diff suppressed because it is too large Load Diff

View File

@@ -3,16 +3,18 @@
* CA test/debug routine
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#ifdef VMS
#include <LIB$ROUTINES.H>
#endif
#include <stdio.h>
#include <assert.h>
#include <stdio.h>
#include <assert.h>
#include "os_depen.h"
#include <cadef.h>
#include "os_depen.h"
#include <cadef.h>
#define EVENT_ROUTINE null_event
#define CONN_ROUTINE conn
@@ -52,9 +54,7 @@ int acctst(char *pname)
NULL,
NULL);
}
#endif /*vxWorks*/
#if defined(UNIX) || defined(VMS)
#else /* not vxWorks */
main(int argc, char **argv)
{
if(argc == 2){
@@ -65,7 +65,7 @@ main(int argc, char **argv)
}
return 0;
}
#endif /* UNIX or VMS */
#endif /*vxWorks*/
int doacctst(char *pname)
@@ -74,18 +74,20 @@ int doacctst(char *pname)
chid chix2;
chid chix3;
chid chix4;
struct dbr_gr_float *ptr;
struct dbr_gr_float *pgrfloat;
struct dbr_gr_float *ptr = NULL;
struct dbr_gr_float *pgrfloat = NULL;
float *pfloat = NULL;
double *pdouble = NULL;
long status;
long i, j;
evid monix;
float *pfloat;
double *pdouble;
char pstring[NUM][MAX_STRING_SIZE];
SEVCHK(ca_task_initialize(), "Unable to initialize");
conn_get_cb_count = 0;
printf("begin\n");
#ifdef VMS
lib$init_timer();
@@ -121,17 +123,17 @@ int doacctst(char *pname)
NULL);
SEVCHK(status, NULL);
assert(INVALID_DB_REQ(chix1->type) == TRUE);
assert(INVALID_DB_REQ(chix2->type) == TRUE);
assert(INVALID_DB_REQ(chix3->type) == TRUE);
assert(INVALID_DB_REQ(chix4->type) == TRUE);
if (ca_test_io() == ECA_IOINPROGRESS) {
assert(INVALID_DB_REQ(chix1->type) == TRUE);
assert(INVALID_DB_REQ(chix2->type) == TRUE);
assert(INVALID_DB_REQ(chix3->type) == TRUE);
assert(INVALID_DB_REQ(chix4->type) == TRUE);
assert(ca_state(chix1) == cs_never_conn);
assert(ca_state(chix2) == cs_never_conn);
assert(ca_state(chix3) == cs_never_conn);
assert(ca_state(chix4) == cs_never_conn);
assert(ca_test_io() == ECA_IOINPROGRESS);
assert(ca_state(chix1) == cs_never_conn);
assert(ca_state(chix2) == cs_never_conn);
assert(ca_state(chix3) == cs_never_conn);
assert(ca_state(chix4) == cs_never_conn);
}
status = ca_pend_io(1000.0);
SEVCHK(status, NULL);
@@ -197,8 +199,6 @@ int doacctst(char *pname)
lib$show_timer();
#endif /*VMS*/
pfloat = &ptr->value;
#ifdef VMS
lib$init_timer();
#endif /*VMS*/
@@ -244,9 +244,7 @@ int doacctst(char *pname)
float temp;
printf("Performing multiple get test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
for(i=0; i<10000; i++){
SEVCHK(ca_get(DBR_FLOAT, chix4, &temp),NULL);
}
@@ -262,9 +260,7 @@ int doacctst(char *pname)
*/
if(ca_write_access(chix4)){
printf("Performing multiple put test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
for(i=0; i<10000; i++){
double fval = 3.3;
status = ca_put(DBR_DOUBLE, chix4, &fval);
@@ -283,9 +279,7 @@ int doacctst(char *pname)
*/
if(ca_read_access(chix1)){
printf("Performing multiple get callback test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
for(i=0; i<10000; i++){
status = ca_array_get_callback(
DBR_FLOAT,
@@ -303,17 +297,17 @@ int doacctst(char *pname)
printf("Skipped multiple get cb test - no read access\n");
}
test_sync_groups(chix1);
if(ca_v42_ok(chix1)){
test_sync_groups(chix1);
}
/*
* verify we dont jam up on many uninterrupted
* solicitations
*/
if(ca_write_access(chix1)){
if(ca_write_access(chix1) && ca_v42_ok(chix1)){
printf("Performing multiple put callback test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
for(i=0; i<10000; i++){
float fval = 3.3;
status = ca_array_put_callback(
@@ -337,9 +331,7 @@ int doacctst(char *pname)
* verify we can add many monitors at once
*/
printf("Performing multiple monitor test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
{
evid mid[1000];
float temp;
@@ -361,7 +353,7 @@ int doacctst(char *pname)
printf(
"Clear of event %d %x failed because \"%s\"\n",
i,
mid[i],
mid[i]->id,
ca_message(status));
}
SEVCHK(status,NULL);
@@ -419,10 +411,10 @@ int doacctst(char *pname)
&monix);
SEVCHK(status, NULL);
}
pfloat = (float *) malloc(sizeof(float) * NUM);
pdouble = (double *) malloc(sizeof(double) * NUM);
pgrfloat = (struct dbr_gr_float *) malloc(sizeof(*pgrfloat) * NUM);
pfloat = (float *) calloc(sizeof(float),NUM);
pdouble = (double *) calloc(sizeof(double),NUM);
pgrfloat = (struct dbr_gr_float *) calloc(sizeof(*pgrfloat),NUM);
if (VALID_DB_REQ(chix1->type))
if (pfloat)
@@ -468,14 +460,19 @@ int doacctst(char *pname)
printf("GR Float value Returned from put/get %f\n", pgrfloat[i].value);
}
#if 0
for (i = 0; i < 10; i++)
ca_get_callback(DBR_GR_FLOAT, chix1, ca_test_event, NULL);
#endif
SEVCHK(ca_modify_user_name("Willma"), NULL);
SEVCHK(ca_modify_host_name("Bed Rock"), NULL);
assert(conn_get_cb_count == 3);
if (conn_get_cb_count != 3){
printf ("!!!! Connect cb count = %d expected = 3 !!!!\n",
conn_get_cb_count);
}
printf("-- Put/Gets done- waiting for Events --\n");
status = ca_pend_event(10.0);
@@ -483,10 +480,18 @@ int doacctst(char *pname)
SEVCHK(status, NULL);
}
free(ptr);
free(pfloat);
free(pdouble);
free(pgrfloat);
if (ptr){
free (ptr);
}
if (pfloat) {
free(pfloat);
}
if (pdouble) {
free(pdouble);
}
if (pgrfloat) {
free(pgrfloat);
}
status = ca_task_exit();
SEVCHK(status,NULL);
@@ -501,7 +506,7 @@ void null_event(struct event_handler_args args)
static int i;
if (i++ > 1000) {
printf("1000 occured\n");
printf("1000 occurred\n");
i = 0;
}
}
@@ -555,9 +560,7 @@ void test_sync_groups(chid chix)
CA_SYNC_GID gid2;
printf("Performing sync group test...");
#ifdef UNIX
fflush(stdout);
#endif /*UNIX*/
status = ca_sg_create(&gid1);
SEVCHK(status, NULL);

View File

@@ -1,6 +1,24 @@
#include <envDefs.h>
void caSetupAddrList(
ELLLIST *pList,
SOCKET socket);
void caPrintAddrList();
void caDiscoverInterfaces(
ELLLIST *pList,
SOCKET socket,
int port);
void caAddConfiguredAddr(
ELLLIST *pList,
ENV_PARAM *pEnv,
SOCKET socket,
int port);
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
union caAddr{

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id$
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
@@ -36,23 +36,41 @@
/*
* cac_select_io()
*
* NOTE: on multithreaded systems this assumes that the
* local implementation of select is reentrant
*/
int cac_select_io(struct timeval *ptimeout, int flags)
{
long status;
IIU *piiu;
unsigned long minfreespace;
unsigned long freespace;
int maxfd;
caFDInfo *pfdi;
LOCK;
pfdi = (caFDInfo *) ellGet(&ca_static->fdInfoFreeList);
if (!pfdi) {
pfdi = (caFDInfo *) calloc (1, sizeof(*pfdi));
if (!pfdi) {
ca_printf("CAC: no mem for select ctx?\n");
UNLOCK;
return -1;
}
}
ellAdd (&ca_static->fdInfoList, &pfdi->node);
FD_ZERO (&pfdi->readMask);
FD_ZERO (&pfdi->writeMask);
maxfd = 0;
for( piiu=(IIU *)iiuList.node.next;
for( piiu = (IIU *) iiuList.node.next;
piiu;
piiu=(IIU *)piiu->node.next){
piiu = (IIU *) piiu->node.next) {
if(!piiu->conn_up){
if (!piiu->conn_up) {
continue;
}
@@ -60,30 +78,22 @@ int cac_select_io(struct timeval *ptimeout, int flags)
* Dont bother receiving if we have insufficient
* space for the maximum UDP message
*/
if(flags&CA_DO_RECVS){
freespace = cacRingBufferWriteSize(&piiu->recv, TRUE);
if(piiu->sock_proto == IPPROTO_UDP){
minfreespace =
MAX_UDP+2*sizeof(struct udpmsglog);
}
else{
minfreespace = 1;
}
if(freespace>=minfreespace){
maxfd = max(maxfd,piiu->sock_chan);
FD_SET(piiu->sock_chan,&readch);
if (flags&CA_DO_RECVS) {
freespace = cacRingBufferWriteSize (&piiu->recv, TRUE);
if (freespace>=piiu->minfreespace) {
maxfd = max (maxfd,piiu->sock_chan);
FD_SET (piiu->sock_chan, &pfdi->readMask);
}
}
if(flags&CA_DO_SENDS){
if(cacRingBufferReadSize(&piiu->send, FALSE)>0){
maxfd = max(maxfd,piiu->sock_chan);
FD_SET(piiu->sock_chan,&writech);
if (flags&CA_DO_SENDS) {
if (cacRingBufferReadSize(&piiu->send, FALSE)>0) {
maxfd = max (maxfd,piiu->sock_chan);
FD_SET (piiu->sock_chan, &pfdi->writeMask);
}
}
}
UNLOCK;
UNLOCK;
#if 0
printf( "max fd=%d tv_usec=%d tv_sec=%d\n",
@@ -91,54 +101,63 @@ printf( "max fd=%d tv_usec=%d tv_sec=%d\n",
ptimeout->tv_usec,
ptimeout->tv_sec);
#endif
#if defined(vxWorks) && 0
if(client_lock->recurse>0){
ca_printf("lock is on and we are going to sleep %d!",
client_lock->recurse);
taskSuspend(0);
}
#endif
status = select(
maxfd+1,
&readch,
&writech,
&pfdi->readMask,
&pfdi->writeMask,
NULL,
ptimeout);
#if 0
printf("leaving select stat=%d errno=%d \n", status, MYERRNO);
#endif
if(status<0){
if(MYERRNO == EINTR){
if (status<0) {
if (MYERRNO == EINTR) {
}
else if(MYERRNO == EWOULDBLOCK){
else if (MYERRNO == EWOULDBLOCK) {
ca_printf("CAC: blocked at select ?\n");
}
else{
ca_printf(
else if (MYERRNO == ESRCH) {
}
else {
ca_printf (
"CAC: unexpected select fail: %s\n",
strerror(MYERRNO));
return status;
}
}
LOCK;
if(status>0){
for( piiu=(IIU *)iiuList.node.next;
LOCK;
if (status>0) {
for ( piiu = (IIU *) iiuList.node.next;
piiu;
piiu=(IIU *)piiu->node.next){
piiu = (IIU *) piiu->node.next) {
if(!piiu->conn_up){
if (!piiu->conn_up) {
continue;
}
if(flags&CA_DO_SENDS &&
FD_ISSET(piiu->sock_chan,&writech)){
if (FD_ISSET(piiu->sock_chan,&pfdi->writeMask)) {
(*piiu->sendBytes)(piiu);
}
if(flags&CA_DO_RECVS &&
FD_ISSET(piiu->sock_chan,&readch)){
if (FD_ISSET(piiu->sock_chan,&pfdi->readMask)) {
(*piiu->recvBytes)(piiu);
}
FD_CLR(piiu->sock_chan,&readch);
FD_CLR(piiu->sock_chan,&writech);
}
}
UNLOCK;
ellDelete (&ca_static->fdInfoList, &pfdi->node);
ellAdd (&ca_static->fdInfoFreeList, &pfdi->node);
UNLOCK;
return status;
}

View File

@@ -1,5 +1,4 @@
/*
* $Id$
* caRepeater.c
* share/src/ca/caRepeater.c
*

View File

@@ -32,20 +32,16 @@
/************************************************************************/
/*_end */
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include <stdio.h>
#include <stdarg.h>
#ifdef vxWorks
# include <vxWorks.h>
# include <logLib.h>
#endif /*vxWorks*/
#ifdef __STDC__
#include <stdarg.h>
#else /*__STDC__*/
#include <varargs.h>
#endif /*__STDC__*/
/*
@@ -65,24 +61,10 @@ va_dcl
{
va_list args;
int status;
#ifndef __STDC__
char *pformat;
#endif /*__STDC__*/
#ifdef __STDC__
va_start(args, pformat);
#else /*__STDC__*/
va_start(args);
pformat = va_arg(args, char *);
#endif /*__STDC__*/
#ifndef vxWorks
status = vfprintf(
stderr,
pformat,
args);
#else /*vxWorks*/
#if defined(vxWorks)
{
int logMsgArgs[6];
int i;
@@ -101,7 +83,12 @@ va_dcl
logMsgArgs[5]);
}
#endif /*vxWorks*/
#else
status = vfprintf(
stderr,
pformat,
args);
#endif
va_end(args);

View File

@@ -10,11 +10,8 @@
*/
# ifdef VMS
lib$init_timer();
# endif
# ifdef VMS
lib$show_timer();
#ifdef VMS
#include <LIB$ROUTINES.H>
#endif

View File

@@ -22,9 +22,11 @@
/* .08 010493 joh removed `<Trying>' message */
/* .09 090293 joh removed flush from manage_conn */
/* (now handled by the send needed flag) */
/* .10 102093 joh improved broadcast schedualing for */
/* .10 102093 joh improved broadcast scheduling for */
/* reconnects */
/* .11 042994 joh removed client side heart beat */
/* .12 110194 joh improved search scheduling */
/* (dont send all chans in a block) */
/* */
/*_begin */
/************************************************************************/
@@ -39,10 +41,19 @@
/************************************************************************/
/*_end */
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include "iocinf.h"
#ifdef DEBUG
#define LOGRETRYINTERVAL logRetryInterval(__FILE__, __LINE__);
#else
#define LOGRETRYINTERVAL
#endif
LOCAL void logRetryInterval(char *pFN, unsigned lineno);
LOCAL void retrySearchRequest(int silent);
/*
*
@@ -55,22 +66,31 @@ static char *sccsId = "$Id$";
void manage_conn(int silent)
{
IIU *piiu;
chid chix;
unsigned int retry_cnt = 0;
unsigned int retry_cnt_no_handler = 0;
ca_time current;
ca_real delay;
unsigned long idelay;
current = time(NULL);
/*
* prevent recursion
*/
if(ca_static->ca_manage_conn_active){
return;
}
ca_static->ca_manage_conn_active = TRUE;
cac_gettimeval(&current);
/*
* issue connection heartbeat
* (if we dont see a beacon)
*/
LOCK;
for( piiu = (IIU *) iiuList.node.next;
piiu;
piiu = (IIU *) piiu->node.next){
if(piiu == piiuCast || !piiu->conn_up){
if (piiu == piiuCast || !piiu->conn_up) {
continue;
}
@@ -78,8 +98,11 @@ void manage_conn(int silent)
* mark connection for shutdown if outgoing messages
* are not accepted by TCP/IP for several seconds
*/
if(piiu->sendPending){
if((current-piiu->timeAtSendBlock)>CA_RETRY_PERIOD){
if (piiu->sendPending) {
delay = cac_time_diff (
&current,
&piiu->timeAtSendBlock);
if (delay>ca_static->ca_connectTMO) {
TAG_CONN_DOWN(piiu);
continue;
}
@@ -93,9 +116,14 @@ void manage_conn(int silent)
int stmo;
int rtmo;
stmo = (current-piiu->timeAtEchoRequest)
> CA_RETRY_PERIOD;
rtmo = (current-piiu->timeAtLastRecv)>CA_RETRY_PERIOD;
delay = cac_time_diff (
&current,
&piiu->timeAtEchoRequest);
stmo = delay > CA_RETRY_PERIOD;
delay = cac_time_diff (
&current,
&piiu->timeAtLastRecv);
rtmo = delay > CA_RETRY_PERIOD;
if(stmo && rtmo && !piiu->sendPending){
piiu->timeAtEchoRequest = current;
noop_msg(piiu);
@@ -104,7 +132,10 @@ void manage_conn(int silent)
}
if(piiu->echoPending){
if((current-piiu->timeAtEchoRequest)>CA_ECHO_TIMEOUT){
delay = cac_time_diff (
&current,
&piiu->timeAtEchoRequest);
if (delay > CA_ECHO_TIMEOUT) {
/*
* mark connection for shutdown
*/
@@ -112,67 +143,208 @@ void manage_conn(int silent)
}
}
else{
int sendBytesAvailable;
sendBytesAvailable =
cacRingBufferWriteSize(&piiu->send, TRUE);
if((current-piiu->timeAtLastRecv)>CA_CONN_VERIFY_PERIOD &&
sendBytesAvailable>sizeof(struct extmsg)){
piiu->echoPending = TRUE;
piiu->timeAtEchoRequest = current;
echo_request(piiu);
delay = cac_time_diff (
&current,
&piiu->timeAtLastRecv);
if (delay>ca_static->ca_connectTMO) {
echo_request(piiu, &current);
}
}
}
UNLOCK;
if(!piiuCast){
/*
* try to attach to the repeater if we havent yet
*/
if (!ca_static->ca_repeater_contacted) {
delay = cac_time_diff (
&current,
&ca_static->ca_last_repeater_try);
if (delay > REPEATER_TRY_PERIOD) {
ca_static->ca_last_repeater_try = current;
notify_ca_repeater();
}
}
/*
* Stop here if there are not any disconnected channels
*/
if(!piiuCast) {
ca_static->ca_manage_conn_active = FALSE;
return;
}
if (piiuCast->chidlist.count == 0) {
ca_static->ca_manage_conn_active = FALSE;
return;
}
if(ca_static->ca_conn_next_retry == CA_CURRENT_TIME){
ca_static->ca_conn_next_retry =
current + ca_static->ca_conn_retry_delay;
if(ca_static->ca_conn_next_retry.tv_sec == CA_CURRENT_TIME.tv_sec &&
ca_static->ca_conn_next_retry.tv_usec == CA_CURRENT_TIME.tv_usec){
ca_static->ca_conn_next_retry = current;
LOGRETRYINTERVAL
}
if(ca_static->ca_conn_next_retry > current)
return;
delay = cac_time_diff (
&ca_static->ca_conn_next_retry,
&current);
if(ca_static->ca_conn_n_tries++ > MAXCONNTRIES)
if (delay > 0.0) {
ca_static->ca_manage_conn_active = FALSE;
return;
}
/*
* the retry sequence number
* (increments once all channels have received this
* number of tries)
*/
if (ca_static->ca_search_retry >= MAXCONNTRIES) {
ca_static->ca_manage_conn_active = FALSE;
return;
if(ca_static->ca_conn_retry_delay<CA_RECAST_PERIOD){
ca_static->ca_conn_retry_delay += ca_static->ca_conn_retry_delay;
}
ca_static->ca_conn_next_retry = current + ca_static->ca_conn_retry_delay;
retrySearchRequest (silent);
/*
* set the retry interval
*/
assert(ca_static->ca_search_retry < NBBY*sizeof(idelay));
idelay = 1;
idelay = idelay << ca_static->ca_search_retry;
delay = idelay * CA_RECAST_DELAY; /* sec */
delay = min (CA_RECAST_PERIOD, delay);
idelay = delay;
ca_static->ca_conn_retry_delay.tv_sec = idelay;
ca_static->ca_conn_retry_delay.tv_usec =
(delay-idelay)*USEC_PER_SEC;
ca_static->ca_conn_next_retry =
cac_time_sum (
&current,
&ca_static->ca_conn_retry_delay);
LOGRETRYINTERVAL
ca_static->ca_manage_conn_active = FALSE;
}
/*
* retrySearchRequest ()
*/
LOCAL void retrySearchRequest (int silent)
{
ELLLIST channelsSent;
chid chix;
unsigned min_retry_num;
unsigned retry_cnt = 0;
unsigned retry_cnt_no_handler = 0;
int status;
if (!piiuCast) {
return;
}
ellInit (&channelsSent);
LOCK;
for( chix = (chid) piiuCast->chidlist.node.next;
chix;
chix = (chid) chix->node.next){
min_retry_num = MAXCONNTRIES;
while (chix = (chid) ellGet (&piiuCast->chidlist)) {
search_msg(chix, DONTREPLY);
retry_cnt++;
ellAdd (&channelsSent, &chix->node);
if(!(silent || chix->pConnFunc)){
ca_signal(ECA_CHIDNOTFND, (char *)(chix+1));
retry_cnt_no_handler++;
min_retry_num = min (min_retry_num, chix->retry);
if (chix->retry <= ca_static->ca_search_retry) {
status = search_msg (chix, DONTREPLY);
if (status == ECA_NORMAL) {
retry_cnt++;
if (!(silent || chix->pConnFunc)) {
ca_signal (
ECA_CHIDNOTFND,
(char *)(chix+1));
retry_cnt_no_handler++;
}
}
else {
break;
}
}
}
UNLOCK;
if(retry_cnt){
if(!silent && retry_cnt_no_handler){
sprintf(
/*
* if we saw the entire list
*/
if (chix==NULL) {
/*
* increment the retry sequence number
*/
if (ca_static->ca_search_retry<MAXCONNTRIES) {
ca_static->ca_search_retry++;
}
/*
* jump to the minimum retry number
*/
if (ca_static->ca_search_retry<min_retry_num) {
ca_static->ca_search_retry = min_retry_num;
}
}
/*
* return channels sent to main cast IIU's
* channel prior to removing the lock
*
* This reorders the list so that each channel
* get a fair chance to connect
*/
ellConcat (&piiuCast->chidlist, &channelsSent);
/*
* LOCK around use of the sprintf buffer
*/
if (retry_cnt) {
if (!silent && retry_cnt_no_handler) {
sprintf (
sprintf_buf,
"%d channels outstanding",
retry_cnt);
ca_signal(ECA_CHIDRETRY, sprintf_buf);
ca_signal (ECA_CHIDRETRY, sprintf_buf);
}
}
UNLOCK;
}
/*
* logRetryInterval()
*/
#ifdef DEBUG
LOCAL void logRetryInterval(char *pFN, unsigned lineno)
{
ca_time currentTime;
ca_real delay;
assert(ca_static->ca_conn_next_retry.tv_usec<USEC_PER_SEC);
cac_gettimeval(&currentTime);
delay = cac_time_diff(
&ca_static->ca_conn_next_retry,
&currentTime);
ca_printf("%s.%d next retry in %f sec\n",
pFN,
lineno,
delay);
delay = ca_static->ca_conn_retry_delay.tv_sec +
((double)ca_static->ca_conn_retry_delay.tv_usec)/
USEC_PER_SEC;
ca_printf("%s.%d retry interval = %f sec - disconn count = %d\n",
pFN,
lineno,
delay,
ellCount(&piiuCast->chidlist));
}
#endif
/*
*
@@ -184,8 +356,9 @@ void manage_conn(int silent)
*/
void mark_server_available(struct in_addr *pnet_addr)
{
int currentPeriod;
int currentTime;
chid chan;
ca_real currentPeriod;
ca_time currentTime;
bhe *pBHE;
unsigned port;
int netChange = FALSE;
@@ -200,7 +373,7 @@ void mark_server_available(struct in_addr *pnet_addr)
return;
}
currentTime = time(NULL);
cac_gettimeval(&currentTime);
LOCK;
/*
@@ -217,11 +390,17 @@ void mark_server_available(struct in_addr *pnet_addr)
/*
* update time stamp and average period
*/
currentPeriod = currentTime - pBHE->timeStamp;
pBHE->averagePeriod = (currentPeriod + pBHE->averagePeriod)>>1;
currentPeriod = cac_time_diff (
&currentTime,
&pBHE->timeStamp);
/*
* update the average
*/
pBHE->averagePeriod += currentPeriod;
pBHE->averagePeriod /= 2.0;
pBHE->timeStamp = currentTime;
if((currentPeriod>>2)>=pBHE->averagePeriod){
if ((currentPeriod/4.0)>=pBHE->averagePeriod) {
#ifdef DEBUG
ca_printf(
"net resume seen %x cur=%d avg=%d\n",
@@ -232,7 +411,7 @@ void mark_server_available(struct in_addr *pnet_addr)
netChange = TRUE;
}
if((pBHE->averagePeriod>>1)>=currentPeriod){
if ((pBHE->averagePeriod/2.0)>=currentPeriod) {
#ifdef DEBUG
ca_printf(
"reboot seen %x cur=%d avg=%d\n",
@@ -260,8 +439,8 @@ void mark_server_available(struct in_addr *pnet_addr)
/*
* This part is very important since many machines
* could have channels in a disconnected state which
* This part is essential since many machines
* might have channels in a disconnected state which
* dont exist anywhere on the network. This insures
* that we dont have many CA clients synchronously
* flooding the network with broadcasts.
@@ -279,23 +458,47 @@ void mark_server_available(struct in_addr *pnet_addr)
piiuCast->sock_chan,
(struct sockaddr *)&saddr,
&saddr_length);
assert(status>=0);
assert (status>=0);
port = ntohs(saddr.sin_port);
}
{
int delay;
int next;
ca_real diff;
ca_real delay;
unsigned idelay;
ca_time ca_delay;
ca_time next;
delay = port&CA_RECAST_PORT_MASK;
delay = (port&CA_RECAST_PORT_MASK);
delay /= MSEC_PER_SEC;
delay += CA_RECAST_DELAY;
idelay = delay;
ca_delay.tv_sec = idelay;
ca_delay.tv_usec = (delay-idelay) * USEC_PER_SEC;
next = cac_time_sum(&currentTime, &ca_delay);
next = currentTime + delay;
if(ca_static->ca_conn_next_retry>next){
diff = cac_time_diff(
&ca_static->ca_conn_next_retry,
&next);
if(diff>0.0){
ca_static->ca_conn_next_retry = next;
LOGRETRYINTERVAL
}
ca_static->ca_conn_retry_delay = CA_RECAST_DELAY;
ca_static->ca_conn_n_tries = 0;
idelay = CA_RECAST_DELAY;
ca_static->ca_conn_retry_delay.tv_sec = idelay;
ca_static->ca_conn_retry_delay.tv_usec =
(CA_RECAST_DELAY-idelay) * USEC_PER_SEC;
ca_static->ca_search_retry = 0;
}
/*
* set retry count of all disconnected channels
* to zero
*/
chan = (chid) ellFirst(&piiuCast->chidlist);
while (chan) {
chan->retry = 0;
chan = (chid) ellNext (&chan->node);
}
UNLOCK;
@@ -330,6 +533,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
#ifdef DEBUG
ca_printf("new IOC %x\n", pnet_addr->s_addr);
#endif
/*
* store the inet address
*/
@@ -338,8 +542,8 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
/*
* start the average at zero
*/
pBHE->averagePeriod = 0;
pBHE->timeStamp = time(NULL);
pBHE->averagePeriod = 0.0;
cac_gettimeval(&pBHE->timeStamp);
/*
* install in the hash table
@@ -383,29 +587,29 @@ bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
void removeBeaconInetAddr(struct in_addr *pnet_addr)
void removeBeaconInetAddr (struct in_addr *pnet_addr)
{
bhe *pBHE;
bhe **ppBHE;
unsigned index;
index = ntohl(pnet_addr->s_addr);
index = ntohl (pnet_addr->s_addr);
index &= BHT_INET_ADDR_MASK;
assert(index<NELEMENTS(ca_static->ca_beaconHash));
assert (index<NELEMENTS(ca_static->ca_beaconHash));
ppBHE = &ca_static->ca_beaconHash[index];
pBHE = *ppBHE;
while(pBHE){
if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){
while (pBHE) {
if (pBHE->inetAddr.s_addr == pnet_addr->s_addr) {
*ppBHE = pBHE->pNext;
free(pBHE);
free (pBHE);
return;
}
ppBHE = &pBHE->pNext;
pBHE = *ppBHE;
}
assert(0);
assert (0);
}

View File

@@ -23,11 +23,12 @@
* joh 07-05-94 Fixed double invocation of ++ operator
* by byte swap macro bug in cvrt_short(),
* cvrt_long(), cvrt_enum().
* joh 11-02-94 moved float convert to this source
*
*
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include <string.h>
@@ -36,11 +37,8 @@ static char *sccsId = "$Id$";
void htond(double *pHost, double *pNet);
void ntohd(double *pNet, double *pHost);
#ifndef CONVERSION_REQUIRED
void htonf(float *IEEEhost, float *IEEEnet);
void ntohf(float *IEEEnet, float *IEEEhost);
#endif /*not CONVERSION_REQUIRED*/
void htonf(float *pHost, float *pNet);
void ntohf(float *pNet, float *pHost);
/*
* if hton is true then it is a host to network conversion
@@ -94,9 +92,6 @@ LOCAL CACVRTFUNC cvrt_ctrl_long;
LOCAL CACVRTFUNC cvrt_ctrl_double;
/* cvrt is (array of) (pointer to) (function returning) int */
#ifdef VMS
globaldef
#endif
CACVRTFUNC *cac_dbr_cvrt[]
=
{
@@ -148,7 +143,7 @@ typedef short ca_short_tt;
typedef float ca_float_tt;
typedef short ca_enum_tt;
typedef char ca_char_tt;
typedef long ca_long_tt;
typedef int ca_long_tt;
typedef double ca_double_tt;
#define dbr_ntohs(A) ntohs(A)
@@ -227,7 +222,7 @@ int encode, /* cvrt HOST to NET if T */
unsigned long num /* number of values */
)
{
unsigned int i;
unsigned long i;
ca_char_tt *pSrc = s;
ca_char_tt *pDest = d;
@@ -280,7 +275,7 @@ int encode, /* cvrt HOST to NET if T */
unsigned long num /* number of values */
)
{
unsigned i;
unsigned long i;
ca_enum_tt *pSrc;
ca_enum_tt *pDest;
@@ -347,7 +342,7 @@ int encode, /* cvrt HOST to NET if T */
unsigned long num /* number of values */
)
{
unsigned int i;
unsigned long i;
ca_double_tt *pSrc = s;
ca_double_tt *pDest = d;
@@ -1379,7 +1374,7 @@ unsigned long num /* number of values */
}
#ifdef MIT_FLOAT
#ifdef CA_FLOAT_MIT
/************************************************************************/
/* double convert */
/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */
@@ -1424,8 +1419,8 @@ void htond(double *pHost, double *pNet)
double copyin;
struct mitdbl *pMIT;
struct ieeedbl *pIEEE;
long *ptmp;
long tmp;
ca_uint32_t *ptmp;
ca_uint32_t tmp;
copyin = *pHost;
pMIT = (struct mitdbl *)&copyin;
@@ -1448,7 +1443,7 @@ void htond(double *pHost, double *pNet)
/*
* byte swap to net order
*/
ptmp = (long *) pNet;
ptmp = (ca_uint32_t *) pNet;
tmp = htonl(ptmp[0]);
ptmp[0] = htonl(ptmp[1]);
ptmp[1] = tmp;
@@ -1464,8 +1459,8 @@ void ntohd(double *pNet, double *pHost)
double copyin;
struct mitdbl *pMIT;
struct ieeedbl *pIEEE;
long *ptmp;
long tmp;
ca_uint32_t *ptmp;
ca_uint32_t tmp;
copyin = *pNet;
pMIT = (struct mitdbl *)pHost;
@@ -1474,7 +1469,7 @@ void ntohd(double *pNet, double *pHost)
/*
* Byte swap from net order to host order
*/
ptmp = (long *) pIEEE;
ptmp = (ca_uint32_t *) pIEEE;
tmp = htonl(ptmp[0]);
ptmp[0] = htonl(ptmp[1]);
ptmp[1] = tmp;
@@ -1505,27 +1500,171 @@ void ntohd(double *pNet, double *pHost)
}
}
#endif /*MIT_FLOAT*/
/************************************************************************/
/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */
/************************************************************************/
#ifndef CONVERSION_REQUIRED
void htond(double *IEEEhost, double *IEEEnet)
struct ieeeflt{
unsigned mant :23;
unsigned exp :8;
unsigned sign :1;
};
/* Exponent sign bias */
#define IEEE_SB 127
/* Conversion Range */
/* -126<exp<127 with mantissa of form 1.mant */
#define EXPMINIEEE -126 /* min for norm # IEEE exponent */
struct mitflt{
unsigned mant1 :7;
unsigned exp :8;
unsigned sign :1;
unsigned mant2 :16;
};
/* Exponent sign bias */
# define MIT_SB 129
/* Conversion Ranges */
/* -128<exp<126 with mantissa of form 1.mant */
# define EXPMAXMIT 126 /* max MIT exponent */
# define EXPMINMIT -128 /* min MIT exponent */
/* (this includes mapping of fringe reals to zero or infinity) */
/* (byte swaps included in conversion */
void htonf(float *pHost, float *pNet)
{
*IEEEnet = *IEEEhost;
struct mitflt *pMIT = pHost;
struct ieeeflt *pIEEE = pNet;
long exp,mant,sign;
sign = pHost->sign;
if( (short)(pMIT->exp < EXPMINIEEE + MIT_SB){
exp = 0;
mant = 0;
sign = 0;
}
else{
exp = (short)pMIT->exp-MIT_SB+IEEE_SB;
mant = (pMIT->mant1<<16) | pMIT->mant2;
}
pIEEE->mant = mant;
pIEEE->exp = exp;
pIEEE->sign = sign;
*(ca_uint32_t *)pIEEE = htonl(*(ca_uint32_t *)pIEEE);
}
void ntohd(double *IEEEnet, double *IEEEhost)
/*
* sign must be forced to zero if the exponent is zero to prevent a reserved
* operand fault- joh 9-13-90
*/
void ntohf(float *pNet, float *pHost)
{
*IEEEhost = *IEEEnet;
struct mitflt *pMIT = pHost;
struct ieeeflt *pIEEE = pNet;
long exp,mant2,mant1,sign;
*(ca_uint32_t *)pIEEE = ntohl(*(ca_uint32_t *)pIEEE);
if( (short) pIEEE->exp > EXPMAXMIT + IEEE_SB){
sign = pIEEE->sign;
exp = EXPMAXMIT + MIT_SB;
mant2 = ~0;
mant1 = ~0;
}
else if( pIEEE->exp == 0){
sign = 0;
exp = 0;
mant2 = 0;
mant1 = 0;
}
else{
sign = pIEEE->sign;
exp = pIEEE->exp+MIT_SB-IEEE_SB;
mant2 = pIEEE->mant;
mant1 = pIEEE->mant>>(unsigned)16;
}
pMIT->exp = exp;
pMIT->mant2 = mant2;
pMIT->mant1 = mant1;
pMIT->sign = sign;
}
void ntohf(float *IEEEnet, float *IEEEhost)
#endif /*CA_FLOAT_MIT*/
#ifndef CA_FLOAT_MIT
/*
* htond ()
* performs only byte swapping
*/
void htond (double *IEEEhost, double *IEEEnet)
{
*IEEEhost = *IEEEnet;
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
ca_uint32_t tmp;
/*
* byte swap to net order
* (assume that src and dest ptrs
* may be identical)
*/
tmp = pHost[0];
pNet[0] = htonl (pHost[1]);
pNet[1] = htonl (tmp);
}
void htonf(float *IEEEhost, float *IEEEnet)
/*
* ntohd ()
* performs only byte swapping
*/
void ntohd (double *IEEEnet, double *IEEEhost)
{
*IEEEnet = *IEEEhost;
}
#endif /* not MIT_FLOAT */
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
ca_uint32_t tmp;
/*
* byte swap to net order
* (assume that src and dest ptrs
* may be identical)
*/
tmp = pNet[0];
pHost[0] = ntohl (pNet[1]);
pHost[1] = htonl (tmp);
}
/*
* ntohf ()
* performs only byte swapping
*/
void ntohf (float *IEEEnet, float *IEEEhost)
{
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
*pHost = ntohl (*pNet);
}
/*
* htonf ()
* performs only byte swapping
*/
void htonf (float *IEEEhost, float *IEEEnet)
{
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
*pNet = htonl (*pHost);
}
#endif /* not CA_MIT_FLOAT*/

View File

@@ -33,7 +33,7 @@
/************************************************************************/
/*_end */
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include "iocinf.h"
@@ -61,7 +61,7 @@ void flow_control(struct ioc_in_use *piiu)
*/
status = socket_ioctl(piiu->sock_chan,
FIONREAD,
(int)&nbytes);
&nbytes);
if (status < 0) {
TAG_CONN_DOWN(piiu);
UNLOCK;

View File

@@ -81,7 +81,7 @@
***************************************************
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#)gsd_sync_subr.c 1.8\t11/5/92";
#if defined(UNIX)
# include <sys/types.h>

View File

@@ -1,5 +1,5 @@
/* if_depen.c */
/* $Id$ */
/* share/src/ca/$Id$ */
/*
* Author: Jeff Hill
@@ -35,11 +35,18 @@
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include "iocinf.h"
/*
* Dont use ca_static based lock macros here because this is
* also called by the server. All locks required are applied at
* a higher level.
*/
#undef LOCK
#undef UNLOCK
/*
@@ -47,6 +54,7 @@ static char *sccsId = "$Id$";
*
* Perhaps it is sufficient for this to return 127.0.0.1
* (the loop back address)
* See Below
*/
int local_addr(int s, struct sockaddr_in *plcladdr)
{
@@ -69,39 +77,42 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
*/
ifconf.ifc_len = sizeof ifreq;
ifconf.ifc_req = ifreq;
status = socket_ioctl(s, SIOCGIFCONF, (int)&ifconf);
status = socket_ioctl(s, SIOCGIFCONF, &ifconf);
if (status < 0 || ifconf.ifc_len == 0) {
ca_printf("CAC: ioctl failed %s\n", strerror(MYERRNO));
ifconf.ifc_len = 0;
}
#ifdef DEBUG
ca_printf("CAC: %d if fnd\n", ifconf.ifc_len/sizeof(*pifreq));
#endif
for ( pifreq = ifconf.ifc_req;
ifconf.ifc_len >= sizeof(*pifreq);
pifreq++, ifconf.ifc_len -= sizeof(*pifreq)) {
status = socket_ioctl(s, SIOCGIFFLAGS, (int)pifreq);
status = socket_ioctl(s, SIOCGIFFLAGS, pifreq);
if (status == ERROR){
ca_printf("CAC: could not obtain if flags\n");
continue;
}
if (!(pifreq->ifr_flags & IFF_UP)) {
continue;
}
if (pifreq->ifr_flags & IFF_LOOPBACK) {
continue;
}
if (!(pifreq->ifr_flags & IFF_BROADCAST)) {
continue;
}
#ifdef DEBUG
ca_printf("CAC: if fnd %s\n", pifreq->ifr_name);
#endif
status = socket_ioctl(s, SIOCGIFADDR, (int)pifreq);
if (!(pifreq->ifr_flags & IFF_UP)) {
#ifdef DEBUG
ca_printf("CAC: if was down\n");
#endif
continue;
}
/*
* o Dont require broadcast capabilities.
* o Loopback addresss is ok - preferable?
*/
status = socket_ioctl(s, SIOCGIFADDR, pifreq);
if (status == ERROR){
#ifdef DEBUG
ca_printf("CAC: could not obtain addr\n");
@@ -118,20 +129,9 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
tmpaddr = (struct sockaddr_in *) &pifreq->ifr_addr;
if (!init){
init = TRUE;
addr = *tmpaddr;
}
else {
if (tmpaddr->sin_addr.s_addr
!= addr.sin_addr.s_addr)
ca_printf("CAC: %s: interface=%s inet addr does not match first interface found %x\n",
__FILE__,
pifreq->ifr_name,
tmpaddr->sin_addr.s_addr);
if (tmpaddr->sin_port != addr.sin_port)
ca_printf("CAC: local_addr(): inconsistent port found- first used\n");
}
init = TRUE;
addr = *tmpaddr;
break;
}
if(!init){
@@ -142,13 +142,46 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
return OK;
}
#if 0
/*
* An alternate sloution
* for os without the if routines
*/
/*
* local_addr()
*
* return 127.0.0.1
* (the loop back address)
*/
int local_addr (int s, struct sockaddr_in *plcladdr)
{
ca_uint32_t loopBackAddress = 0x7f000001;
plcladdr->sa_family = AF_INET;
plcladdr->sin_port = 0;
plcladdr->sin_addr.s_addr = ntohl (loopBackAddress);
}
#endif
/*
* caDiscoverInterfaces()
* caDiscoverInterfaces()
*
* Load the list with the broadcast address for all
* interfaces found that support broadcast.
* This routine is provided with the address of an ELLLIST a socket
* and a destination port number. When the routine returns there
* will be one additional inet address (a caAddrNode) in the list
* for each inet interface found that is up and isnt a loop back
* interface. If the interface supports broadcast then I add its
* broadcast address to the list. If the interface is a point to
* point link then I add the destination address of the point to
* point link to the list. In either case I set the port number
* in the address node to the port supplied in the argument
* list.
*
* LOCK should be applied here for (pList)
* (this is also called from the server)
*/
void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
{
@@ -176,7 +209,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
ifconf.ifc_len = nelem*sizeof(*pifreq);
ifconf.ifc_req = pIfreqList;
status = socket_ioctl(socket, SIOCGIFCONF, (int)&ifconf);
status = socket_ioctl(socket, SIOCGIFCONF, &ifconf);
if (status < 0 || ifconf.ifc_len == 0) {
free(pIfreqList);
return;
@@ -184,7 +217,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
nelem = ifconf.ifc_len/sizeof(struct ifreq);
for (pifreq = pIfreqList; pifreq<(pIfreqList+nelem); pifreq++){
status = socket_ioctl(socket, SIOCGIFFLAGS, (int) pifreq);
status = socket_ioctl(socket, SIOCGIFFLAGS, pifreq);
if (status){
continue;
}
@@ -206,7 +239,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
/*
* Fetch the local address for this interface
*/
status = socket_ioctl(socket, SIOCGIFADDR, (int)pifreq);
status = socket_ioctl(socket, SIOCGIFADDR, pifreq);
if (status){
continue;
}
@@ -234,7 +267,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
status = socket_ioctl(
socket,
SIOCGIFBRDADDR,
(int) pifreq);
pifreq);
if (status){
continue;
}
@@ -243,7 +276,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
status = socket_ioctl(
socket,
SIOCGIFDSTADDR,
(int) pifreq);
pifreq);
if (status){
continue;
}
@@ -264,10 +297,10 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
pNode->destAddr.inetAddr.sin_port = htons(port);
pNode->srcAddr.inetAddr = localAddr;
LOCK;
/*
* LOCK applied externally
*/
ellAdd(pList, &pNode->node);
UNLOCK;
}
free(pIfreqList);

View File

@@ -66,7 +66,7 @@
/************************************************************************/
/*_end */
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
/* Allocate storage for global variables in this module */
@@ -152,7 +152,7 @@ int net_proto
{
struct ioc_in_use *piiu;
int status;
int sock;
SOCKET sock;
int true = TRUE;
struct sockaddr_in saddr;
caAddrNode *pNode;
@@ -190,17 +190,19 @@ int net_proto
}
pNode->destAddr.inetAddr.sin_family = AF_INET;
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
pNode->destAddr.inetAddr.sin_port = htons(CA_SERVER_PORT);
pNode->destAddr.inetAddr.sin_port =
htons (ca_static->ca_server_port);
ellAdd(&piiu->destAddr, &pNode->node);
piiu->recvBytes = tcp_recv_msg;
piiu->sendBytes = cac_tcp_send_msg_piiu;
piiu->procInput = ca_process_tcp;
piiu->minfreespace = 1;
/* allocate a socket */
sock = socket( AF_INET, /* domain */
SOCK_STREAM, /* type */
0); /* deflt proto */
if(sock == ERROR){
if(sock == INVALID_SOCKET){
free(piiu);
UNLOCK;
return ECA_SOCK;
@@ -347,7 +349,7 @@ int net_proto
status = socket_ioctl(
piiu->sock_chan,
FIONBIO,
(int) &true);
&true);
if(status<0){
ca_printf(
"Error setting non-blocking io: %s\n",
@@ -363,7 +365,7 @@ int net_proto
piiu->host_name_str,
sizeof(piiu->host_name_str));
piiu->timeAtLastRecv = time(NULL);
cac_gettimeval (&piiu->timeAtLastRecv);
break;
@@ -373,12 +375,13 @@ int net_proto
piiu->recvBytes = udp_recv_msg;
piiu->sendBytes = cac_udp_send_msg_piiu;
piiu->procInput = ca_process_udp;
piiu->minfreespace = MAX_UDP+2*sizeof(struct udpmsglog);
/* allocate a socket */
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if(sock == ERROR){
if(sock == INVALID_SOCKET){
free (piiu);
UNLOCK;
return ECA_SOCK;
@@ -423,19 +426,18 @@ int net_proto
ca_signal(ECA_INTERNAL,"bind failed");
}
caDiscoverInterfaces(
&piiu->destAddr,
sock,
CA_SERVER_PORT);
caAddConfiguredAddr(
/*
* load user and auto configured
* broadcast address list
*/
caSetupBCastAddrList(
&piiu->destAddr,
&EPICS_CA_ADDR_LIST,
sock,
CA_SERVER_PORT);
sock,
ca_static->ca_server_port);
cacRingBufferInit(&piiu->recv, sizeof(piiu->send.buf));
cacRingBufferInit(&piiu->send, min(MAX_UDP, sizeof(piiu->send.buf)));
cacRingBufferInit(&piiu->send, min(MAX_UDP,
sizeof(piiu->send.buf)));
strncpy(
piiu->host_name_str,
@@ -460,18 +462,6 @@ int net_proto
UNLOCKEVENTS;
}
/*
* setup the recv thread
* (OS dependent)
*/
status = cac_setup_recv_thread(piiu);
if(status != ECA_NORMAL){
free(piiu);
status = socket_close(sock);
return status;
}
/*
* add to the list of active IOCs
*/
@@ -485,12 +475,64 @@ int net_proto
return ECA_NORMAL;
}
/*
* caSetupBCastAddrList()
*/
void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port)
{
char *pstr;
ENV_PARAM yesno;
int yes;
/*
* dont load the list twice
*/
assert (ellCount(pList)==0);
/*
* Check to see if the user has disabled
* initializing the search b-cast list
* from the interfaces found.
*/
yes = TRUE;
pstr = envGetConfigParam (
&EPICS_CA_AUTO_ADDR_LIST,
sizeof(yesno.dflt),
yesno.dflt);
if (pstr) {
if (strstr(pstr,"no")||strstr(pstr,"NO")) {
yes = FALSE;
}
}
/*
* LOCK is for piiu->destAddr list
* (lock outside because this is used by the server also)
*/
if (yes) {
caDiscoverInterfaces(
pList,
sock,
port);
}
caAddConfiguredAddr(
pList,
&EPICS_CA_ADDR_LIST,
sock,
port);
if (ellCount(pList)==0) {
ca_signal (ECA_NOSEARCHADDR, NULL);
}
}
/*
* NOTIFY_CA_REPEATER()
*
* tell the cast repeater that another client has come on line
* tell the cast repeater that another client needs fan out
*
* NOTES:
* 1) local communication only (no LAN traffic)
@@ -498,25 +540,55 @@ int net_proto
*/
void notify_ca_repeater()
{
struct extmsg msg;
struct sockaddr_in saddr;
int status;
static int once = FALSE;
if(!piiuCast)
if (ca_static->ca_repeater_contacted) {
return;
if(!piiuCast->conn_up)
}
if (!piiuCast) {
return;
}
if (!piiuCast->conn_up) {
return;
}
if (ca_static->ca_repeater_tries>N_REPEATER_TRIES_PRIOR_TO_MSG){
if (!once) {
ca_printf(
"Unable to contact CA repeater after %d tries\n",
N_REPEATER_TRIES_PRIOR_TO_MSG);
ca_printf(
"Silence this message by starting a CA repeater daemon\n");
once = TRUE;
}
}
LOCK; /*MULTINET TCP/IP routines are not reentrant*/
status = local_addr(piiuCast->sock_chan, &saddr);
if(status == OK){
saddr.sin_port = htons(CA_CLIENT_PORT);
if (status == OK) {
memset((char *)&msg, 0, sizeof(msg));
msg.m_cmmd = htons(REPEATER_REGISTER);
msg.m_available = saddr.sin_addr.s_addr;
saddr.sin_port = htons(ca_static->ca_repeater_port);
/*
* Intentionally sending a zero length message here
* until most CA repeater daemons have been restarted
* (and only then will accept the above protocol)
* (repeaters began accepting this protocol
* starting with EPICS 3.12)
*/
status = sendto(
piiuCast->sock_chan,
NULL,
0, /* zero length message */
(char *)&msg, /* UCX requires a valid address here */
0, /* <= sizeof(msg) ! see comment above ! */
0,
(struct sockaddr *)&saddr,
sizeof saddr);
sizeof(saddr));
if(status < 0){
if( MYERRNO != EINTR &&
MYERRNO != ENOBUFS &&
@@ -527,6 +599,9 @@ void notify_ca_repeater()
assert(0);
}
}
else{
ca_static->ca_repeater_tries++;
}
}
UNLOCK;
}
@@ -659,7 +734,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
MYERRNO == EINTR){
UNLOCK;
if(!piiu->sendPending){
piiu->timeAtSendBlock = time(NULL);
cac_gettimeval(&piiu->timeAtSendBlock);
piiu->sendPending = TRUE;
}
return;
@@ -830,7 +905,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
* Record the time whenever we receive a message
* from this IOC
*/
piiu->timeAtLastRecv = time(NULL);
cac_gettimeval(&piiu->timeAtLastRecv);
UNLOCK;
return;
@@ -856,7 +931,7 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
pNode = (caAddrNode *) piiu->destAddr.node.next;
post_msg_active++;
post_msg_active = TRUE;
LOCK;
while(TRUE){
@@ -873,7 +948,8 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
bytesToProcess);
if(status != OK){
TAG_CONN_DOWN(piiu);
post_msg_active--;
post_msg_active = FALSE;
UNLOCK;
return;
}
CAC_RING_BUFFER_READ_ADVANCE(
@@ -882,7 +958,7 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
}
UNLOCK;
post_msg_active--;
post_msg_active = FALSE;
flow_control(piiu);
@@ -939,7 +1015,7 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu)
* log the msg size
* and advance the ring index
*/
pmsglog->nbytes = (long) status;
pmsglog->nbytes = status;
pmsglog->valid = TRUE;
bytesActual = status + sizeof(*pmsglog);
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, bytesActual);
@@ -961,7 +1037,7 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu)
ca_printf(
"%s: udp reply of %d bytes\n",
__FILE__,
byte_cnt);
status);
# endif
}
@@ -991,7 +1067,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
}
post_msg_active++;
post_msg_active = TRUE;
LOCK;
while(TRUE){
@@ -1029,7 +1105,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
sizeof(piiu->recv.buf));
piiu->curMsgBytes = 0;
piiu->curDataBytes = 0;
post_msg_active--;
post_msg_active = FALSE;
UNLOCK;
return;
}
@@ -1043,7 +1119,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
UNLOCK;
post_msg_active--;
post_msg_active = FALSE;
return;
}
@@ -1057,7 +1133,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
*
*
*/
void close_ioc(struct ioc_in_use *piiu)
void close_ioc (struct ioc_in_use *piiu)
{
caAddrNode *pNode;
chid chix;
@@ -1066,107 +1142,116 @@ void close_ioc(struct ioc_in_use *piiu)
/*
* dont close twice
*/
if(piiu->sock_chan == -1){
return;
}
assert (piiu->sock_chan!=INVALID_SOCKET);
LOCK;
ellDelete(&iiuList, &piiu->node);
ellDelete (&iiuList, &piiu->node);
/*
* attempt to clear out messages in recv queue
*/
(*piiu->procInput)(piiu);
(*piiu->procInput) (piiu);
if(piiu == piiuCast){
if (piiu == piiuCast) {
piiuCast = NULL;
}
else {
/*
* remove IOC from the hash table
*/
pNode = (caAddrNode *) piiu->destAddr.node.next;
assert (pNode);
removeBeaconInetAddr (&pNode->destAddr.inetAddr.sin_addr);
/*
* Mark all of their channels disconnected
* prior to calling handlers incase the
* handler tries to use a channel before
* I mark it disconnected.
*/
chix = (chid) &piiu->chidlist.node.next;
while(chix = (chid) chix->node.next){
chix->type = TYPENOTCONN;
chix->count = 0;
chix->state = cs_prev_conn;
chix->id.sid = ~0L;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
}
if(piiu->chidlist.count){
ca_signal(ECA_DISCONN,piiu->host_name_str);
}
/*
* remove IOC from the hash table
*/
pNode = (caAddrNode *) piiu->destAddr.node.next;
assert(pNode);
removeBeaconInetAddr(&pNode->destAddr.inetAddr.sin_addr);
/*
* call their connection handler as required
*/
chix = (chid) &piiu->chidlist.node.next;
while(chix = (chid) chix->node.next){
LOCKEVENTS;
if(chix->pConnFunc){
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc)(args);
}
if(chix->pAccessRightsFunc){
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc)(args);
/*
* Mark all of their channels disconnected
* prior to calling handlers incase the
* handler tries to use a channel before
* I mark it disconnected.
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
chix->type = TYPENOTCONN;
chix->count = 0;
chix->state = cs_prev_conn;
chix->id.sid = ~0L;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
/*
* try to reconnect
*/
chix->retry = 0;
}
UNLOCKEVENTS;
chix->piiu = piiuCast;
}
if (piiu->chidlist.count) {
ca_signal (ECA_DISCONN,piiu->host_name_str);
}
/*
* call their connection handler as required
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
LOCKEVENTS;
if (chix->pConnFunc) {
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc) (args);
}
if (chix->pAccessRightsFunc) {
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc) (args);
}
UNLOCKEVENTS;
chix->piiu = piiuCast;
}
/*
* move all channels to the broadcast IIU
*
* if we loose the broadcast IIU its a severe error
*/
assert (piiuCast);
ellConcat (&piiuCast->chidlist, &piiu->chidlist);
assert (piiu->chidlist.count==0);
}
/*
* move all channels to the broadcast IIU
*
* if we loose the broadcast IIU its a severe error
* Try to reconnect
*/
assert(piiuCast);
ellConcat(&piiuCast->chidlist, &piiu->chidlist);
ca_static->ca_search_retry = 0;
assert(piiu->chidlist.count==0);
if(fd_register_func){
if (fd_register_func) {
LOCKEVENTS;
(*fd_register_func)(fd_register_arg, piiu->sock_chan, FALSE);
(*fd_register_func) (fd_register_arg, piiu->sock_chan, FALSE);
UNLOCKEVENTS;
}
status = socket_close(piiu->sock_chan);
assert(status == 0);
status = socket_close (piiu->sock_chan);
assert (status == 0);
/*
* free message body cache
*/
if(piiu->pCurData){
free(piiu->pCurData);
if (piiu->pCurData) {
free (piiu->pCurData);
piiu->pCurData = NULL;
piiu->curDataMax = 0;
}
piiu->sock_chan = -1;
piiu->sock_chan = INVALID_SOCKET;
ellFree(&piiu->destAddr);
ellFree (&piiu->destAddr);
free (piiu);
free(piiu);
UNLOCK;
}
@@ -1179,7 +1264,7 @@ void close_ioc(struct ioc_in_use *piiu)
*
* NOTE: potential race condition here can result
* in two copies of the repeater being spawned
* however the repeater detectes this, prints a message,
* however the repeater detects this, prints a message,
* and lets the other task start the repeater.
*
* QUESTION: is there a better way to test for a port in use?
@@ -1198,12 +1283,11 @@ void close_ioc(struct ioc_in_use *piiu)
*/
int repeater_installed()
{
int status;
int sock;
struct sockaddr_in bd;
int true = 1;
int installed = FALSE;
int status;
SOCKET sock;
struct sockaddr_in bd;
int true = 1;
int installed = FALSE;
LOCK;
@@ -1211,7 +1295,7 @@ int repeater_installed()
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if(sock == ERROR){
if(sock == INVALID_SOCKET) {
UNLOCK;
return installed;
}
@@ -1219,7 +1303,7 @@ int repeater_installed()
memset((char *)&bd,0,sizeof bd);
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(CA_CLIENT_PORT);
bd.sin_port = htons(ca_static->ca_repeater_port);
status = bind( sock,
(struct sockaddr *) &bd,
sizeof bd);
@@ -1417,31 +1501,25 @@ unsigned long cacRingBufferWriteSize(struct ca_buffer *pBuf, int contiguous)
*
* o Indicates failure by setting ptr to nill
*
* o Calls non posix gethostname()
*
* o We want the full domain name however neither
* gethostbyname() or gethostname() appear to provide it
* under SUNOS.
* o Calls non posix gethostbyname() so that we get DNS style names
* (gethostbyname() should be available with most BSD sock libs)
*
* vxWorks user may need to configure a DNS format name for the
* vxWorks user will need to configure a DNS format name for the
* host name if they wish to be cnsistent with UNIX and VMS hosts.
*
*/
char *localHostName()
{
int size;
int status;
char nameBuf[MAXHOSTNAMELEN];
char *pName;
char *pTmp;
int size;
int status;
char pName[MAXHOSTNAMELEN];
char *pTmp;
status = gethostname(nameBuf, sizeof(nameBuf));
status = gethostname(pName, sizeof(pName));
if(status){
return NULL;
}
pName = nameBuf;
size = strlen(pName)+1;
pTmp = malloc(size);
if(!pTmp){
@@ -1459,7 +1537,7 @@ char *localHostName()
* caAddConfiguredAddr()
*/
void caAddConfiguredAddr(ELLLIST *pList, ENV_PARAM *pEnv,
int socket, int port)
SOCKET socket, int port)
{
caAddrNode *pNode;
ENV_PARAM list;
@@ -1572,3 +1650,36 @@ void caPrintAddrList(ELLLIST *pList)
}
}
/*
* caFetchPortConfig()
*/
unsigned caFetchPortConfig(ENV_PARAM *pEnv, unsigned defaultPort)
{
long longStatus;
long port;
longStatus = envGetLongConfigParam(pEnv, &port);
if (longStatus!=0) {
port = defaultPort;
ca_printf ("EPICS \"%s\" integer fetch failed\n", pEnv->name);
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, port);
}
/*
* Thus must be a server port that will fit in a signed
* short
*/
if (port <= IPPORT_USERRESERVED || port>SHRT_MAX) {
ca_printf ("EPICS \"%s\" out of range\n", pEnv->name);
/*
* Quit if the port is wrong due CA coding error
*/
assert (port != defaultPort);
port = defaultPort;
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, port);
}
return port;
}

View File

@@ -53,7 +53,27 @@
#ifndef INCiocinfh
#define INCiocinfh
static char *iocinfhSccsId = "$Id$";
#ifdef CA_GLBLSOURCE
# define GLBLTYPE
#else
# define GLBLTYPE extern
#endif
#ifdef __STDC__
# define VERSIONID(NAME,VERS) \
char *EPICS_CAS_VID_ ## NAME = VERS;
#else /*__STDC__*/
# define VERSIONID(NAME,VERS) \
char *EPICS_CAS_VID_/* */NAME = VERS;
#endif /*__STDC__*/
#ifdef CAC_VERSION_GLOBAL
# define HDRVERSIONID(NAME,VERS) VERSIONID(NAME,VERS)
#else /*CAC_VERSION_GLOBAL*/
# define HDRVERSIONID(NAME,VERS)
#endif /*CAC_VERSION_GLOBAL*/
HDRVERSIONID(iocinfh, "$Id$")
/*
* ANSI C includes
@@ -64,6 +84,7 @@ static char *iocinfhSccsId = "$Id$";
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <limits.h>
/*
@@ -97,7 +118,7 @@ static char *iocinfhSccsId = "$Id$";
# define NBBY 8 /* number of bits per byte */
#endif
#define SELECT_POLL 50000 /* units micro-sec */
#define MSEC_PER_SEC 1000
#define USEC_PER_SEC 1000000
/*
@@ -139,26 +160,38 @@ struct putCvrtBuf{
#define CA_DO_RECVS 2
struct pending_io_event{
ELLNODE node;
void (*io_done_sub)();
void *io_done_arg;
ELLNODE node;
void (*io_done_sub)();
void *io_done_arg;
};
typedef unsigned long ca_time;
typedef struct timeval ca_time;
#define LD_CA_TIME(FLOAT_TIME,PCATIME) \
((PCATIME)->tv_sec = (FLOAT_TIME), \
(PCATIME)->tv_usec = ((FLOAT_TIME)-(PCATIME)->tv_sec)*USEC_PER_SEC)
/*
* dont adjust
*/
#define CA_CURRENT_TIME 0
#ifdef CA_GLBLSOURCE
const ca_time CA_CURRENT_TIME = {0,0};
#else /*CA_GLBLSOURCE*/
extern const ca_time CA_CURRENT_TIME;
#endif /*CA_GLBLSOURCE*/
/*
* these control the duration and period of name resolution
* broadcasts
*
* MAXCONNTRIES must be less than the number of bits in type long
*/
#define MAXCONNTRIES 60 /* N conn retries on unchanged net */
#define CA_RECAST_DELAY 1 /* initial int sec to next recast */
#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */
#define CA_RECAST_PERIOD 5 /* ul on retry period long term */
#define MAXCONNTRIES 30 /* N conn retries on unchanged net */
#define SELECT_POLL (0.1) /* units sec - polls into recast */
#define CA_RECAST_DELAY (0.1) /* initial delay to next recast (sec) */
#define CA_RECAST_PORT_MASK 0xff /* random retry interval off port */
#define CA_RECAST_PERIOD (5.0) /* ul on retry period long term (sec) */
/*
* these two control the period of connection verifies
@@ -166,15 +199,21 @@ typedef unsigned long ca_time;
* long we will wait for an echo reply before we
* give up and flag the connection for disconnect
* - CA_ECHO_TIMEOUT.
*
* CA_CONN_VERIFY_PERIOD is normally obtained from an
* EPICS environment variable.
*/
#define CA_ECHO_TIMEOUT 5 /* disconn if no echo reply tmo */
#define CA_CONN_VERIFY_PERIOD 30 /* how often to request echo */
#define CA_ECHO_TIMEOUT 5.0 /* (sec) disconn no echo reply tmo */
#define CA_CONN_VERIFY_PERIOD 30.0 /* (sec) how often to request echo */
/*
* only used when communicating with old servers
*/
#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */
#define N_REPEATER_TRIES_PRIOR_TO_MSG 50
#define REPEATER_TRY_PERIOD (0.1)
#ifdef vxWorks
typedef struct caclient_put_notify{
ELLNODE node;
@@ -192,10 +231,12 @@ typedef struct caclient_put_notify{
/*
* ! lock needs to be applied when an id is allocated !
*/
#define CLIENT_ID_WIDTH 20 /* bits (1 million before rollover) */
#define CLIENT_HASH_TBL_SIZE (1<<12)
#define CLIENT_ID_WIDTH 28 /* bits */
#define CLIENT_ID_COUNT (1<<CLIENT_ID_WIDTH)
#define CLIENT_ID_MASK (CLIENT_ID_COUNT-1)
#define CLIENT_ID_ALLOC (CLIENT_ID_MASK&nextBucketId++)
#define CLIENT_FAST_ID_ALLOC (CLIENT_ID_MASK&nextFastBucketId++)
#define CLIENT_SLOW_ID_ALLOC (CLIENT_ID_MASK&nextSlowBucketId++)
#define SEND_RETRY_COUNT_INIT 100
@@ -215,12 +256,11 @@ typedef struct caclient_put_notify{
(ca_static->ca_fd_register_func)
#define fd_register_arg (ca_static->ca_fd_register_arg)
#define post_msg_active (ca_static->ca_post_msg_active)
#define send_msg_active (ca_static->ca_send_msg_active)
#define sprintf_buf (ca_static->ca_sprintf_buf)
#define pBucket (ca_static->ca_pBucket)
#define nextBucketId (ca_static->ca_nextBucketId)
#define readch (ca_static->ca_readch)
#define writech (ca_static->ca_writech)
#define pSlowBucket (ca_static->ca_pSlowBucket)
#define pFastBucket (ca_static->ca_pFastBucket)
#define nextSlowBucketId (ca_static->ca_nextSlowBucketId)
#define nextFastBucketId (ca_static->ca_nextFastBucketId)
#if defined(vxWorks)
# define io_done_sem (ca_static->ca_io_done_sem)
@@ -287,26 +327,27 @@ typedef struct ioc_in_use{
ELLNODE node;
ELLLIST chidlist; /* chans on this connection */
ELLLIST destAddr;
struct ca_static *pcas;
int sock_chan;
int sock_proto;
unsigned minor_version_number;
unsigned contiguous_msg_count;
struct ca_buffer send;
struct ca_buffer recv;
struct extmsg curMsg;
unsigned curMsgBytes;
void *pCurData;
unsigned long curDataMax;
unsigned long curDataBytes;
ca_time timeAtLastRecv;
ca_time timeAtSendBlock;
ca_time timeAtEchoRequest;
unsigned long curDataMax;
unsigned long curDataBytes;
struct ca_buffer send;
struct ca_buffer recv;
struct extmsg curMsg;
struct ca_static *pcas;
void *pCurData;
void (*sendBytes)(struct ioc_in_use *);
void (*recvBytes)(struct ioc_in_use *);
void (*procInput)(struct ioc_in_use *);
SOCKET sock_chan;
int sock_proto;
unsigned minor_version_number;
unsigned contiguous_msg_count;
unsigned curMsgBytes;
unsigned read_seq;
unsigned cur_read_seq;
unsigned minfreespace;
char host_name_str[32];
/*
@@ -327,12 +368,21 @@ typedef struct beaconHashEntry{
struct beaconHashEntry *pNext;
IIU *piiu;
struct in_addr inetAddr;
int timeStamp;
int averagePeriod;
ca_time timeStamp;
ca_real averagePeriod;
}bhe;
/*
* This struct allocated off of a free list
* so that the select() ctx is thread safe
*/
typedef struct {
ELLNODE node;
fd_set readMask;
fd_set writeMask;
}caFDInfo;
struct ca_static{
IIU *ca_piiuCast;
ELLLIST ca_iiuList;
ELLLIST ca_ioeventlist;
ELLLIST ca_free_event_list;
@@ -343,44 +393,54 @@ struct ca_static{
ELLLIST activeCASGOP;
ELLLIST freeCASGOP;
ELLLIST putCvrtBuf;
long ca_pndrecvcnt;
void (*ca_exception_func)();
void *ca_exception_arg;
void (*ca_connection_func)();
void *ca_connection_arg;
void (*ca_fd_register_func)();
void *ca_fd_register_arg;
short ca_exit_in_progress;
unsigned short ca_post_msg_active;
short ca_repeater_contacted;
unsigned short ca_send_msg_active;
char ca_sprintf_buf[256];
BUCKET *ca_pBucket;
unsigned long ca_nextBucketId;
bhe *ca_beaconHash[BHT_INET_ADDR_MASK+1];
char *ca_pUserName;
char *ca_pHostName;
unsigned ca_conn_n_tries;
ELLLIST fdInfoFreeList;
ELLLIST fdInfoList;
ca_time ca_conn_next_retry;
ca_time ca_conn_retry_delay;
fd_set ca_readch;
fd_set ca_writech;
ca_time ca_last_repeater_try;
ca_real ca_connectTMO;
long ca_pndrecvcnt;
unsigned long ca_nextSlowBucketId;
unsigned long ca_nextFastBucketId;
IIU *ca_piiuCast;
void (*ca_exception_func)
(struct exception_handler_args);
void *ca_exception_arg;
void (*ca_connection_func)
(struct connection_handler_args);
void *ca_connection_arg;
void (*ca_fd_register_func)
(void *, SOCKET, int);
void *ca_fd_register_arg;
char *ca_pUserName;
char *ca_pHostName;
BUCKET *ca_pSlowBucket;
BUCKET *ca_pFastBucket;
bhe *ca_beaconHash[BHT_INET_ADDR_MASK+1];
unsigned ca_repeater_tries;
unsigned ca_search_retry; /* search retry seq number */
unsigned short ca_server_port;
unsigned short ca_repeater_port;
char ca_sprintf_buf[256];
unsigned ca_post_msg_active:1;
unsigned ca_manage_conn_active:1;
unsigned ca_repeater_contacted:1;
#if defined(vxWorks)
SEM_ID ca_io_done_sem;
SEM_ID ca_blockSem;
void *ca_evuser;
SEM_ID ca_client_lock;
SEM_ID ca_event_lock; /* dont allow events to preempt */
SEM_ID ca_putNotifyLock;
int ca_tid;
ELLLIST ca_local_chidlist;
ELLLIST ca_dbfree_ev_list;
ELLLIST ca_lcl_buff_list;
ELLLIST ca_putNotifyQue;
int ca_event_tid;
unsigned ca_local_ticks;
int recv_tid;
ELLLIST ca_taskVarList;
void *ca_evuser;
int ca_event_tid;
int ca_tid;
int recv_tid;
unsigned ca_local_ticks;
#endif
};
@@ -419,22 +479,9 @@ typedef struct{
/*
GLOBAL VARIABLES
There should only be one - add others to ca_static above -joh
*/
#ifdef CA_GLBLSOURCE
# ifdef VAXC
# define GLBLTYPE globaldef
# else
# define GLBLTYPE
# endif
#else
# ifdef VAXC
# define GLBLTYPE globalref
# else
# define GLBLTYPE extern
# endif
#endif
* GLOBAL VARIABLES
* There should only be one - add others to ca_static above -joh
*/
GLBLTYPE
struct ca_static *ca_static;
@@ -444,31 +491,30 @@ struct ca_static *ca_static;
*
*/
void cac_send_msg();
void cac_mux_io(struct timeval *ptimeout);
int repeater_installed();
void search_msg(chid chix, int reply_type);
int ca_request_event(evid monix);
void ca_busy_message(struct ioc_in_use *piiu);
void ca_ready_message(struct ioc_in_use *piiu);
void noop_msg(struct ioc_in_use *piiu);
void echo_request(struct ioc_in_use *piiu);
void issue_claim_channel(struct ioc_in_use *piiu, chid pchan);
void issue_identify_client(struct ioc_in_use *piiu);
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 flow_control(struct ioc_in_use *piiu);
int broadcast_addr(struct in_addr *pcastaddr);
int local_addr(int s, struct sockaddr_in *plcladdr);
void ca_repeater();
void cac_recv_task(int tid);
void cac_io_done(int lock);
void ca_sg_init(void);
void ca_sg_shutdown(struct ca_static *ca_temp);
int cac_select_io(struct timeval *ptimeout, int flags);
void cac_send_msg(void);
void cac_mux_io(struct timeval *ptimeout);
int repeater_installed(void);
int search_msg(chid chix, int reply_type);
int ca_request_event(evid monix);
void ca_busy_message(struct ioc_in_use *piiu);
void ca_ready_message(struct ioc_in_use *piiu);
void noop_msg(struct ioc_in_use *piiu);
int echo_request(struct ioc_in_use *piiu, ca_time *pCurrentTime);
void issue_claim_channel(struct ioc_in_use *piiu, chid pchan);
void issue_identify_client(struct ioc_in_use *piiu);
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 flow_control(struct ioc_in_use *piiu);
int broadcast_addr(struct in_addr *pcastaddr);
void ca_repeater(void);
void cac_recv_task(int tid);
void cac_io_done(int lock);
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,
@@ -481,8 +527,8 @@ int post_msg(
unsigned long blockSize
);
int alloc_ioc(
struct in_addr *pnet_addr,
struct ioc_in_use **ppiiu
struct in_addr *pnet_addr,
struct ioc_in_use **ppiiu
);
unsigned long cacRingBufferWrite(
struct ca_buffer *pRing,
@@ -502,26 +548,9 @@ unsigned long cacRingBufferReadSize(
struct ca_buffer *pBuf,
int contiguous);
void caSetupAddrList(
ELLLIST *pList,
int socket);
char *localUserName(void);
void caDiscoverInterfaces(
ELLLIST *pList,
int socket,
int port);
void caAddConfiguredAddr(
ELLLIST *pList,
ENV_PARAM *pEnv,
int socket,
int port);
void caPrintAddrList();
char *localUserName();
char *localHostName();
char *localHostName(void);
int create_net_chan(
struct ioc_in_use **ppiiu,
@@ -529,30 +558,39 @@ struct in_addr *pnet_addr, /* only used by TCP connections */
int net_proto
);
int ca_check_for_fp();
int ca_check_for_fp(void);
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);
int cac_setup_recv_thread(IIU *piiu);
void close_ioc(IIU *piiu);
void notify_ca_repeater();
void cac_clean_iiu_list();
void notify_ca_repeater(void);
void cac_clean_iiu_list(void);
void ca_process_input_queue();
void cac_flush_internal();
void cac_block_for_io_completion();
void cac_block_for_sg_completion();
void ca_process_input_queue(void);
void cac_flush_internal(void);
void cac_block_for_io_completion(struct timeval *pTV);
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV);
void os_specific_sg_create(CASG *pcasg);
void os_specific_sg_delete(CASG *pcasg);
void os_specific_sg_io_complete(CASG *pcasg);
int cac_os_depen_init(struct ca_static *pcas);
void ca_process_exit(struct ca_static *ca_temp);
int cac_add_task_variable(struct ca_static *);
void ca_spawn_repeater();
void cac_os_depen_exit (struct ca_static *pcas);
void ca_process_exit();
void ca_spawn_repeater(void);
typedef void CACVRTFUNC(void *pSrc, void *pDest, int hton, unsigned long count);
void cac_gettimeval(struct timeval *pt);
/* returns A - B in floating secs */
ca_real cac_time_diff(ca_time *pTVA, ca_time *pTVB);
/* returns A + B in integer secs & integer usec */
ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB);
void caIOBlockFree(evid pIOBlock);
void clearChannelResources(unsigned id);
/*
* !!KLUDGE!!
@@ -561,6 +599,7 @@ typedef void CACVRTFUNC(void *pSrc, void *pDest, int hton, unsigned long count);
* to include both dbAccess.h and db_access.h at the
* same time.
*/
#define M_dbAccess (501 <<16) /*Database Access Routines */
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
#endif /* this must be the last line in this file */

View File

@@ -19,33 +19,61 @@
* .07 041194 joh New command added for CA V4.2 - access rights
*
* .08 050594 joh New command added for CA V4.3 - echo request
*
* .09 050594 joh New command added for CA V4.3 - repeater fanout register
*
* .10 050594 joh New command added for CA V4.3 - wakeup the server
*/
#define __IOCMSG__
static char *iocmsghSccsId = "$Id$ CA version 4.3";
HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
/* TCP/UDP port number (bumped each protocol change) */
#define CA_PROTOCOL_VERSION 4
#define CA_MINOR_VERSION 3
#define CA_MINOR_VERSION 4
#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)
#else
#define CA_V44(MAJOR,MINOR) ((MINOR)>=4)
#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 )
#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 )
#endif
/*
* NOTE: These port numbers are only used if the CA repeater and
* CA server port numbers cant be obtained from the EPICS
* environment variables "EPICS_CA_REPEATER_PORT" and
* "EPICS_CA_SERVER_PORT"
*/
#define CA_PORT_BASE IPPORT_USERRESERVED + 56
#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2)
#define CA_CLIENT_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
#define CA_REPEATER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
#define MAX_UDP 1024
#define MAX_TCP (MAX_UDP*16) /* so waveforms fit */
#define MAX_MSG_SIZE (MAX_TCP) /* the larger of tcp and udp max */
/*
* architecture independent types
*
* (so far this works on all archs we have ported to)
*/
typedef unsigned short ca_uint16_t;
typedef unsigned int ca_uint32_t;
typedef float ca_float32_t;
/* values for m_cmmd */
#define IOC_NOOP 0 /* do nothing, but verify TCP */
#define IOC_EVENT_ADD 1 /* add an event */
@@ -54,6 +82,7 @@ static char *iocmsghSccsId = "$Id$ CA version 4.3";
#define IOC_WRITE 4 /* write a channel value */
#define IOC_SNAPSHOT 5 /* snapshot of the system */
#define IOC_SEARCH 6 /* IOC channel search */
/* 7 */
#define IOC_EVENTS_OFF 8 /* flow control */
#define IOC_EVENTS_ON 9 /* flow control */
#define IOC_READ_SYNC 10 /* purge old reads */
@@ -62,6 +91,7 @@ static char *iocmsghSccsId = "$Id$ CA version 4.3";
#define IOC_RSRV_IS_UP 13 /* CA server has joined the net */
#define IOC_NOT_FOUND 14 /* channel not found */
#define IOC_READ_NOTIFY 15 /* add a one shot event */
/* 16 */
#define REPEATER_CONFIRM 17 /* registration confirmation */
#define IOC_CLAIM_CIU 18 /* client claims resource in server */
#define IOC_WRITE_NOTIFY 19 /* notify after write chan value */
@@ -69,6 +99,8 @@ static char *iocmsghSccsId = "$Id$ CA version 4.3";
#define IOC_HOST_NAME 21 /* CA V4.1 identify client */
#define IOC_ACCESS_RIGHTS 22 /* CA V4.2 asynch access rights chg */
#define IOC_ECHO 23 /* CA V4.3 connection verify */
#define REPEATER_REGISTER 24 /* registr for repeater fan out */
#define IOC_SIGNAL 25 /* knock the server out of select */
/*
* for use with search and not_found (if search fails and
@@ -98,12 +130,8 @@ static char *iocmsghSccsId = "$Id$ CA version 4.3";
#define CA_ACCESS_RIGHT_WRITE (1<<1)
/*
* Required Message Alignment
*
* Determined by the architecture with the most restrictive
* alignment requirements (currently the SPARC).
*
* octal rounding
* All structures passed in the protocol must have individual
* fields aligned on natural boundaries.
*
* NOTE: all structures declared in this file must have a
* byte count which is evenly divisible by 8 for the SPARC.
@@ -114,25 +142,25 @@ static char *iocmsghSccsId = "$Id$ CA version 4.3";
* the common part of each message sent/recv by the
* CA server.
*/
struct extmsg {
unsigned short m_cmmd; /* operation to be performed */
unsigned short m_postsize; /* size of message extension */
unsigned short m_type; /* operation data type */
unsigned short m_count; /* operation data count */
unsigned long m_cid; /* channel identifier */
unsigned long m_available; /* undefined message location for use
typedef struct extmsg {
ca_uint16_t m_cmmd; /* operation to be performed */
ca_uint16_t m_postsize; /* size of message extension */
ca_uint16_t m_type; /* operation data type */
ca_uint16_t m_count; /* operation data count */
ca_uint32_t m_cid; /* channel identifier */
ca_uint32_t m_available; /* undefined message location for use
* by client processes */
};
}caHdr;
/*
* for monitor (event) message extension
*/
struct mon_info{
float m_lval; /* low delta */
float m_hval; /* high delta */
float m_toval; /* period btween samples */
unsigned short m_mask; /* event select mask */
unsigned short m_pad; /* extend to 32 bits */
ca_float32_t m_lval; /* low delta */
ca_float32_t m_hval; /* high delta */
ca_float32_t m_toval; /* period btween samples */
ca_uint16_t m_mask; /* event select mask */
ca_uint16_t m_pad; /* extend to 32 bits */
};
struct monops { /* monitor req opi to ioc */

View File

@@ -29,7 +29,7 @@ printf("%x\n", net_addr.s_addr);
/* the above seems to be broken ? */
ent = gethostbyaddr(&net, sizeof(net_addr), AF_INET);
ent = gethostbyaddr(&addr, sizeof(net_addr), AF_INET);
if(ent)
printf("%s\n", ent->h_name);

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id$
*
* N E T _ C O N V E R T . H
* MACROS for rapid conversion between HOST data formats and those used
@@ -10,151 +10,63 @@
* to prevent a reseved operand fault.
*
* joh 03-16-94 Added double fp
* joh 11-02-94 Moved all fp cvrt to functions in
* convert.c
*
*
*/
/************************************************************************/
/* So byte swapping can be performed in line for efficiency */
/* (WINTCP has library routines with the same same functionality */
/* but more than twice the delay) JH */
/* WARNING: WILL NOT WORK ON TYPES FLOAT OR DOUBLE */
/* (use *(long *)& to perform type convert without reformat) */
/************************************************************************/
#ifdef LITTLE_ENDIAN
# define ntohs(SHORT)\
((unsigned short)(((short)(SHORT))<<8 | ((unsigned short)(SHORT))>>8 ))
# define htons(SHORT)\
((unsigned short)(((short)(SHORT))<<8 | ((unsigned short)(SHORT))>>8 ))
#ifdef CA_LITTLE_ENDIAN
# ifndef ntohs
# define ntohs(SHORT)\
( ((SHORT) & 0x00ff) << 8 | ((SHORT) & 0xff00) >> 8 )
# endif
# ifndef htons
# define htons(SHORT)\
( ((SHORT) & 0x00ff) << 8 | ((SHORT) & 0xff00) >> 8 )
# endif
#else
# ifndef ntohs
# define ntohs(SHORT) (SHORT)
# endif
# ifndef htons
# define htons(SHORT) (SHORT)
# endif
# ifndef ntohs
# define ntohs(SHORT) (SHORT)
# endif
# ifndef htons
# define htons(SHORT) (SHORT)
# endif
#endif
#ifdef LITTLE_ENDIAN
# define ntohl(LONG)\
(\
((long)(LONG))<<24 |\
((unsigned long)(LONG))>>24 |\
(((long)(LONG))&0x00ff0000)>>8 |\
(((long)(LONG))&0x0000ff00)<<8\
)
# define htonl(LONG)\
(\
((long)(LONG))<<24 |\
((unsigned long)(LONG))>>24 |\
(((long)(LONG))&0x00ff0000)>>8 |\
(((long)(LONG))&0x0000ff00)<<8\
)
#else
# ifndef ntohl
# define ntohl(LONG) (LONG)
# endif
# ifndef htonl
# define htonl(LONG) (LONG)
# endif
#ifdef CA_LITTLE_ENDIAN
# ifndef ntohl
# define ntohl(LONG)\
(\
((LONG) & 0xff000000) >> 24 |\
((LONG) & 0x000000ff) << 24 |\
((LONG) & 0x0000ff00) << 8 |\
((LONG) & 0x00ff0000) >> 8\
)
# endif
# ifndef htonl
# define htonl(LONG)\
(\
((LONG) & 0x000000ff) << 24 |\
((LONG) & 0xff000000) >> 24 |\
((LONG) & 0x00ff0000) >> 8 |\
((LONG) & 0x0000ff00) << 8\
)
# endif
# else
# ifndef ntohl
# define ntohl(LONG) (LONG)
# endif
# ifndef htonl
# define htonl(LONG) (LONG)
# endif
#endif
/************************************************************************/
/* So float convert can be performed in line */
/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */
/************************************************************************/
struct ieeeflt{
unsigned mant :23;
unsigned exp :8;
unsigned sign :1;
};
/* Exponent sign bias */
#define IEEE_SB 127
/* Conversion Range */
/* -126<exp<127 with mantissa of form 1.mant */
#define EXPMINIEEE -126 /* min for norm # IEEE exponent */
#ifdef MIT_FLOAT
struct mitflt{
unsigned mant1 :7;
unsigned exp :8;
unsigned sign :1;
unsigned mant2 :16;
};
/* Exponent sign bias */
# define MIT_SB 129
/* Conversion Ranges */
/* -128<exp<126 with mantissa of form 1.mant */
# define EXPMAXMIT 126 /* max MIT exponent */
# define EXPMINMIT -128 /* min MIT exponent */
/* passed by ref until beter alternative found */
/* (this includes mapping of fringe reals to zero or infinity) */
/* (byte swaps included in conversion */
# define htonf(MIT,IEEE)\
{\
long exp,mant,sign;\
sign = ((struct mitflt *) (MIT))->sign;\
if( (short)((struct mitflt *) (MIT))->exp < EXPMINIEEE + MIT_SB){\
exp = 0;\
mant = 0;\
sign = 0;\
}\
else{\
exp = (short)((struct mitflt *) (MIT))->exp-MIT_SB+IEEE_SB;\
mant = (((struct mitflt *) (MIT))->mant1<<16) |\
((struct mitflt *) (MIT))->mant2;\
}\
((struct ieeeflt *) (IEEE))->mant = mant;\
((struct ieeeflt *) (IEEE))->exp = exp;\
((struct ieeeflt *) (IEEE))->sign = sign;\
*(long *)(IEEE) = ntohl(*(long*)(IEEE));\
}
/*
* sign must be forced to zero if the exponent is zero to prevent a reserved
* operand fault- joh 9-13-90
*/
# define ntohf(IEEE,MIT)\
{\
long exp,mant2,mant1,sign;\
*(long *)(IEEE) = htonl(*(long*)(IEEE));\
if( (short)((struct ieeeflt *) (IEEE))->exp > EXPMAXMIT + IEEE_SB){\
sign = ((struct ieeeflt *) (IEEE))->sign;\
exp = EXPMAXMIT + MIT_SB;\
mant2 = ~0;\
mant1 = ~0;\
}\
else if( ((struct ieeeflt *) (IEEE))->exp == 0){\
sign = 0;\
exp = 0;\
mant2 = 0;\
mant1 = 0;\
}\
else{\
sign = ((struct ieeeflt *) (IEEE))->sign;\
exp = ((struct ieeeflt *) (IEEE))->exp+MIT_SB-IEEE_SB;\
mant2 = ((struct ieeeflt *) (IEEE))->mant;\
mant1 = ((struct ieeeflt *) (IEEE))->mant>>(unsigned)16;\
}\
((struct mitflt *) (MIT))->exp = exp;\
((struct mitflt *) (MIT))->mant2 = mant2;\
((struct mitflt *) (MIT))->mant1 = mant1;\
((struct mitflt *) (MIT))->sign = sign;\
}
#else
# define ntohf(NET,HOST) {*(float *)(HOST) = *(float *)(NET);}
# define htonf(HOST,NET) {*(float *)(NET) = *(float *)(HOST);}
#if !defined(MIT_FLOAT) && !defined(CA_LITTLE_ENDIAN)
#define htond(IEEEhost, IEEEnet) (*(double *)(IEEEnet) = *(double *)(IEEEhost))
#define ntohd(IEEEnet, IEEEhost) (*(double *)(IEEEhost) = *(double *)(IEEEnet))
#define htonf(IEEEhost, IEEEnet) (*(float *)(IEEEnet) = *(float *)(IEEEhost))
#define ntohf(IEEEnet, IEEEhost) (*(float *)(IEEEhost) = *(float *)(IEEEnet))
#endif

View File

@@ -1,5 +1,5 @@
/* netdb_depen.c */
/* $Id$ */
/* share/src/ca/$Id$ */
/*
* Author: Jeff Hill
* Date: 04-05-94
@@ -31,7 +31,7 @@
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include <ctype.h>

View File

@@ -23,6 +23,7 @@
* .10 joh 112092 removed the requirement that VMS locking
* pairs reside at the same C bracket level
* .11 GeG 120992 support VMS/UCX
* .12 CJM 130794 define MYERRNO properly for UCX
*
*/
@@ -92,7 +93,7 @@ static char *os_depenhSccsId = "$Id$";
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# define __TIME /* dont include VMS CC time.h under MULTINET */
# define __TIME_LOADED /* dont include VMS CC time.h under MULTINET */
# include <sys/time.h>
# include <tcp/errno.h>
# include <ssdef>
@@ -113,30 +114,64 @@ static char *os_depenhSccsId = "$Id$";
# define CA_OS_CONFIGURED
#endif /*VMS*/
#ifdef _WINDOWS
# include <errno.h>
# include <time.h>
# include <windows.h>
# include <winsock.h>
# define CA_OS_CONFIGURED
#endif /*_WINDOWS*/
#ifndef CA_OS_CONFIGURED
#error Please define one of vxWorks, UNIX or VMS
#endif
/*
* Set the flag "CONVERSION_REQUIRED" if the architechure is
* little endian or if the local floating point format isnt IEEE.
* Big endin architecture is assumed. Otherwise set "CA_LITTLE_ENDIAN".
*
* Big endin architecture is assumed. Otherwise set "LITTLE_ENDIAN".
*
* IEEE floating point architecture assumed. Set "MIT_FLOAT" if
* IEEE floating point architecture assumed. Set "CA_FLOAT_MIT" if
* appropriate. No other floating point formats currently
* supported.
*/
#ifdef VAX
#define CONVERSION_REQUIRED
#define MIT_FLOAT
#define LITTLE_ENDIAN
#if defined(VAX)
# define CA_FLOAT_MIT
# define CA_LITTLE_ENDIAN
#elif defined(_X86_)
# define CA_FLOAT_IEEE
# define CA_LITTLE_ENDIAN
#elif (defined(__ALPHA) || defined(__alpha)) && defined(VMS)
# define CA_FLOAT_MIT
# define CA_LITTLE_ENDIAN
#elif (defined(__ALPHA) || defined(__alpha)) && defined(UNIX)
# define CA_FLOAT_IEEE
# define CA_LITTLE_ENDIAN
#else
# define CA_FLOAT_IEEE
# define CA_BIG_ENDIAN
#endif
#ifdef __ALPHA
/*
* some architecture sanity checks
*/
#if defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN)
#error defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN)
#endif
#if !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN)
#error !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN)
#endif
#if defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT)
#error defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT)
#endif
#if !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT)
#error !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT)
#endif
/*
* CONVERSION_REQUIRED is set if either the byte order
* or the floating point does not match
*/
#if !defined(CA_FLOAT_IEEE) || !defined(CA_BIG_ENDIAN)
#define CONVERSION_REQUIRED
#define MIT_FLOAT
#define LITTLE_ENDIAN
#endif
#ifndef NULL
@@ -167,45 +202,57 @@ static char *os_depenhSccsId = "$Id$";
#define LOCAL static
#endif
/************************************************************************/
/* Provided to enforce one thread at a time code sections */
/* independent of a particular operating system */
/************************************************************************/
/* delay for when a poll is used */
/* NOTE: DELAYTICKS must be less than TICKSPERSEC */
#define DELAYTICKS 50L /* (adjust units below) */
#define TICKSPERSEC 1000L /* mili sec per sec */
/*
* order of ops is important here
*
* NOTE: large OS dependent SYFREQ might cause an overflow
*/
#define LOCALTICKS ((SYSFREQ*DELAYTICKS)/TICKSPERSEC)
#if defined(VMS)
# define LOCK
# define UNLOCK
# define LOCKEVENTS
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active!=0)
#endif
#if defined(vxWorks)
# define VXTASKIDNONE 0
# define LOCK semTake(client_lock, WAIT_FOREVER);
# define UNLOCK semGive(client_lock);
# define LOCKEVENTS \
# define VXTASKIDNONE 0
# define LOCK semTake(client_lock, WAIT_FOREVER);
# define UNLOCK semGive(client_lock);
# define LOCKEVENTS \
{semTake(event_lock, WAIT_FOREVER); event_tid=(int)taskIdCurrent;}
# define UNLOCKEVENTS \
# define UNLOCKEVENTS \
{event_tid=VXTASKIDNONE; semGive(event_lock);}
# define EVENTLOCKTEST \
# define EVENTLOCKTEST \
(((int)taskIdCurrent)==event_tid || ca_static->recv_tid == (int)taskIdCurrent)
# define VXTHISTASKID taskIdSelf()
# define abort() taskSuspend(VXTHISTASKID)
# define socket_close(S) close(S)
/* vxWorks still has a brain dead func proto for ioctl */
# define socket_ioctl(A,B,C) ioctl(A,B,(int)C)
# define MYERRNO (errnoGet()&0xffff)
# define POST_IO_EV semGive(io_done_sem)
# define SYSFREQ ((long) sysClkRateGet()) /* usually 60 Hz */
# define time(A) (tickGet()/SYSFREQ)
typedef int SOCKET;
# define INVALID_SOCKET (-1)
#endif
#if defined(UNIX)
# define LOCK
# define UNLOCK
# define LOCKEVENTS
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active!=0)
# define LOCK
# define UNLOCK
# define LOCKEVENTS
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active)
# define socket_close(S) close(S)
# define socket_ioctl(A,B,C) ioctl(A,B,C)
# define MYERRNO errno
# define POST_IO_EV
# define SYSFREQ 1000000L /* 1 MHz */
typedef int SOCKET;
# define INVALID_SOCKET (-1)
#endif
#ifdef vxWorks
# define VXTHISTASKID taskIdSelf()
# define abort() taskSuspend(VXTHISTASKID)
#endif
#if defined(VMS)
# if defined(WINTCP) /* Wallangong */
/* (the VAXC runtime lib has its own close */
@@ -216,73 +263,42 @@ static char *os_depenhSccsId = "$Id$";
# define socket_close(S) close(S)
# define socket_ioctl(A,B,C) ioctl(A,B,C)
# endif
#endif
#if defined(UNIX)
# define socket_close(S) close(S)
# define socket_ioctl(A,B,C) ioctl(A,B,C)
#endif
#if defined(vxWorks)
# define socket_close(S) close(S)
# define socket_ioctl(A,B,C) ioctl(A,B,C)
#endif
#if defined(VMS)
# ifdef WINTCP
extern int uerrno; /* Wallongong errno is uerrno */
extern int uerrno;
# define MYERRNO uerrno
# else
# ifdef UCX
# define MYERRNO errno
extern volatile int noshare errno ;
# else
# define MYERRNO socket_errno
# endif
# endif
#endif
#if defined(vxWorks)
# define MYERRNO (errnoGet()&0xffff)
#endif
#if defined(UNIX)
# define MYERRNO errno
#endif
#if defined(vxWorks)
# define POST_IO_EV semGive(io_done_sem)
#endif
#if defined(VMS)
# define POST_IO_EV
#endif
#if defined(UNIX)
# define POST_IO_EV
#endif
/* delay for when a poll is used */
/* NOTE: DELAYTICKS must be less than TICKSPERSEC */
#define DELAYTICKS 50L /* (adjust units below) */
#define TICKSPERSEC 1000L /* mili sec per sec */
/*
* order of ops is important here
*
* NOTE: large SYFREQ can cause an overflow
*/
# define LOCALTICKS ((SYSFREQ*DELAYTICKS)/TICKSPERSEC)
#if defined(VMS)
# define SYSFREQ 10000000L /* 10 MHz */
# define LOCK
# define UNLOCK
# define LOCKEVENTS
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active)
typedef int SOCKET;
# define INVALID_SOCKET (-1)
#endif
#if defined(vxWorks)
# define SYSFREQ ((long) sysClkRateGet()) /* usually 60 Hz */
# define time(A) (tickGet()/SYSFREQ)
#endif
#if defined(UNIX)
# define SYSFREQ 1000000L /* 1 MHz */
#endif
#ifdef _WINDOWS
# define IPPORT_USERRESERVED 5000
# define EWOULDBLOCK WSAEWOULDBLOCK
# define ENOBUFS WSAENOBUFS
# define ECONNRESET WSAECONNRESET
# define ETIMEDOUT WSAETIMEDOUT
# define EADDRINUSE WSAEADDRINUSE
# define socket_close(S) closesocket(S)
# define socket_ioctl(A,B,C) ioctlsocket(A,B,C)
# define MYERRNO WSAGetLastError()
# define POST_IO_EV
# define SYSFREQ 1000000L /* 1 MHz */
#endif /*_WINDOWS*/
#endif

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id$
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
@@ -45,6 +45,22 @@
#include "iocinf.h"
/*
* cac_gettimeval
*/
void cac_gettimeval(struct timeval *pt)
{
struct timezone tz;
int status;
/*
* Not POSIX but available on most of the systems that we use
*/
status = gettimeofday(pt, &tz);
assert(status == 0);
}
/*
* CAC_MUX_IO()
@@ -61,14 +77,15 @@ void cac_mux_io(struct timeval *ptimeout)
int newInput;
struct timeval timeout;
if(!ca_static->ca_repeater_contacted){
notify_ca_repeater();
}
cac_clean_iiu_list();
timeout = *ptimeout;
do{
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
newInput = FALSE;
do{
count = cac_select_io(
@@ -83,27 +100,35 @@ void cac_mux_io(struct timeval *ptimeout)
while(count>0);
ca_process_input_queue();
}
while(newInput);
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
}
log_time(char *pStr)
{
static struct timeval time;
struct timeval newtime;
struct timezone tz;
ca_real diff;
int status;
status = gettimeofday(&newtime, &tz);
assert(status==0);
diff = cac_time_diff(&newtime, &time);
printf("Expired %f - %s\n", diff, pStr);
time = newtime;
}
/*
* cac_block_for_io_completion()
*/
void cac_block_for_io_completion()
void cac_block_for_io_completion(struct timeval *pTV)
{
struct timeval itimeout;
itimeout.tv_usec = SELECT_POLL%USEC_PER_SEC;
itimeout.tv_sec = SELECT_POLL/USEC_PER_SEC;
cac_mux_io(&itimeout);
cac_mux_io(pTV);
}
@@ -126,14 +151,9 @@ void os_specific_sg_delete(CASG *pcasg)
}
void cac_block_for_sg_completion(CASG *pcasg)
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
struct timeval itimeout;
itimeout.tv_usec = SELECT_POLL%USEC_PER_SEC;
itimeout.tv_sec = SELECT_POLL/USEC_PER_SEC;
cac_mux_io(&itimeout);
cac_mux_io(pTV);
}
@@ -152,7 +172,9 @@ int cac_add_task_variable(struct ca_static *ca_temp)
*/
int cac_os_depen_init(struct ca_static *pcas)
{
int status;
int status;
ca_static = pcas;
/*
* dont allow disconnect to terminate process
@@ -163,7 +185,22 @@ int cac_os_depen_init(struct ca_static *pcas)
*/
signal(SIGPIPE,SIG_IGN);
return ECA_NORMAL;
status = ca_os_independent_init ();
return status;
}
/*
* cac_os_depen_exit ()
*/
void cac_os_depen_exit (struct ca_static *pcas)
{
ca_static = pcas;
ca_process_exit();
ca_static = NULL;
free ((char *)pcas);
}
@@ -245,17 +282,6 @@ void ca_spawn_repeater()
}
/*
* Setup recv thread
* (OS dependent)
*/
int cac_setup_recv_thread(IIU *piiu)
{
return ECA_NORMAL;
}
/*
* ca_printf()

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* REPEATER.C
*
* CA broadcast repeater
*
@@ -60,7 +60,7 @@
*
*/
static char *sccsId = "$Id$";
static char *sccsId = "@(#)$Id$";
#include "iocinf.h"
@@ -77,7 +77,9 @@ static ELLLIST client_list;
static char buf[MAX_UDP];
LOCAL int clean_client(struct one_client *pclient, int sock);
LOCAL int clean_client(struct one_client *pclient);
LOCAL void register_new_client(SOCKET sock, struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom);
/*
@@ -90,8 +92,7 @@ void ca_repeater()
{
int status;
int size;
int sock;
int bindsock;
SOCKET sock;
int true = 1;
struct sockaddr_in from;
struct sockaddr_in bd;
@@ -99,6 +100,11 @@ void ca_repeater()
int from_size = sizeof from;
struct one_client *pclient;
struct one_client *pnxtclient;
short port;
port = caFetchPortConfig(
&EPICS_CA_REPEATER_PORT,
CA_REPEATER_PORT);
ellInit(&client_list);
@@ -106,18 +112,13 @@ void ca_repeater()
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
assert(sock >= 0);
assert(sock != INVALID_SOCKET);
/* allocate a socket */
bindsock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
assert(bindsock >= 0);
memset((char *)&bd,0,sizeof(bd));
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(CA_CLIENT_PORT);
bd.sin_port = htons(port);
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status<0){
if(MYERRNO != EADDRINUSE){
@@ -149,91 +150,81 @@ void ca_repeater()
#endif
while(TRUE){
struct extmsg *pMsg;
size = recvfrom(
sock,
buf,
sizeof buf,
0,
(struct sockaddr *)&from,
&from_size);
if(size > 0){
if(from.sin_addr.s_addr != local.sin_addr.s_addr)
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = (struct one_client *)
pclient->node.next){
status = sendto(
sock,
buf,
size,
0,
(struct sockaddr *)&pclient->from,
sizeof pclient->from);
if(status < 0){
ca_printf("CA Repeater: fanout err %s\n",
strerror(MYERRNO));
}
#ifdef DEBUG
ca_printf("Sent\n");
#endif
}
}
else if(size == 0){
struct extmsg confirm;
/*
* If this is a processor local message then add to
* the list of clients to repeat to if not there
* already
*/
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = (struct one_client *)
pclient->node.next)
if(from.sin_port == pclient->from.sin_port)
break;
if(!pclient){
pclient = (struct one_client *)
calloc(1,sizeof *pclient);
if(pclient){
pclient->from = from;
ellAdd( &client_list,
&pclient->node);
#ifdef DEBUG
ca_printf(
"Added %x %d\n",
from.sin_port, size);
#endif
}
}
memset((char *)&confirm, 0, sizeof confirm);
confirm.m_cmmd = htons(REPEATER_CONFIRM);
confirm.m_available = local.sin_addr.s_addr;
status = sendto(
sock,
(char *)&confirm,
sizeof confirm,
0,
(struct sockaddr *)&from, /* back to sender */
sizeof from);
if(status != sizeof confirm){
ca_printf("CA Repeater: confirm err %s\n",
strerror(MYERRNO));
}
}
else{
buf,
sizeof(buf),
0,
(struct sockaddr *)&from,
&from_size);
if(size < 0){
ca_printf("CA Repeater: recv err %s\n",
strerror(MYERRNO));
}
/* remove any dead wood prior to pending */
pMsg = (struct extmsg *) buf;
/*
* both zero leng message and a registartion message
* will register a new client
*/
if(size >= sizeof(*pMsg)){
if(ntohs(pMsg->m_cmmd) == REPEATER_REGISTER){
register_new_client(sock, &local, &from);
/*
* strip register client message
*/
pMsg++;
size -= sizeof(*pMsg);
}
}
else if(size == 0){
register_new_client(sock, &local, &from);
}
/*
* size may have been adjusted above
*/
if(size){
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = (struct one_client *)
pclient->node.next){
/*
* 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));
}
#ifdef DEBUG
ca_printf("Sent\n");
#endif
}
}
/*
* remove any dead wood prior to pending
*/
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
@@ -241,44 +232,129 @@ void ca_repeater()
/* do it now in case item deleted */
pnxtclient = (struct one_client *)
pclient->node.next;
clean_client(pclient, bindsock);
clean_client(pclient);
}
}
}
/*
* register_new_client()
*/
void register_new_client(
SOCKET sock,
struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom)
{
int status;
struct one_client *pclient;
struct extmsg confirm;
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)
break;
}
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
}
}
memset((char *)&confirm, 0, sizeof confirm);
confirm.m_cmmd = htons(REPEATER_CONFIRM);
confirm.m_available = pLocal->sin_addr.s_addr;
status = sendto(
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));
}
}
/*
*
* 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, int sock)
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;
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){
if(MYERRNO == EADDRINUSE)
present = TRUE;
/*
* 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: client cleanup err %s\n",
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){
#ifdef DEBUG
ca_printf("Deleted %d\n", pclient->from.sin_port);
#endif
ellDelete(&client_list, &pclient->node);
free(pclient);
#ifdef DEBUG
ca_printf("Deleted\n");
#endif
}
return OK;

View File

@@ -68,7 +68,7 @@
/************************************************************************/
/*_end */
static char *sccsId = "$Id$";
static char *sccsId = "@(#) $Id$";
#include "iocinf.h"
#include "net_convert.h"
@@ -90,7 +90,7 @@ struct in_addr *pnet_addr
);
#ifdef CONVERSION_REQUIRED
globalref CACVRTFUNC *cac_dbr_cvrt[];
extern CACVRTFUNC *cac_dbr_cvrt[];
#endif /*CONVERSION_REQUIRED*/
@@ -230,7 +230,6 @@ struct in_addr *pnet_addr
)
{
evid monix;
int status;
switch (piiu->curMsg.m_cmmd) {
@@ -243,13 +242,21 @@ struct in_addr *pnet_addr
case IOC_WRITE_NOTIFY:
{
/*
* run the user's event handler
* m_available points to event descriptor
*/
struct event_handler_args args;
monix = (evid) piiu->curMsg.m_available;
/*
* run the user's event handler
*/
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client write io id from server");
break;
}
/*
*
@@ -276,21 +283,31 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_write_list, &monix->node);
ellAdd(&free_event_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
break;
}
case IOC_READ_NOTIFY:
{
/*
* run the user's event handler
* m_available points to event descriptor
*/
struct event_handler_args args;
monix = (evid) piiu->curMsg.m_available;
/*
* run the user's event handler
*/
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client read notify io id from server");
break;
}
/*
*
@@ -339,8 +356,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_read_list, &monix->node);
ellAdd(&free_event_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
break;
}
@@ -350,10 +367,18 @@ struct in_addr *pnet_addr
struct event_handler_args args;
/*
* run the user's event handler m_available
* points to event descriptor
* run the user's event handler
*/
monix = (evid) piiu->curMsg.m_available;
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client event id from server");
break;
}
/*
@@ -363,8 +388,8 @@ struct in_addr *pnet_addr
if (!piiu->curMsg.m_postsize) {
LOCK;
ellDelete(&monix->chan->eventq, &monix->node);
ellAdd(&free_event_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
break;
}
@@ -420,17 +445,19 @@ struct in_addr *pnet_addr
}
case IOC_READ:
{
chid chan;
evid pIOBlock;
/*
* verify the channel id
* verify the event id
*/
LOCK;
chan = bucketLookupItem(pBucket, piiu->curMsg.m_cid);
pIOBlock = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&piiu->curMsg.m_available);
UNLOCK;
if(!chan){
if(!pIOBlock){
ca_signal(ECA_INTERNAL,
"bad client channel id from server");
"bad client read io id from server");
break;
}
@@ -438,30 +465,35 @@ struct in_addr *pnet_addr
* only count get returns if from the current
* read seq
*/
if (!VALID_MSG(piiu))
break;
if (VALID_MSG(piiu)){
/*
* convert the data buffer from net
* format to host format
*/
# ifdef CONVERSION_REQUIRED
(*cac_dbr_cvrt[piiu->curMsg.m_type])(
piiu->pCurData,
piiu->curMsg.m_available,
FALSE,
piiu->curMsg.m_count);
# else
memcpy(
(char *)piiu->curMsg.m_available,
piiu->pCurData,
dbr_size_n(piiu->curMsg.m_type, piiu->curMsg.m_count));
# endif
/*
* convert the data buffer from net
* format to host format
*/
# ifdef CONVERSION_REQUIRED
(*cac_dbr_cvrt[piiu->curMsg.m_type])(
piiu->pCurData,
pIOBlock->usr_arg,
FALSE,
piiu->curMsg.m_count);
# else
memcpy(
(char *)pIOBlock->usr_arg,
piiu->pCurData,
dbr_size_n(piiu->curMsg.m_type,
piiu->curMsg.m_count));
# endif
/*
* decrement the outstanding IO count
*/
CLRPENDRECV(TRUE);
/*
* decrement the outstanding IO count
*/
CLRPENDRECV(TRUE);
}
LOCK;
ellDelete(&pend_read_list, &pIOBlock->node);
UNLOCK;
caIOBlockFree(pIOBlock);
break;
}
case IOC_SEARCH:
@@ -477,7 +509,7 @@ struct in_addr *pnet_addr
{
struct in_addr ina;
ina.s_addr = (long) piiu->curMsg.m_available;
ina.s_addr = piiu->curMsg.m_available;
mark_server_available(&ina);
}
UNLOCK;
@@ -494,46 +526,12 @@ struct in_addr *pnet_addr
break;
case IOC_CLEAR_CHANNEL:
{
chid chix = (chid) piiu->curMsg.m_available;
struct ioc_in_use *piiu = chix->piiu;
register evid monix;
LOCK;
/*
* remove any orphaned get callbacks for this
* channel
*/
for (monix = (evid) pend_read_list.node.next;
monix;
monix = (evid) monix->node.next){
if (monix->chan == chix) {
ellDelete(
&pend_read_list,
&monix->node);
ellAdd(
&free_event_list,
&monix->node);
}
}
ellConcat(&free_event_list, &chix->eventq);
ellDelete(&piiu->chidlist, &chix->node);
status = bucketRemoveItem(pBucket, chix->cid, chix);
if(status != BUCKET_SUCCESS){
ca_signal(
ECA_INTERNAL,
"bad id at channel delete");
}
free(chix);
if (!piiu->chidlist.count){
TAG_CONN_DOWN(piiu);
}
UNLOCK;
clearChannelResources (piiu->curMsg.m_available);
break;
}
case IOC_ERROR:
{
evid monix;
char nameBuf[64];
char context[255];
struct extmsg *req = piiu->pCurData;
@@ -567,12 +565,36 @@ struct in_addr *pnet_addr
* future. This is quite wasteful of space
* however.
*/
monix = NULL;
args.addr = NULL;
switch (ntohs(req->m_cmmd)) {
case IOC_READ_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_GET;
break;
case IOC_READ:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
if(monix){
args.addr = monix->usr_arg;
}
op = CA_OP_GET;
break;
case IOC_WRITE_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_PUT;
break;
case IOC_WRITE:
op = CA_OP_PUT;
break;
@@ -580,9 +602,19 @@ 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;
break;
case IOC_EVENT_CANCEL:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_CLEAR_EVENT;
break;
default:
@@ -590,14 +622,19 @@ struct in_addr *pnet_addr
break;
}
if (monix) {
caIOBlockFree(monix);
}
LOCK;
args.chid = bucketLookupItem(pBucket, piiu->curMsg.m_cid);
args.chid = bucketLookupItemUnsignedId
(pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
args.usr = ca_static->ca_exception_arg;
args.type = ntohs(req->m_type);
args.count = ntohs(req->m_count);
args.addr = (void *) (req->m_available);
args.stat = ntohl((long) piiu->curMsg.m_available); args.op = op;
args.type = ntohs (req->m_type);
args.count = ntohs (req->m_count);
args.stat = ntohl (piiu->curMsg.m_available);
args.op = op;
args.ctx = context;
LOCKEVENTS;
@@ -611,11 +648,17 @@ struct in_addr *pnet_addr
chid chan;
LOCK;
chan = bucketLookupItem(pBucket, piiu->curMsg.m_cid);
chan = bucketLookupItemUnsignedId(pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
assert(chan);
if(!chan){
/*
* end up here if they delete the channel
* prior to connecting
*/
break;
}
ar = ntohl(piiu->curMsg.m_available);
ar = ntohl (piiu->curMsg.m_available);
chan->ar.read_access = (ar&CA_ACCESS_RIGHT_READ)?1:0;
chan->ar.write_access = (ar&CA_ACCESS_RIGHT_WRITE)?1:0;
@@ -633,9 +676,20 @@ struct in_addr *pnet_addr
chid chan;
LOCK;
chan = bucketLookupItem(pBucket, piiu->curMsg.m_cid);
chan = bucketLookupItemUnsignedId(
pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
assert(chan);
if(!chan){
/*
* end up here if they delete the channel
* prior to connecting
*/
break;
}
if (CA_V44(CA_PROTOCOL_VERSION,piiu->minor_version_number)) {
chan->id.sid = ntohl (piiu->curMsg.m_available);
}
reconnect_channel(piiu, chan);
break;
}
@@ -674,7 +728,9 @@ struct in_addr *pnet_addr
* lock required around use of the sprintf buffer
*/
LOCK;
chan = bucketLookupItem(pBucket, piiu->curMsg.m_available);
chan = bucketLookupItemUnsignedId(
pSlowBucket,
&piiu->curMsg.m_available);
if(!chan){
UNLOCK;
return;

View File

@@ -60,13 +60,35 @@ void ca_sg_init(void)
*/
void ca_sg_shutdown(struct ca_static *ca_temp)
{
CASG *pcasg;
CASG *pnextcasg;
int status;
/*
* free all sync group lists
*/
ellFree(&ca_temp->activeCASG);
ellFree(&ca_temp->freeCASG);
ellInit(&ca_temp->activeCASGOP);
ellInit(&ca_temp->freeCASGOP);
LOCK;
pcasg = (CASG *) ellFirst (&ca_temp->activeCASG);
while (pcasg) {
pnextcasg = (CASG *) ellNext (&pcasg->node);
status = ca_sg_delete (pcasg->id);
assert (status==ECA_NORMAL);
pcasg = pnextcasg;
}
assert (ellCount(&ca_temp->activeCASG)==0);
/*
* per sync group
*/
ellFree (&ca_temp->freeCASG);
/*
* per sync group op
*/
ellFree (&ca_temp->activeCASGOP);
ellFree (&ca_temp->freeCASGOP);
UNLOCK;
return;
}
@@ -108,13 +130,13 @@ int ca_sg_create(CA_SYNC_GID *pgid)
*/
memset((char *)pcasg,0,sizeof(*pcasg));
pcasg->magic = CASG_MAGIC;
pcasg->id = CLIENT_ID_ALLOC;
pcasg->id = CLIENT_SLOW_ID_ALLOC;
pcasg->opPendCount = 0;
pcasg->seqNo = 0;
os_specific_sg_create(pcasg);
status = bucketAddItem(pBucket, pcasg->id, pcasg);
status = bucketAddItemUnsignedId(pSlowBucket, &pcasg->id, pcasg);
if(status == BUCKET_SUCCESS){
/*
* place it on the active sync group list
@@ -154,13 +176,13 @@ int ca_sg_delete(CA_SYNC_GID gid)
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
}
status = bucketRemoveItem(pBucket, gid, pcasg);
status = bucketRemoveItemUnsignedId(pSlowBucket, &gid);
assert(status == BUCKET_SUCCESS);
os_specific_sg_delete(pcasg);
@@ -180,9 +202,11 @@ int ca_sg_delete(CA_SYNC_GID gid)
*/
int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
{
time_t beg_time;
int status;
CASG *pcasg;
struct timeval beg_time;
struct timeval cur_time;
ca_real delay;
int status;
CASG *pcasg;
/*
* Force the CA client id bucket to
@@ -191,6 +215,10 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
*/
INITCHK;
if(timeout<0.0){
return ECA_TIMEOUT;
}
/*
* until CAs input mechanism is
* revised we have to dissallow
@@ -202,7 +230,7 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
}
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
@@ -216,21 +244,35 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
*/
ca_flush_io();
cac_gettimeval(&beg_time);
status = ECA_NORMAL;
beg_time = time(NULL);
while(pcasg->opPendCount){
/*
* wait for asynch notification
*/
cac_block_for_sg_completion(pcasg);
ca_real remaining;
struct timeval tmo;
/*
* Exit if the timeout has expired
*/
if(timeout < time(NULL)-beg_time){
cac_gettimeval (&cur_time);
delay = cac_time_diff (&cur_time, &beg_time);
remaining = timeout-delay;
if (remaining<=0.0) {
status = ECA_TIMEOUT;
break;
}
/*
* Allow for CA background labor
*/
remaining = min(SELECT_POLL, remaining);
/*
* wait for asynch notification
*/
tmo.tv_sec = remaining;
tmo.tv_usec = (remaining-tmo.tv_sec)*USEC_PER_SEC;
cac_block_for_sg_completion (pcasg, &tmo);
}
pcasg->opPendCount = 0;
pcasg->seqNo++;
@@ -246,7 +288,7 @@ int ca_sg_reset(CA_SYNC_GID gid)
CASG *pcasg;
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
@@ -268,7 +310,7 @@ int ca_sg_test(CA_SYNC_GID gid)
CASG *pcasg;
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
@@ -301,7 +343,7 @@ void *pvalue)
CASG *pcasg;
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
@@ -338,14 +380,15 @@ void *pvalue)
pcasgop);
if(status != ECA_NORMAL){
LOCK;
pcasg->opPendCount--;
ellDelete(&ca_static->activeCASGOP, &pcasgop->node);
ellAdd(&ca_static->freeCASGOP, &pcasgop->node);
UNLOCK;
}
LOCK;
pcasg->opPendCount--;
ellDelete(&ca_static->activeCASGOP, &pcasgop->node);
ellAdd(&ca_static->freeCASGOP, &pcasgop->node);
UNLOCK;
}
return status;
return status;
}
@@ -365,7 +408,7 @@ void *pvalue)
CASG *pcasg;
LOCK;
pcasg = bucketLookupItem(pBucket, gid);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid);
if(!pcasg || pcasg->magic != CASG_MAGIC){
UNLOCK;
return ECA_BADSYNCGRP;
@@ -391,6 +434,7 @@ void *pvalue)
pcasgop->pValue = pvalue;
ellAdd(&ca_static->activeCASGOP, &pcasgop->node);
pcasg->opPendCount++;
UNLOCK;
status = ca_array_get_callback(
@@ -405,9 +449,8 @@ void *pvalue)
pcasg->opPendCount--;
ellDelete(&ca_static->activeCASGOP, &pcasgop->node);
ellAdd(&ca_static->freeCASGOP, &pcasgop->node);
UNLOCK;
UNLOCK;
}
return status;
}
@@ -425,7 +468,6 @@ LOCAL void io_complete(struct event_handler_args args)
assert(pcasgop->magic == CASG_MAGIC);
LOCK;
ellDelete(&ca_static->activeCASGOP, &pcasgop->node);
pcasgop->magic = 0;
ellAdd(&ca_static->freeCASGOP, &pcasgop->node);
@@ -433,7 +475,7 @@ LOCAL void io_complete(struct event_handler_args args)
/*
* ignore stale replies
*/
pcasg = bucketLookupItem(pBucket, pcasgop->id);
pcasg = bucketLookupItemUnsignedId(pSlowBucket, &pcasgop->id);
if(!pcasg || pcasg->seqNo != pcasgop->seqNo){
UNLOCK;
return;
@@ -441,6 +483,7 @@ LOCAL void io_complete(struct event_handler_args args)
assert(pcasg->magic == CASG_MAGIC);
if(!(args.status&CA_M_SUCCESS)){
ca_printf(
"CA Sync Group (id=%d) request failed because \"%s\"\n",

View File

@@ -52,7 +52,7 @@ void ca_test_event(struct event_handler_args args)
ca_printf("CAC: Value:\t<%f>\n",*(float *)args.dbr);
break;
case DBR_DOUBLE:
ca_printf("CAC: Value:\t<%f>\n",*(double *)args.dbr);
ca_printf("CAC: Value:\t<%lf>\n",*(double *)args.dbr);
break;
case DBR_STS_STRING:
ca_printf("CAC: Value:\t<%s>\n",((struct dbr_sts_string *)args.dbr)->value);

View File

@@ -1,10 +1,11 @@
/*
* $Id$
*
* U C X . H
* UNIX ioctl structures and defines used for VAX/UCX
* Author: Gerhard Grygiel (GeG)
*
* GeG 09-DEC-1992 initial edit
* CJM 13-Jul-1994 add fd_set etc for R3.12
*
*/
#ifndef _UCX_H_
@@ -14,6 +15,7 @@
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is point to point */
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
@@ -54,6 +56,28 @@ struct ifconf {
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
};
#ifndef NBBY
#define NBBY 8
#endif
#ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
typedef long fd_mask ;
#define NFDBITS (sizeof (fd_mask) * NBBY ) /* bits per mask */
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
typedef struct fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)] ;
} fd_set ;
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) bzero((char *)(p), sizeof (*(p)))
#include <iodef.h>
#define IO$_RECEIVE (IO$_WRITEVBLK)
@@ -61,3 +85,4 @@ struct ifconf {
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id$
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
@@ -51,6 +51,19 @@
#define CONNECTION_TIMER_ID 56
/*
* cac_gettimeval
*/
void cac_gettimeval(struct timeval *pt)
{
struct timezone tz;
int status;
status = gettimeofday(pt, &tz);
assert(status==0);
}
/*
* CAC_MUX_IO()
@@ -67,14 +80,15 @@ void cac_mux_io(struct timeval *ptimeout)
int newInput;
struct timeval timeout;
if(!ca_static->ca_repeater_contacted){
notify_ca_repeater();
}
cac_clean_iiu_list();
timeout = *ptimeout;
do{
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
newInput = FALSE;
do{
count = cac_select_io(
@@ -89,13 +103,10 @@ void cac_mux_io(struct timeval *ptimeout)
while(count>0);
ca_process_input_queue();
}
while(newInput);
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
}
@@ -103,13 +114,9 @@ void cac_mux_io(struct timeval *ptimeout)
/*
* cac_block_for_io_completion()
*/
void cac_block_for_io_completion()
void cac_block_for_io_completion(struct timeval *pTV)
{
struct timeval itimeout;
itimeout.tv_usec = SELECT_POLL%USEC_PER_SEC;
itimeout.tv_sec = SELECT_POLL/USEC_PER_SEC;
cac_mux_io(&itimeout);
cac_mux_io(pTV);
}
@@ -140,23 +147,9 @@ void os_specific_sg_io_complete(CASG *pcasg)
/*
* cac_block_for_sg_completion()
*/
void cac_block_for_sg_completion(CASG *pcasg)
void cac_block_for_sg_completion(pTV)
{
struct timeval itimeout;
itimeout.tv_usec = SELECT_POLL%USEC_PER_SEC;
itimeout.tv_sec = SELECT_POLL/USEC_PER_SEC;
cac_mux_io(&itimeout);
}
/*
* CAC_ADD_TASK_VARIABLE()
*/
int cac_add_task_variable(struct ca_static *ca_temp)
{
ca_static = ca_temp;
return ECA_NORMAL;
cac_mux_io(pTV);
}
@@ -166,7 +159,26 @@ int cac_add_task_variable(struct ca_static *ca_temp)
*/
int cac_os_depen_init(struct ca_static *pcas)
{
return ECA_NORMAL;
int status;
ca_static = pcas;
status = ca_os_independent_init ();
return status;
}
/*
* cac_os_depen_exit ()
*/
void cac_os_depen_exit (struct ca_static *pcas)
{
ca_static = pcas;
ca_process_exit();
ca_static = NULL;
free ((char *)pcas);
}
@@ -296,12 +308,6 @@ void ca_spawn_repeater()
}
cac_setup_recv_thread(IIU *piiu)
{
return ECA_NORMAL;
}
/*
* caHostFromInetAddr()

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id$
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
@@ -33,13 +33,61 @@
#include <stdarg.h>
#include <callback.h>
#include "iocinf.h"
#include "remLib.h"
LOCAL void ca_repeater_task();
LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb);
LOCAL void ca_extra_event_labor(void *pArg);
LOCAL int cac_os_depen_exit(struct ca_static *pcas, int tid);
LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid);
LOCAL int cac_add_task_variable (struct ca_static *ca_temp);
LOCAL void deleteCallBack(CALLBACK *pcb);
#define USEC_PER_SEC 1000000
/*
* cac_gettimeval()
*/
void cac_gettimeval(struct timeval *pt)
{
unsigned long sec;
unsigned long current;
static unsigned long rate;
static unsigned long last;
static unsigned long offset;
static SEM_ID sem;
int status;
assert(pt);
/*
* Lazy Init
*/
if(!rate){
sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
rate = sysClkRateGet();
assert(rate);
assert(sem!=NULL);
}
else {
status = semTake(sem, WAIT_FOREVER);
assert(status==OK);
}
current = tickGet();
if(current<last){
offset += (~0UL)/rate;
}
last = current;
status = semGive(sem);
assert(status==OK);
sec = current/rate;
pt->tv_sec = sec + offset;
pt->tv_usec = ((current-sec*rate)*USEC_PER_SEC)/rate;
}
/*
@@ -56,30 +104,51 @@ void cac_mux_io(struct timeval *ptimeout)
int count;
struct timeval timeout;
#if NOASYNCRECV
cac_clean_iiu_list();
manage_conn(TRUE);
#endif
timeout = *ptimeout;
do{
count = cac_select_io(
&timeout,
CA_DO_SENDS);
CA_DO_SENDS | CA_DO_RECVS);
timeout.tv_usec = 0;
timeout.tv_sec = 0;
}
while(count>0);
#if NOASYNCRECV
ca_process_input_queue();
#endif
}
/*
* cac_block_for_io_completion()
*/
void cac_block_for_io_completion()
void cac_block_for_io_completion(struct timeval *pTV)
{
struct timeval itimeout;
unsigned long ticks;
unsigned long rate = sysClkRateGet();
#if NOASYNCRECV
cac_mux_io(pTV);
#else
/*
* flush outputs
* (recv occurs in another thread)
*/
itimeout.tv_usec = 0;
itimeout.tv_sec = 0;
cac_mux_io(&itimeout);
semTake(io_done_sem, LOCALTICKS);
ticks = pTV->tv_sec*rate + (pTV->tv_usec*rate)/USEC_PER_SEC;
ticks = min(LOCALTICKS, ticks);
semTake(io_done_sem, ticks);
#endif
}
@@ -89,7 +158,7 @@ void cac_block_for_io_completion()
void os_specific_sg_create(CASG *pcasg)
{
pcasg->sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
assert(pcasg->sem);
assert (pcasg->sem);
}
@@ -101,7 +170,7 @@ void os_specific_sg_delete(CASG *pcasg)
int status;
status = semDelete(pcasg->sem);
assert(status == OK);
assert (status == OK);
}
@@ -113,22 +182,35 @@ void os_specific_sg_io_complete(CASG *pcasg)
int status;
status = semGive(pcasg->sem);
assert(status == OK);
assert (status == OK);
}
/*
* cac_block_for_sg_completion()
*/
void cac_block_for_sg_completion(CASG *pcasg)
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
struct timeval itimeout;
unsigned long ticks;
unsigned long rate = sysClkRateGet();
#if NOASYNCRECV
cac_mux_io(pTV);
#else
/*
* flush outputs
* (recv occurs in another thread)
*/
itimeout.tv_usec = 0;
itimeout.tv_sec = 0;
cac_mux_io(&itimeout);
semTake(pcasg->sem, LOCALTICKS);
ticks = pTV->tv_sec*rate + (pTV->tv_usec*rate)/USEC_PER_SEC;
ticks = min(LOCALTICKS, ticks);
semTake (pcasg->sem, ticks);
#endif
}
@@ -136,7 +218,7 @@ void cac_block_for_sg_completion(CASG *pcasg)
/*
* CAC_ADD_TASK_VARIABLE()
*/
int cac_add_task_variable(struct ca_static *ca_temp)
LOCAL int cac_add_task_variable (struct ca_static *ca_temp)
{
static char ca_installed;
TVIU *ptviu;
@@ -147,7 +229,7 @@ int cac_add_task_variable(struct ca_static *ca_temp)
return status;
}
# if DEBUG
# ifdef DEBUG
ca_printf("CAC: adding task variable\n");
# endif
@@ -173,7 +255,7 @@ int cac_add_task_variable(struct ca_static *ca_temp)
* taskDeleteHookAdd() if you use a task variable
* in a task exit handler.
*/
# if DEBUG
# ifdef DEBUG
ca_printf("CAC: adding delete hook\n");
# endif
@@ -188,13 +270,12 @@ int cac_add_task_variable(struct ca_static *ca_temp)
}
}
ptviu = calloc(1, sizeof(*ptviu));
ptviu = (TVIU *) calloc(1, sizeof(*ptviu));
if(!ptviu){
return ECA_INTERNAL;
}
ptviu->tid = taskIdSelf();
ellAdd(&ca_temp->ca_taskVarList, &ptviu->node);
status = taskVarAdd(VXTHISTASKID, (int *)&ca_static);
if (status != OK){
@@ -203,6 +284,7 @@ int cac_add_task_variable(struct ca_static *ca_temp)
}
ca_static = ca_temp;
ellAdd(&ca_temp->ca_taskVarList, &ptviu->node);
return ECA_NORMAL;
}
@@ -214,13 +296,13 @@ int cac_add_task_variable(struct ca_static *ca_temp)
*/
LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb)
{
int status;
struct ca_static *ca_temp;
# if DEBUG
# ifdef DEBUG
ca_printf("CAC: entering the exit handler %x\n", ptcb);
# endif
/*
* NOTE: vxWorks provides no method at this time
* to get the task id from the ptcb so I am
@@ -228,18 +310,35 @@ LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb)
* the task id - somthing which may not be true
* on future releases of vxWorks
*/
ca_temp = (struct ca_static *)taskVarGet((int)ptcb, (int *) &ca_static);
ca_temp = (struct ca_static *)
taskVarGet((int)ptcb, (int *) &ca_static);
if (ca_temp == (struct ca_static *) ERROR){
return;
}
if(ca_temp->ca_exit_in_progress){
return;
}
/*
* Add CA task var for the exit handler
*/
if (ptcb != taskIdCurrent) {
status = taskVarAdd (VXTHISTASKID, (int *)&ca_static);
if (status == ERROR){
ca_printf ("Couldnt add task var to CA exit task\n");
return;
}
}
cac_os_depen_exit(ca_temp, (int) ptcb);
/*
* normal CA shut down
*/
cac_os_depen_exit_tid (ca_temp, (int) ptcb);
ca_process_exit(ca_temp);
if (ptcb != taskIdCurrent) {
status = taskVarDelete(VXTHISTASKID, (int *)&ca_static);
if (status == ERROR){
ca_printf ("Couldnt remove task var from CA exit task\n");
return;
}
}
}
@@ -270,6 +369,16 @@ int cac_os_depen_init(struct ca_static *pcas)
pcas->ca_blockSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
assert(pcas->ca_blockSem);
status = cac_add_task_variable (pcas);
if (status != ECA_NORMAL) {
return status;
}
status = ca_os_independent_init ();
if (status != ECA_NORMAL){
return status;
}
evuser = (void *) db_init_events();
assert(evuser);
@@ -296,51 +405,87 @@ int cac_os_depen_init(struct ca_static *pcas)
/*
* cac_os_depen_exit()
* cac_os_depen_exit ()
*/
LOCAL int cac_os_depen_exit(struct ca_static *pcas, int tid)
void cac_os_depen_exit (struct ca_static *pcas)
{
int status;
chid chix;
evid monix;
TVIU *ptviu;
cac_os_depen_exit_tid (pcas, 0);
}
/*
* cac_os_depen_exit_tid ()
*/
LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid)
{
int status;
chid chix;
evid monix;
TVIU *ptviu;
CALLBACK *pcb;
# ifdef DEBUG
ca_printf("CAC: entering the exit routine %x %x\n",
tid, pcas);
# endif
ca_static = pcas;
LOCK;
/*
* stop the socket recv task
* !! only after we get the LOCK here !!
*/
if(taskIdVerify(pcas->recv_tid)==OK){
taskwdRemove(pcas->recv_tid);
if (taskIdVerify (pcas->recv_tid)==OK) {
taskwdRemove (pcas->recv_tid);
/*
* dont do a task suspend if the exit handler is
* running for this task - it botches vxWorks -
*/
if(pcas->recv_tid != tid){
taskSuspend(pcas->recv_tid);
if (pcas->recv_tid != tid) {
status = taskSuspend (pcas->recv_tid);
if (status<0) {
ca_printf ("taskSuspend() error = %s\n",
strerror (MYERRNO) );
}
}
}
/*
* Cancel all local events
* (and put call backs)
*
*/
chix = (chid) & pcas->ca_local_chidlist.node;
while (chix = (chid) chix->node.next){
while (chix = (chid) chix->node.next) {
while (monix = (evid) ellGet(&chix->eventq)) {
/*
* temp release lock so that the event task
* can finish
*/
UNLOCK;
status = db_cancel_event(monix + 1);
LOCK;
assert(status == OK);
free(monix);
}
if(chix->ppn){
if (chix->ppn) {
CACLIENTPUTNOTIFY *ppn;
ppn = chix->ppn;
if(ppn->busy){
dbNotifyCancel(&ppn->dbPutNotify);
if (ppn->busy) {
dbNotifyCancel (&ppn->dbPutNotify);
}
free(ppn);
free (ppn);
}
}
/*
* set ca_static for access.c
* (run this before deleting the task variable)
*/
ca_process_exit();
/*
* cancel task vars for other tasks so this
@@ -351,7 +496,11 @@ LOCAL int cac_os_depen_exit(struct ca_static *pcas, int tid)
*
* db_close_events() does not require a CA context.
*/
while(ptviu = (TVIU *)ellGet(&pcas->ca_taskVarList)){
while (ptviu = (TVIU *)ellGet(&pcas->ca_taskVarList)) {
# ifdef DEBUG
ca_printf("CAC: removing task var %x\n", ptviu->tid);
# endif
status = taskVarDelete(
ptviu->tid,
(int *)&ca_static);
@@ -363,9 +512,15 @@ LOCAL int cac_os_depen_exit(struct ca_static *pcas, int tid)
free(ptviu);
}
if(taskIdVerify(pcas->recv_tid)==OK){
if (taskIdVerify(pcas->recv_tid)==OK) {
if(pcas->recv_tid != tid){
taskDelete(pcas->recv_tid);
pcb = (CALLBACK *) calloc(1,sizeof(*pcb));
if (pcb) {
pcb->callback = deleteCallBack;
pcb->priority = priorityHigh;
pcb->user = (void *) pcas->recv_tid;
callbackRequest (pcb);
}
}
}
@@ -384,11 +539,38 @@ LOCAL int cac_os_depen_exit(struct ca_static *pcas, int tid)
ellFree(&pcas->ca_local_chidlist);
ellFree(&pcas->ca_dbfree_ev_list);
/*
* remove semaphores here so that ca_process_exit()
* can use them.
*/
assert(semDelete(pcas->ca_client_lock)==OK);
assert(semDelete(pcas->ca_event_lock)==OK);
assert(semDelete(pcas->ca_putNotifyLock)==OK);
assert(semDelete(pcas->ca_io_done_sem)==OK);
assert(semDelete(pcas->ca_blockSem)==OK);
ca_static = NULL;
free ((char *)pcas);
return ECA_NORMAL;
}
/*
* deleteCallBack()
*/
LOCAL void deleteCallBack(CALLBACK *pcb)
{
int status;
status = taskDelete ((int)pcb->user);
if (status < 0) {
ca_printf ("CAC: tak delete at exit failed: %s\n",
strerror(errno));
}
free (pcb);
}
@@ -464,7 +646,7 @@ int ca_import(int tid)
return ECA_NORMAL;
}
ptviu = calloc(1, sizeof(*ptviu));
ptviu = (TVIU *) calloc(1, sizeof(*ptviu));
if(!ptviu){
return ECA_ALLOCMEM;
}
@@ -530,13 +712,11 @@ int ca_import_cancel(int tid)
*/
int ca_check_for_fp()
{
{
int options;
int options;
assert(taskOptionsGet(taskIdSelf(), &options) == OK);
if (!(options & VX_FP_TASK)) {
return ECA_NEEDSFP;
}
assert(taskOptionsGet(taskIdSelf(), &options) == OK);
if (!(options & VX_FP_TASK)) {
return ECA_NEEDSFP;
}
return ECA_NORMAL;
}
@@ -558,16 +738,16 @@ void ca_spawn_repeater()
CA_REPEATER_OPT,
CA_REPEATER_STACK,
(FUNCPTR)ca_repeater_task,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
0,
0,
0,
0,
0,
0,
0,
0,
0,
0);
if (status < 0){
SEVCHK(ECA_NOREPEATER, NULL);
}
@@ -583,16 +763,6 @@ void ca_repeater_task()
ca_repeater();
}
/*
* Setup recv thread
* (OS dependent)
*/
int cac_setup_recv_thread(IIU *piiu)
{
return ECA_NORMAL;
}
/*
@@ -657,13 +827,13 @@ LOCAL void ca_extra_event_labor(void *pArg)
*/
status = semGive(pcas->ca_blockSem);
if(status != OK){
logMsg("CA block sem corrupted\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
logMsg( "CA block sem corrupted\n",
0,
0,
0,
0,
0,
0);
}
}
@@ -689,13 +859,14 @@ void cac_recv_task(int tid)
* ca_task_exit() is called.
*/
while(TRUE){
#if NOASYNCRECV
taskDelay(60);
#else
manage_conn(TRUE);
timeout.tv_usec = 0;
timeout.tv_sec = 1;
if(!ca_static->ca_repeater_contacted){
notify_ca_repeater();
}
cac_clean_iiu_list();
cac_select_io(
@@ -703,7 +874,7 @@ void cac_recv_task(int tid)
CA_DO_RECVS);
ca_process_input_queue();
manage_conn(TRUE);
#endif
}
}

254
src/ca/windows_depen.c Normal file
View File

@@ -0,0 +1,254 @@
/*
* $Id$
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
* Date: 9-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:
* -----------------
*
*/
/*
* ANSI includes
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "iocinf.h"
#ifndef _WINDOWS
#error This source is specific to DOS/WINDOS
#endif
/*
* cac_gettimeval
*/
void cac_gettimeval(struct timeval *pt)
{
SYSTEMTIME st;
GetSystemTime(&st);
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 +
(long)st.wHour*360;
pt->tv_usec = st.wMilliseconds*1000;
}
/*
* CAC_MUX_IO()
*
* Asynch notification of incomming messages under UNIX
* 1) Wait no longer than timeout
* 2) Return early if nothing outstanding
*
*
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
int newInput;
struct timeval timeout;
cac_clean_iiu_list();
timeout = *ptimeout;
do{
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE); newInput = FALSE;
do{
count = cac_select_io(
&timeout,
CA_DO_RECVS | CA_DO_SENDS);
if(count>0){
newInput = TRUE;
}
timeout.tv_usec = 0;
timeout.tv_sec = 0;
}
while(count>0);
ca_process_input_queue();
}
while(newInput);
}
/*
* cac_block_for_io_completion()
*/
void cac_block_for_io_completion(struct timeval *pTV)
{
cac_mux_io(pTV);
}
/*
* os_specific_sg_io_complete()
*/
void os_specific_sg_io_complete(CASG *pcasg)
{
}
/*
* does nothing but satisfy undefined
*/
void os_specific_sg_create(CASG *pcasg)
{
}
void os_specific_sg_delete(CASG *pcasg)
{
}
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
cac_mux_io(pTV);
}
/*
* cac_os_depen_init()
*/
int cac_os_depen_init(struct ca_static *pcas)
{
int status;
ca_static = ca_temp;
/*
* dont allow disconnect to terminate process
* when running in UNIX enviroment
*
* allow error to be returned to sendto()
* instead of handling disconnect at interrupt
*/
signal(SIGPIPE,SIG_IGN);
# ifdef _WINSOCKAPI_
status = WSAStartup(MAKEWORD(1,1), &WsaData));
assert (status==0);
# endif
status = ca_os_independent_init ();
return status;
}
/*
* cac_os_depen_exit ()
*/
void cac_os_depen_exit (struct ca_static *pcas)
{
ca_static = pcas;
ca_process_exit();
ca_static = NULL;
free ((char *)pcas);
}
/*
*
* This should work on any POSIX compliant OS
*
* o Indicates failure by setting ptr to nill
*/
char *localUserName()
{
int length;
char *pName;
char *pTmp;
pName = "Joe PC";
length = strlen(pName)+1;
pTmp = malloc(length);
if(!pTmp){
return pTmp;
}
strncpy(pTmp, pName, length-1);
pTmp[length-1] = '\0';
return pTmp;
}
/*
* ca_spawn_repeater()
*/
void ca_spawn_repeater()
{
int status;
char *pImageName;
/*
* running in the repeater process
* if here
*/
pImageName = "caRepeater";
status = system(pImageName);
if(status<0){
ca_printf("!!WARNING!!\n");
ca_printf("Unable to locate the executable \"%s\".\n",
pImageName);
ca_printf("You may need to modify your environment.\n");
}
}
/*
* ca_printf()
*/
int ca_printf(char *pformat, ...)
{
va_list args;
int status;
va_start(args, pformat);
status = vfprintf(
stderr,
pformat,
args);
va_end(args);
return status;
}

View File

@@ -5,6 +5,11 @@ include $(EPICS)/config/CONFIG_BASE
USR_LDLIBS = -lDb -lCom
USR_LDFLAGS = -L.
LEX = $(ELEX)
YACC = $(EYACC)
YACCOPT = -l
LEXOPT = -L
DEPLIBS_BASE = $(EPICS_BASE_LIB)
DEPLIBS = ./libDb.a\
$(DEPLIBS_BASE)/libCom.a
@@ -13,10 +18,8 @@ DEPLIBS = ./libDb.a\
SRCS.c = \
../dbStaticLib.c \
atdb_lex.c \
atdb_yacc.c \
../dbta.c \
../atdb.c \
../dbl.c \
../dbls.c
@@ -25,17 +28,17 @@ LIBOBJS = dbStaticLib.o
LIBNAME = libDb.a
PROD = dbta dbl dbls atdb
PROD = atdb dbl dbls dbta
include $(EPICS)/config/RULES.Unix
atdb: atdb.o atdb_yacc.o $(DEPLIBS)
$(LINK.c) -o $@ atdb.o atdb_yacc.o $(LDLIBS)
atdb: atdb_yacc.o $(DEPLIBS)
$(LINK.c) -o $@ atdb_yacc.o $(LDLIBS)
# Extra rule since atdb_lex.c is included in atdb_yacc.c
# In my opinion, these objects should really be built
# independently.
atdb_yacc.o: atdb_lex.c
atdb_yacc.o: atdb_lex.c ../atdb.c
clean::
@$(RM) atdb_lex.c atdb_yacc.c

View File

@@ -21,7 +21,7 @@ yyreset()
^"PV:" { return(PV); }
"Type:" { return(TYPE); }
{ return(CLOSE); }
" " { return(CLOSE); }
"$$end" { return(CLOSE); }
{d}+ { yylval.Str=(char *)malloc(strlen(yytext)+1);

View File

@@ -2,6 +2,7 @@
#include <stdio.h>
#include <memory.h>
#include <string.h>
static int yy_start;
#include <dbStaticLib.h>
/* kludge for buggy lex/yacc. exploits the fact that we know the union */
/* below will be given the name YYSTYPE. done so that ifndef YYSTYPE */
@@ -127,9 +128,8 @@ junko: WORD
yyerror(str)
char *str;
{
sprintf(message,"Error line %d : %s\n",line_num, yytext);
sprintf(message,"Error line %d : %s %s\n",line_num, yytext,str);
errMessage(-1,message);
}
yywrap() { return(1); }
#include "atdb.c"

View File

@@ -1651,7 +1651,7 @@ char *pstring;
plink->value.vmeio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%31s",&plink->value.vmeio.parm[0]);
strcpy(&plink->value.vmeio.parm[0],pstr);
}
}
break;
@@ -1678,7 +1678,7 @@ char *pstring;
plink->value.camacio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%25s",&plink->value.camacio.parm[0]);
strcpy(&plink->value.camacio.parm[0],pstr);
}
}
break;
@@ -1708,7 +1708,7 @@ char *pstring;
plink->value.abio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%25s",&plink->value.abio.parm[0]);
strcpy(&plink->value.abio.parm[0],pstr);
}
}
break;
@@ -1726,7 +1726,7 @@ char *pstring;
plink->value.gpibio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%31s",&plink->value.gpibio.parm[0]);
strcpy(&plink->value.gpibio.parm[0],pstr);
}
}
break;
@@ -1758,7 +1758,7 @@ char *pstring;
plink->value.bitbusio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%31s",&plink->value.bitbusio.parm[0]);
strcpy(&plink->value.bitbusio.parm[0],pstr);
}
}
break;
@@ -1786,7 +1786,7 @@ char *pstring;
plink->value.bbgpibio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%31s",&plink->value.bbgpibio.parm[0]);
strcpy(&plink->value.bbgpibio.parm[0],pstr);
}
}
break;
@@ -1819,7 +1819,7 @@ char *pstring;
plink->value.vxiio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%27s",&plink->value.vxiio.parm[0]);
strcpy(&plink->value.vxiio.parm[0],pstr);
}
}
break;
@@ -1829,7 +1829,7 @@ char *pstring;
plink->value.instio.string[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
sscanf(pstr,"%35s",&plink->value.instio.string[0]);
strcpy(&plink->value.instio.string[0],pstr);
}
}
break;

View File

@@ -1270,13 +1270,15 @@ void *devLibA24Malloc(size_t size)
void *ret;
if (devLibA24Debug)
printf("devLibA24Malloc(%d) entered\n", size);
logMsg("devLibA24Malloc(%d) entered\n", size, 0,0,0,0,0);
if (A24MallocFunc == NULL)
{
/* See if the sysA24Malloc() function is present. */
if(symFindByName(sysSymTbl,"_sysA24Malloc", (char**)&A24MallocFunc,&stype)==ERROR)
{ /* Could not find sysA24Malloc... use the malloc one and hope we are OK */
if (devLibA24Debug)
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
A24MallocFunc = malloc;
A24FreeFunc = free;
}
@@ -1284,6 +1286,8 @@ void *devLibA24Malloc(size_t size)
{
if(symFindByName(sysSymTbl,"_sysA24Free", (char**)&A24FreeFunc, &stype) == ERROR)
{ /* That's strange... we have malloc, but no free! */
if (devLibA24Debug)
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
A24MallocFunc = malloc;
A24FreeFunc = free;
}
@@ -1301,5 +1305,8 @@ void *devLibA24Malloc(size_t size)
void devLibA24Free(void *pBlock)
{
if (devLibA24Debug)
logMsg("devLibA24Free(%p) entered\n", (unsigned long)pBlock,0,0,0,0,0);
A24FreeFunc(pBlock);
}

View File

@@ -1,6 +1,10 @@
/*
* $Log$
* Revision 1.4 1994/10/28 20:15:10 jbk
* increased the USP packet time-out to 250ms, added a parm to the configure()
* routine to let user specify it.
*
*/
/**************************************************************************
@@ -653,7 +657,23 @@ static void TSerrorHandler(int Card, int ErrorNum)
Could put the slave on the vxworks timer until next sync
*/
logMsg("***TSerrorHandler: error number %d=n",ErrorNum,0,0,0,0,0);
if(MAKE_DEBUG)
{
switch(ErrorNum)
{
case 1:
logMsg("***TSerrorHandler: event system error: TAXI violation",0,0,0,0,0,0);
break;
case 2:
logMsg("***TSerrorHandler: event system error: lost heartbeat",0,0,0,0,0,0);
break;
case 3:
logMsg("***TSerrorHandler: event system error: lost events",0,0,0,0,0,0);
break;
default:
logMsg("***TSerrorHandler: unknown error %d from event system", ErrorNum,0,0,0,0,0);
}
}
return;
}

View File

@@ -53,7 +53,6 @@
* .23 09-10-92 rcz changed funcptr pinitHooks from ret long to void
* .24 09-11-92 rcz moved setMasterTimeToSelf to a seperate C file
* .25 07-15-93 mrk Changed dbLoad for new dbStaticLib support
<<<<<<< iocInit.c
* .26 02-09-94 jbk changed to new time stamp support software ts_init()
* .27 03-18-94 mcn added comments
* .28 03-23-94 mrk Added asInit
@@ -176,11 +175,6 @@ int iocInit(char * pResourceFilename)
* Read EPICS resources.
*/
status = getResources(pResourceFilename);
if (status != 0) {
logMsg("iocInit aborting because getResources failed\n",0,0,0,0,0,0);
return(-1);
}
/* Call hook for after resources are read. */
if (pinitHooks) (*pinitHooks)(INITHOOKafterGetResources);
@@ -778,9 +772,10 @@ static long initDatabase(void)
* Severity/No Maximize Severity(MS/NMS), and output NMS
* links ... The following code checks for this.
*/
if (plink->value.db_link.process_passive
if (errVerbose &&
(plink->value.db_link.process_passive
|| (pfldDes->field_type == DBF_OUTLINK
&& plink->value.db_link.maximize_sevr))
&& plink->value.db_link.maximize_sevr)))
{
/*
* Link PP and/or Outlink MS ...
@@ -795,7 +790,7 @@ static long initDatabase(void)
strcat(message," PP and/or MS illegal");
status = S_db_badField;
errMessage(status,message);
if(rtnval==OK) rtnval=status;
status = 0;
}
}
}
@@ -1078,7 +1073,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: Line too long - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
for (i = 0; i < len; i++) {
if (buff[i] == '!') {
@@ -1090,7 +1085,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: Not enough fields - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
found = 0;
len2 = strlen(s2);
@@ -1107,7 +1102,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: Field 2 not defined - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
strcpy(name, "_");
strcat(name, s1);
@@ -1116,7 +1111,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: Symbol name not found - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
if ( (strncmp(s1,"EPICS_",6)) == SAME)
epicsFlag = 1;
@@ -1143,7 +1138,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: conversion failed - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
if ( epicsFlag ) {
sprintf(message,
@@ -1160,7 +1155,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: conversion failed - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
if ( epicsFlag ) {
sprintf(message,
@@ -1176,7 +1171,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: conversion failed - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
if ( epicsFlag ) {
sprintf(message,
@@ -1193,7 +1188,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: conversion failed - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
}
if ( epicsFlag ) {
sprintf(message,
@@ -1209,7 +1204,7 @@ static long getResources(char *fname)
sprintf(message,
"getResources: switch default reached - line=%d", lineNum);
errMessage(-1L, message);
return (-1);
continue;
break;
}
CLEAR: memset(buff, '\0', MAX);

View File

@@ -5,69 +5,192 @@ include $(EPICS)/config/CONFIG_BASE
USR_INCLUDES = -I../../drv
SRCS.c = \
../devAiDvx2502.c ../devAiSoft.c ../devAiSoftRaw.c \
../devAiSymb.c ../devAiTestAsyn.c ../devAiXy566Di.c \
../devAiXy566DiL.c ../devAiXy566Se.c ../devAoSoft.c \
../devApsEg.c ../devApsEr.c\
../devAoSoftRaw.c ../devAoSymb.c ../devAoTestAsyn.c \
../devAoVmiVme4100.c ../devBiMpv910.c ../devBiSoft.c \
../devBiSoftRaw.c ../devBiTestAsyn.c ../devBiXVme210.c \
../devBoMpv902.c ../devBoSoft.c ../devBoSoftRaw.c \
../devBoTestAsyn.c ../devBoXVme220.c ../devCommonGpib.c \
../devEventSoft.c ../devEventTestIoEvent.c ../devHistogramSoft.c \
../devHistogramTestAsyn.c ../devLiSoft.c ../devLiSymb.c \
../devLoSoft.c ../devLoSymb.c ../devMbbiMpv910.c \
../devMbbiSoft.c ../devMbbiSoftRaw.c ../devMbbiTestAsyn.c \
../devMbbiXVme210.c ../devMbboMpv902.c ../devMbboSoft.c \
../devMbboSoftRaw.c ../devMbboTestAsyn.c ../devMbboXVme220.c \
../devMbbiDirectMpv910.c ../devMbbiDirectSoft.c \
../devMbbiDirectSoftRaw.c ../devMbbiDirectXVme210.c \
../devMbboDirectMpv902.c ../devMbboDirectSoft.c \
../devMbboDirectSoftRaw.c ../devMbboDirectXVme220.c \
../devPtSoft.c ../devSmCompumotor1830.c ../devSmOms6Axis.c \
../devSiSoft.c ../devSiSymb.c ../devSiTestAsyn.c ../devSoSoft.c \
../devSASoft.c ../devSoSymb.c \
../devSoTestAsyn.c ../devWfSoft.c ../devWfTestAsyn.c \
../devWfXy566Sc.c ../devAllenBradley.c ../devAt5Vxi.c \
../devMz8310.c ../devTimerMz8310.c \
../devVxiTDM.c ../devAiKscV215.c ../devXy240.c \
../devHpe1368a.c ../devAt8Fp.c ../devWfComet.c \
../devWfDvx2502.c ../devWfJoergerVtr1.c \
../devAvme9440.c \
../devAiDvx2502.c\
../devAiSoft.c\
../devAiSoftRaw.c\
../devAiSymb.c\
../devAiTestAsyn.c\
../devAiXy566Di.c\
../devAiXy566DiL.c\
../devAiXy566Se.c\
../devAoSoft.c\
../devApsEg.c\
../devApsEr.c\
../devAoSoftRaw.c\
../devAoSymb.c\
../devAoTestAsyn.c\
../devAoVmiVme4100.c\
../devBiMpv910.c\
../devBiSoft.c\
../devBiSoftRaw.c\
../devBiTestAsyn.c\
../devBiXVme210.c\
../devBoMpv902.c\
../devBoSoft.c\
../devBoSoftRaw.c\
../devBoTestAsyn.c\
../devBoXVme220.c\
../devCommonGpib.c\
../devEventSoft.c\
../devEventTestIoEvent.c\
../devHistogramSoft.c\
../devHistogramTestAsyn.c\
../devLiSoft.c\
../devLiSymb.c\
../devLoSoft.c\
../devLoSymb.c\
../devMbbiMpv910.c\
../devMbbiSoft.c\
../devMbbiSoftRaw.c\
../devMbbiTestAsyn.c\
../devMbbiXVme210.c\
../devMbboMpv902.c\
../devMbboSoft.c\
../devMbboSoftRaw.c\
../devMbboTestAsyn.c\
../devMbboXVme220.c\
../devMbbiDirectMpv910.c\
../devMbbiDirectSoft.c\
../devMbbiDirectSoftRaw.c\
../devMbbiDirectXVme210.c\
../devMbboDirectMpv902.c\
../devMbboDirectSoft.c\
../devMbboDirectSoftRaw.c\
../devMbboDirectXVme220.c\
../devPtSoft.c\
../devSmCompumotor1830.c\
../devSmOms6Axis.c\
../devSiSoft.c\
../devSiSymb.c\
../devSiTestAsyn.c\
../devSoSoft.c\
../devSASoft.c\
../devSoSymb.c\
../devSoTestAsyn.c\
../devWfSoft.c\
../devWfTestAsyn.c\
../devWfXy566Sc.c\
../devAllenBradley.c\
../devAt5Vxi.c\
../devMz8310.c\
../devTimerMz8310.c\
../devVxiTDM.c\
../devAiKscV215.c\
../devXy240.c\
../devHpe1368a.c\
../devAt8Fp.c\
../devWfComet.c\
../devWfDvx2502.c\
../devWfJoergerVtr1.c\
../devAvme9440.c\
../devSysmon.c
# ../devAiCamac.c ../devAaiCamac.c ../devBiCamac.c ../devLiCamac.c \
# ../devMbbiCamac.c ../devMbbiDirectCamac.c ../devWfCamac.c \
# ../devAoCamac.c ../devAaoCamac.c ../devBoCamac.c ../devLoCamac.c \
# ../devMbboCamac.c ../devMbboDirectCamac.c
# ../devAiCamac.c\
# ../devAaiCamac.c\
# ../devBiCamac.c\
# ../devLiCamac.c\
# ../devMbbiCamac.c\
# ../devMbbiDirectCamac.c\
# ../devWfCamac.c\
# ../devAoCamac.c\
# ../devAaoCamac.c\
# ../devBoCamac.c\
# ../devLoCamac.c\
# ../devMbboCamac.c\
# ../devMbboDirectCamac.c
OBJS = \
devAiDvx2502.o devAiSoft.o devAiSoftRaw.o devAiSymb.o \
devAiTestAsyn.o devAiXy566Di.o devAiXy566DiL.o devAiXy566Se.o \
devAoSoft.o devAoSoftRaw.o devAoSymb.o devAoTestAsyn.o \
devAoVmiVme4100.o devBiMpv910.o devApsEg.o devApsEr.o \
devBiSoft.o devBiSoftRaw.o \
devBiTestAsyn.o devBiXVme210.o devBoMpv902.o devBoSoft.o \
devBoSoftRaw.o devBoTestAsyn.o devBoXVme220.o devCommonGpib.o \
devEventSoft.o devEventTestIoEvent.o devHistogramSoft.o \
devHistogramTestAsyn.o devLiSoft.o devLiSymb.o \
devLoSoft.o devLoSymb.o devMbbiMpv910.o devMbbiSoft.o \
devMbbiSoftRaw.o devMbbiTestAsyn.o devMbbiXVme210.o devMbboMpv902.o \
devMbboSoft.o devMbboSoftRaw.o devMbboTestAsyn.o devMbboXVme220.o \
devMbbiDirectMpv910.o devMbbiDirectSoft.o devMbbiDirectSoftRaw.o \
devMbbiDirectXVme210.o devMbboDirectMpv902.o devMbboDirectSoft.o \
devMbboDirectSoftRaw.o devMbboDirectXVme220.o devPtSoft.o \
devSmCompumotor1830.o devSmOms6Axis.o devSASoft.o devSiSoft.o \
devSiSymb.o devSiTestAsyn.o devSoSoft.o devSoSymb.o devSoTestAsyn.o \
devWfSoft.o devWfTestAsyn.o devWfXy566Sc.o devAllenBradley.o \
devAt5Vxi.o devMz8310.o devTimerMz8310.o devVxiTDM.o devAiKscV215.o \
devXy240.o devHpe1368a.o devAt8Fp.o devWfComet.o \
devWfDvx2502.o devWfJoergerVtr1.o \
devAvme9440.o \
devAiDvx2502.o\
devAiSoft.o\
devAiSoftRaw.o\
devAiSymb.o\
devAiTestAsyn.o\
devAiXy566Di.o\
devAiXy566DiL.o\
devAiXy566Se.o\
devAoSoft.o\
devAoSoftRaw.o\
devAoSymb.o\
devAoTestAsyn.o\
devAoVmiVme4100.o\
devBiMpv910.o\
devApsEg.o\
devApsEr.o\
devBiSoft.o\
devBiSoftRaw.o\
devBiTestAsyn.o\
devBiXVme210.o\
devBoMpv902.o\
devBoSoft.o\
devBoSoftRaw.o\
devBoTestAsyn.o\
devBoXVme220.o\
devCommonGpib.o\
devEventSoft.o\
devEventTestIoEvent.o\
devHistogramSoft.o\
devHistogramTestAsyn.o\
devLiSoft.o\
devLiSymb.o\
devLoSoft.o\
devLoSymb.o\
devMbbiMpv910.o\
devMbbiSoft.o\
devMbbiSoftRaw.o\
devMbbiTestAsyn.o\
devMbbiXVme210.o\
devMbboMpv902.o\
devMbboSoft.o\
devMbboSoftRaw.o\
devMbboTestAsyn.o\
devMbboXVme220.o\
devMbbiDirectMpv910.o\
devMbbiDirectSoft.o\
devMbbiDirectSoftRaw.o\
devMbbiDirectXVme210.o\
devMbboDirectMpv902.o\
devMbboDirectSoft.o\
devMbboDirectSoftRaw.o\
devMbboDirectXVme220.o\
devPtSoft.o\
devSmCompumotor1830.o\
devSmOms6Axis.o\
devSASoft.o\
devSiSoft.o\
devSiSymb.o\
devSiTestAsyn.o\
devSoSoft.o\
devSoSymb.o\
devSoTestAsyn.o\
devWfSoft.o\
devWfTestAsyn.o\
devWfXy566Sc.o\
devAllenBradley.o\
devAt5Vxi.o\
devMz8310.o\
devTimerMz8310.o\
devVxiTDM.o\
devAiKscV215.o\
devXy240.o\
devHpe1368a.o\
devAt8Fp.o\
devWfComet.o\
devWfDvx2502.o\
devWfJoergerVtr1.o\
devAvme9440.o\
devSysmon.o
# devAiCamac.o devAaiCamac.o devBiCamac.o devLiCamac.o \
# devMbbiCamac.o devMbbiDirectCamac.o devWfCamac.o \
# devAoCamac.o devAaoCamac.o devBoCamac.o devLoCamac.o \
# devMbboCamac.o devMbboDirectCamac.o
# devAiCamac.o\
# devAaiCamac.o\
# devBiCamac.o\
# devLiCamac.o\
# devMbbiCamac.o\
# devMbbiDirectCamac.o\
# devWfCamac.o\
# devAoCamac.o\
# devAaoCamac.o\
# devBoCamac.o\
# devLoCamac.o\
# devMbboCamac.o\
# devMbboDirectCamac.o
PROD = devSup

View File

@@ -133,7 +133,7 @@ static long read_ai(pai)
return(2); /* don`t convert*/
} else {
wait_time = (int)(pai->disv * vxTicksPerSecond);
if(wait_time<=0) return(0);
if(wait_time<=0) return(2);
callbackSetPriority(pai->prio,&pcallback->callback);
printf("Starting asynchronous processing: %s\n",pai->name);
wdStart(pcallback->wd_id,wait_time,(FUNCPTR)callbackRequest,(int)pcallback);

View File

@@ -172,6 +172,15 @@ gDset *dset; /* pointer to dset used to reference the init function */
return(OK);
}
static void RegisterProcessCallback(CALLBACK *pCallback, int Priority, void *Parm)
{
callbackSetCallback(devGpibLib_processCallback, pCallback);
callbackSetPriority(Priority, pCallback);
callbackSetUser(Parm, pCallback);
callbackRequest(pCallback);
return;
}
/******************************************************************************
*
@@ -1288,9 +1297,13 @@ 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
{
@@ -1335,9 +1348,13 @@ 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 */
@@ -1382,9 +1399,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
}
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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(0);
}
@@ -1426,9 +1447,14 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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);
}
@@ -1458,9 +1484,13 @@ 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
{
@@ -1505,9 +1535,13 @@ 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 */
@@ -1551,9 +1585,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
}
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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(0);
}
@@ -1595,9 +1633,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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);
}
@@ -1624,9 +1666,13 @@ 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 */
{
@@ -1669,9 +1715,13 @@ 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 */
@@ -1718,9 +1768,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
}
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback); /* jrw */
#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(0);
}
@@ -1763,9 +1817,14 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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);
}
@@ -1792,9 +1851,13 @@ 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
{
@@ -1839,9 +1902,13 @@ 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 */
@@ -1888,9 +1955,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
}
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#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(0);
}
@@ -1934,9 +2005,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback); /* jrw */
#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);
}
@@ -1966,9 +2041,13 @@ 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); /* jrw */
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -2013,9 +2092,13 @@ 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 */
@@ -2051,9 +2134,13 @@ struct gpibDpvt *pdpvt;
psi->val[40] = '\0';
psi->udf = FALSE;
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback); /* jrw */
#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(0);
}
@@ -2094,9 +2181,13 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback); /* jrw */
#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);
}
@@ -2279,14 +2370,16 @@ unsigned short val; /* used for EFAST operations only */
*
* The reason it is done this way is because the process() call may
* recursively call itself when records are chained and the callback
* task's stack is larger... just for this purpose.
* task's stack is larger... just for that reason.
*
******************************************************************************/
void
devGpibLib_processCallback(pDpvt)
struct gpibDpvt *pDpvt;
devGpibLib_processCallback(CALLBACK *pCallback)
{
struct gpibDpvt *pDpvt;
callbackGetUser(pDpvt, pCallback);
dbScanLock(pDpvt->precord);
(*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord);
dbScanUnlock(pDpvt->precord);
@@ -2462,9 +2555,13 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pwf,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((void *)pdpvt);
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -2509,9 +2606,13 @@ int srqStatus;
{
devGpibLib_setPvSevr(pwf,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((void *)pdpvt);
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_wfGpibFinish(pdpvt); /* and finish the processing */
@@ -2547,9 +2648,14 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
}
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest((void *)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(0);
}

View File

@@ -81,7 +81,7 @@ static long init_record(pmbbo)
case (VME_IO) :
pvmeio = &(pmbbo->out.value.vmeio);
pmbbo->shft = pvmeio->signal;
pmbbo->mask = pmbbo->shft;
pmbbo->mask <<= pmbbo->shft;
status = xy220_read(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = pmbbo->rval = value;
else status = 2;

View File

@@ -83,7 +83,7 @@ static long init_record(pmbbo)
case (VME_IO) :
pvmeio = &(pmbbo->out.value.vmeio);
pmbbo->shft = pvmeio->signal;
pmbbo->mask = pmbbo->shft;
pmbbo->mask <<= pmbbo->shft;
status = xy220_read(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = pmbbo->rval = value;
else status = 2;

View File

@@ -57,6 +57,15 @@
* mgh 1/31/94 Started to add interrupt
* ...
* ...
*
* $Log$
* Revision 1.4 1994/11/30 15:10:23 winans
* Added IRQ mode stuff
*
* Revision 1.3 1994/11/17 21:11:58 winans
* Major restructuring of init code.
*
*
*/
@@ -74,7 +83,6 @@
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <module_types.h>
#include <link.h>
#include <fast_lock.h>
@@ -87,15 +95,19 @@
#include <errMdef.h>
#include <eventRecord.h>
void SysmonInit();
static long init();
static long report();
static long init_bo_record(), init_bi_record();
static long init_mbbo_record(), init_mbbi_record();
static long write_bo(), read_bi();
static long write_mbbo(), read_mbbi();
static long get_ioint_info();
static void Sysmon_isr();
#define NUM_LINKS 1 /* max number of allowed sysmon cards */
#define STATIC
int SysmonConfig();
STATIC long SysmonInit();
STATIC long SysmonReport();
STATIC long SysmonInitBoRec(), SysmonInitBiRec();
STATIC long SysmonInitMbboRec(), SysmonInitMbbiRec();
STATIC long SysmonWriteBo(), SysmonReadBi();
STATIC long SysmonWriteMbbo(), SysmonReadMbbi();
static long SysmonGetIointInfoBi();
STATIC void SysmonIsr();
int devSysmonDebug = 0;
@@ -108,29 +120,39 @@ int devSysmonDebug = 0;
/** devSysmonDebug >= 20 -- read commands **/
struct parm_table {
typedef struct ParmTableStruct
{
char *parm_name;
int index;
};
typedef struct parm_table PARM_TABLE;
} ParmTableStruct;
#define SYSMON_PARM_STATUS 0
#define SYSMON_PARM_DIO 1
#define SYSMON_PARM_TEMP 2
#define SYSMON_PARM_WATCHDOG 3
static PARM_TABLE table[]={
{"StatusLink", 0},
{"Dio", 1},
{"IntMask", 2},
{"Temperature", 3},
{"Watchdog", 4},
{"VXIVector", 5},
{"IntVector", 6},
{"IRQ1", 7},
{"IRQ2", 8},
{"IRQ3", 9},
{"IRQ4", 10},
{"IRQ5", 11},
{"IRQ6", 12},
{"IRQ7", 13}
static ParmTableStruct ParmTable[]=
{
{"StatusLink", SYSMON_PARM_STATUS},
{"Dio", SYSMON_PARM_DIO},
{"Temperature", SYSMON_PARM_TEMP},
{"Watchdog", SYSMON_PARM_WATCHDOG},
#if 0 /* This crap is pointless -- JRW */
{"IntMask", 2},
{"VXIVector", 5},
{"IntVector", 6},
{"IRQ1", 7},
{"IRQ2", 8},
{"IRQ3", 9},
{"IRQ4", 10},
{"IRQ5", 11},
{"IRQ6", 12},
{"IRQ7", 13}
#endif
};
#define PARM_TABLE_SIZE (sizeof(ParmTable)/sizeof(ParmTable[0]))
/*** SysMonStatusLink Rx, Tx ***/
/*** SysmonDio output, input ***/
@@ -147,7 +169,7 @@ static PARM_TABLE table[]={
/*** SysmonIRQ6 IRQ 1 vector ***/
/*** SysmonIRQ7 IRQ 1 vector ***/
struct sysmon {
typedef struct SysmonStruct {
char Pad[36]; /*** nF0 - nF17 36 bytes ***/
unsigned short SysmonStatusLink; /*** nF18 ***/
unsigned short SysmonDio; /*** nF19 ***/
@@ -163,43 +185,42 @@ struct sysmon {
unsigned short SysmonIRQ5; /*** nF29 ***/
unsigned short SysmonIRQ6; /*** nF30 ***/
unsigned short SysmonIRQ7; /*** nF31 ***/
};
}SysmonStruct;
struct pvtarea {
/*****************************************************************************
*
* Per-record private structure hooked onto dpvt.
*
*****************************************************************************/
typedef struct PvtStruct
{
int index;
unsigned short mask;
};
} PvtStruct;
struct ioCard { /* structure maintained for each card */
int cardValid; /* card exists */
volatile unsigned short *ThisCard; /* address of this cards registers */
FAST_LOCK lock; /* semaphore */
IOSCANPVT ioscanpvt; /* list of records that are processed at interrupt */
/*****************************************************************************
*
* Per-card global variables.
*
*****************************************************************************/
struct ioCard { /* structure maintained for each card */
int CardValid; /* card exists */
unsigned long SysmonBaseA16; /* A16 card address */
volatile SysmonStruct *SysmonBase; /* Physical card address */
FAST_LOCK lock; /* semaphore */
IOSCANPVT ioscanpvt; /* Token for I/O intr scanned records */
int VMEintVector; /* IRQ vector used by sysmon */
int VMEintLevel; /* IRQ level */
int VXIintVector; /* Generated when C008 is written to (VXI silliness) */
int IrqInfo[2];
};
#define CONST_NUM_LINKS 1
#define STATIC
static int VMEintVector = 0x71;
static int VMEintLevel = 0x06;
static int VXIintVector = 0x72;
static unsigned short *SYSMON_BASE = (unsigned short *) 0x8b80;
#define INITLEDS 0x01
/* #define int1 0x71 */
/* #define int2 0x72 */
/* #define intlevel 0x06 */
/* #define SYSMON_BASE 0x8b80 hard coded base address */
static struct ioCard cards[NUM_LINKS]; /* card information structure */
#define INITLEDS 0xff
#define mikeOFFSET 0x24 /* where first function starts */
volatile static struct sysmon *sysmon_base; /*base pointer of board */
static struct ioCard cards[CONST_NUM_LINKS]; /* card information structure */
static int init_flag = 0;
static int interrupt_info[2]; /*0x71, 0x72*/
/* Create the dset for devBoSysmon */
struct dset_sysmon {
long number;
DEVSUPFUN report; /* used by dbior */
@@ -210,113 +231,152 @@ struct dset_sysmon {
};
typedef struct dset_sysmon DSET_SYSMON;
DSET_SYSMON devEventSysmon={
5,
NULL,
NULL,
NULL,
get_ioint_info,
NULL
};
DSET_SYSMON devBoSysmon={
5,
NULL,
SysmonInit,
SysmonInitBoRec,
NULL,
init_bo_record,
NULL,
write_bo
SysmonWriteBo
};
/* Create the dset for devBiSysmon */
DSET_SYSMON devBiSysmon={
5,
NULL,
NULL,
init_bi_record,
NULL,
read_bi
SysmonReport,
SysmonInit,
SysmonInitBiRec,
SysmonGetIointInfoBi,
SysmonReadBi
};
/* Create the dset for devMbboSysmon */
DSET_SYSMON devMbboSysmon={
5,
NULL,
SysmonInit,
SysmonInitMbboRec,
NULL,
init_mbbo_record,
NULL,
write_mbbo
SysmonWriteMbbo
};
/* Create the dset for devMbbiSysmon */
DSET_SYSMON devMbbiSysmon={
5,
NULL,
SysmonInit,
SysmonInitMbbiRec,
NULL,
init_mbbi_record,
NULL,
read_mbbi
SysmonReadMbbi
};
STATIC long SysmonReport(void)
{
int j;
for (j=0; j<NUM_LINKS; j++)
{
if (cards[j].CardValid)
{
printf(" card %d: 0x%4.4X VME-IRQ 0x%2.2X VXI-IRQ 0x%2.2X IRQ-level %d\n",
j, cards[j].SysmonBaseA16, cards[j].VMEintVector,
cards[j].VXIintVector, cards[j].VMEintLevel);
}
}
}
/*************************
initialization of the device support
************************/
void SysmonInit(
unsigned long xSYSMON_BASE,
int xVMEintVector,
int xVMEintLevel,
int xVXIintVector
int SysmonConfig(
int Card, /* Which card to set parms for */
unsigned long SysmonBaseA16, /* Base address in A16 */
int VMEintVector, /* IRQ vector used by sysmon */
int VMEintLevel, /* IRQ level */
int VXIintVector /* Generated when C008 is written to (VXI silliness) */
)
{
if ( 64 < xVMEintVector || xVMEintVector < 256 )
VMEintVector = xVMEintVector;
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME int vector = 0x%X\n", VMEintVector);
if ((Card < 0) || (Card >= NUM_LINKS))
{
printf("ERROR: Invalid card number specified %d\n", Card);
return(-1);
}
if ( 0 > xVMEintLevel || xVMEintLevel < 8)
VMEintLevel = xVMEintLevel;
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME int level = %d\n", VMEintLevel);
cards[Card].CardValid = 0;
cards[Card].VMEintVector = 0;
cards[Card].VMEintLevel = 0;
cards[Card].VXIintVector = 0;
cards[Card].SysmonBaseA16 = 0;
cards[Card].IrqInfo[0] = 0;
cards[Card].IrqInfo[1] = 0;
if ( 64 < xVXIintVector || xVXIintVector < 256 )
VXIintVector = xVXIintVector;
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VXI int vector = 0x%X\n", VXIintVector);
if ((VMEintVector < 64) || (VMEintVector > 255))
{
printf("devSysmon: ERROR VME IRQ vector out of range\n");
return(-1);
}
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME int vector = 0x%2.2X\n", VMEintVector);
SYSMON_BASE = (unsigned short *) xSYSMON_BASE;
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME (VXI) base address = 0x%X\n", SYSMON_BASE);
if ((VMEintLevel < 0) || (VMEintLevel > 7))
{
printf("devSysmon: ERROR VME IRQ level out of range\n");
return(-1);
}
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME int level = %d\n", VMEintLevel);
interrupt_info[0] = VMEintVector; /*0x71*/
interrupt_info[1] = VXIintVector; /*0x72*/
init(0);
if ((VXIintVector < 64) || (VXIintVector > 255))
{
printf("devSysmon: ERROR VXI IRQ vector out of range\n");
return(-1);
}
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VXI int vector = 0x%2.2X\n", VXIintVector);
}
if ((SysmonBaseA16 > 0xffff) || (SysmonBaseA16 & 0x003f))
{
printf("devSysmon: ERROR Invalid address specified 0x4.4X\n", SysmonBaseA16);
return(-1);
}
if (devSysmonDebug >= 5)
printf("devSysmon: SysmonInit VME (VXI) base address = %p\n", SysmonBaseA16);
cards[Card].VMEintVector = VMEintVector;
cards[Card].VMEintLevel = VMEintLevel;
cards[Card].VXIintVector = VXIintVector;
cards[Card].SysmonBaseA16 = SysmonBaseA16;
cards[Card].IrqInfo[0] = VMEintVector; /*0x71*/
cards[Card].IrqInfo[1] = VXIintVector; /*0x72*/
cards[Card].CardValid = 1;
return(0);
}
/**************************************************
initialization of isr
************************************************/
**************************************************/
static void Sysmon_isr(IOSCANPVT ioscanpvt)
STATIC void SysmonIsr(int Card)
{
logMsg("In Sysmon_isr\n");
scanIoRequest(ioscanpvt);
if (devSysmonDebug >= 10)
logMsg("In SysmonIsr\n");
scanIoRequest(cards[Card].ioscanpvt);
cards[Card].SysmonBase->SysmonIntMask |= 0xff00;
}
/**************************************************************************
*
* Initialization of SYSMON Binary I/O Card
*
***************************************************************************/
static long init(int flag)
STATIC long SysmonInit(int flag)
{
int j;
unsigned char probeVal, initVal;
struct sysmon *sm;
int Card;
unsigned short probeVal;
static int init_flag = 0;
if (init_flag != 0)
@@ -324,60 +384,59 @@ static long init(int flag)
init_flag = 1;
if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char *)SYSMON_BASE, (char **)&sysmon_base) == ERROR)
{
if (devSysmonDebug >= 5)
printf("devSysmon: can not find short address space\n");
return(ERROR);
}
/* We end up here 1 time before all records are initialized */
for (j=0; j < CONST_NUM_LINKS; j++)
for (Card=0; Card < NUM_LINKS; Card++)
{
if (cards[Card].CardValid != 0)
{
if (devSysmonDebug >= 5)
printf("devSysmon: init link %d\n", j);
printf("devSysmon: init link %d\n", Card);
if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char *)cards[Card].SysmonBaseA16, (char **)&(cards[Card].SysmonBase)) == ERROR)
{
if (devSysmonDebug >= 5)
printf("devSysmon: can not find short address space\n");
return(ERROR); /* BUG */
}
probeVal = INITLEDS;
if (devSysmonDebug >= 5)
printf("devSysmon: init SysmonWatchdog 0x%X\n", (char *)&sysmon_base[j].SysmonWatchdog);
printf("devSysmon: init SysmonWatchdog 0x%X\n", (char *)&cards[Card].SysmonBase->SysmonWatchdog);
if (vxMemProbe((char *)&sysmon_base[j].SysmonWatchdog, WRITE, sizeof(probeVal), &probeVal) != OK)
if (vxMemProbe((char *)&cards[Card].SysmonBase->SysmonWatchdog, WRITE, sizeof(cards[Card].SysmonBase->SysmonWatchdog), (char *)&probeVal) != OK)
{
cards[j].cardValid = 0; /* No card found */
cards[Card].CardValid = 0; /* No card found */
if (devSysmonDebug >= 5)
printf("devSysmon: init vxMemProbe FAILED\n");
}
else
{
probeVal = 0;
vxMemProbe((char *)&sysmon_base[j].SysmonIntMask, WRITE, sizeof(probeVal), &probeVal);
cards[j].cardValid = 1; /* Remember address of the board */
FASTLOCKINIT(&(cards[j].lock));
FASTUNLOCK(&(cards[j].lock)); /* Init the board lock */
cards[j].ThisCard = &sysmon_base[j].SysmonStatusLink;
cards[Card].SysmonBase->SysmonIntMask = 0;
FASTLOCKINIT(&(cards[Card].lock));
/* FASTUNLOCK(&(cards[Card].lock)); /* Init the board lock */
if (devSysmonDebug >= 5)
printf("devSysmon: init address\n");
scanIoInit(&cards[j].ioscanpvt); /* interrupt initialized */
scanIoInit(&cards[Card].ioscanpvt); /* interrupt initialized */
if (devSysmonDebug >= 5)
printf("devSysmon: init ScanIoInit \n");
sm = (struct sysmon *) &sysmon_base[j];
if (devSysmonDebug >= 5)
printf("devSysmon: init address of System Monitor %8.8x \n", sm);
printf("devSysmon: init address of System Monitor %8.8x \n", cards[Card].SysmonBase);
sm->SysmonIntVector = interrupt_info[0];
cards[Card].SysmonBase->SysmonIntVector = cards[Card].VMEintVector;
if (devSysmonDebug >= 5)
printf("devSysmon: init Interrupt vector loaded \n");
if(intConnect(INUM_TO_IVEC(interrupt_info[j]),(FUNCPTR)Sysmon_isr,
(int)cards[j].ioscanpvt)!=OK) {
errPrintf(M_devSup, __FILE__, __LINE__, "devSysmon (init) intConnect failed \n");
return(M_devSup);
if(intConnect(INUM_TO_IVEC(cards[Card].VMEintVector),(FUNCPTR)SysmonIsr, Card)!=OK)
{
printf("devSysmon (init) intConnect failed \n");
return(ERROR);
if (devSysmonDebug >= 5)
printf("devSysmon: init intConnect\n");
@@ -388,6 +447,8 @@ static long init(int flag)
printf("devSysmon: init vxMemProbe OK\n");
}
sysIntEnable(cards[Card].VMEintLevel);
}
}
return(OK);
}
@@ -398,21 +459,19 @@ static long init(int flag)
static long generic_init_record(struct dbCommon *pr, DBLINK *link)
{
struct vmeio* pvmeio = (struct vmeio*)&(link->value);
int table_size, j;
struct pvtarea * pvt;
struct vmeio *pvmeio = (struct vmeio*)&(link->value);
int j;
PvtStruct *pvt;
switch (link->type)
if (link->type != VME_IO)
{
case (VME_IO) : break;
default:
recGblRecordError(S_dev_badBus,(void *)pr,
"devSysmon (init_record) Illegal Bus Type");
return(S_dev_badBus);
}
/* makes sure that signal is valid */
if (pvmeio->signal > 15)
/* make sure that signal is valid */
if ((pvmeio->signal > 15) || (pvmeio->signal < 0))
{
pr->pact = 1; /* make sure we don't process this thing */
@@ -425,14 +484,14 @@ static long generic_init_record(struct dbCommon *pr, DBLINK *link)
}
/* makes sure that card is valid */
if (pvmeio->card > CONST_NUM_LINKS || !cards[pvmeio->card].cardValid )
if ((pvmeio->card > NUM_LINKS) || (pvmeio->card < 0) || (!cards[pvmeio->card].CardValid))
{
pr->pact = 1; /* make sure we don't process this thing */
if (devSysmonDebug >= 10)
{
printf("devSysmon: Illegal CARD field ->%s, %d<- \n", pr->name, pvmeio->card);
if(!cards[pvmeio->card].cardValid)
if(!cards[pvmeio->card].CardValid)
printf("devSysmon: Illegal CARD field card NOT VALID \n\n");
}
@@ -442,11 +501,9 @@ static long generic_init_record(struct dbCommon *pr, DBLINK *link)
}
/* verifies that parm field is valid */
table_size = sizeof(table) / sizeof(PARM_TABLE);
for (j = 0; (j < table_size) && strcmp(table[j].parm_name, pvmeio->parm); j++ );
for (j = 0; (j < PARM_TABLE_SIZE) && strcmp(ParmTable[j].parm_name, pvmeio->parm); j++ );
if (j >= table_size)
if (j >= PARM_TABLE_SIZE)
{
pr->pact = 1; /* make sure we don't process this thing */
@@ -458,9 +515,9 @@ static long generic_init_record(struct dbCommon *pr, DBLINK *link)
return(S_dev_badSignal);
}
if (devSysmonDebug >= 10)
printf("devSysmon: %s of record type %d - %s\n", pr->name, j, table[j].parm_name);
printf("devSysmon: %s of record type %d - %s\n", pr->name, j, ParmTable[j].parm_name);
pvt = (struct pvtarea *) malloc(sizeof(struct pvtarea));
pvt = (PvtStruct *) malloc(sizeof(PvtStruct));
pvt->index = j;
pr->dpvt = pvt;
@@ -474,21 +531,17 @@ static long generic_init_record(struct dbCommon *pr, DBLINK *link)
* BO Initialization (Called one time for each BO SYSMON card record)
*
**************************************************************************/
static long init_bo_record(struct boRecord *pbo)
STATIC long SysmonInitBoRec(struct boRecord *pbo)
{
struct vmeio* pvmeio = (struct vmeio*)&(pbo->out.value);
int status = 0;
int table_size;
struct pvtarea * pvt;
status = generic_init_record((struct dbCommon *)pbo, &pbo->out);
if(status)
return(status);
pvt = pbo->dpvt;
pvt->mask = 1<<pvmeio->signal;
((PvtStruct *)(pbo->dpvt))->mask = 1<<pvmeio->signal;
return (0);
}
@@ -498,21 +551,17 @@ static long init_bo_record(struct boRecord *pbo)
* BI Initialization (Called one time for each BI SYSMON card record)
*
**************************************************************************/
static long init_bi_record(struct biRecord *pbi)
STATIC long SysmonInitBiRec(struct biRecord *pbi)
{
struct vmeio* pvmeio = (struct vmeio*)&(pbi->inp.value);
int status = 0;
int table_size;
struct pvtarea * pvt;
status = generic_init_record((struct dbCommon *)pbi, &pbi->inp);
if(status)
return(status);
pvt = pbi->dpvt;
pvt->mask = 1<<pvmeio->signal;
((PvtStruct *)(pbi->dpvt))->mask = 1<<pvmeio->signal;
return (0);
}
@@ -523,26 +572,16 @@ static long init_bi_record(struct biRecord *pbi)
* MBBO Initialization (Called one time for each MBBO SYSMON card record)
*
**************************************************************************/
static long init_mbbo_record(struct mbboRecord *pmbbo)
STATIC long SysmonInitMbboRec(struct mbboRecord *pmbbo)
{
struct vmeio* pvmeio = (struct vmeio*)&(pmbbo->out.value);
int status = 0;
int table_size;
struct pvtarea * pvt;
status = generic_init_record((struct dbCommon *)pmbbo, &pmbbo->out);
if(status)
return(status);
if (pvmeio->signal > 15)
{
recGblRecordError(S_dev_badSignal,(void *)pmbbo,
"devSysmon(init_mbbo_record) Illegal OUT signal number");
return(S_dev_badSignal);
}
pvt = pmbbo->dpvt;
pmbbo->shft = pvmeio->signal;
pmbbo->mask <<= pmbbo->shft;
@@ -556,18 +595,16 @@ static long init_mbbo_record(struct mbboRecord *pmbbo)
*
**************************************************************************/
static long init_mbbi_record(struct mbbiRecord *pmbbi)
STATIC long SysmonInitMbbiRec(struct mbbiRecord *pmbbi)
{
struct vmeio* pvmeio = (struct vmeio*)&(pmbbi->inp.value);
int status = 0;
int table_size;
struct pvtarea * pvt;
status = generic_init_record((struct dbCommon *)pmbbi, &pmbbi->inp);
/* load temperature values up */
/* load temperature values up */
if (!strcmp(table[3].parm_name, pvmeio->parm))
if (!strcmp(ParmTable[SYSMON_PARM_TEMP].parm_name, pvmeio->parm))
{
if (devSysmonDebug >= 10)
printf("devSysmon: mbbi record is Temperature\n");
@@ -614,14 +651,6 @@ static long init_mbbi_record(struct mbbiRecord *pmbbi)
if(status)
return(status);
if (pvmeio->signal > 15)
{
recGblRecordError(S_dev_badSignal,(void *)pmbbi,
"devSysmon(init_mbbi_record) Illegal IN signal number");
return(S_dev_badSignal);
}
pvt = pmbbi->dpvt;
pmbbi->shft = pvmeio->signal;
pmbbi->mask <<= pmbbi->shft;
@@ -633,29 +662,33 @@ static long init_mbbi_record(struct mbbiRecord *pmbbi)
* Perform a write operation from a BO record
*
**************************************************************************/
static long write_bo(struct boRecord *pbo)
STATIC long SysmonWriteBo(struct boRecord *pbo)
{
struct pvtarea *pvt = pbo->dpvt;
struct vmeio *pvmeio = (struct vmeio*)&(pbo->out.value);
volatile unsigned short *reg;
unsigned short regVal;
PvtStruct *pvt = (PvtStruct *)pbo->dpvt;
FASTLOCK(&cards[pvmeio->card].lock);
reg = &cards[pvmeio->card].ThisCard[pvt->index];
regVal = *reg;
if(pbo->val)
switch (pvt->index)
{
regVal |= pvt->mask;
}
else
{
regVal &= ~pvt->mask;
case SYSMON_PARM_DIO:
if (pbo->val)
cards[pvmeio->card].SysmonBase->SysmonDio |= pvt->mask;
else
cards[pvmeio->card].SysmonBase->SysmonDio &= ~pvt->mask;
break;
case SYSMON_PARM_WATCHDOG:
if (pbo->val)
cards[pvmeio->card].SysmonBase->SysmonWatchdog |= pvt->mask;
else
cards[pvmeio->card].SysmonBase->SysmonWatchdog &= ~pvt->mask;
break;
}
*reg = regVal;
FASTUNLOCK(&cards[pvmeio->card].lock);
return(0);
}
@@ -664,19 +697,30 @@ static long write_bo(struct boRecord *pbo)
* Perform a read operation from a BI record
*
**************************************************************************/
static long read_bi(struct biRecord *pbi)
STATIC long SysmonReadBi(struct biRecord *pbi)
{
struct pvtarea *pvt = pbi->dpvt;
struct vmeio *pvmeio = (struct vmeio*)&(pbi->inp.value);
volatile unsigned short *reg;
unsigned short regVal;
reg = &cards[pvmeio->card].ThisCard[pvt->index];
unsigned short regVal = 0;
PvtStruct *pvt = (PvtStruct *)pbi->dpvt;
FASTLOCK(&cards[pvmeio->card].lock);
regVal = *reg;
switch (pvt->index)
{
case SYSMON_PARM_STATUS:
regVal = cards[pvmeio->card].SysmonBase->SysmonStatusLink;
break;
case SYSMON_PARM_DIO:
regVal = cards[pvmeio->card].SysmonBase->SysmonDio;
break;
case SYSMON_PARM_WATCHDOG:
regVal = cards[pvmeio->card].SysmonBase->SysmonWatchdog;
break;
}
FASTUNLOCK(&cards[pvmeio->card].lock);
if (devSysmonDebug)
printf("read 0x%2.2X, masking with 0x%2.2X\n", regVal, pvt->mask);
regVal &= pvt->mask;
if(regVal)
@@ -693,18 +737,17 @@ static long read_bi(struct biRecord *pbi)
* Perform a write operation from a MBBO record
*
**************************************************************************/
static long write_mbbo(struct mbboRecord *pmbbo)
STATIC long SysmonWriteMbbo(struct mbboRecord *pmbbo)
{
struct pvtarea *pvt = pmbbo->dpvt;
struct vmeio *pvmeio = (struct vmeio*)&(pmbbo->out.value);
volatile unsigned short *reg;
unsigned short regVal;
FASTLOCK(&cards[pvmeio->card].lock);
reg = &cards[pvmeio->card].ThisCard[pvt->index];
regVal = *reg;
regVal = cards[pvmeio->card].SysmonBase->SysmonTemperature;
regVal = (regVal & ~pmbbo->mask) | (pmbbo->rval & pmbbo->mask);
*reg = regVal;
cards[pvmeio->card].SysmonBase->SysmonTemperature = regVal;
FASTUNLOCK(&cards[pvmeio->card].lock);
return(0);
@@ -715,48 +758,55 @@ static long write_mbbo(struct mbboRecord *pmbbo)
* Perform a read operation from a MBBI record
*
**************************************************************************/
static long read_mbbi(struct mbbiRecord *pmbbi)
STATIC long SysmonReadMbbi(struct mbbiRecord *pmbbi)
{
struct pvtarea *pvt = pmbbi->dpvt;
struct vmeio *pvmeio = (struct vmeio*)&(pmbbi->inp.value);
volatile unsigned short *reg;
unsigned short regVal;
reg = &cards[pvmeio->card].ThisCard[pvt->index];
FASTLOCK(&cards[pvmeio->card].lock);
regVal = *reg;
regVal = cards[pvmeio->card].SysmonBase->SysmonTemperature;
FASTUNLOCK(&cards[pvmeio->card].lock);
pmbbi->rval=regVal&pmbbi->mask;
pmbbi->rval=regVal & pmbbi->mask;
pmbbi->udf = 0;
return(0);
}
/*****************************************************
record support interrupt routine
***************************************************/
*
* cmd = 0 if being added
* cmd = 1 if taken off the I/O Event scanned list
*
****************************************************/
static long get_ioint_info(
static long SysmonGetIointInfoBi(
int cmd,
struct eventRecord *pr,
struct biRecord *pr,
IOSCANPVT *ppvt)
{
struct vmeio *pvmeio = (struct vmeio *)(&pr->inp.value);
unsigned int card,intvec;
int intmask;
if(pvmeio->card > CONST_NUM_LINKS) {
if(pvmeio->card > NUM_LINKS) {
recGblRecordError(S_dev_badCard,(void *)pr,
"devSysmon (get_int_info) exceeded maximum supported cards");
return(S_dev_badCard);
}
*ppvt = cards[pvmeio->card].ioscanpvt;
if (cmd == 0)
sysIntEnable(VMEintLevel);
{
intmask = (((PvtStruct *)(pr->dpvt))->mask)>>8;
if (devSysmonDebug)
printf("SysmonGetIointInfoBi mask is %2.2X\n", intmask);
cards[pvmeio->card].SysmonBase->SysmonIntMask |= intmask;
}
return(0);
}

View File

@@ -7,17 +7,20 @@ USR_INCLUDES = -I../../drv
SRCS.c = \
../devAnalytekGpib.c ../devXxDg535Gpib.c ../devBBInteract.c \
../devGpibInteract.c ../devXxSr620Gpib.c ../devK486Gpib.c \
../devXxK196Gpib.c ../devXxDc5009Gpib.c ../devXxK263Gpib.c
../devXxK196Gpib.c ../devXxDc5009Gpib.c ../devXxK263Gpib.c \
../devXxSkeletonGpib.c
OBJS = \
devAnalytekGpib.o devXxDg535Gpib.o devBBInteract.o \
devGpibInteract.o devXxSr620Gpib.o devK486Gpib.o \
devXxK196Gpib.o devXxDc5009Gpib.o devXxK263Gpib.o
devXxK196Gpib.o devXxDc5009Gpib.o devXxK263Gpib.o \
devXxSkeletonGpib.o
PROD = devLibOpt
PROD = devLibOpt $(OBJS)
include $(EPICS)/config/RULES.Vx
devLibOpt: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -139,8 +139,10 @@ int GI(void)
for (cnt=0; cnt < LIST_SIZE; cnt++)
{ /* init the elements of the command table */
#if 0
gpibIntCmds[cnt].head.header.list.list1 = NULL;
gpibIntCmds[cnt].head.header.list.list2 = NULL;
#endif
gpibIntCmds[cnt].head.workStart = gpibWork;
gpibIntCmds[cnt].head.link = 0;
gpibIntCmds[cnt].head.device = 0;
@@ -155,7 +157,7 @@ int GI(void)
}
ans = 0; /* set loop not to exit */
printf("\n\n");
logMsg("\n\n");
while ((ans != 'q') && (ans != 'Q'))
{
@@ -380,6 +382,8 @@ static int sendMsg(void)
if (replyIsBack)
{
if (ibDebug)
taskDelay(60); /* Allow debug printing to complete */
showGpibMsg(msgNum);
}
else
@@ -438,7 +442,7 @@ static int gpibWork(struct gpibIntCmd *pCmd)
}
else if (status > (MAX_MSG_LENGTH - 1)) /* check length of resp */
{
printf("GPIB Response length equaled allocated space !!!\n");
logMsg("GPIB Response length equaled allocated space !!!\n");
pCmd->resp[(MAX_MSG_LENGTH)] = '\0'; /* place \0 at end */
}
else

View File

@@ -391,8 +391,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else

View File

@@ -404,9 +404,9 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest(phwpvt->unsolicitedDpvt);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else
{

View File

@@ -282,8 +282,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else

View File

@@ -4,28 +4,73 @@ include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield -traditional
SRCS.c = \
../module_types.c ../drvXy010.c ../drvAb.c ../drvBb902.c \
../drvBb910.c ../drvCompuSm.c ../drvDvx.c ../drvMz8310.c \
../drvOms.c ../drvStc.c ../drvTime.c ../drvVmi4100.c \
../drvXy210.c ../drvXy220.c ../drvXy240.c \
../drvXy566.c ../drvAt5Vxi.c ../drvHp1404a.c ../drvEpvxi.c \
../drvEpvxiMsg.c ../drvBitBus.c ../drvGpib.c \
../drvMsg.c ../drvBB232.c ../drvHpe1368a.c ../drvHpe1445a.c \
../drvKscV215.c ../drvComet.c ../drvJgvtr1.c ../drvFp.c \
../drvMvme162.c ../drvFpm.c
../module_types.c\
../drvXy010.c\
../drvAb.c\
../drvBb902.c\
../drvBb910.c\
../drvCompuSm.c\
../drvDvx.c\
../drvMz8310.c\
../drvOms.c\
../drvStc.c\
../drvTime.c\
../drvVmi4100.c\
../drvXy210.c\
../drvXy220.c\
../drvXy240.c\
../drvXy566.c\
../drvAt5Vxi.c\
../drvHp1404a.c\
../drvEpvxi.c\
../drvEpvxiMsg.c\
../drvBitBus.c\
../drvGpib.c\
../drvMsg.c\
../drvBB232.c\
../drvHpe1368a.c\
../drvHpe1445a.c\
../drvKscV215.c\
../drvComet.c\
../drvJgvtr1.c\
../drvFp.c\
../drvMvme162.c\
../drvFpm.c
OBJS = \
module_types.o drvXy010.o drvAb.o drvBb902.o \
drvBb910.o drvCompuSm.o drvDvx.o drvMz8310.o \
drvOms.o drvStc.o drvTime.o drvVmi4100.o \
drvXy210.o drvXy220.o drvXy240.o \
drvXy566.o drvAt5Vxi.o drvHp1404a.o drvEpvxi.o \
drvEpvxiMsg.o drvBitBus.o drvGpib.o \
drvMsg.o drvBB232.o drvHpe1368a.o drvHpe1445a.o \
drvKscV215.o drvComet.o drvJgvtr1.o drvFp.o \
drvMvme162.o drvFpm.o
module_types.o\
drvXy010.o\
drvAb.o\
drvBb902.o\
drvBb910.o\
drvCompuSm.o\
drvDvx.o\
drvMz8310.o\
drvOms.o\
drvStc.o\
drvTime.o\
drvVmi4100.o\
drvXy210.o\
drvXy220.o\
drvXy240.o\
drvXy566.o\
drvAt5Vxi.o\
drvHp1404a.o\
drvEpvxi.o\
drvEpvxiMsg.o\
drvBitBus.o\
drvGpib.o\
drvMsg.o\
drvBB232.o\
drvHpe1368a.o\
drvHpe1445a.o\
drvKscV215.o\
drvComet.o\
drvJgvtr1.o\
drvFp.o\
drvMvme162.o\
drvFpm.o
PROD = drvSup
@@ -35,3 +80,6 @@ $(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)
# ../drvCaenV265.c\
# drvCaenV265.o\

View File

@@ -65,6 +65,16 @@
* This driver currently needs work on error message generation.
*
* $Log$
* Revision 1.35 1994/12/12 16:02:57 winans
* Rewrote the init code so that it always returns a zero (don't kill the
* startup.cmd file.) It is possible that this could cause some confusion
* to the database, should it decide to then use a link that did not init
* properly.
*
* Revision 1.34 1994/10/19 18:31:22 winans
* ANSIfied the bitbus driver so that the compiler stopped warning about
* exery third line of code.
*
* Revision 1.33 1994/10/04 18:42:42 winans
* Added an extensive debugging facility.
*
@@ -129,6 +139,8 @@ STATIC int bbKill(int link);
STATIC void BBrebootFunc(void);
STATIC int txStuck(int link);
int BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int __BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#ifdef BB_SUPER_DEBUG
int BBHistDump(int link);
@@ -157,7 +169,7 @@ int XycomMaxOutstandMsgs = XYCOM_BB_MAX_OUTSTAND_MSGS;
* To disable this feature, set one of them to -1.
*
*****************************************************************************/
int bbDebug = 0;
int bbDebug = 1;
int bbDebugLink=-1;
int bbDebugNode=-1;
@@ -199,7 +211,16 @@ int BBConfig(unsigned long Link,
unsigned long IrqVector,
unsigned long IrqLevel)
{
__BBConfig(Link, LinkType, BaseAddr, IrqVector, IrqLevel);
return(0);
}
int __BBConfig(unsigned long Link,
unsigned long LinkType,
unsigned long BaseAddr,
unsigned long IrqVector,
unsigned long IrqLevel)
{
void *pVoid;
int j;
static int FirstTime = 1;
@@ -419,7 +440,7 @@ STATIC long reportBB(void)
{
int i;
if (bbDebug)
if (bbDebug>1)
printf("Bitbus debugging flag is set to %d\n", bbDebug);
for (i=0; i< BB_NUM_LINKS; i++)
@@ -468,8 +489,10 @@ pepReset(int link)
taskDelay(20); /* give the 80152 time to self check */
if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & 0x10) != 0x0) {
printf("pepReset(%d): PB-BIT firmware reset failed!\n", link);
if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & 0x10) != 0x0)
{
if (bbDebug)
printf("pepReset(%d): PB-BIT firmware reset failed!\n", link);
return(ERROR);
}
@@ -480,7 +503,8 @@ pepReset(int link)
if (!j)
{
printf("pepReset(%d): receive fifo will not clear after reset!\n", link);
if (bbDebug)
printf("pepReset(%d): receive fifo will not clear after reset!\n", link);
return(ERROR);
}
@@ -532,7 +556,8 @@ STATIC int xvmeReset(int link)
if (!j)
{
printf("xvmeReset(%d): Command buffer will not clear after reset!\n", link);
if (bbDebug)
printf("xvmeReset(%d): Command buffer will not clear after reset!\n", link);
return(ERROR);
}
@@ -542,13 +567,15 @@ STATIC int xvmeReset(int link)
if (!j)
{
printf("xvmeReset(%d): Data buffer will not clear after reset!\n", link);
if (bbDebug)
printf("xvmeReset(%d): Data buffer will not clear after reset!\n", link);
return(ERROR);
}
if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_FSVALID) != XVME_FSIDLE)
{
printf("xvmeReset(%d): XVME board not returning to idle status after reset!\n", link);
if (bbDebug)
printf("xvmeReset(%d): XVME board not returning to idle status after reset!\n", link);
return(ERROR);
}
@@ -846,7 +873,8 @@ xvmeRxTask(int link)
{ /* something bad happened... inject a delay to the */
/* requested timeout duration. */
printf("xvmeRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[2]);
if (bbDebug)
printf("xvmeRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[2]);
(pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire;
pBBLink[link]->DelayCount++;
}
@@ -892,17 +920,6 @@ xvmeRxTask(int link)
rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */
rxState = BBRX_DATA; /* finish reading till RCMD */
#if 0
if (bbDebug)
{
printf("xvmeRxTask(%d): msg from node %d unsolicited!\nHeader:", link, rxHead[2]);
rxDpvtHead->rxMsg.length = 7; /* we just have the header now */
drvBitBusDumpMsg(&(rxDpvtHead->rxMsg));
}
semGive(pXvmeLink[link]->pbbLink->busyList.sem);
rxState = BBRX_IGN; /* nothing waiting... toss it */
#endif
}
break;
@@ -935,7 +952,8 @@ xvmeRxTask(int link)
if (rxDpvtHead == NULL)
{
ch = pBBLink[link]->l.XycomLink.bbRegs->cmnd;
printf("xvmeRxTask(%d): got unexpected XVME_RCMD\n", link);
if (bbDebug)
printf("xvmeRxTask(%d): got unexpected XVME_RCMD\n", link);
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, NULL, XACT_HIST_STATE_RX_URCMD);
#endif
@@ -945,7 +963,7 @@ xvmeRxTask(int link)
rxDpvtHead->status = BB_OK;
rxDpvtHead->rxCmd = pBBLink[link]->l.XycomLink.bbRegs->cmnd;
/* if (bbDebug) */
if (bbDebug)
{
printf("xvmeRxTask(%d): msg from node %d unsolicited:", link, rxDpvtHead->rxMsg.node);
drvBitBusDumpMsg(&(rxDpvtHead->rxMsg));
@@ -1008,14 +1026,14 @@ xvmeRxTask(int link)
/* Tell the watch dog I am ready for the reset (reset in the dog task) */
pBBLink[link]->rxAbortAck = 1;
/* if (bbDebug) */
if (bbDebug)
printf("xvmeRxTask(%d): resetting due to abort status\n", link);
/* wait for link state to become active again */
while (pBBLink[link]->abortFlag != 0)
taskDelay(RESET_POLL_TIME);
/* if bbDebug) */
if (bbDebug)
printf("xvmeRxTask(%d): restarting after abort\n", link);
}
}
@@ -1134,7 +1152,7 @@ xvmeWdTask(int link)
/* Get rid of the request and set error status etc... */
listDel(&(pBBLink[link]->busyList), pnode);
/*if (bbDebug)*/
if (bbDebug)
{
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT);
@@ -1172,7 +1190,8 @@ xvmeWdTask(int link)
{ /* Send out a RAC_NODE_OFFLINE to the controller */
semGive(pBBLink[link]->busyList.sem);
printf("issuing a node offline for link %d node %d\n", link, resetNodeData);
if (bbDebug)
printf("issuing a node offline for link %d node %d\n", link, resetNodeData);
semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER);
listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode);
@@ -1182,7 +1201,8 @@ printf("issuing a node offline for link %d node %d\n", link, resetNodeData);
if (semTake(syncSem, sysClkRateGet()/4) == ERROR)
{
printf("xvmeWdTask(%d): link dead, trying manual reboot\n", link);
if (bbDebug)
printf("xvmeWdTask(%d): link dead, trying manual reboot\n", link);
pBBLink[link]->nukeEm = 1;
pBBLink[link]->abortFlag = 1; /* Start the abort sequence */
@@ -1286,13 +1306,13 @@ xvmeTxTask(int link)
BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT);
#endif
/* if (bbDebug) */
if (bbDebug)
printf("xvmeTxTask(%d): resetting due to abort status\n", link);
while (pBBLink[link]->abortFlag != 0)
taskDelay(RESET_POLL_TIME); /* wait for link to reset */
/* if (bbDebug) */
if (bbDebug)
printf("xvmeTxTask(%d): restarting after abort\n", link);
}
else
@@ -1325,7 +1345,8 @@ xvmeTxTask(int link)
if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0)
&& (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now))
{
printf("xvmeTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node);
if (bbDebug)
printf("xvmeTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node);
(pBBLink[link]->deviceStatus[pnode->txMsg.node])--;
pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0;
pBBLink[link]-> DelayCount--;
@@ -1397,7 +1418,7 @@ xvmeTxTask(int link)
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET);
#endif
/* if (bbDebug) */
if (bbDebug)
printf("xvmeTxTask(%d): RAC_RESET_SLAVE sent, resetting node %d\n", link, pnode->txMsg.node);
pnode->status = BB_OK;
@@ -1471,8 +1492,11 @@ xvmeTxTask(int link)
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_ABORT);
#endif
printf("Message in progress when abort issued:\n");
drvBitBusDumpMsg(&pnode->txMsg);
if (bbDebug)
{
printf("Message in progress when abort issued:\n");
drvBitBusDumpMsg(&pnode->txMsg);
}
}
/* BUG -- I don't really need this */
/* break;*/ /* stop checking the fifo queues */
@@ -1495,7 +1519,7 @@ xvmeTxTask(int link)
******************************************************************************/
STATIC int txStuck(int link)
{
/* if (bbDebug) */
if (bbDebug)
printf("bitbus transmitter task stuck, resetting link %d\n", link);
bbReset(link);
@@ -1523,14 +1547,6 @@ STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio)
errMessage(S_BB_badPrio, message);
return(ERROR);
}
#if 0
if (checkLink(pdpvt->link) == ERROR)
{
sprintf(message, "invalid link requested in call to qbbreq(%8.8X, %d)\n", pdpvt, prio);
errMessage(S_BB_rfu1, message);
return(ERROR);
}
#else
if (checkLink(pdpvt->link) == ERROR)
{
if (pdpvt->link >= BB_NUM_LINKS)
@@ -1546,7 +1562,6 @@ STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio)
}
return(ERROR);
}
#endif
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(pdpvt->link, pdpvt, XACT_HIST_STATE_QUEUE);
@@ -1945,7 +1960,8 @@ pepRxTask(int link)
if (rxHead[6] == 0x91)
{ /* something bad happened... inject a delay to the */
/* requested timeout duration. */
printf("pepRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[4]);
if (bbDebug)
printf("pepRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[4]);
(pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire;
pBBLink[link]->DelayCount++;
}
@@ -1990,21 +2006,6 @@ pepRxTask(int link)
rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */
rxState = BBRX_DATA; /* finish reading till RCMD */
#if 0 /* relocated to later spot in function */
if (rxDpvtHead == NULL)
{
if (bbDebug > 9)
{
printf("pepRxTask(%d): msg from node %d unsolicited!\n",
link, rxHead[4]);
printf("contents: %2.2x %2.2x %2.2x %2.2x %2.2x\n",rxHead[2],
rxHead[3],rxHead[4],rxHead[5],rxHead[6]);
}
semGive(pXvmeLink[link]->pbbLink->busyList.sem);
rxState = BBRX_IGN; /* nothing waiting... toss it */
}
#endif
}
break;
@@ -2044,7 +2045,7 @@ pepRxTask(int link)
else if (rxDpvtHead == &UselessMsg)
{
rxDpvtHead->status = BB_OK;
/* if (bbDebug) */
if (bbDebug)
{
printf("pepRxTask(%d): msg from node %d unsolicited:\n", link, rxDpvtHead->rxMsg.node);
drvBitBusDumpMsg(&(rxDpvtHead->rxMsg));
@@ -2107,15 +2108,15 @@ pepRxTask(int link)
/* Tell the watch dog I am ready for the reset (reset in the dog task) */
pBBLink[link]->rxAbortAck = 1;
/* if (bbDebug) */
printf("pepRxTask(%d): resetting due to abort status\n", link);
if (bbDebug)
printf("pepRxTask(%d): resetting due to abort status\n", link);
/* wait for link state to become active again */
while (pBBLink[link]->abortFlag != 0)
taskDelay(RESET_POLL_TIME);
/* if bbDebug) */
printf("pepRxTask(%d): restarting after abort\n", link);
if (bbDebug)
printf("pepRxTask(%d): restarting after abort\n", link);
}
}
}
@@ -2233,9 +2234,11 @@ STATIC int pepWdTask(int link)
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT);
#endif
/* printf("pepWdTask(%d): TIMEOUT on xact 0x%8.8X\n", link, pnode);*/
printf("pepWdTask(%d): TIMEOUT on bitbus message:\n", link);
drvBitBusDumpMsg(&pnode->txMsg);
if (bbDebug)
{
printf("pepWdTask(%d): TIMEOUT on bitbus message:\n", link);
drvBitBusDumpMsg(&pnode->txMsg);
}
/* BUG -- do this here or defer until RX gets a response? */
(pBBLink[link]->deviceStatus[pnode->txMsg.node])--; /* fix device status */
@@ -2284,8 +2287,11 @@ STATIC int pepWdTask(int link)
semGive(pBBLink[link]->linkEventSem); /* Tell TxTask to send the messages */
if (semTake(syncSem, (sysClkRateGet()) ) == ERROR) {
printf("pepWdTask(%d): link dead, trying manual reboot\n", link);
if (semTake(syncSem, (sysClkRateGet()) ) == ERROR)
{
if (bbDebug)
printf("pepWdTask(%d): link dead, trying manual reboot\n", link);
pBBLink[link]->nukeEm = 1;
pBBLink[link]->abortFlag = 1;
semGive(pBBLink[link]->linkEventSem);
@@ -2373,7 +2379,7 @@ STATIC int pepTxTask(int link)
register int x;
unsigned long now;
if (bbDebug)
if (bbDebug>1)
printf("pepTxTask started for link %d\n", link);
while(1) {
@@ -2385,12 +2391,14 @@ STATIC int pepTxTask(int link)
BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT);
#endif
printf("pepTxTask(%d): resetting due to abort status\n", link);
if (bbDebug)
printf("pepTxTask(%d): resetting due to abort status\n", link);
while (pBBLink[link]->abortFlag != 0)
taskDelay(RESET_POLL_TIME); /* wait for link to reset */
printf("pepTxTask(%d): restarting after abort\n", link);
if (bbDebug)
printf("pepTxTask(%d): restarting after abort\n", link);
}
else
{
@@ -2420,7 +2428,8 @@ STATIC int pepTxTask(int link)
if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0)
&& (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now))
{
printf("pepTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node);
if (bbDebug)
printf("pepTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node);
(pBBLink[link]->deviceStatus[pnode->txMsg.node])--;
pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0;
pBBLink[link]->DelayCount--;
@@ -2504,7 +2513,8 @@ STATIC int pepTxTask(int link)
#ifdef BB_SUPER_DEBUG
BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET);
#endif
printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link);
if (bbDebug)
printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link);
pnode->status = BB_OK;

View File

@@ -1,7 +1,7 @@
#ifndef EPICS_DRVBITBUS_H
#define EPICS_DRVBITBUS_H
#define BB_SUPER_DEBUG
/* #define BB_SUPER_DEBUG */
/*
* Author: John Winans
@@ -36,6 +36,9 @@
* .03 07-01-94 jrw Bigtime hacking... merged PEP and Xycom.
*
* $Log$
* Revision 1.8 1994/10/04 18:42:44 winans
* Added an extensive debugging facility.
*
*
*/

807
src/drv/drvCaenV265.c Normal file
View File

@@ -0,0 +1,807 @@
/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */
/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265
*
* Author: Jeff Hill (johill@lanl.gov)
* Date: 8-11-94
*
* 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
* MIT Bates Lab
*
* Modification Log:
* -----------------
*/
/*
* ANSI C Includes
*/
#include <stdio.h>
#include <stddef.h>
#include <types.h>
#include <assert.h>
/*
* vxWorks includes
*/
#include <vme.h>
#include <iv.h>
#include <sysLib.h>
#include <intLib.h>
#include <logLib.h>
#include <vxLib.h>
#include <rebootLib.h>
#include <taskLib.h>
#include <tickLib.h>
#include <wdLib.h>
/*
* EPICS include
*/
#include <dbDefs.h>
#include <dbScan.h>
#include <drvSup.h>
#include <devSup.h>
#include <recSup.h>
#include <devLib.h>
#include <aiRecord.h>
#include <errMdef.h>
/*
* base address, base interrupt vector,
* number of cards, & interrupt level
*/
#define CAIN_V265_A24_BASE (0x000000)
#define CAIN_V265_INTVEC_BASE (0xA0)
#define CAIN_V265_MAX_CARD_COUNT (8)
#define CAIN_V265_INT_LEVEL (6)
/*
* all device registers declared
* ANSI C volatile so we dont need to
* use the -fvolatile flag (and dont
* limit the optimizer)
*/
typedef volatile int16_t devReg;
struct caenV265 {
devReg csr;
devReg clear;
devReg DAC;
devReg gate;
const devReg data;
const devReg pad1[(0xf8-0x8)/2];
const devReg fixed;
const devReg identifier;
const devReg version;
};
#define CAENV265ID 0x0812
/*
* Insert or extract a bit field using the standard
* masks and shifts defined below
*/
#ifdef __STDC__
#define INSERT(FIELD,VALUE)\
(((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S))
#define EXTRACT(FIELD,VALUE)\
( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M))
#else /*__STDC__*/
#define INSERT(FIELD,VALUE)\
(((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S))
#define EXTRACT(FIELD,VALUE)\
( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M))
#endif /*__STDC__*/
/*
* in the constants below _M is a right justified mask
* and _S is a shift required to right justify the field
*/
/*
* csr register
*/
#define FD_FULL_M (0x1)
#define FD_FULL_S (14)
#define FD_READY_M (0x1)
#define FD_READY_S (15)
#define FD_BUSY_FULL_M (0x3)
#define FD_BUSY_FULL_S (14)
#define FD_IVEC_M (0xff)
#define FD_IVEC_S (0)
#define FD_ILEVEL_M (0x7)
#define FD_ILEVEL_S (8)
/*
* series/version register
*/
#define FD_SERIES_M (0xfff)
#define FD_SERIES_S (0)
#define FD_VERSION_M (0xf)
#define FD_VERSION_S (12)
/*
* data register
*/
#define FD_CHANNEL_M (0x7)
#define FD_CHANNEL_S (13)
#define FD_RANGE_M (1)
#define FD_RANGE_S (12)
#define FD_DATA_M (0xfff)
#define FD_DATA_S (0)
struct channel{
int16_t signal;
char newData;
};
enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES};
#define NUMBER_OF_SIGNALS 8
#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES)
LOCAL struct caenV265Config{
struct caenV265 *pCaenV265; /* pointer to the card */
struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES];
IOSCANPVT scanpvt;
WDOG_ID wdid;
}caenV265Info[CAIN_V265_MAX_CARD_COUNT];
#ifdef __STDC__
#define SHOW_OFFSET(STRUCT,FIELD) \
printf( "%s.%s is at 0x%X\n", \
#STRUCT, \
#FIELD, \
offsetof(struct STRUCT, FIELD))
#endif
LOCAL void caenV265ISR(unsigned card);
LOCAL int caenV265Shutdown(void);
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265);
int caenV265Test(unsigned card);
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config);
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal);
LOCAL int caenV265IntEnable(unsigned card);
/*
* device support entry table
*/
LOCAL long caenV265InitRecord(struct aiRecord *pai);
LOCAL long caenV265AiRead(struct aiRecord *pai);
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after);
LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt);
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_ai;
DEVSUPFUN special_linconv;
} devCaenV265 ={
6,
NULL,
NULL,
caenV265InitRecord,
caenV265GetIoIntInfo,
caenV265AiRead,
caenV265SpecialLinconv};
/*
* driver support entry table
*/
LOCAL long caenV265Init(void);
LOCAL long caenV265IOReport(int level);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvCaenV265 ={
2,
caenV265IOReport,
caenV265Init};
/*
* verify that register
* offsets match the doc.
*/
#ifdef DEBUG
void offsettest()
{
SHOW_OFFSET(caenV265, version);
SHOW_OFFSET(caenV265, identifier);
SHOW_OFFSET(caenV265, fixed);
SHOW_OFFSET(caenV265, data);
SHOW_OFFSET(caenV265, gate);
SHOW_OFFSET(caenV265, DAC);
SHOW_OFFSET(caenV265, clear);
SHOW_OFFSET(caenV265, csr);
return;
}
#endif
/*
* caenV265InitRecord()
*/
LOCAL long caenV265InitRecord(struct aiRecord *pai)
{
struct vmeio *pvmeio;
/* ai.inp must be an VME_IO */
switch (pai->inp.type) {
case (VME_IO):
break;
default :
recGblRecordError(S_db_badField,(void *)pai,
"devAiXy566Se (init_record) Illegal INP field");
return(S_db_badField);
}
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad signal or card number
*/
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 bad card or signal number");
return -1;
}
if(!caenV265Info[pvmeio->card].pCaenV265){
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 card does not exist");
return -1;
}
/* set linear conversion slope*/
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
return(0);
}
/*
* caenV265AiRead()
*/
LOCAL long caenV265AiRead(struct aiRecord *pai)
{
int16_t value;
struct vmeio *pvmeio;
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad signal or card number
*/
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
return -1;
}
/*
* uninitialized data?
*/
if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) {
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
return -1;
}
value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal;
pai->rval = value;
return 0;
}
/*
* caenV265SpecialLinconv()
*/
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after)
{
if(!after) {
return 0;
}
/* set linear conversion slope*/
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
return 0;
}
/*
* caenV265GetIoIntInfo()
*/
LOCAL long caenV265GetIoIntInfo(
int cmd,
struct aiRecord *pai,
IOSCANPVT *ppvt)
{
struct vmeio *pvmeio;
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad card number
*/
if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
logMsg(
"%s.%d:devCaenV265 bad card number %d %s\n",
(int)__FILE__,
__LINE__,
pvmeio->card,
(int)pai->name,0,0);
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 bad card number");
return -1;
}
*ppvt = &caenV265Info[pvmeio->card].scanpvt;
return 0;
}
/*
* caenV265Init()
*/
LOCAL long caenV265Init(void)
{
unsigned card;
struct caenV265 *pCaenV265;
int status;
status = rebootHookAdd(caenV265Shutdown);
if(status){
errMessage(S_dev_internal,"reboot hook add failed");
return ERROR;
}
status = sysBusToLocalAdrs(
VME_AM_STD_SUP_DATA,
CAIN_V265_A24_BASE,
(char **)&pCaenV265);
if(status!=OK){
errPrintf(
S_dev_badA24,
__FILE__,
__LINE__,
"caenV265Init");
return ERROR;
}
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++, pCaenV265++){
unsigned vec;
if(!caenV265IdTest(pCaenV265)){
continue;
}
caenV265Info[card].wdid = wdCreate();
if(!caenV265Info[card].wdid){
continue;
}
/*
* flag that we have found a caen V265
*/
caenV265Info[card].pCaenV265 = pCaenV265;
/*
* init the EPICS db int event scan block
*/
scanIoInit(&caenV265Info[card].scanpvt);
/*
* reset the device
*/
pCaenV265->clear = 0; /* any rw op resets the device */
pCaenV265->DAC = 0; /* set test-signal "offset" to zero */
/*
* attach ISR
*/
vec = CAIN_V265_INTVEC_BASE+card;
status = intConnect(
INUM_TO_IVEC(vec),
caenV265ISR,
card);
assert(status>=0);
/*
* Enable interrupts
*/
caenV265IntEnable(card);
}
status = sysIntEnable(CAIN_V265_INT_LEVEL);
assert(status>=0);
return OK;
}
/*
* caenV265ISR()
*/
LOCAL void caenV265ISR(unsigned card)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned signal;
int16_t csr;
static unsigned ticks;
unsigned newTicks;
/*
* If its full then its more efficient
* to read it out without checking
* in between each read
*/
csr = pCaenV265->csr;
if (EXTRACT(FULL,csr)) {
for( signal=0;
signal<NUMBER_OF_FIFO_ENTRIES;
signal++){
caenV265ReadData(pCaenV256Config);
}
return;
}
/*
* Not full so check to see if its ready before
* reading
*/
while (EXTRACT(READY, csr)) {
caenV265ReadData(pCaenV256Config);
csr = pCaenV265->csr;
}
/*
* limit the EPICS scan rate
*/
newTicks = tickGet();
if(newTicks == ticks){
/*
* Disable Interrupts
*/
pCaenV265->csr = 0;
/*
* start a watch dog after one tick
* so that we limit the int rate to
* the system tick rate.
*/
wdStart(pCaenV256Config->wdid,
1,
caenV265IntEnable,
card);
return;
}
else{
ticks = newTicks;
}
/*
* tell EPICS to scan on int
*/
scanIoRequest(&caenV265Info[card].scanpvt);
return;
}
/*
* caenV265IntEnable
*/
LOCAL int caenV265IntEnable(unsigned card)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned vec;
int16_t newcsr;
vec = CAIN_V265_INTVEC_BASE+card;
newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL);
pCaenV265->csr = newcsr;
return OK;
}
/*
* caenV265ReadData()
*/
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config)
{
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
int16_t val = pCaenV265->data;
int16_t data = EXTRACT(DATA, val);
unsigned range = EXTRACT(RANGE, val);
unsigned signal = EXTRACT(CHANNEL, val);
if(range>=NUMBER_OF_ADC_RANGES){
logMsg("caenV265ReadData: bad range number\n",0,0,0,0,0,0);
return;
}
if(signal>=NUMBER_OF_SIGNALS){
logMsg("caenV265ReadData: bad signal number\n",0,0,0,0,0,0);
return;
}
pCaenV256Config->chan[signal][range].signal=data;
pCaenV256Config->chan[signal][range].newData=TRUE;
return;
}
/*
* caenV265IdTest()
*/
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265)
{
int status;
int16_t id;
/*
* Is a card present
*/
status = vxMemProbe(
(char *)&pCaenV265->identifier,
READ,
sizeof(id),
(char *)&id);
if(status!=OK){
return FALSE;
}
/*
* Is the correct type of card present
*/
if(id!=CAENV265ID){
errPrintf(
S_dev_wrongDevice,
__FILE__,
__LINE__,
"caenV265IdTest");
return FALSE;
}
return TRUE;
}
/*
* caenV265Shutdown()
* turns off interrupts so that dont foul up the boot
*/
LOCAL int caenV265Shutdown(void)
{
struct caenV265 *pCaenV265;
unsigned card;
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++){
pCaenV265 = caenV265Info[card].pCaenV265;
if(!pCaenV265){
continue;
}
if(caenV265IdTest(pCaenV265)){
/*
* disable interrupts
*/
pCaenV265->csr=0;
}
}
return OK;
}
/*
* caenV265Test()
*/
int caenV265Test(unsigned card)
{
unsigned dacVal;
struct caenV265Config cofigCpy;
unsigned range;
unsigned signal;
dacVal=0;
caenV265TestVal(card, dacVal);
while(dacVal<FD_DATA_M){
cofigCpy = caenV265Info[card];
dacVal = dacVal+32;
caenV265TestVal(card, dacVal);
for( range=0;
range<NUMBER_OF_ADC_RANGES;
range++){
char *pRangeName[] = { "12 bit signal",
"15 bit signal"};
printf( "\t%s with DAC = 0x%X\n",
pRangeName[range],
dacVal);
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
unsigned newdata;
unsigned olddata;
olddata = cofigCpy.chan[signal][range].signal;
newdata = caenV265Info[card].
chan[signal][range].signal;
printf( "\t\tchan=0x%1X diff = 0x%03X\n",
signal,
newdata-olddata);
}
}
}
return OK;
}
/*
* caenV265TestVal()
*/
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned signal;
if(!pCaenV265){
return ERROR;
}
if(!caenV265IdTest(pCaenV265)){
return ERROR;
}
/*
* clear the module
*/
pCaenV265->clear=0;
/*
* generate a test signal
*/
pCaenV265->DAC=dacVal;
/*
* generate a test gate
*/
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
caenV265Info[card].chan[signal][adc_12].newData=FALSE;
caenV265Info[card].chan[signal][adc_15].newData=FALSE;
while(!caenV265Info[card].chan[signal][adc_15].newData){
pCaenV265->gate=0;
taskDelay(1);
}
while(!caenV265Info[card].chan[signal][adc_12].newData){
pCaenV265->gate=0;
taskDelay(1);
}
}
/*
* turn off test signal
*/
pCaenV265->clear=0;
pCaenV265->DAC=0;
return OK;
}
/*
* caenV265IOReport()
*/
LOCAL long caenV265IOReport(int level)
{
struct caenV265 *pCaenV265;
unsigned card;
unsigned signal;
unsigned range;
char *pVersion[] = {"NIM","ECL"};
char *pState[] = {
"FIFO empty",
"FIFO full",
"FIFO partially filled",
"FIFO full"};
for (card=0; card<CAIN_V265_MAX_CARD_COUNT; card++) {
pCaenV265 = caenV265Info[card].pCaenV265;
if (!pCaenV265) {
continue;
}
if (!caenV265IdTest(pCaenV265)) {
continue;
}
printf("AI: caen V265:\tcard %d\n", card);
if (level == 0) {
continue;
}
printf("\tversion = %s\n",
pVersion[EXTRACT(VERSION, pCaenV265->version)]);
printf("\tseries = %d\n",
EXTRACT(SERIES, pCaenV265->version));
printf("\tstate = %s\n",
pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]);
printf("\tint level = %d\n",
EXTRACT(ILEVEL,pCaenV265->csr));
printf("\tint vec = 0x%02X\n",
EXTRACT(IVEC,pCaenV265->csr));
printf( "\tbase addr= 0x%X on the %s\n",
(unsigned)caenV265Info[card].pCaenV265,
sysModel());
for( range=0;
range<NUMBER_OF_ADC_RANGES;
range++){
char *pRangeName[] = { "12 bit signal",
"15 bit signal"};
printf("\t%s\n", pRangeName[range]);
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
int16_t data;
data = caenV265Info[card].
chan[signal][range].signal;
if(caenV265Info[card].chan[signal][range].newData){
printf( "\t\tchan=0x%1X val = 0x%03X\n",
signal,
data);
}
else{
printf( "\t\tchan=0x%1X <NO GATE>\n",
signal);
}
}
}
}
return OK;
}

View File

@@ -1,7 +1,17 @@
/* drvGpib.c */
/* share/src/drv/drvGpib.c %W% %G% */
/* Author: John Winans
/******************************************************************************
*
* TODO:
* - Autodetect the need to use a bounce buffer (saves time on boards that have
* "malloc"-able A24 space.
*
* - Launch campaign against the use of National Instruments hardware.
*
******************************************************************************
*
* Author: John Winans
* Date: 09-10-91
* GPIB driver for the NI-1014 and NI-1014D VME cards.
*
@@ -52,6 +62,15 @@
*
*
* $Log$
* Revision 1.26 1994/12/12 16:03:00 winans
* Rewrote the init code so that it always returns a zero (don't kill the
* startup.cmd file.) It is possible that this could cause some confusion
* to the database, should it decide to then use a link that did not init
* properly.
*
* Revision 1.25 1994/10/28 19:55:30 winans
* Added VME bus violation prevention code/bug fix from LANL.
*
* Revision 1.24 1994/10/04 18:42:46 winans
* Added an extensive debugging facility.
*
@@ -183,6 +202,11 @@ struct cc_ary
short cc_TWO;
};
typedef struct DmaStuffStruct
{
struct cc_ary cc_array;
char cc_byte;
}DmaStuffStruct;
/******************************************************************************
*
* This structure is used to hold the hardware-specific information for a
@@ -197,8 +221,12 @@ struct niLink {
WDOG_ID watchDogId; /* watchdog for timeouts */
struct ibregs *ibregs;/* pointer to board registers */
#if 0
char cc_byte;
struct cc_ary cc_array;
#else
DmaStuffStruct *DmaStuff;
#endif
char r_isr1;
char r_isr2;
@@ -218,7 +246,7 @@ STATIC int pollInhibit[NIGPIB_NUM_LINKS][IBAPERLINK];
/******************************************************************************
*
* This structure is used to hold the hardware-specific information for a
* single Bit Bus GPIB link. They are dynamically allocated (and an ibLinkTask
* single BitBus GPIB link. They are dynamically allocated (and an ibLinkTask
* started for it) when an IOCTL command requests it.
*
* The IOCTL requests to initiate a BBGPIB_IO link comes from the device support
@@ -372,9 +400,9 @@ initGpib(void)
if (ibDebug)
logMsg("GPIB card found at address 0x%08.8X\n", pibregs);
if ((pNiLink[i] = (struct niLink *) devLibA24Malloc(sizeof(struct niLink))) == NULL)
if ((pNiLink[i] = (struct niLink *)malloc(sizeof(struct niLink))) == NULL)
{ /* This better never happen! */
logMsg("initGpib(): Can't malloc memory for NI-link data structures!");
logMsg("initGpib(): Can't malloc memory for NI-link data structures!\n");
return(ERROR);
}
@@ -402,10 +430,15 @@ initGpib(void)
pNiLink[i]->cmdSpins = 0;
pNiLink[i]->maxSpins = 0;
pNiLink[i]->cc_array.cc_ccb = 0; /* DMAC array chained structure */
pNiLink[i]->cc_array.cc_ONE = 1;
pNiLink[i]->cc_array.cc_n_1addr = 0;
pNiLink[i]->cc_array.cc_TWO = 2;
if ((pNiLink[i]->DmaStuff = (DmaStuffStruct *)devLibA24Malloc(sizeof(DmaStuffStruct))) == NULL)
{ /* This better never happen! */
logMsg("initGpib(): Can't malloc A24 memory for DMAC control structures!\n");
return(ERROR);
}
pNiLink[i]->DmaStuff->cc_array.cc_ccb = 0; /* DMAC chaining structure */
pNiLink[i]->DmaStuff->cc_array.cc_ONE = 1;
pNiLink[i]->DmaStuff->cc_array.cc_n_1addr = 0;
pNiLink[i]->DmaStuff->cc_array.cc_TWO = 2;
pNiLink[i]->first_read = 1; /* used in physIo() */
}
@@ -970,9 +1003,9 @@ int time; /* time to wait on the DMA operation */
b->auxmr = AUXRA | HR_HLDE; /* hold off on end */
if (cnt != 1)
pNiLink[link]->cc_byte = AUXRA | HR_HLDA; /* (cc) holdoff on all */
pNiLink[link]->DmaStuff->cc_byte = AUXRA | HR_HLDA; /* (cc) holdoff on all */
else
pNiLink[link]->cc_byte = b->auxmr = AUXRA | HR_HLDA; /* last byte, do now */
pNiLink[link]->DmaStuff->cc_byte = b->auxmr = AUXRA | HR_HLDA; /* last byte, do now */
b->ch0.ocr = D_DTM | D_XRQ;
/* make sure I only alter the 1014D port-specific fields here! */
b->cfg1 = D_ECC | D_IN | (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM;
@@ -989,7 +1022,7 @@ int time; /* time to wait on the DMA operation */
memcpy(pNiLink[link]->A24BounceBuffer, buffer, length);
if (cnt != 1)
pNiLink[link]->cc_byte = AUX_SEOI; /* send EOI with last byte */
pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */
else
b->auxmr = AUX_SEOI; /* last byte, do it now */
@@ -1006,28 +1039,28 @@ int time; /* time to wait on the DMA operation */
/* setup channel 1 (carry cycle) */
if(ibDebug > 5)
logMsg("PhysIO: readying to xlate cc pointers at %8.8X and %8.8X\n", &(pNiLink[link]->cc_byte), &pNiLink[link]->A24BounceBuffer[cnt - 1]);
logMsg("PhysIO: readying to xlate cc pointers at %8.8X and %8.8X\n", &(pNiLink[link]->DmaStuff->cc_byte), &pNiLink[link]->A24BounceBuffer[cnt - 1]);
#ifdef USE_OLD_XLATION
pNiLink[link]->cc_array.cc_ccb = &(pNiLink[link]->cc_byte) + (long) ram_base;
pNiLink[link]->cc_array.cc_n_1addr = &(pNiLink[link]->A24BounceBuffer[cnt - 1]) + (long)ram_base;
pNiLink[link]->DmaStuff->cc_array.cc_ccb = &(pNiLink[link]->DmaStuff->cc_byte) + (long) ram_base;
pNiLink[link]->DmaStuff->cc_array.cc_n_1addr = &(pNiLink[link]->A24BounceBuffer[cnt - 1]) + (long)ram_base;
#else
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->cc_byte), &(pNiLink[link]->cc_array.cc_ccb)) == ERROR)
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_byte), &(pNiLink[link]->DmaStuff->cc_array.cc_ccb)) == ERROR)
return(ERROR);
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->A24BounceBuffer[cnt - 1]), &(pNiLink[link]->cc_array.cc_n_1addr)) == ERROR)
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->A24BounceBuffer[cnt - 1]), &(pNiLink[link]->DmaStuff->cc_array.cc_n_1addr)) == ERROR)
return(ERROR);
#endif
if(ibDebug > 5)
logMsg("PhysIO: &cc_byte=%8.8X, &pNiLink[link]->A24BounceBuffer[cnt-1]=%8.8X, ", pNiLink[link]->cc_array.cc_ccb, pNiLink[link]->cc_array.cc_n_1addr);
logMsg("PhysIO: &cc_byte=%8.8X, &pNiLink[link]->A24BounceBuffer[cnt-1]=%8.8X, ", pNiLink[link]->DmaStuff->cc_array.cc_ccb, pNiLink[link]->DmaStuff->cc_array.cc_n_1addr);
cnt--;
#ifdef USE_OLD_XLATION
temp_addr = (long) (&(pNiLink[link]->cc_array)) + (long)ram_base;
temp_addr = (long) (&(pNiLink[link]->DmaStuff->cc_array)) + (long)ram_base;
#else
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->cc_array), &temp_addr) == ERROR)
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_array), &temp_addr) == ERROR)
return(ERROR);
#endif
if(ibDebug > 5)
@@ -1079,7 +1112,7 @@ int time; /* time to wait on the DMA operation */
if (ibDmaTimingError > ibDmaMaxError)
ibDmaMaxError = ibDmaTimingError;
if (ibDmaDebug)
printf("DMA timing: error = %d, total = %d, max = %d\n",
logMsg("DMA timing: error = %d, total = %d, max = %d\n",
ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError);
/***************************************************************************/
@@ -1095,7 +1128,7 @@ int time; /* time to wait on the DMA operation */
if (ibDmaTimingError > ibDmaMaxError)
ibDmaMaxError = ibDmaTimingError;
if (ibDmaDebug)
printf("DMA timing: error = %d, total = %d, max = %d\n",
logMsg("DMA timing: error = %d, total = %d, max = %d\n",
ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError);
/***************************************************************************/
@@ -2008,6 +2041,102 @@ int length; /* number of bytes to write out from the data buffer */
return(ERROR);
}
#ifdef INCLUDE_HIDEOS_INTERFACE
/******************************************************************************
*
* Interface functions for HiDEOS access.
*
******************************************************************************/
/******************************************************************************
*
* Read up to <length> bytes into <*buffer>.
*
******************************************************************************/
STATIC int
HideosGpibRead(struct ibLink *pibLink, int device, char *buffer, int length, int time)
{
logMsg("HideosGpibRead() entered\n");
return(bytes read | error);
}
/******************************************************************************
*
* Write <length> bytes from <*buffer> in data mode.
*
******************************************************************************/
STATIC int
HideosGpibWrite(struct ibLink *pibLink, int device, char *buffer, int length, int time)
{
logMsg("HideosGpibWrite() entered\n");
return(bytes sent | error);
}
/******************************************************************************
*
* Write <length> bytes from <*buffer> in command mode.
*
******************************************************************************/
STATIC int
HideosGpibCmd(struct ibLink *pibLink, char *buffer, int length)
{
logMsg("HideosGpibCmd() entered\n");
return(bytes sent | error);
}
/******************************************************************************
*
* Verify that the given GPIB port exists.
*
******************************************************************************/
STATIC int
HideosGpibCheckLink(int link, int bug)
{
logMsg("HideosGpibCheckLink() entered\n");
return(OK | ERROR);
}
/******************************************************************************
*
* Prevent SRQs from being polled on a given GPIB port.
*
******************************************************************************/
STATIC int
HideosGpibSrqPollInhibit(int link, int bug, int gpibAddr)
{
logMsg("HideosGpibSrqPollInhibit() entered -- NOT SUPPORTED YET\n");
return(ERROR);
}
/******************************************************************************
*
* Generate a GPIB link for a HiDEOS port.
*
******************************************************************************/
STATIC int
HideosGpibGenLink(int link, int bug)
{
logMsg("HideosGpibGenLink() entered\n");
return(ibLinkStart() | ERROR);
}
/******************************************************************************
*
* Handle a GPIB IOCTL call.
*
******************************************************************************/
STATIC int
HideosGpibIoctl(int link, int bug, int cmd, int v, caddr_t p)
{
logMsg("HideosGpibIoctl() entered\n");
return(OK | ERROR);
}
/******************************************************************************
*
* Given the port information, return a link structure.
*
******************************************************************************/
struct bbIbLink *
HideosGpibFindLink(int link, int bug)
{
logMsg("HideosGpibFindLink() entered\n");
return(bbIbLink* | NULL);
}
#endif
/******************************************************************************
*
* These are the BitBus architecture specific functions.
@@ -2524,13 +2653,13 @@ IBHistDump(int type, int link, int bug)
{
if (pibLink->linkType == GPIB_IO)
{
printf("%d GPIB-L%d-D%d: %s\n", pibLink->History.Hist[i].Time,
logMsg("%d GPIB-L%d-D%d: %s\n", pibLink->History.Hist[i].Time,
pibLink->linkId, pibLink->History.Hist[i].DevAddr,
pibLink->History.Hist[i].Msg);
}
else if (pibLink->linkType == BBGPIB_IO)
{
printf("%d BBIB-l%d-B%d-D%d: %s\n", pibLink->History.Hist[i].Time,
logMsg("%d BBIB-l%d-B%d-D%d: %s\n", pibLink->History.Hist[i].Time,
pibLink->linkId, pibLink->bug, pibLink->History.Hist[i].DevAddr,
pibLink->History.Hist[i].Msg);
}
@@ -2544,3 +2673,12 @@ IBHistDump(int type, int link, int bug)
return(0);
}
#endif
#if 1
/* A way to stop the CPU when idle... run from shell at prio 250 */
BigFFT()
{
while (1)
asm(" stop #0x3000");
}
#endif

View File

@@ -22,10 +22,12 @@ PROD = iocCore vxWorks vxWorks.sym
include $(EPICS)/config/RULES.Vx
vxWorks: $(VX_IMAGE)
@$(INSTALL) -m 444 $? $@
$(RM) $@
cp $< .
vxWorks.sym: $(VX_IMAGE_SYM)
@$(INSTALL) -m 444 $? $@
$(RM) $@
cp $< .
iocCore: $(IOC_CORE_OBJS)
$(LINK.c) $@ $(IOC_CORE_OBJS)

View File

@@ -15,7 +15,7 @@ SRCS.c = \
OBJS = \
calcPerform.o cvtBpt.o cvtFast.o ellLib.o envSubr.o errSymLib.o \
errSymTbl.o genSubr.o genTaskSubr.o nextFieldSubr.o postfix.o \
bucketLib.o tsSubr.o gpHashLib.o freeListLib.o pal.o paldef.o
bucketLib.o tsSubr.o gpHashLib.o freeListLib.o pal.o paldef.o
OBJS1 = \
cmdSubr.o cvtNumbers.o cvtFast.o ezsSockSubr.o helpSubr.o

View File

@@ -29,16 +29,19 @@
* -----------------
* .01 091493 joh fixed overzealous parameter check
* .02 121693 joh added bucketFree()
*
* NOTES:
* .01 Storage for identifier must persist until an item is deleted
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <bucketLib.h>
#ifndef NBBY
#define NBBY 8
#endif /* NBBY */
@@ -48,142 +51,319 @@
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef LOCAL
#define LOCAL static
#endif /* LOCAL */
#ifndef max
#define max(A,B) ((A)>(B)?(A):(B))
#endif /* max */
#define BUCKET_IX_WIDTH 12
#define BUCKET_IX_N (1<<BUCKET_IX_WIDTH)
#define BUCKET_IX_MASK (BUCKET_IX_N-1)
/*
* these data type dependent routines are
* provided in the bucketLib.c
*/
typedef BUCKETID bucketHash(BUCKET *pb, const void *pId);
typedef ITEM **bucketCompare(ITEM **ppi, const void *pId);
LOCAL bucketCompare bucketUnsignedCompare;
LOCAL bucketCompare bucketPointerCompare;
LOCAL bucketCompare bucketStringCompare;
LOCAL bucketHash bucketUnsignedHash;
LOCAL bucketHash bucketPointerHash;
LOCAL bucketHash bucketStringHash;
typedef struct {
bucketHash *pHash;
bucketCompare *pCompare;
buckTypeOfId type;
}bucketSET;
LOCAL bucketSET BSET[] = {
{bucketUnsignedHash, bucketUnsignedCompare, bidtUnsigned},
{bucketPointerHash, bucketPointerCompare, bidtPointer},
{bucketStringHash, bucketStringCompare, bidtString}
};
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp);
LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId);
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId);
/*
* bucket id bit width
*/
#define BUCKETID_BIT_WIDTH (sizeof(BUCKETID)*NBBY)
/*
* Maximum bucket size
*/
#define BUCKET_MAX_WIDTH 12
#ifdef DEBUG
#error This is out of date
main()
{
BUCKETID id;
BUCKETID id1;
BUCKETID id2;
char *pValSave1;
char *pValSave2;
int s;
BUCKET *pb;
char *pValSave;
char *pVal;
unsigned i;
clock_t start, finish;
double duration;
const int LOOPS = 500000;
pb = bucketCreate(NBBY*sizeof(BUCKETID));
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
}
id = 444;
pValSave = "fred";
s = bucketAddItem(pb, id, pValSave);
if(s != BUCKET_SUCCESS){
return BUCKET_FAILURE;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
printf("Begin\n");
for(i=0; i<500000; i++){
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
start = clock();
for(i=0; i<LOOPS; i++){
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id2);
assert(pVal == pValSave2);
}
printf("End\n");
finish = clock();
duration = finish-start;
duration = duration/CLOCKS_PER_SEC;
printf("It took %15.10f total sec\n", duration);
duration = duration/LOOPS;
duration = duration/10;
duration = duration * 1e6;
printf("It took %15.10f u sec per hash lookup\n", duration);
bucketShow(pb);
return BUCKET_SUCCESS;
}
#endif
/*
* bucketUnsignedCompare()
*/
LOCAL ITEM **bucketUnsignedCompare (ITEM **ppi, const void *pId)
{
unsigned id;
unsigned *pItemId;
ITEM *pi;
id = * (unsigned *) pId;
while (pi = *ppi) {
if (bidtUnsigned == pi->type) {
pItemId = (unsigned *) pi->pId;
if (id == *pItemId) {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketPointerCompare()
*/
ITEM **bucketPointerCompare (ITEM **ppi, const void *pId)
{
void *ptr;
void **pItemId;
ITEM *pi;
ptr = * (void **) pId;
while (pi = *ppi) {
if (bidtPointer == pi->type ) {
pItemId = (void **) pi->pId;
if (ptr == *pItemId) {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketStringCompare ()
*/
ITEM **bucketStringCompare (ITEM **ppi, const void *pId)
{
const char *pStr = pId;
ITEM *pi;
int status;
while (pi = *ppi) {
if (bidtString == pi->type) {
status = strcmp (pStr, (char *)pi->pId);
if (status == '\0') {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketUnsignedHash ()
*/
BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId)
{
const unsigned *pUId = pId;
unsigned src;
BUCKETID hashid;
src = *pUId;
hashid = src;
src = src >> pb->hashIdNBits;
while (src) {
hashid = hashid ^ src;
src = src >> pb->hashIdNBits;
}
hashid = hashid & pb->hashIdMask;
return hashid;
}
/*
* bucketPointerHash ()
*
*/
BUCKETID bucketPointerHash (BUCKET *pb, const void *pId)
{
void * const *ppId = pId;
unsigned long src;
BUCKETID hashid;
/*
* This makes the assumption that
* a pointer will fit inside of a long
* (this assumption may not port to all
* CPU architectures)
*/
src = (unsigned long) *ppId;
hashid = src;
src = src >> pb->hashIdNBits;
while(src){
hashid = hashid ^ src;
src = src >> pb->hashIdNBits;
}
hashid = hashid & pb->hashIdMask;
return hashid;
}
/*
* bucketStringHash ()
*/
BUCKETID bucketStringHash (BUCKET *pb, const void *pId)
{
const char *pStr = pId;
BUCKETID hashid;
unsigned i;
hashid = 0;
i = 1;
while(*pStr){
hashid += *pStr * i;
pStr++;
i++;
}
hashid = hashid % (pb->hashIdMask+1);
return hashid;
}
/*
* bucketCreate()
*/
#ifdef __STDC__
BUCKET *bucketCreate(unsigned indexWidth)
#else
BUCKET *bucketCreate(indexWidth)
unsigned indexWidth;
#endif
BUCKET *bucketCreate (unsigned nHashTableEntries)
{
BUCKETID mask;
unsigned nbits;
BUCKET *pb;
/*
* no absurd sized buckets
*/
if (nHashTableEntries<=1) {
fprintf (stderr, "Tiny bucket create failed\n");
return NULL;
}
/*
* count the number of bits in the bucket id
*/
for (nbits=0; nbits<BUCKETID_BIT_WIDTH; nbits++) {
mask = (1<<nbits) - 1;
if ( ((nHashTableEntries-1) & ~mask) == 0){
break;
}
}
/*
* indexWidth must be specified at least one
* bit less than the bit size of type BUCKETID
*/
if(indexWidth>sizeof(BUCKETID)*NBBY){
printf("%s at %d: Requested index width=%d is to large. max=%d\n" ,
if (nbits>=BUCKETID_BIT_WIDTH) {
fprintf (
stderr,
"%s at %d: Requested index width=%d to large. max=%d\n",
__FILE__,
__LINE__,
indexWidth,
sizeof(BUCKETID)*NBBY-1);
nbits,
BUCKETID_BIT_WIDTH-1);
return NULL;
}
pb = (BUCKET *) calloc(1, sizeof(*pb));
if(!pb){
if (!pb) {
return pb;
}
if(indexWidth>BUCKET_IX_WIDTH){
pb->indexShift = indexWidth - BUCKET_IX_WIDTH;
}
else{
pb->indexShift = 0;
}
pb->nextIndexMask = (1<<pb->indexShift)-1;
pb->nEntries = 1<<(indexWidth-pb->indexShift);
if(indexWidth == sizeof(BUCKETID)*NBBY){
pb->indexMask = 0;
pb->indexMask = ~pb->indexMask;
}
else{
pb->indexMask = (1<<indexWidth)-1;
}
pb->hashIdMask = mask;
pb->hashIdNBits = nbits;
pb->pTable = (ITEMPTR *) calloc(
pb->nEntries,
sizeof(ITEMPTR));
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
return NULL;
@@ -202,14 +382,24 @@ int bucketFree(prb)
BUCKET *prb;
#endif
{
ITEM *pi;
ITEM *pni;
/*
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
if(prb->nInUse){
return BUCKET_FAILURE;
}
assert(prb->nInUse==0);
/*
* free the free list
*/
pi = prb->pFreeItems;
while (pi) {
pni = pi->pItem;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
@@ -220,69 +410,49 @@ BUCKET *prb;
/*
* bucketAddItem()
*/
#ifdef __STDC__
int bucketAddItem(BUCKET *prb, BUCKETID id, void *pItem)
#else
int bucketAddItem(prb, id, pItem)
BUCKET *prb;
BUCKETID id;
void *pItem;
#endif
int bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, void *pApp)
{
int s;
ITEMPTR *pi;
return bucketAddItem(prb, &BSET[bidtUnsigned], pId, pApp);
}
int bucketAddItemPointerId(BUCKET *prb, void * const *pId, void *pApp)
{
return bucketAddItem(prb, &BSET[bidtPointer], pId, pApp);
}
int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
{
return bucketAddItem(prb, &BSET[bidtString], pId, pApp);
}
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM *pi;
/*
* is the id to big ?
* try to get it off the free list first. If
* that fails then malloc()
*/
if(id&~prb->indexMask){
return BUCKET_FAILURE;
pi = prb->pFreeItems;
if (pi) {
prb->pFreeItems = pi->pItem;
}
if(prb->indexShift){
int new;
BUCKET *pb;
pi = &prb->pTable[id>>prb->indexShift];
pb = pi->pBucket;
if(!pb){
pb = bucketCreate(prb->indexShift);
if(!pb){
return BUCKET_FAILURE;
}
pi->pBucket = pb;
prb->nInUse++;
new = TRUE;
}
else{
new = FALSE;
else {
pi = (ITEM *) malloc(sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
}
s = bucketAddItem(
pb,
id&prb->nextIndexMask,
pItem);
/*
* if memory cant be allocated at a lower
* level dont leak everything allocated for this new
* item so far
*/
if(s != BUCKET_SUCCESS && new){
s = bucketFree(pb);
assert(s == BUCKET_SUCCESS);
pi->pBucket = NULL;
prb->nInUse--;
}
return s;
}
pi = &prb->pTable[id];
if(pi->pItem){
return BUCKET_FAILURE;
}
pi->pItem = pItem;
/*
* create the hash index
*/
hashid = (*pBSET->pHash) (prb, pId);
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
@@ -292,97 +462,85 @@ void *pItem;
/*
* bucketRemoveItem()
*/
#ifdef __STDC__
int bucketRemoveItem (BUCKET *prb, BUCKETID id, void *pItem)
#else
int bucketRemoveItem (prb, id, pItem)
BUCKET *prb;
BUCKETID id;
void *pItem;
#endif
int bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId)
{
ITEMPTR *ppi;
return bucketRemoveItem(prb, &BSET[bidtUnsigned], pId);
}
int bucketRemoveItemPointerId (BUCKET *prb, void * const *pId)
{
return bucketRemoveItem(prb, &BSET[bidtPointer], pId);
}
int bucketRemoveItemStringId (BUCKET *prb, const char *pId)
{
return bucketRemoveItem(prb, &BSET[bidtString], pId);
}
LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
ITEM *pi;
/*
* is the id to big ?
* create the hash index
*/
if(id&~prb->indexMask){
hashid = (*pBSET->pHash) (prb, pId);
assert((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
}
if(prb->indexShift){
BUCKET *pb;
int s;
ppi = &prb->pTable[id>>prb->indexShift];
pb = ppi->pBucket;
if(!pb){
return BUCKET_FAILURE;
}
s = bucketRemoveItem(
pb,
id&prb->nextIndexMask,
pItem);
if(s!=BUCKET_SUCCESS){
return s;
}
if(pb->nInUse==0){
free(pb->pTable);
free(pb);
ppi->pBucket = NULL;
prb->nInUse--;
}
return s;
}
ppi = &prb->pTable[id];
if(ppi->pItem != pItem){
return BUCKET_FAILURE;
}
prb->nInUse--;
ppi->pItem = NULL;
pi = *ppi;
*ppi = pi->pItem;
/*
* stuff it on the free list
*/
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
}
/*
* bucketLookupItem()
*/
#ifdef __STDC__
void *bucketLookupItem(BUCKET *pb, BUCKETID id)
#else
void *bucketLookupItem(pb, id)
BUCKET *pb;
BUCKETID id;
#endif
void *bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId)
{
unsigned shift;
return bucketLookupItem(prb, &BSET[bidtUnsigned], pId);
}
void *bucketLookupItemPointerId (BUCKET *prb, void * const *pId)
{
return bucketLookupItem(prb, &BSET[bidtPointer], pId);
}
void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
/*
* is the id to big ?
* create the hash index
*/
if(id&~pb->indexMask){
return NULL;
hashid = (*pBSET->pHash) (pb, pId);
assert((hashid & ~pb->hashIdMask) == 0);
/*
* at the bottom level just
* linear search for it.
*/
ppi = (*pBSET->pCompare) (&pb->pTable[hashid], pId);
if(ppi){
return (*ppi)->pApp;
}
while(shift = pb->indexShift){
BUCKETID nextId;
nextId = id & pb->nextIndexMask;
pb = pb->pTable[id>>shift].pBucket;
if(!pb){
return pb;
}
id = nextId;
}
return pb->pTable[id].pItem;
return NULL;
}
@@ -397,24 +555,62 @@ int bucketShow(pb)
BUCKET *pb;
#endif
{
ITEMPTR *pi;
ITEM **ppi;
ITEM *pi;
ITEM *pni;
unsigned nElem;
double X;
double XX;
double mean;
double stdDev;
unsigned count;
unsigned maxEntries;
unsigned freeListCount;
pi = pb->pTable;
printf( "Bucket: mask=%x entries in use=%d bytes in use=%d\n",
(pb->nEntries-1)<<pb->indexShift,
pb->nInUse,
sizeof(*pb)+pb->nEntries*sizeof(*pi));
if(pb->indexShift){
for( pi = pb->pTable;
pi<&pb->pTable[pb->nEntries];
pi++){
if(pi->pBucket){
bucketShow(pi->pBucket);
}
}
/*
* count bytes on the free list
*/
pi = pb->pFreeItems;
freeListCount = 0;
while (pi) {
freeListCount++;
pni = pi->pItem;
pi = pni;
}
printf( "Bucket entries in use = %d bytes in use = %d\n",
pb->nInUse,
sizeof(*pb)+(pb->hashIdMask+1)*
sizeof(ITEM *)+pb->nInUse*sizeof(ITEM));
printf( "Free list bytes in use = %d\n",
freeListCount*sizeof(ITEM));
ppi = pb->pTable;
nElem = pb->hashIdMask+1;
X = 0.0;
XX = 0.0;
maxEntries = 0;
while (ppi < &pb->pTable[nElem]) {
pi = *ppi;
count = 0;
while (pi) {
count++;
pi = pi->pItem;
}
X += count;
XX += count*count;
maxEntries = max (count, maxEntries);
ppi++;
}
mean = X/nElem;
stdDev = sqrt(XX/nElem - mean*mean);
printf( "Bucket entries/hash id - mean = %f std dev = %f max = %d\n",
mean,
stdDev,
maxEntries);
return BUCKET_SUCCESS;
}

View File

@@ -29,16 +29,19 @@
* -----------------
* .01 091493 joh fixed overzealous parameter check
* .02 121693 joh added bucketFree()
*
* NOTES:
* .01 Storage for identifier must persist until an item is deleted
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <bucketLib.h>
#ifndef NBBY
#define NBBY 8
#endif /* NBBY */
@@ -48,142 +51,319 @@
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef LOCAL
#define LOCAL static
#endif /* LOCAL */
#ifndef max
#define max(A,B) ((A)>(B)?(A):(B))
#endif /* max */
#define BUCKET_IX_WIDTH 12
#define BUCKET_IX_N (1<<BUCKET_IX_WIDTH)
#define BUCKET_IX_MASK (BUCKET_IX_N-1)
/*
* these data type dependent routines are
* provided in the bucketLib.c
*/
typedef BUCKETID bucketHash(BUCKET *pb, const void *pId);
typedef ITEM **bucketCompare(ITEM **ppi, const void *pId);
LOCAL bucketCompare bucketUnsignedCompare;
LOCAL bucketCompare bucketPointerCompare;
LOCAL bucketCompare bucketStringCompare;
LOCAL bucketHash bucketUnsignedHash;
LOCAL bucketHash bucketPointerHash;
LOCAL bucketHash bucketStringHash;
typedef struct {
bucketHash *pHash;
bucketCompare *pCompare;
buckTypeOfId type;
}bucketSET;
LOCAL bucketSET BSET[] = {
{bucketUnsignedHash, bucketUnsignedCompare, bidtUnsigned},
{bucketPointerHash, bucketPointerCompare, bidtPointer},
{bucketStringHash, bucketStringCompare, bidtString}
};
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp);
LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId);
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId);
/*
* bucket id bit width
*/
#define BUCKETID_BIT_WIDTH (sizeof(BUCKETID)*NBBY)
/*
* Maximum bucket size
*/
#define BUCKET_MAX_WIDTH 12
#ifdef DEBUG
#error This is out of date
main()
{
BUCKETID id;
BUCKETID id1;
BUCKETID id2;
char *pValSave1;
char *pValSave2;
int s;
BUCKET *pb;
char *pValSave;
char *pVal;
unsigned i;
clock_t start, finish;
double duration;
const int LOOPS = 500000;
pb = bucketCreate(NBBY*sizeof(BUCKETID));
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
}
id = 444;
pValSave = "fred";
s = bucketAddItem(pb, id, pValSave);
if(s != BUCKET_SUCCESS){
return BUCKET_FAILURE;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
printf("Begin\n");
for(i=0; i<500000; i++){
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pVal = bucketLookupItem(pb, id);
if(pVal != pValSave){
printf("failure\n");
break;
}
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
start = clock();
for(i=0; i<LOOPS; i++){
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id1);
assert(pVal == pValSave1);
pVal = bucketLookupItem(pb, id2);
assert(pVal == pValSave2);
}
printf("End\n");
finish = clock();
duration = finish-start;
duration = duration/CLOCKS_PER_SEC;
printf("It took %15.10f total sec\n", duration);
duration = duration/LOOPS;
duration = duration/10;
duration = duration * 1e6;
printf("It took %15.10f u sec per hash lookup\n", duration);
bucketShow(pb);
return BUCKET_SUCCESS;
}
#endif
/*
* bucketUnsignedCompare()
*/
LOCAL ITEM **bucketUnsignedCompare (ITEM **ppi, const void *pId)
{
unsigned id;
unsigned *pItemId;
ITEM *pi;
id = * (unsigned *) pId;
while (pi = *ppi) {
if (bidtUnsigned == pi->type) {
pItemId = (unsigned *) pi->pId;
if (id == *pItemId) {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketPointerCompare()
*/
ITEM **bucketPointerCompare (ITEM **ppi, const void *pId)
{
void *ptr;
void **pItemId;
ITEM *pi;
ptr = * (void **) pId;
while (pi = *ppi) {
if (bidtPointer == pi->type ) {
pItemId = (void **) pi->pId;
if (ptr == *pItemId) {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketStringCompare ()
*/
ITEM **bucketStringCompare (ITEM **ppi, const void *pId)
{
const char *pStr = pId;
ITEM *pi;
int status;
while (pi = *ppi) {
if (bidtString == pi->type) {
status = strcmp (pStr, (char *)pi->pId);
if (status == '\0') {
return ppi;
}
}
ppi = &pi->pItem;
}
return NULL;
}
/*
* bucketUnsignedHash ()
*/
BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId)
{
const unsigned *pUId = pId;
unsigned src;
BUCKETID hashid;
src = *pUId;
hashid = src;
src = src >> pb->hashIdNBits;
while (src) {
hashid = hashid ^ src;
src = src >> pb->hashIdNBits;
}
hashid = hashid & pb->hashIdMask;
return hashid;
}
/*
* bucketPointerHash ()
*
*/
BUCKETID bucketPointerHash (BUCKET *pb, const void *pId)
{
void * const *ppId = pId;
unsigned long src;
BUCKETID hashid;
/*
* This makes the assumption that
* a pointer will fit inside of a long
* (this assumption may not port to all
* CPU architectures)
*/
src = (unsigned long) *ppId;
hashid = src;
src = src >> pb->hashIdNBits;
while(src){
hashid = hashid ^ src;
src = src >> pb->hashIdNBits;
}
hashid = hashid & pb->hashIdMask;
return hashid;
}
/*
* bucketStringHash ()
*/
BUCKETID bucketStringHash (BUCKET *pb, const void *pId)
{
const char *pStr = pId;
BUCKETID hashid;
unsigned i;
hashid = 0;
i = 1;
while(*pStr){
hashid += *pStr * i;
pStr++;
i++;
}
hashid = hashid % (pb->hashIdMask+1);
return hashid;
}
/*
* bucketCreate()
*/
#ifdef __STDC__
BUCKET *bucketCreate(unsigned indexWidth)
#else
BUCKET *bucketCreate(indexWidth)
unsigned indexWidth;
#endif
BUCKET *bucketCreate (unsigned nHashTableEntries)
{
BUCKETID mask;
unsigned nbits;
BUCKET *pb;
/*
* no absurd sized buckets
*/
if (nHashTableEntries<=1) {
fprintf (stderr, "Tiny bucket create failed\n");
return NULL;
}
/*
* count the number of bits in the bucket id
*/
for (nbits=0; nbits<BUCKETID_BIT_WIDTH; nbits++) {
mask = (1<<nbits) - 1;
if ( ((nHashTableEntries-1) & ~mask) == 0){
break;
}
}
/*
* indexWidth must be specified at least one
* bit less than the bit size of type BUCKETID
*/
if(indexWidth>sizeof(BUCKETID)*NBBY){
printf("%s at %d: Requested index width=%d is to large. max=%d\n" ,
if (nbits>=BUCKETID_BIT_WIDTH) {
fprintf (
stderr,
"%s at %d: Requested index width=%d to large. max=%d\n",
__FILE__,
__LINE__,
indexWidth,
sizeof(BUCKETID)*NBBY-1);
nbits,
BUCKETID_BIT_WIDTH-1);
return NULL;
}
pb = (BUCKET *) calloc(1, sizeof(*pb));
if(!pb){
if (!pb) {
return pb;
}
if(indexWidth>BUCKET_IX_WIDTH){
pb->indexShift = indexWidth - BUCKET_IX_WIDTH;
}
else{
pb->indexShift = 0;
}
pb->nextIndexMask = (1<<pb->indexShift)-1;
pb->nEntries = 1<<(indexWidth-pb->indexShift);
if(indexWidth == sizeof(BUCKETID)*NBBY){
pb->indexMask = 0;
pb->indexMask = ~pb->indexMask;
}
else{
pb->indexMask = (1<<indexWidth)-1;
}
pb->hashIdMask = mask;
pb->hashIdNBits = nbits;
pb->pTable = (ITEMPTR *) calloc(
pb->nEntries,
sizeof(ITEMPTR));
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
return NULL;
@@ -202,14 +382,24 @@ int bucketFree(prb)
BUCKET *prb;
#endif
{
ITEM *pi;
ITEM *pni;
/*
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
if(prb->nInUse){
return BUCKET_FAILURE;
}
assert(prb->nInUse==0);
/*
* free the free list
*/
pi = prb->pFreeItems;
while (pi) {
pni = pi->pItem;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
@@ -220,69 +410,49 @@ BUCKET *prb;
/*
* bucketAddItem()
*/
#ifdef __STDC__
int bucketAddItem(BUCKET *prb, BUCKETID id, void *pItem)
#else
int bucketAddItem(prb, id, pItem)
BUCKET *prb;
BUCKETID id;
void *pItem;
#endif
int bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, void *pApp)
{
int s;
ITEMPTR *pi;
return bucketAddItem(prb, &BSET[bidtUnsigned], pId, pApp);
}
int bucketAddItemPointerId(BUCKET *prb, void * const *pId, void *pApp)
{
return bucketAddItem(prb, &BSET[bidtPointer], pId, pApp);
}
int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
{
return bucketAddItem(prb, &BSET[bidtString], pId, pApp);
}
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM *pi;
/*
* is the id to big ?
* try to get it off the free list first. If
* that fails then malloc()
*/
if(id&~prb->indexMask){
return BUCKET_FAILURE;
pi = prb->pFreeItems;
if (pi) {
prb->pFreeItems = pi->pItem;
}
if(prb->indexShift){
int new;
BUCKET *pb;
pi = &prb->pTable[id>>prb->indexShift];
pb = pi->pBucket;
if(!pb){
pb = bucketCreate(prb->indexShift);
if(!pb){
return BUCKET_FAILURE;
}
pi->pBucket = pb;
prb->nInUse++;
new = TRUE;
}
else{
new = FALSE;
else {
pi = (ITEM *) malloc(sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
}
s = bucketAddItem(
pb,
id&prb->nextIndexMask,
pItem);
/*
* if memory cant be allocated at a lower
* level dont leak everything allocated for this new
* item so far
*/
if(s != BUCKET_SUCCESS && new){
s = bucketFree(pb);
assert(s == BUCKET_SUCCESS);
pi->pBucket = NULL;
prb->nInUse--;
}
return s;
}
pi = &prb->pTable[id];
if(pi->pItem){
return BUCKET_FAILURE;
}
pi->pItem = pItem;
/*
* create the hash index
*/
hashid = (*pBSET->pHash) (prb, pId);
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
@@ -292,97 +462,85 @@ void *pItem;
/*
* bucketRemoveItem()
*/
#ifdef __STDC__
int bucketRemoveItem (BUCKET *prb, BUCKETID id, void *pItem)
#else
int bucketRemoveItem (prb, id, pItem)
BUCKET *prb;
BUCKETID id;
void *pItem;
#endif
int bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId)
{
ITEMPTR *ppi;
return bucketRemoveItem(prb, &BSET[bidtUnsigned], pId);
}
int bucketRemoveItemPointerId (BUCKET *prb, void * const *pId)
{
return bucketRemoveItem(prb, &BSET[bidtPointer], pId);
}
int bucketRemoveItemStringId (BUCKET *prb, const char *pId)
{
return bucketRemoveItem(prb, &BSET[bidtString], pId);
}
LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
ITEM *pi;
/*
* is the id to big ?
* create the hash index
*/
if(id&~prb->indexMask){
hashid = (*pBSET->pHash) (prb, pId);
assert((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
}
if(prb->indexShift){
BUCKET *pb;
int s;
ppi = &prb->pTable[id>>prb->indexShift];
pb = ppi->pBucket;
if(!pb){
return BUCKET_FAILURE;
}
s = bucketRemoveItem(
pb,
id&prb->nextIndexMask,
pItem);
if(s!=BUCKET_SUCCESS){
return s;
}
if(pb->nInUse==0){
free(pb->pTable);
free(pb);
ppi->pBucket = NULL;
prb->nInUse--;
}
return s;
}
ppi = &prb->pTable[id];
if(ppi->pItem != pItem){
return BUCKET_FAILURE;
}
prb->nInUse--;
ppi->pItem = NULL;
pi = *ppi;
*ppi = pi->pItem;
/*
* stuff it on the free list
*/
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
}
/*
* bucketLookupItem()
*/
#ifdef __STDC__
void *bucketLookupItem(BUCKET *pb, BUCKETID id)
#else
void *bucketLookupItem(pb, id)
BUCKET *pb;
BUCKETID id;
#endif
void *bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId)
{
unsigned shift;
return bucketLookupItem(prb, &BSET[bidtUnsigned], pId);
}
void *bucketLookupItemPointerId (BUCKET *prb, void * const *pId)
{
return bucketLookupItem(prb, &BSET[bidtPointer], pId);
}
void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
/*
* is the id to big ?
* create the hash index
*/
if(id&~pb->indexMask){
return NULL;
hashid = (*pBSET->pHash) (pb, pId);
assert((hashid & ~pb->hashIdMask) == 0);
/*
* at the bottom level just
* linear search for it.
*/
ppi = (*pBSET->pCompare) (&pb->pTable[hashid], pId);
if(ppi){
return (*ppi)->pApp;
}
while(shift = pb->indexShift){
BUCKETID nextId;
nextId = id & pb->nextIndexMask;
pb = pb->pTable[id>>shift].pBucket;
if(!pb){
return pb;
}
id = nextId;
}
return pb->pTable[id].pItem;
return NULL;
}
@@ -397,24 +555,62 @@ int bucketShow(pb)
BUCKET *pb;
#endif
{
ITEMPTR *pi;
ITEM **ppi;
ITEM *pi;
ITEM *pni;
unsigned nElem;
double X;
double XX;
double mean;
double stdDev;
unsigned count;
unsigned maxEntries;
unsigned freeListCount;
pi = pb->pTable;
printf( "Bucket: mask=%x entries in use=%d bytes in use=%d\n",
(pb->nEntries-1)<<pb->indexShift,
pb->nInUse,
sizeof(*pb)+pb->nEntries*sizeof(*pi));
if(pb->indexShift){
for( pi = pb->pTable;
pi<&pb->pTable[pb->nEntries];
pi++){
if(pi->pBucket){
bucketShow(pi->pBucket);
}
}
/*
* count bytes on the free list
*/
pi = pb->pFreeItems;
freeListCount = 0;
while (pi) {
freeListCount++;
pni = pi->pItem;
pi = pni;
}
printf( "Bucket entries in use = %d bytes in use = %d\n",
pb->nInUse,
sizeof(*pb)+(pb->hashIdMask+1)*
sizeof(ITEM *)+pb->nInUse*sizeof(ITEM));
printf( "Free list bytes in use = %d\n",
freeListCount*sizeof(ITEM));
ppi = pb->pTable;
nElem = pb->hashIdMask+1;
X = 0.0;
XX = 0.0;
maxEntries = 0;
while (ppi < &pb->pTable[nElem]) {
pi = *ppi;
count = 0;
while (pi) {
count++;
pi = pi->pItem;
}
X += count;
XX += count*count;
maxEntries = max (count, maxEntries);
ppi++;
}
mean = X/nElem;
stdDev = sqrt(XX/nElem - mean*mean);
printf( "Bucket entries/hash id - mean = %f std dev = %f max = %d\n",
mean,
stdDev,
maxEntries);
return BUCKET_SUCCESS;
}

View File

@@ -34,7 +34,7 @@
#include <ellLib.h>
#if !defined(NULL) || (NULL!=0)
#if !defined(NULL)
#define NULL 0
#endif

View File

@@ -34,7 +34,7 @@
#include <ellLib.h>
#if !defined(NULL) || (NULL!=0)
#if !defined(NULL)
#define NULL 0
#endif

View File

@@ -74,6 +74,7 @@
#define ENV_PRIVATE_DATA
#include <envDefs.h>
#include <epicsEnvParams.h>
/*+/subr**********************************************************************
@@ -378,3 +379,34 @@ char *value; /* I pointer to value string */
#endif
return 0;
}
/*parameters meant to be modified in epicsEnvParams.h*/
epicsSetEnvParams()
{
printf("setting EPICS environment parameters\n");
envSetConfigParam(&EPICS_TS_MIN_WEST, EPICS_TS_MIN_VALUE);
envSetConfigParam(&EPICS_AR_PORT, "7002");
envSetConfigParam(&EPICS_IOC_LOG_INET, EPICS_IOC_LOG_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_PORT, "7004");
envSetConfigParam(&EPICS_IOC_LOG_FILE_LIMIT, EPICS_IOC_FILE_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_FILE_NAME, EPICS_IOC_LOG_FILE_TXT);
return 0;
}
epicsPrtEnvParams()
{
envPrtConfigParam(&EPICS_TS_MIN_WEST);
envPrtConfigParam(&EPICS_CMD_PROTO_PORT);
envPrtConfigParam(&EPICS_AR_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_INET);
envPrtConfigParam(&EPICS_IOC_LOG_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_LIMIT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_NAME);
envPrtConfigParam(&EPICS_CA_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_CONN_TMO);
envPrtConfigParam(&EPICS_CA_BEACON_PERIOD);
envPrtConfigParam(&EPICS_CA_AUTO_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_REPEATER_PORT);
envPrtConfigParam(&EPICS_CA_SERVER_PORT);
return 0;
}

View File

@@ -74,6 +74,7 @@
#define ENV_PRIVATE_DATA
#include <envDefs.h>
#include <epicsEnvParams.h>
/*+/subr**********************************************************************
@@ -378,3 +379,34 @@ char *value; /* I pointer to value string */
#endif
return 0;
}
/*parameters meant to be modified in epicsEnvParams.h*/
epicsSetEnvParams()
{
printf("setting EPICS environment parameters\n");
envSetConfigParam(&EPICS_TS_MIN_WEST, EPICS_TS_MIN_VALUE);
envSetConfigParam(&EPICS_AR_PORT, "7002");
envSetConfigParam(&EPICS_IOC_LOG_INET, EPICS_IOC_LOG_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_PORT, "7004");
envSetConfigParam(&EPICS_IOC_LOG_FILE_LIMIT, EPICS_IOC_FILE_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_FILE_NAME, EPICS_IOC_LOG_FILE_TXT);
return 0;
}
epicsPrtEnvParams()
{
envPrtConfigParam(&EPICS_TS_MIN_WEST);
envPrtConfigParam(&EPICS_CMD_PROTO_PORT);
envPrtConfigParam(&EPICS_AR_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_INET);
envPrtConfigParam(&EPICS_IOC_LOG_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_LIMIT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_NAME);
envPrtConfigParam(&EPICS_CA_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_CONN_TMO);
envPrtConfigParam(&EPICS_CA_BEACON_PERIOD);
envPrtConfigParam(&EPICS_CA_AUTO_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_REPEATER_PORT);
envPrtConfigParam(&EPICS_CA_SERVER_PORT);
return 0;
}

View File

@@ -0,0 +1,18 @@
/* $Id$
* $Log$
* Revision 1.3 1994/11/01 14:55:15 jba
* set values for ANL/APS/ASD
*
* Revision 1.2 1994/09/09 12:40:30 mrk
* Removed env variables for old time support. New uses standard Unix methods.
*
* Revision 1.1 1994/07/17 07:14:24 bordua
* Initial version.
*
*/
/*These are env variables meant to be modified by each epics site*/
char *EPICS_TS_MIN_VALUE= "360";
char *EPICS_IOC_LOG_VALUE= "164.54.8.167";
char *EPICS_IOC_FILE_VALUE= "1000000";
char *EPICS_IOC_LOG_FILE_TXT= "/home/phebos1/epics/apple/log/iocLog.text";

View File

@@ -4,6 +4,7 @@
/* common to epics Unix and vxWorks */
#include "dbAccess.h"
#include "asLib.h"
#include "sdrHeader.h"
#include "drvSup.h"
#include "devSup.h"

View File

@@ -1,6 +1,6 @@
/*
*
* $Id$
* share/src/libCom/$Id$
*
* A file descriptor manager for use with the UNIX system call select
*
@@ -62,7 +62,6 @@
* if we are in fdmgr_pend_event()
* .15 joh 011993 Created fdmgr header file
* .16 joh 011993 Converted to ANSI C
* .17 pg 050494 HPUX cpp changes (elif converted to else & if)
*
* NOTES:
*
@@ -90,12 +89,26 @@
*
*/
static char *pSccsId = "$Id$";
static char *pSccsId = "@(#) $Id$";
/*
* ANSI
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <taskLib.h>
#include <sysLib.h>
#include <tickLib.h>
#include <logLib.h>
#include <selectLib.h>
#endif
#include <fdmgr.h>
#ifdef vxWorks
#include <taskLib.h>
#endif
#ifndef TRUE
#define TRUE 1
@@ -113,6 +126,10 @@ static char *pSccsId = "$Id$";
#define NULL 0
#endif
#ifndef LOCAL
#define LOCAL static
#endif
#ifndef max
#define max(x, y) (((x) < (y)) ? (y) : (x))
#endif
@@ -130,9 +147,6 @@ typedef struct{
#if defined(vxWorks)
# define LOCK(PFDCTX) FASTLOCK(&(PFDCTX)->lock)
# define UNLOCK(PFDCTX) FASTUNLOCK(&(PFDCTX)->lock)
# define LOCK_FDMGR_PEND_EVENT(PFDCTX) \
FASTLOCK(&(PFDCTX)->fdmgr_pend_event_lock) \
(PFDCTX)->fdmgr_pend_event_tid = taskIdCurrent
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
FASTUNLOCK(&(PFDCTX)->fdmgr_pend_event_lock) \
(PFDCTX)->fdmgr_pend_event_tid = NULL;
@@ -144,109 +158,55 @@ typedef struct{
FASTLOCK(&(PFDCTX)->fd_handler_lock)
# define UNLOCK_FD_HANDLER(PFDCTX) \
FASTUNLOCK(&(PFDCTX)->fd_handler_lock)
# define printf logMsg
# define fdmgr_gettimeval fdmgr_vxWorks_gettimeval
# define memset(D,V,N) bfill(D,N,V)
#else
#if defined(UNIX)
#elif defined(UNIX) || defined(VMS) || defined(_WIN32)
# define LOCK(PFDCTX)
# define UNLOCK(PFDCTX)
# define LOCK_FDMGR_PEND_EVENT(PFDCTX) \
{ \
if((PFDCTX)->fdmgr_pend_event_in_use){ \
printf("Double invocation of fdmgr_pend_event()\n"); \
abort(); \
} \
(PFDCTX)->fdmgr_pend_event_in_use++; \
}
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
{(PFDCTX)->fdmgr_pend_event_in_use--;}
# define fdmgr_gettimeval fdmgr_UNIX_gettimeval
# define LOCK_EXPIRED(PFDCTX)
# define UNLOCK_EXPIRED(PFDCTX)
# define LOCK_FD_HANDLER(PFDCTX)
# define UNLOCK_FD_HANDLER(PFDCTX)
#else
#if defined(VMS)
# define LOCK(PFDCTX)
# define UNLOCK(PFDCTX)
# define LOCK_FDMGR_PEND_EVENT(PFDCTX) \
{ \
if((PFDCTX)->fdmgr_pend_event_in_use){ \
printf("Double invocation of fdmgr_pend_event()\n"); \
abort(); \
} \
(PFDCTX)->fdmgr_pend_event_in_use++; \
}
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
{(PFDCTX)->fdmgr_pend_event_in_use--;}
# define fdmgr_gettimeval fdmgr_VMS_gettimeval
# define LOCK_EXPIRED(PFDCTX)
# define UNLOCK_EXPIRED(PFDCTX)
# define LOCK_FD_HANDLER(PFDCTX)
# define UNLOCK_FD_HANDLER(PFDCTX)
#else
@@@@ dont compile in this case @@@@
#endif
#endif
#error Please define the host OS type
#endif
#define USEC_PER_SEC 1000000
#ifdef __STDC__
#define printf @@@@ Please dont use printf in this source @@@@
LOCAL int fdmgrPrintf(char *pformat, ...);
static int fdmgr_vxWorks_gettimeval(
LOCAL int fdmgr_gettimeval(
fdctx *pfdctx,
struct timeval *pt
);
static int fdmgr_UNIX_gettimeval(
fdctx *pfdctx,
struct timeval *pt
);
static void select_alarm(
LOCAL void select_alarm(
fdctx *pfdctx
);
static int fdmgr_select(
LOCAL int fdmgr_select(
fdctx *pfdctx,
struct timeval *ptimeout
);
static void fdmgr_finish_off_fdentry(
LOCAL void fdmgr_finish_off_fdentry(
fdctx *pfdctx,
register fdentry *pfdentry
);
#else
static int fdmgr_vxWorks_gettimeval();
static int fdmgr_UNIX_gettimeval();
static void select_alarm();
static int fdmgr_select();
static void fdmgr_finish_off_fdentry();
#endif
#if defined(vxWorks)
# define abort(A) taskSuspend(taskIdSelf())
#endif
LOCAL void lockFDMGRPendEvent (fdctx *pfdctx);
/*
* This routine is to be only called from fdmgr_pend_event()
* If other uses are needed then locking issues must be
* reinvestigated
*/
#ifdef __STDC__
static void process_alarm_queue(
fdctx *pfdctx,
struct timeval *poffset
);
#else
static void process_alarm_queue();
#endif
LOCAL void process_alarm_queue(
fdctx *pfdctx,
struct timeval *poffset
);
/*
@@ -254,11 +214,7 @@ static void fdmgr_finish_off_fdentry();
* fdmgr_init()
*
*/
#ifdef __STDC__
fdctx *fdmgr_init(void)
#else
fdctx *fdmgr_init()
#endif
{
fdctx *pfdctx;
@@ -284,29 +240,41 @@ fdctx *fdmgr_init()
return pfdctx;
}
/*
*
* fdmgr_delete()
*
*/
int fdmgr_delete(fdctx *pfdctx)
{
if(!pfdctx){
return ERROR;
}
# if defined(vxWorks)
FASTLOCKFREE(&pfdctx->lock);
FASTLOCKFREE(&pfdctx->fdmgr_pend_event_lock);
FASTLOCKFREE(&pfdctx->expired_alarm_lock);
FASTLOCKFREE(&pfdctx->fd_handler_lock);
# endif
return OK;
}
/*
* fdmgr_add_timeout()
*/
#ifdef __STDC__
alarm *fdmgr_add_timeout(
fdmgrAlarm *fdmgr_add_timeout(
fdctx *pfdctx,
struct timeval *ptimeout,
void (*func)(),
void *param
)
#else
alarm *fdmgr_add_timeout(pfdctx,ptimeout,func,param)
fdctx *pfdctx;
struct timeval *ptimeout;
void (*func)();
void *param;
#endif
{
alarm *palarm=NULL;
alarm *pa;
fdmgrAlarm *palarm=NULL;
fdmgrAlarm *pa;
struct timeval t;
int status;
@@ -320,10 +288,10 @@ void *param;
return NULL;
LOCK(pfdctx);
palarm = (alarm *) ellGet(&pfdctx->free_alarm_list);
palarm = (fdmgrAlarm *) ellGet(&pfdctx->free_alarm_list);
UNLOCK(pfdctx);
if(!palarm){
palarm = (alarm *) malloc(sizeof(alarm));
palarm = (fdmgrAlarm *) malloc(sizeof(fdmgrAlarm));
if(!palarm){
return NULL;
}
@@ -332,7 +300,7 @@ void *param;
/*
* force all fields to a known state
*/
memset(palarm, 0, sizeof(*palarm));
memset((char *)palarm, 0, sizeof(*palarm));
ptimeout->tv_sec += ptimeout->tv_usec/USEC_PER_SEC;
ptimeout->tv_usec = ptimeout->tv_usec%USEC_PER_SEC;
@@ -347,9 +315,9 @@ void *param;
palarm->t.tv_usec = (t.tv_usec + ptimeout->tv_usec)%USEC_PER_SEC;
LOCK(pfdctx);
for( pa=(alarm *)pfdctx->alarm_list.node.next;
for( pa=(fdmgrAlarm *)pfdctx->alarm_list.node.next;
pa;
pa=(alarm *)pa->node.next){
pa=(fdmgrAlarm *)pa->node.next){
if(pa->t.tv_sec > palarm->t.tv_sec){
break;
}
@@ -379,16 +347,10 @@ void *param;
* fdmgr_clear_timeout()
*
*/
#ifdef __STDC__
int fdmgr_clear_timeout(
fdctx *pfdctx,
alarm *palarm
fdmgrAlarm *palarm
)
#else
int fdmgr_clear_timeout(pfdctx, palarm)
fdctx *pfdctx;
alarm *palarm;
#endif
{
int status;
enum alarm_list_type alt;
@@ -458,20 +420,12 @@ alarm *palarm;
* this rouitine is supplied solely for compatibility
* with earlier versions of this software
*/
#if __STDC__
int fdmgr_add_fd(
fdctx *pfdctx,
int fd,
void (*pfunc)(),
void *param
)
#else
int fdmgr_add_fd(pfdctx,fd,pfunc,param)
fdctx *pfdctx;
int fd;
void (*pfunc)();
void *param;
#endif
{
int status;
@@ -491,7 +445,6 @@ void *param;
* fdmgr_add_fd_callback()
*
*/
#ifdef __STDC__
int fdmgr_add_callback(
fdctx *pfdctx,
int fd,
@@ -499,14 +452,6 @@ enum fdi_type fdi,
void (*pfunc)(),
void *param
)
#else
int fdmgr_add_callback(pfdctx,fd,fdi,pfunc,param)
fdctx *pfdctx;
int fd;
enum fdi_type fdi;
void (*pfunc)();
void *param;
#endif
{
fdentry *pfdentry;
fd_set *pfds;
@@ -540,7 +485,7 @@ void *param;
/*
* force all fields to a known state
*/
memset(pfdentry, 0, sizeof(*pfdentry));
memset((char *)pfdentry, 0, sizeof(*pfdentry));
pfdentry->fd = fd;
pfdentry->fdi = fdi;
@@ -564,16 +509,10 @@ void *param;
* included solely for compatibility with previous release
*
*/
#ifdef __STDC__
int fdmgr_clear_fd(
fdctx *pfdctx,
int fd
)
#else
int fdmgr_clear_fd(pfdctx,fd)
fdctx *pfdctx;
int fd;
#endif
{
return fdmgr_clear_callback(pfdctx, fd, fdi_read);
}
@@ -584,18 +523,11 @@ int fd;
* fdmgr_clear_callback()
*
*/
#ifdef __STDC__
int fdmgr_clear_callback(
fdctx *pfdctx,
int fd,
enum fdi_type fdi
)
#else
int fdmgr_clear_callback(pfdctx,fd,fdi)
fdctx *pfdctx;
int fd;
enum fdi_type fdi;
#endif
{
register fdentry *pfdentry;
int status;
@@ -641,6 +573,7 @@ enum fdi_type fdi;
*/
# ifdef vxWorks
if(delete_pending == TRUE){
@@@@ review all of this delete pending stuff
LOCK_FD_HANDLER(pfdctx);
UNLOCK_FD_HANDLER(pfdctx);
}
@@ -650,7 +583,7 @@ enum fdi_type fdi;
* If it is an ukn fd its a problem worth printing out
*/
if(status != OK){
printf("fdmg: delete of ukn fd failed\n");
fdmgrPrintf("fdmg: delete of ukn fd failed\n");
}
return status;
@@ -664,16 +597,10 @@ enum fdi_type fdi;
* !! LOCK(pfdctx) must be applied !!
*
*/
#ifdef __STDC__
static void fdmgr_finish_off_fdentry(
LOCAL void fdmgr_finish_off_fdentry(
fdctx *pfdctx,
register fdentry *pfdentry
)
#else
static void fdmgr_finish_off_fdentry(pfdctx,pfdentry)
fdctx *pfdctx;
register fdentry *pfdentry;
#endif
{
FD_CLR(pfdentry->fd, pfdentry->pfds);
ellAdd(&pfdctx->fdentry_free_list, (ELLNODE*)pfdentry);
@@ -685,24 +612,18 @@ register fdentry *pfdentry;
* fdmgr_pend_event()
*
*/
#ifdef __STDC__
int fdmgr_pend_event(
fdctx *pfdctx,
struct timeval *ptimeout
)
#else
int fdmgr_pend_event(pfdctx,ptimeout)
fdctx *pfdctx;
struct timeval *ptimeout;
#endif
{
int status;
extern errno;
struct timeval t;
alarm *palarm;
fdmgrAlarm *palarm;
LOCK_FDMGR_PEND_EVENT(pfdctx);
lockFDMGRPendEvent(pfdctx);
/*
* If its a poll dont add a timeout
@@ -757,21 +678,14 @@ struct timeval *ptimeout;
* returns TRUE if any labor was performed, otherwise FALSE
*
*/
#ifdef __STDC__
static int fdmgr_select(
LOCAL int fdmgr_select(
fdctx *pfdctx,
struct timeval *ptimeout
)
#else
static int fdmgr_select(pfdctx,ptimeout)
fdctx *pfdctx;
struct timeval *ptimeout;
#endif
{
register fdentry *pfdentry;
int labor_performed;
int status;
int s;
labor_performed = FALSE;
@@ -790,8 +704,8 @@ struct timeval *ptimeout;
* it is in select() so I am turning
* on task delete disable to be safe
*/
# ifdef vxWorks
TASK_SAFE();
# ifdef vxWorks
taskSafe();
# endif
status = select(
pfdctx->maxfd,
@@ -799,8 +713,8 @@ struct timeval *ptimeout;
&pfdctx->writech,
&pfdctx->excpch,
ptimeout);
# ifdef vxWorks
TASK_UNSAFE();
# ifdef vxWorks
taskUnsafe();
# endif
if(status == 0){
return labor_performed;
@@ -809,12 +723,14 @@ struct timeval *ptimeout;
if(errno == EINTR)
;
else if(errno == EINVAL)
printf( "fdmgr: bad select args ? %d %d %d\n",
fdmgrPrintf(
"fdmgr: bad select args ? %d %d %d\n",
pfdctx->maxfd,
ptimeout->tv_sec,
ptimeout->tv_usec);
else
printf( "fdmgr: error from select %d\n",
fdmgrPrintf(
"fdmgr: error from select %d\n",
errno);
return labor_performed;
@@ -822,7 +738,6 @@ struct timeval *ptimeout;
pfdentry = (fdentry *) &pfdctx->fdentry_list.node;
while(TRUE){
void *pfunc;
LOCK(pfdctx)
pfdentry = (fdentry *) pfdentry->node.next;
@@ -896,36 +811,28 @@ struct timeval *ptimeout;
* only to be called by fdmgr_pend_event(). If other uses
* come up then the locking must be revisited
*/
#ifdef __STDC__
static void process_alarm_queue(
LOCAL void process_alarm_queue(
fdctx *pfdctx,
struct timeval *poffset
)
#else
static void process_alarm_queue(pfdctx,poffset)
fdctx *pfdctx;
struct timeval *poffset;
#endif
{
struct timeval t;
int status;
alarm *pa;
alarm *nextpa;
fdmgrAlarm *pa;
fdmgrAlarm *nextpa;
status = fdmgr_gettimeval(pfdctx, &t);
if(status < 0){
abort();
}
assert (status >= 0);
LOCK(pfdctx);
for(pa = (alarm*)pfdctx->alarm_list.node.next; pa; pa = nextpa){
for(pa = (fdmgrAlarm*)pfdctx->alarm_list.node.next; pa; pa = nextpa){
if(pa->t.tv_sec > t.tv_sec)
break;
else if(pa->t.tv_sec == t.tv_sec)
if(pa->t.tv_usec > t.tv_usec)
break;
nextpa = (alarm*)pa->node.next;
nextpa = (fdmgrAlarm*)pa->node.next;
ellDelete(&pfdctx->alarm_list, (ELLNODE*)pa);
ellAdd(&pfdctx->expired_alarm_list, (ELLNODE*)pa);
pa->alt = alt_expired;
@@ -954,7 +861,7 @@ struct timeval *poffset;
* on multithreaded OS
*/
LOCK_EXPIRED(pfdctx);
pa = (alarm*) pfdctx->expired_alarm_list.node.next;
pa = (fdmgrAlarm*) pfdctx->expired_alarm_list.node.next;
while(pa){
void (*pfunc)();
@@ -966,7 +873,7 @@ struct timeval *poffset;
if(pfunc){
(*pfunc)(pa->param);
}
pa = (alarm*)pa->node.next;
pa = (fdmgrAlarm*)pa->node.next;
}
UNLOCK_EXPIRED(pfdctx);
@@ -976,14 +883,14 @@ struct timeval *poffset;
* expired list onto the free list
*/
LOCK(pfdctx);
pa = (alarm*) pfdctx->expired_alarm_list.node.next;
pa = (fdmgrAlarm*) pfdctx->expired_alarm_list.node.next;
while(pa){
pa->alt = alt_free;
pa = (alarm *) pa->node.next;
pa = (fdmgrAlarm *) pa->node.next;
}
ellConcat(&pfdctx->free_alarm_list, &pfdctx->expired_alarm_list);
pa = (alarm *)pfdctx->alarm_list.node.next;
pa = (fdmgrAlarm *)pfdctx->alarm_list.node.next;
if(pa){
if(pa->t.tv_usec >= t.tv_usec){
poffset->tv_sec = pa->t.tv_sec - t.tv_sec;
@@ -1007,14 +914,9 @@ struct timeval *poffset;
* select_alarm()
*
*/
#ifdef __STDC__
static void select_alarm(
LOCAL void select_alarm(
fdctx *pfdctx
)
#else
static void select_alarm(pfdctx)
fdctx *pfdctx;
#endif
{
pfdctx->select_tmo = TRUE;
}
@@ -1024,21 +926,15 @@ fdctx *pfdctx;
/*
*
* fdmgr_UNIX_gettimeval
*
* UNIX & VMS
* fdmgr_gettimeval
*
*/
#ifdef UNIX
#ifdef __STDC__
static int fdmgr_UNIX_gettimeval(
#if defined(UNIX) || defined(VMS)
LOCAL int fdmgr_gettimeval(
fdctx *pfdctx,
struct timeval *pt
)
#else
static int fdmgr_UNIX_gettimeval(pfdctx,pt)
fdctx *pfdctx;
struct timeval *pt;
#endif
{
struct timezone tz;
@@ -1049,46 +945,38 @@ struct timeval *pt;
/*
*
* fdmgr_VMS_gettimeval
* WIN32
* fdmgr_gettimeval
*
*
*/
#ifdef VMS
#ifdef __STDC__
static int fdmgr_VMS_gettimeval(
fdctx *pfdctx,
struct timeval *pt
#ifdef _WIN32
LOCAL int fdmgr_gettimeval(
fdctx *pfdctx,
struct timeval *pt
)
#else
static int fdmgr_VMS_gettimeval(pfdctx,pt)
fdctx *pfdctx;
struct timeval *pt;
#endif
{
struct timezone tz;
SYSTEMTIME st;
GetSystemTime(&st);
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 + (long)st.wHour*360
0;
pt->tv_usec = st.wMilliseconds*1000;
return gettimeofday(pt, &tz);
return 0;
}
#endif
/*
*
* fdmgr_vxWorks_gettimeval
*
* vxWorks
* fdmgr_gettimeval
*
*/
#ifdef vxWorks
#ifdef __STDC__
static int fdmgr_vxWorks_gettimeval(
LOCAL int fdmgr_gettimeval(
fdctx *pfdctx,
struct timeval *pt
)
#else
static int fdmgr_vxWorks_gettimeval(pfdctx,pt)
fdctx *pfdctx;
struct timeval *pt;
#endif
{
unsigned long current;
@@ -1108,3 +996,66 @@ struct timeval *pt;
return OK;
}
#endif
/*
* lockFDMGRPendEvent()
*/
LOCAL void lockFDMGRPendEvent (fdctx *pfdctx)
{
# if defined(vxWorks)
FASTLOCK(&pfdctx->fdmgr_pend_event_lock);
pfdctx->fdmgr_pend_event_tid = taskIdCurrent;
# else
assert (pfdctx->fdmgr_pend_event_in_use==0);
pfdctx->fdmgr_pend_event_in_use++;
# endif
}
/*
*
*
* fdmgrPrintf()
*
* Dump error messages to the appropriate place
*
*/
LOCAL int fdmgrPrintf(char *pformat, ...)
{
va_list args;
int status;
va_start(args, pformat);
#ifndef vxWorks
status = vfprintf(
stderr,
pformat,
args);
#else /*vxWorks*/
{
int logMsgArgs[6];
int i;
for(i=0; i< NELEMENTS(logMsgArgs); i++){
logMsgArgs[i] = va_arg(args, int);
}
status = logMsg(
pformat,
logMsgArgs[0],
logMsgArgs[1],
logMsgArgs[2],
logMsgArgs[3],
logMsgArgs[4],
logMsgArgs[5]);
}
#endif /*vxWorks*/
va_end(args);
return status;
}

View File

@@ -49,17 +49,14 @@
unsigned memDebugLevel = 1;
#define debugMallocMagic 0xaaaaaaaa
typedef struct debugMallocFooter{
unsigned long magic;
}DMF;
#define debugMallocMagic 0xaaaaaaaa
#define debugMallocFooter "Dont Tread On Me"
typedef struct debugMallocHeader{
ELLNODE node;
char *pFile;
char *pUser;
DMF *pFoot;
char *pFoot;
unsigned long line;
unsigned long size;
unsigned long tick;
@@ -99,14 +96,16 @@ unsigned long line;
unsigned long size;
#endif /*__STDC__*/
{
DMH *pHdr;
DMH *pHdr;
unsigned long totSize;
pHdr = (DMH *)calloc(1,sizeof(DMH)+sizeof(DMF)+size);
totSize = sizeof(DMH)+strlen(debugMallocFooter)+1+size;
pHdr = (DMH *)calloc(1, totSize);
if(!pHdr){
return NULL;
}
pHdr->pUser = (char *) (pHdr+1);
pHdr->pFoot = (DMF *) (pHdr->pUser+size);
pHdr->pFoot = (char *) (pHdr->pUser+size);
pHdr->pFile = pFile;
pHdr->line = line;
pHdr->size = size;
@@ -114,9 +113,9 @@ unsigned long size;
#ifdef vxWorks
pHdr->tick = tickGet();
#else /*vxWorks*/
pHdr->tick = 0;
pHdr->tick = clock();
#endif /*vxWorks*/
pHdr->pFoot->magic = debugMallocMagic;
strcpy (pHdr->pFoot, debugMallocFooter);
#ifdef LOCKS_REQUIRED
if(!memDebugInit){
@@ -131,7 +130,7 @@ unsigned long size;
if(memDebugLevel>2){
fprintf(stderr, "%08x=malloc(%d) %s.%d\n",
pHdr->pUser, size, pFile, line);
(unsigned) pHdr->pUser, size, pFile, line);
}
return pHdr->pUser;
@@ -178,8 +177,10 @@ void *ptr;
if(status<0 || (pHdr->pUser != ptr)){
FASTUNLOCK(&memDebugLock);
fprintf(stderr, "%s.%d free(%08x) failed\n", pFile, line, ptr);
fprintf(stderr, "malloc occured at %s.%d\n", pHdr->pFile, pHdr->line);
fprintf(stderr, "%s.%d free(%08x) failed\n",
pFile, line, (unsigned) ptr);
fprintf(stderr, "malloc occured at %s.%d\n",
pHdr->pFile, pHdr->line);
assert(0);
}
ellDelete(&memDebugList, &pHdr->node);
@@ -188,7 +189,8 @@ void *ptr;
memDebugVerify(pHdr);
if(memDebugLevel>2){
fprintf(stderr, "free(%08x) %s.%d\n", ptr, pFile, line);
fprintf(stderr, "free(%08x) %s.%d\n",
(unsigned)ptr, pFile, line);
fprintf(stderr,
"\tmalloc(%d) at %s.%d\n",
pHdr->size,
@@ -214,9 +216,14 @@ DMH *pHdr;
return 1;
}
if(pHdr->magic != debugMallocMagic || pHdr->pFoot->magic != debugMallocMagic){
fprintf(stderr, "block overwritten %x\n", pHdr->pUser);
fprintf(stderr, "malloc occured at %s.%d\n", pHdr->pFile, pHdr->line);
strcpy (pHdr->pFoot, debugMallocFooter);
if(pHdr->magic != debugMallocMagic ||
strcmp(pHdr->pFoot, debugMallocFooter)){
fprintf(stderr, "block overwritten %x\n",
(unsigned)pHdr->pUser);
fprintf(stderr, "malloc occured at %s.%d\n",
pHdr->pFile, pHdr->line);
return 1;
}
@@ -252,22 +259,21 @@ int memDebugPrintAll(ignoreBeforeThisTick)
unsigned long ignoreBeforeThisTick;
#endif /*__STDC__*/
{
int status;
DMH *pHdr;
FASTLOCK(&memDebugLock);
pHdr = (DMH *) ellFirst(&memDebugList);
while(pHdr = (DMH *) ellNext(pHdr)){
if(pHdr->tick<ignoreBeforeThisTick){
continue;
while(pHdr){
if(pHdr->tick>=ignoreBeforeThisTick){
fprintf(stderr,
"%8x = malloc(%d) at %s.%d tick=%d\n",
(unsigned) pHdr->pUser,
pHdr->size,
pHdr->pFile,
pHdr->line,
pHdr->tick);
}
fprintf(stderr,
"%8x = malloc(%d) at %s.%d tick=%d\n",
pHdr->pUser,
pHdr->size,
pHdr->pFile,
pHdr->line,
pHdr->tick);
pHdr = (DMH *) ellNext(pHdr);
}
FASTUNLOCK(&memDebugLock);
return 0;

View File

@@ -2,9 +2,9 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
SRCS.c = ../epicsEnvParams.c ../epicsRelease.c
SRCS.c = ../epicsRelease.c
OBJS = epicsEnvParams.o epicsRelease.o
OBJS = epicsRelease.o
PROD = miscLib

View File

@@ -5,28 +5,96 @@ include $(EPICS)/config/CONFIG_BASE
USR_INCLUDES = -I../../drv
SRCS.c = \
../recAi.c ../recGsub.c ../recPulseDelay.c ../recAo.c \
../recHistogram.c ../recPulseTrain.c ../recBi.c ../recLongin.c \
../recSel.c ../recBo.c ../recLongout.c ../recSeq.c \
../recCalc.c ../recMbbi.c ../recState.c ../recCompress.c \
../recMbbiDirect.c ../recSteppermotor.c ../recEg.c ../recMbbo.c \
../recStringin.c ../recEgevent.c ../recMbboDirect.c ../recStringout.c \
../recEr.c ../recPal.c ../recSub.c ../recErevent.c \
../recPermissive.c ../recSwitch.c ../recEvent.c ../recPid.c \
../recTimer.c ../recFanout.c ../recPulseCounter.c ../recWaveform.c \
../recSubArray.c ../recWait.c ../caMonitor.c ../recScan.c \
../recAai.c ../recAao.c ../recDfanout.c ../recMbbiDirect.c ../recMbboDirect.c
../recAi.c\
../recAo.c\
../recBi.c\
../recBo.c\
../recCalc.c\
../recCompress.c\
../recDfanout.c\
../recEg.c\
../recEgevent.c\
../recEr.c\
../recErevent.c\
../recEvent.c\
../recFanout.c\
../recHistogram.c\
../recLongin.c\
../recLongout.c\
../recMbbi.c\
../recMbbiDirect.c\
../recMbbo.c\
../recMbboDirect.c\
../recPermissive.c\
../recPid.c\
../recPulseCounter.c\
../recPulseDelay.c\
../recPulseTrain.c\
../recScan.c\
../recSel.c\
../recSeq.c\
../recState.c\
../recSteppermotor.c\
../recStringin.c\
../recStringout.c\
../recSub.c\
../recSubArray.c\
../recTimer.c\
../recWaveform.c\
../recWait.c\
../caMonitor.c
# ../recPal.c\
# ../recSwitch.c\
# ../recGsub.c\
# ../recAai.c\
# ../recAao.c
OBJS = \
recAi.o recGsub.o recPulseDelay.o recAo.o recHistogram.o \
recPulseTrain.o recBi.o recLongin.o recSel.o recBo.o \
recLongout.o recSeq.o recCalc.o recMbbi.o recState.o recCompress.o \
recMbbiDirect.o recSteppermotor.o recEg.o recMbbo.o \
recStringin.o recEgevent.o recMbboDirect.o recStringout.o \
recEr.o recPal.o recSub.o recErevent.o recPermissive.o recSwitch.o \
recEvent.o recPid.o recTimer.o recFanout.o recPulseCounter.o \
recWaveform.o recSubArray.o recWait.o caMonitor.o recScan.o \
recAai.o recAao.o recDfanout.o recMbbiDirect.o recMbboDirect.o
recAi.o\
recPulseDelay.o\
recAo.o\
recHistogram.o\
recPulseTrain.o\
recBi.o\
recLongin.o\
recSel.o\
recBo.o\
recLongout.o\
recSeq.o\
recCalc.o\
recMbbi.o\
recState.o\
recCompress.o\
recMbbiDirect.o\
recSteppermotor.o\
recEg.o\
recMbbo.o\
recStringin.o\
recEgevent.o\
recMbboDirect.o\
recStringout.o\
recEr.o\
recSub.o\
recErevent.o\
recPermissive.o\
recEvent.o\
recPid.o\
recTimer.o\
recFanout.o\
recPulseCounter.o\
recWaveform.o\
recSubArray.o\
recWait.o\
recScan.o\
recDfanout.o\
recMbbiDirect.o\
recMbboDirect.o\
caMonitor.o
# recPal.o\
# recSwitch.o\
# recGsub.o\
# recAai.o\
# recAao.o\
PROD = recSup

View File

@@ -501,6 +501,7 @@ static void convert(pao,pvalue)
if (pao->oroc < -diff) value = pao->oval - pao->oroc;
}else if (pao->oroc < diff) value = pao->oval + pao->oroc;
}
if(pao->oval==value) pao->omod = FALSE; else pao->omod = TRUE;
pao->oval = value;
/* convert */
@@ -556,8 +557,9 @@ static void monitor(pao)
if (monitor_mask){
db_post_events(pao,&pao->val,monitor_mask);
}
if(pao->oval!=pao->val) monitor_mask |= (DBE_VALUE|DBE_LOG);
if(pao->omod) monitor_mask |= (DBE_VALUE|DBE_LOG);
if(monitor_mask) {
pao->omod = FALSE;
db_post_events(pao,&pao->oval,monitor_mask);
if(pao->oraw != pao->rval) {
db_post_events(pao,&pao->rval,monitor_mask|DBE_VALUE);

View File

@@ -238,9 +238,12 @@ static long get_enum_strs(paddr,pes)
pes->no_str = 2;
memset(pes->strs,'\0',sizeof(pes->strs));
strncpy(pes->strs[0],pbi->znam,sizeof(pbi->znam));
if(*pbi->znam!=0) pes->no_str=1;
strncpy(pes->strs[1],pbi->onam,sizeof(pbi->onam));
if(*pbi->onam!=0) pes->no_str=2;
return(0);
}
static long put_enum_str(paddr,pstring)
struct dbAddr *paddr;
char *pstring;

View File

@@ -368,10 +368,13 @@ static long get_enum_strs(paddr,pes)
{
struct boRecord *pbo=(struct boRecord *)paddr->precord;
/*SETTING no_str=0 breaks channel access clients*/
pes->no_str = 2;
memset(pes->strs,'\0',sizeof(pes->strs));
strncpy(pes->strs[0],pbo->znam,sizeof(pbo->znam));
if(*pbo->znam!=0) pes->no_str=1;
strncpy(pes->strs[1],pbo->onam,sizeof(pbo->onam));
if(*pbo->onam!=0) pes->no_str=2;
return(0);
}
static long put_enum_str(paddr,pstring)

View File

@@ -1,49 +1,14 @@
/* recLongout.c */
/* share/src/rec @(#)recLongout.c 1.16 6/4/93 */
/* recDfanout.c */
/* share/src/rec @(#)recDfanout.c 1.16 6/4/93 */
/* recLongout.c - Record Support Routines for Longout records */
/* recDfanout.c - Record Support Routines for Dfanout records */
/*
* Author: Janet Anderson
* Date: 9/23/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
* Author: Matt Bickley
* Date: Sometime in 1994
*
* Modification Log:
* -----------------
* .01 11-11-91 jba Moved set and reset of alarm stat and sevr to macros
* .02 02-05-92 jba Changed function arguments from paddr to precord
* .03 02-28-92 jba ANSI C changes
* .04 04-10-92 jba pact now used to test for asyn processing, not status
* .05 04-18-92 jba removed process from dev init_record parms
* .06 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo
* .07 07-15-92 jba changed VALID_ALARM to INVALID alarm
* .08 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro
* .09 07-21-92 jba changed alarm limits for non val related fields
* .10 08-06-92 jba New algorithm for calculating analog alarms
* .11 08-14-92 jba Added simulation processing
* .12 08-19-92 jba Added code for invalid alarm output action
* .13 09-10-92 jba modified fetch of val from dol to call recGblGetLinkValue
* .14 09-18-92 jba pact now set in recGblGetLinkValue
* .15 10-21-93 mhb Started with longout record to make the data fanout
* .01 1994 mhb Started with longout record to make the data fanout
*/
@@ -105,7 +70,6 @@ struct rset dfanoutRSET={
static void alarm();
static void monitor();
static long writeValue();
static long push_values();
#define OUT_ARG_MAX 8
@@ -124,22 +88,6 @@ static long init_record(pdfanout,pass)
if (pass==0) return(0);
/* dfanout.siml must be a CONSTANT or a PV_LINK or a DB_LINK */
switch (pdfanout->siml.type) {
case (CONSTANT) :
pdfanout->simm = pdfanout->siml.value.value;
break;
case (PV_LINK) :
status = dbCaAddInlink(&(pdfanout->siml), (void *) pdfanout, "SIMM");
if(status) return(status);
break;
case (DB_LINK) :
break;
default :
recGblRecordError(S_db_badField,(void *)pdfanout,
"dfanout: init_record Illegal SIML field");
return(S_db_badField);
}
plink = &pdfanout->outa;
for (i=0; i<OUT_ARG_MAX; i++, plink++) {
@@ -149,12 +97,6 @@ static long init_record(pdfanout,pass)
}
}
/* dfanout.siol may be a PV_LINK */
if (pdfanout->siol.type == PV_LINK){
status = dbCaAddOutlink(&(pdfanout->siol), (void *) pdfanout, "VAL");
if(status) return(status);
}
/* get the initial value dol is a constant*/
if (pdfanout->dol.type == CONSTANT){
pdfanout->val = pdfanout->dol.value.value;
@@ -184,37 +126,12 @@ static long process(pdfanout)
if(RTN_SUCCESS(status)) pdfanout->udf=FALSE;
}
/* check for alarms */
alarm(pdfanout);
if (pdfanout->nsev < INVALID_ALARM )
status=writeValue(pdfanout); /* write the new value */
else {
switch (pdfanout->ivoa) {
case (IVOA_CONTINUE) :
status=writeValue(pdfanout); /* write the new value */
break;
case (IVOA_NO_OUTPUT) :
break;
case (IVOA_OUTPUT_IVOV) :
if(pdfanout->pact == FALSE){
pdfanout->val=pdfanout->ivov;
}
status=writeValue(pdfanout); /* write the new value */
break;
default :
status=-1;
recGblRecordError(S_db_badField,(void *)pdfanout,
"dfanout:process Illegal IVOA field");
}
}
/* check if device support set pact */
if ( !pact && pdfanout->pact ) return(0);
pdfanout->pact = TRUE;
recGblGetTimeStamp(pdfanout);
/* Push out the data to all the forward links */
status = push_values(pdfanout);
/* check for alarms */
alarm(pdfanout);
/* check event list */
@@ -223,8 +140,6 @@ static long process(pdfanout)
/* process the forward scan link record */
recGblFwdLink(pdfanout);
/* Push out the data to all the forward links */
status = push_values(pdfanout);
pdfanout->pact=FALSE;
return(status);
@@ -380,30 +295,6 @@ static void monitor(pdfanout)
return;
}
static long writeValue(pdfanout)
struct dfanoutRecord *pdfanout;
{
long status;
long nRequest=1;
long options=0;
status=recGblGetLinkValue(&(pdfanout->siml),
(void *)pdfanout,DBR_ENUM,&(pdfanout->simm),&options,&nRequest);
if (!RTN_SUCCESS(status))
return(status);
if (pdfanout->simm == YES){
status=recGblPutLinkValue(&(pdfanout->siol),
(void *)pdfanout,DBR_LONG,&(pdfanout->val),&nRequest);
} else {
status=-1;
recGblSetSevr(pdfanout,SOFT_ALARM,INVALID_ALARM);
return(status);
}
recGblSetSevr(pdfanout,SIMM_ALARM,pdfanout->sims);
return(status);
}
static long push_values(pdfanout)
struct dfanoutRecord *pdfanout;
{

View File

@@ -43,9 +43,11 @@
* .07 10-21-94 nda changed linear scan parameter algorithms so changing
* start/end modifies step/width unless frozen. This
* seems more intuitive.
* .08 12-06-94 nda added support for .FFO .When set to 1, frzFlag values
* are saved in recPvtStruct. Restored when FFO set to 0.
*/
#define VERSION 1.07
#define VERSION 1.08
@@ -144,6 +146,28 @@ struct recPvtStruct {
struct p_limits *pP2Limits;
struct p_limits *pP3Limits;
struct p_limits *pP4Limits;
short pffo; /* previouss state of ffo */
short fpts; /* backup copy of all freeze flags */
short p1fs;
short p1fi;
short p1fc;
short p1fe;
short p1fw;
short p2fs;
short p2fi;
short p2fc;
short p2fe;
short p2fw;
short p3fs;
short p3fi;
short p3fc;
short p3fe;
short p3fw;
short p4fs;
short p4fi;
short p4fc;
short p4fe;
short p4fw;
unsigned long tickStart; /* used to time the scan */
unsigned char scanErr;
unsigned char nptsCause; /* who caused the "# of points to change:
@@ -208,6 +232,9 @@ static void adjLinParms();
static void changedNpts();
static void checkScanLimits();
static void drawPos1Scan();
static void saveFrzFlags();
static void resetFrzFlags();
static void restoreFrzFlags();
/* variables ... */
long scanRecDebug=0;
long viewScanPos=0;
@@ -286,6 +313,11 @@ static long init_record(pscan,pass)
precPvt->nptsCause = 0; /* resolve all positioner parameters */
changedNpts(pscan);
if(pscan->ffo) {
saveFrzFlags(pscan);
resetFrzFlags(pscan);
}
/* init field values */
pscan->exsc = 0;
pscan->pxsc = 0;
@@ -344,6 +376,7 @@ static long special(paddr,after)
unsigned char prevAlrt;
if(!after) {
precPvt->pffo = pscan->ffo; /* save previous ffo flag */
return(0);
}
switch(special_type) {
@@ -417,6 +450,25 @@ static long special(paddr,after)
}
break;
case(SPC_SC_FFO):
/* Freeze Flag Override field */
if((pscan->ffo) && (!precPvt->pffo)) {
saveFrzFlags(pscan);
resetFrzFlags(pscan);
}
else if(!pscan->ffo && precPvt->pffo) /* only on 1->0 */
restoreFrzFlags(pscan);
break;
case(SPC_SC_F):
/* Freeze Flag Override field */
if(pscan->ffo)
resetFrzFlags(pscan);
break;
default:
/* recGblDbaddrError(S_db_badChoice,paddr,"scan: special");
return(S_db_badChoice);
@@ -1993,3 +2045,267 @@ static void drawPos1Scan(pscan)
}
static void saveFrzFlags(pscan)
struct scanRecord *pscan;
{
struct recPvtStruct *precPvt = (struct recPvtStruct *)pscan->rpvt;
/* save state of each freeze flag */
precPvt->fpts = pscan->fpts;
precPvt->p1fs = pscan->p1fs;
precPvt->p1fi = pscan->p1fi;
precPvt->p1fc = pscan->p1fc;
precPvt->p1fe = pscan->p1fe;
precPvt->p1fw = pscan->p1fw;
precPvt->p2fs = pscan->p2fs;
precPvt->p2fi = pscan->p2fi;
precPvt->p2fc = pscan->p2fc;
precPvt->p2fe = pscan->p2fe;
precPvt->p2fw = pscan->p2fw;
precPvt->p3fs = pscan->p3fs;
precPvt->p3fi = pscan->p3fi;
precPvt->p3fc = pscan->p3fc;
precPvt->p3fe = pscan->p3fe;
precPvt->p3fw = pscan->p3fw;
precPvt->p4fs = pscan->p4fs;
precPvt->p4fi = pscan->p4fi;
precPvt->p4fc = pscan->p4fc;
precPvt->p4fe = pscan->p4fe;
precPvt->p4fw = pscan->p4fw;
}
static void resetFrzFlags(pscan)
struct scanRecord *pscan;
{
struct recPvtStruct *precPvt = (struct recPvtStruct *)pscan->rpvt;
/* reset each frzFlag, post monitor if changed */
if(pscan->fpts) {
pscan->fpts = 0;
db_post_events(pscan,&pscan->fpts, DBE_VALUE);
}
if(pscan->p1fs) {
pscan->p1fs = 0;
db_post_events(pscan,&pscan->p1fs, DBE_VALUE);
}
if(pscan->p1fi) {
pscan->p1fi = 0;
db_post_events(pscan,&pscan->p1fi, DBE_VALUE);
}
if(pscan->p1fc) {
pscan->p1fc = 0;
db_post_events(pscan,&pscan->p1fc, DBE_VALUE);
}
if(pscan->p1fe) {
pscan->p1fe = 0;
db_post_events(pscan,&pscan->p1fe, DBE_VALUE);
}
if(pscan->p1fw) {
pscan->p1fw = 0;
db_post_events(pscan,&pscan->p1fw, DBE_VALUE);
}
if(pscan->p2fs) {
pscan->p2fs = 0;
db_post_events(pscan,&pscan->p2fs, DBE_VALUE);
}
if(pscan->p2fi) {
pscan->p2fi = 0;
db_post_events(pscan,&pscan->p2fi, DBE_VALUE);
}
if(pscan->p2fc) {
pscan->p2fc = 0;
db_post_events(pscan,&pscan->p2fc, DBE_VALUE);
}
if(pscan->p2fe) {
pscan->p2fe = 0;
db_post_events(pscan,&pscan->p2fe, DBE_VALUE);
}
if(pscan->p2fw) {
pscan->p2fw = 0;
db_post_events(pscan,&pscan->p2fw, DBE_VALUE);
}
if(pscan->p3fs) {
pscan->p3fs = 0;
db_post_events(pscan,&pscan->p3fs, DBE_VALUE);
}
if(pscan->p3fi) {
pscan->p3fi = 0;
db_post_events(pscan,&pscan->p3fi, DBE_VALUE);
}
if(pscan->p3fc) {
pscan->p3fc = 0;
db_post_events(pscan,&pscan->p3fc, DBE_VALUE);
}
if(pscan->p3fe) {
pscan->p3fe = 0;
db_post_events(pscan,&pscan->p3fe, DBE_VALUE);
}
if(pscan->p3fw) {
pscan->p3fw = 0;
db_post_events(pscan,&pscan->p3fw, DBE_VALUE);
}
if(pscan->p4fs) {
pscan->p4fs = 0;
db_post_events(pscan,&pscan->p4fs, DBE_VALUE);
}
if(pscan->p4fi) {
pscan->p4fi = 0;
db_post_events(pscan,&pscan->p4fi, DBE_VALUE);
}
if(pscan->p4fc) {
pscan->p4fc = 0;
db_post_events(pscan,&pscan->p4fc, DBE_VALUE);
}
if(pscan->p4fe) {
pscan->p4fe = 0;
db_post_events(pscan,&pscan->p4fe, DBE_VALUE);
}
if(pscan->p4fw) {
pscan->p4fw = 0;
db_post_events(pscan,&pscan->p4fw, DBE_VALUE);
}
}
/* Restores Freeze Flags to the state they were in */
static void restoreFrzFlags(pscan)
struct scanRecord *pscan;
{
struct recPvtStruct *precPvt = (struct recPvtStruct *)pscan->rpvt;
/* restore state of each freeze flag, post if changed */
pscan->fpts = precPvt->fpts;
if(pscan->fpts) {
db_post_events(pscan,&pscan->fpts, DBE_VALUE);
}
pscan->p1fs = precPvt->p1fs;
if(pscan->p1fs) {
db_post_events(pscan,&pscan->p1fs, DBE_VALUE);
}
pscan->p1fi = precPvt->p1fi;
if(pscan->p1fi) {
db_post_events(pscan,&pscan->p1fi, DBE_VALUE);
}
pscan->p1fc = precPvt->p1fc;
if(pscan->p1fc) {
db_post_events(pscan,&pscan->p1fc, DBE_VALUE);
}
pscan->p1fe = precPvt->p1fe;
if(pscan->p1fe) {
db_post_events(pscan,&pscan->p1fe, DBE_VALUE);
}
pscan->p1fw = precPvt->p1fw;
if(pscan->p1fw) {
db_post_events(pscan,&pscan->p1fw, DBE_VALUE);
}
pscan->p2fs = precPvt->p2fs;
if(pscan->p2fs) {
db_post_events(pscan,&pscan->p2fs, DBE_VALUE);
}
pscan->p2fi = precPvt->p2fi;
if(pscan->p2fi) {
db_post_events(pscan,&pscan->p2fi, DBE_VALUE);
}
pscan->p2fc = precPvt->p2fc;
if(pscan->p2fc) {
db_post_events(pscan,&pscan->p2fc, DBE_VALUE);
}
pscan->p2fe = precPvt->p2fe;
if(pscan->p2fe) {
db_post_events(pscan,&pscan->p2fe, DBE_VALUE);
}
pscan->p2fw = precPvt->p2fw;
if(pscan->p2fw) {
db_post_events(pscan,&pscan->p2fw, DBE_VALUE);
}
pscan->p3fs = precPvt->p3fs;
if(pscan->p3fs) {
db_post_events(pscan,&pscan->p3fs, DBE_VALUE);
}
pscan->p3fi = precPvt->p3fi;
if(pscan->p3fi) {
db_post_events(pscan,&pscan->p3fi, DBE_VALUE);
}
pscan->p3fc = precPvt->p3fc;
if(pscan->p3fc) {
db_post_events(pscan,&pscan->p3fc, DBE_VALUE);
}
pscan->p3fe = precPvt->p3fe;
if(pscan->p3fe) {
db_post_events(pscan,&pscan->p3fe, DBE_VALUE);
}
pscan->p3fw = precPvt->p3fw;
if(pscan->p3fw) {
db_post_events(pscan,&pscan->p3fw, DBE_VALUE);
}
pscan->p4fs = precPvt->p4fs;
if(pscan->p4fs) {
db_post_events(pscan,&pscan->p4fs, DBE_VALUE);
}
pscan->p4fi = precPvt->p4fi;
if(pscan->p4fi) {
db_post_events(pscan,&pscan->p4fi, DBE_VALUE);
}
pscan->p4fc = precPvt->p4fc;
if(pscan->p4fc) {
db_post_events(pscan,&pscan->p4fc, DBE_VALUE);
}
pscan->p4fe = precPvt->p4fe;
if(pscan->p4fe) {
db_post_events(pscan,&pscan->p4fe, DBE_VALUE);
}
pscan->p4fw = precPvt->p4fw;
if(pscan->p4fw) {
db_post_events(pscan,&pscan->p4fw, DBE_VALUE);
}
}

View File

@@ -182,7 +182,13 @@ LOCAL void access_rights_reply(
struct channel_in_use *pciu
);
LOCAL unsigned long bucketID;
LOCAL struct channel_in_use *casCreateChannel (
struct client *client,
struct db_addr *pAddr,
unsigned cid
);
LOCAL unsigned bucketID;
/*
@@ -204,7 +210,7 @@ struct message_buffer *recv
struct channel_in_use *pciu;
if(!pCaBucket){
pCaBucket = bucketCreate(NBBY*sizeof(mp->m_cid));
pCaBucket = bucketCreate(CAS_HASH_TABLE_SIZE);
if(!pCaBucket){
return ERROR;
}
@@ -537,53 +543,80 @@ struct client *client
int status;
struct channel_in_use *pciu;
FASTLOCK(&prsrv_cast_client->addrqLock);
/*
* clients which dont claim their
* channel in use block prior to
* timeout must reconnect
* The available field is used (abused)
* here to communicate the miner version number
* starting with CA 4.1. The field was set to zero
* prior to 4.1
*/
pciu = MPTOPCIU(mp);
if(!pciu){
logMsg("CAS: client timeout disconnect id=%d\n",
mp->m_cid,
NULL,
NULL,
NULL,
NULL,
NULL);
client->minor_version_number = mp->m_available;
if (CA_V44(CA_PROTOCOL_VERSION,client->minor_version_number)) {
struct db_addr tmp_addr;
status = db_name_to_addr(
mp + 1,
&tmp_addr);
if (status < 0) {
return;
}
pciu = casCreateChannel (
client,
&tmp_addr,
mp->m_cid);
if (!pciu) {
SEND_LOCK(client);
send_err(mp,
ECA_ALLOCMEM,
client,
RECORD_NAME(&tmp_addr));
SEND_UNLOCK(client);
return;
}
}
else {
FASTLOCK(&prsrv_cast_client->addrqLock);
/*
* clients which dont claim their
* channel in use block prior to
* timeout must reconnect
*/
pciu = MPTOPCIU(mp);
if(!pciu){
logMsg("CAS: client timeout disconnect id=%d\n",
mp->m_cid,
NULL,
NULL,
NULL,
NULL,
NULL);
FASTUNLOCK(&prsrv_cast_client->addrqLock);
free_client(client);
exit(0);
}
/*
* remove channel in use block from
* the UDP client where it could time
* out and place it on the client
* who is claiming it
*/
ellDelete(
&prsrv_cast_client->addrq,
&pciu->node);
FASTUNLOCK(&prsrv_cast_client->addrqLock);
/*
* Any other client attachment is a severe error
*/
assert (pciu->client==prsrv_cast_client);
FASTLOCK(&prsrv_cast_client->addrqLock);
pciu->client = client;
ellAdd(&client->addrq, &pciu->node);
FASTUNLOCK(&prsrv_cast_client->addrqLock);
free_client(client);
exit(0);
}
/*
* remove channel in use block from
* the UDP client where it could time
* out and place it on the client
* who is claiming it
*/
ellDelete(
&prsrv_cast_client->addrq,
&pciu->node);
FASTUNLOCK(&prsrv_cast_client->addrqLock);
/*
* Any other client attachment is a severe error
*/
if(pciu->client!=prsrv_cast_client){
logMsg("CAS: bad channel claim disconnect %d %x %x\n",
mp->m_cid,
(int)pciu,
(int)pciu->client,
NULL,
NULL,
NULL);
free_client(client);
exit(0);
}
/*
* set up access security for this channel
@@ -608,19 +641,6 @@ struct client *client
*/
asPutClientPvt(pciu->asClientPVT, pciu);
FASTLOCK(&prsrv_cast_client->addrqLock);
pciu->client = client;
ellAdd(&client->addrq, &pciu->node);
FASTUNLOCK(&prsrv_cast_client->addrqLock);
/*
* The available field is used (abused)
* here to communicate the miner version number
* starting with CA 4.1. The field was set to zero
* prior to 4.1
*/
pciu->client->minor_version_number = mp->m_available;
v42 = CA_V42(
CA_PROTOCOL_VERSION,
client->minor_version_number);
@@ -631,7 +651,9 @@ struct client *client
* the correct client, and the clients version is
* known)
*/
status = asRegisterClientCallback(pciu->asClientPVT, casAccessRightsCB);
status = asRegisterClientCallback(
pciu->asClientPVT,
casAccessRightsCB);
if(status == S_asLib_asNotActive){
/*
* force the initial update
@@ -654,6 +676,7 @@ struct client *client
claim_reply->m_type = pciu->addr.field_type;
claim_reply->m_count = pciu->addr.no_elements;
claim_reply->m_cid = pciu->cid;
claim_reply->m_available = pciu->sid;
END_MSG(client);
SEND_UNLOCK(client);
}
@@ -1183,7 +1206,7 @@ struct client *client
}
FASTLOCK(&rsrv_free_addrq_lck);
status = bucketRemoveItem(pCaBucket, pciu->sid, pciu);
status = bucketRemoveItemUnsignedId (pCaBucket, &pciu->sid);
if(status != BUCKET_SUCCESS){
logBadId(client, mp);
}
@@ -1543,15 +1566,24 @@ struct extmsg *mp,
struct client *client
)
{
struct db_addr tmp_addr;
struct extmsg *search_reply;
struct extmsg *get_reply;
unsigned short *pMinorVersion;
int status;
struct db_addr tmp_addr;
struct channel_in_use *pchannel;
unsigned long sid;
unsigned sid;
/*
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
*/
if(casDontAllowSearchReplies){
SEND_LOCK(client);
send_err(mp,
ECA_ALLOCMEM,
client,
"Server memory exhausted");
SEND_UNLOCK(client);
return;
}
/* Exit quickly if channel not on this node */
status = db_name_to_addr(
@@ -1572,25 +1604,22 @@ struct client *client
}
/*
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
* starting with V4.4 the count field is used (abused)
* to store the minor version number of the client.
*
* New versions dont alloc the channel in response
* to a search request.
*/
if(casDontAllowSearchReplies){
SEND_LOCK(client);
send_err(mp,
ECA_ALLOCMEM,
client,
"Server memory exhausted");
SEND_UNLOCK(client);
return;
if (CA_V44(CA_PROTOCOL_VERSION,htons(mp->m_count))) {
sid = ~0U;
}
else {
struct channel_in_use *pchannel;
/* get block off free list if possible */
FASTLOCK(&rsrv_free_addrq_lck);
pchannel = (struct channel_in_use *) ellGet(&rsrv_free_addrq);
FASTUNLOCK(&rsrv_free_addrq_lck);
if (!pchannel) {
pchannel = (struct channel_in_use *) malloc(sizeof(*pchannel));
pchannel = casCreateChannel (
client,
&tmp_addr,
ntohs(mp->m_cid));
if (!pchannel) {
SEND_LOCK(client);
send_err(mp,
@@ -1600,39 +1629,14 @@ struct client *client
SEND_UNLOCK(client);
return;
}
}
memset((char *)pchannel, 0, sizeof(*pchannel));
ellInit(&pchannel->eventq);
pchannel->ticks_at_creation = tickGet();
pchannel->addr = tmp_addr;
pchannel->client = client;
pchannel->cid = mp->m_cid;
/*
* allocate a server id and enter the channel pointer
* in the table
*/
FASTLOCK(&rsrv_free_addrq_lck);
sid = bucketID++;
pchannel->sid = sid;
status = bucketAddItem(pCaBucket, sid, pchannel);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(status!=BUCKET_SUCCESS){
SEND_LOCK(client);
send_err(mp, ECA_ALLOCMEM, client, "No room for hash table");
SEND_UNLOCK(client);
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return;
sid = pchannel->sid;
}
SEND_LOCK(client);
search_reply = (struct extmsg *)
ALLOC_MSG(client, sizeof(*pMinorVersion));
if (!search_reply)
taskSuspend(0);
assert (search_reply);
*search_reply = *mp;
search_reply->m_postsize = sizeof(*pMinorVersion);
@@ -1653,12 +1657,75 @@ struct client *client
END_MSG(client);
SEND_UNLOCK(client);
/* store the addr block on the cast queue until it is claimed */
return;
}
/*
* casCreateChannel ()
*/
LOCAL struct channel_in_use *casCreateChannel (
struct client *client,
struct db_addr *pAddr,
unsigned cid
)
{
unsigned *pCID;
struct channel_in_use *pchannel;
unsigned sid;
int status;
/* get block off free list if possible */
FASTLOCK(&rsrv_free_addrq_lck);
pchannel = (struct channel_in_use *) ellGet(&rsrv_free_addrq);
FASTUNLOCK(&rsrv_free_addrq_lck);
if (!pchannel) {
pchannel = (struct channel_in_use *)
malloc(sizeof(*pchannel));
if (!pchannel) {
return NULL;
}
}
memset((char *)pchannel, 0, sizeof(*pchannel));
ellInit(&pchannel->eventq);
pchannel->ticks_at_creation = tickGet();
pchannel->addr = *pAddr;
pchannel->client = client;
/*
* bypass read only warning
*/
pCID = (unsigned *) &pchannel->cid;
*pCID = cid;
/*
* allocate a server id and enter the channel pointer
* in the table
*/
FASTLOCK(&rsrv_free_addrq_lck);
sid = bucketID++;
/*
* bypass read only warning
*/
pCID = (unsigned *) &pchannel->sid;
*pCID = sid;
status = bucketAddItemUnsignedId (
pCaBucket,
&pchannel->sid,
pchannel);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(status!=BUCKET_SUCCESS){
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return NULL;
}
FASTLOCK(&client->addrqLock);
ellAdd(&client->addrq, &pchannel->node);
FASTUNLOCK(&client->addrqLock);
return;
return pchannel;
}
@@ -1905,10 +1972,11 @@ struct client *pc
*/
LOCAL struct channel_in_use *MPTOPCIU(struct extmsg *mp)
{
struct channel_in_use *pciu;
struct channel_in_use *pciu;
const unsigned id = mp->m_cid;
FASTLOCK(&rsrv_free_addrq_lck);
pciu = bucketLookupItem(pCaBucket, mp->m_cid);
pciu = bucketLookupItemUnsignedId (pCaBucket, &id);
FASTUNLOCK(&rsrv_free_addrq_lck);
return pciu;
@@ -1926,7 +1994,6 @@ LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type)
struct client *pclient;
struct channel_in_use *pciu;
struct event_ext *pevext;
int status;
pciu = asGetClientPvt(ascpvt);
assert(pciu);

View File

@@ -78,7 +78,6 @@ FAST int sock;
int nchars;
FAST int status;
FAST struct client *client;
int i;
int true = TRUE;
client = NULL;

View File

@@ -66,6 +66,7 @@ static char *sccsId = "@(#)caservertask.c 1.22 5/6/94";
#include <taskwd.h>
#include <db_access.h>
#include <task_params.h>
#include <envDefs.h>
#include <server.h>
LOCAL int terminate_one_client(struct client *client);
@@ -88,6 +89,11 @@ 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);
if (IOC_sock != 0 && IOC_sock != ERROR)
if ((status = close(IOC_sock)) == ERROR)
@@ -113,13 +119,11 @@ int req_server(void)
NULL);
taskSuspend(0);
}
taskwdInsert((int)taskIdCurrent,NULL,NULL);
/* Zero the sock_addr structure */
bfill((char *)&serverAddr, sizeof(serverAddr), 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = CA_SERVER_PORT;
serverAddr.sin_port = htons(port);
/* get server's Internet address */
if (bind(IOC_sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == ERROR) {
@@ -315,7 +319,9 @@ LOCAL int terminate_one_client(struct client *client)
free(pciu->pPutNotify);
}
FASTLOCK(&rsrv_free_addrq_lck);
status = bucketRemoveItem(pCaBucket, pciu->sid, pciu);
status = bucketRemoveItemUnsignedId (
pCaBucket,
&pciu->sid);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(status != BUCKET_SUCCESS){
logMsg(

View File

@@ -79,6 +79,7 @@ static char *sccsId = "@(#)cast_server.c 1.24 5/6/94";
#include <taskwd.h>
#include <db_access.h>
#include <task_params.h>
#include <envDefs.h>
#include <server.h>
@@ -100,9 +101,12 @@ int cast_server(void)
struct sockaddr_in new_recv_addr;
int recv_addr_size;
unsigned nchars;
short port;
taskwdInsert((int)taskIdCurrent,NULL,NULL);
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
recv_addr_size = sizeof(new_recv_addr);
if( IOC_cast_sock!=0 && IOC_cast_sock!=ERROR )
@@ -137,8 +141,7 @@ int cast_server(void)
bfill((char *)&sin, sizeof(sin), 0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = CA_SERVER_PORT;
sin.sin_port = htons(port);
/* get server's Internet address */
if( bind(IOC_cast_sock, (struct sockaddr *)&sin, sizeof (sin)) == ERROR){
@@ -339,11 +342,12 @@ LOCAL void clean_addrq()
}
if (delay > timeout) {
int status;
ellDelete(&prsrv_cast_client->addrq, &pciu->node);
FASTLOCK(&rsrv_free_addrq_lck);
s = bucketRemoveItem(pCaBucket, pciu->sid, pciu);
s = bucketRemoveItemUnsignedId (
pCaBucket,
&pciu->sid);
if(s != BUCKET_SUCCESS){
logMsg(
"%s Bad id at close",

View File

@@ -74,23 +74,39 @@ int rsrv_online_notify_task()
{
ELLLIST destAddr;
caAddrNode *pNode;
/*
* 1 sec init delay
*/
unsigned long delay = sysClkRateGet();
/*
* CA_ONLINE_DELAY max delay in ticks
*/
unsigned long maxdelay = CA_ONLINE_DELAY;
unsigned long delay;
unsigned long maxdelay;
long longStatus;
double maxPeriod;
struct extmsg msg;
struct sockaddr_in recv_addr;
int status;
int sock;
int true = TRUE;
short port;
taskwdInsert(taskIdSelf(),NULL,NULL);
longStatus = envGetDoubleConfigParam (
&EPICS_CA_BEACON_PERIOD,
&maxPeriod);
if (longStatus) {
maxPeriod = 15.0;
ca_printf (
"EPICS \"%s\" float fetch failed\n",
EPICS_CA_BEACON_PERIOD.name);
ca_printf (
"Setting \"%s\" = %f\n",
EPICS_CA_BEACON_PERIOD.name,
maxPeriod);
}
/*
* 1 sec init delay between beacons
*/
delay = sysClkRateGet();
maxdelay = max(maxPeriod*sysClkRateGet(),sysClkRateGet());
/*
* Open the socket.
* Use ARPA Internet address format and datagram socket.
@@ -128,13 +144,13 @@ int rsrv_online_notify_task()
msg.m_cmmd = htons(IOC_RSRV_IS_UP);
ellInit(&destAddr);
caDiscoverInterfaces(&destAddr, sock, CA_CLIENT_PORT);
caAddConfiguredAddr(
&destAddr,
&EPICS_CA_ADDR_LIST,
sock,
CA_CLIENT_PORT);
/*
* load user and auto configured
* broadcast address list
*/
port = caFetchPortConfig(&EPICS_CA_REPEATER_PORT, CA_REPEATER_PORT);
caSetupBCastAddrList (&destAddr, sock, port);
# ifdef DEBUG
caPrintAddrList(&destAddr);

View File

@@ -45,6 +45,14 @@
static char *serverhSccsId = "@(#)server.h 1.19 5/6/94";
#if defined(CAS_VERSION_GLOBAL) && 0
# define HDRVERSIONID(NAME,VERS) VERSIONID(NAME,VERS)
#else /*CAS_VERSION_GLOBAL*/
# define HDRVERSIONID(NAME,VERS)
#endif /*CAS_VERSION_GLOBAL*/
typedef int SOCKET;
#include <vxLib.h>
#include <ellLib.h>
#include <fast_lock.h>
@@ -54,6 +62,7 @@ static char *serverhSccsId = "@(#)server.h 1.19 5/6/94";
#include <dbEvent.h>
#include <iocmsg.h>
#include <bucketLib.h>
#include <taskwd.h>
#include <asLib.h>
#include <asDbLib.h>
@@ -112,8 +121,8 @@ struct channel_in_use{
ELLLIST eventq;
struct client *client;
RSRVPUTNOTIFY *pPutNotify; /* potential active put notify */
unsigned long cid; /* client id */
unsigned long sid; /* server id */
const unsigned cid; /* client id */
const unsigned sid; /* server id */
unsigned long ticks_at_creation; /* for UDP timeout */
struct db_addr addr;
ASCLIENTPVT asClientPVT;
@@ -158,6 +167,9 @@ GLBLTYPE FAST_LOCK rsrv_free_addrq_lck;
GLBLTYPE FAST_LOCK rsrv_free_eventq_lck;
GLBLTYPE struct client *prsrv_cast_client;
GLBLTYPE BUCKET *pCaBucket;
#define CAS_HASH_TABLE_SIZE 4096
/*
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
*/

View File

@@ -2,14 +2,20 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
LEX = $(ELEX)
YACC = $(EYACC)
#YACCOPT = -l
#LEXOPT = -L
USR_LDLIBS = -ll
YACCOPT = -d -v
SRCS.c = ../snc_main.c ../parse.c ../phase2.c ../gen_ss_code.c \
../gen_tables.c sncVersion.c snc.c snc_lex.c
SRCS.c = ../parse.c ../phase2.c ../gen_ss_code.c \
../gen_tables.c sncVersion.c snc.c
OBJS = snc_main.o parse.o phase2.o gen_ss_code.o \
gen_tables.o sncVersion.o snc.o snc_lex.o
OBJS = parse.o phase2.o gen_ss_code.o \
gen_tables.o sncVersion.o snc.o
PROD = snc
@@ -20,6 +26,8 @@ include $(EPICS)/config/RULES.Unix
#
snc_lex.c: snc.h
snc.o: snc_lex.c
sncVersion.c: ../Version
$(RM) sncVersion.c
sh ../makeVersion ../Version > sncVersion.c

View File

@@ -321,4 +321,5 @@ global_c
: C_STMT { global_c_stmt($1); }
;
%%
#include "snc_lex.c"
#include "snc_main.c"

View File

@@ -22,8 +22,10 @@
* Comments are recognized as part of the syntax.
*/
/*
#include "parse.h"
#include "snc.h" /* output from yacc */
#include "snc.h"
*/
#ifndef TRUE
#define TRUE 1
#define FALSE 0

View File

@@ -3,18 +3,25 @@ include Target.include
include $(EPICS)/config/CONFIG_BASE
CMPLR = OLD
YACCOPT = -d
YACC = $(EYACC)
YACCOPT = -l -d
SKELETON_FILE=include/flex.skel.static
ifeq ($(T_A),hp700)
USR_CFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_FILE)\" -DSCO_UNIX
else
USR_CFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_FILE)\"
endif
USR_LDLIBS = -s
SRCS.c = ../ccl.c ../dfa.c ../ecs.c ../gen.c ../main.c \
../misc.c ../nfa.c parse.c ../scan.c ../sym.c \
../tblcmp.c ../yylex.c
# main.c is included in parse.c
SRCS.c = ../ccl.c ../dfa.c ../ecs.c ../gen.c \
../misc.c ../nfa.c ../sym.c \
../tblcmp.c parse.c
OBJS = \
ccl.o dfa.o ecs.o gen.o main.o misc.o \
nfa.o parse.o scan.o sym.o tblcmp.o yylex.o
ccl.o dfa.o ecs.o gen.o misc.o \
nfa.o sym.o tblcmp.o parse.o
PROD = e_flex

View File

@@ -194,16 +194,18 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
#ifndef lint
static char rcsid[] =
"@(#) $Header$ (LBL)";
#endif
#undef yywrap
#include "flexdef.h"
#include "parse.h"
*/
#undef yywrap
#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );

View File

@@ -32,13 +32,14 @@ char copyright[] =
All rights reserved.\n";
#endif /* not lint */
/*
#ifndef lint
static char rcsid[] =
"@(#) $Header$ (LBL)";
#endif
#include "flexdef.h"
*/
static char flex_version[] = "2.3";

View File

@@ -700,3 +700,8 @@ char msg[];
{
}
#include "scan.c"
#include "yylex.c"
#include "main.c"

View File

@@ -194,15 +194,18 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
#ifndef lint
static char rcsid[] =
"@(#) $Header$ (LBL)";
#endif
#include "flexdef.h"
#include <parse.h>
*/
#undef yywrap
#include "flexdef.h"
#include <parse.h>
#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );

View File

@@ -26,6 +26,7 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
#ifndef lint
static char rcsid[] =
"@(#) $Header$ (LBL)";
@@ -34,7 +35,7 @@ static char rcsid[] =
#include <ctype.h>
#include "flexdef.h"
#include "parse.h"
*/
/* ANSI C does not guarantee that isascii() is defined */
#ifndef isascii
@@ -214,3 +215,4 @@ int yylex()
return ( toktype );
}

View File

@@ -15,13 +15,13 @@ USR_INCLUDES = -I$(OPENWIN)/include
USR_CFLAGS = -DXWINDOWS -UvxWorks
SRCS.c = \
../apCreateShadow.c ../apStatusSync.c ../bfRing.c ../ca_test.c \
../bfRing.c ../ca_test.c \
../calcTest.c ../cmdClient.c ../extrDoc.c ../guiSubr.c \
../iocLogServer.c ../pprPlot.c ../racPrint.c ../recListProg.c \
../recordTest.c ../startCArepeater.c ../sydPlot.c
OBJS = \
apCreateShadow.o apStatusSync.o bfRing.o ca_test.o calcTest.o \
bfRing.o ca_test.o calcTest.o \
cmdClient.o extrDoc.o guiSubr.o iocLogServer.o pprPlot.o racPrint.o \
recListProg.o recordTest.o startCArepeater.o sydPlot.o
@@ -31,7 +31,7 @@ LIBOBJS = \
LIBNAME = libppr.a
PROD = \
apCreateShadow apStatusSync bfRing ca_test calcTest cmdClient \
bfRing ca_test calcTest cmdClient \
extrDoc iocLogServer racPrint recListProg recordTest startCArepeater
include $(EPICS)/config/RULES.Unix

View File

@@ -161,7 +161,7 @@ char *pname;
/*
* fetch as each type
*/
for(i=0; i<=LAST_BUFFER_TYPE; i++){
for(i=0; i<=DBR_CTRL_DOUBLE; i++){
if(ca_field_type(chan_id)==0) {
if( (i!=DBR_STRING)
&& (i!=DBR_STS_STRING)

View File

@@ -1270,13 +1270,15 @@ void *devLibA24Malloc(size_t size)
void *ret;
if (devLibA24Debug)
printf("devLibA24Malloc(%d) entered\n", size);
logMsg("devLibA24Malloc(%d) entered\n", size, 0,0,0,0,0);
if (A24MallocFunc == NULL)
{
/* See if the sysA24Malloc() function is present. */
if(symFindByName(sysSymTbl,"_sysA24Malloc", (char**)&A24MallocFunc,&stype)==ERROR)
{ /* Could not find sysA24Malloc... use the malloc one and hope we are OK */
if (devLibA24Debug)
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
A24MallocFunc = malloc;
A24FreeFunc = free;
}
@@ -1284,6 +1286,8 @@ void *devLibA24Malloc(size_t size)
{
if(symFindByName(sysSymTbl,"_sysA24Free", (char**)&A24FreeFunc, &stype) == ERROR)
{ /* That's strange... we have malloc, but no free! */
if (devLibA24Debug)
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
A24MallocFunc = malloc;
A24FreeFunc = free;
}
@@ -1301,5 +1305,8 @@ void *devLibA24Malloc(size_t size)
void devLibA24Free(void *pBlock)
{
if (devLibA24Debug)
logMsg("devLibA24Free(%p) entered\n", (unsigned long)pBlock,0,0,0,0,0);
A24FreeFunc(pBlock);
}

View File

@@ -1,6 +1,10 @@
/*
* $Log$
* Revision 1.4 1994/10/28 20:15:10 jbk
* increased the USP packet time-out to 250ms, added a parm to the configure()
* routine to let user specify it.
*
*/
/**************************************************************************
@@ -653,7 +657,23 @@ static void TSerrorHandler(int Card, int ErrorNum)
Could put the slave on the vxworks timer until next sync
*/
logMsg("***TSerrorHandler: error number %d=n",ErrorNum,0,0,0,0,0);
if(MAKE_DEBUG)
{
switch(ErrorNum)
{
case 1:
logMsg("***TSerrorHandler: event system error: TAXI violation",0,0,0,0,0,0);
break;
case 2:
logMsg("***TSerrorHandler: event system error: lost heartbeat",0,0,0,0,0,0);
break;
case 3:
logMsg("***TSerrorHandler: event system error: lost events",0,0,0,0,0,0);
break;
default:
logMsg("***TSerrorHandler: unknown error %d from event system", ErrorNum,0,0,0,0,0);
}
}
return;
}

View File

@@ -139,8 +139,10 @@ int GI(void)
for (cnt=0; cnt < LIST_SIZE; cnt++)
{ /* init the elements of the command table */
#if 0
gpibIntCmds[cnt].head.header.list.list1 = NULL;
gpibIntCmds[cnt].head.header.list.list2 = NULL;
#endif
gpibIntCmds[cnt].head.workStart = gpibWork;
gpibIntCmds[cnt].head.link = 0;
gpibIntCmds[cnt].head.device = 0;
@@ -155,7 +157,7 @@ int GI(void)
}
ans = 0; /* set loop not to exit */
printf("\n\n");
logMsg("\n\n");
while ((ans != 'q') && (ans != 'Q'))
{
@@ -380,6 +382,8 @@ static int sendMsg(void)
if (replyIsBack)
{
if (ibDebug)
taskDelay(60); /* Allow debug printing to complete */
showGpibMsg(msgNum);
}
else
@@ -438,7 +442,7 @@ static int gpibWork(struct gpibIntCmd *pCmd)
}
else if (status > (MAX_MSG_LENGTH - 1)) /* check length of resp */
{
printf("GPIB Response length equaled allocated space !!!\n");
logMsg("GPIB Response length equaled allocated space !!!\n");
pCmd->resp[(MAX_MSG_LENGTH)] = '\0'; /* place \0 at end */
}
else

View File

@@ -391,8 +391,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else

View File

@@ -404,9 +404,9 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest(phwpvt->unsolicitedDpvt);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else
{

View File

@@ -282,8 +282,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else