]> jspc29.x-matter.uni-frankfurt.de Git - daqdata.git/commitdiff
*** empty log message ***
authormuench <muench>
Tue, 31 Aug 1999 10:37:23 +0000 (10:37 +0000)
committermuench <muench>
Tue, 31 Aug 1999 10:37:23 +0000 (10:37 +0000)
67 files changed:
hadaq/Makefile [new file with mode: 0644]
hadaq/agent.c [new file with mode: 0644]
hadaq/agent.x [new file with mode: 0644]
hadaq/cmds.tcl [new file with mode: 0644]
hadaq/ctrlctu.c [new file with mode: 0644]
hadaq/ctu.h [new file with mode: 0644]
hadaq/evt.c [new file with mode: 0644]
hadaq/evt.h [new file with mode: 0644]
hadaq/evtbuild.c [new file with mode: 0644]
hadaq/grmblfx.h [new file with mode: 0644]
hadaq/hadaq.tcl [new file with mode: 0644]
hadaq/hadaq_init.tcl [new file with mode: 0644]
hadaq/hadtu.c [new file with mode: 0644]
hadaq/hadtu.h [new file with mode: 0644]
hadaq/hadtuqueue.c [new file with mode: 0644]
hadaq/hadtuqueue.h [new file with mode: 0644]
hadaq/hardware.h [new file with mode: 0644]
hadaq/hldread.c [new file with mode: 0644]
hadaq/hldread.h [new file with mode: 0644]
hadaq/ht98.tcl [new file with mode: 0644]
hadaq/hwmdc.c [new file with mode: 0644]
hadaq/hwrace.c [new file with mode: 0644]
hadaq/hwrace.h [new file with mode: 0644]
hadaq/hwrich.c [new file with mode: 0644]
hadaq/hwsam.c [new file with mode: 0644]
hadaq/hwsam.h [new file with mode: 0644]
hadaq/hwship.c [new file with mode: 0644]
hadaq/hwship.h [new file with mode: 0644]
hadaq/hwshow.c [new file with mode: 0644]
hadaq/hwsoft.c [new file with mode: 0644]
hadaq/ipc_basis.h [new file with mode: 0644]
hadaq/memnet.c [new file with mode: 0644]
hadaq/mman.c [new file with mode: 0644]
hadaq/mman.h [new file with mode: 0644]
hadaq/netmem.c [new file with mode: 0644]
hadaq/nettrans.c [new file with mode: 0644]
hadaq/nettrans.h [new file with mode: 0644]
hadaq/online.c [new file with mode: 0644]
hadaq/online.x [new file with mode: 0644]
hadaq/param.c [new file with mode: 0644]
hadaq/param.h [new file with mode: 0644]
hadaq/param.tcl [new file with mode: 0644]
hadaq/pkt.c [new file with mode: 0644]
hadaq/pkt.h [new file with mode: 0644]
hadaq/psxshm.c [new file with mode: 0644]
hadaq/psxshm.h [new file with mode: 0644]
hadaq/rc.c [new file with mode: 0644]
hadaq/rc.h [new file with mode: 0644]
hadaq/readout.c [new file with mode: 0644]
hadaq/sam_defs.h [new file with mode: 0644]
hadaq/sched.h [new file with mode: 0644]
hadaq/semaphore.c [new file with mode: 0644]
hadaq/semaphore.h [new file with mode: 0644]
hadaq/shmtrans.c [new file with mode: 0644]
hadaq/shmtrans.h [new file with mode: 0644]
hadaq/showevt [new file with mode: 0644]
hadaq/showevt.c [new file with mode: 0644]
hadaq/sniff.c [new file with mode: 0644]
hadaq/startacq [new file with mode: 0644]
hadaq/stopacq [new file with mode: 0644]
hadaq/subevt.c [new file with mode: 0644]
hadaq/subevt.h [new file with mode: 0644]
hadaq/tclAppInit.c [new file with mode: 0644]
hadaq/tcldaq.c [new file with mode: 0644]
hadaq/tkAppInit.c [new file with mode: 0644]
hadaq/worker.c [new file with mode: 0644]
hadaq/worker.h [new file with mode: 0644]

diff --git a/hadaq/Makefile b/hadaq/Makefile
new file mode 100644 (file)
index 0000000..14ed4c2
--- /dev/null
@@ -0,0 +1,195 @@
+# UNIX
+#CC = c89
+#RPCGEN = rpcgen
+#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -L/usr/fore/lib -latm -lrt -ltk -lX11 -ltcl -lm
+#INCLUDES = -I$(HOME)/include -I/usr/fore/include
+#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT
+
+# UNIX w/o ATM
+#CC = c89
+#RPCGEN = rpcgen
+#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -lrt -ltk -lX11 -ltcl -lm
+#INCLUDES = -I$(HOME)/include -I/usr/fore/include
+#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT -DNOATM
+
+# Linux
+#CC = gcc
+#RPCGEN = rpcgen -k
+#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -llvme
+#INCLUDES = -I$(HOME)/include
+#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT -DNOATM
+
+# LynxOS
+CC = gcc
+RPCGEN = rpcgen
+LOADLIBES = -L/usr/local/lib -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -llvme -ltcl -lm -lrpc -lnetinet -L/lib/ces -lvme -lbma -luio
+INCLUDES = -I/usr/local/include -I$(HOME)/include
+DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DNOATM
+
+CFLAGS = -g $(INCLUDES) $(DEFINES)
+
+HW_OBJS = hwrich.o hwrace.o rc.o
+#HW_OBJS = hwsoft.o
+
+
+DAQ_XMANAGE_OBJS = tcldaq.o tkAppInit.o \
+       agent_clnt.o agent_xdr.o worker.o psxshm.o mman.o
+DAQ_MANAGE_OBJS = tcldaq.o tclAppInit.o \
+       agent_clnt.o agent_xdr.o worker.o psxshm.o mman.o
+DAQ_AGENT_OBJS = agent.o agent_svc.o agent_xdr.o \
+       worker.o psxshm.o mman.o
+DAQ_READOUT_OBJS = readout.o \
+       worker.o \
+       $(HW_OBJS) param.o subevt.o \
+       shmtrans.o semaphore.o hadtuqueue.o \
+               psxshm.o mman.o \
+               hadtu.o \
+               latm.o
+DAQ_MEMNET_OBJS = memnet.o \
+       worker.o \
+       shmtrans.o semaphore.o hadtuqueue.o \
+               psxshm.o mman.o \
+       nettrans.o pkt.o latm.o \
+               hadtu.o
+DAQ_NETMEM_OBJS = netmem.o \
+       worker.o \
+       shmtrans.o semaphore.o hadtuqueue.o \
+               psxshm.o mman.o \
+       nettrans.o pkt.o latm.o \
+               hadtu.o
+DAQ_EVTBUILD_OBJS = evtbuild.o \
+       worker.o \
+       shmtrans.o semaphore.o hadtuqueue.o \
+               psxshm.o mman.o \
+       online.o online_svc.o online_xdr.o \
+               evt.o subevt.o \
+                       hadtu.o
+DAQ_CTRLCTU_OBJS = ctrlctu.o \
+       worker.o psxshm.o mman.o
+DAQ_SNIFF_OBJS = sniff.o online_clnt.o online_xdr.o
+DAQ_ANAL_OBJS = showevt.o hldread.o evt.o subevt.o hadtu.o
+
+mini: daq_readout daq_evtbuild
+seb: daq_readout daq_memnet daq_agent
+eb: daq_netmem daq_evtbuild
+anal: daq_sniff daq_anal
+manage: daq_manage
+xmanage: daq_xmanage anal
+
+all : seb eb anal
+
+daq_xmanage: $(DAQ_XMANAGE_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_XMANAGE_OBJS) $(LOADLIBES) -o daq_xmanage
+
+daq_manage: $(DAQ_MANAGE_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_MANAGE_OBJS) $(LOADLIBES) -o daq_manage
+
+daq_agent: $(DAQ_AGENT_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_AGENT_OBJS) $(LOADLIBES) -o daq_agent
+
+daq_ctrlctu: $(DAQ_CTRLCTU_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_CTRLCTU_OBJS) $(LOADLIBES) -o daq_ctrlctu
+
+daq_readout: $(DAQ_READOUT_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_READOUT_OBJS) $(LOADLIBES) -o daq_readout
+
+daq_memnet: $(DAQ_MEMNET_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_MEMNET_OBJS) $(LOADLIBES) -o daq_memnet
+
+daq_netmem: $(DAQ_NETMEM_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_NETMEM_OBJS) $(LOADLIBES) -o daq_netmem
+
+daq_evtbuild: $(DAQ_EVTBUILD_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_EVTBUILD_OBJS) $(LOADLIBES) -o daq_evtbuild
+
+daq_sniff: $(DAQ_SNIFF_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_SNIFF_OBJS) $(LOADLIBES) -o daq_sniff
+
+daq_anal: $(DAQ_ANAL_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_ANAL_OBJS) $(LOADLIBES) -o daq_anal
+
+clean:
+       rm -f *.o *.out core tags \
+       agent.h agent_clnt.c agent_svc.c agent_xdr.c \
+       online.h online_clnt.c online_svc.c online_xdr.c
+
+latm.o: latm.c latm.h
+       cc $(CFLAGS) -c latm.c
+
+online_clnt.c: online.x
+       $(RPCGEN) -l online.x >online_clnt.c
+
+online_svc.c: online.x
+       $(RPCGEN) -m online.x >online_svc.c
+
+online_xdr.c: online.x
+       $(RPCGEN) -c online.x >online_xdr.c
+
+online.h: online.x
+       $(RPCGEN) -h online.x >online.h
+
+agent_clnt.c: agent.x
+       $(RPCGEN) -l agent.x >agent_clnt.c
+
+agent_svc.c: agent.x
+       $(RPCGEN) -s tcp agent.x >agent_svc.c
+
+agent_xdr.c: agent.x
+       $(RPCGEN) -c agent.x >agent_xdr.c
+
+agent.h: agent.x
+       $(RPCGEN) -h agent.x >agent.h
+
+depend:
+       $(RPCGEN) online.x
+       $(RPCGEN) agent.x
+       gcc -MM $(CFLAGS) *.c
+
+agent.o: agent.c agent.h worker.h psxshm.h
+agent_clnt.o: agent_clnt.c agent.h
+agent_svc.o: agent_svc.c agent.h
+agent_xdr.o: agent_xdr.c agent.h
+ctrlctu.o: ctrlctu.c ctu.h worker.h psxshm.h
+evt.o: evt.c evt.h hadtu.h subevt.h
+evtbuild.o: evtbuild.c worker.h psxshm.h evt.h hadtu.h subevt.h \
+ shmtrans.h hadtuqueue.h
+hadtu.o: hadtu.c hadtu.h
+hadtuqueue.o: hadtuqueue.c hadtu.h hadtuqueue.h
+hldread.o: hldread.c evt.h hadtu.h subevt.h hldread.h
+hwmdc.o: hwmdc.c param.h subevt.h hadtu.h hwsam.h hardware.h
+hwrace.o: hwrace.c subevt.h hadtu.h param.h rc.h hwrace.h
+hwrich.o: hwrich.c param.h subevt.h hadtu.h hwrace.h rc.h hardware.h
+hwsam.o: hwsam.c sam_defs.h hwsam.h param.h
+hwship.o: hwship.c param.h ipc_basis.h hwship.h
+hwshow.o: hwshow.c param.h subevt.h hadtu.h hwship.h hardware.h
+hwsoft.o: hwsoft.c subevt.h hadtu.h param.h hardware.h
+latm.o: latm.c
+memnet.o: memnet.c shmtrans.h psxshm.h hadtuqueue.h hadtu.h nettrans.h \
+ worker.h
+mman.o: mman.c
+netmem.o: netmem.c worker.h psxshm.h nettrans.h hadtu.h shmtrans.h \
+ hadtuqueue.h
+nettrans.o: nettrans.c grmblfx.h latm.h hadtu.h pkt.h worker.h \
+ psxshm.h nettrans.h
+online.o: online.c evt.h hadtu.h subevt.h online.h
+online_clnt.o: online_clnt.c online.h
+online_svc.o: online_svc.c online.h
+online_xdr.o: online_xdr.c online.h
+param.o: param.c param.h
+pkt.o: pkt.c pkt.h hadtu.h
+psxshm.o: psxshm.c psxshm.h
+rc.o: rc.c rc.h
+readout.o: readout.c grmblfx.h hardware.h shmtrans.h psxshm.h \
+ hadtuqueue.h hadtu.h worker.h
+semaphore.o: semaphore.c semaphore.h
+shmtrans.o: shmtrans.c grmblfx.h psxshm.h hadtuqueue.h hadtu.h \
+ shmtrans.h
+showevt.o: showevt.c hldread.h evt.h hadtu.h subevt.h
+sniff.o: sniff.c online.h
+subevt.o: subevt.c subevt.h hadtu.h
+tclAppInit.o: tclAppInit.c \
+ /usr/lib/gcc-lib/ppc-unknown-lynxos2.5/2.7-96q1/../../../../include/tcl.h
+tcldaq.o: tcldaq.c worker.h psxshm.h agent.h
+tkAppInit.o: tkAppInit.c \
+ /usr/lib/gcc-lib/ppc-unknown-lynxos2.5/2.7-96q1/../../../../include/tk.h
+worker.o: worker.c worker.h psxshm.h
diff --git a/hadaq/agent.c b/hadaq/agent.c
new file mode 100644 (file)
index 0000000..accc519
--- /dev/null
@@ -0,0 +1,71 @@
+#include <rpc/rpc.h>
+#include "agent.h"
+#include "worker.h"
+
+#define NWORKERS 16
+Worker *workers[NWORKERS];             /* inplicitly set to zero */
+
+static int addWorker(Worker *worker)
+{
+       int i;
+
+       for (i = 0; workers[i] != NULL; i++) {  /* BUGBUG crash if workers full */
+       }
+       workers[i] = worker;
+
+       return i;
+}
+
+static Worker *getWorker(int id)
+{
+       return workers[id];
+}
+
+static void removeWorker(int id)
+{
+       workers[id] = NULL;
+}
+
+int *rpcworker_start_1(RpcWorker_startArgs * args, CLIENT * cl)
+{
+       static int retVal;
+       Worker *worker;
+       int i;
+       char **argv;
+
+       /* The closing NULL in argv cannot be passed via rpc, we have to add it
+     here */
+
+       argv = malloc((args->argv.argv_len + 1) * sizeof(char *));
+
+       for (i = 0; i < args->argv.argv_len; i++) {
+               argv[i] = args->argv.argv_val[i];
+       }
+       argv[i] = NULL;
+
+       worker = Worker_start(args->name, argv);
+
+       free(argv);
+
+       retVal = addWorker(worker);
+       return &retVal;
+}
+
+char **rpcworker_status_1(int *id, CLIENT * cl)
+{
+       static char *retVal;
+
+       retVal = Worker_status(getWorker(*id));
+       return &retVal;
+}
+
+int *rpcworker_stop_1(int *id, CLIENT * cl)
+{
+       static int retVal;
+
+       Worker_stop(getWorker(*id), 15);
+
+       retVal = 0;
+
+       return &retVal;
+}
diff --git a/hadaq/agent.x b/hadaq/agent.x
new file mode 100644 (file)
index 0000000..2f498fe
--- /dev/null
@@ -0,0 +1,14 @@
+typedef string vstring<>;
+
+struct RpcWorker_startArgs {
+       string name<14>;
+       vstring argv<>;
+};
+
+program DAQAGENTPROG {
+       version DAQAGENTVERS {
+               int RpcWorker_start(RpcWorker_startArgs) = 1;
+               string RpcWorker_status(int) = 2;
+               int RpcWorker_stop(int) = 3;
+       } = 1;
+} = 0x20000002;
diff --git a/hadaq/cmds.tcl b/hadaq/cmds.tcl
new file mode 100644 (file)
index 0000000..4e082dc
--- /dev/null
@@ -0,0 +1,334 @@
+proc createAgent {agent} {
+       global agents
+       global agentList
+
+       lappend agentList $agent
+       set agents($agent.name) $agent
+       set agents($agent.host) $agent
+       set agents($agent.status) down
+}
+
+proc deleteAgent {agent} {
+       global agents
+       global agentList
+
+       unset agents($agent.name)
+       unset agents($agent.host)
+       unset agents($agent.status)
+       set agentList [lreplace $agentList [lsearch $agentList $agent] [lsearch $agentList $agent]]
+}
+
+proc catAgent {opts} {
+       global agents
+       global agentList
+
+       set status ""
+       if {[lsearch $opts "-up"] != -1} {
+               set status up
+       } elseif {[lsearch $opts "-down"] != -1} {
+               set status down
+       }
+       set w ""
+       if {[info exists agentList]} {
+               foreach i $agentList {
+                       if {$status == "" || $status == $agents($i.status)} {
+                               lappend w $i
+                       }
+               }
+       }
+       return $w
+}
+
+proc chkAgent {agent} {
+       global agents
+
+       if [catch {exec /usr/sbin/rpcinfo -t [agent list $agent host] 536870914}] {
+               set agents($agent.status) down
+       } else {
+               set agents($agent.status) up
+       }
+}
+
+proc connectAgent {agent} {
+       global agents
+
+  chkAgent $agent
+       if {"$agents($agent.status)" == "up"} {
+               set agents($agent.addr) [eval c_agent connect $agents($agent.host)]
+       }
+}
+
+proc disconnectAgent {agent} {
+       global agents
+
+       c_agent disconnect $agents($agent.addr)
+       unset agents($agent.addr)
+       set agents($agent.status) down
+}
+
+proc listAgent {agent what } {
+       global agents
+
+       if {$what == {}} {
+               set what {name host status}
+       }
+       foreach i $what {
+               catch {unset m}
+               if {[llength $what] != 1} {
+                       lappend m "$i"
+               }
+               lappend m "$agents($agent.$i)"
+               lappend l "$m"
+       }
+       return $l
+}
+
+proc agent {oper {agent {}} {args {}}} {
+       global agents
+
+       if {"$oper" == "help"} {
+               puts {usage: agent <oper> [options]}
+       } elseif {"$oper" == "oper"} {
+               puts "create delete connect disconnect status oper help"
+       } elseif {"$oper" == "cat"} {
+               catAgent "$agent $args"
+       } elseif {"$oper" == "create"} {
+               createAgent $agent
+       } elseif {"$oper" == "connect"} {
+               if {"$agent" == "all"} {
+                       while {[agent cat -down] != {}} {
+                               connectAgent [lindex [agent cat -down] 0]
+                       }
+               } else {
+                       connectAgent $agent
+               }
+       } elseif {"$oper" == "disconnect"} {
+               if {"$agent" == "all"} {
+                       while {[agent cat -up] != {}} {
+                               disconnectAgent [lindex [agent cat -up] [expr [llength [agent cat -up]] - 1]]
+                       }
+               } else {
+                       disconnectAgent $agent
+               }
+       } elseif {"$oper" == "status"} {
+               return $agents($agent.status)
+       } elseif {"$oper" == "list"} {
+               listAgent $agent $args
+       } elseif {"$oper" == "delete"} {
+               deleteAgent $agent
+       }
+}
+
+proc createWorker {worker opts} {
+       global workers
+       global workerList
+
+       lappend workerList $worker
+       regexp {^([^:]*):([^:]*)$} $worker workers($worker.name) workers($worker.agent) workers($worker.file)
+       set workers($worker.file) daq_$workers($worker.file)
+       set workers($worker.opts) $opts
+       set workers($worker.addOpts) {}
+       set workers($worker.status) down
+}
+
+proc addOptsWorker {worker opts} {
+       global workers
+
+       set workers($worker.addOpts) $opts
+}
+
+proc deleteWorker {worker} {
+       global workers
+       global workerList
+
+       unset workers($worker.name)
+       unset workers($worker.agent)
+       unset workers($worker.file)
+       unset workers($worker.status)
+       unset workers($worker.opts)
+       unset workers($worker.addOpts)
+       set workerList [lreplace $workerList [lsearch $workerList $worker] [lsearch $workerList $worker]]
+}
+
+proc catWorker {opts} {
+       global workers
+       global workerList
+
+       set status ""
+       if {[lsearch $opts "-up"] != -1} {
+               set status up
+       } elseif {[lsearch $opts "-down"] != -1} {
+               set status down
+       }
+       set w ""
+       if {[info exists workerList]} {
+               foreach i $workerList {
+                       if {$status == "" || $status == $workers($i.status)} {
+                               lappend w $i
+                       }
+               }
+       }
+       return $w
+}
+
+proc listWorker {worker what } {
+       global workers
+
+       if {$what == {}} {
+               set what {name agent file opts status}
+       }
+       foreach i $what {
+               catch {unset m}
+               if {[llength $what] != 1} {
+                       lappend m "$i"
+               }
+               lappend m "$workers($worker.$i)"
+               lappend l "$m"
+       }
+       return $l
+}
+
+proc startWorker {worker} {
+       global workers
+
+       set opts "$workers($worker.opts) $workers($worker.addOpts)"
+       set workers($worker.addr) [eval c_worker start [agent list $workers($worker.agent) addr] $workers($worker.file) $opts]
+       set workers($worker.status) up
+}
+
+proc stopWorker {worker} {
+       global workers
+
+       c_worker stop [agent list $workers($worker.agent) addr] $workers($worker.addr)
+       unset workers($worker.addr)
+       set workers($worker.status) down
+}
+
+proc worker {oper {worker {}} {args {}}} {
+       global workers
+
+       if {"$oper" == "help"} {
+               puts {usage: worker <oper> [options]}
+       } elseif {"$oper" == "oper"} {
+               puts "create delete start stop status oper help"
+       } elseif {"$oper" == "cat"} {
+               catWorker "$worker $args"
+       } elseif {"$oper" == "create"} {
+               createWorker $worker $args
+       } elseif {"$oper" == "addopts"} {
+               addOptsWorker $worker $args
+       } elseif {"$oper" == "start"} {
+               if {"$worker" == "all"} {
+                       while {[worker cat -down] != {}} {
+                               startWorker [lindex [worker cat -down] 0]
+                       }
+               } else {
+                       startWorker $worker
+               }
+       } elseif {"$oper" == "stop"} {
+               if {"$worker" == "all"} {
+                       while {[worker cat -up] != {}} {
+                               stopWorker [lindex [worker cat -up] [expr [llength [worker cat -up]] - 1]]
+                       }
+               } else {
+                       stopWorker $worker
+               }
+       } elseif {"$oper" == "status"} {
+               if {[lsearch $args "-counter"] != -1 && $workers($worker.status) == "up"} {
+                       set l [c_worker status [agent list $workers($worker.agent) addr] $workers($worker.addr)]
+               } else {
+                       set l $workers($worker.status)
+               }
+               return $l
+       } elseif {"$oper" == "list"} {
+               listWorker $worker $args
+       } elseif {"$oper" == "delete"} {
+               deleteWorker $worker
+       }
+}
+
+proc createGroup {group} {
+       global groups
+       global groupList
+
+       lappend groupList $group
+       set groups($group.name) $group
+}
+
+proc deleteGroup {group} {
+       global groups
+       global groupList
+
+       unset groups($group.name)
+       set groupList [lreplace $groupList [lsearch $groupList $group] [lsearch $groupList $group]]
+}
+
+proc catGroup {opts} {
+       global groups
+       global groupList
+
+       return $groupList
+}
+
+proc addGroup {group worker} {
+       global groups
+
+       lappend groups($group.members) $worker
+}
+
+proc removeGroup {group worker} {
+       global groups
+
+       set groups($group.members) [lreplace $groups($group.members) [lsearch $groups($group.members) $worker] [lsearch $groups($group.members) $worker]]
+}
+
+proc reverse {l} {
+       set x [expr [llength $l] - 1]
+       while {$x >= 0} {
+               lappend m [lindex $l $x]
+               set x [expr $x - 1]
+       }
+       return $m
+}
+
+proc group {oper {group {}} {args {}}} {
+       global groups
+
+       if {"$oper" == "oper"} {
+               puts "create delete add remove oper help"
+       } elseif {"$oper" == "cat"} {
+               catGroup "$group $args"
+       } elseif {"$oper" == "create"} {
+               createGroup $group
+       } elseif {"$oper" == "add"} {
+               addGroup $group $args
+       } elseif {"$oper" == "remove"} {
+               removeGroup $group $args
+       } elseif {"$oper" == "start"} {
+               foreach i $groups($group.members) {
+                       worker start $i $args
+               }
+       } elseif {"$oper" == "stop"} {
+               foreach i [reverse $groups($group.members)] {
+                       worker stop $i
+               }
+       } elseif {"$oper" == "status"} {
+               catch {unset l}
+               foreach i $groups($group.members) {
+                       lappend l [list $i [worker status $i $args]]
+               }
+               return $l
+       } elseif {"$oper" == "list"} {
+               foreach i {name members} {
+                       catch {unset m}
+                       lappend m "$i"
+                       lappend m "$groups($group.$i)"
+                       lappend l "$m"
+               }
+               return $l
+       } elseif {"$oper" == "delete"} {
+               deleteGroup $group
+       } else {
+               puts {usage: group <oper> [options]}
+       }
+}
diff --git a/hadaq/ctrlctu.c b/hadaq/ctrlctu.c
new file mode 100644 (file)
index 0000000..25bc6f0
--- /dev/null
@@ -0,0 +1,117 @@
+
+#include <stddef.h>
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <types.h>
+#include <ces/vmelib.h>
+
+#include <hadesstd.h>
+
+#include "ctu.h"
+#include "worker.h"
+
+static jmp_buf terminateJmp;
+
+void sigHandler(int sig)
+{
+       longjmp(terminateJmp, sig);
+}
+
+static void usage(const char *progName)
+{
+       msglog(LOG_ERR, "Usage: %s start|stop|#trig\n", progName);
+       msglog_usage();
+}
+
+int main(int argc, char *argv[])
+{
+       Ctu *ctu;
+       Worker *worker;
+       int isStandalone;
+       int priority;
+       ptrdiff_t offset;
+       int i;
+       unsigned long value;
+       struct pdparam_master paramS, *param = &paramS;
+       int oper;
+       unsigned long *ctuEnabled;
+
+       msglog_setlevel(argv[0], "info");
+
+       isStandalone = 1;
+       priority = 0;
+       while ((i = getopt(argc, argv, "ap:v:")) != -1) {
+               switch (i) {
+               case 'a':
+                       isStandalone = 0;
+                       break;
+               case 'p':
+                       priority = atoi(optarg);
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) != 1) {
+                               usage(argv[0]);
+                               goto bailOut0;
+                       }
+                       break;
+               default:
+                       usage(argv[0]);
+                       goto bailOut0;
+                       break;
+               }
+       }
+
+       if (NULL == (worker = Worker_init(argv[0], sigHandler, priority, isStandalone))) {
+               msglog(LOG_ERR, "connecting to agent: %s\n", strerror(errno));
+               goto bailOut0;
+       }
+       if (NULL == (ctuEnabled = Worker_addStatistic(worker, "ctuEnabled"))) {
+               msglog(LOG_ERR, "addingStatistic: %s\n", strerror(errno));
+               goto bailOut0;
+       }
+       param->iack = 1;
+       param->rdpref = 0;
+       param->wrpost = 0;
+       param->swap = 1;
+
+       ctu = allocMem(sizeof(Ctu));
+       if (-1 == conCtu(ctu, 0x44000000)) {
+               msglog(LOG_ERR, "Initializing Ctu: %s\n", strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+       Ctu_softBusy(ctu, 1);
+       (*ctuEnabled) = 0;
+       Ctu_clear(ctu);
+       Ctu_wrDeadtime(ctu, 0x08);
+       Ctu_wrDelay(ctu, 0x08);
+       Ctu_inhibit(ctu, 1);
+       Ctu_maskTrig(ctu, 1);
+       Ctu_softBusy(ctu, 0);
+       (*ctuEnabled) = 1;
+       Ctu_softTrig(ctu, 0x10);
+       Ctu_maskTrig(ctu, 0);
+       msglog(LOG_DEBUG, "%s\n", Ctu_2charP(ctu));
+       if (0 == setjmp(terminateJmp)) {
+               sleep(32767);
+       }
+       Ctu_maskTrig(ctu, 1);
+       Ctu_softTrig(ctu, 0x20);
+       msglog(LOG_DEBUG, "%s\n", Ctu_2charP(ctu));
+       Ctu_softBusy(ctu, 1);
+       Ctu_maskTrig(ctu, 0);
+       Ctu_inhibit(ctu, 0);
+       (*ctuEnabled) = 0;
+
+       desCtu(ctu);
+       Worker_fini(worker);
+       freeMem(ctu);
+
+       exit(0);
+
+  bailOut0:
+       exit(1);
+}
diff --git a/hadaq/ctu.h b/hadaq/ctu.h
new file mode 100644 (file)
index 0000000..400eef2
--- /dev/null
@@ -0,0 +1,232 @@
+#ifndef CTU_H
+#define CTU_H
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <ces/vmelib.h>
+
+#include <hadesstd.h>
+
+#define STATUS1                0x00
+#define        DEAD1           0x04
+#define CODE1          0x08
+#define TAG1           0x0c
+#define STATUS2                0x10
+#define        DEAD2           0x14
+#define CODE2          0x18
+#define TAG2           0x1c
+#define TRIG1          0x20
+#define FIPO2          0x24
+#define MEM_DATA1      0x30
+#define MEM_DATA2      0x34
+#define MEM_RESET      0x38
+#define MAGIC          0x3c
+
+typedef struct CtuS {
+  volatile UInt1 *base;
+  UInt2 internalTrigNr;
+} Ctu;
+
+static UInt1 Ctu_rdStatus(Ctu * my)
+{
+  return *(my->base + STATUS1);
+}
+
+static UInt1 Ctu_rdDeadtime(Ctu * my)
+{
+  return *(my->base + DEAD1);
+}
+
+static void Ctu_wrDelay(Ctu * my, UInt1 delay)
+{
+       *(my->base + FIPO2) = delay;
+}
+
+static UInt1 Ctu_magicIsOk(Ctu * my)
+{
+  return *(my->base + MAGIC) == 0x51;
+}
+
+static void Ctu_clear(Ctu *my)
+{
+       *(my->base + STATUS1) |= 0x01;
+       *(my->base + STATUS1) &= ~0x01;
+       *(my->base + STATUS2) |= 0x01;
+       *(my->base + STATUS2) &= ~0x01;
+}
+
+static void Ctu_inhibit(Ctu *my, int v)
+{
+  if (v) {
+               *(my->base + STATUS1) |= 0x02;
+               *(my->base + STATUS2) |= 0x02;
+       } else {
+               *(my->base + STATUS1) &= ~0x02;
+               *(my->base + STATUS2) &= ~0x02;
+       }
+}
+
+static void Ctu_maskBusy(Ctu *my, int v)
+{
+  if (v) {
+               *(my->base + STATUS1) |= 0x40;
+       } else {
+               *(my->base + STATUS1) &= ~0x40;
+       }
+}
+
+static void Ctu_maskTrig(Ctu *my, int v)
+{
+  if (v) {
+               *(my->base + STATUS1) |= 0x08;
+       } else {
+               *(my->base + STATUS1) &= ~0x08;
+       }
+}
+
+static void Ctu_lockBusy(Ctu *my, int v)
+{
+  if (v) {
+               *(my->base + STATUS1) |= 0x01;
+       } else {
+               *(my->base + STATUS1) &= ~0x01;
+       }
+}
+
+static void Ctu_softBusy(Ctu *my, int v)
+{
+  if (v) {
+               *(my->base + STATUS1) |= 0x20;
+       } else {
+               *(my->base + STATUS1) &= ~0x20;
+       }
+}
+
+static int Ctu_isBusy(Ctu *my)
+{
+  return (*(my->base + STATUS1) & 0x40) != 0;
+}
+
+static int Ctu_isError(Ctu *my)
+{
+  return (*(my->base + STATUS1) & 0x80) != 0;
+}
+
+static void Ctu_wrDeadtime(Ctu * my, UInt1 time)
+{
+       *(my->base + DEAD1) = time;
+}
+
+static UInt1 Ctu_rdTrigCode(Ctu * my)
+{
+       return *(my->base + CODE1) & 0x0f;
+}
+
+static UInt1 Ctu_rdTrigTag(Ctu * my)
+{
+       return *(my->base + TAG1);
+}
+
+static int Ctu_fifoIsEmpty(Ctu * my)
+{
+       return (*(my->base + FIPO2) & 0x01) != 0;
+}
+
+static void Ctu_popFifo(Ctu * my)
+{
+       *(my->base + FIPO2) = 0;
+}
+
+static void Ctu_softTrig(Ctu *my, UInt1 trigType) {
+       struct timespec tS, *t = &tS;
+       t->tv_sec = 0;
+       t->tv_nsec = 1;
+
+       *(my->base + TRIG1) = 0x80;
+       nanosleep(t, NULL);
+       *(my->base + TRIG1) = 0x80 | trigType;
+       nanosleep(t, NULL);
+       *(my->base + TRIG1) = 0x00;
+       nanosleep(t, NULL);
+}
+
+static char *Ctu_2charP(Ctu * my)
+{
+  static char s[7 * 80];
+
+  sprintf(s,
+    "base: 0x%08x\n"
+    "status: 0x%02x\n"
+    "deadtime: 0x%02x\n"
+    "trigCode: 0x%01x\n"
+    "trigTag: 0x%02x\n"
+    "magicIsOk: %d\n",
+    my->base,
+    Ctu_rdStatus(my),
+    Ctu_rdDeadtime(my),
+    Ctu_rdTrigCode(my),
+    Ctu_rdTrigTag(my),
+    Ctu_magicIsOk(my)
+  );
+  return s;
+}
+
+static int Ctu_invariant(Ctu * my)
+{
+  return 1;
+}
+
+static int conCtu(Ctu * my, unsigned long cardBase)
+{
+  struct pdparam_master paramS, *param = &paramS;
+unsigned char  init_code1[] = {0, 1, 4, 4, 5, 5, 5, 5,
+                               6, 6, 6, 6, 6, 6, 6, 6,
+                               2, 2, 2, 2, 2, 2, 2, 2,
+                               2, 2, 2, 2, 2, 2, 2, 2,
+                               3, 3, 3, 3, 3, 3, 3, 3,
+                               3, 3, 3, 3, 3, 3, 3, 3,
+                               3, 3, 3, 3, 3, 3, 3, 3,
+                               3, 3, 3, 3, 3, 3, 3, 3};
+       int i;
+
+  assert(my != NULL);
+
+  param->iack = 1;
+  param->rdpref = 0;
+  param->wrpost = 0;
+  param->swap = 2;
+
+
+  if (
+    (volatile UInt1 *)-1 == (my->base = (volatile UInt1 *)find_controller(
+      cardBase, 0x10000UL, 0x09UL, 0x0000003cUL, 1UL, param
+    ))
+  ) {
+    return -1;
+  }
+
+       *(my->base + STATUS1) = 0;
+       *(my->base + STATUS2) = 0;
+       for(i=0; i<64; ++i)
+       {
+               *(my->base + TAG1) = i;
+               *(my->base + CODE1) = init_code1[i];
+       }
+       *(my->base + TAG1) = 0;
+  assert(Ctu_invariant(my));
+
+  return 0;
+}
+
+static void desCtu(Ctu * my)
+{
+  assert(Ctu_invariant(my));
+
+  Ctu_inhibit(my, 0);
+  return_controller((unsigned long)my->base, 0x10000UL);
+}
+
+#endif
diff --git a/hadaq/evt.c b/hadaq/evt.c
new file mode 100644 (file)
index 0000000..b46ed60
--- /dev/null
@@ -0,0 +1,225 @@
+static char rcsId[] = "$Id: evt.c,v 6.1 1999-08-31 10:37:23 muench Exp $";
+
+#define _ANSI_C_SOURCE
+#include <stddef.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "evt.h"
+#include "subevt.h"
+
+enum EvtIdx {
+       EvtIdx_size,
+       EvtIdx_decoding,
+       EvtIdx_id,
+       EvtIdx_seqNr,
+       EvtIdx_date,
+       EvtIdx_time,
+       EvtIdx_runNr,
+       EvtIdx_pad,
+       EvtIdx_data
+};
+
+size_t Evt_hdrLen(void)
+{
+       return EvtIdx_data;
+}
+
+size_t Evt_hdrSize(void)
+{
+       return Evt_hdrLen() * sizeof(UInt4);
+}
+
+size_t Evt_dataSize(const void *my)
+{
+       return Evt_size(my) - Evt_hdrSize();
+}
+
+void *Evt_data(const void *my)
+{
+       return (void *) ((char *) my + Evt_hdrSize());
+}
+
+UInt4 Evt_id(const void *my)
+{
+       return Evt_hdrValue(my, EvtIdx_id);
+}
+
+void Evt_setId(void *my, UInt4 id)
+{
+       Evt_setHdrValue(my, EvtIdx_id, id);
+}
+
+UInt4 Evt_seqNr(const void *my)
+{
+       return Evt_hdrValue(my, EvtIdx_seqNr);
+}
+
+void Evt_setSeqNr(void *my, UInt4 seqNr)
+{
+       Evt_setHdrValue(my, EvtIdx_seqNr, seqNr);
+}
+
+UInt4 Evt_date(const void *my)
+{
+       return Evt_hdrValue(my, EvtIdx_date);
+}
+
+void Evt_setDate(void *my, UInt4 date)
+{
+       Evt_setHdrValue(my, EvtIdx_date, date);
+}
+
+UInt4 Evt_time(const void *my)
+{
+       return Evt_hdrValue(my, EvtIdx_time);
+}
+
+void Evt_setTime(void *my, UInt4 time)
+{
+       Evt_setHdrValue(my, EvtIdx_time, time);
+}
+
+UInt4 Evt_runNr(const void *my)
+{
+       return Evt_hdrValue(my, EvtIdx_runNr);
+}
+
+void Evt_setRunNr(void *my, UInt4 runNr)
+{
+       Evt_setHdrValue(my, EvtIdx_runNr, runNr);
+}
+
+char *Evt_date2charP(const void *my)
+{
+       time_t tempo;
+       struct tm *gmTime;
+       static char buffer[80];
+
+       tempo = time(NULL);
+       gmTime = gmtime(&tempo);
+       gmTime->tm_year = (Evt_date(my) >> 16) & 0xff;
+       gmTime->tm_mon = (Evt_date(my) >> 8) & 0xff;
+       gmTime->tm_mday = (Evt_date(my) >> 0) & 0xff;
+       strftime(buffer, 80, "%Y-%m-%d", gmTime);
+
+       return buffer;
+}
+
+char *Evt_time2charP(const void *my)
+{
+       time_t tempo;
+       struct tm *gmTime;
+       static char buffer[80];
+
+       tempo = time(NULL);
+       gmTime = gmtime(&tempo);
+       gmTime->tm_hour = (Evt_time(my) >> 16) & 0xff;
+       gmTime->tm_min = (Evt_time(my) >> 8) & 0xff;
+       gmTime->tm_sec = (Evt_time(my) >> 0) & 0xff;
+       strftime(buffer, 80, "%H:%M:%S", gmTime);
+
+       return buffer;
+}
+
+char *Evt_2charP(const void *my)
+{
+       static char buf[2 * 132];
+
+       sprintf(buf,
+                       "size: %08x\tdecoding: %08x\tid: %08x\tseqNr: %08x\n"
+                       "date: %s\ttime: %s\trunNr: %d",
+                       Evt_size(my), Evt_decoding(my), Evt_id(my), Evt_seqNr(my),
+                       Evt_date2charP(my), Evt_time2charP(my), Evt_runNr(my)
+               );
+
+       return buf;
+}
+
+void *newEvt(UInt4 decoding, UInt4 id, UInt4 runNr)
+{
+       void *my;
+
+       my = allocMem(Evt_hdrSize());
+
+       Evt_setSize(my, Evt_hdrSize());
+       Evt_setDecoding(my, decoding);
+       Evt_setId(my, id);
+       Evt_setRunNr(my, runNr);
+
+       return my;
+}
+
+void *getEvt(void *my)
+{
+       static UInt4 seqNr = 0;
+       time_t tempo;
+       struct tm *gmTime;
+       UInt4 dummy;
+
+       Evt_setSeqNr(my, seqNr++);
+
+       tempo = time(NULL);
+       gmTime = gmtime(&tempo);
+
+       dummy = 0;
+       dummy |= gmTime->tm_year << 16;
+       dummy |= gmTime->tm_mon << 8;
+       dummy |= gmTime->tm_mday;
+       Evt_setDate(my, dummy);
+
+       dummy = 0;
+       dummy |= gmTime->tm_hour << 16;
+       dummy |= gmTime->tm_min << 8;
+       dummy |= gmTime->tm_sec;
+       Evt_setTime(my, dummy);
+
+       return my;
+}
+
+void deleteEvt(void *my)
+{
+       freeMem(my);
+}
+
+int Evt_write(void *my, FILE * file)
+{
+       return fwrite(my, 1, Evt_paddedSize(my), file);
+}
+
+void *Evt_appendSubEvt(void *my, void *subEvt)
+{
+       /* BUGBUG in principal, aligned memory size must be allocated */
+       my = reallocMem(my, Evt_paddedSize(my) + SubEvt_size(subEvt));
+       memcpy(Evt_end(my), subEvt, SubEvt_size(subEvt));
+       Evt_setSize(my, Evt_paddedSize(my) + SubEvt_size(subEvt));
+
+       return my;
+}
+
+void *Evt_fget(FILE * file)
+{
+       static void *evt = NULL;
+
+       if (evt != NULL) {
+               freeMem(evt);
+       }
+       evt = allocMem(Evt_hdrSize());
+
+       if (Evt_hdrSize() != fread(evt, 1, Evt_hdrSize(), file)) {
+               msglog(LOG_DEBUG, "%s:%d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       evt = reallocMem(evt, Evt_paddedSize(evt));
+
+       /* BUGBUG quickhack for a "Evt_paddedDataSize" */
+       if (Evt_paddedSize(evt) - Evt_hdrSize() != fread(Evt_data(evt), 1, Evt_paddedSize(evt) - Evt_hdrSize(), file)) {
+               msglog(LOG_ERR, "%s:%d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       return evt;
+}
diff --git a/hadaq/evt.h b/hadaq/evt.h
new file mode 100644 (file)
index 0000000..8202ce1
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef EVT_H
+#define EVT_H
+
+#include <stdio.h>
+#include <time.h>
+#include <hadesstd.h>
+
+#include "hadtu.h"
+#include "subevt.h"
+
+static const int evtBlockSize = 8 * 1024;
+
+enum EvtId {
+  EvtId_data,
+  EvtId_runStart
+};
+
+enum EvtDecoding {
+  EvtDecoding_default = 1,
+  EvtDecoding_64bitAligned = (0x03 << 16) | 0x0001
+};
+
+#define Evt_hdr HadTu_hdr
+#define Evt_isSwapped HadTu_isSwapped
+#define Evt_hdrValue HadTu_hdrValue
+#define Evt_setHdrValue HadTu_setHdrValue
+#define Evt_decoding HadTu_decoding
+#define Evt_setDecoding HadTu_setDecoding
+#define Evt_alignment HadTu_alignment
+#define Evt_size HadTu_size
+#define Evt_setSize HadTu_setSize
+#define Evt_paddedSize HadTu_paddedSize
+#define Evt_begin HadTu_begin
+#define Evt_end HadTu_end
+#define Evt_next HadTu_next
+
+size_t Evt_hdrLen(void);
+size_t Evt_hdrSize(void);
+size_t Evt_dataSize(const void *my);
+void *Evt_data(const void *my);
+char *Evt_date2charP(const void *my);
+char *Evt_time2charP(const void *my);
+char *Evt_2charP(const void *my);
+
+UInt4 Evt_id(const void *my);
+void Evt_setId(void *my, UInt4 id);
+UInt4 Evt_seqNr(const void *my);
+void Evt_setSeqNr(void *my, UInt4 seqNr);
+UInt4 Evt_date(const void *my);
+void Evt_setDate(void *my, UInt4 date);
+UInt4 Evt_time(const void *my);
+void Evt_setTime(void *my, UInt4 time);
+UInt4 Evt_runNr(const void *my);
+void Evt_setRunNr(void *my, UInt4 runNr);
+
+void *newEvt(UInt4 decoding, UInt4 id, UInt4 runNr);
+void *getEvt(void *my);
+void deleteEvt(void *my);
+int Evt_write(void *my, FILE * file);
+void *Evt_fget(FILE * file);
+void *Evt_appendSubEvt(void *my, void *subEvt);
+
+#endif
diff --git a/hadaq/evtbuild.c b/hadaq/evtbuild.c
new file mode 100644 (file)
index 0000000..fa52723
--- /dev/null
@@ -0,0 +1,375 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/evtbuild.c,v 6.1 1999-08-31 10:37:23 muench Exp $";
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <hadesstd.h>
+
+#include "worker.h"
+#include "evt.h"
+#include "subevt.h"
+#include "shmtrans.h"
+
+static jmp_buf terminateJmp;
+
+void sigHandler(int sig)
+{
+       longjmp(terminateJmp, sig);
+}
+
+static void *appendFile(void *my, const char *path)
+{
+       void *subEvt;
+       char *dataBuf;
+       FILE *file;
+       size_t fileSize;
+
+       if (NULL == (file = fopen(path, "r"))) {
+               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return my;
+       }
+       subEvt = newSubEvt(SubEvtDecoding_text, SubEvtId_slow, 0);
+
+       if (NULL == (dataBuf = malloc(strlen(path + 2)))) {
+               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return my;
+       }
+       sprintf(dataBuf, "#%s\n", path);
+       subEvt = SubEvt_appendData(subEvt, dataBuf, strlen(dataBuf));
+       free(dataBuf);
+
+       fseek(file, 0, SEEK_END);
+       fileSize = ftell(file);
+       fseek(file, 0, SEEK_SET);
+       if (NULL == (dataBuf = malloc(fileSize))) {
+               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return my;
+       }
+       fread(dataBuf, 1, fileSize, file);
+
+       subEvt = SubEvt_appendData(subEvt, dataBuf, fileSize);
+       my = Evt_appendSubEvt(my, subEvt);
+
+       deleteSubEvt(subEvt);
+       free(dataBuf);
+       fclose(file);
+
+       return my;
+}
+
+/* BUGBUG Tape handling needs complete new implementation */
+static FILE *openTape(const char *outPath)
+{
+       FILE *outFile;
+       int fd[2];
+       char path[_POSIX_PATH_MAX];
+
+       strcpy(path, "of=");
+       strcat(path, outPath);
+
+       if (0 > pipe(fd)) {
+               msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       switch (fork()) {
+       case -1:
+               msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+               break;
+       case 0:
+               if (-1 == close(0)) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+               if (0 != dup(fd[0])) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+               if (-1 == close(fd[0])) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+               if (-1 == close(fd[1])) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+               if (-1 == execlp("dd", "dd", "ibs=1024k", "obs=8192", path, NULL)) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+               break;
+       default:
+               outFile = fdopen(fd[1], "wb");
+               if (-1 == close(fd[0])) {
+                       msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       return NULL;
+               }
+               break;
+       }
+       return outFile;
+}
+
+static void usage(const char *progName)
+{
+       msglog(LOG_ERR, "Usage: %s -s nrOfSubEvts [...] [-r runNr]\n", progName);
+       msglog(LOG_ERR, "Usage: [-m nrOfMsgs]\n");
+       msglog(LOG_ERR, "Usage: [-f slowCtrlFile ...] [-o outPath] [-d null|tape|file]\n");
+       msglog(LOG_ERR, "Usage: [-a (agent)] [-p priority]\n");
+       msglog_usage();
+}
+
+/* BUGBUG bailOut not proper yet */
+int main(int argc, char *argv[])
+{
+       int i;
+       ShmTrans **shmTrans;
+       HadTuQueue **hadTuQueue;
+       Worker *worker;
+       int isStandalone;
+       int nrOfMsgs;
+       void *evt;
+       char *outPath;
+       char *outDev;
+       int priority;
+       FILE *outFile;
+       void *subEvt;
+       UInt4 nrOfSubEvts = 0;
+       UInt4 runNr;
+       char **slowCtrlFiles;
+       int slowCtrlFileCnt;
+       size_t queueSize;
+
+       int scanWasSuccessful;
+       int currNrOfSubEvts;
+       UInt4 currTrigNr;
+
+       unsigned long *evtsDiscarded;
+       unsigned long *evtsComplete;
+
+       msglog_setlevel(argv[0], "info");
+       isStandalone = 1;
+       nrOfMsgs = 0;
+       slowCtrlFiles = NULL;
+       slowCtrlFileCnt = 0;
+       outPath = "-";
+       outDev = "null";
+       priority = 0;
+       runNr = time(NULL);
+       queueSize = 100 * 1024;
+
+       while ((i = getopt(argc, argv, "am:f:r:s:o:d:p:v:")) != -1) {
+               switch (i) {
+               case 'a':
+                       isStandalone = 0;
+                       break;
+               case 'm':
+                       nrOfMsgs = atoi(optarg);
+                       break;
+               case 'f':
+                       slowCtrlFiles = realloc(slowCtrlFiles, sizeof(char *) * (slowCtrlFileCnt + 1));
+
+                       slowCtrlFiles[slowCtrlFileCnt++] = optarg;
+                       break;
+               case 'r':
+                       runNr = atoi(optarg);
+                       break;
+               case 's':
+                       nrOfSubEvts = atoi(optarg);
+                       break;
+               case 'o':
+                       outPath = optarg;
+                       break;
+               case 'd':
+                       outDev = optarg;
+                       break;
+               case 'p':
+                       priority = atoi(optarg);
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) != 1) {
+                               usage(argv[0]);
+                               exit(EXIT_FAILURE);
+                       }
+                       break;
+               default:
+                       usage(argv[0]);
+                       exit(EXIT_FAILURE);
+                       break;
+               }
+       }
+
+       if (nrOfSubEvts == 0) {
+               msglog(LOG_ERR, "missing nrOfSubEvts\n");
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+       if (nrOfMsgs == 0) {
+               msglog(LOG_NOTICE, "nrOfMsgs not set, assuming readout is local\n");
+       }
+       if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) {
+               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+       if (strcmp(outDev, "null") == 0) {
+               outFile = NULL;
+       } else if (strcmp(outDev, "file") == 0) {
+               if (strcmp(outPath, "-") == 0) {
+                       outFile = stdout;
+               } else {
+                       if (NULL == (outFile = fopen(outPath, "wb"))) {
+                               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                               exit(EXIT_FAILURE);
+                       }
+               }
+       } else if (strcmp(outDev, "tape") == 0) {
+               if (NULL == (outFile = openTape(outPath))) {
+                       msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+       } else {
+               msglog(LOG_ERR, "unknown outputDev \"%s\"\n", outDev);
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       if (-1 == initOnline()) {
+               msglog(LOG_ERR, "unable to initialize online service\n");
+               exit(EXIT_FAILURE);
+       }
+       if (nrOfMsgs == 0) {
+               /*
+       no '-m' option was on command line, we assume that the readout task
+       (daq_readout) is running on the same node and communicates directly
+       via shared memory */
+               shmTrans = allocMem(sizeof(ShmTrans *));
+               hadTuQueue = allocMem(sizeof(HadTuQueue *));
+
+               shmTrans[0] = ShmTrans_create("subevtqueue", 2 * queueSize);
+               hadTuQueue[0] = NULL;
+               nrOfMsgs = 1;
+       } else {
+               shmTrans = allocMem(nrOfMsgs * sizeof(ShmTrans *));
+               hadTuQueue = allocMem(nrOfMsgs * sizeof(HadTuQueue *));
+
+               for (i = 0; i < nrOfMsgs; i++) {
+                       char buf[_POSIX_PATH_MAX];
+
+                       sprintf(buf, "netqueue%d", i);
+                       shmTrans[i] = ShmTrans_create(buf, 2 * queueSize);
+                       hadTuQueue[i] = NULL;
+               }
+       }
+
+       evtsDiscarded = Worker_addStatistic(worker, "evtsDiscarded");
+       evtsComplete = Worker_addStatistic(worker, "evtsComplete");
+       Worker_initEnd(worker);
+
+       evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStart, runNr);
+       for (i = 0; i < slowCtrlFileCnt; i++) {
+               evt = appendFile(evt, slowCtrlFiles[i]);
+       }
+       if (outFile != NULL) {
+               Evt_write(getEvt(evt), outFile);
+       }
+       deleteEvt(evt);
+
+       currTrigNr = 0;
+       while (setjmp(terminateJmp) == 0) {
+               int tryNext;
+
+               Worker_dump(worker, 1);
+
+               i = 0;
+               tryNext = 0;
+               evt = newEvt(EvtDecoding_64bitAligned, EvtId_data, runNr);
+               currNrOfSubEvts = 0;
+               while (i < nrOfMsgs) {
+                       if (hadTuQueue[i] == NULL) {
+                               void *storage;
+
+                               storage = ShmTrans_recv(shmTrans[i]);
+                               hadTuQueue[i] = allocMem(HadTuQueue_sizeOf());
+                               conHadTuQueue_voidP(hadTuQueue[i], storage);
+                       }
+                       if (NULL != (subEvt = HadTuQueue_front(hadTuQueue[i]))) {
+#ifndef NDEBUG
+                               msglog(LOG_DEBUG, "hadTuQueue[%d]: %p = subEvt: %s\n", i, subEvt, SubEvt_2charP(subEvt));
+#endif
+                               if (i == 0 && currNrOfSubEvts == 0) {
+                                       currTrigNr = SubEvt_trigNr(subEvt);
+                               }
+                               if (SubEvt_id(subEvt) == SubEvtId_trigCode) {
+                                       /* BUGBUG, this is indeed no header word */
+                                       Evt_setId(evt, SubEvt_hdrValue(subEvt, 4));
+                               }
+                               if (SubEvt_trigNr(subEvt) == currTrigNr) {
+                                       evt = Evt_appendSubEvt(evt, subEvt);
+                                       HadTuQueue_pop(hadTuQueue[i]);
+                                       currNrOfSubEvts++;
+                               } else if (SubEvt_trigNr(subEvt) < currTrigNr) {
+                                       HadTuQueue_pop(hadTuQueue[i]);
+                                       /* BUGBUG subevt discarded, not in statistic */
+                               } else {
+                                       tryNext = 1;
+                               }
+                       }
+                       if (HadTuQueue_empty(hadTuQueue[i])) {
+                               desHadTuQueue(hadTuQueue[i]);
+                               freeMem(hadTuQueue[i]);
+                               hadTuQueue[i] = NULL;
+                               ShmTrans_free(shmTrans[i]);
+                       }
+                       if (tryNext) {
+                               i++;
+                               tryNext = 0;
+                       }
+               }
+               if (currNrOfSubEvts == nrOfSubEvts) {
+                       evt = getEvt(evt);      /* BUGBUG differnce newEvt <> getEvt not
+                                   necessary  any more */
+                       if (outFile != NULL) {
+                               Evt_write(evt, outFile);
+                       }
+                       Evt_online(evt);
+                       (*evtsComplete)++;
+               } else {
+                       (*evtsDiscarded)++;
+               }
+               deleteEvt(evt);
+       }
+       Worker_dump(worker, 0);
+
+       evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStart, runNr);
+       for (i = 0; i < slowCtrlFileCnt; i++) {
+               evt = appendFile(evt, slowCtrlFiles[i]);
+       }
+       if (outFile != NULL) {
+               Evt_write(getEvt(evt), outFile);
+       }
+       deleteEvt(evt);
+
+       free(slowCtrlFiles);
+
+       if (outFile != NULL) {
+               if (-1 == fclose(outFile)) {
+                       msglog(LOG_NOTICE, "%s, line %d:\n", __FILE__, __LINE__, strerror(errno));
+               }
+       }
+       for (i = 0; i < nrOfMsgs; i++) {
+               ShmTrans_remove(shmTrans[i]);
+       }
+       Worker_fini(worker);
+
+       exit(EXIT_SUCCESS);
+}
diff --git a/hadaq/grmblfx.h b/hadaq/grmblfx.h
new file mode 100644 (file)
index 0000000..ff0fb3d
--- /dev/null
@@ -0,0 +1,3 @@
+#if defined(__osf__) && defined(_POSIX_C_SOURCE)
+#define ushort unsigned short
+#endif
diff --git a/hadaq/hadaq.tcl b/hadaq/hadaq.tcl
new file mode 100644 (file)
index 0000000..19d6470
--- /dev/null
@@ -0,0 +1,527 @@
+#!/usr/local/bin/dpwish -f
+source cmds.tcl
+source ht98.tcl
+
+set runInfo(name) {}
+set runInfo(user) {}
+set runInfo(outputType) null
+set runInfo(output) {}
+set runInfo(comment) {}
+
+proc writeFile {name cont} {
+       set f [open $name w]
+       foreach line $cont {
+               puts $f $line
+       }
+       close $f
+}
+
+proc updateViewFile {top name} {
+       .$top.txt configure -state normal
+       .$top.txt delete 1.0 end
+       set f [open $name r]
+       while {[gets $f line] >= 0} {
+               .$top.txt insert end "$line\n"
+       }
+       close $f
+       .$top.txt see end
+       .$top.txt configure -state disabled
+}
+
+proc pollViewFile {top name} {
+       global mtime
+
+       if {[winfo exists .$top]} {
+               if {[file mtime $name] > $mtime($name)} {
+                       updateViewFile $top $name
+               }
+               set mtime($name) [file mtime $name]
+               after 1000 pollViewFile $top $name
+       }
+}
+
+proc viewFile {top title name} {
+       global mtime
+
+       toplevel .$top
+       wm title .$top "$title"
+       wm iconname .$top "$title"
+
+       text .$top.txt -state disabled -yscrollcommand ".$top.scroll set"
+       scrollbar .$top.scroll -command ".$top.txt yview"
+       pack .$top.txt -side left -fill both -expand 1
+       pack .$top.scroll -side right -fill y
+
+       set mtime($name) 0
+       pollViewFile $top $name
+}
+
+proc writeRunInfo {} {
+  global runInfo
+
+       lappend l [list set runInfo(name) $runInfo(name)]
+       lappend l [list set runInfo(user) $runInfo(user)]
+       lappend l [list set runInfo(output) $runInfo(output)]
+       lappend l [list set runInfo(comment) $runInfo(comment)]
+       writeFile runinfo.tcl $l
+}
+
+proc distrFile {name} {
+       set f [open $name r]
+       while {[gets $f line] >= 0} {
+               lappend l "$line"
+       }
+       foreach agent [agent cat] {
+#              dp_RPC [agent list $agent addr] writeFile $name $l
+       }
+}
+
+proc updateRunButtons {} {
+       if [isDown [group status run]] {
+               .mbar.file.menu entryconfigure 0 -state normal
+               .mbar.file.menu entryconfigure 1 -state disabled
+       } else {
+               .mbar.file.menu entryconfigure 0 -state disabled
+               .mbar.file.menu entryconfigure 1 -state normal
+       }
+}
+
+proc outputTypeCmd {} {
+       global runInfo
+
+       if {"$runInfo(outputType)" == "null"} {
+               .startRunDlg.top.output.ent configure -state normal
+               set runInfo(output) /dev/null
+               .startRunDlg.top.output.ent delete 0 end
+               .startRunDlg.top.output.ent insert 0 $runInfo(output)
+               .startRunDlg.top.output.ent configure -state disabled
+       } elseif {"$runInfo(outputType)" == "tape"} {
+               .startRunDlg.top.output.ent configure -state normal
+    set runInfo(output) /dev/nrmt0h
+               .startRunDlg.top.output.ent delete 0 end
+               .startRunDlg.top.output.ent insert 0 $runInfo(output)
+               .startRunDlg.top.output.ent configure -state disabled
+  } elseif {"$runInfo(outputType)" == "file"} {
+               .startRunDlg.top.output.ent configure -state normal
+    set runInfo(output) {}
+               .startRunDlg.top.output.ent delete 0 end
+               .startRunDlg.top.output.ent insert 0 $runInfo(output)
+  }
+}
+
+proc startRunDlg {} {
+       global runInfo
+       global dlgButton
+
+       toplevel .startRunDlg
+       wm title .startRunDlg "Start Run"
+       wm iconname .startRunDlg "Start Run"
+       frame .startRunDlg.top -relief raised -bd 1
+       pack .startRunDlg.top -side top -fill both
+       frame .startRunDlg.bottom -relief raised -bd 1
+       pack .startRunDlg.bottom -side bottom -fill both
+
+       frame .startRunDlg.top.name
+       pack .startRunDlg.top.name -side top
+       label .startRunDlg.top.name.lbl -text "Run Name:" -width 20 -anchor ne
+       entry .startRunDlg.top.name.ent -width 20
+       .startRunDlg.top.name.ent insert 0 $runInfo(name)
+       pack .startRunDlg.top.name.lbl .startRunDlg.top.name.ent -side left
+
+       frame .startRunDlg.top.user
+       pack .startRunDlg.top.user -side top
+       label .startRunDlg.top.user.lbl -text "Started by:" -width 20 -anchor ne
+       entry .startRunDlg.top.user.ent -width 20
+       .startRunDlg.top.user.ent insert 0 $runInfo(user)
+       pack .startRunDlg.top.user.lbl .startRunDlg.top.user.ent -side left
+
+       frame .startRunDlg.top.output
+       pack .startRunDlg.top.output -side top
+       frame .startRunDlg.top.output.frm
+       label .startRunDlg.top.output.frm.lbl -text "Output to:" -width 20 -anchor ne
+       frame .startRunDlg.top.output.frm.b
+       entry .startRunDlg.top.output.ent -width 20
+       outputTypeCmd
+       pack .startRunDlg.top.output.frm .startRunDlg.top.output.ent -side left
+       pack .startRunDlg.top.output.frm.lbl .startRunDlg.top.output.frm.b -side left
+       radiobutton .startRunDlg.top.output.frm.b.null -text Null -variable runInfo(outputType) -value null -command outputTypeCmd
+       radiobutton .startRunDlg.top.output.frm.b.tape -text Tape -variable runInfo(outputType) -value tape -command outputTypeCmd
+       radiobutton .startRunDlg.top.output.frm.b.file -text File -variable runInfo(outputType) -value file -command outputTypeCmd
+       pack .startRunDlg.top.output.frm.b.null .startRunDlg.top.output.frm.b.tape .startRunDlg.top.output.frm.b.file -side top
+
+       frame .startRunDlg.top.comment
+       pack .startRunDlg.top.comment -side top
+       label .startRunDlg.top.comment.lbl -text "Comment:" -width 20 -anchor ne
+       text .startRunDlg.top.comment.ent -width 20 -height 5
+       .startRunDlg.top.comment.ent insert 1.0 "$runInfo(comment)"
+       pack .startRunDlg.top.comment.lbl .startRunDlg.top.comment.ent -side left
+
+       set dlgButton "cancel"
+       button .startRunDlg.bottom.ok -text "OK" -command {set dlgButton "ok"}
+       pack .startRunDlg.bottom.ok -side left
+       button .startRunDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"}
+       pack .startRunDlg.bottom.cancel -side right
+
+       grab set .startRunDlg
+       tkwait variable dlgButton
+       if {"$dlgButton" == "ok"} {
+               set runInfo(name) [.startRunDlg.top.name.ent get]
+               set runInfo(user) [.startRunDlg.top.user.ent get]
+               set runInfo(output) [.startRunDlg.top.output.ent get]
+               set runInfo(comment) [.startRunDlg.top.comment.ent get 1.0 end]
+       }
+       destroy .startRunDlg
+       return $dlgButton
+}
+
+proc stopRunDlg {} {
+       global runInfo
+       global dlgButton
+
+       toplevel .stopRunDlg
+       wm title .stopRunDlg "Stop Run"
+       wm iconname .stopRunDlg "Stop Run"
+       frame .stopRunDlg.top -relief raised -bd 1
+       pack .stopRunDlg.top -side top -fill both
+       frame .stopRunDlg.bottom -relief raised -bd 1
+       pack .stopRunDlg.bottom -side bottom -fill both
+
+       frame .stopRunDlg.top.user
+       pack .stopRunDlg.top.user -side top
+       label .stopRunDlg.top.user.lbl -text "Stopped by:" -width 20 -anchor ne
+       entry .stopRunDlg.top.user.ent -width 20
+       .stopRunDlg.top.user.ent insert 0 $runInfo(user)
+       pack .stopRunDlg.top.user.lbl .stopRunDlg.top.user.ent -side left
+
+       frame .stopRunDlg.top.comment
+       pack .stopRunDlg.top.comment -side top
+       label .stopRunDlg.top.comment.lbl -text "Comment:" -width 20 -anchor ne
+       text .stopRunDlg.top.comment.ent -width 20 -height 5
+       .stopRunDlg.top.comment.ent insert 1.0 "$runInfo(comment)"
+       pack .stopRunDlg.top.comment.lbl .stopRunDlg.top.comment.ent -side left
+
+       set dlgButton "cancel"
+       button .stopRunDlg.bottom.ok -text "OK" -command {set dlgButton "ok"}
+       pack .stopRunDlg.bottom.ok -side left
+       button .stopRunDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"}
+       pack .stopRunDlg.bottom.cancel -side right
+
+       grab set .stopRunDlg
+       tkwait variable dlgButton
+       if {"$dlgButton" == "ok"} {
+               set runInfo(user) [.stopRunDlg.top.user.ent get]
+               set runInfo(comment) [.stopRunDlg.top.comment.ent get 1.0 end]
+       }
+       destroy .stopRunDlg
+       return $dlgButton
+}
+
+proc startRunCmd {} {
+       global runInfo
+       global tapeInfo
+
+  foreach worker [worker cat] {
+               if {[string first evtbuild $worker] != -1} {
+                       set evtbuildWorker $worker
+               }
+       }
+
+       if {[startRunDlg] == "ok"} {
+               writeRunInfo
+#              distrFile slowctrl.tcl
+               worker addopts $evtbuildWorker -o $runInfo(output) -d $runInfo(outputType)
+               if {$runInfo(outputType) == "tape"} {
+                       set tapeInfo(hdr1) [format "%-11s         ULTRIX00010001000100 98342 99366 000000DECULTRIX0000       " $runInfo(name)]
+                       set tapeInfo(hdr2) "F0819208192                     M             00                            "
+                       set f [open /tmp/ansitape.tmp w]
+                       puts -nonewline $f "$tapeInfo(vol)HDR1$tapeInfo(hdr1)HDR2$tapeInfo(hdr2)"
+                       close $f
+                       set tapeInfo(vol) {}
+                       exec sh -c "dd if=/tmp/ansitape.tmp bs=80 of=$runInfo(output) >/dev/null 2>&1"
+               }
+               group start run
+       }
+       updateRunButtons
+}
+
+proc stopRunCmd {} {
+       global runInfo
+       global tapeInfo
+
+       if {[stopRunDlg] == "ok"} {
+               group stop run
+               if {$runInfo(outputType) == "tape"} {
+                       set f [open /tmp/ansitape.tmp w]
+                       puts -nonewline $f "EOF1$tapeInfo(hdr1)EOF2tapeInfo(hdr2)"
+                       close $f
+                       set tapeInfo(vol) {}
+                       exec sh -c "dd if=/tmp/ansitape.tmp bs=80 of=$runInfo(output) >/dev/null 2>&1"
+               }
+       }
+       updateRunButtons
+}
+
+proc viewStat {top title statList} {
+       toplevel .$top
+       wm title .$top "$title"
+       wm iconname .$top "$title"
+
+       foreach worker $statList {
+               set name [lindex $worker 0]
+
+               frame .$top.$name
+               pack .$top.$name -side top
+               label .$top.$name.lbl -text $name
+               text .$top.$name.txt -width 35 -height 7
+               pack .$top.$name.lbl .$top.$name.txt -side top
+       }
+}
+
+proc updateStat {top countList} {
+       foreach worker $countList {
+               set name [lindex $worker 0]
+               set pairs [lindex $worker 1]
+
+               .$top.$name.txt configure -state normal
+               .$top.$name.txt delete 1.0 end
+               foreach pair $pairs {
+                       set p0 [lindex $pair 0]
+                       set p1 [lindex $pair 1]
+                       
+                       if {$p1 != "down"} {
+                               .$top.$name.txt insert end [format "%19s:%14d\n" $p0 $p1]
+                       }
+               }
+               .$top.$name.txt configure -state disabled
+       }
+}
+
+proc isDown {statList} {
+       foreach pair $statList {
+               set p0 [lindex $pair 0]
+               set p1 [lindex $pair 1]
+               
+               if {$p1 == "down"} {
+                       return 1
+               }
+       }
+       return 0
+}
+
+proc updateRunStat {} {
+       if {![isDown [group status run]]} {
+               updateStat viewRunStat [group status run -counter]
+       }
+}
+
+proc pollRunStat {} {
+       if {[catch updateRunStat] == 0} {
+               after 5000 pollRunStat
+       }
+}
+
+proc viewRunCmd {} {
+       viewStat viewRunStat "Run Status" [group status run]
+       pollRunStat
+}
+
+proc updateAcquisitionButtons {} {
+       if [isDown [group status acquisition]] {
+               .mbar.options.menu entryconfigure 0 -state normal
+               .mbar.options.menu entryconfigure 1 -state disabled
+       } else {
+               .mbar.options.menu entryconfigure 0 -state disabled
+               .mbar.options.menu entryconfigure 1 -state normal
+       }
+}
+
+proc startAcquisitionCmd {} {
+       group start acquisition
+       updateAcquisitionButtons
+}
+
+proc stopAcquisitionCmd {} {
+       group stop acquisition
+       updateAcquisitionButtons
+}
+
+proc updateAcquisitionStat {} {
+       if {![isDown [group status acquisition]]} {
+               updateStat viewAcquisitionStat [group status acquisition -counter]
+       }
+}
+
+proc pollAcquisitionStat {} {
+       if {[catch updateAcquisitionStat] == 0} {
+               after 5000 pollAcquisitionStat
+       }
+}
+
+proc viewAcquisitionCmd {} {
+       viewStat viewAcquisitionStat "Acquisition Status" [group status acquisition]
+       pollAcquisitionStat
+}
+
+proc viewErrorlogCmd {} {
+       viewFile viewErrorLog "Error Log" hadaq.log
+}
+
+proc viewEventCmd {} {
+
+  foreach worker [worker cat] {
+               if {[string first evtbuild $worker] != -1} {
+                       set evtbuildAgent [worker list $worker agent]
+               }
+       }
+       set f [open daq_anal.out w]
+       puts $f "Waiting for event"
+       close $f
+       after 1000
+       viewFile viewEvt "View Event" daq_anal.out
+       exec sh -c "daq_sniff -h [agent list $evtbuildAgent host] | daq_anal -n 1" </dev/null >daq_anal.out 2>/dev/null &
+}
+
+if {$tk_version < 4.0} {
+       set tearoff {}
+} else {
+       set tearoff {-tearoff 0}
+}
+
+proc loadTapeDlg {} {
+       global runInfo
+       global dlgButton
+
+       toplevel .loadTapeDlg
+       wm title .loadTapeDlg "Load Tape"
+       wm iconname .loadTapeDlg "Load Tape"
+       frame .loadTapeDlg.top -relief raised -bd 1
+       pack .loadTapeDlg.top -side top -fill both
+       frame .loadTapeDlg.bottom -relief raised -bd 1
+       pack .loadTapeDlg.bottom -side bottom -fill both
+
+       label .loadTapeDlg.top.lbl -text "Insert Tape"
+
+       checkbutton .loadTapeDlg.top.overWr -text "Initialize Tape" -variable overwriteTape
+       pack .loadTapeDlg.top.lbl .loadTapeDlg.top.overWr -side top
+
+       set dlgButton "cancel"
+       button .loadTapeDlg.bottom.ok -text "OK" -command {set dlgButton "ok"}
+       pack .loadTapeDlg.bottom.ok -side left
+       button .loadTapeDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"}
+       pack .loadTapeDlg.bottom.cancel -side right
+       grab set .loadTapeDlg
+       tkwait variable dlgButton
+       destroy .loadTapeDlg
+       return $dlgButton
+}
+
+proc loadTapeCmd {} {
+       global overwriteTape
+       global tapeInfo
+
+       set overwriteTape 0
+       if {[loadTapeDlg] == "ok"} {
+               set c [lindex [. config -cursor] 4]
+               . config -cursor clock
+               update
+               while 1 {
+                       if {[catch {exec mt online}] == 0} {
+                               break
+                       }
+                       after 1000
+               }
+               if {$overwriteTape} {
+                       set tapeInfo(vol) "VOL1ULTRIX                           HADES                                     3"
+                       exec mt rewind
+               } else {
+                       exec mt seod
+                       exec mt bsf 1
+               }
+               . config -cursor $c
+               update
+       }
+}
+
+proc ejectTapeCmd {} {
+       set c [lindex [. config -cursor] 4]
+       . config -cursor clock
+       update
+       exec mt offline
+       . config -cursor $c
+       update
+}
+
+wm title . hadaq
+frame .mbar -relief raised -bd 1
+
+menubutton .mbar.file -text File -menu .mbar.file.menu
+menubutton .mbar.view -text View -menu .mbar.view.menu
+menubutton .mbar.options -text Options -menu .mbar.options.menu
+menubutton .mbar.help -text Help -menu .mbar.help.menu
+pack .mbar.file .mbar.view .mbar.options -side left
+pack .mbar.help -side right
+
+eval menu .mbar.file.menu $tearoff
+.mbar.file.menu add command -label "Start Run" -command startRunCmd
+.mbar.file.menu add command -label "Stop Run" -command stopRunCmd
+.mbar.file.menu add separator
+.mbar.file.menu add command -label "Load Tape" -command loadTapeCmd
+.mbar.file.menu add command -label "Eject Tape" -command ejectTapeCmd
+.mbar.file.menu add separator
+.mbar.file.menu add command -label Exit -command {exit}
+
+eval menu .mbar.view.menu $tearoff
+.mbar.view.menu add command -label "Acquisition" -command viewAcquisitionCmd
+.mbar.view.menu add command -label "Run" -command viewRunCmd
+.mbar.view.menu add command -label "Tape" -command viewTapeCmd -state disabled
+.mbar.view.menu add separator
+.mbar.view.menu add command -label "Errorlog" -command viewErrorlogCmd
+.mbar.view.menu add separator
+.mbar.view.menu add command -label "Event" -command viewEventCmd
+
+eval menu .mbar.options.menu $tearoff
+.mbar.options.menu add command -label "Start Acquisition" -command startAcquisitionCmd
+.mbar.options.menu add command -label "Stop Acquisition" -command stopAcquisitionCmd
+
+eval menu .mbar.help.menu $tearoff
+.mbar.help.menu add command -label "About" -command aboutCmd -state disabled
+
+frame .map
+pack .mbar .map -side top -fill x
+
+proc updateMap {} {
+       set statusColor(up) darkGreen
+       set statusColor(down) red
+
+       foreach agent [agent cat] {
+               .map.$agent configure -background $statusColor([agent status $agent])
+       }
+       update
+}
+
+proc pollMap {} {
+       foreach agent [agent cat] {
+               chkAgent $agent
+       }
+       updateMap
+
+       after 5000 pollMap
+}
+
+proc mkMap {} {
+       foreach agent [agent cat] {
+               label .map.$agent -text $agent
+               pack .map.$agent -side left -expand 1 -fill x
+       }
+}
+
+mkMap
+
+foreach agent [agent cat] {
+       agent connect $agent
+}
+
+pollMap
+
+updateRunButtons
+updateAcquisitionButtons
diff --git a/hadaq/hadaq_init.tcl b/hadaq/hadaq_init.tcl
new file mode 100644 (file)
index 0000000..d89dd16
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/local/bin/tclsh -f
+source cmds.tcl
+source ht98.tcl
+
+foreach i [agent cat] {
+       set host [agent list $i host]
+       set user muench
+       set dir hadaq/hadaq-0.5
+
+       puts $host 
+       if {[string match "gast8" $host] || [string match "gast7" $host]} {
+               set psCmd {ps -ax | awk '{ print $1, $NF }'}
+       } else {
+               set psCmd {export UNIX95=XPG4; ps -e -o pid -o comm}
+       }
+
+       if {[lindex $argv 0] == "stop" || [lindex $argv 0] == "restart"} {
+               set f [open "|rsh $host -l $user \"$psCmd\"" r]
+               while {[gets $f line] >= 0} {
+                       set cmd [lindex $line 1]
+                       if {![string match {*_manage} $cmd] && [string match {daq_*} $cmd] || [string match {./daq_*} $cmd]} {
+                               puts $line
+                               set pid [lindex $line 0]
+                               catch {eval exec "rsh $host -l $user sh -c {'kill $pid'}"}
+                       }
+               }
+               close $f
+       }
+
+       if {[lindex $argv 0] == "start" || [lindex $argv 0] == "restart"} {
+               catch {exec mv hadaq.log hadaq.log.old}
+               eval exec "rsh $host -l $user sh -c {'cd $dir; ./daq_agent'}" </dev/null >>&hadaq.log &
+               exec cat hadaq.log
+       }
+}
diff --git a/hadaq/hadtu.c b/hadaq/hadtu.c
new file mode 100644 (file)
index 0000000..53112e3
--- /dev/null
@@ -0,0 +1,21 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/hadtu.c,v 6.1 1999-08-31 10:37:23 muench Stab $";
+
+#define _ANSI_C_SOURCE
+#include <stddef.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <hadesstd.h>
+
+#include "hadtu.h"
+
+char *HadTu_2charP(const void *my)
+{
+       static char buf[80];
+
+       sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x",
+                       HadTu_size(my), HadTu_decoding(my));
+
+       return buf;
+}
diff --git a/hadaq/hadtu.h b/hadaq/hadtu.h
new file mode 100644 (file)
index 0000000..e78f02f
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef HADTU_H
+#define HADTU_H
+
+#include <stddef.h>
+#include <hadesstd.h>
+
+enum HadTu_Decoding {
+  HadTu_queueDecoding = 3 << 16 | 99
+};
+
+static UInt4 *HadTu_hdr(const void *my);
+static size_t HadTu_hdrLen(void);
+static size_t HadTu_hdrSize(void);
+static int HadTu_isSwapped(const void *my);
+static UInt4 HadTu_hdrValue(const void *my, unsigned idx);
+static void HadTu_setHdrValue(const void *my, unsigned idx, UInt4 value);
+static UInt4 HadTu_decoding(const void *my);
+static void HadTu_setDecoding(void *my, UInt4 decoding);
+static unsigned HadTu_alignment(const void *my);
+static UInt4 HadTu_size(const void *my);
+static void HadTu_setSize(void *my, UInt4 size);
+static size_t HadTu_paddedSize(const void *my);
+static void *HadTu_begin(const void *my);
+static void *HadTu_end(const void *my);
+static size_t HadTu_dataSize(const void *my);
+static void *HadTu_data(const void *my);
+static void *HadTu_next(const void *my, const void *hadTu);
+char *HadTu_2charP(const void *my);
+
+enum HadTuIdx {
+  HadTuIdx_size,
+  HadTuIdx_decoding,
+  HadTuIdx_data
+};
+
+static UInt4 *HadTu_hdr(const void *my)
+{
+  return (UInt4 *) my;
+}
+
+static size_t HadTu_hdrLen(void)
+{
+  return HadTuIdx_data;
+}
+
+static size_t HadTu_hdrSize(void)
+{
+  return HadTu_hdrLen() * sizeof(UInt4);
+}
+
+static int HadTu_isSwapped(const void *my)
+{
+  UInt4 *hdr = HadTu_hdr(my);
+
+  return hdr[HadTuIdx_decoding] > 0xffffff;
+}
+
+static UInt4 HadTu_hdrValue(const void *my, unsigned idx)
+{
+  UInt4 *hdr = HadTu_hdr(my);
+
+  if (HadTu_isSwapped(my)) {
+    UInt4 tmp0;
+    UInt4 tmp1;
+
+    tmp0 = hdr[idx];
+    ((char *) &tmp1)[0] = ((char *) &tmp0)[3];
+    ((char *) &tmp1)[1] = ((char *) &tmp0)[2];
+    ((char *) &tmp1)[2] = ((char *) &tmp0)[1];
+    ((char *) &tmp1)[3] = ((char *) &tmp0)[0];
+    return tmp1;
+  } else {
+    return hdr[idx];
+  }
+}
+
+static void HadTu_setHdrValue(const void *my, unsigned idx, UInt4 value)
+{
+  UInt4 *hdr = HadTu_hdr(my);
+
+  hdr[idx] = value;
+}
+
+static UInt4 HadTu_decoding(const void *my)
+{
+  return HadTu_hdrValue(my, HadTuIdx_decoding);
+}
+
+static void HadTu_setDecoding(void *my, UInt4 decoding)
+{
+  HadTu_setHdrValue(my, HadTuIdx_decoding, decoding);
+}
+
+static unsigned HadTu_alignment(const void *my)
+{
+  return 1 << (HadTu_decoding(my) >> 16 & 0xff);
+}
+
+static UInt4 HadTu_size(const void *my)
+{
+  return HadTu_hdrValue(my, HadTuIdx_size);
+}
+
+static void HadTu_setSize(void *my, UInt4 size)
+{
+  HadTu_setHdrValue(my, HadTuIdx_size, size);
+}
+
+static size_t HadTu_paddedSize(const void *my)
+{
+  UInt4 size;
+  UInt4 alignment;
+
+  size = HadTu_size(my);
+  alignment = HadTu_alignment(my);
+  return (size & (alignment - 1))
+    ? (size & ~(alignment - 1)) + alignment : size;
+}
+
+static void *HadTu_begin(const void *my)
+{
+  return (void *) my;
+}
+
+static void *HadTu_end(const void *my)
+{
+  return (void *) ((char *) my + HadTu_paddedSize(my));
+}
+
+static size_t HadTu_dataSize(const void *my)
+{
+  return HadTu_size(my) - HadTu_hdrSize();
+}
+
+static void *HadTu_data(const void *my)
+{
+  return (void *) ((char *) my + HadTu_hdrSize());
+}
+
+static void *HadTu_next(const void *my, const void *hadTu)
+{
+  UInt4 size;
+  UInt4 alignment;
+  size_t paddedSize;
+
+  size = HadTu_size(hadTu);
+  alignment = HadTu_alignment(my);
+  paddedSize = (size & (alignment - 1))
+    ? (size & ~(alignment - 1)) + alignment : size;
+
+  return (void *) ((char *) hadTu + paddedSize);
+}
+
+#endif
diff --git a/hadaq/hadtuqueue.c b/hadaq/hadtuqueue.c
new file mode 100644 (file)
index 0000000..f986fa7
--- /dev/null
@@ -0,0 +1,138 @@
+static char rcsId[] = "$Id: hadtuqueue.c,v 6.1 1999-08-31 10:37:23 muench Stab $";
+
+#define _ANSI_C_SOURCE
+#include <stddef.h>
+
+#include <assert.h>
+
+#include "hadtu.h"
+
+struct HadTuQueueS {
+       void *hadTu;
+       void *run;
+       size_t maxSize;
+};
+
+#include "hadtuqueue.h"
+
+int HadTuQueue_invariant(const HadTuQueue *my)
+{
+       return (
+                          my->maxSize > HadTu_hdrSize()
+                          && my->run >= HadTu_data(my->hadTu)
+                          && my->run <= HadTu_end(my->hadTu)
+                          && HadTu_size(my->hadTu) == HadTu_paddedSize(my->hadTu)
+       );
+}
+
+void conHadTuQueue(HadTuQueue *my, void *mem, size_t maxSize)
+{
+       my->hadTu = mem;
+       HadTu_setSize(my->hadTu, HadTu_hdrSize());
+       HadTu_setDecoding(my->hadTu, HadTu_queueDecoding);
+
+       my->run = HadTu_data(my->hadTu);
+
+       /* truncate to aligned size */
+       my->maxSize = (maxSize / HadTu_alignment(my->hadTu)) * HadTu_alignment(my->hadTu);
+
+       assert(HadTuQueue_invariant(my));
+}
+
+void conHadTuQueue_voidP(HadTuQueue *my, void *mem)
+{
+       my->hadTu = mem;
+       my->run = HadTu_data(my->hadTu);
+       my->maxSize = HadTu_size(my->hadTu);
+
+       assert(HadTuQueue_invariant(my));
+}
+
+void desHadTuQueue(HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+}
+
+size_t HadTuQueue_sizeOf(void)
+{
+       return sizeof(HadTuQueue);
+}
+
+void HadTuQueue_cntl(HadTuQueue *my, int flag)
+{
+       assert(HadTuQueue_invariant(my));
+       assert(flag == HadTuQueueProt_read || flag == HadTuQueueProt_write);
+
+       switch (flag) {
+       case HadTuQueueProt_read:
+               my->run = HadTu_data(my->hadTu);
+               break;
+       case HadTuQueueProt_write:
+               my->run = HadTu_data(my->hadTu);
+               HadTu_setSize(my->hadTu, HadTu_hdrSize());
+               break;
+       }
+       assert(HadTuQueue_invariant(my));
+}
+
+void HadTuQueue_clear(HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+       my->run = HadTu_data(my->hadTu);
+       HadTu_setSize(my->hadTu, HadTu_hdrSize());
+       assert(HadTuQueue_invariant(my));
+}
+
+int HadTuQueue_empty(const HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+       return HadTu_size(my->hadTu) == (char *) my->run - (char *) my->hadTu;
+}
+
+void *HadTuQueue_alloc(const HadTuQueue *my, size_t size)
+{
+       void *retVal;
+
+       assert(HadTuQueue_invariant(my));
+       assert(size + HadTu_hdrSize() <= my->maxSize);
+       if (HadTu_size(my->hadTu) + size > my->maxSize) {
+               retVal = NULL;
+       } else {
+               retVal = my->run;
+       }
+       return retVal;
+}
+
+void HadTuQueue_push(HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+       my->run = HadTu_next(my->hadTu, my->run);
+       HadTu_setSize(my->hadTu, (char *) my->run - (char *) my->hadTu);
+       assert(HadTuQueue_invariant(my));
+}
+
+void *HadTuQueue_2voidP(const HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+       return HadTu_hdr(my->hadTu);
+}
+
+void *HadTuQueue_front(const HadTuQueue *my)
+{
+       void *retVal;
+
+       assert(HadTuQueue_invariant(my));
+       if (HadTuQueue_empty(my)) {
+               retVal = NULL;
+       } else {
+               retVal = my->run;
+       }
+       return retVal;
+}
+
+void HadTuQueue_pop(HadTuQueue *my)
+{
+       assert(HadTuQueue_invariant(my));
+       my->run = HadTu_next(my->hadTu, my->run);
+       assert(HadTuQueue_invariant(my));
+}
diff --git a/hadaq/hadtuqueue.h b/hadaq/hadtuqueue.h
new file mode 100644 (file)
index 0000000..0ab4282
--- /dev/null
@@ -0,0 +1,30 @@
+
+#ifndef HADTUQUEUE_H
+#define HADTUQUEUE_H
+
+#include <stddef.h>
+#include "hadtu.h"
+
+typedef struct HadTuQueueS HadTuQueue;
+
+typedef enum HadTuQueueProtE {
+  HadTuQueueProt_read,
+  HadTuQueueProt_write
+} HadTuQueueProt;
+
+void conHadTuQueue(HadTuQueue *my, void *mem, size_t size);
+void conHadTuQueue_voidP(HadTuQueue *my, void *mem);
+void desHadTuQueue(HadTuQueue *my);
+size_t HadTuQueue_sizeOf(void);
+void HadTuQueue_cntl(HadTuQueue *my, int flag);
+void HadTuQueue_clear(HadTuQueue *my);
+int HadTuQueue_invariant(const HadTuQueue *my);
+
+int HadTuQueue_empty(const HadTuQueue *my);
+void *HadTuQueue_alloc(const HadTuQueue *my, size_t size);
+void HadTuQueue_push(HadTuQueue *my);
+void *HadTuQueue_2voidP(const HadTuQueue *my);
+void *HadTuQueue_front(const HadTuQueue *my);
+void HadTuQueue_pop(HadTuQueue *my);
+
+#endif
diff --git a/hadaq/hardware.h b/hadaq/hardware.h
new file mode 100644 (file)
index 0000000..07eeb13
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+typedef struct HardwareS Hardware;
+
+Hardware *newHardware(void);
+void deleteHardware(Hardware * my);
+int Hardware_inSpill(const Hardware * my);
+size_t Hardware_maxSubEvtSize(const Hardware * my);
+void Hardware_waitForTrigger(const Hardware * my, void *subEvt);
+void Hardware_readout(const Hardware * my, void *subEvt);
+
+#endif
diff --git a/hadaq/hldread.c b/hadaq/hldread.c
new file mode 100644 (file)
index 0000000..a063faf
--- /dev/null
@@ -0,0 +1,151 @@
+static char rcsId[] = "$Id: hldread.c,v 6.1 1999-08-31 10:37:23 muench Stab $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <stddef.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <limits.h>
+
+#include <hadesstd.h>
+
+#include "evt.h"
+#include "hldread.h"
+
+static unsigned long processedEvts = 0;
+static unsigned int timeout = 0;
+
+static int excludeAnal = 0;
+
+static void showProcessedEvts(unsigned long processedEvts)
+{
+       static unsigned long keepProcessedEvts = 0;
+       int level;
+       char *notice;
+
+       if (processedEvts > keepProcessedEvts) {
+               level = LOG_INFO;
+               notice = "";
+       } else {
+               level = LOG_NOTICE;
+               notice = ", \ano new events arrived";
+       }
+       msglog(level, "%5u events processed %-30s\r", processedEvts, notice);
+}
+
+static void atexit0(void)
+{
+       if (!excludeAnal)
+               stopAnalysis();
+       msglog(LOG_INFO, "%5u events processed %-30s\n", processedEvts, "");
+}
+
+void sigHandler(int sig)
+{
+       exit(128 + sig);
+}
+
+void alarmHandler(int x)
+{
+       signal(SIGALRM, alarmHandler);
+       alarm(timeout);
+       showProcessedEvts(processedEvts);
+}
+
+void main(int argc, char *argv[])
+{
+       int i = 0;
+       FILE *file = NULL;
+       void *evt;
+       unsigned long readEvts = 0;
+       unsigned long fEvts = 0;
+       unsigned long nEvts = ULONG_MAX;
+       unsigned long echoRate = ULONG_MAX;
+       char **analArgv = malloc(sizeof(char *));
+       int analArgc = 1;                       /* Filename is in analArgv[0] */
+
+       msglog_setlevel(argv[0], "info");
+       while ((i = getopt(argc, argv, "n:f:e:t:xo:v:")) != -1) {
+               switch (i) {
+               case 'f':
+                       fEvts = atol(optarg);
+                       break;
+               case 'n':
+                       nEvts = atol(optarg);
+                       break;
+               case 'e':
+                       echoRate = atol(optarg);
+                       break;
+               case 't':
+                       timeout = atoi(optarg);
+                       break;
+               case 'x':
+                       excludeAnal = 1;
+                       break;
+               case 'o':
+                       analArgv = realloc(analArgv, sizeof(char *) * (analArgc + 1));
+
+                       analArgv[analArgc++] = optarg;
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) == 1) {
+                               break;
+                       }                                       /* FALLTHROUGH to default */
+               default:
+                       msglog(
+                                         LOG_ERR,
+                                       "Usage: %s -f firstEvent -n numEvents -e echoRate\n",
+                                         argv[0]
+                               );
+                       msglog_usage();
+                       msglog(
+                                         LOG_ERR,
+                                  "-t timeout -o analArgs -x (excludeAnal) [fileName]\n"
+                               );
+                       exit(EXIT_FAILURE);
+                       break;
+               }                                               /* switch (i ... */
+       }                                                       /* while ((i ... */
+       if (argv[optind] == NULL) {
+               file = stdin;
+               analArgv[0] = "-";
+       } else {
+               file = fopen(argv[optind], "r");
+               analArgv[0] = argv[optind];
+       }
+       if (file == NULL) {
+               msglog(LOG_ERR, "Opening input file: %s\n", strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+       if (!excludeAnal) {
+               startAnalysis(analArgc, analArgv);
+       }
+       atexit(atexit0);
+
+       signal(SIGINT, sigHandler);
+       signal(SIGTERM, sigHandler);
+
+       signal(SIGALRM, alarmHandler);
+       alarm(timeout);
+
+       while ((evt = Evt_fget(file)) != NULL && processedEvts < nEvts) {
+               readEvts++;
+               if (readEvts >= fEvts) {
+                       if (!excludeAnal)
+                               analyseEvt(evt);
+                       processedEvts++;
+                       if (processedEvts == 1) {
+                               msglog(LOG_INFO, "First event  processed %-30s\r", "");
+                       } else if (processedEvts % echoRate == 0) {
+                               alarm(timeout);
+                               showProcessedEvts(processedEvts);
+                       }
+               }
+       }
+       exit(EXIT_SUCCESS);
+}
diff --git a/hadaq/hldread.h b/hadaq/hldread.h
new file mode 100644 (file)
index 0000000..c3ca816
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef HLDREAD_H
+#define HLDREAD_H
+
+#include "evt.h"
+
+int startAnalysis(int argc, char **argv);
+int analyseEvt(void *evt);
+int stopAnalysis(void);
+
+#endif
diff --git a/hadaq/ht98.tcl b/hadaq/ht98.tcl
new file mode 100644 (file)
index 0000000..6ad7ebd
--- /dev/null
@@ -0,0 +1,14 @@
+agent create acheron
+agent create gast8
+worker create acheron:evtbuild -a -p -2 -s 3 -m 1 -f runinfo.tcl
+worker create acheron:netmem -a -p -1 -m 1
+worker create gast8:memnet -a -p -1 -o 0:50 -w 68000
+worker create gast8:readout -a -p -2
+worker create gast8:ctrlctu -a
+group create acquisition
+group create run
+group add acquisition gast8:memnet
+group add acquisition gast8:readout
+group add acquisition gast8:ctrlctu
+group add run acheron:evtbuild
+group add run acheron:netmem
diff --git a/hadaq/hwmdc.c b/hadaq/hwmdc.c
new file mode 100644 (file)
index 0000000..a07d8fd
--- /dev/null
@@ -0,0 +1,84 @@
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "param.h"
+#include "subevt.h"
+#include "hwsam.h"
+
+struct HardwareS {
+       size_t maxSubEvtSize;
+       void *specific;
+};
+
+#include "hardware.h"
+
+size_t Hardware_maxSubEvtSize(const Hardware *my)
+{
+       return my->maxSubEvtSize;
+}
+
+int Hardware_inSpill(const Hardware *my)
+{
+       return 0;
+}
+
+Hardware *newHardware(void)
+{
+       Hardware *my;
+       Param paramS, *param = &paramS;
+       HwSam *sam;
+       int i;
+
+       if (0 > conParam(param, "param.tcl")) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       my = allocMem(sizeof(Hardware));
+       my->specific = allocMem(sizeof(sam));
+
+       my->maxSubEvtSize = SubEvt_hdrSize();
+
+       sam = allocMem(sizeof(HwSam));
+       if (0 > conHwSam(sam, "sam", param)) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       (HwSam *) my->specific = sam;
+
+
+       desParam(param);
+       return my;
+}
+
+void deleteHardware(Hardware *my)
+{
+       HwSam *sam = (HwSam *) my->specific;
+
+       desHwSam(sam);
+       freeMem(sam);
+
+       freeMem(my);
+}
+
+void Hardware_waitForTrigger(const Hardware *my, void *subEvt)
+{
+       HwSam *sam = (HwSam *) my->specific;
+
+       while (HwSam_isBusy(sam) || HwSam_isEmpty(sam)) {
+#if 1
+               struct timespec tS, *t = &tS;
+               t->tv_sec = 0;
+               t->tv_nsec = 020000000;
+               nanosleep(t, NULL);
+#endif
+       }
+}
+
+void Hardware_readout(const Hardware *my, void *subEvt)
+{
+       HwSam *sam = (HwSam *) my->specific;
+
+       HwSam_readSubEvt(sam, subEvt);
+}
diff --git a/hadaq/hwrace.c b/hadaq/hwrace.c
new file mode 100644 (file)
index 0000000..d030242
--- /dev/null
@@ -0,0 +1,146 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwrace.c,v 6.1 1999-08-31 10:37:23 muench Exp $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <hadesstd.h>
+#include <lvme.h>
+
+
+#include "subevt.h"
+#include "param.h"
+#include "rc.h"
+#include "hwrace.h"
+
+#define RCPAGESIZE 256
+
+static int bankRequested(HwRace *my)
+{
+       return Rc_readPages(my->rc) >> 14 & 1;
+}
+
+static int bankConfirmed(HwRace *my)
+{
+       return Rc_readPages(my->rc) >> 15 & 1;
+}
+
+static int endOfData(HwRace *my)
+{
+       return (Rc_readPages(my->rc) & 0x1ff) * RCPAGESIZE;
+}
+
+static void standbyMode(HwRace *my)
+{
+       Rc_clrStop(my->rc);
+       Rc_clrReset(my->rc);
+       Rc_setReset(my->rc);
+}
+
+static void acquireMode(HwRace *my)
+{
+       Rc_ClrCtrs(my->rc);
+       Rc_writeStatusid(my->rc, 0x55);
+       Rc_setMemfull(my->rc, 0x1f4);
+       Rc_writeSedec_high(my->rc, 0x0002);
+       Rc_writeSedec_low(my->rc, 0x0001);
+       Rc_writeSeid_high(my->rc, 0x0000);
+       Rc_writeSeid_low(my->rc, 113);
+       Rc_setMsel(my->rc);
+       /* Rc_writeMskreg(my->rc, 0xff); */
+       Rc_clrMsel(my->rc);
+       Rc_setStop(my->rc);
+}
+
+int conHwRace(HwRace *my, const char *name, const Param *param)
+{
+       unsigned long cardBase;
+       int i;
+
+       assert(my != NULL);
+
+       strcpy(my->name, name);
+
+       cardBase = Param_getVal(param, my->name, "cardbase");
+       my->rc = allocMem(sizeof(Rc));
+
+       if (0 > conRc(my->rc, "rc", cardBase)) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return -1;
+       }
+       my->lbma = allocMem(sizeof(LBma));
+
+       if (0 > conLBma(my->lbma, cardBase + 0x100000, 512 * 1024, 0x09)) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return -1;
+       }
+       my->buf = LBma_getPtrL(my->lbma, 0);
+
+       standbyMode(my);
+       acquireMode(my);
+       return 0;
+}
+
+void desHwRace(HwRace *my)
+{
+       desLBma(my->lbma);
+       freeMem(my->lbma);
+
+       standbyMode(my);
+       desRc(my->rc);
+       freeMem(my->rc);
+}
+
+void HwRace_requestBuffer(HwRace *my)
+{
+       my->currAddr = 0;
+       Rc_setSwrq(my->rc);
+       Rc_clrSwrq(my->rc);
+}
+
+int HwRace_isBusy(HwRace *my)
+{
+       return bankRequested(my) != bankConfirmed(my);
+}
+
+int HwRace_isEmpty(HwRace *my)
+{
+       return my->currAddr >= endOfData(my);
+}
+
+int HwRace_readSubEvt(HwRace *my, void *subEvt)
+{
+       UInt4 *data = (UInt4 *) subEvt;
+       int firstAddr;
+       int size;
+
+       if (my->currAddr == 0) {
+               size = endOfData(my) - my->currAddr;
+               if (0 > LBma_read(my->lbma, 0, 0, size)) {
+                       msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               }
+       }
+       size = *(my->buf + my->currAddr / 4);
+
+       /* copy one sub evt from RC to memory */
+       memcpy(data, my->buf + my->currAddr / 4, size);
+       my->currAddr += size;
+       data += size / 4;
+
+       /* normal extension of trigger tag */
+       if (SubEvt_trigNr(subEvt) < (my->trigNr & 0xff)) {
+               my->trigNr += 0x100;
+       }
+       my->trigNr = (my->trigNr & 0xffffff00) | (SubEvt_trigNr(subEvt) & 0x000000ff);
+       SubEvt_setTrigNr(subEvt, my->trigNr);
+
+       /* align currAddr to next page */
+       if ((my->currAddr & 0xff) != 0) {
+               my->currAddr = (my->currAddr / RCPAGESIZE + 1) * RCPAGESIZE;
+       }
+       return 0;
+}
diff --git a/hadaq/hwrace.h b/hadaq/hwrace.h
new file mode 100644 (file)
index 0000000..ae7de41
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef HwRace_H
+#define HwRace_H
+
+#include <lvme.h>
+#include "rc.h"
+
+#include "param.h"
+
+typedef struct HwRaceS {
+  char name[16];
+  Rc *rc;
+  LBma *lbma;
+  LVme_L *buf;
+  int currAddr;
+  int trigNr;
+} HwRace;
+
+
+int conHwRace(HwRace *my, const char *name, const Param *param);
+void desHwRace(HwRace *my);
+
+void HwRace_requestBuffer(HwRace *my);
+int HwRace_isBusy(HwRace *my);
+int HwRace_isEmpty(HwRace *my);
+int HwRace_readSubEvt(HwRace *my, void *subEvt);
+
+#endif
diff --git a/hadaq/hwrich.c b/hadaq/hwrich.c
new file mode 100644 (file)
index 0000000..e62273a
--- /dev/null
@@ -0,0 +1,92 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwrich.c,v 6.1 1999-08-31 10:37:24 muench Exp $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h> 
+#include <sys/time.h>
+
+#include "param.h"
+#include "subevt.h"
+#include "hwrace.h"
+
+struct HardwareS {
+       size_t maxSubEvtSize;
+       void *specific;
+};
+
+#include "hardware.h"
+
+size_t Hardware_maxSubEvtSize(const Hardware *my)
+{
+       return my->maxSubEvtSize;
+}
+
+int Hardware_inSpill(const Hardware *my)
+{
+       return 0;
+}
+
+Hardware *newHardware(void)
+{
+       Hardware *my;
+       Param paramS, *param = &paramS;
+       HwRace *race;
+       int i;
+
+       if (0 > conParam(param, "param.tcl")) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       my = allocMem(sizeof(Hardware));
+       my->specific = allocMem(sizeof(race));
+
+       my->maxSubEvtSize = SubEvt_hdrSize() + (2564 * sizeof(UInt4));
+
+       race = allocMem(sizeof(HwRace));
+       if (0 > conHwRace(race, "race", param)) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       (HwRace *) my->specific = race;
+
+
+       desParam(param);
+       return my;
+}
+
+void deleteHardware(Hardware *my)
+{
+       HwRace *race = (HwRace *) my->specific;
+
+       desHwRace(race);
+       freeMem(race);
+
+       freeMem(my);
+}
+
+void Hardware_waitForTrigger(const Hardware *my, void *subEvt)
+{
+       HwRace *race = (HwRace *) my->specific;
+
+       if (HwRace_isEmpty(race)) {
+               HwRace_requestBuffer(race);
+               while (HwRace_isBusy(race)) {
+#if 1
+                       struct timespec tS, *t = &tS;
+                       t->tv_sec = 0;
+                       t->tv_nsec = 020000000;
+                       nanosleep(t, NULL);
+#endif
+               }
+       }
+}
+
+void Hardware_readout(const Hardware *my, void *subEvt)
+{
+       HwRace *race = (HwRace *) my->specific;
+
+       HwRace_readSubEvt(race, subEvt);
+}
diff --git a/hadaq/hwsam.c b/hadaq/hwsam.c
new file mode 100644 (file)
index 0000000..5d147c2
--- /dev/null
@@ -0,0 +1,111 @@
+
+#include <assert.h>
+#include <string.h>
+
+#include <hadesstd.h>
+#include <lvme.h>
+
+#include "param.h"
+
+#include "sam_defs.h"
+#include "hwsam.h"
+
+#define BUFSIZE 0x1000
+
+static int bankRequested(HwSam *my)
+{
+       return LVme_getBitL(my->lvme, CRR, 0);
+}
+
+static int bankConfirmed(HwSam *my)
+{
+       return LVme_getBitL(my->lvme, VMSR, 0);
+}
+
+static int endOfData(HwSam *my)
+{
+       int i;
+
+       i = BUFSIZE * bankRequested(my);
+       return i + LVme_getL(my->lvme, i);
+}
+
+static void standbyMode(HwSam *my)
+{
+       LVme_clrBitL(my->lvme, KSR, 0);
+       do {
+               LVme_setL(my->lvme, CRR, 0);
+       } while (LVme_getL(my->lvme, CRR) != 0);
+}
+
+static void acquireMode(HwSam *my)
+{
+       LVme_setBitL(my->lvme, KSR, 0);
+}
+
+int conHwSam(HwSam *my, const char *name, const Param *param)
+{
+       unsigned long cardBase;
+       int i;
+
+       assert(my != NULL);
+
+       strcpy(my->name, name);
+
+       cardBase = Param_getVal(param, my->name, "cardbase");
+       my->lvme = allocMem(sizeof(LVme));
+       if (0 > conLVme(my->lvme, 0x4c000000, 0x04000000L, 0x09, 0x01000004, 4)) {
+               msglog(LOG_ERR, "HwSam on %p not found\n", cardBase);
+               return -1;
+       }
+       standbyMode(my);
+       acquireMode(my);
+       return 0;
+}
+
+void desHwSam(HwSam *my)
+{
+       standbyMode(my);
+       desLVme(my->lvme);
+}
+
+void HwSam_requestBuffer(HwSam *my)
+{
+       int i;
+
+       i = bankRequested(my) == 1 ? 0 : 1;
+       do {
+               if (i == 1) {
+                       LVme_setBitL(my->lvme, CRR, 0);
+               } else {
+                       LVme_clrBitL(my->lvme, CRR, 0);
+               }
+       } while (LVme_getBitL(my->lvme, CRR) != i);
+
+       my->currAddr = BUFSIZE * bankRequested(my) + 8;
+}
+
+int HwSam_isBusy(HwSam *my)
+{
+       return bankRequested(my) != bankConfirmed(my);
+}
+
+int HwSam_isEmpty(HwSam *my)
+{
+       return my->currAddr >= endOfData(my);
+}
+
+void *HwSam_nextSubEvt(HwSam *my, void *subEvt)
+{
+       UInt4 *data = (UInt4 *) subEvt;
+       int firstAddr;
+       int size;
+
+       size = LVme_getL(my->lvme, my->currAddr);
+
+       /* copy one sub evt from RC to memory */
+       for (firstAddr = my->currAddr; my->currAddr - firstAddr < size; my->currAddr += 4) {
+               *data++ = LVme_getL(my->lvme, my->currAddr);
+       }
+       return 0;
+}
diff --git a/hadaq/hwsam.h b/hadaq/hwsam.h
new file mode 100644 (file)
index 0000000..ad7533a
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef HwSam_H
+#define HwSam_H
+
+#include <lvme.h>
+
+#include "param.h"
+
+typedef struct HwSamS {
+  char name[16];
+  LVme *lvme;
+  int bufSize;
+  int currAddr;
+} HwSam;
+
+
+int conHwSam(HwSam *my, const char *name, const Param *param);
+void desHwSam(HwSam *my);
+
+void HwSam_requestBuffer(HwSam *my);
+int HwSam_isBusy(HwSam *my);
+int HwSam_isEmpty(HwSam *my);
+void *HwSam_nextSubEvt(HwSam *my, void *subEvt);
+
+#endif
diff --git a/hadaq/hwship.c b/hadaq/hwship.c
new file mode 100644 (file)
index 0000000..664708f
--- /dev/null
@@ -0,0 +1,169 @@
+
+#include <assert.h>
+#include <string.h>
+
+#include <sys/time.h>
+#include <hadesstd.h>
+#include <lvme.h>
+
+#include "param.h"
+
+#include "ipc_basis.h"
+#include "hwship.h"
+
+#define SHIP_SUBEVTSIZE (4 * 2 * 386)
+
+static int bankRequested(HwShip *my)
+{
+       UInt2 val;
+
+       val = LVme_tstBitW(my->lvme, LVL2_STAT_READ, 6);
+       return val;
+}
+
+static int bankConfirmed(HwShip *my)
+{
+       UInt2 val;
+
+       val = LVme_tstBitW(my->lvme, LVL2_STAT_READ, 8);
+       return val;
+}
+
+static int endOfData(HwShip *my)
+{
+       return ((LVme_getL(my->lvme, LVL2_OFFSET) & 0x7f) + 1) * SHIP_SUBEVTSIZE + LVL2_OFFSET;
+}
+
+static void standbyMode(HwShip *my)
+{
+       LVme_setW(my->lvme, ID_CTR_ACCESS_ON, 0);
+       LVme_setW(my->lvme, ID_CTR_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_SW_TO_LUT12, 0);
+       LVme_setW(my->lvme, LUT_CTR_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_SW_TO_LUT34, 0);
+       LVme_setW(my->lvme, LUT_CTR_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, PEDAS_ACCESS_ON, 0);
+       LVme_setW(my->lvme, PEDAS_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, PEDAS_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, RC1_ACCESS_ON, 0);
+       LVme_setW(my->lvme, RC1_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, RC1_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, LVL2_ACCESS_ON, 0);
+       LVme_setW(my->lvme, LVL2_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, LVL2_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, RC3_ACCESS_ON, 0);
+       LVme_setW(my->lvme, RC3_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, RC3_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, ADDON_ACCESS_ON, 0);
+       LVme_setW(my->lvme, ADDON_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, ADDON_ACCESS_OFF, 0);
+}
+
+static void acquireMode(HwShip *my)
+{
+       LVme_setW(my->lvme, ID_CTR_ACCESS_ON, 0);
+       LVme_setW(my->lvme, ID_CTR_STANDBY_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_SW_TO_LUT12, 0);
+       LVme_setW(my->lvme, LUT_CTR_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_SW_TO_LUT34, 0);
+       LVme_setW(my->lvme, LUT_CTR_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, ID_CTR_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, RC1_ACCESS_ON, 0);
+       LVme_setW(my->lvme, RC1_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, RC1_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, PEDAS_ACCESS_ON, 0);
+       LVme_setW(my->lvme, PEDAS_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, PEDAS_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, LVL2_ACCESS_ON, 0);
+       LVme_setW(my->lvme, LVL2_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, LVL2_STAT_WRITE, 0);
+       LVme_setW(my->lvme, LVL2_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, RC3_ACCESS_ON, 0);
+       LVme_setW(my->lvme, RC3_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, RC3_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, ADDON_ACCESS_ON, 0);
+       LVme_setW(my->lvme, ADDON_SHOWER_MODE, 0);
+       LVme_setW(my->lvme, ADDON_ACCESS_OFF, 0);
+       LVme_setW(my->lvme, LVL2_ACCESS_ON, 0);
+}
+
+int conHwShip(HwShip *my, const char *name, const Param *param)
+{
+       unsigned long cardBase;
+       int i;
+
+       assert(my != NULL);
+
+       strcpy(my->name, name);
+
+       cardBase = Param_getVal(param, my->name, "cardbase");
+       my->lvme = allocMem(sizeof(LVme));
+       if (0 > conLVme(my->lvme, cardBase, 0x400000UL, 0x39UL, 0, 0)) {
+               msglog(LOG_ERR, "HwShip on %p not found\n", cardBase);
+               return -1;
+       }
+       standbyMode(my);
+       acquireMode(my);
+       return 0;
+}
+
+void desHwShip(HwShip *my)
+{
+       standbyMode(my);
+       desLVme(my->lvme);
+}
+
+void HwShip_requestBuffer(HwShip *my)
+{
+       int i;
+
+       msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ));
+       while ((LVme_getW(my->lvme, LVL2_STAT_READ) >> 9 & 0x7f) < 2) {
+       }
+       msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ));
+       i = bankRequested(my) == 1 ? 0 : 1;
+       msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, i);
+       LVme_setW(my->lvme, LVL2_STAT_WRITE, i << 1);
+
+       my->currAddr = 0x18 + LVL2_OFFSET;
+}
+
+int HwShip_isBusy(HwShip *my)
+{
+       msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ));
+       return bankRequested(my) != bankConfirmed(my);
+}
+
+int HwShip_isEmpty(HwShip *my)
+{
+       return my->currAddr >= endOfData(my);
+}
+
+int HwShip_readSubEvt(HwShip *my, void *subEvt)
+{
+       UInt4 *data = (UInt4 *) subEvt;
+       static UInt1 trigTag;
+       int firstAddr;
+       int size;
+
+       size = SHIP_SUBEVTSIZE;
+
+       if ((trigTag + 2) != (LVme_getL(my->lvme, my->currAddr) & 0xff)) {
+               msglog(LOG_ERR, "0x%08x != 0x%08x\n", trigTag + 2, LVme_getL(my->lvme, my->currAddr));
+       }
+       trigTag = LVme_getL(my->lvme, my->currAddr);
+
+       if (LVme_getL(my->lvme, my->currAddr) & 0xff != LVme_getL(my->lvme, my->currAddr + 4 * 388) & 0xff) {
+               msglog(LOG_ERR, "0x%08x != 0x%08x\n", LVme_getL(my->lvme, my->currAddr), LVme_getL(my->lvme, my->currAddr + 4 * 388));
+       }
+       *data++ = size + 16;
+       *data++ = 0x00020001;
+       *data++ = 456;
+       *data++ = LVme_getL(my->lvme, my->currAddr);
+       /* copy one sub evt from RC to memory */
+       for (firstAddr = my->currAddr; my->currAddr - firstAddr < size; my->currAddr += 4) {
+               *data++ = LVme_getL(my->lvme, my->currAddr);
+       }
+       return 0;
+}
diff --git a/hadaq/hwship.h b/hadaq/hwship.h
new file mode 100644 (file)
index 0000000..68a10b0
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef HwShip_H
+#define HwShip_H
+
+#include <lvme.h>
+
+#include "param.h"
+
+typedef struct HwShipS {
+  char name[16];
+  LVme *lvme;
+  int currAddr;
+} HwShip;
+
+
+int conHwShip(HwShip *my, const char *name, const Param *param);
+void desHwShip(HwShip *my);
+
+void HwShip_requestBuffer(HwShip *my);
+int HwShip_isBusy(HwShip *my);
+int HwShip_isEmpty(HwShip *my);
+int HwShip_readSubEvt(HwShip *my, void *subEvt);
+
+#endif
diff --git a/hadaq/hwshow.c b/hadaq/hwshow.c
new file mode 100644 (file)
index 0000000..6c9fc7c
--- /dev/null
@@ -0,0 +1,90 @@
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "param.h"
+#include "subevt.h"
+#include "hwship.h"
+
+struct HardwareS {
+       size_t maxSubEvtSize;
+       void *specific;
+};
+
+#include "hardware.h"
+
+size_t Hardware_maxSubEvtSize(const Hardware *my)
+{
+       return my->maxSubEvtSize;
+}
+
+int Hardware_inSpill(const Hardware *my)
+{
+       return 0;
+}
+
+Hardware *newHardware(void)
+{
+       Hardware *my;
+       Param paramS, *param = &paramS;
+       HwShip *ship;
+       int i;
+
+       if (0 > conParam(param, "param.tcl")) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       my = allocMem(sizeof(Hardware));
+       my->specific = allocMem(sizeof(ship));
+
+       my->maxSubEvtSize = SubEvt_hdrSize();
+
+       ship = allocMem(sizeof(HwShip));
+       if (0 > conHwShip(ship, "ship", param)) {
+               msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno));
+               return NULL;
+       }
+       (HwShip *) my->specific = ship;
+
+
+       desParam(param);
+       return my;
+}
+
+void deleteHardware(Hardware *my)
+{
+       HwShip *ship = (HwShip *) my->specific;
+
+       desHwShip(ship);
+       freeMem(ship);
+
+       freeMem(my);
+}
+
+void Hardware_waitForTrigger(const Hardware *my, void *subEvt)
+{
+       HwShip *ship = (HwShip *) my->specific;
+
+       if (HwShip_isEmpty(ship)) {
+               msglog(LOG_DEBUG, "switchRequest\n");
+               HwShip_requestBuffer(ship);
+               while (HwShip_isBusy(ship)) {
+#if 0
+                       struct timespec tS, *t = &tS;
+                       t->tv_sec = 0;
+                       t->tv_nsec = 020000000;
+                       nanosleep(t, NULL);
+#endif
+               }
+               msglog(LOG_DEBUG, "switchComplete\n");
+       }
+}
+
+void Hardware_readout(const Hardware *my, void *subEvt)
+{
+       HwShip *ship = (HwShip *) my->specific;
+
+       HwShip_readSubEvt(ship, subEvt);
+       msglog(LOG_DEBUG, "subEvt read\n");
+}
diff --git a/hadaq/hwsoft.c b/hadaq/hwsoft.c
new file mode 100644 (file)
index 0000000..59ffce7
--- /dev/null
@@ -0,0 +1,79 @@
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <sys/time.h>
+
+#include "subevt.h"
+#include "param.h"
+
+struct HardwareS {
+       size_t maxSubEvtSize;
+};
+
+#include "hardware.h"
+
+size_t Hardware_maxSubEvtSize(const Hardware *my)
+{
+       return my->maxSubEvtSize;
+}
+
+#include <hadesstd.h>
+
+int Hardware_inSpill(const Hardware *my)
+{
+       return 0;
+}
+
+Hardware *newHardware(void)
+{
+       Hardware *my;
+       Param *param;
+
+       my = allocMem(sizeof(Hardware));
+       my->maxSubEvtSize = SubEvt_hdrSize() + 401 * sizeof(UInt4);
+
+       param = allocMem(sizeof(Param));
+       conParam(param, "param.tcl");
+       printf("%d\n", Param_getVal(param, "soft", "size"));
+       desParam(param);
+       return my;
+}
+
+void deleteHardware(Hardware *my)
+{
+       freeMem(my);
+}
+
+void Hardware_waitForTrigger(const Hardware *my, void *subEvt)
+{
+       struct timespec tS, *t = &tS;
+       static UInt4 trigNr = 0;
+
+       SubEvt_setSize(subEvt, SubEvt_hdrSize());
+       SubEvt_setDecoding(subEvt, SubEvtDecoding_32bitData);
+       SubEvt_setId(subEvt, SubEvtId_test1);
+       SubEvt_setTrigNr(subEvt, trigNr++);
+
+       t->tv_sec = 0;
+       t->tv_nsec = 100000000;
+       nanosleep(t, NULL);
+}
+
+void Hardware_readout(const Hardware *my, void *subEvt)
+{
+       UInt4 *data = SubEvt_data(subEvt);
+       UInt4 *first = data;
+
+       *data++ = 0x55aa00FF;
+       *data++ = 0x55aa00FF;
+       *data++ = 0x55aa00FF;
+#if 0
+       data += (int) ((100.0 * rand()) / RAND_MAX);
+       data += (int) ((100.0 * rand()) / RAND_MAX);
+       data += (int) ((100.0 * rand()) / RAND_MAX);
+       data += (int) ((100.0 * rand()) / RAND_MAX);
+#endif
+
+       SubEvt_setSize(subEvt, SubEvt_size(subEvt) + sizeof(UInt4) * (data - first));
+}
diff --git a/hadaq/ipc_basis.h b/hadaq/ipc_basis.h
new file mode 100644 (file)
index 0000000..af9964a
--- /dev/null
@@ -0,0 +1,177 @@
+/*     ------------------------------------------------------------
+       - Header File for the Image Processing Card (Basis-Module) -
+       ------------------------------------------------------------
+       
+       Date: 20/01/1999                        Author: Markus Petri
+       
+       Remarks:
+       
+               ~
+               ~
+               ~
+*/
+#if !defined(IPC_BASIS)
+#define IPC_BASIS
+
+#define BASIS_ADRESSE                  0xffc00000
+#define BASIS_ADDR                     0x00000000
+#define IPC_BASIS_ADR                  0x00c00000
+#define LVL2_OFFSET                    0x60000
+#define LUT5_OFFSET                    0x40000
+
+#define RC3_ACCESS_OFF                 0x04022
+#define RC3_ACCESS_ON                  0x04020
+#define RC3_FIFO_RESET                 0x04008
+#define RC3_SHOWER_MODE                        0x04006
+#define RC3_TEST_MODE                  0x04004
+#define RC3_CONF_MODE                  0x04002
+#define RC3_STANDBY_MODE               0x04000
+
+#define ADDON_ACCESS_OFF               0x02012
+#define ADDON_ACCESS_ON                0x02010
+#define ADDON_FIFO_RESET                0x02108
+#define ADDON_SHOWER_MODE               0x02106
+#define ADDON_TEST_MODE                 0x02104
+#define ADDON_CONF_MODE                 0x02102
+#define ADDON_STANDBY_MODE              0x02100
+
+#define LVL2_ACCESS_OFF                        0x0101e
+#define LVL2_ACCESS_ON                 0x0101c
+#define LVL2_STAT_READ                  0x0100c
+#define LVL2_STAT_WRITE                        0x0100a
+#define LVL2_VME_RCLK                  0x01008
+#define LVL2_SHOWER_MODE               0x01006
+#define LVL2_TEST_MODE                 0x01004
+#define LVL2_CONF_MODE                 0x01002
+#define LVL2_STANDBY_MODE              0x01000
+
+#define PEDAS_ACCESS_OFF               0x00e02
+#define PEDAS_ACCESS_ON                        0x00e00
+#define PEDAS_FIFO_RESET                0x00c08
+#define PEDAS_SHOWER_MODE              0x00c06
+#define PEDAS_TEST_MODE                        0x00c04
+#define PEDAS_CONF_MODE                        0x00c02
+#define PEDAS_STANDBY_MODE             0x00c00
+
+#define RC1_ACCESS_OFF                 0x00a12
+#define RC1_ACCESS_ON                  0x00a10
+#define RC1_FIFO_RCLK                   0x00a0c
+#define RC1_VME_LVL2                    0x00a0a
+#define RC1_FIFO_RESET                 0x00a08
+#define RC1_SHOWER_MODE                        0x00a06
+#define RC1_TEST_MODE                  0x00a04
+#define RC1_CONF_MODE                  0x00a02
+#define RC1_STANDBY_MODE               0x00a00
+
+#define ALT3456_CONF_ON                0x0081c
+#define ALT3456_CONF_OFF               0x0081a
+#define ALT3456_CONF_REG               0x00818
+
+#define ALT12_CONF_ON                  0x00816
+#define ALT12_CONF_OFF                 0x00814
+#define ALT12_CONF_REG                 0x00812
+
+#define RESET_ADDON                    0x00806
+#define RESET_LVL1                      0x00804
+#define RESET_PEDAS                    0x00802
+#define RESET_LUTS                     0x00800
+
+#define ID_CTR_ACCESS_ON               0x00600
+#define ID_CTR_ACCESS_OFF              0x00200
+
+#define ID_CTR_SHOWER_MODE             0x000c0
+#define ID_CTR_TEST_MODE               0x000a0
+#define ID_CTR_CONF_MODE               0x00080
+#define ID_CTR_STANDBY_MODE            0x00060
+#define ID_CTR_SW_TO_LUT12             0x00040
+#define ID_CTR_SW_TO_LUT34             0x00020
+
+#define LUT_CTR_STANDBY_MODE           0x00000
+#define LUT_CTR_CONF_MODE              0x00002
+#define LUT_CTR_TEST_MODE              0x00004
+#define LUT_CTR_SHOWER_MODE            0x00006
+#define LUT_CTR_REG_ADDR_A             0x00008
+#define LUT_CTR_REG_ADDR_B             0x0000a
+#define LUT_CTR_REG_DATA               0x0000c
+#define LUT1_WE                                0x0000e /* bzw. LUT3_WE  */
+#define LUT2_WE                                0x00010 /* bzw. LUT4_WE  */
+#define LUT12_WE                       0x00012 /* bzw. LUT34_WE */
+#define LUT1234_READ                   0x00014
+
+/* -- Operational Modes of the Image Processing Card --
+
+These codes/flags are just used by the controlling C-software
+
+       - NORMAL_MODE   : all address lines are exclusively decoded by the
+                         VME-Controller.
+
+       - LUT_CONF_MODE : A9-A1 address lines are map to the ID-Controller
+                         and are used to control the ID-Controller and the
+                         Look up Table #1 through #4
+
+       - xxxxxxxxx     :
+*/
+
+#define STANDBY_MODE                   0x0
+#define CONF_MODE                       0x1
+#define TEST_MODE                       0x2
+#define SHOWER_MODE                     0x3
+#define LUT_CONF_MODE                  0x4
+#define LUT_TEST_MODE                  0x5
+#define LUT_STANDBY_MODE               0x6
+#define RESET                           0x7
+#define NO_MODE_CHG                    0x77
+
+#define TEST_VECTOR_SIZE               100000
+#define LUT5_SIZE                       524287
+#define LUT1234_SIZE                   131071
+#define LVL2_SIZE                      65536
+#define EVENT_SIZE                      388
+#define NUM_RB_FIFOS                    2
+#define NUM_COLS_RB_FIFO                8
+
+#define FILENAME_LENGTH                        30
+#define CONF_VECTOR_SIZE               750000
+#define COL_WIDTH                      3
+#define COLS_ALT3456                   91
+#define COLS_ALT12                     60
+
+#define ALTERA_3456                    1
+#define ALTERA_12                      0
+
+#define TDAT_RANDOM                    1
+#define TDAT_ZERO                      2
+
+#define INTACTIVE                      1
+#define BATCH                          0
+
+#define SRAM_A                          0
+#define SRAM_B                          1
+#define SRAM_OLD                        2
+
+#define POS                            1
+#define NEG                            0
+
+#define SRAM_ACCESS                    0
+#define BUFF_ACCESS                    1
+
+#define D_LAYS                         3
+#define D_ROWS                         32
+#define D_COLS                         16
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hadaq/memnet.c b/hadaq/memnet.c
new file mode 100644 (file)
index 0000000..912ea37
--- /dev/null
@@ -0,0 +1,125 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/memnet.c,v 6.1 1999-08-31 10:37:24 muench Exp $";
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+
+#include <stddef.h>
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include <hadesstd.h>
+
+#include "shmtrans.h"
+#include "nettrans.h"
+
+#include "worker.h"
+
+static jmp_buf terminateJmp;
+
+void sigHandler(int sig)
+{
+       longjmp(terminateJmp, sig);
+}
+
+static int min(int a, int b)
+{
+       return a < b ? a : b;
+}
+
+static void usage(const char *progName)
+{
+       msglog(LOG_ERR, "Usage: %s -o outPath -w bandwidth\n", progName);
+       msglog(LOG_ERR, "Usage: [-p priority]\n");
+       msglog_usage();
+}
+
+int main(int argc, char *argv[])
+{
+       int i;
+       int priority;
+       char *outPath;
+       int bandWidth;
+       int isStandalone;
+       Worker *worker;
+       NetTrans *netTrans;
+       ShmTrans *shmTrans;
+       size_t queueSize = 100 * 1024;
+       int exitStat;
+
+       msglog_setlevel(argv[0], "info");
+       outPath = "-";
+       bandWidth = -1;
+       priority = 0;
+       isStandalone = 1;
+       while ((i = getopt(argc, argv, "aw:o:p:v:")) != -1) {
+               switch (i) {
+               case 'a':
+                       isStandalone = 0;
+                       break;
+               case 'w':
+                       bandWidth = atoi(optarg);
+                       break;
+               case 'o':
+                       outPath = optarg;
+                       break;
+               case 'p':
+                       priority = atoi(optarg);
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) == 1) {
+                               break;
+                       }                                       /* FALLTHROUGH to default */
+               default:
+                       usage(argv[0]);
+                       exit(EXIT_FAILURE);
+                       break;
+               }
+       }
+       if (strcmp(outPath, "-") == 0 || bandWidth == -1) {
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+       if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) {
+               msglog(LOG_ERR, "initializing working process: %s\n"), strerror(errno);
+               exitStat = EXIT_FAILURE;
+               goto bailOut0;
+       }
+       if (NULL == (shmTrans = ShmTrans_create("subevtqueue", 2 * queueSize))) {
+               msglog(LOG_ERR,
+               "creating shared memory \"subevtqueue\": %s\n"), strerror(errno);
+               exitStat = EXIT_FAILURE;
+               goto bailOut1;
+       }
+       if (NULL == (netTrans = NetTrans_open(outPath, bandWidth, worker))) {
+               msglog(LOG_ERR,
+                "opening network transport %s: %s\n", outPath, strerror(errno));
+               exitStat = EXIT_FAILURE;
+               goto bailOut2;
+       }
+       Worker_initEnd(worker);
+
+       while (setjmp(terminateJmp) == 0) {
+               void *hadTuQueue;
+
+               Worker_dump(worker, 1);
+
+               hadTuQueue = ShmTrans_recv(shmTrans);
+               NetTrans_send(netTrans, hadTuQueue);
+               ShmTrans_free(shmTrans);
+       }
+       exitStat = EXIT_SUCCESS;
+
+  bailOut3:
+       NetTrans_close(netTrans);
+  bailOut2:
+       ShmTrans_remove(shmTrans);
+  bailOut1:
+       Worker_fini(worker);
+  bailOut0:
+       exit(exitStat);
+}
diff --git a/hadaq/mman.c b/hadaq/mman.c
new file mode 100644 (file)
index 0000000..eb4f9b8
--- /dev/null
@@ -0,0 +1,127 @@
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+
+#ifndef _POSIX_SHARED_MEMORY_OBJECTS
+static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/mman.c,v 6.1 1999-08-31 10:37:24 muench Stab $";
+
+#include <errno.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "mman.h"
+
+static int ourShmFlg;
+static size_t ourShmLen;
+static char ourShmPath[_POSIX_PATH_MAX];
+
+static char *name2Path(char *path, const char *name)
+{
+       char *prefix;
+
+       if (NULL == (prefix = getenv("OUR_MMAN_PREFIX"))) {
+               prefix = "";
+       }
+       if (strlen(prefix) + strlen(name) + 1 > _POSIX_PATH_MAX) {
+               errno = ENAMETOOLONG;
+               path = NULL;
+       } else {
+               strcpy(path, prefix);
+               strcat(path, name);
+       }
+       return path;
+}
+
+int MMAN_shm_open(const char *name, int oflags, mode_t mode)
+{
+       int fd;
+
+       if (NULL == name2Path(ourShmPath, name)) {
+               return -1;
+       }
+       if (0 > (fd = open(ourShmPath, oflags, mode))) {
+               return -1;
+       }
+       ourShmFlg = mode;                       /* BUGBUG This depends on ipc modes having
+                                   the same semantics as file modes */
+       if ((oflags & O_CREAT) != 0) {
+               ourShmFlg |= IPC_CREAT;
+       }
+       if ((oflags & O_EXCL) != 0) {
+               ourShmFlg |= IPC_EXCL;
+       }
+       return fd;
+}
+
+int MMAN_ftruncate(int fd, off_t size)
+{
+       key_t key;
+
+       if ((key_t) - 1 == (key = ftok(ourShmPath, 'A'))) {
+               return -1;
+       }
+       if (0 > shmget(key, size, ourShmFlg)) {
+               return -1;
+       }
+       return 0;
+}
+
+void *MMAN_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
+{
+       void *p;
+       int shmflg;
+       int shmid;
+       key_t key;
+
+       if ((key_t) - 1 == (key = ftok(ourShmPath, 'A'))) {
+               return MAP_FAILED;
+       }
+       if (0 > (shmid = shmget(key, len, 0))) {
+               return MAP_FAILED;
+       }
+       shmflg = 0;
+       if ((flags & MAP_SHARED) == 0) {
+               shmflg |= IPC_PRIVATE;
+       }
+       if ((prot & PROT_WRITE) == 0) {
+               shmflg |= SHM_RDONLY;
+       }
+       if ((void *) -1 == (p = shmat(shmid, addr, shmflg))) {
+               return MAP_FAILED;
+       }
+       return p;
+}
+
+int MMAN_munmap(void *addr, size_t len)
+{
+       ourShmLen = len;
+       return shmdt(addr);
+}
+
+int MMAN_shm_unlink(const char *name)
+{
+       int retVal;
+       int shmid;
+       key_t key;
+
+       retVal = 0;
+       if (NULL == name2Path(ourShmPath, name)
+               || (key_t) - 1 == (key = ftok(ourShmPath, 'A'))
+               || 0 > (shmid = shmget(key, ourShmLen, 0))
+               || 0 > shmctl(shmid, IPC_RMID, NULL)
+               ) {
+               retVal = -1;
+       }
+       if (0 > unlink(ourShmPath)) {
+               retVal = -1;
+       }
+       return retVal;
+}
+
+#endif
diff --git a/hadaq/mman.h b/hadaq/mman.h
new file mode 100644 (file)
index 0000000..1ad6ef8
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef OUR_MMAN_H
+#define OUR_MMAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* redefine function names to prevent name clashes */
+/* BUGBUG makes ftruncate,mmap,munmap unusable for anything else */
+/* BUGBUG shm_open must be called directly before ftruncate */
+/* for the same shm */
+/* BUGBUG shm_open must be called directly before ftruncate */
+/* ftruncate directly before mmap for the same shm */
+/* BUGBUG munmap must be called directly before shm_unlink */
+/* for the same shm */
+#define shm_open MMAN_shm_open
+#define ftruncate MMAN_ftruncate
+#define mmap MMAN_mmap
+#define munmap MMAN_munmap
+#define shm_unlink MMAN_shm_unlink
+
+#define MAP_FAILED ((void *)-1)
+#define PROT_READ 4             /* BUGBUG this three must correspond to the */
+#define PROT_WRITE 2            /* file access modes of the */
+#define PROT_EXEC 1             /* operating system */
+#define MAP_SHARED 4
+
+  int MMAN_shm_open(const char *name, int oflags, mode_t mode);
+  int MMAN_ftruncate(int fd, off_t size);
+  void *MMAN_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off);
+  int MMAN_munmap(void *addr, size_t len);
+  int MMAN_shm_unlink(const char *name);
+
+#ifdef __cplusplus
+}
+
+#endif
+#endif
diff --git a/hadaq/netmem.c b/hadaq/netmem.c
new file mode 100644 (file)
index 0000000..48b7b35
--- /dev/null
@@ -0,0 +1,130 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/netmem.c,v 6.1 1999-08-31 10:37:24 muench Exp $";
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <hadesstd.h>
+
+#include "worker.h"
+#include "nettrans.h"
+#include "shmtrans.h"
+
+static jmp_buf terminateJmp;
+
+void sigHandler(int sig)
+{
+       longjmp(terminateJmp, sig);
+}
+
+static void usage(const char *progName)
+{
+       msglog(LOG_ERR, "Usage: %s -m nrOfMsgs [-p priority]\n", progName);
+       msglog_usage();
+}
+
+int main(int argc, char *argv[])
+{
+       int i;
+       Worker *worker;
+       NetTrans **netTrans;
+       ShmTrans **shmTrans;
+       void **hadTu;
+       size_t *hadTuSize;
+       int priority;
+       int isStandalone;
+       int nrOfMsgs;
+       size_t queueSize;
+
+       msglog_setlevel(argv[0], "info");
+       priority = 0;
+       isStandalone = 1;
+       nrOfMsgs = 0;
+       queueSize = 100 * 1024;
+
+       while ((i = getopt(argc, argv, "am:p:v:")) != -1) {
+               switch (i) {
+               case 'a':
+                       isStandalone = 0;
+                       break;
+               case 'm':
+                       nrOfMsgs = atoi(optarg);
+                       break;
+               case 'p':
+                       priority = atoi(optarg);
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) == 1) {
+                               break;
+                       }                                       /* FALLTHROUGH to default */
+               default:
+                       usage(argv[0]);
+                       exit(EXIT_FAILURE);
+                       break;
+               }
+       }
+       if (nrOfMsgs == 0) {
+               msglog(LOG_ERR, "missing nrOfMsgs\n");
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+       netTrans = allocMem(nrOfMsgs * sizeof(NetTrans *));
+       shmTrans = allocMem(nrOfMsgs * sizeof(ShmTrans *));
+       hadTu = allocMem(nrOfMsgs * sizeof(void *));
+       hadTuSize = allocMem(nrOfMsgs * sizeof(size_t));
+
+       if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) {
+               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+       for (i = 0; i < nrOfMsgs; i++) {
+               char buf[80];
+
+               sprintf(buf, "0:%d", i + 50);
+               netTrans[i] = NetTrans_create(buf, 0, worker);
+
+               sprintf(buf, "netqueue%d", i);
+               shmTrans[i] = ShmTrans_open(buf, 2 * queueSize);
+
+               hadTu[i] = NULL;
+               hadTuSize[i] = queueSize - HadTu_hdrSize();
+       }
+       Worker_initEnd(worker);
+
+       if (setjmp(terminateJmp) == 0) {
+               while (1) {
+                       long msgsCompleted;
+
+                       Worker_dump(worker, 1);
+
+                       for (i = 0; i < nrOfMsgs; i++) {
+                               if (hadTu[i] == NULL) {
+                                       ShmTrans_requestSpace(shmTrans[i]);
+                                       hadTu[i] = ShmTrans_tryAlloc(shmTrans[i], hadTuSize[i]);
+                               }
+                       }
+
+                       msgsCompleted = NetTrans_multiRecv(netTrans, hadTu, hadTuSize, nrOfMsgs);
+
+                       for (i = 0; i < nrOfMsgs; i++) {
+                               if ((msgsCompleted & (1 << i)) != 0) {
+                                       ShmTrans_send(shmTrans[i]);
+                                       hadTu[i] = NULL;
+                               }
+                       }
+               }
+       }
+       Worker_dump(worker, 0);
+
+       for (i = 0; i < nrOfMsgs; i++) {
+               ShmTrans_remove(shmTrans[i]);
+               NetTrans_remove(netTrans[i]);
+       }
+       Worker_fini(worker);
+       exit(EXIT_SUCCESS);
+}
diff --git a/hadaq/nettrans.c b/hadaq/nettrans.c
new file mode 100644 (file)
index 0000000..0a0e1b0
--- /dev/null
@@ -0,0 +1,300 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/nettrans.c,v 6.1 1999-08-31 10:37:24 muench Exp $";
+
+#define _XOPEN_SOURCE_EXTENDED
+#include <unistd.h>
+#include "grmblfx.h"
+
+#include <assert.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <hadesstd.h>
+
+#include "latm.h"
+
+#include "hadtu.h"
+#include "pkt.h"
+
+#include "worker.h"
+#include "nettrans.h"
+
+static int min(int a, int b)
+{
+       return a < b ? a : b;
+}
+
+NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker *worker)
+{
+       NetTrans *my;
+       char *vpi;
+       char *vci;
+       LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS;
+       char buf[80];
+
+       my = allocMem(sizeof(NetTrans));
+
+       strcpy(buf, name);
+
+       if (NULL == (vpi = strtok(buf, ":"))) {
+               return NULL;
+       }
+       if (NULL == (vci = strtok(NULL, ":"))) {
+               return NULL;
+       }
+       lAtmAttr->aal = 5;
+       lAtmAttr->vpi = atoi(vpi);
+       lAtmAttr->vci = atoi(vci);
+       lAtmAttr->peakBandwidth = bandwidth;
+
+       msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n",
+       lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth);
+
+       if (0 > (my->fd = lAtmOpen("/dev/fa0", O_RDONLY))) {
+               return NULL;
+       }
+       if (0 > lAtmBind(my->fd, lAtmAttr)) {
+               lAtmClose(my->fd);
+               return NULL;
+       }
+       my->mtuSize = 8192;
+
+       my->pkt = allocMem(my->mtuSize);
+       my->seqNr = 0;
+       my->offset = 0;
+
+       my->pktsSent = NULL;
+       my->msgsSent = NULL;
+       my->bytesSent = NULL;
+       sprintf(buf, "%s_%s", name, "pktsReceived");
+       my->pktsReceived = Worker_addStatistic(worker, buf);
+       sprintf(buf, "%s_%s", name, "pktsDiscarded");
+       my->pktsDiscarded = Worker_addStatistic(worker, buf);
+       sprintf(buf, "%s_%s", name, "msgsDiscarded");
+       my->msgsDiscarded = Worker_addStatistic(worker, buf);
+       sprintf(buf, "%s_%s", name, "msgsReceived");
+       my->msgsReceived = Worker_addStatistic(worker, buf);
+
+       return my;
+}
+
+NetTrans *NetTrans_open(const char *name, size_t bandwidth, Worker *worker)
+{
+       NetTrans *my;
+       char *vpi;
+       char *vci;
+       LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS;
+       char buf[80];
+
+       my = allocMem(sizeof(NetTrans));
+
+       strcpy(buf, name);
+
+       if (NULL == (vpi = strtok(buf, ":"))) {
+               return NULL;
+       }
+       if (NULL == (vci = strtok(NULL, ":"))) {
+               return NULL;
+       }
+       lAtmAttr->aal = 5;
+       lAtmAttr->vpi = atoi(vpi);
+       lAtmAttr->vci = atoi(vci);
+       lAtmAttr->peakBandwidth = bandwidth;
+
+       msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n",
+       lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth);
+
+       if (0 > (my->fd = lAtmOpen("/dev/fa0", O_WRONLY))) {
+               return NULL;
+       }
+       if (0 > lAtmConnect(my->fd, lAtmAttr)) {
+               lAtmClose(my->fd);
+               return NULL;
+       }
+       my->mtuSize = 8192;
+
+       my->pkt = allocMem(my->mtuSize);
+       my->seqNr = 0;
+       my->offset = 0;
+
+       sprintf(buf, "%s_%s", name, "pktsSent");
+       my->pktsSent = Worker_addStatistic(worker, buf);
+       sprintf(buf, "%s_%s", name, "msgsSent");
+       my->msgsSent = Worker_addStatistic(worker, buf);
+       sprintf(buf, "%s_%s", name, "bytesSent");
+       my->bytesSent = Worker_addStatistic(worker, buf);
+       my->pktsReceived = NULL;
+       my->pktsDiscarded = NULL;
+       my->msgsDiscarded = NULL;
+       my->msgsReceived = NULL;
+
+       return my;
+}
+
+void NetTrans_close(NetTrans *my)
+{
+       freeMem(my->pkt);
+       lAtmClose(my->fd);
+       freeMem(my);
+}
+
+void NetTrans_remove(NetTrans *my)
+{
+       NetTrans_close(my);
+}
+
+int NetTrans_send(NetTrans *my, void *hadTu)
+{
+       int i;
+       int msgIsComplete;
+
+       Pkt_setDecoding(my->pkt, PktDecoding_default);
+       Pkt_setId(my->pkt, PktId_bom);
+
+       i = 0;
+       msgIsComplete = 0;
+       do {
+               size_t payload;
+
+               payload = min(my->mtuSize - Pkt_hdrSize(), HadTu_size(hadTu) - i);
+
+               memcpy(Pkt_data(my->pkt), (char *) hadTu + i, payload);
+               Pkt_setSize(my->pkt, payload + Pkt_hdrSize());
+
+               i += payload;
+               if (i == HadTu_size(hadTu)) {
+                       Pkt_setId(my->pkt, Pkt_id(my->pkt) | PktId_eom);
+                       msgIsComplete = 1;
+                       (*my->msgsSent)++;
+               }
+               Pkt_setSeqNr(my->pkt, my->seqNr++);
+
+               if (Pkt_size(my->pkt) != lAtmSend(my->fd, my->pkt, Pkt_size(my->pkt))) {
+                       return -1;
+               }
+               (*my->pktsSent)++;
+               (*my->bytesSent) += Pkt_size(my->pkt);
+               Pkt_setId(my->pkt, Pkt_id(my->pkt) & ~PktId_bom);
+       } while (!msgIsComplete);
+       return 0;
+}
+
+static int assembleMsg(NetTrans *my, void *hadTu, size_t size)
+{
+       int retVal;
+       int i;
+       int pktIsOk;
+       int n;
+       void *pkt;
+       UInt4 pktHdrSize;
+       UInt4 pktSize;
+       UInt4 pktId;
+       UInt4 pktSeqNr;
+
+       /* BUGBUG quickhack for flushing the input data.  Properly in one of */
+       /* the parent functions this should be handled, but this would need */
+       /* better sunc. between nettrans & shmtrans */
+       if (hadTu == NULL) {
+               if (0 > (n = lAtmRecv(my->fd, my->pkt, my->mtuSize))) {
+                       abort();
+               }
+               my->offset = 0;
+               (*my->pktsDiscarded)++;
+               return 0;
+       }
+       /* for in situ assembly of the pkts we receive the data "a little bit in
+     front of the beginning", save that data, and copy it back. CAUTION:
+     Pkt_hdrSize() bytes in front of hadTu must be accessible! */
+       pktHdrSize = Pkt_hdrSize();
+       pkt = (char *) hadTu + my->offset - pktHdrSize;
+       memcpy(my->pkt, pkt, pktHdrSize);
+
+       if (0 > (n = lAtmRecv(my->fd, pkt, my->mtuSize))) {
+               memcpy(pkt, my->pkt, pktHdrSize);
+               abort();
+       }
+       if (n != Pkt_size(pkt)) {
+               memcpy(pkt, my->pkt, pktHdrSize);
+               abort();
+       }
+       (*my->pktsReceived)++;
+       pktSize = n;
+       pktId = Pkt_id(pkt);
+       pktSeqNr = Pkt_seqNr(pkt);
+       memcpy(pkt, my->pkt, pktHdrSize);
+
+       if ((pktId & PktId_bom) != 0) { /* start of new msg */
+               if (my->offset != 0) {
+                       (*my->msgsDiscarded)++;
+                       (*my->pktsDiscarded)++;
+                       my->offset = 0;
+                       pktIsOk = 0;
+               } else {
+                       my->seqNr = pktSeqNr;
+                       pktIsOk = 1;
+               }
+       } else {
+               if (my->seqNr != pktSeqNr) {
+                       (*my->pktsDiscarded)++;
+                       my->offset = 0;
+                       pktIsOk = 0;
+               } else {
+                       pktIsOk = 1;
+               }
+       }
+       if (pktIsOk) {
+               my->seqNr++;
+
+               if ((pktId & PktId_eom) == 0) {
+                       my->offset += pktSize - pktHdrSize;;
+                       retVal = 0;
+               } else {
+                       (*my->msgsReceived)++;
+                       my->offset = 0;
+                       retVal = 1;
+               }
+       } else {
+               retVal = 0;
+       }
+       return retVal;
+}
+
+void NetTrans_recv(NetTrans *my, void *hadTu, size_t size)
+{
+       while (!assembleMsg(my, hadTu, size)) {
+       }
+}
+
+unsigned long NetTrans_multiRecv(NetTrans *my[], void *hadTu[], size_t size[], int nrOfMsgs)
+{
+       int i;
+       unsigned long msgIsComplete;
+       fd_set fdSetS, *fdSet = &fdSetS;
+
+       assert((1L << (nrOfMsgs - 1)) != 0);    /* is long long enough for result */
+
+       msgIsComplete = 0;
+
+       do {
+               FD_ZERO(fdSet);
+               for (i = 0; i < nrOfMsgs; i++) {
+                       FD_SET(my[i]->fd, fdSet);
+               }
+               if (0 > (getdtablesize(), fdSet, NULL, NULL, NULL)) {
+                       abort();
+               }
+               for (i = 0; i < nrOfMsgs; i++) {
+                       if (FD_ISSET(my[i]->fd, fdSet)) {
+                               if (assembleMsg(my[i], hadTu[i], size[i])) {
+                                       msgIsComplete |= 1 << i;
+                               }
+                       }
+               }
+       } while (0 && msgIsComplete == 0);
+
+       return msgIsComplete;
+}
diff --git a/hadaq/nettrans.h b/hadaq/nettrans.h
new file mode 100644 (file)
index 0000000..30eb0b6
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef NETTRANS_H
+#define NETTRANS_H
+
+#include <hadesstd.h>
+
+#include "worker.h"
+#include "hadtu.h"
+
+typedef struct NetTransS {
+  char name[512];
+  int fd;
+  size_t mtuSize;
+  UInt4 *pkt;
+  UInt4 seqNr;
+  size_t offset;
+  unsigned long *pktsSent;
+  unsigned long *msgsSent;
+  unsigned long *bytesSent;
+  unsigned long *pktsReceived;
+  unsigned long *pktsDiscarded;
+  unsigned long *msgsDiscarded;
+  unsigned long *msgsReceived;
+} NetTrans;
+
+NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker * worker);
+NetTrans *NetTrans_open(const char *name, size_t bandwidth, Worker * worker);
+void NetTrans_close(NetTrans *my);
+void NetTrans_remove(NetTrans *my);
+
+int NetTrans_send(NetTrans *my, void *hadTu);
+void NetTrans_recv(NetTrans *my, void *hadTu, size_t size);
+unsigned long NetTrans_multiRecv(NetTrans *my[], void *hadTu[], size_t size[], int nrOfMsgs);
+
+#endif
diff --git a/hadaq/online.c b/hadaq/online.c
new file mode 100644 (file)
index 0000000..9d31318
--- /dev/null
@@ -0,0 +1,73 @@
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+#include <hadesstd.h>
+
+#include "evt.h"
+#include "online.h"
+
+static void *ourEvt;
+
+extern void daqprog_1();
+
+static struct timeval timeout =
+{0, 0};
+
+initOnline()
+{
+       register SVCXPRT *transp;
+
+       (void) pmap_unset(DAQPROG, DAQVERS);
+
+       transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+       if (transp == NULL) {
+               fprintf(stderr, "cannot create tcp service.");
+               exit(1);
+       }
+       if (!svc_register(transp, DAQPROG, DAQVERS, daqprog_1, IPPROTO_TCP)) {
+               fprintf(stderr, "unable to register (DAQPROG, DAQVERS, tcp).");
+               exit(1);
+       }
+       return 0;
+}
+
+void Evt_online(void *evt)
+{
+       fd_set readfdset;
+       static int tsize = 0;
+
+       if (tsize == 0) {
+               tsize = getdtablesize();
+       }
+       readfdset = svc_fdset;
+
+       switch (select(tsize, &readfdset, (fd_set *) NULL, (fd_set *) NULL, &timeout)) {
+       case -1:
+               if (errno != EBADF) {
+                       perror("select");
+                       return;
+               }
+               break;
+       case 0:
+               break;
+       default:
+               ourEvt = evt;
+               svc_getreqset(&readfdset);
+               break;
+       }
+       return;
+}
+
+rpcevt *onlineevt_1(void *dummy, CLIENT * cl)
+{
+       static rpcevt result;
+
+       result.rpcevt_len = Evt_paddedSize(ourEvt);
+       result.rpcevt_val = (char *) ourEvt;
+
+       return &result;
+}
diff --git a/hadaq/online.x b/hadaq/online.x
new file mode 100644 (file)
index 0000000..b2ddc1c
--- /dev/null
@@ -0,0 +1,6 @@
+typedef opaque rpcevt<>;
+program DAQPROG {
+       version DAQVERS {
+               rpcevt ONLINEEVT(void) = 1;
+       } = 1;
+} = 0x20000001;
diff --git a/hadaq/param.c b/hadaq/param.c
new file mode 100644 (file)
index 0000000..fb5c27c
--- /dev/null
@@ -0,0 +1,64 @@
+static char rcsId[] = "$Id: param.c,v 6.1 1999-08-31 10:37:24 muench Exp $";
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <hadesstd.h>
+
+#include "param.h"
+
+int conParam(Param *my, const char *fileName)
+{
+       int i;
+       FILE *f;
+       char buf[132 + 1];
+
+       if (NULL == (f = fopen(fileName, "r"))) {
+               msglog(LOG_ERR, "opening param file: %s\n", strerror(errno));
+               return -1;
+       }
+       for (
+                       i = 0;
+                       i < PARAM_MAXNVALS
+                       && NULL != fgets(buf, 132, f);
+                       i++
+               ) {
+               if (buf[0] != '#') {
+                       sscanf(buf, "set%s%d", &my->name[i], &my->val[i]);
+               }
+       }
+       if (i == PARAM_MAXNVALS) {
+               msglog(LOG_WARNING,
+                          "More than %d Parameter in file, ignoring the rest\n", PARAM_MAXNVALS);
+       }
+       fclose(f);
+}
+
+void desParam(Param *my)
+{
+}
+
+long Param_getVal(const Param *my, const char *name, const char *idx)
+{
+       int i;
+       int val;
+       char fullName[PARAM_MAXNAMELEN];
+
+       sprintf(fullName, "%s(%s)", name, idx);
+       for (
+                       i = 0;
+                       i < PARAM_MAXNVALS
+                       && strcmp(my->name[i], fullName) != 0;
+                       i++
+               ) {
+       }
+       if (i == PARAM_MAXNVALS) {
+               val = 0;
+               msglog(LOG_WARNING, "Parameter %s not found, defaulting to 0\n", fullName);
+       } else {
+               val = my->val[i];
+       }
+       return val;
+}
diff --git a/hadaq/param.h b/hadaq/param.h
new file mode 100644 (file)
index 0000000..bf78cf6
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef PARAM_H
+#define PARAM_H
+
+#define PARAM_MAXNVALS 1024
+#define PARAM_MAXNAMELEN 32
+
+typedef struct ParamS {
+       int nVals;
+       char name[PARAM_MAXNVALS][PARAM_MAXNAMELEN];
+       long val[PARAM_MAXNVALS];
+} Param;
+
+int conParam(Param *my, const char *fileName);
+void desParam(Param *my);
+long Param_getVal(const Param *my, const char *name, const char *idx);
+
+#endif
diff --git a/hadaq/param.tcl b/hadaq/param.tcl
new file mode 100644 (file)
index 0000000..60fd674
--- /dev/null
@@ -0,0 +1,162 @@
+set soft(size) 1024
+
+set dtu0(cardbase) 1148190720 ;# 0x44700000
+set dtu0(deadtime) 10
+
+set tdc3(cardbase) 3992977408 ;# 0xee000000
+set tdc0(threshold00) 0
+set tdc0(threshold01) 0
+set tdc0(threshold02) 0
+set tdc0(threshold03) 0
+set tdc0(threshold04) 0
+set tdc0(threshold05) 0
+set tdc0(threshold06) 0
+set tdc0(threshold07) 0
+set tdc0(threshold08) 0
+set tdc0(threshold09) 0
+set tdc0(threshold10) 0
+set tdc0(threshold11) 0
+set tdc0(threshold12) 0
+set tdc0(threshold13) 0
+set tdc0(threshold14) 0
+set tdc0(threshold15) 0
+set tdc0(threshold16) 0
+set tdc0(threshold17) 0
+set tdc0(threshold18) 0
+set tdc0(threshold19) 0
+set tdc0(threshold20) 0
+set tdc0(threshold21) 0
+set tdc0(threshold22) 0
+set tdc0(threshold23) 0
+set tdc0(threshold24) 0
+set tdc0(threshold25) 0
+set tdc0(threshold26) 0
+set tdc0(threshold27) 0
+set tdc0(threshold28) 0
+set tdc0(threshold29) 0
+set tdc0(threshold30) 0
+set tdc0(threshold31) 0
+set tdc0(range) 255
+set tdc0(voltage) 254
+set tdc0(offset) 0
+
+set tdc0(cardbase) 3993108480 ;# 0xee000000
+set tdc1(threshold00) 0
+set tdc1(threshold01) 0
+set tdc1(threshold02) 0
+set tdc1(threshold03) 0
+set tdc1(threshold04) 0
+set tdc1(threshold05) 0
+set tdc1(threshold06) 0
+set tdc1(threshold07) 0
+set tdc1(threshold08) 0
+set tdc1(threshold09) 0
+set tdc1(threshold10) 0
+set tdc1(threshold11) 0
+set tdc1(threshold12) 0
+set tdc1(threshold13) 0
+set tdc1(threshold14) 0
+set tdc1(threshold15) 0
+set tdc1(threshold16) 0
+set tdc1(threshold17) 0
+set tdc1(threshold18) 0
+set tdc1(threshold19) 0
+set tdc1(threshold20) 0
+set tdc1(threshold21) 0
+set tdc1(threshold22) 0
+set tdc1(threshold23) 0
+set tdc1(threshold24) 0
+set tdc1(threshold25) 0
+set tdc1(threshold26) 0
+set tdc1(threshold27) 0
+set tdc1(threshold28) 0
+set tdc1(threshold29) 0
+set tdc1(threshold30) 0
+set tdc1(threshold31) 0
+set tdc1(range) 255
+set tdc1(voltage) 254
+set tdc1(offset) 0
+
+set tdc1(cardbase) 3993239552 ;# 0xee000000
+set tdc2(threshold00) 0
+set tdc2(threshold01) 0
+set tdc2(threshold02) 0
+set tdc2(threshold03) 0
+set tdc2(threshold04) 0
+set tdc2(threshold05) 0
+set tdc2(threshold06) 0
+set tdc2(threshold07) 0
+set tdc2(threshold08) 0
+set tdc2(threshold09) 0
+set tdc2(threshold10) 0
+set tdc2(threshold11) 0
+set tdc2(threshold12) 0
+set tdc2(threshold13) 0
+set tdc2(threshold14) 0
+set tdc2(threshold15) 0
+set tdc2(threshold16) 0
+set tdc2(threshold17) 0
+set tdc2(threshold18) 0
+set tdc2(threshold19) 0
+set tdc2(threshold20) 0
+set tdc2(threshold21) 0
+set tdc2(threshold22) 0
+set tdc2(threshold23) 0
+set tdc2(threshold24) 0
+set tdc2(threshold25) 0
+set tdc2(threshold26) 0
+set tdc2(threshold27) 0
+set tdc2(threshold28) 0
+set tdc2(threshold29) 0
+set tdc2(threshold30) 0
+set tdc2(threshold31) 0
+set tdc2(range) 255
+set tdc2(voltage) 254
+set tdc2(offset) 0
+
+set tdc2(cardbase) 3993370624 ;# 0xee000000
+set tdc3(threshold00) 0
+set tdc3(threshold01) 0
+set tdc3(threshold02) 0
+set tdc3(threshold03) 0
+set tdc3(threshold04) 0
+set tdc3(threshold05) 0
+set tdc3(threshold06) 0
+set tdc3(threshold07) 0
+set tdc3(threshold08) 0
+set tdc3(threshold09) 0
+set tdc3(threshold10) 0
+set tdc3(threshold11) 0
+set tdc3(threshold12) 0
+set tdc3(threshold13) 0
+set tdc3(threshold14) 0
+set tdc3(threshold15) 0
+set tdc3(threshold16) 0
+set tdc3(threshold17) 0
+set tdc3(threshold18) 0
+set tdc3(threshold19) 0
+set tdc3(threshold20) 0
+set tdc3(threshold21) 0
+set tdc3(threshold22) 0
+set tdc3(threshold23) 0
+set tdc3(threshold24) 0
+set tdc3(threshold25) 0
+set tdc3(threshold26) 0
+set tdc3(threshold27) 0
+set tdc3(threshold28) 0
+set tdc3(threshold29) 0
+set tdc3(threshold30) 0
+set tdc3(threshold31) 0
+set tdc3(range) 255
+set tdc3(voltage) 254
+set tdc3(offset) 0
+
+set tdc4(cardbase) 2097408 ;# 0x200100
+set tdc4(lowThreshold) 1
+set tdc4(highThreshold) 198
+set tdc4(range) 192 ;# 0 = 90ns, 224 = 770ns
+
+set adc0(cardbase) 0 ;# 0
+set adc0(lowThreshold) 8
+set adc0(highThreshold) 198
+set adc0(delay) 0
diff --git a/hadaq/pkt.c b/hadaq/pkt.c
new file mode 100644 (file)
index 0000000..d680a0f
--- /dev/null
@@ -0,0 +1,48 @@
+static char rcsId[] = "$Id: pkt.c,v 6.1 1999-08-31 10:37:24 muench Stab $";
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "pkt.h"
+
+char *Pkt_2charP(const void *my)
+{
+       static char buf[132];
+
+       sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x\tid: 0x%08x\tseqNr: 0x%08x",
+                       Pkt_size(my), Pkt_decoding(my), Pkt_id(my), Pkt_seqNr(my));
+
+       return buf;
+}
+
+void *newPkt(UInt4 decoding, UInt4 id, UInt4 seqNr)
+{
+       void *my;
+
+       my = allocMem(Pkt_hdrSize());
+
+       Pkt_setSize(my, Pkt_hdrSize());
+       Pkt_setDecoding(my, decoding);
+       Pkt_setId(my, id);
+       Pkt_setSeqNr(my, seqNr);
+
+       return my;
+}
+
+void deletePkt(void *my)
+{
+       freeMem(my);
+}
+
+void *Pkt_appendData(void *my, const void *data, size_t size)
+{
+
+       my = reallocMem(my, Pkt_paddedSize(my) + size);
+       memcpy(Pkt_end(my), data, size);
+       Pkt_setSize(my, Pkt_paddedSize(my) + size);
+
+       return my;
+}
diff --git a/hadaq/pkt.h b/hadaq/pkt.h
new file mode 100644 (file)
index 0000000..fe58506
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef PKT_H
+#define PKT_H
+
+#include <hadesstd.h>
+
+#include "hadtu.h"
+
+enum PktId {
+  PktId_bom = 1,
+  PktId_eom = 2
+};
+
+enum PktDecoding {
+  PktDecoding_default = 98
+};
+
+#define Pkt_hdr HadTu_hdr
+#define Pkt_isSwapped HadTu_isSwapped
+#define Pkt_hdrValue HadTu_hdrValue
+#define Pkt_setHdrValue HadTu_setHdrValue
+#define Pkt_decoding HadTu_decoding
+#define Pkt_setDecoding HadTu_setDecoding
+#define Pkt_alignment HadTu_alignment
+#define Pkt_size HadTu_size
+#define Pkt_setSize HadTu_setSize
+#define Pkt_paddedSize HadTu_paddedSize
+#define Pkt_begin HadTu_begin
+#define Pkt_end HadTu_end
+#define Pkt_next HadTu_next
+
+static size_t Pkt_hdrLen(void);
+static size_t Pkt_hdrSize(void);
+static size_t Pkt_dataSize(const void *my);
+static void *Pkt_data(const void *my);
+
+static UInt4 Pkt_id(const void *my);
+static void Pkt_setId(void *my, UInt4 id);
+static UInt4 Pkt_seqNr(const void *my);
+static void Pkt_setSeqNr(void *my, UInt4 seqNr);
+
+char *Pkt_2charP(const void *my);
+
+void *newPkt(UInt4 decoding, UInt4 id, UInt4 seqNr);
+void deletePkt(void *my);
+void *Pkt_appendData(void *my, const void *data, size_t size);
+
+static enum PktIdx {
+  PktIdx_size,
+  PktIdx_decoding,
+  PktIdx_id,
+  PktIdx_seqNr,
+  PktIdx_data
+};
+
+static size_t Pkt_hdrLen(void)
+{
+  return PktIdx_data;
+}
+
+static size_t Pkt_hdrSize(void)
+{
+  return Pkt_hdrLen() * sizeof(UInt4);
+}
+
+static size_t Pkt_dataSize(const void *my)
+{
+  return Pkt_size(my) - Pkt_hdrSize();
+}
+
+static void *Pkt_data(const void *my)
+{
+  return (void *) ((char *) my + Pkt_hdrSize());
+}
+
+static UInt4 Pkt_id(const void *my)
+{
+  return Pkt_hdrValue(my, PktIdx_id);
+}
+
+static void Pkt_setId(void *my, UInt4 id)
+{
+  Pkt_setHdrValue(my, PktIdx_id, id);
+}
+
+static UInt4 Pkt_seqNr(const void *my)
+{
+  return Pkt_hdrValue(my, PktIdx_seqNr);
+}
+
+static void Pkt_setSeqNr(void *my, UInt4 seqNr)
+{
+  Pkt_setHdrValue(my, PktIdx_seqNr, seqNr);
+}
+
+#endif
diff --git a/hadaq/psxshm.c b/hadaq/psxshm.c
new file mode 100644 (file)
index 0000000..7a26221
--- /dev/null
@@ -0,0 +1,74 @@
+static char rcsId[] = "$Id: psxshm.c,v 6.1 1999-08-31 10:37:24 muench Stab $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#ifdef _POSIX_SHARED_MEMORY_OBJECTS
+#include <sys/mman.h>
+#else
+#include "mman.h"
+#endif
+
+#include "psxshm.h"
+
+PsxShm *PsxShm_open(const char *name, int oflag, mode_t mode, off_t size)
+{
+       PsxShm *my;
+
+       if (NULL == (my = malloc(sizeof(PsxShm)))) {
+               goto cleanup0;
+       }
+       if (0 > (my->fd = shm_open(name, oflag, mode))) {
+               goto cleanup1;
+       }
+       my->size = size;
+       if ((oflag & O_CREAT) != 0) {
+               if (0 > ftruncate(my->fd, my->size)) {
+                       goto cleanup2;
+               }
+       }
+       if ((void *) MAP_FAILED == (my->addr = mmap(0, my->size, PROT_READ | PROT_WRITE, MAP_SHARED, my->fd, 0L))) {
+               goto cleanup2;
+       }
+       return my;
+
+/* cleanup allocated resources and report error */
+  cleanup2:
+       {
+               int e = errno;
+
+               close(my->fd);
+               if ((oflag & O_CREAT) != 0) {   /* let's assume we have created it */
+                       shm_unlink(name);
+               }
+               errno = e;
+       }
+  cleanup1:
+       free(my);
+  cleanup0:
+       return NULL;
+}
+
+int PsxShm_close(PsxShm *my)
+{
+       int ret;
+
+       if (
+                  0 > munmap(my->addr, my->size)
+                  || 0 > close(my->fd)
+               ) {
+               ret = -1;
+       } else {
+               ret = 0;
+       }
+       free(my);
+       return ret;
+}
+
+int PsxShm_unlink(const char *name)
+{
+       return shm_unlink(name);
+}
diff --git a/hadaq/psxshm.h b/hadaq/psxshm.h
new file mode 100644 (file)
index 0000000..c5877c7
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef PSXSHM_H
+#define PSXSHM_H
+
+#include <sys/types.h>
+
+typedef struct PsxShmS {
+  int fd;
+  void *addr;
+  off_t size;
+} PsxShm;
+
+PsxShm *PsxShm_open(const char *name, int oflag, mode_t mode, off_t size);
+int PsxShm_close(PsxShm * my);
+int PsxShm_unlink(const char *name);
+
+#endif
diff --git a/hadaq/rc.c b/hadaq/rc.c
new file mode 100644 (file)
index 0000000..ce50503
--- /dev/null
@@ -0,0 +1,37 @@
+
+#include <stdlib.h>
+#include <hadesstd.h>
+#include <lvme.h>
+
+#include "rc.h"
+
+int Rc_invariant(Rc *my)
+{
+       int retVal;
+       int i;
+
+       retVal = 1;
+       if (my->lvme == NULL) {
+               retVal = 0;
+       }
+       return retVal;
+}
+
+int conRc(Rc *my, const char *name, unsigned long vmeBase)
+{
+       if (NULL == (my->lvme = malloc(sizeof(LVme)))) {
+               perror("malloc");
+               exit(EXIT_FAILURE);
+       }
+       if (0 > conLVme(my->lvme, vmeBase, Rc_addrSpace, 0x09, 0, 0)) {
+               free(my->lvme);
+               return -1;
+       }
+       return 0;
+}
+
+void desRc(Rc *my)
+{
+       desLVme(my->lvme);
+       free(my->lvme);
+}
diff --git a/hadaq/rc.h b/hadaq/rc.h
new file mode 100644 (file)
index 0000000..03653c1
--- /dev/null
@@ -0,0 +1,644 @@
+#ifndef RC_H
+#define RC_H
+
+#include <stddef.h>
+#include <lvme.h>
+
+typedef struct RcS {
+       LVme *lvme;
+} Rc;
+
+/**********************************
+ * INTERFACE2 Xilinx part         *
+ * based on ver10rev1, 07.05.1999 *
+ **********************************/
+
+enum Rc_regions {
+                memRegion = 0x100000,
+                busRegion = 0x200000,
+                regRegion = 0x300000,
+                xcRegion  = 0x400000,
+                dprRegion = 0x500000
+};
+
+static const size_t Rc_addrSpace = 0x600000;
+
+/* Offsets for INTERFACE2 registers */
+static const ptrdiff_t ctrlReg   = regRegion + 0x000;
+static const ptrdiff_t ctrlPad   = regRegion + 0x002;
+static const ptrdiff_t trgReg    = regRegion + 0x004;
+static const ptrdiff_t trgPad    = regRegion + 0x006;
+static const ptrdiff_t trgCtr    = regRegion + 0x008;
+static const ptrdiff_t prdoutCtr = regRegion + 0x00a;
+static const ptrdiff_t ardoutCtr = regRegion + 0x00c;
+static const ptrdiff_t adelCtr   = regRegion + 0x00e;
+static const ptrdiff_t lcdReg    = regRegion + 0x010;
+static const ptrdiff_t lcdPad    = regRegion + 0x012;
+
+/* CTRL register definitions */
+static unsigned short Rc_getCtrlReg(Rc * my) { return LVme_getW(my->lvme, ctrlReg); }
+static unsigned short Rc_getCtrlPad(Rc * my) { return LVme_getW(my->lvme, ctrlPad); }
+
+static void Rc_setReset(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 6); }
+static void Rc_clrReset(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 6); }
+static int Rc_getReset(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 6); }
+static int Rc_padReset(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 6); }
+
+static void Rc_setMwr(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 7); }
+static void Rc_clrMwr(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 7); }
+static int Rc_getMwr(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 7); }
+static int Rc_padMwr(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 7); }
+
+static void Rc_setMsel(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 8); }
+static void Rc_clrMsel(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 8); }
+static int Rc_getMsel(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 8); }
+static int Rc_padMsel(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 8); }
+
+static void Rc_setEvtend(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 9); }
+static void Rc_clrEvtend(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 9); }
+static int Rc_getEvtend(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 9); }
+static int Rc_padEvtend(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 9); }
+
+static void Rc_setEvtbeg(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 10); }
+static void Rc_clrEvtbeg(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 10); }
+static int Rc_getEvtbeg(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 10); }
+static int Rc_padEvtbeg(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 10); }
+
+static void Rc_setSysclk(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 11); }
+static void Rc_clrSysclk(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 11); }
+static int Rc_getSysclk(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 11); }
+static int Rc_padSysclk(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 11); }
+
+static void Rc_Cycle(Rc * my)
+{
+       if(Rc_getSysclk(my))
+       {
+               Rc_clrSysclk(my);
+               Rc_setSysclk(my);
+       }
+       else
+       {
+               Rc_setSysclk(my);
+               Rc_clrSysclk(my);
+       }
+}
+       
+static void Rc_setSwrq(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 12); }
+static void Rc_clrSwrq(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 12); }
+static int Rc_getSwrq(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 12); }
+static int Rc_padSwrq(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 12); }
+
+static void Rc_setStop(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 13); }
+static void Rc_clrStop(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 13); }
+static int Rc_getStop(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 13); }
+static int Rc_padStop(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 13); }
+
+/* Magic numbers */
+static const int PRDOUT = 0x00;        /* Pattern readout (daisy chain)     */
+static const int PDEL   = 0x01;        /* Pattern delete (buslike)          */
+static const int ARDOUT = 0x02;        /* Analog readout (daisy chain)      */
+static const int ADEL   = 0x03;        /* Analog delete (buslike)           */
+static const int RFIFO  = 0x04;        /* Reset FIFO (buslike)              */
+static const int RDAISY = 0x05;        /* Reset daisy chain (buslike)       */
+static const int WCFG   = 0x06;        /* Write configuration (daisy chain) */
+static const int RCFG   = 0x07;        /* Read configuration (daisy chain)  */
+static const int NOP    = 0x0F;   /* No OPeration - do nothing         */
+
+static void Rc_setFc(Rc * my, int fc) 
+{
+       unsigned short savedCtrlReg;
+       savedCtrlReg = LVme_getW(my->lvme, ctrlReg);
+       savedCtrlReg = ( savedCtrlReg & 0xFFF0 ) | ( fc & 0x000F );
+       LVme_setW(my->lvme, ctrlReg, savedCtrlReg);
+}
+
+static int Rc_getFc(Rc * my)
+{
+       return LVme_getW(my->lvme, ctrlReg) & 0x000f;
+}
+
+static void Rc_setError(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 4); }
+static void Rc_clrError(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 4); }
+static int Rc_getError(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 4); }
+static int Rc_padError(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 4); }
+
+static void Rc_setRcbsy(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 5); }
+static void Rc_clrRcbsy(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 5); }
+static int Rc_getRcbsy(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 5); }
+static int Rc_padRcbsy(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 5); }
+
+/* TRG register definitions */
+static unsigned short Rc_getTrgReg(Rc * my) { return LVme_getW(my->lvme, trgReg); }
+static unsigned short Rc_getTrgPad(Rc * my) { return LVme_getW(my->lvme, trgPad); }
+
+static void Rc_setStrb0(Rc * my) { LVme_setBitW(my->lvme, trgReg, 0); }
+static void Rc_clrStrb0(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 0); }
+static int Rc_getStrb0(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 0); }
+static int Rc_padStrb0(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 0); }
+
+static void Rc_setStrb1(Rc * my) { LVme_setBitW(my->lvme, trgReg, 1); }
+static void Rc_clrStrb1(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 1); }
+static int Rc_getStrb1(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 1); }
+static int Rc_padStrb1(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 1); }
+
+static void Rc_setStrb2(Rc * my) { LVme_setBitW(my->lvme, trgReg, 2); }
+static void Rc_clrStrb2(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 2); }
+static int Rc_getStrb2(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 2); }
+static int Rc_padStrb2(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 2); }
+
+static void Rc_setStrb3(Rc * my) { LVme_setBitW(my->lvme, trgReg, 3); }
+static void Rc_clrStrb3(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 3); }
+static int Rc_getStrb3(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 3); }
+static int Rc_padStrb3(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 3); }
+
+static void Rc_setStrb4(Rc * my) { LVme_setBitW(my->lvme, trgReg, 4); }
+static void Rc_clrStrb4(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 4); }
+static int Rc_getStrb4(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 4); }
+static int Rc_padStrb4(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 4); }
+
+static void Rc_setStrb5(Rc * my) { LVme_setBitW(my->lvme, trgReg, 5); }
+static void Rc_clrStrb5(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 5); }
+static int Rc_getStrb5(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 5); }
+static int Rc_padStrb5(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 5); }
+
+static void Rc_setStrb6(Rc * my) { LVme_setBitW(my->lvme, trgReg, 6); }
+static void Rc_clrStrb6(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 6); }
+static int Rc_getStrb6(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 6); }
+static int Rc_padStrb6(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 6); }
+
+static void Rc_setStrb7(Rc * my) { LVme_setBitW(my->lvme, trgReg, 7); }
+static void Rc_clrStrb7(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 7); }
+static int Rc_getStrb7(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 7); }
+static int Rc_padStrb7(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 7); }
+
+/* Range for port: 0...7; other values are dangerous and no checking for the correct value is done ! */
+static void Rc_setStrbPort(Rc * my, int port) { LVme_setBitW(my->lvme, trgReg, port & 0x07); }
+static void Rc_clrStrbPort(Rc * my, int port) { LVme_clrBitW(my->lvme, trgReg, port & 0x07); }
+static int Rc_getStrbPort(Rc * my, int port) { return LVme_tstBitW(my->lvme, trgReg, port & 0x07); }
+static int Rc_padStrbPort(Rc * my, int port) { return LVme_tstBitW(my->lvme, trgPad, port & 0x07); }
+
+static void Rc_StrobePort(Rc * my, int port)
+{
+       Rc_clrStrbPort(my, port);
+       Rc_setStrbPort(my, port);
+}
+
+static void Rc_setDecision(Rc * my) { LVme_setBitW(my->lvme, trgReg, 8); }
+static void Rc_clrDecision(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 8); }
+static int Rc_getDecision(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 8); }
+static int Rc_padDecision(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 8); }
+
+static void Rc_setArdout(Rc * my) { LVme_setBitW(my->lvme, trgReg, 9); }
+static void Rc_clrArdout(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 9); }
+static int Rc_getArdout(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 9); }
+static int Rc_padArdout(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 9); }
+
+static void Rc_setPrdout(Rc * my) { LVme_setBitW(my->lvme, trgReg, 10); }
+static void Rc_clrPrdout(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 10); }
+static int Rc_getPrdout(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 10); }
+static int Rc_padPrdout(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 10); }
+
+static void Rc_setBegrun(Rc * my) { LVme_setBitW(my->lvme, trgReg, 11); }
+static void Rc_clrBegrun(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 11); }
+static int Rc_getBegrun(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 11); }
+static int Rc_padBegrun(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 11); }
+
+static void Rc_setTagclk(Rc * my) { LVme_setBitW(my->lvme, trgReg, 12); }
+static void Rc_clrTagclk(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 12); }
+static int Rc_getTagclk(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 12); }
+static int Rc_padTagclk(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 12); }
+
+static void Rc_setTagdata(Rc * my) { LVme_setBitW(my->lvme, trgReg, 13); }
+static void Rc_clrTagdata(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 13); }
+static int Rc_getTagdata(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 13); }
+static int Rc_padTagdata(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 13); }
+
+static void Rc_setTbsy(Rc * my) { LVme_setBitW(my->lvme, trgReg, 14); }
+static void Rc_clrTbsy(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 14); }
+static int Rc_getTbsy(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 14); }
+static int Rc_padTbsy(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 14); }
+
+static void Rc_setTrg(Rc * my) { LVme_setBitW(my->lvme, trgReg, 15); }
+static void Rc_clrTrg(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 15); }
+static int Rc_getTrg(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 15); }
+static int Rc_padTrg(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 15); }
+
+static void Rc_TriggerPort(Rc * my)
+{
+       Rc_clrTrg(my);
+       Rc_setTrg(my);
+}
+
+/* Status counter access */
+static unsigned short Rc_getTrgCtr(Rc * my)    { return LVme_getW(my->lvme, trgCtr); }
+static unsigned short Rc_getPrdoutCtr(Rc * my) { return LVme_getW(my->lvme, prdoutCtr); }
+static unsigned short Rc_getArdoutCtr(Rc * my) { return LVme_getW(my->lvme, ardoutCtr); }
+static unsigned short Rc_getAdelCtr(Rc * my)   { return LVme_getW(my->lvme, adelCtr); }
+
+static void Rc_setRctr(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 15); }
+static void Rc_clrRctr(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 15); }
+
+static void Rc_ClrCtrs(Rc * my)
+{
+       Rc_setRctr(my);
+       Rc_clrRctr(my);
+}
+
+/* LCD register definitions */
+
+/* Magic numbers */
+static const int CLR_DISPLAY = 0x01;   /* clears display, sets cursor home, unshifts */
+static const int CRSR_HOME   = 0x02;   /* sets cursor home, unshifts */
+static const int CRSR_LEFT   = 0x10;   /* move cursor one char left */
+static const int CRSR_RIGHT  = 0x14;   /* move cursor one char right */
+static const int DISP_LEFT   = 0x18;   /* shifts whole display one char left */
+static const int DISP_RIGHT  = 0x1c;   /* shifts whole display one char right */
+static const int CRSR_ON     = 0x0a;   /* display cursor */
+static const int BLINK_ON    = 0x09;   /* blinks cursor */
+static const int DISP_ON     = 0x0c;   /* set display on */
+static const int DISP_CTRL   = 0x08;   /* magic byte for CRSR_ON, BLINK_ON, DISP_ON */
+
+/* Do not use this function alone */
+static int Rc_readInstrLCD(Rc * my)
+{
+       LVme_setW(my->lvme, lcdReg, 0x01FF); 
+       LVme_setBitW(my->lvme, lcdReg, 10);
+       LVme_clrBitW(my->lvme, lcdReg, 10);
+       return LVme_getW(my->lvme, lcdPad);
+}
+static void Rc_waitBusyLCD(Rc * my)
+{
+       while((Rc_readInstrLCD(my) & 0x80) >> 7) 
+               {
+               /* Delay loop -> something useful to put in here ? */
+               }
+}
+static void Rc_writeDataLCD(Rc * my, int data)
+{
+       unsigned short realData = 0x0000;
+       realData = 0x0200 | data;
+       Rc_waitBusyLCD(my);
+       LVme_setW(my->lvme, lcdReg, realData);
+       LVme_setBitW(my->lvme, lcdReg, 10);
+       LVme_clrBitW(my->lvme, lcdReg, 10);
+}
+static void Rc_writeInstrLCD(Rc * my, int instr)
+{
+       unsigned short realInstr = 0x0000;
+       realInstr = 0x0000 | instr;
+       Rc_waitBusyLCD(my);
+       LVme_setW(my->lvme, lcdReg, realInstr);
+       LVme_setBitW(my->lvme, lcdReg, 10);
+       LVme_clrBitW(my->lvme, lcdReg, 10);
+}
+static void Rc_initLCD(Rc * my)
+{
+       /* Function Set: 8bit, 2lines, 5x7 font */
+       LVme_setW(my->lvme, lcdReg, 0x0038); 
+       LVme_setBitW(my->lvme, lcdReg, 10);
+       LVme_clrBitW(my->lvme, lcdReg, 10);
+       /* Wait more than 4.1ms */
+       usleep(5000);
+       /* Display ON/OFF control */
+       Rc_writeInstrLCD(my, 0x0e);
+       /* Entry mode set */
+       Rc_writeInstrLCD(my, 0x06);
+}
+
+/*********************************
+ * MEMORY2 Xilinx part           *
+ * based on ver16rev1 07.05.1999 *
+ *********************************/
+
+/* Offsets for MEMORY2 registers */
+static const ptrdiff_t statusid   = regRegion + 0x100;
+static const ptrdiff_t bugreg     = regRegion + 0x102;
+static const ptrdiff_t memreg     = regRegion + 0x104;
+static const ptrdiff_t pages      = regRegion + 0x106;
+static const ptrdiff_t sedec_high = regRegion + 0x108;
+static const ptrdiff_t sedec_low  = regRegion + 0x10a;
+static const ptrdiff_t seid_high  = regRegion + 0x10c;
+static const ptrdiff_t seid_low   = regRegion + 0x10e;
+
+/* STATUSID register */
+static unsigned int Rc_readStatusid(Rc * my) 
+{
+       int realId;
+       realId = 0x00FF & LVme_getW(my->lvme, statusid);
+       return realId;
+}
+static void Rc_writeStatusid(Rc * my, unsigned char value) 
+{
+       unsigned short savedStatusId;
+       savedStatusId = LVme_getW(my->lvme, statusid);     /* StatusID Register retten        */
+       savedStatusId = ( savedStatusId & 0xFF00 ) | ( value & 0x00FF ); /* Neue ID auf low byte einblenden */
+       LVme_setW(my->lvme, statusid, savedStatusId);      /* neues Register zurueckschreiben */
+}
+static unsigned short Rc_getStatusID(Rc * my) 
+{
+       return LVme_getW(my->lvme, statusid);
+}
+
+static void Rc_setIrqR(Rc * my) { LVme_setBitW(my->lvme, statusid, 15); }
+static void Rc_clrIrqR(Rc * my) { LVme_clrBitW(my->lvme, statusid, 15); }
+static int Rc_getIrqR(Rc * my) { return LVme_tstBitW(my->lvme, statusid, 15); }
+static void Rc_setIrqS(Rc * my) { LVme_setBitW(my->lvme, statusid, 14); }
+static void Rc_clrIrqS(Rc * my) { LVme_clrBitW(my->lvme, statusid, 14); }
+static int Rc_getIrqS(Rc * my) { return LVme_tstBitW(my->lvme, statusid, 14); }
+
+static void Rc_IrqRon(Rc * my)
+{
+       Rc_setIrqR(my);
+}
+static void Rc_IrqRoff(Rc * my)
+{
+       Rc_clrIrqR(my);
+}
+static void Rc_IrqSon(Rc * my)
+{
+       Rc_setIrqS(my);
+}
+static void Rc_IrqSoff(Rc * my)
+{
+       Rc_clrIrqS(my);
+}
+
+/* BUG register */
+static unsigned short Rc_getBug(Rc * my) 
+{
+       return LVme_getW(my->lvme, bugreg);
+}
+
+/* MEMREG register */
+/* Do not use this function alone */
+static unsigned short Rc_readMemreg(Rc * my) 
+{
+       return LVme_getW(my->lvme, memreg);
+}
+/* Do not use this function alone */
+static void Rc_writeMemreg(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, memreg, value);
+}
+static void Rc_setMemfull(Rc * my, unsigned short pages) 
+{
+       unsigned short realMemreg = 0x0000;
+       pages = pages & 0x07FF;             /* PAGES auf untere 11 bits begrenzen */
+       if(pages == 0x0000)
+               {
+                       pages++;              /* PAGES muss groesser 1 sein (RCBSY) */
+               }
+       realMemreg = Rc_readMemreg(my);     /* Altes Memreg retten                */ 
+       realMemreg = realMemreg & 0xF800 ;  /* Alte PAGES loeschen                */ 
+       realMemreg = realMemreg | pages ;   /* Neue PAGES einblenden              */
+       Rc_writeMemreg(my, realMemreg);     /* Memreg zurueckschreiben            */
+}
+
+/* PAGES register */
+/* Do not use this function alone */
+static unsigned short Rc_readPages(Rc * my) 
+{
+       return LVme_getW(my->lvme, pages);
+}
+static void Rc_waitSwitchcomplete(Rc * my) 
+{
+       unsigned short realPages = 0x0000;                    
+       realPages = Rc_readPages(my);                         /* Altes Register retten           */
+       realPages = realPages & 0xc000;                       /* oberste zwei Bits anschauen     */
+       while((realPages != 0x0000) || (realPages != 0xc000)) /* Schleife, bis beide Bits gleich */
+       {
+               realPages = (Rc_readPages(my) & 0xc000);       /* immer wieder reingucken         */
+       }
+}
+static int Rc_testMemfull(Rc * my) 
+{
+       unsigned short realPages = 0x0000;
+       realPages = Rc_readPages(my);
+       realPages = (realPages & 0x2000) >> 13;
+       return realPages;
+}
+
+/* SEDEC_HIGH register */
+static unsigned short Rc_readSedec_high(Rc * my) 
+{
+       return LVme_getW(my->lvme, sedec_high);
+}
+static void Rc_writeSedec_high(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, sedec_high, value);
+}
+
+/* SEDEC_LOW register */
+static unsigned short Rc_readSedec_low(Rc * my) 
+{
+       return LVme_getW(my->lvme, sedec_low);
+}
+static void Rc_writeSedec_low(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, sedec_low, value);
+}
+
+/* SEID_HIGH register */
+static unsigned short Rc_readSeid_high(Rc * my) 
+{
+       return LVme_getW(my->lvme, seid_high);
+}
+static void Rc_writeSeid_high(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, seid_high, value);
+}
+
+/* SEID_LOW register */
+static unsigned short Rc_readSeid_low(Rc * my) 
+{
+       return LVme_getW(my->lvme, seid_low);
+}
+static void Rc_writeSeid_low(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, seid_low, value);
+}
+
+/***********************
+ * TIMING2 Xilinx part *
+ * based on verXrevY   *
+ ***********************/
+
+/* Keep in mind: TIMING2 is a 2nd class Xilinx -> busRegion */
+
+/* Offsets for TIMING2 registers */
+static const ptrdiff_t evtgReg = busRegion + 0x100;
+static const ptrdiff_t errReg  = busRegion + 0x102;
+static const ptrdiff_t mskReg = busRegion + 0x104;
+
+/* EVTG-Register read/write (16bit wide) */
+static unsigned short Rc_readEvtgreg(Rc * my) 
+{
+       return LVme_getW(my->lvme, evtgReg);
+}
+static void Rc_writeEvtgreg(Rc * my, unsigned short value) 
+{
+       LVme_setW(my->lvme, evtgReg, value);
+}
+
+/* ERR-Register read; write resets register to zero (8bit wide) */
+static int Rc_readErrreg(Rc * my) 
+{
+       return LVme_getW(my->lvme, errReg);
+}
+static void Rc_writeErrreg(Rc * my, int value) 
+{
+       unsigned short realValue = 0x0000;
+       realValue = 0x0000 | value; 
+       LVme_setW(my->lvme, errReg, realValue);
+}
+
+/* MSK-Register read/write (8bit wide) */
+static int Rc_readMskreg(Rc * my) 
+{
+       return LVme_getW(my->lvme, mskReg);
+}
+static void Rc_writeMskreg(Rc * my, int value) 
+{
+       unsigned short realValue = 0x0000;
+       realValue = 0x0000 | value; 
+       LVme_setW(my->lvme, mskReg, realValue);
+}
+
+/****************
+ * Port XC part *
+ ****************/
+
+static const ptrdiff_t Pstatus    = busRegion + 0x002;
+static const ptrdiff_t Pcontrol   = busRegion + 0x008;
+static const ptrdiff_t portOffset = 0x020;
+
+static unsigned short Rc_getPstat(Rc * my, int port) 
+{ 
+       port = port & 0x07;
+       return LVme_getW(my->lvme, (port * portOffset + Pstatus)); 
+}
+static unsigned short Rc_getPctrl(Rc * my, int port) 
+{ 
+       port = port & 0x07;
+       return LVme_getW(my->lvme, (port * portOffset + Pcontrol)); 
+}
+
+
+/*************** 
+ * Memory part *
+ *             *
+ ***************/
+
+static unsigned long Rc_readMem(Rc * my, unsigned long offsetValue) 
+{
+       return LVme_getL(my->lvme, memRegion + offsetValue);
+}
+static void Rc_writeMem(Rc * my, unsigned long offsetValue, unsigned long value) 
+{
+       LVme_setL(my->lvme, memRegion + offsetValue, value);
+}
+
+static void Rc_clearMem(Rc * my) 
+{
+       long i;
+       const long RC_MEMSIZE    = 0x80000;
+       const long CLEARVALUE = 0x00000000;
+       for(i = 0; i < RC_MEMSIZE; i = i + 0x04)
+       {
+               Rc_writeMem(my, i, CLEARVALUE);
+       }
+}
+static long Rc_testMem(Rc * my) 
+{
+       long i;
+       const long RC_MEMSIZE    = 0x80000;
+       const long CLEARVALUE = 0x00000000;
+       unsigned long different = 0x00000000;
+       unsigned long memValue = 0x00000000;
+       for(i = 0; i < RC_MEMSIZE; i = i + 0x04)
+       {
+               memValue = Rc_readMem(my, i);
+               if(memValue != CLEARVALUE)
+               {
+                       different++;
+                       printf("A: 0x%08x: 0x%08x\n", i, memValue);
+               }
+       }
+       return different;
+}
+
+
+/***********************
+ * Dualported RAM part *
+ *                     *
+ ***********************/
+
+static unsigned short Rc_readDpr(Rc * my, unsigned long offsetValue) 
+{
+       unsigned long realValue = 0x00000000;
+       realValue = LVme_getL(my->lvme, dprRegion + offsetValue);
+       realValue = 0x0000FFFF & realValue;
+       return realValue;
+}
+static void Rc_writeDpr(Rc * my, unsigned long offsetValue, unsigned short value) 
+{
+       unsigned long realValue;
+       realValue = 0x0000FFFF & value;
+       LVme_setL(my->lvme, dprRegion + offsetValue, realValue);
+}
+static void Rc_clearDpr(Rc * my) 
+{
+       unsigned short i;
+       const unsigned short DPRSIZE    = 0x8000;
+       const unsigned short CLEARVALUE = 0x0000;
+       for(i = 0; i < DPRSIZE; i = i + 0x04)
+       {
+               if (i % 256 == 0)
+               {
+                       printf(".");
+               }
+               Rc_writeDpr(my, i, CLEARVALUE);
+       }
+       printf("\n");
+}
+static unsigned short Rc_testDpr(Rc * my) 
+{
+       unsigned short i;
+       const unsigned short DPRSIZE    = 0x8000;
+       const unsigned short CLEARVALUE = 0x0000;
+       unsigned short different = 0x0000;
+       unsigned short memValue = 0x0000;
+       for(i = 0; i < DPRSIZE; i = i + 0x04)
+       {
+               memValue = Rc_readDpr(my, i);
+               if(memValue != CLEARVALUE)
+               {
+                       different++;
+                       printf("    -> A: 0x%08x: 0x%04x\n", i, memValue);
+               }
+       }
+       return different;
+}
+
+/************************
+ * Internal DB bus part *
+ *                      *
+ ************************/
+
+static void Rc_writeDB(Rc * my, ptrdiff_t offset, unsigned short data)
+{
+       LVme_setW(my->lvme, busRegion + offset, data);
+}
+static unsigned short Rc_readDB(Rc * my, ptrdiff_t offset)
+{
+       return LVme_getW(my->lvme, busRegion + offset);
+}
+
+int Rc_invariant(Rc *my);
+int conRc(Rc *my, const char *name, unsigned long vmeBase);
+void desRc(Rc *my);
+
+
+
+/* This is a comment */
+#endif
diff --git a/hadaq/readout.c b/hadaq/readout.c
new file mode 100644 (file)
index 0000000..8893ad7
--- /dev/null
@@ -0,0 +1,137 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/readout.c,v 6.1 1999-08-31 10:37:25 muench Exp $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+#include "grmblfx.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <hadesstd.h>
+
+#include "hardware.h"
+#include "shmtrans.h"
+#include "hadtuqueue.h"
+#include "worker.h"
+
+static jmp_buf terminateJmp;
+
+void sigHandler(int sig)
+{
+       longjmp(terminateJmp, sig);
+}
+
+static void usage(const char *progName)
+{
+       msglog(LOG_ERR, "Usage: %s [-a (agentCtrl)] [-p priority]\n", progName);
+       msglog_usage();
+}
+
+void main(int argc, char *argv[])
+{
+       Hardware *hw;
+       void *subEvt;
+       Worker *worker;
+       ShmTrans *shmTrans;
+       int i;
+       int isStandalone;
+       char *outPath;
+       int priority;
+       size_t queueSize;
+       unsigned long *trigAccepted;
+       unsigned long *subevtsRead;
+
+       isStandalone = 1;
+       outPath = "subevtqueue";
+       priority = 0;
+       queueSize = 100 * 1024;
+       msglog_setlevel(argv[0], "info");
+
+       while ((i = getopt(argc, argv, "ap:v:")) != -1) {
+               switch (i) {
+               case 'a':
+                       isStandalone = 0;
+                       break;
+               case 'p':
+                       priority = atoi(optarg);
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) != 1) {
+                               usage(argv[0]);
+                               goto bailOut0;
+                       }
+                       break;
+               default:
+                       usage(argv[0]);
+                       goto bailOut0;
+                       break;
+               }
+       }
+
+       if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) {
+               msglog(LOG_ERR, "connecting to agent: %s\n", strerror(errno));
+               goto bailOut0;
+       }
+       if (NULL == (hw = newHardware())) {
+               msglog(LOG_ERR, "initializing hardware: %s\n", strerror(errno));
+               goto bailOut1;
+       }
+       if (NULL == (shmTrans = ShmTrans_open(outPath, 2 * queueSize))) {
+               msglog(LOG_ERR,
+                "opening shared memory \"%s\": %s\n", outPath, strerror(errno));
+               goto bailOut2;
+       }
+       trigAccepted = Worker_addStatistic(worker, "trigAccepted");
+       subevtsRead = Worker_addStatistic(worker, "subevtsRead");
+
+       Worker_initEnd(worker);
+
+       while (setjmp(terminateJmp) == 0) {
+               void *hadTu;
+               HadTuQueue *hadTuQueue;
+               Worker_dump(worker, 1);
+
+               hadTu = ShmTrans_alloc(shmTrans, queueSize - HadTu_hdrSize());
+#ifndef NDEBUG
+               msglog(LOG_DEBUG, "shmTrans: %p = hadTu: %s\n", hadTu, HadTu_2charP(hadTu));
+#endif
+               hadTuQueue = allocMem(HadTuQueue_sizeOf());
+#ifdef BIGMSG
+               conHadTuQueue(hadTuQueue, hadTu, queueSize - HadTu_hdrSize());
+#else
+               conHadTuQueue(hadTuQueue, hadTu, Hardware_maxSubEvtSize(hw) + HadTu_hdrSize() + 8);
+#endif
+               while (NULL != (subEvt = HadTuQueue_alloc(hadTuQueue, Hardware_maxSubEvtSize(hw)))) {
+                       Hardware_waitForTrigger(hw, subEvt);
+                       (*trigAccepted)++;
+
+                       Hardware_readout(hw, subEvt);
+                       (*subevtsRead)++;
+#ifndef NDEBUG
+                       msglog(LOG_DEBUG, "hadTuQueue: %p = subEvt: %s\n", subEvt, SubEvt_2charP(subEvt));
+#endif
+
+                       HadTuQueue_push(hadTuQueue);
+               }
+               desHadTuQueue(hadTuQueue);
+               freeMem(hadTuQueue);
+               ShmTrans_send(shmTrans);
+       }
+
+       Worker_fini(worker);
+       ShmTrans_close(shmTrans);
+       deleteHardware(hw);
+
+       exit(EXIT_SUCCESS);
+
+       ShmTrans_close(shmTrans);
+  bailOut2:
+       deleteHardware(hw);
+  bailOut1:
+       Worker_fini(worker);
+  bailOut0:
+       exit(EXIT_FAILURE);
+}
diff --git a/hadaq/sam_defs.h b/hadaq/sam_defs.h
new file mode 100644 (file)
index 0000000..116fd66
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef SAM_DEFS_H
+#define SAM_DEFS_H
+
+#define VMSR  0x01000008
+#define KSR   0x01000004
+#define CRAM  0x00000000
+#define CRR   0x00001ffc
+
+#endif
diff --git a/hadaq/sched.h b/hadaq/sched.h
new file mode 100644 (file)
index 0000000..5ef196a
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef OURSCHED_H
+#define OURSCHED_H
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+#include <sched.h>
+#else
+#ifdef __Lynx__
+#include <conf.h>
+#include <sys/types.h>
+#include <sys/sched.h>
+
+struct sched_param {
+  int sched_priority;
+};
+
+static int sched_getscheduler(pid_t pid)
+{
+  return getscheduler(pid);
+}
+
+static int sched_setscheduler(pid_t pid, int policy, const struct sched_param *p)
+{
+  return setscheduler(pid, policy, p->sched_priority);
+}
+
+int sched_get_priority_max(int alg)
+{
+  return PRIO_FIFO_MAX;
+}
+
+int sched_get_priority_min(int alg)
+{
+  return PRIO_FIFO_MIN;
+}
+
+int sched_getparam(pid_t pid, struct sched_param *p)
+{
+  p->sched_priority = getprio(pid);
+
+  return p->sched_priority == -1 ? -1 : 0;
+}
+
+int sched_setparam(pid_t pid, const struct sched_param *p)
+{
+  return setprio(pid, p->sched_priority) == -1 ? -1 : 0;
+}
+
+int sched_yield(void)
+{
+  return yield();
+}
+
+#else
+#error POSIX_PRIORITY_SCHEDULING not available on this OS
+#endif
+#endif
+#endif
diff --git a/hadaq/semaphore.c b/hadaq/semaphore.c
new file mode 100644 (file)
index 0000000..ae16635
--- /dev/null
@@ -0,0 +1,147 @@
+
+#define _XOPEN_SOURCE
+#include <unistd.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#if defined(__hpux) || defined(__osf__)
+union semun {
+       int val;
+       struct semid_ds *buf;
+       unsigned short *array;
+};
+
+#endif
+
+#include "semaphore.h"
+
+static char *name2Path(char *path, char *name)
+{
+       char *prefix;
+
+       if (NULL == (prefix = getenv("OUR_SEMAPHORE_PREFIX"))) {
+               prefix = "";
+       }
+       if (strlen(prefix) + strlen(name) + 1 > _POSIX_PATH_MAX) {
+               errno = ENAMETOOLONG;
+               path = NULL;
+       } else {
+               strcpy(path, prefix);
+               strcat(path, name);
+       }
+       return path;
+}
+
+sem_t *SEMAPHORE_sem_open(char *name, int oflags, mode_t mode, unsigned int value)
+{
+       int *sem;
+       char path[_POSIX_PATH_MAX];
+       key_t key;
+       int semflg;
+       int fd;
+       union semun arg;
+
+       if (NULL == name2Path(path, name)) {
+               return (sem_t *) -1;
+       }
+       if (0 > (fd = open(path, oflags, mode))) {
+               return (sem_t *) -1;
+       }
+       if ((key_t) - 1 == (key = ftok(path, 'A'))) {
+               close(fd);
+               return (sem_t *) -1;
+       }
+       close(fd);
+
+       if (NULL == (sem = malloc(sizeof(int)))) {
+               return (sem_t *) -1;
+       }
+       semflg = mode;                          /* BUGBUG This depends on ipc modes having
+                                   the same */
+       /* semantics as file modes */
+       if ((oflags & O_CREAT) != 0) {
+               semflg |= IPC_CREAT;
+       }
+       if ((oflags & O_EXCL) != 0) {
+               semflg |= IPC_EXCL;
+       }
+       if (semget(key, 1, 0) != -1) {  /* semaphore existst already */
+               if (0 > (*sem = semget(key, 1, semflg))) {
+                       free(sem);
+                       return (sem_t *) -1;
+               }
+       } else {
+               arg.val = value;
+               if (0 > (*sem = semget(key, 1, semflg))
+                       || 0 > semctl(*sem, 0, SETVAL, arg)
+                       ) {
+                       free(sem);
+                       return (sem_t *) -1;
+               }
+       }
+       return sem;
+}
+
+int SEMAPHORE_sem_close(sem_t *sem)
+{
+       free(sem);
+       return 0;
+}
+
+int SEMAPHORE_sem_unlink(char *name)
+{
+       int retVal;
+       sem_t semS, *sem = &semS;
+       char path[_POSIX_PATH_MAX];
+       key_t key;
+       union semun arg;
+
+       retVal = 0;
+
+       arg.val = 0;
+       if (
+                  NULL == name2Path(path, name)
+                  || (key_t) - 1 == (key = ftok(path, 'A'))
+                  || 0 > (*sem = semget(key, 1, 0))
+                  || 0 > semctl(*sem, 0, IPC_RMID, arg)
+               ) {
+               retVal = -1;
+       }
+       if (-1 == unlink(path)) {
+               retVal = -1;
+       }
+       return retVal;
+}
+
+int SEMAPHORE_sem_wait(sem_t *sem)
+{
+       static struct sembuf waitOpS =
+       {0, -1, 0}, *waitOp = &waitOpS;
+
+       return semop(*sem, waitOp, 1);
+}
+
+int SEMAPHORE_sem_trywait(sem_t *sem)
+{
+       static struct sembuf trywaitOpS =
+       {0, -1, IPC_NOWAIT}, *trywaitOp = &trywaitOpS;
+
+       return semop(*sem, trywaitOp, 1);
+}
+
+int SEMAPHORE_sem_post(sem_t *sem)
+{
+       static struct sembuf postOpS =
+       {0, +1, 0}, *postOp = &postOpS;
+
+       return semop(*sem, postOp, 1);
+}
diff --git a/hadaq/semaphore.h b/hadaq/semaphore.h
new file mode 100644 (file)
index 0000000..aaaa7d9
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef OUR_SEMAPHORE_H
+#define OUR_SEMAPHORE_H
+
+#include <sys/types.h>
+
+typedef int sem_t;
+
+#define sem_open SEMAPHORE_sem_open
+#define sem_close SEMAPHORE_sem_close
+#define sem_unlink SEMAPHORE_sem_unlink
+#define sem_wait SEMAPHORE_sem_wait
+#define sem_trywait SEMAPHORE_sem_trywait
+#define sem_post SEMAPHORE_sem_post
+
+sem_t *SEMAPHORE_sem_open(char *name, int oflags, mode_t mode, unsigned int value);
+int SEMAPHORE_sem_close(sem_t * sem);
+int SEMAPHORE_sem_unlink(char *name);
+int SEMAPHORE_sem_wait(sem_t * sem);
+int SEMAPHORE_sem_trywait(sem_t * sem);
+int SEMAPHORE_sem_post(sem_t * sem);
+
+#endif
diff --git a/hadaq/shmtrans.c b/hadaq/shmtrans.c
new file mode 100644 (file)
index 0000000..ae99b65
--- /dev/null
@@ -0,0 +1,343 @@
+static char rcsId[] = "$Id: shmtrans.c,v 6.1 1999-08-31 10:37:25 muench Stab $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+#include "grmblfx.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#ifdef _POSIX_SEMAPHORES
+#include <semaphore.h>
+#else
+#include "semaphore.h"
+#endif
+#include <string.h>
+#include <sys/stat.h>
+
+#include <hadesstd.h>
+
+#include "psxshm.h"
+#include "hadtuqueue.h"
+
+#include "shmtrans.h"
+
+#define SPACE_IN_FRONT 16              /* Reserve a little space in front of the
+                                   hadtuqueues that is not used, but
+                                   accessible. Allows for in situ asembly of
+                                   fragments with headers. */
+
+static void switchStorage(ShmTrans *my)
+{
+       HadTuQueue *queue;
+
+       queue = my->rdQueue;
+       my->rdQueue = my->wrQueue;
+       my->wrQueue = queue;
+}
+
+ShmTrans *ShmTrans_create(const char *name, size_t size)
+{
+       ShmTrans *my;
+       char ipcName[_POSIX_PATH_MAX];
+       unsigned long pageSize;
+       size_t shmSize;
+       char *addr;
+
+       my = allocMem(sizeof(ShmTrans));
+
+       my->wrQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf());
+       my->rdQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf());
+
+       strcpy(my->name, name);
+
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       if (0 > PsxShm_unlink(ipcName)) {
+               switch (errno) {
+               case ENOENT:
+                       break;
+               default:
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut1;
+                       break;
+               }
+       }
+       if (0 > (pageSize = sysconf(_SC_PAGESIZE))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       shmSize = 2 * (size + SPACE_IN_FRONT);
+       shmSize = (shmSize & (pageSize - 1))
+               ? (shmSize & ~(pageSize - 1)) + pageSize : shmSize;
+
+       if (NULL == (my->shm = PsxShm_open(ipcName, O_CREAT | O_RDWR, S_IRWXU, shmSize))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       addr = my->shm->addr;
+       addr += SPACE_IN_FRONT;
+       conHadTuQueue(my->wrQueue, addr, size);
+       addr += size;
+       addr += SPACE_IN_FRONT;
+       conHadTuQueue(my->rdQueue, addr, size);
+       HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write);
+       HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write);
+
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SR.sem");
+
+       if (0 > sem_unlink(ipcName)) {
+               switch (errno) {
+               case ENOENT:
+                       break;
+               default:
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut2;
+                       break;
+               }
+       }
+       if ((sem_t *) -1 == (my->switchRequest = sem_open(ipcName, O_CREAT | O_EXCL, S_IRWXU, 0))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut2;
+       }
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SC.sem");
+       if (0 > sem_unlink(ipcName)) {
+               switch (errno) {
+               case ENOENT:
+                       break;
+               default:
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut3;
+                       break;
+               }
+       }
+       if ((sem_t *) -1 == (my->switchComplete = sem_open(ipcName, O_CREAT | O_EXCL, S_IRWXU, 0))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut3;
+       }
+       return my;
+
+  bailOut3:
+       sem_close(my->switchRequest);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SC.sem");
+       sem_unlink(ipcName);
+  bailOut2:
+       desHadTuQueue(my->rdQueue);
+       desHadTuQueue(my->wrQueue);
+
+       PsxShm_close(my->shm);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       PsxShm_unlink(ipcName);
+  bailOut1:
+       freeMem(my->wrQueue);
+       freeMem(my->rdQueue);
+       freeMem(my);
+
+       return NULL;
+}
+
+void ShmTrans_remove(ShmTrans *my)
+{
+       char ipcName[_POSIX_PATH_MAX];
+
+       sem_close(my->switchRequest);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SR.sem");
+       sem_unlink(ipcName);
+
+       sem_close(my->switchComplete);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SC.sem");
+       sem_unlink(ipcName);
+
+       desHadTuQueue(my->rdQueue);
+       desHadTuQueue(my->wrQueue);
+
+       PsxShm_close(my->shm);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       PsxShm_unlink(ipcName);
+
+       freeMem(my->wrQueue);
+       freeMem(my->rdQueue);
+       freeMem(my);
+}
+
+ShmTrans *ShmTrans_open(const char *name, size_t size)
+{
+       ShmTrans *my;
+       char ipcName[_POSIX_PATH_MAX];
+       unsigned long pageSize;
+       size_t shmSize;
+       char *addr;
+
+       my = allocMem(sizeof(ShmTrans));
+
+       my->wrQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf());
+       my->rdQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf());
+
+       strcpy(my->name, name);
+
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+
+       if (0 > (pageSize = sysconf(_SC_PAGESIZE))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       shmSize = 2 * (size + SPACE_IN_FRONT);
+       shmSize = (shmSize & (pageSize - 1))
+               ? (shmSize & ~(pageSize - 1)) + pageSize : shmSize;
+
+       if (NULL == (my->shm = PsxShm_open(ipcName, O_RDWR, 0, shmSize))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       addr = my->shm->addr;
+       addr += SPACE_IN_FRONT;
+       conHadTuQueue(my->wrQueue, addr, size);
+       addr += size;
+       addr += SPACE_IN_FRONT;
+       conHadTuQueue(my->rdQueue, addr, size);
+       HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read);
+       HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read);
+
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SR.sem");
+
+       if ((sem_t *) -1 == (my->switchRequest = sem_open(ipcName, 0, 0, 0))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut2;
+       }
+       strcpy(ipcName, my->name);
+       strcat(ipcName, "SC.sem");
+
+       if ((sem_t *) -1 == (my->switchComplete = sem_open(ipcName, 0, 0, 0))) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut3;
+       }
+       return my;
+
+  bailOut3:
+       sem_close(my->switchRequest);
+  bailOut2:
+       desHadTuQueue(my->rdQueue);
+       desHadTuQueue(my->wrQueue);
+
+       PsxShm_close(my->shm);
+  bailOut1:
+       freeMem(my->wrQueue);
+       freeMem(my->rdQueue);
+       freeMem(my);
+
+       return NULL;
+}
+
+void ShmTrans_close(ShmTrans *my)
+{
+       sem_close(my->switchComplete);
+       sem_close(my->switchRequest);
+       desHadTuQueue(my->rdQueue);
+       desHadTuQueue(my->wrQueue);
+       PsxShm_close(my->shm);
+       freeMem(my->wrQueue);
+       freeMem(my->rdQueue);
+       freeMem(my);
+}
+
+void *ShmTrans_alloc(ShmTrans *my, size_t size)
+{
+       void *storage;
+
+       if (sem_trywait(my->switchRequest) == 0) {
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read);
+               switchStorage(my);
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write);
+               sem_post(my->switchComplete);
+       }
+       while (NULL == (storage = HadTuQueue_alloc(my->wrQueue, size))) {
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read);
+               sem_wait(my->switchRequest);
+               switchStorage(my);
+               sem_post(my->switchComplete);
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write);
+       }
+       return storage;
+}
+
+void *ShmTrans_tryAlloc(ShmTrans *my, size_t size)
+{
+       return HadTuQueue_alloc(my->wrQueue, size);
+}
+
+void ShmTrans_requestSpace(ShmTrans *my)
+{
+       if (sem_trywait(my->switchRequest) == 0) {
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read);
+               switchStorage(my);
+               HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write);
+               sem_post(my->switchComplete);
+       }
+}
+
+void ShmTrans_send(ShmTrans *my)
+{
+       HadTuQueue_push(my->wrQueue);
+}
+
+void *ShmTrans_recv(ShmTrans *my)
+{
+       void *storage;
+
+       while (NULL == (storage = HadTuQueue_front(my->rdQueue))) {
+               HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write);
+               sem_post(my->switchRequest);
+               sem_wait(my->switchComplete);
+               switchStorage(my);
+               HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read);
+       }
+       return storage;
+}
+
+void *ShmTrans_recvWhole(ShmTrans *my)
+{
+       while (HadTuQueue_empty(my->rdQueue)) {
+               HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write);
+               sem_post(my->switchRequest);
+               sem_wait(my->switchComplete);
+               switchStorage(my);
+               HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read);
+       }
+       return HadTuQueue_2voidP(my->rdQueue);
+}
+
+void *ShmTrans_tryRecv(ShmTrans *my)
+{
+       return HadTuQueue_front(my->rdQueue);
+}
+
+void ShmTrans_requestData(ShmTrans *my)
+{
+       HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write);
+       sem_post(my->switchRequest);
+       sem_wait(my->switchComplete);
+       switchStorage(my);
+       HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read);
+}
+
+void ShmTrans_free(ShmTrans *my)
+{
+       HadTuQueue_pop(my->rdQueue);
+}
+
+void ShmTrans_freeWhole(ShmTrans *my)
+{
+       HadTuQueue_clear(my->rdQueue);
+}
diff --git a/hadaq/shmtrans.h b/hadaq/shmtrans.h
new file mode 100644 (file)
index 0000000..f8ef890
--- /dev/null
@@ -0,0 +1,42 @@
+
+#ifndef SHMTRANS_H
+#define SHMTRANS_H
+
+#include <limits.h>
+
+#ifdef _POSIX_SEMAPHORES
+#include <semaphore.h>
+#else
+#include "semaphore.h"
+#endif
+
+#include "psxshm.h"
+
+#include "hadtuqueue.h"
+
+typedef struct ShmTransS {
+  char name[_POSIX_PATH_MAX];
+  PsxShm *shm;
+  HadTuQueue *rdQueue;
+  HadTuQueue *wrQueue;
+  sem_t *switchRequest;
+  sem_t *switchComplete;
+} ShmTrans;
+
+ShmTrans *ShmTrans_create(const char *name, size_t size);
+ShmTrans *ShmTrans_open(const char *name, size_t size);
+void ShmTrans_close(ShmTrans *my);
+void ShmTrans_remove(ShmTrans *my);
+
+void *ShmTrans_alloc(ShmTrans *my, size_t size);
+void *ShmTrans_tryAlloc(ShmTrans *my, size_t size);
+void ShmTrans_requestSpace(ShmTrans *my);
+void ShmTrans_send(ShmTrans *my);
+void *ShmTrans_recv(ShmTrans *my);
+void *ShmTrans_recvWhole(ShmTrans *my);
+void *ShmTrans_tryRecv(ShmTrans *my);
+void ShmTrans_requestData(ShmTrans *my);
+void ShmTrans_free(ShmTrans *my);
+void ShmTrans_freeWhole(ShmTrans *my);
+
+#endif
diff --git a/hadaq/showevt b/hadaq/showevt
new file mode 100644 (file)
index 0000000..a40082c
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/sh
+./daq_sniff -h localhost | daq_anal -n 1
+exit 0
diff --git a/hadaq/showevt.c b/hadaq/showevt.c
new file mode 100644 (file)
index 0000000..c78236b
--- /dev/null
@@ -0,0 +1,87 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/showevt.c,v 6.1 1999-08-31 10:37:25 muench Exp $";
+
+#define _ANSI_C_SOURCE
+#include <stddef.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <hadesstd.h>
+
+#include "hldread.h"
+
+int startAnalysis(int argc, char **argv)
+{
+       msglog(LOG_DEBUG, "startAnalysis called\n");
+       return 0;
+}
+
+int analyseEvt(void *evt)
+{
+       int i;
+       void *subEvt;
+
+       msglog(LOG_DEBUG, "analyseEvt called\n");
+
+       /* print the event header */
+       printf(
+                       "size: 0x%08x  decoding: 0x%08x  id: 0x%08x  seqNr: 0x%08x\n"
+                         "date: %s  time: %s  runNr: 0x%08x\n",
+                  Evt_size(evt), Evt_decoding(evt), Evt_id(evt), Evt_seqNr(evt),
+                         Evt_date2charP(evt), Evt_time2charP(evt), Evt_runNr(evt)
+               );
+
+       i = 0;
+       /* loop over all subevents */
+       for (subEvt = Evt_data(evt); subEvt < Evt_end(evt); subEvt = Evt_next(evt, subEvt)) {
+               printf("size: 0x%08x  decoding: 0x%08x  id: 0x%08x  trigNr: 0x%08x\n",
+                          SubEvt_size(subEvt), SubEvt_decoding(subEvt), SubEvt_id(subEvt), SubEvt_trigNr(subEvt));
+               if (SubEvt_decoding(subEvt) == SubEvtDecoding_32bitData) {
+                       UInt4 *data;
+
+                       data = SubEvt_data(subEvt);
+                       for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt4); i++) {
+                               if (i % 4 == 0) {       /* newline and the offset in the subEvt */
+                                       printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt));
+                               }
+                               printf("  0x%08x", data[i]);
+                       }
+               } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_16bitData) {
+                       UInt2 *data;
+
+                       data = SubEvt_data(subEvt);
+                       for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt2); i++) {
+                               if (i % 8 == 0) {       /* newline and the offset in the subEvt */
+                                       printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt));
+                               }
+                               printf("  0x%04x", data[i]);
+                       }
+               } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_8bitData) {
+                       UInt1 *data;
+
+                       data = SubEvt_data(subEvt);
+                       for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt1); i++) {
+                               if (i % 8 == 0) {       /* newline and the offset in the subEvt */
+                                       printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt));
+                               }
+                               printf("  0x%02x", data[i]);
+                       }
+               } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_text) {
+                       char *data;
+
+                       printf("%c", '\n');
+                       data = (char *) SubEvt_data(subEvt);
+                       for (i = 0; i < SubEvt_dataSize(subEvt); i++) {
+                               printf("%c", data[i]);
+                       }
+               }
+               printf("%c", '\n');
+       }
+       printf("%c", '\n');
+       return 0;
+}
+
+int stopAnalysis(void)
+{
+       msglog(LOG_DEBUG, "stopAnalysis called\n");
+       return 0;
+}
diff --git a/hadaq/sniff.c b/hadaq/sniff.c
new file mode 100644 (file)
index 0000000..82739f7
--- /dev/null
@@ -0,0 +1,73 @@
+
+#include <unistd.h>
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+#include <hadesstd.h>
+
+#include "online.h"
+
+main(int argc, char *argv[])
+{
+       CLIENT *cl;
+       char *server;
+       int i;
+       struct rpc_err rpcErrS, *rpcErr = &rpcErrS;
+       rpcevt rpcEvtS, *rpcEvt = &rpcEvtS;
+
+       msglog_setlevel(argv[0], "info");
+
+       server = NULL;
+
+       while ((i = getopt(argc, argv, "v:h:")) != -1) {
+               switch (i) {
+               case 'h':
+                       server = optarg;
+                       break;
+               case 'v':
+                       if (msglog_setlevel(argv[0], optarg) == 1) {
+                               break;
+                       }                                       /* FALLTHROUGH to default */
+               default:
+                       msglog(LOG_ERR, "Usage: %s -h evtBuildHost\n", argv[0]);
+                       msglog_usage();
+                       exit(EXIT_FAILURE);
+                       break;
+               }
+       }
+
+       if (server == NULL) {
+               msglog(LOG_ERR, "Usage: %s -h evtBuildHost\n", argv[0]);
+               msglog_usage();
+               exit(EXIT_FAILURE);
+       }
+       while (1) {
+               if (NULL == (cl = clnt_create(server, DAQPROG, DAQVERS, "tcp"))) {
+                       msglog(LOG_INFO, "online server not running, trying to connect\n");
+                       msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, clnt_spcreateerror(server));
+                       sleep(5);
+               } else {
+                       do {
+                               if (NULL == (rpcEvt = onlineevt_1(NULL, cl))) {
+                                       clnt_geterr(cl, rpcErr);
+                                       switch (rpcErr->re_status) {
+                                       case RPC_TIMEDOUT:
+                                               break;
+                                       case RPC_CANTRECV:
+                                               msglog(LOG_INFO, "server shutdown, trying to reconnect\n");
+                                               msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, clnt_sperror(cl, "onlineevt_1"));
+                                               break;
+                                       default:
+                                               msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, clnt_sperror(cl, "onlineevt_1"));
+                                               break;
+                                       }
+                               } else {
+                                       fwrite(rpcEvt->rpcevt_val, 1, rpcEvt->rpcevt_len, stdout);
+                               }
+                       } while (rpcErr->re_status != RPC_CANTRECV);
+                       clnt_destroy(cl);
+               }
+       }
+       exit(0);
+}
diff --git a/hadaq/startacq b/hadaq/startacq
new file mode 100644 (file)
index 0000000..3e33891
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/sh
+./daq_evtbuild -p -1 -s 3 -v notice &
+echo $! >evtbuild.pid
+sleep 1;
+./daq_readout -p -2 -v notice &
+echo $! >readout.pid
+sleep 1;
+./daq_ctrlctu 0 &
+echo $! >ctrlctu.pid
+exit 0
diff --git a/hadaq/stopacq b/hadaq/stopacq
new file mode 100644 (file)
index 0000000..fb213bb
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/sh
+kill $(cat ctrlctu.pid)
+rm ctrlctu.pid
+kill $(cat readout.pid)
+rm readout.pid
+kill $(cat evtbuild.pid)
+rm evtbuild.pid
+exit 0
diff --git a/hadaq/subevt.c b/hadaq/subevt.c
new file mode 100644 (file)
index 0000000..178026e
--- /dev/null
@@ -0,0 +1,96 @@
+static char rcsId[] = "$Id: subevt.c,v 6.1 1999-08-31 10:37:25 muench Exp $";
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "subevt.h"
+
+enum SubEvtIdx {
+       SubEvtIdx_size,
+       SubEvtIdx_decoding,
+       SubEvtIdx_id,
+       SubEvtIdx_trigNr,
+       SubEvtIdx_data
+};
+
+size_t SubEvt_hdrLen(void)
+{
+       return SubEvtIdx_data;
+}
+
+size_t SubEvt_hdrSize(void)
+{
+       return SubEvt_hdrLen() * sizeof(UInt4);
+}
+
+size_t SubEvt_dataSize(const void *my)
+{
+       return SubEvt_size(my) - SubEvt_hdrSize();
+}
+
+void *SubEvt_data(const void *my)
+{
+       return (void *) ((char *) my + SubEvt_hdrSize());
+}
+
+UInt4 SubEvt_id(const void *my)
+{
+       return SubEvt_hdrValue(my, SubEvtIdx_id);
+}
+
+void SubEvt_setId(void *my, UInt4 id)
+{
+       SubEvt_setHdrValue(my, SubEvtIdx_id, id);
+}
+
+UInt4 SubEvt_trigNr(const void *my)
+{
+       return SubEvt_hdrValue(my, SubEvtIdx_trigNr);
+}
+
+void SubEvt_setTrigNr(void *my, UInt4 trigNr)
+{
+       SubEvt_setHdrValue(my, SubEvtIdx_trigNr, trigNr);
+}
+
+char *SubEvt_2charP(const void *my)
+{
+       static char buf[132];
+
+       sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x\tid: 0x%08x\ttrigNr: 0x%08x",
+                       SubEvt_size(my), SubEvt_decoding(my), SubEvt_id(my), SubEvt_trigNr(my));
+
+       return buf;
+}
+
+void *newSubEvt(UInt4 decoding, UInt4 id, UInt4 trigNr)
+{
+       void *my;
+
+       my = allocMem(SubEvt_hdrSize());
+
+       SubEvt_setSize(my, SubEvt_hdrSize());
+       SubEvt_setDecoding(my, decoding);
+       SubEvt_setId(my, id);
+       SubEvt_setTrigNr(my, trigNr);
+
+       return my;
+}
+
+void deleteSubEvt(void *my)
+{
+       freeMem(my);
+}
+
+void *SubEvt_appendData(void *my, const void *data, size_t size)
+{
+
+       my = reallocMem(my, SubEvt_paddedSize(my) + size);
+       memcpy(SubEvt_end(my), data, size);
+       SubEvt_setSize(my, SubEvt_paddedSize(my) + size);
+
+       return my;
+}
diff --git a/hadaq/subevt.h b/hadaq/subevt.h
new file mode 100644 (file)
index 0000000..6b315fe
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef SUBEVT_H
+#define SUBEVT_H
+
+#include <hadesstd.h>
+
+#include "hadtu.h"
+
+enum SubEvtId {
+  SubEvtId_test1 = 1,
+  SubEvtId_slow = 2,
+  SubEvtId_test2 = 3,
+  SubEvtId_mdc = 6,
+  SubEvtId_shower = 7,
+  SubEvtId_rich = 8,
+  SubEvtId_tof = 9,
+  SubEvtId_start = 10,
+  SubEvtId_veto = 11,
+  SubEvtId_richPed = 12,
+       SubEvtId_tofTest = 400,
+  SubEvtId_trigCode = 500,
+  SubEvtId_trigInfo = 501
+};
+
+enum SubEvtDecoding {
+  SubEvtDecoding_8bitData = 1,
+  SubEvtDecoding_16bitData = (1 << 16) | 1,
+  SubEvtDecoding_32bitData = (2 << 16) | 1,
+  SubEvtDecoding_text = 2
+};
+
+#define SubEvt_hdr HadTu_hdr
+#define SubEvt_isSwapped HadTu_isSwapped
+#define SubEvt_hdrValue HadTu_hdrValue
+#define SubEvt_setHdrValue HadTu_setHdrValue
+#define SubEvt_decoding HadTu_decoding
+#define SubEvt_setDecoding HadTu_setDecoding
+#define SubEvt_alignment HadTu_alignment
+#define SubEvt_size HadTu_size
+#define SubEvt_setSize HadTu_setSize
+#define SubEvt_paddedSize HadTu_paddedSize
+#define SubEvt_begin HadTu_begin
+#define SubEvt_end HadTu_end
+#define SubEvt_next HadTu_next
+
+size_t SubEvt_hdrLen(void);
+size_t SubEvt_hdrSize(void);
+size_t SubEvt_dataSize(const void *my);
+void *SubEvt_data(const void *my);
+UInt4 SubEvt_dataValue(const void *my, unsigned idx);
+char *SubEvt_2charP(const void *my);
+
+UInt4 SubEvt_id(const void *my);
+void SubEvt_setId(void *my, UInt4 id);
+UInt4 SubEvt_trigNr(const void *my);
+void SubEvt_setTrigNr(void *my, UInt4 trigNr);
+
+void *newSubEvt(UInt4 decoding, UInt4 id, UInt4 trigNr);
+void deleteSubEvt(void *my);
+void *SubEvt_appendData(void *my, const void *data, size_t size);
+
+#endif
diff --git a/hadaq/tclAppInit.c b/hadaq/tclAppInit.c
new file mode 100644 (file)
index 0000000..926d24a
--- /dev/null
@@ -0,0 +1,134 @@
+
+/*
+ * tclAppInit.c --
+ *
+ *     Provides a default version of the main program and Tcl_AppInit
+ *     procedure for Tcl applications (without Tk).
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tclAppInit.c 1.20 97/03/24 14:29:43
+ */
+
+#ifdef TCL_XT_TEST
+#include <X11/Intrinsic.h>
+#endif
+
+#include "tcl.h"
+
+/*
+ * The following variable is a special hack that is needed in order for
+ * Sun shared libraries to be used for Tcl.
+ */
+
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
+
+#ifdef TCL_TEST
+EXTERN int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp * interp));
+EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp * interp));
+#endif                                                 /* TCL_TEST */
+#ifdef TCL_XT_TEST
+EXTERN int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp * interp));
+#endif
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ *     This is the main program for the application.
+ *
+ * Results:
+ *     None: Tcl_Main never returns here, so this procedure never
+ *     returns either.
+ *
+ * Side effects:
+ *     Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int main(argc, argv)
+int argc;                                              /* Number of command-line arguments. */
+char **argv;                                   /* Values of command-line arguments. */
+{
+#ifdef TCL_XT_TEST
+       XtToolkitInitialize();
+#endif
+       Tcl_Main(argc, argv, Tcl_AppInit);
+       return 0;                                       /* Needed only to prevent compiler warning. */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ *     This procedure performs application-specific initialization.
+ *     Most applications, especially those that incorporate additional
+ *     packages, will have their own version of this procedure.
+ *
+ * Results:
+ *     Returns a standard Tcl completion code, and leaves an error
+ *     message in interp->result if an error occurs.
+ *
+ * Side effects:
+ *     Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int Tcl_AppInit(interp)
+Tcl_Interp *interp;                            /* Interpreter for application. */
+{
+       if (Tcl_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+#ifdef TCL_TEST
+#ifdef TCL_XT_TEST
+       if (Tclxttest_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+#endif
+       if (Tcltest_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+       if (TclObjTest_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+#endif                                                 /* TCL_TEST */
+
+       /*
+     * Call the init procedures for included packages.  Each call should
+     * look like this:
+     *
+     * if (Mod_Init(interp) == TCL_ERROR) {
+     *     return TCL_ERROR;
+     * }
+     *
+     * where "Mod" is the name of the module.
+     */
+       if (Daq_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+       /*
+     * Call Tcl_CreateCommand for application-specific commands, if
+     * they weren't already created by the init procedures called above.
+     */
+
+       /*
+     * Specify a user-specific startup file to invoke if the application
+     * is run interactively.  Typically the startup file is "~/.apprc"
+     * where "app" is the name of the application.  If this line is deleted
+     * then no user-specific startup file will be run under any conditions.
+     */
+
+       Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
+       return TCL_OK;
+}
diff --git a/hadaq/tcldaq.c b/hadaq/tcldaq.c
new file mode 100644 (file)
index 0000000..8f539ed
--- /dev/null
@@ -0,0 +1,109 @@
+
+#include <unistd.h>
+
+#include <stddef.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rpc/rpc.h>
+
+#include <tcl.h>
+#include <hadesstd.h>
+#include "worker.h"
+#include "agent.h"
+
+int AgentCmd(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[])
+{
+       CLIENT *cl;
+
+       if (argc != 3) {
+               Tcl_AppendResult(interp, "usage: c_agent connect|disconnect|ping <agent>", NULL);
+               return TCL_ERROR;
+       }
+       if (strcmp(argv[1], "connect") == 0) {
+               if (NULL == (cl = clnt_create(argv[2], DAQAGENTPROG, DAQAGENTVERS, "tcp"))) {
+                       Tcl_AppendResult(interp, clnt_spcreateerror(argv[2]), NULL);
+                       return TCL_ERROR;
+               }
+               sprintf(interp->result, "%p", cl);
+       } else if (strcmp(argv[1], "disconnect") == 0) {
+               sscanf(argv[2], "%p", &cl);
+               clnt_destroy(cl);
+       } else if (strcmp(argv[1], "ping") == 0) {
+       } else {
+               Tcl_AppendResult(interp, "usage: c_agent connect|disconnect <agent>", NULL);
+               return TCL_ERROR;
+       }
+       return TCL_OK;
+}
+
+int WorkerCmd(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[])
+{
+       CLIENT *cl;
+       int id, *idP;
+
+       if (argc < 4) {
+               Tcl_AppendResult(interp, "usage: c_worker start|stop <agent> <worker> [worker options]", NULL);
+               return TCL_ERROR;
+       }
+       sscanf(argv[2], "%p", &cl);
+       if (strcmp(argv[1], "start") == 0) {
+               RpcWorker_startArgs startArgsS, *startArgs = &startArgsS;
+
+               startArgs->name = argv[3];
+               /* CAUTION This does not pass the closing NULL pointer in argv */
+               startArgs->argv.argv_len = argc - 3;
+               startArgs->argv.argv_val = argv + 3;
+
+               if (NULL == (idP = rpcworker_start_1(startArgs, cl))) {
+                       Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_start_1"), NULL);
+                       return TCL_ERROR;
+               }
+               id = *idP;
+               sprintf(interp->result, "%d", id);
+       } else if (strcmp(argv[1], "stop") == 0) {
+               int *res;
+
+               idP = &id;
+               sscanf(argv[3], "%d", idP);
+               if (NULL == (res = rpcworker_stop_1(idP, cl))) {
+                       Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_stop_1"), NULL);
+                       return TCL_ERROR;
+               }
+       } else if (strcmp(argv[1], "status") == 0) {
+               char *sS, **s = &sS;
+
+               idP = &id;
+               sscanf(argv[3], "%d", idP);
+               if (NULL == (s = rpcworker_status_1(idP, cl))) {
+                       Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_status_1"), NULL);
+                       return TCL_ERROR;
+               }
+               Tcl_AppendResult(interp, *s, NULL);
+       } else {
+               Tcl_AppendResult(interp, "usage: c_worker start|stop|status <worker> [options]", NULL);
+               return TCL_ERROR;
+       }
+
+       return TCL_OK;
+}
+
+int Daq_Init(Tcl_Interp * interp)
+{
+       /*
+   * Call Tcl_CreateCommand for application-specific commands, if
+   * they weren't already created by the init procedures called above.
+   */
+       Tcl_CreateCommand(interp, "c_worker", WorkerCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+       Tcl_CreateCommand(interp, "c_agent", AgentCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+
+       /*
+   * Specify a user-specific startup file to invoke if the application
+   * is run interactively.  Typically the startup file is "~/.apprc"
+   * where "app" is the name of the application.  If this line is deleted
+   * then no user-specific startup file will be run under any conditions.
+   */
+       return TCL_OK;
+}
diff --git a/hadaq/tkAppInit.c b/hadaq/tkAppInit.c
new file mode 100644 (file)
index 0000000..5dbb0e0
--- /dev/null
@@ -0,0 +1,118 @@
+
+/*
+ * tkAppInit.c --
+ *
+ *     Provides a default version of the Tcl_AppInit procedure for
+ *     use in wish and similar Tk-based applications.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tkAppInit.c 1.22 96/05/29 09:47:08
+ */
+
+#include "tk.h"
+
+/*
+ * The following variable is a special hack that is needed in order for
+ * Sun shared libraries to be used for Tcl.
+ */
+
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
+#ifdef TK_TEST
+EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp * interp));
+#endif                                                 /* TK_TEST */
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ *     This is the main program for the application.
+ *
+ * Results:
+ *     None: Tk_Main never returns here, so this procedure never
+ *     returns either.
+ *
+ * Side effects:
+ *     Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int main(argc, argv)
+int argc;                                              /* Number of command-line arguments. */
+char **argv;                                   /* Values of command-line arguments. */
+{
+       Tk_Main(argc, argv, Tcl_AppInit);
+       return 0;                                       /* Needed only to prevent compiler warning. */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ *     This procedure performs application-specific initialization.
+ *     Most applications, especially those that incorporate additional
+ *     packages, will have their own version of this procedure.
+ *
+ * Results:
+ *     Returns a standard Tcl completion code, and leaves an error
+ *     message in interp->result if an error occurs.
+ *
+ * Side effects:
+ *     Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int Tcl_AppInit(interp)
+Tcl_Interp *interp;                            /* Interpreter for application. */
+{
+       if (Tcl_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+       if (Tk_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+#ifdef TK_TEST
+       if (Tktest_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+#endif                                                 /* TK_TEST */
+
+
+       /*
+     * Call the init procedures for included packages.  Each call should
+     * look like this:
+     *
+     * if (Mod_Init(interp) == TCL_ERROR) {
+     *     return TCL_ERROR;
+     * }
+     *
+     * where "Mod" is the name of the module.
+     */
+       if (Daq_Init(interp) == TCL_ERROR) {
+               return TCL_ERROR;
+       }
+       /*
+     * Call Tcl_CreateCommand for application-specific commands, if
+     * they weren't already created by the init procedures called above.
+     */
+
+       /*
+     * Specify a user-specific startup file to invoke if the application
+     * is run interactively.  Typically the startup file is "~/.apprc"
+     * where "app" is the name of the application.  If this line is deleted
+     * then no user-specific startup file will be run under any conditions.
+     */
+
+       Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
+       return TCL_OK;
+}
diff --git a/hadaq/worker.c b/hadaq/worker.c
new file mode 100644 (file)
index 0000000..a57db93
--- /dev/null
@@ -0,0 +1,303 @@
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/worker.c,v 6.1 1999-08-31 10:37:25 muench Stab $";
+
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#ifdef _POSIX_PRIORITY_SCHEDULING
+#include <sched.h>
+#else
+#include "sched.h"
+#endif
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <hadesstd.h>
+
+#include "worker.h"
+
+static struct sigaction ourOldSigActionS, *ourOldSigAction = &ourOldSigActionS;
+
+static sigReceived = 0;
+
+static void noopHandler(int sig)
+{
+       sigReceived = sig;
+}
+
+static int changePriority(int p)
+{
+       struct sched_param spS, *sp = &spS;;
+
+       if (sched_getscheduler(0) != SCHED_FIFO) {
+#if defined(__osf__)
+               /* FIFO priorities are not all real time under DEC-UNIX */
+               sp->sched_priority = SCHED_PRIO_RT_MIN + 16;
+#else
+               sp->sched_priority = sched_get_priority_min(SCHED_FIFO) + 16;
+#endif
+       } else {
+               sched_getparam(0, sp);
+       }
+       sp->sched_priority += p;
+       if (0 > sched_setscheduler(0, SCHED_FIFO, sp)) {
+               msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut0;
+       }
+       return 0;
+
+  bailOut0:
+       return -1;
+}
+
+Worker *Worker_initBegin(const char *name, void (*sigHandler) (int), int priority, int isStandalone)
+{
+       Worker *my;
+       char ipcName[_POSIX_PATH_MAX];
+       struct sigaction actS, *act = &actS;
+
+       my = allocMem(sizeof(Worker));
+
+       strcpy(my->name, name);
+       my->pid = getpid();
+
+       act->sa_handler = sigHandler;
+       sigfillset(&(act->sa_mask));
+       act->sa_flags = 0;
+       if (0 > sigaction(SIGTERM, act, ourOldSigAction)) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       if (0 > sigaction(SIGINT, act, ourOldSigAction)) {
+               msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut2;
+       }
+       if (0 > changePriority(priority)) {
+               msglog(LOG_WARNING,
+                          "changeing priority: %s\n", strerror(errno));
+       }
+       my->isStandalone = isStandalone;
+
+       if (my->isStandalone) {
+               my->statistics = allocMem(32 * sizeof(Statistic));
+       } else {
+               strcpy(ipcName, my->name);
+               strcat(ipcName, ".shm");
+
+               if (NULL == (my->shm = PsxShm_open(ipcName, O_RDWR, 0, 32 * sizeof(Statistic)))) {
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut3;
+               }
+               my->statistics = my->shm->addr;
+
+       }
+       strcpy(my->statistics[0].name, "");
+       return my;
+
+       if (my->isStandalone) {
+               freeMem(my->statistics);
+       } else {
+               PsxShm_close(my->shm);
+       }
+  bailOut3:
+       sigaction(SIGINT, ourOldSigAction, NULL);
+  bailOut2:
+       sigaction(SIGTERM, ourOldSigAction, NULL);
+  bailOut1:
+       freeMem(my);
+
+       return NULL;
+}
+
+void Worker_initEnd(Worker *my)
+{
+       if (!my->isStandalone) {
+               if (0 > kill(getppid(), SIGUSR1)) {
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               }
+       }
+}
+
+void Worker_fini(Worker *my)
+{
+       if (my->isStandalone) {
+               freeMem(my->statistics);
+       } else {
+               PsxShm_close(my->shm);
+       }
+       sigaction(SIGINT, ourOldSigAction, NULL);
+       sigaction(SIGTERM, ourOldSigAction, NULL);
+       freeMem(my);
+}
+
+Worker *Worker_start(const char *name, char *argv[])
+{
+       Worker *my;
+       char ipcName[_POSIX_PATH_MAX];
+       struct sigaction actS, *act = &actS;
+       struct sigaction oAlrmActS, *oAlrmAct = &oAlrmActS;
+       struct sigaction oChldActS, *oChldAct = &oChldActS;
+       sigset_t sigMaskS, *sigMask = &sigMaskS;
+
+       my = allocMem(sizeof(Worker));
+
+       strcpy(my->name, name);
+
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       if (-1 == PsxShm_unlink(ipcName)) {
+               switch (errno) {
+               case ENOENT:
+                       break;
+               default:
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut1;
+                       break;
+               }
+       }
+       if (NULL == (my->shm = PsxShm_open(ipcName, O_CREAT | O_RDWR, S_IRWXU, 32 * sizeof(Statistic)))) {
+               msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut1;
+       }
+       my->statistics = my->shm->addr;
+
+       act->sa_handler = noopHandler;
+       sigfillset(&(act->sa_mask));
+       act->sa_flags = 0;
+       if (0 > sigaction(SIGCHLD, act, oChldAct)) {
+               msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut2;
+       }
+       if (0 > sigaction(SIGUSR1, act, oAlrmAct)) {
+               msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut3;
+       }
+       if (0 > (my->pid = fork())) {
+               msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+               goto bailOut4;
+       }
+       if (my->pid == 0) {                     /* This is the child, we can not get out of
+                                   this block */
+               if (0 > execvp(name, argv)) {
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       msglog(LOG_EMERG, "Starting %s: %s\n", name, strerror(errno));
+                       abort();
+               }
+       } else {
+               /* BUGBUG there should be a timeout here */
+               sigemptyset(sigMask);   /* This is the parent, so wait for the child */
+               sigsuspend(sigMask);    /* to initialize */
+
+               if (sigReceived == SIGCHLD) {
+                       msglog(LOG_DEBUG,
+                          "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno));
+                       goto bailOut4;
+               }
+       }
+
+       sigaction(SIGUSR1, oAlrmAct, NULL);
+       sigaction(SIGCHLD, oChldAct, NULL);
+
+       return my;
+
+  bailOut5:
+       if (0 == kill(my->pid, SIGTERM)) {
+               wait(NULL);
+       }
+  bailOut4:
+       sigaction(SIGUSR1, oAlrmAct, NULL);
+  bailOut3:
+       sigaction(SIGCHLD, oChldAct, NULL);
+  bailOut2:
+       PsxShm_close(my->shm);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       PsxShm_unlink(ipcName);
+  bailOut1:
+       freeMem(my);
+
+       return NULL;
+}
+
+char *Worker_status(Worker *my)
+{
+       static char buf[32 * 80];
+       char *p;
+       int i;
+
+       strcpy(buf, "{}");
+       for (
+                       i = 0, p = buf;
+                       i < 32 && strcmp(my->statistics[i].name, "") != 0;
+                       i++) {
+               p += sprintf(p,
+                "{ %s %lu } ", my->statistics[i].name, my->statistics[i].value);
+       }
+       return buf;
+}
+
+void Worker_stop(Worker *my, int timeout)
+{
+       char ipcName[_POSIX_PATH_MAX];
+
+       if (0 == kill(my->pid, SIGTERM)) {
+               wait(NULL);
+       }
+       PsxShm_close(my->shm);
+       strcpy(ipcName, my->name);
+       strcat(ipcName, ".shm");
+       PsxShm_unlink(ipcName);
+       freeMem(my);
+}
+
+unsigned long *Worker_addStatistic(Worker *my, const char *name)
+{
+       int i;
+
+       for (i = 0; i < 32 && strcmp(my->statistics[i].name, "") != 0; i++) {
+       }
+       if (i == 32) {
+               errno = 0;
+               msglog(LOG_DEBUG,
+                "%s, line %d: %s\n", __FILE__, __LINE__, "Too many statistics");
+               goto bailOut0;
+       }
+       strcpy(my->statistics[i].name, name);
+       my->statistics[i].value = 0;
+       strcpy(my->statistics[i + 1].name, "");
+
+       return &(my->statistics[i].value);
+
+  bailOut0:
+       return NULL;
+}
+
+void Worker_dump(Worker *my, time_t interval)
+{
+       if (my->isStandalone) {
+               static time_t lastTime = 0;
+               time_t curTime;
+
+               curTime = time(NULL);
+               if (curTime >= lastTime + interval) {
+                       msglog(LOG_INFO, "%s\n", Worker_status(my));
+                       lastTime = curTime;
+               }
+       }
+}
diff --git a/hadaq/worker.h b/hadaq/worker.h
new file mode 100644 (file)
index 0000000..0a7b0e1
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef WORKER_H
+#define WORKER_H
+
+#include <limits.h>
+
+#include "psxshm.h"
+
+typedef struct StatisticS {
+  char name[32];
+  unsigned long value;
+} Statistic;
+
+typedef struct WorkerS {
+  char name[_POSIX_PATH_MAX];
+  PsxShm *shm;
+  Statistic *statistics;
+  pid_t pid;
+  int isStandalone;
+} Worker;
+
+Worker *Worker_start(const char *name, char *argv[]);
+char *Worker_status(Worker * my);
+void Worker_stop(Worker * my, int timeout);
+Worker *Worker_initBegin(const char *name, void (*sigHandler) (int), int priority, int isStandalone);
+void Worker_initEnd(Worker * my);
+void Worker_fini(Worker * my);
+unsigned long *Worker_addStatistic(Worker * my, const char *name);
+void Worker_dump(Worker * my, time_t interval);
+
+#endif