source: trunk/FACT++/src/EventBuilder.c@ 15467

Last change on this file since 15467 was 15467, checked in by tbretz, 11 years ago
Unified mBuffer and evtCtrl, there is no need to keep those two informations separated; this will also immediately reveal threading problems which were hidden before.
File size: 80.0 KB
Line 
1
2// // // #define EVTDEBUG
3
4#define NUMSOCK 1 //set to 7 for old configuration
5#define MAXREAD 65536 //64kB wiznet buffer
6
7#include <stdlib.h>
8#include <stdint.h>
9#include <stdarg.h>
10#include <unistd.h>
11#include <stdio.h>
12#include <sys/time.h>
13#include <arpa/inet.h>
14#include <string.h>
15#include <math.h>
16#include <error.h>
17#include <errno.h>
18#include <unistd.h>
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <netinet/in.h>
22#include <netinet/tcp.h>
23#include <pthread.h>
24#include <sched.h>
25
26#include "EventBuilder.h"
27
28enum Severity
29{
30 kMessage = 10, ///< Just a message, usually obsolete
31 kInfo = 20, ///< An info telling something which can be interesting to know
32 kWarn = 30, ///< A warning, things that somehow might result in unexpected or unwanted bahaviour
33 kError = 40, ///< Error, something unexpected happened, but can still be handled by the program
34 kFatal = 50, ///< An error which cannot be handled at all happend, the only solution is program termination
35 kDebug = 99, ///< A message used for debugging only
36};
37
38#define MIN_LEN 32 // min #bytes needed to interpret FADheader
39#define MAX_LEN 256*1024 // size of read-buffer per socket
40
41//#define nanosleep(x,y)
42
43extern FileHandle_t runOpen (uint32_t irun, RUN_HEAD * runhd, size_t len);
44extern int runWrite (FileHandle_t fileHd, EVENT * event, size_t len);
45extern int runClose (FileHandle_t fileHd, RUN_TAIL * runth, size_t len);
46//extern int runFinish (uint32_t runnr);
47
48extern void factOut (int severity, int err, char *message);
49extern void factReportIncomplete (uint64_t rep);
50
51extern void gotNewRun (int runnr, PEVNT_HEADER * headers);
52
53
54extern void factStat (GUI_STAT gj);
55
56extern void factStatNew (EVT_STAT gi);
57
58extern int eventCheck (uint32_t runNr, PEVNT_HEADER * fadhd, EVENT * event);
59
60extern int subProcEvt (int threadID, PEVNT_HEADER * fadhd, EVENT * event,
61 int8_t * buffer);
62
63extern void debugHead (int i, int j, void *buf);
64
65extern void debugRead (int isock, int ibyte, int32_t event, int32_t ftmevt,
66 int32_t runnr, int state, uint32_t tsec,
67 uint32_t tusec);
68extern void debugStream (int isock, void *buf, int len);
69
70int CloseRunFile (uint32_t runId, uint32_t closeTime, uint32_t maxEvt);
71
72
73int evtCtrl_frstPtr;
74int evtCtrl_lastPtr;
75
76
77
78int g_maxProc;
79int g_maxSize;
80int gi_maxSize;
81int gi_maxProc;
82
83uint g_actTime;
84uint g_actUsec;
85int g_runStat;
86int g_reset;
87int g_useFTM;
88
89int gi_reset, gi_resetR, gi_resetS, gi_resetW, gi_resetX;
90size_t g_maxMem; //maximum memory allowed for buffer
91
92//no longer needed ...
93int g_maxBoards; //maximum number of boards to be initialized
94int g_actBoards;
95//
96
97FACT_SOCK g_port[NBOARDS]; // .addr=string of IP-addr in dotted-decimal "ddd.ddd.ddd.ddd"
98
99
100int gi_runStat;
101int gp_runStat;
102int gw_runStat;
103
104//int gi_memStat = +1;
105
106uint32_t actrun = 0;
107
108
109uint gi_NumConnect[NBOARDS]; //4 crates * 10 boards
110
111//uint gi_EvtStart= 0 ;
112//uint gi_EvtRead = 0 ;
113//uint gi_EvtBad = 0 ;
114//uint gi_EvtTot = 0 ;
115//size_t gi_usedMem = 0 ;
116
117//uint gw_EvtTot = 0 ;
118//uint gp_EvtTot = 0 ;
119
120//PIX_MAP g_pixMap[NPIX];
121
122EVT_STAT gi;
123GUI_STAT gj;
124
125EVT_CTRL evtCtrl[MAX_EVT * MAX_RUN]; //control of events during processing
126
127//#define MXSTR 1000
128//char str[MXSTR];
129
130void factPrintf(int severity, int id, const char *fmt, ...)
131{
132 char str[1000];
133
134 va_list ap;
135 va_start(ap, fmt);
136 vsnprintf(str, 1000, fmt, ap);
137 va_end(ap);
138
139 factOut(severity, id, str);
140}
141
142
143#define THOMAS_MALLOC
144
145#ifdef THOMAS_MALLOC
146#define MAX_HEAD_MEM (NBOARDS * sizeof(PEVNT_HEADER))
147#define MAX_TOT_MEM (sizeof(EVENT) + (NPIX+NTMARK)*1024*2 + MAX_HEAD_MEM)
148typedef struct TGB_struct
149{
150 struct TGB_struct *prev;
151 void *mem;
152} TGB_entry;
153
154TGB_entry *tgb_last = NULL;
155uint64_t tgb_memory = 0;
156uint64_t tgb_inuse = 0;
157
158void *TGB_Malloc()
159{
160 // No free slot available, next alloc would exceed max memory
161 if (!tgb_last && tgb_memory+MAX_TOT_MEM>g_maxMem)
162 return NULL;
163
164 // We will return this amount of memory
165 tgb_inuse += MAX_TOT_MEM;
166
167 // No free slot available, allocate a new one
168 if (!tgb_last)
169 {
170 tgb_memory += MAX_TOT_MEM;
171 return malloc(MAX_TOT_MEM);
172 }
173
174 // Get the next free slot from the stack and return it
175 TGB_entry *last = tgb_last;
176
177 void *mem = last->mem;
178 tgb_last = last->prev;
179
180 free(last);
181
182 return mem;
183};
184
185void TGB_free(void *mem)
186{
187 // Add the last free slot to the stack
188 TGB_entry *entry = (TGB_entry*)malloc(sizeof(TGB_entry));
189
190 entry->prev = tgb_last;
191 entry->mem = mem;
192
193 tgb_last = entry;
194
195 // Decrease the amont of memory in use accordingly
196 tgb_inuse -= MAX_TOT_MEM;
197}
198#endif
199
200#ifdef ETIENNE_MALLOC
201//ETIENNE
202#define MAX_SLOTS_PER_CHUNK 100
203
204typedef struct {
205 int32_t eventNumber;
206 int32_t chunk;
207 int32_t slot;
208} CHUNK_MAPPING;
209
210CHUNK_MAPPING mBufferMapping[MAX_EVT * MAX_RUN];
211
212#define MAX_EVT_MEM (sizeof(EVENT) + NPIX*1024*2 + NTMARK*1024*2)
213#define MAX_HEAD_MEM (NBOARDS * sizeof(PEVNT_HEADER))
214#define MAX_SLOT_SIZE (MAX_EVT_MEM + MAX_HEAD_MEM)
215#define MAX_CHUNK_SIZE (MAX_SLOT_SIZE*MAX_SLOTS_PER_CHUNK)
216
217typedef struct {
218 void * pointers[MAX_SLOTS_PER_CHUNK];
219 int32_t events[MAX_SLOTS_PER_CHUNK];
220 int32_t nFreeSlots;
221 int32_t nSlots;
222} ETI_CHUNK;
223
224int32_t numAllocatedChunks = 0;
225
226#define MAX_CHUNKS 8096
227ETI_CHUNK EtiMemoryChunks[MAX_CHUNKS];
228
229void* ETI_Malloc(int evtId, int evtIndex)
230{
231 for (int i=0;i<numAllocatedChunks;i++) {
232 if (EtiMemoryChunks[i].nFreeSlots > 0) {
233 for (int j=0;j<EtiMemoryChunks[i].nSlots;j++)
234 {
235 if (EtiMemoryChunks[i].events[j] == -1)
236 {
237 EtiMemoryChunks[i].events[j] = evtId;
238 EtiMemoryChunks[i].nFreeSlots--;
239 if (EtiMemoryChunks[i].nFreeSlots < 0)
240 {
241 factPrintf(kError, 0, "Number of free slot in chunk %d went below zero (%d) slot: %d", i, EtiMemoryChunks[i].nFreeSlots, j);
242 return NULL;
243 }
244 mBufferMapping[evtIndex].eventNumber = evtId;
245 mBufferMapping[evtIndex].chunk = i;
246 mBufferMapping[evtIndex].slot = j;
247 return EtiMemoryChunks[i].pointers[j];
248 }
249 }
250 //If I reach this point then we have a problem because it should have found
251 //a free spot just above.
252 factPrintf(kError, 0, "Could not find a free slot in a chunk that's supposed to have some. chunk=%d", i);
253 return NULL;
254 }
255 }
256 //If we reach this point this means that we should allocate more memory
257 int32_t numNewSlots = MAX_SLOTS_PER_CHUNK;
258 if ((numAllocatedChunks + 1)*MAX_CHUNK_SIZE >= g_maxMem)
259 return NULL;
260
261 EtiMemoryChunks[numAllocatedChunks].pointers[0] = malloc(MAX_SLOT_SIZE*MAX_SLOTS_PER_CHUNK);
262 if (EtiMemoryChunks[numAllocatedChunks].pointers[0] == NULL)
263 {
264 factPrintf(kError, 0, "Allocation of %lu bytes failed. %d chunks are currently allocated (max allowed %lu bytes)", MAX_CHUNK_SIZE, numAllocatedChunks, g_maxMem);
265 return NULL;
266 }
267
268 EtiMemoryChunks[numAllocatedChunks].nSlots = numNewSlots;
269 EtiMemoryChunks[numAllocatedChunks].events[0] = evtId;
270 EtiMemoryChunks[numAllocatedChunks].nFreeSlots = numNewSlots-1;
271 mBufferMapping[evtIndex].eventNumber = evtId;
272 mBufferMapping[evtIndex].chunk = numAllocatedChunks;
273 mBufferMapping[evtIndex].slot = 0;
274
275 for (int i=1;i<numNewSlots;i++)
276 {
277 EtiMemoryChunks[numAllocatedChunks].pointers[i] = (char*)EtiMemoryChunks[numAllocatedChunks].pointers[0] + i*MAX_SLOT_SIZE;// &(((char*)(EtiMemoryChunks[numAllocatedChunks].pointers[i-1]))[MAX_SLOT_SIZE]);
278 EtiMemoryChunks[numAllocatedChunks].events[i] = -1;
279 }
280 numAllocatedChunks++;
281
282 return EtiMemoryChunks[numAllocatedChunks-1].pointers[0];
283}
284
285void ETI_Free(int evtId, int evtIndex)
286{
287 ETI_CHUNK* currentChunk = &EtiMemoryChunks[mBufferMapping[evtIndex].chunk];
288 if (currentChunk->events[mBufferMapping[evtIndex].slot] != evtId)
289 {
290 factPrintf(kError, 0, "Mismatch in chunk mapping table. Expected evtId %d. Got %d. No memory was freed.", evtId, currentChunk->events[mBufferMapping[evtIndex].slot]);
291 return;
292 }
293 currentChunk->events[mBufferMapping[evtIndex].slot] = -1;
294 currentChunk->nFreeSlots++;
295
296 return; /* TEST */
297
298 int chunkIndex = mBufferMapping[evtIndex].chunk;
299 if (chunkIndex != numAllocatedChunks-1)
300 return;
301
302 while (EtiMemoryChunks[chunkIndex].nFreeSlots == EtiMemoryChunks[chunkIndex].nSlots)
303 {//free this chunk
304 if (EtiMemoryChunks[chunkIndex].pointers[0] == NULL)
305 {
306 factPrintf(kError, 0, "Chunk %d not allocated as it ought to be. Skipping memory release.", chunkIndex);
307 return;
308 }
309 free(EtiMemoryChunks[chunkIndex].pointers[0]);
310 EtiMemoryChunks[chunkIndex].pointers[0] = NULL;
311 EtiMemoryChunks[chunkIndex].nSlots = 0;
312 numAllocatedChunks--;
313 chunkIndex--;
314 if (numAllocatedChunks == 0)
315 break;
316 }
317}
318//END ETIENNE
319#endif
320
321
322RUN_CTRL runCtrl[MAX_RUN];
323//RUN_TAIL runTail[MAX_RUN];
324
325
326/*
327*** Definition of rdBuffer to read in IP packets; keep it global !!!!
328 */
329
330
331typedef union
332{
333 int8_t B[MAX_LEN];
334 int16_t S[MAX_LEN / 2];
335 int32_t I[MAX_LEN / 4];
336 int64_t L[MAX_LEN / 8];
337} CNV_FACT;
338
339typedef struct
340{
341 int bufTyp; //what are we reading at the moment: 0=header 1=data -1=skip ...
342 int32_t bufPos; //next byte to read to the buffer next
343 int32_t bufLen; //number of bytes left to read
344// size_t bufLen; //number of bytes left to read size_t might be better
345 int32_t skip; //number of bytes skipped before start of event
346
347 int errCnt; //how often connect failed since last successful
348 int sockStat; //-1 if socket not yet connected , 99 if not exist
349 int socket; //contains the sockets
350 struct sockaddr_in SockAddr; //IP for each socket
351
352 int evtID; // event ID of event currently read
353 int runID; // run "
354 int ftmID; // event ID from FTM
355 uint fadLen; // FADlength of event currently read
356 int fadVers; // Version of FAD
357 int ftmTyp; // trigger type
358 int board; // boardID (softwareID: 0..40 )
359 int Port;
360
361 CNV_FACT *rBuf;
362
363} READ_STRUCT;
364
365
366typedef union
367{
368 int8_t B[2];
369 int16_t S;
370} SHORT_BYTE;
371
372
373
374
375
376SHORT_BYTE start, stop;
377
378READ_STRUCT rd[MAX_SOCK]; //buffer to read IP and afterwards store in mBuffer
379
380
381
382/*-----------------------------------------------------------------*/
383
384
385/*-----------------------------------------------------------------*/
386
387
388
389int
390runFinish1 (uint32_t runnr)
391{
392 factPrintf(kInfo, 173, "Should finish(1) run %d (but not yet possible)", runnr);
393 return 0;
394}
395int
396runFinish (uint32_t runnr)
397{
398 factPrintf(kInfo, 173, "Should finish run %d (but not yet possible)", runnr);
399 return 0;
400}
401
402int
403GenSock (int flag, int sid, int port, struct sockaddr_in *sockAddr,
404 READ_STRUCT * rs)
405{
406/*
407*** generate Address, create sockets and allocates readbuffer for it
408***
409*** if flag==0 generate socket and buffer
410*** <0 destroy socket and buffer
411*** >0 close and redo socket
412***
413*** sid : board*7 + port id
414 */
415
416 int j;
417 int optval = 1; //activate keepalive
418 socklen_t optlen = sizeof (optval);
419
420
421 if (sid % 7 >= NUMSOCK) {
422 //this is a not used socket, so do nothing ...
423 rs->sockStat = 77;
424 rs->rBuf = NULL ;
425 return 0;
426 }
427
428 if (rs->sockStat == 0) { //close socket if open
429 j = close (rs->socket);
430 if (j > 0) {
431 factPrintf(kFatal, 771, "Closing socket %d failed: %m (close,rc=%d)", sid, errno);
432 } else {
433 factPrintf(kInfo, 771, "Succesfully closed socket %d", sid);
434 }
435 }
436
437 rs->sockStat = 99;
438
439 if (flag < 0) {
440 free (rs->rBuf); //and never open again
441 rs->rBuf = NULL;
442 return 0;
443 }
444
445
446 if (flag == 0) { //generate address and buffer ...
447 rs->Port = port;
448 rs->SockAddr.sin_family = sockAddr->sin_family;
449 rs->SockAddr.sin_port = htons (port);
450 rs->SockAddr.sin_addr = sockAddr->sin_addr;
451
452 rs->rBuf = (CNV_FACT*)malloc (sizeof (CNV_FACT));
453 if (rs->rBuf == NULL) {
454 factPrintf(kFatal, 774, "Could not create local buffer %d (malloc failed)", sid);
455 rs->sockStat = 77;
456 return -3;
457 }
458 }
459
460
461 if ((rs->socket = socket (PF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) <= 0) {
462 factPrintf(kFatal, 773, "Generating socket %d failed: %m (socket,rc=%d)", sid, errno);
463 rs->sockStat = 88;
464 return -2;
465 }
466 optval = 1;
467 if (setsockopt (rs->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
468 factPrintf(kInfo, 173, "Setting SO_KEEPALIVE for socket %d failed: %m (setsockopt,rc=%d)", sid, errno);
469 }
470 optval = 10; //start after 10 seconds
471 if (setsockopt (rs->socket, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) {
472 factPrintf(kInfo, 173, "Setting TCP_KEEPIDLE for socket %d failed: %m (setsockopt,rc=%d)", sid, errno);
473 }
474 optval = 10; //do every 10 seconds
475 if (setsockopt (rs->socket, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) {
476 factPrintf(kInfo, 173, "Setting TCP_KEEPINTVL for socket %d failed: %m (setsockopt,rc=%d)", sid, errno);
477 }
478 optval = 2; //close after 2 unsuccessful tries
479 if (setsockopt (rs->socket, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) {
480 factPrintf(kInfo, 173, "Setting TCP_KEEPCNT for socket %d failed: %m (setsockopt,rc=%d)", sid, errno);
481 }
482
483 factPrintf(kInfo, 773, "Successfully generated socket %d", sid);
484
485 rs->sockStat = -1; //try to (re)open socket
486 rs->errCnt = 0;
487 return 0;
488
489} /*-----------------------------------------------------------------*/
490
491 /*-----------------------------------------------------------------*/
492
493
494
495
496int
497mBufInit ()
498{
499// initialize mBuffer (mark all entries as unused\empty)
500
501 //uint32_t actime = g_actTime + 50000000;
502
503 for (int i = 0; i < MAX_EVT * MAX_RUN; i++) {
504 evtCtrl[i].evNum = evtCtrl[i].nRoi = -1;
505 evtCtrl[i].runNum = 0;
506
507 //evtCtrl[i].mBuffer_idx = -1;
508 evtCtrl[i].evtStat = -1;
509
510#ifdef ETIENNE_MALLOC
511 //ETIENNE
512 mBufferMapping[i].chunk = -1;
513 mBufferMapping[i].eventNumber = -1;
514 mBufferMapping[i].slot = -1;
515 //END ETIENNE
516#endif
517 }
518#ifdef ETIENNE_MALLOC
519 for (int j=0;j<MAX_CHUNKS;j++)
520 EtiMemoryChunks[j].pointers[0] = NULL;
521#endif
522
523 //actRun.FADhead = malloc (NBOARDS * sizeof (PEVNT_HEADER));
524
525 evtCtrl_frstPtr = 0;
526 evtCtrl_lastPtr = 0;
527
528 return 0;
529
530} /*-----------------------------------------------------------------*/
531
532int checkRoiConsistency(int i, int roi[]);
533
534int mBufEvt(int sk)
535{
536// generate a new Event into mBuffer:
537// make sure only complete Event are possible, so 'free' will always work
538// returns index into mBuffer[], or negative value in case of error
539// error: <-9000 if roi screwed up (not consistent with run)
540// <-8000 (not consistent with event)
541// <-7000 (not consistent with board)
542// < 0 if no space left
543
544// int evFree;
545// int headmem = 0;
546// size_t needmem = 0;
547
548 int nRoi[9];
549 if (!checkRoiConsistency(sk, nRoi))
550 return -9999;
551
552 //const int b = sk / 7;
553
554 const int evID = rd[sk].evtID;
555 const uint runID = rd[sk].runID;
556 const int trgTyp = rd[sk].ftmTyp;
557 const int trgNum = rd[sk].ftmID;
558 const int fadNum = rd[sk].evtID;
559
560 int beg = (evtCtrl_lastPtr + MAX_EVT*MAX_RUN - 1) % (MAX_EVT*MAX_RUN);
561 int end = (evtCtrl_frstPtr + MAX_EVT*MAX_RUN - 1) % (MAX_EVT*MAX_RUN);
562
563 for (int k=beg; k!=end; k--, k += MAX_EVT*MAX_RUN, k %= MAX_EVT*MAX_RUN)
564 {
565 // If the run is different, go on searching.
566 // We cannot stop searching if a lower run-id is found as in
567 // the case of the events, because theoretically, there
568 // can be the same run on two different days.
569 if (runID != evtCtrl[k].runNum)
570 continue;
571
572 // The event in the control structure has an event id with
573 // a lower event id than the current one. All previous events
574 // should have an even lower event id, so there is no way it
575 // can be found in the structure.
576 if (evtCtrl[k].evNum < evID/* && runID == evtCtrl[k].runNum*/)
577 break;
578
579 if (evID != evtCtrl[k].evNum/* || runID != evtCtrl[k].runNum*/)
580 continue;
581
582 // is it ok ????
583 if (evtCtrl[k].nRoi != nRoi[0] || evtCtrl[k].nRoiTM != nRoi[8])
584 {
585 factPrintf(kError, 821, "Mismatch of roi within event. Expected roi=%d and roi_tm=%d, got %d and %d.",
586 evtCtrl[k].nRoi, evtCtrl[k].nRoiTM, nRoi[0], nRoi[8]);
587 return -8201;
588 }
589
590 // count for inconsistencies
591 if (evtCtrl[k].trgNum != trgNum)
592 evtCtrl[k].Errors[0]++;
593 if (evtCtrl[k].fadNum != fadNum)
594 evtCtrl[k].Errors[1]++;
595 if (evtCtrl[k].trgTyp != trgTyp)
596 evtCtrl[k].Errors[2]++;
597
598 //everything seems fine so far ==> use this slot ....
599 return k;
600 }
601
602 //event does not yet exist; create it
603
604 if (end-beg==1 || (end==0 && beg==MAX_EVT*MAX_RUN-1)) //no space available in ctrl
605 {
606 factPrintf(kError, 881, "No control slot to keep event %d (run %d) %d %d", evID, runID, beg, end);
607 return -1;
608 }
609
610 // FIXME: This should be the time of the first receiped board
611 struct timeval tv;
612 gettimeofday (&tv, NULL);
613
614 const uint32_t tsec = tv.tv_sec;
615 const uint32_t tusec = tv.tv_usec;
616
617 //check if runId already registered in runCtrl
618
619 uint oldest = g_actTime + 1000;
620 int jold = -1;
621
622 int found = 0;
623
624 // fileId==-2: not yet used or run assigned but not open
625 // fileId== 0: file open
626 // fileId>0: run closed
627
628 for (int k=0; k<MAX_RUN; k++)
629 {
630 // Check if run already registered (old entries should have runId==-1)
631 if (runCtrl[k].runId == runID)
632 {
633 // FIXME: Compare to previous event
634 if (runCtrl[k].roi0 != nRoi[0] || runCtrl[k].roi8 != nRoi[8])
635 {
636 factPrintf(kError, 931, "Mismatch of roi within run. Expected roi=%d and roi_tm=%d, got %d and %d (runID=%d, evID=%d)",
637 runCtrl[k].roi0, runCtrl[k].roi8, nRoi[0], nRoi[8], runID, evID);
638 return -9301;
639 }
640
641 found = 1;
642 break;
643 }
644
645 // This is just for sanity. We use the oldest free entry (until
646 // we have understood the concept and can use "just" a free entry
647 if (runCtrl[k].runId==0 && runCtrl[k].closeTime < oldest)
648 {
649 oldest = runCtrl[k].closeTime;
650 jold = k;
651 }
652 }
653
654 if (!found) // Run not yet registered, register run
655 {
656 if (jold < 0)
657 {
658 factPrintf(kFatal, 883, "Not able to register the new run %d", runID);
659 return -1001;
660 }
661
662 int evFree = jold;
663
664 factPrintf(kInfo, 503, "New run %d (evID=%d, evFree=%d) registered with roi=%d and roi_tm=%d",
665 runID, evID, evFree, nRoi[0], nRoi[8]);
666
667 runCtrl[evFree].runId = runID;
668 runCtrl[evFree].roi0 = nRoi[0]; // FIXME: Make obsolete!
669 runCtrl[evFree].roi8 = nRoi[8]; // FIXME: Make obsolete!
670 runCtrl[evFree].fileId = -2;
671 runCtrl[evFree].procId = -2;
672 runCtrl[evFree].lastEvt = 1; // Number of events partially started to read
673 runCtrl[evFree].actEvt = 0; // Number of written events (write)
674 runCtrl[evFree].procEvt = 0; // Number of successfully checked events (checkEvent)
675 runCtrl[evFree].maxEvt = 999999999; // max number events allowed
676 runCtrl[evFree].lastTime = tsec; // Time when the last event was written
677 runCtrl[evFree].closeTime = tsec + 3600 * 24; //max time allowed
678 }
679
680 const int k = evtCtrl_lastPtr;
681
682 //flag all boards as unused
683 evtCtrl[k].nBoard = 0;
684 for (int b=0; b<NBOARDS; b++)
685 evtCtrl[k].board[b] = -1;
686
687 evtCtrl[k].pcTime[0] = tsec;
688 evtCtrl[k].pcTime[1] = tusec;
689 evtCtrl[k].nRoi = nRoi[0];
690 evtCtrl[k].nRoiTM = nRoi[8];
691 evtCtrl[k].evNum = evID;
692 evtCtrl[k].runNum = runID;
693 evtCtrl[k].fadNum = fadNum;
694 evtCtrl[k].trgNum = trgNum;
695 evtCtrl[k].trgTyp = trgTyp;
696 evtCtrl[k].Errors[0] = 0;
697 evtCtrl[k].Errors[1] = 0;
698 evtCtrl[k].Errors[2] = 0;
699 evtCtrl[k].Errors[3] = 0;
700 evtCtrl[k].fEvent = NULL;
701 evtCtrl[k].FADhead = NULL;
702
703 evtCtrl[k].evtStat = 0;
704
705 // This is dangerous, because theoretically, it can result is
706 // acessing invalid memory in another thread if this is split
707 // in two instructions. Must be done only _after_ the contents
708 // have been initialized
709 evtCtrl_lastPtr = (evtCtrl_lastPtr+1) % MAX_EVT * MAX_RUN;
710
711 return k;
712
713} /*-----------------------------------------------------------------*/
714
715
716void initEvent(int i)
717{
718 evtCtrl[i].fEvent = (EVENT*)((char*)evtCtrl[i].FADhead+MAX_HEAD_MEM);
719 memset(evtCtrl[i].fEvent->Adc_Data, 0, (NPIX+NTMARK)*2*evtCtrl[i].nRoi);
720
721 //flag all pixels as unused
722 for (int k = 0; k < NPIX; k++)
723 evtCtrl[i].fEvent->StartPix[k] = -1;
724
725 //flag all TMark as unused
726 for (int k = 0; k < NTMARK; k++)
727 evtCtrl[i].fEvent->StartTM[k] = -1;
728
729 evtCtrl[i].fEvent->NumBoards = 0;
730 evtCtrl[i].fEvent->PCTime = evtCtrl[i].pcTime[0];
731 evtCtrl[i].fEvent->PCUsec = evtCtrl[i].pcTime[1];
732}
733
734
735int
736mBufFree (int i)
737{
738//delete entry [i] from mBuffer:
739//(and make sure multiple calls do no harm ....)
740
741// int headmem = 0;
742// size_t freemem = 0;
743
744#ifdef ETIENNE_MALLOC
745 int evid;
746 evid = mBuffer[i].evNum;
747 ETI_Free(evid, i);
748#endif
749
750// freemem = mBuffer[i].evtLen;
751 //ETIENNE
752#ifdef THOMAS_MALLOC
753 TGB_free(evtCtrl[i].FADhead);
754#endif
755
756#ifdef STANDARD_MALLOC
757 free (mBuffer[i].FADhead);
758#endif
759
760// free (mBuffer[i].fEvent);
761 evtCtrl[i].fEvent = NULL;
762
763// free (mBuffer[i].FADhead);
764 evtCtrl[i].FADhead = NULL;
765
766// free (mBuffer[i].buffer);
767// mBuffer[i].buffer = NULL;
768//END ETIENNE
769// headmem = NBOARDS * sizeof (PEVNT_HEADER);
770 evtCtrl[i].evNum = evtCtrl[i].nRoi = -1;
771 evtCtrl[i].runNum = 0;
772
773#ifdef ETIENNE_MALLOC
774//ETIENNE
775// gj.usdMem = gj.usdMem - freemem - headmem - gi_maxSize;
776 gj.usdMem = 0;
777 for (int k=0;k<numAllocatedChunks;k++)
778 {
779 gj.usdMem += EtiMemoryChunks[k].nSlots * MAX_SLOT_SIZE;
780 }
781//END ETIENNE
782#endif
783
784#ifdef THOMAS_MALLOC
785 gj.usdMem = tgb_inuse;
786#endif
787
788 gj.bufTot--;
789
790 /*if (gi_memStat < 0) {
791 if (gj.usdMem <= 0.75 * gj.maxMem)
792 gi_memStat = +1;
793 }*/
794
795 return 0;
796
797} /*-----------------------------------------------------------------*/
798
799/*
800void
801resetEvtStat ()
802{
803 for (int i = 0; i < MAX_SOCK; i++)
804 gi.numRead[i] = 0;
805
806 for (int i = 0; i < NBOARDS; i++) {
807 gi.gotByte[i] = 0;
808 gi.gotErr[i] = 0;
809
810 }
811
812 gi.evtGet = 0; //#new Start of Events read
813 gi.evtTot = 0; //#complete Events read
814 gi.evtErr = 0; //#Events with Errors
815 gi.evtSkp = 0; //#Events incomplete (timeout)
816
817 gi.procTot = 0; //#Events processed
818 gi.procErr = 0; //#Events showed problem in processing
819 gi.procTrg = 0; //#Events accepted by SW trigger
820 gi.procSkp = 0; //#Events rejected by SW trigger
821
822 gi.feedTot = 0; //#Events used for feedBack system
823 gi.feedErr = 0; //#Events rejected by feedBack
824
825 gi.wrtTot = 0; //#Events written to disk
826 gi.wrtErr = 0; //#Events with write-error
827
828 gi.runOpen = 0; //#Runs opened
829 gi.runClose = 0; //#Runs closed
830 gi.runErr = 0; //#Runs with open/close errors
831
832 return;
833}*/ /*-----------------------------------------------------------------*/
834
835void reportIncomplete(int id)
836{
837 factPrintf(kWarn, 601, "%5d skip incomplete evt %8d",
838 evtCtrl[id].evNum, id);
839
840 uint64_t report = 0;
841
842 char str[1000];
843
844 int ik=0;
845 for (int ib=0; ib<NBOARDS; ib++)
846 {
847 if (ib%10==0)
848 str[ik++] = '|';
849
850 const int jb = evtCtrl[id].board[ib];
851 if (jb>=0) // data received from that board
852 {
853 str[ik++] = '0'+(jb%10);
854 continue;
855 }
856
857 // FIXME: Is that really 'b' or should that be 'ib' ?
858 if (gi_NumConnect[ib]<=0) // board not connected
859 {
860 str[ik++] = 'x';
861 continue;
862 }
863
864 // data from this board lost
865 str[ik++] = '.';
866 report |= ((uint64_t)1)<<ib;
867 }
868
869 str[ik++] = '|';
870 str[ik] = 0;
871
872 factOut(kWarn, 601, str);
873
874 factReportIncomplete(report);
875}
876
877int checkRoiConsistency(int i, int roi[])
878{
879 int xjr = -1;
880 int xkr = -1;
881
882 //points to the very first roi
883 int roiPtr = sizeof(PEVNT_HEADER)/2 + 2;
884
885 roi[0] = ntohs(rd[i].rBuf->S[roiPtr]);
886
887 for (int jr = 0; jr < 9; jr++)
888 {
889 roi[jr] = ntohs(rd[i].rBuf->S[roiPtr]);
890
891 if (roi[jr]<0 || roi[jr]>1024)
892 {
893 factPrintf(kError, 999, "Illegal roi in channel %d (allowed: 0<=roi<=1024)", jr, roi[jr]);
894 return 0;
895 }
896
897 // Check that the roi of pixels jr are compatible with the one of pixel 0
898 if (jr!=8 && roi[jr]!=roi[0])
899 {
900 xjr = jr;
901 break;
902 }
903
904 // Check that the roi of all other DRS chips on boards are compatible
905 for (int kr = 1; kr < 4; kr++)
906 {
907 const int kroi = ntohs(rd[i].rBuf->S[roiPtr]);
908 if (kroi != roi[jr])
909 {
910 xjr = jr;
911 xkr = kr;
912 break;
913 }
914 roiPtr += kroi+4;
915 }
916 }
917
918 if (xjr>=0)
919 {
920 if (xkr<0)
921 factPrintf(kFatal, 1, "Inconsistent Roi accross chips [DRS=%d], expected %d, got %d", xjr, roi[0], roi[xjr]);
922 else
923 factPrintf(kFatal, 1, "Inconsistent Roi accross channels [DRS=%d Ch=%d], expected %d, got %d", xjr, xkr, roi[xjr], ntohs(rd[i].rBuf->S[roiPtr]));
924
925 return 0;
926 }
927
928 //const int b = i / 7;
929
930/*
931 if (roi[0]<0 || roi[0] > 1024)
932 {
933 factPrintf(kError, 999, "Illegal roi in channel 0: %d (allowed: 0<=roi<=1024)", roi[0]);
934 gj.badRoiR++;
935 gj.badRoi[b]++;
936 return 0;
937 }
938 */
939 /*
940 for (int jr = 1; jr < 8; jr++)
941 {
942 if (roi[jr] != roi[0])
943 {
944 factPrintf(kError, 711, "Mismatch of roi (%d) in channel %d with roi (%d) in channel 0.", roi[jr], jr, roi[0]);
945 gj.badRoiB++;
946 gj.badRoi[b]++;
947 return 0;
948 }
949 }
950*/
951 if (roi[8] < roi[0])
952 {
953 factPrintf(kError, 712, "Mismatch of roi (%d) in channel 8. Should be larger or equal than the roi (%d) in channel 0.", roi[8], roi[0]);
954 //gj.badRoiB++;
955 //gj.badRoi[b]++;
956 return 0;
957 }
958
959 return 1;
960}
961
962void swapEventHeaderBytes(int i)
963{
964 //End of the header. to channels now
965 int eStart = 36;
966 for (int ePatchesCount = 0; ePatchesCount<4*9;ePatchesCount++)
967 {
968 rd[i].rBuf->S[eStart+0] = ntohs(rd[i].rBuf->S[eStart+0]);//id
969 rd[i].rBuf->S[eStart+1] = ntohs(rd[i].rBuf->S[eStart+1]);//start_cell
970 rd[i].rBuf->S[eStart+2] = ntohs(rd[i].rBuf->S[eStart+2]);//roi
971 rd[i].rBuf->S[eStart+3] = ntohs(rd[i].rBuf->S[eStart+3]);//filling
972
973 eStart += 4+rd[i].rBuf->S[eStart+2];//skip the pixel data
974 }
975}
976
977void copyData(int i, int evID, /*int roi,*/ int boardId)
978{
979 swapEventHeaderBytes(i);
980
981 memcpy(&evtCtrl[evID].FADhead[boardId].start_package_flag,
982 &rd[i].rBuf->S[0], sizeof(PEVNT_HEADER));
983
984 int src = sizeof(PEVNT_HEADER) / 2;
985
986 // consistency of ROIs have been checked already (is it all correct?)
987 const int roi = rd[i].rBuf->S[src+2];
988
989 // different sort in FAD board.....
990 for (int px = 0; px < 9; px++)
991 {
992 for (int drs = 0; drs < 4; drs++)
993 {
994 // pixH = rd[i].rBuf->S[src++]; // ID
995 src++;
996
997 const int pixC = rd[i].rBuf->S[src++]; // start-cell
998 const int pixR = rd[i].rBuf->S[src++]; // roi
999 //here we should check if pixH is correct ....
1000
1001 const int pixS = boardId * 36 + drs * 9 + px;
1002 src++;
1003
1004 evtCtrl[evID].fEvent->StartPix[pixS] = pixC;
1005
1006 const int dest1 = pixS * roi;
1007 memcpy(&evtCtrl[evID].fEvent->Adc_Data[dest1],
1008 &rd[i].rBuf->S[src], roi * 2);
1009
1010 src += pixR;
1011
1012 if (px == 8)
1013 {
1014 const int tmS = boardId * 4 + drs;
1015
1016 //and we have additional TM info
1017 if (pixR > roi)
1018 {
1019 const int dest2 = tmS * roi + NPIX * roi;
1020
1021 const int srcT = src - roi;
1022 evtCtrl[evID].fEvent->StartTM[tmS] = (pixC + pixR - roi) % 1024;
1023
1024 memcpy(&evtCtrl[evID].fEvent->Adc_Data[dest2],
1025 &rd[i].rBuf->S[srcT], roi * 2);
1026 }
1027 else
1028 {
1029 evtCtrl[evID].fEvent->StartTM[tmS] = -1;
1030
1031 //ETIENNE because the TM channels are always processed during drs calib,
1032 //set them to zero if they are not present
1033 //I suspect that it may be more efficient to set all the allocated mem to
1034 //zero when allocating it
1035 // dest = tmS*roi[0] + NPIX*roi[0];
1036 // bzero(&mBuffer[evID].fEvent->Adc_Data[dest],roi[0]*2);
1037 }
1038 }
1039 }
1040 }
1041}
1042
1043
1044void
1045initReadFAD ()
1046{
1047 return;
1048} /*-----------------------------------------------------------------*/
1049
1050//struct rnd
1051//{
1052// int val;
1053// int idx;
1054//};
1055//
1056//struct rnd random_arr[MAX_SOCK];
1057//
1058//int compare(const void *f1, const void *f2)
1059//{
1060// struct rnd *r1 = (struct rnd*)f1;
1061// struct rnd *r2 = (struct rnd*)f2;
1062// return r1->val - r2->val;
1063//}
1064
1065
1066void *readFAD (void *ptr)
1067{
1068/* *** main loop reading FAD data and sorting them to complete events */
1069
1070 factPrintf(kInfo, -1, "Start initializing (readFAD)");
1071
1072// int cpu = 7; //read thread
1073// cpu_set_t mask;
1074
1075/* CPU_ZERO initializes all the bits in the mask to zero. */
1076// CPU_ZERO (&mask);
1077/* CPU_SET sets only the bit corresponding to cpu. */
1078// cpu = 7;
1079// CPU_SET (cpu, &mask);
1080
1081/* sched_setaffinity returns 0 in success */
1082// if (sched_setaffinity (0, sizeof (mask), &mask) == -1) {
1083// snprintf (str, MXSTR, "W ---> can not create affinity to %d", cpu);
1084// factOut (kWarn, -1, str);
1085// }
1086
1087
1088 const int minLen = sizeof(PEVNT_HEADER); //min #bytes needed to check header: full header for debug
1089
1090 start.S = 0xFB01;
1091 stop.S = 0x04FE;
1092
1093/* initialize run control logics */
1094 for (int i = 0; i < MAX_RUN; i++) {
1095 runCtrl[i].runId = 0;
1096 runCtrl[i].fileId = -2;
1097 runCtrl[i].procId = -2;
1098 }
1099 gi_resetS = gi_resetR = 9;
1100
1101 int sockDef[NBOARDS]; //internal state of sockets
1102 memset(sockDef, 0, NBOARDS*sizeof(int));
1103
1104 START:
1105 evtCtrl_frstPtr = 0;
1106 evtCtrl_lastPtr = 0;
1107
1108 //time in seconds
1109 uint gi_SecTime = time(NULL);;
1110
1111 const int cntsock = 8 - NUMSOCK ;
1112
1113 if (gi_resetS > 0) {
1114 //make sure all sockets are preallocated as 'not exist'
1115 for (int i = 0; i < MAX_SOCK; i++) {
1116 rd[i].socket = -1;
1117 rd[i].sockStat = 99;
1118 }
1119
1120 for (int k = 0; k < NBOARDS; k++) {
1121 gi_NumConnect[k] = 0;
1122 //gi.numConn[k] = 0;
1123 gj.numConn[k] = 0;
1124 //gj.errConn[k] = 0;
1125 gj.rateBytes[k] = 0;
1126 gj.totBytes[k] = 0;
1127 }
1128
1129 }
1130
1131
1132 if (gi_resetR > 0) {
1133 //resetEvtStat ();
1134 gj.bufTot = gj.maxEvt = gj.xxxEvt = 0;
1135 gj.usdMem = gj.maxMem = gj.xxxMem = 0;
1136#ifdef THOMAS_MALLOC
1137 gj.totMem = tgb_memory;
1138#else
1139 gj.totMem = g_maxMem;
1140#endif
1141 gj.bufNew = gj.bufEvt = 0;
1142 //gj.badRoiE = gj.badRoiR = gj.badRoiB = 0;
1143 gj.evtSkip = gj.evtWrite = gj.evtErr = 0;
1144
1145 //for (int b = 0; b < NBOARDS; b++)
1146 // gj.badRoi[b] = 0;
1147
1148 mBufInit (); //initialize buffers
1149
1150 factPrintf(kInfo, -1, "End initializing (readFAD)");
1151 }
1152
1153
1154 gi_reset = gi_resetR = gi_resetS = gi_resetW = 0;
1155
1156 //loop until global variable g_runStat claims stop
1157 while (g_runStat >= 0 && g_reset == 0)
1158 {
1159 gi_runStat = g_runStat;
1160 gj.readStat = g_runStat;
1161
1162 struct timeval tv;
1163 gettimeofday (&tv, NULL);
1164 g_actTime = tv.tv_sec;
1165 g_actUsec = tv.tv_usec;
1166
1167
1168 for (int b = 0; b < NBOARDS; b++)
1169 {
1170 // Nothing has changed
1171 if (g_port[b].sockDef == sockDef[b])
1172 continue;
1173
1174 gi_NumConnect[b] = 0; //must close all connections
1175 //gi.numConn[b] = 0;
1176 gj.numConn[b] = 0;
1177
1178 // s0 = 0: sockets to be defined and opened
1179 // s0 = -1: sockets to be destroyed
1180 // s0 = +1: sockets to be closed and reopened
1181
1182 int s0 = 0;
1183 if (sockDef[b] != 0)
1184 s0 = g_port[b].sockDef==0 ? -1 : +1;
1185
1186 const int p0 = s0==0 ? ntohs (g_port[b].sockAddr.sin_port) : 0;
1187
1188 int k = b * 7;
1189 for (int p = p0 + 1; p < p0 + 8; p++, k++)
1190 GenSock (s0, k, p, &g_port[b].sockAddr, &rd[k]); //generate address and socket
1191
1192 sockDef[b] = g_port[b].sockDef;
1193 }
1194
1195 // count the number of active boards
1196 int actBoards = 0;
1197 for (int b = 0; b < NBOARDS; b++)
1198 if (sockDef[b] > 0)
1199 actBoards++;
1200
1201 //count number of succesfull actions
1202// int numok = 0;
1203
1204/*
1205 for (i=0; i<MAX_SOCK/7; i++)
1206 {
1207 random_arr[i].val = rand();
1208 random_arr[i].idx = i;
1209 }
1210
1211 qsort(random_arr, MAX_SOCK/7, sizeof(struct rnd), compare);
1212
1213 for (int iii = 0; iii < MAX_SOCK/7; iii++) { //check all sockets if something to read
1214
1215 b = random_arr[iii].idx;
1216 i = b*7;
1217 p = 0;
1218 */
1219
1220 //check all sockets if something to read
1221 for (int i = 0; i < MAX_SOCK; i+=7)
1222 {
1223 // Do not try to connect this socket
1224 if (rd[i].sockStat > 0)
1225 continue;
1226
1227 const int board = i / 7 ;
1228 //const int p = i % 7 ;
1229
1230 if (rd[i].sockStat == -1)
1231 {
1232 //try to connect if not yet done
1233 rd[i].sockStat = connect (rd[i].socket,
1234 (struct sockaddr *) &rd[i].SockAddr,
1235 sizeof (rd[i].SockAddr));
1236 // Failed
1237 if (rd[i].sockStat == -1)
1238 {
1239 rd[i].errCnt++;
1240 usleep(25000);
1241 continue;
1242 }
1243
1244 // Success (rd[i].sockStat == 0)
1245
1246 if (sockDef[board] > 0)
1247 {
1248 rd[i].bufTyp = 0; // expect a header
1249 rd[i].bufLen = sizeof(PEVNT_HEADER); // max size to read at begining
1250 }
1251 else
1252 {
1253 rd[i].bufTyp = -1; // full data to be skipped
1254 rd[i].bufLen = MAX_LEN; // huge for skipping
1255 }
1256
1257 rd[i].bufPos = 0; // no byte read so far
1258 rd[i].skip = 0; // start empty
1259
1260 gi_NumConnect[board] += cntsock;
1261
1262 //gi.numConn[b]++;
1263 gj.numConn[board]++;
1264
1265 factPrintf(kInfo, -1, "New connection %d (number of connections: %d)", board, gj.numConn[board]);
1266 }
1267
1268 // Do not read from this socket
1269 if (rd[i].bufLen<0)
1270 continue;
1271
1272 //numok++;
1273
1274 if (rd[i].bufLen>0)
1275 {
1276 const int32_t jrd =
1277 recv(rd[i].socket, &rd[i].rBuf->B[rd[i].bufPos],
1278 rd[i].bufLen, MSG_DONTWAIT);
1279
1280 // recv failed
1281 if (jrd<0)
1282 {
1283 // There was just nothing waiting
1284 if (errno==EWOULDBLOCK || errno==EAGAIN)
1285 {
1286 //numok--;
1287 continue;
1288 }
1289
1290 factPrintf(kError, 442, "Reading from socket %d failed: %m (recv,rc=%d)", i, errno);
1291 //gi.gotErr[b]++;
1292 continue;
1293 }
1294
1295 // connection was closed ...
1296 if (jrd==0)
1297 {
1298 factPrintf(kInfo, 441, "Socket %d closed by FAD", i);
1299
1300 const int s0 = sockDef[board] > 0 ? +1 : -1;
1301 GenSock(s0, i, 0, NULL, &rd[i]);
1302
1303 //gi.gotErr[b]++;
1304
1305 gi_NumConnect[board]-= cntsock ;
1306 //gi.numConn[b]--;
1307 gj.numConn[board]--;
1308
1309 continue;
1310 }
1311 // Success (jrd > 0)
1312
1313 gj.rateBytes[board] += jrd;
1314
1315 // are we skipping this board ...
1316 if (rd[i].bufTyp < 0)
1317 continue;
1318
1319 rd[i].bufPos += jrd; //==> prepare for continuation
1320 rd[i].bufLen -= jrd;
1321
1322#ifdef EVTDEBUG
1323 debugRead(i, jrd, rd[i].evtID, rd[i].ftmID, rd[i].runID, rd[i].bufTyp, tv.tv_sec, tv.tv_usec); // i=socket; jrd=#bytes; ievt=eventid; 1=finished event
1324#endif
1325 }
1326
1327 //we are reading event header
1328 if (rd[i].bufTyp <= 0)
1329 {
1330 //not yet sufficient data to take action
1331 if (rd[i].bufPos < minLen)
1332 continue;
1333
1334 //check if startflag correct; else shift block ....
1335 // FIXME: This is not enough... this combination of
1336 // bytes can be anywhere... at least the end bytes
1337 // must be checked somewhere, too.
1338 int k;
1339 for (k = 0; k < rd[i].bufPos - 1; k++)
1340 {
1341 if (rd[i].rBuf->B[k] == start.B[1] && rd[i].rBuf->B[k+1] == start.B[0])
1342 break;
1343 }
1344 rd[i].skip += k;
1345
1346 //no start of header found
1347 if (k >= rd[i].bufPos - 1)
1348 {
1349 rd[i].bufPos = 0;
1350 rd[i].bufLen = sizeof(PEVNT_HEADER);
1351 continue;
1352 }
1353
1354 if (k > 0)
1355 {
1356 rd[i].bufPos -= k;
1357 rd[i].bufLen += k;
1358 memmove (&rd[i].rBuf->B[0], &rd[i].rBuf->B[k],
1359 rd[i].bufPos);
1360 }
1361
1362 if (rd[i].bufPos < minLen)
1363 continue;
1364
1365 if (rd[i].skip > 0)
1366 {
1367 factPrintf(kInfo, 666, "Skipped %d bytes on port %d", rd[i].skip, i);
1368 rd[i].skip = 0;
1369 }
1370
1371 // TGB: This needs much more checks than just the first two bytes!
1372
1373 // Swap everything except start_package_flag.
1374 // It is to difficult to find out where it is used how,
1375 // but it doesn't really matter because it is not really
1376 // used anywehere else
1377 // rd[i].rBuf->S[1] = ntohs(rd[i].rBuf->S[1]); // package_length
1378 rd[i].rBuf->S[2] = ntohs(rd[i].rBuf->S[2]); // version_no
1379 rd[i].rBuf->S[3] = ntohs(rd[i].rBuf->S[3]); // PLLLCK
1380 rd[i].rBuf->S[4] = ntohs(rd[i].rBuf->S[4]); // trigger_crc
1381 rd[i].rBuf->S[5] = ntohs(rd[i].rBuf->S[5]); // trigger_type
1382
1383 rd[i].rBuf->S[12] = ntohs(rd[i].rBuf->S[12]); // board id
1384 rd[i].rBuf->S[13] = ntohs(rd[i].rBuf->S[13]); // adc_clock_phase_shift
1385 rd[i].rBuf->S[14] = ntohs(rd[i].rBuf->S[14]); // number_of_triggers_to_generate
1386 rd[i].rBuf->S[15] = ntohs(rd[i].rBuf->S[15]); // trigger_generator_prescaler
1387
1388 rd[i].rBuf->I[3] = ntohl(rd[i].rBuf->I[3]); // trigger_id
1389 rd[i].rBuf->I[4] = ntohl(rd[i].rBuf->I[4]); // fad_evt_counter
1390 rd[i].rBuf->I[5] = ntohl(rd[i].rBuf->I[5]); // REFCLK_frequency
1391
1392 rd[i].rBuf->I[10] = ntohl(rd[i].rBuf->I[10]); // runnumber;
1393 rd[i].rBuf->I[11] = ntohl(rd[i].rBuf->I[11]); // time;
1394
1395 for (int s=24;s<24+NTemp+NDAC;s++)
1396 rd[i].rBuf->S[s] = ntohs(rd[i].rBuf->S[s]); // drs_temperature / dac
1397
1398 rd[i].fadLen = ntohs(rd[i].rBuf->S[1]) * 2;
1399 rd[i].fadVers = rd[i].rBuf->S[2];
1400 rd[i].ftmTyp = rd[i].rBuf->S[5];
1401 rd[i].ftmID = rd[i].rBuf->I[3]; //(FTMevt)
1402 rd[i].evtID = rd[i].rBuf->I[4]; //(FADevt)
1403 rd[i].runID = rd[i].rBuf->I[11]==0 ? (int)g_actTime : rd[i].rBuf->I[11];
1404 rd[i].bufTyp = 1; //ready to read full record
1405 rd[i].bufLen = rd[i].fadLen - rd[i].bufPos;
1406
1407 const int fadBoard = rd[i].rBuf->S[12];
1408 debugHead(i, fadBoard, rd[i].rBuf);
1409
1410 continue;
1411 }
1412
1413 // are we reading data
1414
1415 // not yet all read
1416 if (rd[i].bufLen > 0)
1417 continue;
1418
1419 if (rd[i].rBuf->B[rd[i].fadLen - 1] != stop.B[0] ||
1420 rd[i].rBuf->B[rd[i].fadLen - 2] != stop.B[1])
1421 {
1422 //gi.evtErr++;
1423 factPrintf(kError, 301, "End-of-event flag wrong on socket %3d for event %4d (len=%5d), expected %3d %3d, got %3d %3d",
1424 i, rd[i].evtID, rd[i].fadLen, stop.B[0], stop.B[1],
1425 rd[i].rBuf->B[rd[i].fadLen - 1], rd[i].rBuf->B[rd[i].fadLen - 2]);
1426
1427 // ready to read next header
1428 rd[i].bufTyp = 0;
1429 rd[i].bufLen = sizeof(PEVNT_HEADER);
1430 rd[i].bufPos = 0;
1431
1432 continue;
1433 }
1434
1435 // int actid;
1436 // if (g_useFTM > 0)
1437 // actid = rd[i].evtID;
1438 // else
1439 // actid = rd[i].ftmID;
1440
1441 //get index into mBuffer for this event (create if needed)
1442 const int evID = mBufEvt(i);
1443
1444 // no free entry in mBuffer, retry later
1445 if (evID == -1)
1446 continue;
1447
1448 // We have a valid entry, but no memory has yet been allocated
1449 if (evID >= 0 && evtCtrl[evID].FADhead == NULL)
1450 {
1451 // Try to get memory from the big buffer
1452 evtCtrl[evID].FADhead = (PEVNT_HEADER*)TGB_Malloc();
1453 if (evtCtrl[evID].FADhead == NULL)
1454 {
1455 // If this works properly, this is a hack which can be removed, or
1456 // replaced by a signal or dim message
1457 if (rd[i].bufTyp==2)
1458 factPrintf(kError, 882, "malloc failed for event %d", evID);
1459 rd[i].bufTyp = 2;
1460 continue;
1461 }
1462
1463 // Initialice mBuffer[evID]->fEvent
1464 initEvent(evID);
1465
1466 // Some statistics
1467 gj.usdMem = tgb_inuse;
1468
1469 if (gj.usdMem > gj.maxMem)
1470 gj.maxMem = gj.usdMem;
1471
1472 gj.rateNew++;
1473 gj.bufTot++;
1474 if (gj.bufTot > gj.maxEvt)
1475 gj.maxEvt = gj.bufTot;
1476
1477 //register event in 'active list (reading)'
1478 //mBuffer[evID].evtCtrl_idx = evtCtrl_lastPtr;
1479
1480 //evtCtrl[evtCtrl_lastPtr].mBuffer_idx = evID;
1481 //evtCtrl[evtCtrl_lastPtr].evtStat = 0;
1482 //evtCtrl[evtCtrl.lastPtr].pcTime = g_actTime;
1483
1484 //evtCtrl_lastPtr++;
1485 //evtCtrl_lastPtr %= MAX_EVT * MAX_RUN;
1486 }
1487
1488 // ready to read next header
1489 rd[i].bufTyp = 0;
1490 rd[i].bufLen = sizeof(PEVNT_HEADER);
1491 rd[i].bufPos = 0;
1492
1493 // Fatal error occured. Event cannot be processed. Skip it. Start reading next header.
1494 if (evID < -1000)
1495 continue;
1496
1497 //we have a valid entry in mBuffer[]; fill it
1498 const int fadBoard = rd[i].rBuf->S[12];
1499 const int fadCrate = fadBoard>>8;
1500
1501 if (board != (fadCrate * 10 + (fadBoard&0xff)))
1502 {
1503 factPrintf(kWarn, 301, "Board ID mismatch. Expected %d, got %d (C=%d, B=%d)",
1504 board, fadBoard, fadCrate, fadBoard&0xff);
1505 }
1506
1507 if (evtCtrl[evID].board[board] != -1)
1508 {
1509 factPrintf(kWarn, 501, "Got event %5d from board %3d (i=%3d, len=%5d) twice: Starts with %3d %3d - ends with %3d %3d",
1510 evID, board, i, rd[i].fadLen,
1511 rd[i].rBuf->B[0], rd[i].rBuf->B[1],
1512 rd[i].rBuf->B[rd[i].fadLen - 2],
1513 rd[i].rBuf->B[rd[i].fadLen - 1]);
1514 continue; // Continue reading next header
1515 }
1516
1517 // Copy data from rd[i] to mBuffer[evID]
1518 copyData(i, evID, board);
1519
1520 // now we have stored a new board contents into Event structure
1521
1522 evtCtrl[evID].fEvent->NumBoards++;
1523 evtCtrl[evID].board[board] = board;
1524 evtCtrl[evID].nBoard++;
1525 evtCtrl[evID].evtStat = evtCtrl[evID].nBoard;
1526
1527 // have we already reported first (partial) event of this run ???
1528 if (evtCtrl[evID].nBoard==1 && evtCtrl[evID].runNum != actrun)
1529 {
1530 // Signal the fadctrl that a new run has been started
1531 gotNewRun(evtCtrl[evID].runNum, NULL);
1532
1533 factPrintf(kInfo, 1, "gotNewRun called, prev run %d, new run %d, event %d",
1534 actrun, evtCtrl[evID].runNum, evtCtrl[evID].evNum);
1535
1536 for (int j=0; j<MAX_RUN; j++)
1537 {
1538 // Since we have started a new run, we know already when to close the
1539 // previous run in terms of number of events
1540 if (runCtrl[j].runId==actrun)
1541 runCtrl[j].maxEvt = runCtrl[j].lastEvt;
1542
1543 // We got the first part of this event, so this is
1544 // the number of events we expect for this run
1545 if (runCtrl[j].runId==evtCtrl[evID].runNum)
1546 runCtrl[j].lastEvt++;
1547 }
1548
1549 // Change 'actrun' the the new runnumber
1550 actrun = evtCtrl[evID].runNum;
1551 }
1552
1553 // event not yet complete
1554 if (evtCtrl[evID].nBoard < actBoards)
1555 continue;
1556
1557 // This is a non-ideal hack to lower the probability that
1558 // in mBufEvt the search for correct entry in runCtrl
1559 // will not return a super-old entry
1560 for (int ir=0; ir<MAX_RUN; ir++)
1561 {
1562 if (runCtrl[ir].runId != actrun && runCtrl[ir].fileId>0)
1563 runCtrl[ir].runId = 0;
1564 }
1565
1566 // Flag that the event is ready for processing
1567 evtCtrl[evID].evtStat = 99;
1568
1569 } // end for loop over all sockets
1570
1571 g_actTime = time (NULL);
1572 if (g_actTime <= gi_SecTime)
1573 {
1574 usleep(1);
1575 continue;
1576 }
1577
1578 gi_SecTime = g_actTime;
1579
1580 gj.bufNew = gj.bufEvt = 0;
1581
1582 //loop over all active events and flag those older than read-timeout
1583 //delete those that are written to disk ....
1584 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
1585 {
1586 /*
1587 if (k0==evtCtrl_frstPtr && evtCtrl[k0].evtStat<0)
1588 {
1589 evtCtrl_frstPtr++;
1590 evtCtrl_frstPtr %= MAX_EVT * MAX_RUN;
1591
1592 // Continue because evtCtrl.evtStat[k0] must be <0
1593 continue;
1594 }*/
1595
1596 // Check the more likely case first: incomplete events
1597 if (evtCtrl[k0].evtStat>0 && evtCtrl[k0].evtStat<92)
1598 {
1599 gj.bufNew++; //incomplete event in Buffer
1600
1601 // Event has not yet timed out or was reported already
1602 const int id = k0;//vtCtrl[k0].mBuffer_idx;
1603
1604 if (evtCtrl[k0].evtStat>=90 || evtCtrl[id].pcTime[0]/*evtCtrl[k0].lastRecv*/>=g_actTime - 30)
1605 continue;
1606
1607 reportIncomplete(id);
1608
1609 //timeout for incomplete events
1610 evtCtrl[k0].evtStat = 91;
1611 gj.evtSkip++;
1612
1613 continue;
1614 }
1615
1616 // complete event in Buffer
1617 if (evtCtrl[k0].evtStat >= 95)
1618 gj.bufEvt++;
1619
1620 // Check the less likely case: 'useless' or 'delete'
1621 if (evtCtrl[k0].evtStat==0 || evtCtrl[k0].evtStat >= 9000)
1622 {
1623 const int id = k0;//evtCtrl[k0].mBuffer_idx;
1624#ifdef EVTDEBUG
1625 factPrintf(kDebug, -1, "%5d free event buffer, nb=%3d", evtCtrl[id].evNum, evtCtrl[id].nBoard);
1626#endif
1627 mBufFree (id); //event written--> free memory
1628 evtCtrl[k0].evtStat = -1;
1629
1630 if (k0==evtCtrl_frstPtr)
1631 {
1632 evtCtrl_frstPtr++;
1633 evtCtrl_frstPtr %= MAX_EVT * MAX_RUN;
1634 }
1635 else
1636 factPrintf(kDebug, -1, "Freed a non-first slot");
1637
1638
1639 gj.evtWrite++;
1640 gj.rateWrite++;
1641 }
1642
1643 }
1644
1645 gj.deltaT = 1000; //temporary, must be improved
1646
1647 for (int ib = 0; ib < NBOARDS; ib++)
1648 gj.totBytes[ib] += gj.rateBytes[ib];
1649
1650#ifdef THOMAS_MALLOC
1651 gj.totMem = tgb_memory;
1652#else
1653 gj.totMem = g_maxMem;
1654#endif
1655
1656 if (gj.maxMem > gj.xxxMem)
1657 gj.xxxMem = gj.maxMem;
1658 if (gj.maxEvt > gj.xxxEvt)
1659 gj.xxxEvt = gj.maxEvt;
1660
1661 factStat (gj);
1662 factStatNew (gi);
1663 gj.rateNew = gj.rateWrite = 0;
1664 gj.maxMem = gj.usdMem;
1665 gj.maxEvt = gj.bufTot;
1666 for (int b = 0; b < NBOARDS; b++)
1667 gj.rateBytes[b] = 0;
1668
1669 } // while (g_runStat >= 0 && g_reset == 0)
1670
1671 factPrintf(kInfo, -1, "Stop reading ... RESET=%d", g_reset);
1672
1673 if (g_reset > 0)
1674 {
1675 gi_reset = g_reset;
1676 gi_resetR = gi_reset % 10; //shall we stop reading ?
1677 gi_resetS = (gi_reset / 10) % 10; //shall we close sockets ?
1678 gi_resetW = (gi_reset / 100) % 10; //shall we close files ?
1679 gi_resetX = gi_reset / 1000; //shall we simply wait resetX seconds ?
1680 g_reset = 0;
1681 }
1682 else
1683 {
1684 gi_reset = 0;
1685 gi_resetR = g_runStat == -1 ? 1 : 7;
1686
1687 gi_resetS = 7; //close all sockets
1688 gi_resetW = 7; //close all files
1689 gi_resetX = 0;
1690
1691 //inform others we have to quit ....
1692 gi_runStat = -11; //inform all that no update to happen any more
1693 gj.readStat = -11; //inform all that no update to happen any more
1694 }
1695
1696 if (gi_resetS > 0)
1697 {
1698 //must close all open sockets ...
1699 factPrintf(kInfo, -1, "Close all sockets...");
1700
1701 for (int i = 0; i < MAX_SOCK; i++)
1702 {
1703 if (rd[i].sockStat != 0)
1704 continue;
1705
1706 GenSock(-1, i, 0, NULL, &rd[i]); //close and destroy open socket
1707 if (i%7)
1708 continue;
1709
1710 gi_NumConnect[i / 7]-= cntsock ;
1711 //gi.numConn[i / 7]--;
1712 gj.numConn[i / 7]--;
1713 sockDef[i / 7] = 0; //flag ro recreate the sockets ...
1714 rd[i / 7].sockStat = -1; //and try to open asap
1715 }
1716 }
1717
1718
1719 if (gi_resetR > 0)
1720 {
1721 //flag all events as 'read finished'
1722 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
1723 {
1724 if (evtCtrl[k0].evtStat > 0 && evtCtrl[k0].evtStat < 90)
1725 {
1726 evtCtrl[k0].evtStat = 91;
1727 //gi.evtSkp++;
1728 //gi.evtTot++;
1729 }
1730 }
1731
1732 //and clear all buffers (might have to wait until all others are done)
1733 // If minclear is 0, an event could be deleted while writing is still ongoing
1734 /*
1735 int minclear;
1736 if (gi_resetR == 1) {
1737 minclear = 900;
1738 factPrintf(kInfo, -1, "Drain all buffers ...");
1739 } else {
1740 minclear = 0;
1741 factPrintf(kInfo, -1, "Flush all buffers ...");
1742 }*/
1743 const int minclear = 900;
1744
1745 int numclear = 1;
1746 while (numclear > 0)
1747 {
1748 numclear = 0;
1749
1750 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
1751 {
1752 if (evtCtrl[k0].evtStat > minclear)
1753 {
1754 const int id = k0;//evtCtrl[k0].mBuffer_idx;
1755#ifdef EVTDEBUG
1756 factPrintf(kDebug, -1, "ev %5d free event buffer, nb=%3d", evtCtrl[id].evNum, evtCtrl[id].nBoard);
1757#endif
1758 mBufFree (id); //event written--> free memory
1759 evtCtrl[k0].evtStat = -1;
1760
1761 if (k0==evtCtrl_frstPtr)
1762 {
1763 evtCtrl_frstPtr++;
1764 evtCtrl_frstPtr %= MAX_EVT * MAX_RUN;
1765 }
1766 else
1767 factPrintf(kDebug, -1, "Freed a non-first slot");
1768 }
1769 else
1770 if (evtCtrl[k0].evtStat > 0)
1771 numclear++; //writing is still ongoing...
1772
1773 /*
1774 if (k0 == evtCtrl_frstPtr && evtCtrl[k0].evtStat < 0)
1775 {
1776 evtCtrl_frstPtr++;
1777 evtCtrl_frstPtr %= MAX_EVT * MAX_RUN;
1778 }*/
1779 }
1780
1781 usleep(1);
1782 }
1783 }
1784
1785 if (gi_reset > 0)
1786 {
1787 if (gi_resetW > 0)
1788 CloseRunFile (0, 0, 0); //ask all Runs to be closed
1789
1790 if (gi_resetX > 0)
1791 {
1792 struct timespec xwait;
1793 xwait.tv_sec = gi_resetX;
1794 xwait.tv_nsec = 0;
1795 nanosleep (&xwait, NULL);
1796 }
1797
1798 factPrintf(kInfo, -1, "Continue read Process ...");
1799 gi_reset = 0;
1800 goto START;
1801 }
1802
1803 factPrintf(kInfo, -1, "Exit read Process...");
1804
1805#ifdef THOMAS_MALLOC
1806 factPrintf(kInfo, -1, "%ld Bytes flaged as in-use.", tgb_inuse);
1807#endif
1808
1809 gi_runStat = -99;
1810 gj.readStat = -99;
1811
1812 factStat (gj);
1813 factStatNew (gi);
1814
1815 return 0;
1816
1817} /*-----------------------------------------------------------------*/
1818
1819
1820void *subProc(void *thrid)
1821{
1822 const int64_t threadID = (int64_t)thrid;
1823
1824 factPrintf(kInfo, -1, "Starting sub-process-thread %ld", threadID);
1825
1826 while (g_runStat > -2) //in case of 'exit' we still must process pending events
1827 {
1828 int numWait = 0;
1829 int numProc = 0;
1830
1831 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
1832 {
1833 if (evtCtrl[k0].evtStat != 1000 + threadID)
1834 {
1835 if (evtCtrl[k0].evtStat < 1000 + threadID)
1836 numWait++;
1837
1838 continue;
1839 }
1840
1841 /*** if (evtCtrl.evtStat[k0] == 1000 + threadID) ****/
1842
1843 int jret = 9100; // flag to be deleted (gi_resetR>1 : flush buffers asap)
1844
1845 if (gi_resetR<=1)
1846 {
1847 const int id = k0;//evtCtrl[k0].mBuffer_idx;
1848
1849 jret = subProcEvt(threadID, evtCtrl[id].FADhead,
1850 evtCtrl[id].fEvent, NULL/*mBuffer[id].buffer*/);
1851
1852
1853 if (jret <= threadID) {
1854 factPrintf(kError, -1, "Process %ld wants to send event to process %d... not allowed.", threadID, jret);
1855 jret = 5300;
1856 } else if (jret <= 0)
1857 jret = 9200 + threadID; // flag as 'to be deleted'
1858 else if (jret >= gi_maxProc)
1859 jret = 5200 + threadID; // flag as 'to be written'
1860 else
1861 jret = 1000 + jret; // flag for next proces
1862 }
1863
1864 evtCtrl[k0].evtStat = jret;
1865 numProc++;
1866 }
1867
1868 if (gj.readStat < -10 && numWait == 0) { //nothing left to do
1869 factPrintf(kInfo, -1, "Exit subProcessing in process %ld", threadID);
1870 return 0;
1871 }
1872
1873 //seems we have nothing to do, so sleep a little
1874 if (numProc == 0)
1875 usleep(1);
1876 }
1877
1878 factPrintf(kInfo, -1, "Ending sub-process-thread %ld", threadID);
1879
1880 return 0;
1881}
1882
1883/*-----------------------------------------------------------------*/
1884
1885
1886void *
1887procEvt (void *ptr)
1888{
1889/* *** main loop processing file, including SW-trigger */
1890 int status;
1891
1892 int lastRun = 0; //usually run from last event still valid
1893
1894// cpu_set_t mask;
1895// int cpu = 1; //process thread (will be several in final version)
1896
1897 factPrintf(kInfo, -1, "Starting process-thread with %d subprocesses", gi_maxProc);
1898
1899/* CPU_ZERO initializes all the bits in the mask to zero. */
1900// CPU_ZERO (&mask);
1901/* CPU_SET sets only the bit corresponding to cpu. */
1902// CPU_SET( 0 , &mask ); leave for system
1903// CPU_SET( 1 , &mask ); used by write process
1904// CPU_SET (2, &mask);
1905// CPU_SET (3, &mask);
1906// CPU_SET (4, &mask);
1907// CPU_SET (5, &mask);
1908// CPU_SET (6, &mask);
1909// CPU_SET( 7 , &mask ); used by read process
1910/* sched_setaffinity returns 0 in success */
1911// if (sched_setaffinity (0, sizeof (mask), &mask) == -1) {
1912// snprintf (str, MXSTR, "P ---> can not create affinity to %d", cpu);
1913// factOut (kWarn, -1, str);
1914// }
1915
1916
1917 pthread_t thread[100];
1918// int th_ret[100];
1919
1920 for (long long k = 0; k < gi_maxProc; k++) {
1921 /*th_ret[k] =*/ pthread_create (&thread[k], NULL, subProc, (void *) k);
1922 }
1923
1924 // in case of 'exit' we still must process pending events
1925 while (g_runStat > -2)
1926 {
1927 int numWait = 0;
1928 int numProc = 0;
1929
1930 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
1931 {
1932 if (evtCtrl[k0].evtStat <= 90 || evtCtrl[k0].evtStat >= 1000)
1933 {
1934 if (evtCtrl[k0].evtStat >= 0 && evtCtrl[k0].evtStat< 90)
1935 numWait++;
1936
1937 continue;
1938 }
1939
1940 //we are asked to flush buffers asap
1941 if (gi_resetR > 1)
1942 {
1943 evtCtrl[k0].evtStat = 9991;
1944 continue;
1945 }
1946
1947 //-------- it is better to open the run already here, so call can be used to initialize
1948 //-------- buffers etc. needed to interprete run (e.g. DRS calibration)
1949 const int id = k0;//evtCtrl[k0].mBuffer_idx;
1950
1951 const uint32_t irun = evtCtrl[id].runNum;
1952 const int32_t ievt = evtCtrl[id].evNum;
1953
1954 // Find entry in runCtrl which belongs to the event mBuffer[id]
1955 // (only check if there is a need to check)
1956 if (runCtrl[lastRun].runId != irun)
1957 {
1958 //check which fileID to use (or open if needed)
1959 int j;
1960 for (j=0;j<MAX_RUN; j++)
1961 if (runCtrl[j].runId == irun)
1962 break;
1963
1964 if (j>=MAX_RUN)
1965 {
1966 factPrintf(kFatal, 901, "writeEvt: Can not find run %d for event %d in %d", irun, ievt, id);
1967 // FIXME: What is the right action? (Flag event for deletion?)
1968 continue;
1969 }
1970
1971 lastRun = j;
1972 }
1973
1974 // File not yet open
1975 if (runCtrl[lastRun].fileId < 0)
1976 {
1977 //---- we need to open a new run ==> make sure all older runs are
1978 //---- finished and marked to be closed ....
1979 // This loop is unique to procEvt
1980 for (int j=0; j<MAX_RUN; j++)
1981 {
1982 if (runCtrl[j].fileId == 0)
1983 {
1984 runCtrl[j].procId = 2; //--> do no longer accept events for processing
1985
1986 //---- problem: processing still going on ==> must wait for closing ....
1987 factPrintf(kInfo, -1, "procEvt: Finished run since new one opened %d", runCtrl[j].runId);
1988 runFinish1(runCtrl[j].runId);
1989 }
1990 }
1991
1992 RUN_HEAD actRun;
1993 actRun.Version = 1;
1994 actRun.RunType = -1; //to be adapted
1995 actRun.Nroi = evtCtrl[id].nRoi; //runCtrl[lastRun].roi0;
1996 actRun.NroiTM = evtCtrl[id].nRoiTM; //runCtrl[lastRun].roi8;
1997 actRun.RunTime = evtCtrl[id].pcTime[0]; //runCtrl[lastRun].firstTime;
1998 actRun.RunUsec = evtCtrl[id].pcTime[1]; //runCtrl[lastRun].firstUsec;
1999 actRun.NBoard = NBOARDS;
2000 actRun.NPix = NPIX;
2001 actRun.NTm = NTMARK;
2002
2003 memcpy(actRun.FADhead, evtCtrl[id].FADhead, NBOARDS*sizeof(PEVNT_HEADER));
2004
2005 runCtrl[lastRun].fileHd = runOpen (irun, &actRun, sizeof (actRun));
2006 if (runCtrl[lastRun].fileHd == NULL)
2007 {
2008 factPrintf(kError, 502, "procEvt: Could not open a file for run %d (runOpen failed)", irun);
2009 runCtrl[lastRun].fileId = 91;
2010 runCtrl[lastRun].procId = 91; // Is not set in writeEvt
2011 continue;
2012 }
2013
2014 runCtrl[lastRun].fileId = 0;
2015 runCtrl[lastRun].procId = 0; // Is not set in writeEvt
2016
2017 factPrintf(kInfo, -1, "procEvt: Opened new file for run %d (evt=%d)", irun, ievt);
2018 }
2019
2020 //-------- also check if run shall be closed (==> skip event, but do not close the file !!! )
2021 if (runCtrl[lastRun].procId == 0)
2022 {
2023 if (runCtrl[lastRun].closeTime < g_actTime ||
2024 runCtrl[lastRun].lastTime < g_actTime - 300 ||
2025 runCtrl[lastRun].maxEvt <= runCtrl[lastRun].procEvt)
2026 {
2027 factPrintf(kInfo, 502, "procEvt: Reached end of run condition for run %d", irun);
2028 runFinish1 (runCtrl[lastRun].runId);
2029 runCtrl[lastRun].procId = 1;
2030 }
2031 }
2032
2033 // Skip event because of no active run
2034 if (runCtrl[lastRun].procId != 0)
2035 {
2036 evtCtrl[k0].evtStat = 9091;
2037 continue;
2038 }
2039
2040 //--------
2041 //--------
2042
2043 //const int roi = mBuffer[id].nRoi;
2044 //const int roiTM = mBuffer[id].nRoiTM;
2045
2046 //make sure unused pixels/tmarks are cleared to zero
2047 //ETIENNE don't reset it to zero as it is taken care of in DataWriteFits
2048 // if (roiTM == roi)
2049 // roiTM = 0;
2050 /*
2051 for (int ip=0; ip<NPIX; ip++)
2052 {
2053 if (mBuffer[id].fEvent->StartPix[ip] == -1)
2054 {
2055 const int dest = ip * roi;
2056 memset(&mBuffer[id].fEvent->Adc_Data[dest], 0, roi * 2);
2057 }
2058 }
2059
2060 for (int it=0; it<NTMARK; it++)
2061 {
2062 if (mBuffer[id].fEvent->StartTM[it] == -1)
2063 {
2064 const int dest = it * roi + NPIX * roi;
2065 memset(&mBuffer[id].fEvent->Adc_Data[dest], 0, roi * 2);
2066 }
2067 }*/
2068
2069 //and set correct event header ; also check for consistency in event (not yet)
2070 evtCtrl[id].fEvent->Roi = evtCtrl[id].nRoi;
2071 evtCtrl[id].fEvent->RoiTM = evtCtrl[id].nRoiTM;
2072 evtCtrl[id].fEvent->EventNum = evtCtrl[id].evNum;
2073 evtCtrl[id].fEvent->TriggerNum = evtCtrl[id].trgNum;
2074 evtCtrl[id].fEvent->TriggerType = evtCtrl[id].trgTyp;
2075 evtCtrl[id].fEvent->Errors[0] = evtCtrl[id].Errors[0];
2076 evtCtrl[id].fEvent->Errors[1] = evtCtrl[id].Errors[1];
2077 evtCtrl[id].fEvent->Errors[2] = evtCtrl[id].Errors[2];
2078 evtCtrl[id].fEvent->Errors[3] = evtCtrl[id].Errors[3];
2079 evtCtrl[id].fEvent->SoftTrig = 0;
2080
2081
2082 for (int ib=0; ib<NBOARDS; ib++)
2083 {
2084 // board is not read
2085 if (evtCtrl[id].board[ib] == -1)
2086 {
2087 evtCtrl[id].FADhead[ib].start_package_flag = 0;
2088 evtCtrl[id].fEvent->BoardTime[ib] = 0;
2089 }
2090 else
2091 {
2092 evtCtrl[id].fEvent->BoardTime[ib] = evtCtrl[id].FADhead[ib].time;
2093 }
2094 }
2095
2096 const int rc = eventCheck(evtCtrl[id].runNum, evtCtrl[id].FADhead,
2097 evtCtrl[id].fEvent);
2098 //gi.procTot++;
2099 numProc++;
2100
2101 if (rc < 0)
2102 {
2103 evtCtrl[k0].evtStat = 9999; //flag event to be skipped
2104 //gi.procErr++;
2105 }
2106 else
2107 {
2108 evtCtrl[k0].evtStat = 1000;
2109 runCtrl[lastRun].procEvt++;
2110 }
2111 }
2112
2113 if (gj.readStat < -10 && numWait == 0) { //nothing left to do
2114 factPrintf(kInfo, -1, "Exit Processing Process ...");
2115 gp_runStat = -22; //==> we should exit
2116 gj.procStat = -22; //==> we should exit
2117 return 0;
2118 }
2119
2120 //seems we have nothing to do, so sleep a little
2121 if (numProc == 0)
2122 usleep(1);
2123
2124 gp_runStat = gi_runStat;
2125 gj.procStat = gj.readStat;
2126
2127 }
2128
2129 //we are asked to abort asap ==> must flag all remaining events
2130 // when gi_runStat claims that all events are in the buffer...
2131
2132 factPrintf(kInfo, -1, "Abort Processing Process ...");
2133
2134 for (int k = 0; k < gi_maxProc; k++) {
2135 pthread_join (thread[k], (void **) &status);
2136 }
2137
2138 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
2139 {
2140 if (evtCtrl[k0].evtStat >= 0 && evtCtrl[k0].evtStat < 1000)
2141 evtCtrl[k0].evtStat = 9800; //flag event as 'processed'
2142 }
2143
2144 gp_runStat = -99;
2145 gj.procStat = -99;
2146
2147 return 0;
2148
2149} /*-----------------------------------------------------------------*/
2150
2151int
2152CloseRunFile (uint32_t runId, uint32_t closeTime, uint32_t maxEvt)
2153{
2154/* close run runId (all all runs if runId=0) */
2155/* return: 0=close scheduled / >0 already closed / <0 does not exist */
2156 int j;
2157
2158
2159 if (runId == 0) {
2160 for (j = 0; j < MAX_RUN; j++) {
2161 if (runCtrl[j].fileId == 0) { //run is open
2162 runCtrl[j].closeTime = closeTime;
2163 runCtrl[j].maxEvt = maxEvt;
2164 }
2165 }
2166 return 0;
2167 }
2168
2169 for (j = 0; j < MAX_RUN; j++) {
2170 if (runCtrl[j].runId == runId) {
2171 if (runCtrl[j].fileId == 0) { //run is open
2172 runCtrl[j].closeTime = closeTime;
2173 runCtrl[j].maxEvt = maxEvt;
2174 return 0;
2175 } else if (runCtrl[j].fileId < 0) { //run not yet opened
2176 runCtrl[j].closeTime = closeTime;
2177 runCtrl[j].maxEvt = maxEvt;
2178 return +1;
2179 } else { // run already closed
2180 return +2;
2181 }
2182 }
2183 } //we only reach here if the run was never created
2184 return -1;
2185
2186}
2187
2188void checkAndCloseRun(int j, int irun, int cond, int where)
2189{
2190 if (!cond &&
2191 runCtrl[j].closeTime >= g_actTime &&
2192 runCtrl[j].lastTime >= g_actTime - 300 &&
2193 runCtrl[j].maxEvt > runCtrl[j].actEvt)
2194 return;
2195
2196 //close run for whatever reason
2197 int ii = 0;
2198 if (cond)
2199 ii = 1;
2200 if (runCtrl[j].closeTime < g_actTime)
2201 ii |= 2; // = 2;
2202 if (runCtrl[j].lastTime < g_actTime - 300)
2203 ii |= 4; // = 3;
2204 if (runCtrl[j].maxEvt <= runCtrl[j].actEvt)
2205 ii |= 8; // = 4;
2206
2207 if (runCtrl[j].procId == 0)
2208 {
2209 runFinish1(runCtrl[j].runId);
2210 runCtrl[j].procId = 92;
2211 }
2212
2213 runCtrl[j].closeTime = g_actTime - 1;
2214
2215 const int rc = runClose(runCtrl[j].fileHd, NULL, 0);//&runTail[j], sizeof(runTail[j]));
2216 if (rc<0)
2217 {
2218 factPrintf(kError, 503, "writeEvt-%d: Error closing run %d (runClose,rc=%d)",
2219 where, runCtrl[j].runId, rc);
2220 runCtrl[j].fileId = 92+where*2;
2221 }
2222 else
2223 {
2224 factPrintf(kInfo, 503, "writeEvt-%d: Closed run %d (reason=%d)",
2225 where, irun, ii);
2226 runCtrl[j].fileId = 93+where*2;
2227 }
2228}
2229
2230/*-----------------------------------------------------------------*/
2231
2232
2233void *writeEvt (void *ptr)
2234{
2235/* *** main loop writing event (including opening and closing run-files */
2236
2237// cpu_set_t mask;
2238// int cpu = 1; //write thread
2239
2240 factPrintf(kInfo, -1, "Starting write-thread");
2241
2242/* CPU_ZERO initializes all the bits in the mask to zero. */
2243// CPU_ZERO (&mask);
2244/* CPU_SET sets only the bit corresponding to cpu. */
2245// CPU_SET (cpu, &mask);
2246/* sched_setaffinity returns 0 in success */
2247// if (sched_setaffinity (0, sizeof (mask), &mask) == -1) {
2248// snprintf (str, MXSTR, "W ---> can not create affinity to %d", cpu);
2249// }
2250
2251 int lastRun = 0; //usually run from last event still valid
2252
2253 while (g_runStat > -2)
2254 {
2255 int numWrite = 0;
2256 int numWait = 0;
2257
2258 for (int k0=evtCtrl_frstPtr; k0!=evtCtrl_lastPtr; k0++, k0 %= MAX_EVT*MAX_RUN)
2259 {
2260 if (evtCtrl[k0].evtStat <= 5000 || evtCtrl[k0].evtStat >= 9000)
2261 {
2262 if (evtCtrl[k0].evtStat > 0 && evtCtrl[k0].evtStat < 9000)
2263 numWait++;
2264
2265 continue;
2266 }
2267
2268 //we must drain the buffer asap
2269 if (gi_resetR > 1)
2270 {
2271 evtCtrl[k0].evtStat = 9904;
2272 continue;
2273 }
2274
2275 const int id = k0;//evtCtrl[k0].mBuffer_idx;
2276
2277 const uint32_t irun = evtCtrl[id].runNum;
2278 const int32_t ievt = evtCtrl[id].evNum;
2279
2280 // Find entry in runCtrl which belongs to the event mBuffer[id]
2281 // (only check if there is a need to check)
2282 if (runCtrl[lastRun].runId != irun)
2283 {
2284 //check which fileID to use (or open if needed)
2285 int j;
2286 for (j=0;j<MAX_RUN; j++)
2287 if (runCtrl[j].runId == irun)
2288 break;
2289
2290 if (j>=MAX_RUN)
2291 {
2292 factPrintf(kFatal, 901, "writeEvt: Can not find run %d for event %d in %d", irun, ievt, id);
2293 // FIXME: What is the right action?
2294 continue;
2295 }
2296
2297 lastRun = j;
2298 }
2299
2300 // File not yet open
2301 if (runCtrl[lastRun].fileId < 0)
2302 {
2303 RUN_HEAD actRun;
2304 actRun.Version = 1;
2305 actRun.RunType = -1; //to be adapted
2306 actRun.Nroi = evtCtrl[id].nRoi; //runCtrl[lastRun].roi0;
2307 actRun.NroiTM = evtCtrl[id].nRoiTM; //runCtrl[lastRun].roi8;
2308 actRun.RunTime = evtCtrl[id].pcTime[0];//runCtrl[lastRun].firstTime;
2309 actRun.RunUsec = evtCtrl[id].pcTime[1];//runCtrl[lastRun].firstUsec;
2310 actRun.NBoard = NBOARDS;
2311 actRun.NPix = NPIX;
2312 actRun.NTm = NTMARK;
2313
2314 memcpy(actRun.FADhead, evtCtrl[id].FADhead, NBOARDS * sizeof (PEVNT_HEADER));
2315
2316 runCtrl[lastRun].fileHd = runOpen (irun, &actRun, sizeof (actRun));
2317 if (runCtrl[lastRun].fileHd == NULL)
2318 {
2319 factPrintf(kError, 502, "writeEvt: Could not open a file for run %d (runOpen failed)", irun);
2320 runCtrl[lastRun].fileId = 91;
2321 continue;
2322 }
2323
2324 runCtrl[lastRun].fileId = 0;
2325 factPrintf(kInfo, -1, "writeEvt: Opened new file for run %d (evt %d)", irun, ievt);
2326 }
2327
2328 if (runCtrl[lastRun].fileId > 0)
2329 {
2330 // There is an event but file is already closed
2331 /*
2332 if (runCtrl[j].fileId < 100)
2333 {
2334 factPrintf(kWarn, 123, "writeEvt: File for run %d is closed", irun);
2335 runCtrl[j].fileId += 100;
2336 }*/
2337
2338 evtCtrl[k0].evtStat = 9903;
2339 }
2340
2341 // File is open
2342 if (runCtrl[lastRun].fileId==0)
2343 {
2344 const int rc = runWrite(runCtrl[lastRun].fileHd, evtCtrl[id].fEvent,
2345 sizeof (evtCtrl[id]));
2346 if (rc >= 0)
2347 {
2348 // Sucessfully wrote event
2349 runCtrl[lastRun].lastTime = g_actTime;
2350 runCtrl[lastRun].actEvt++;
2351
2352 evtCtrl[k0].evtStat = 9901;
2353 }
2354 else
2355 {
2356 factPrintf(kError, 503, "writeEvt: Writing event for run %d failed (runWrite)", irun);
2357 evtCtrl[k0].evtStat = 9902;
2358 }
2359
2360 checkAndCloseRun(lastRun, irun, rc<0, 1);
2361 }
2362 }
2363/*
2364 //check if we should close a run (mainly when no event pending)
2365 //ETIENNE but first figure out which one is the latest run with a complete event.
2366 //i.e. max run Id and lastEvt >= 0
2367 //this condition is sufficient because all pending events were written already in the loop just above
2368 //actrun
2369 uint32_t lastStartedTime = 0;
2370 uint32_t runIdFound = 1;
2371
2372 //If we have an active run, look for its start time
2373 if (actrun != 0)
2374 {
2375 runIdfound = 0;
2376 for (int j=0;j<MAX_RUN;j++)
2377 {
2378 if (runCtrl[j].runId == actrun)
2379 {
2380 lastStartedTime = runCtrl[j].lastTime;
2381 runIdFound = 1;
2382 }
2383 }
2384 }
2385
2386 if (runIdFound == 0)
2387 {
2388 factPrintf(kInfo, 0, "An Active run (number %u) has been registered, but it could not be found in the runs list", actrun);
2389 }
2390
2391 //Also check if some files will never be opened
2392 //EDIT: this is completely useless, because as run Numbers are taken from FADs board,
2393 //I will never get run numbers for which no file is to be opened
2394 for (int j=0;j<MAX_RUN;j++)
2395 {
2396 if ((runCtrl[j].fileId < 0) &&
2397 (runCtrl[j].lastTime < lastStartedTime) &&
2398 (runCtrl[j].runId != 0))
2399 {
2400 factPrintf(kInfo, 0, "writeEvt: No file will be opened for run %u. Last run: %u (started)", runCtrl[j].runId, actrun);
2401 ;//TODO notify that this run will never be opened
2402 }
2403 }
2404 */
2405
2406 // Although the are no pending events, we have to check if a run should be closed (timeout)
2407 for (int j=0; j<MAX_RUN; j++)
2408 {
2409 if (runCtrl[j].fileId == 0)
2410 {
2411 //ETIENNE added the condition at this line. dunno what to do with run 0: skipping it
2412 const int cond = /*runCtrl[j].lastTime < lastStartedTime &&*/ runCtrl[j].runId == 0;
2413 checkAndCloseRun(j, runCtrl[j].runId, cond, 2);
2414 }
2415 }
2416
2417 //seems we have nothing to do, so sleep a little
2418 if (numWrite == 0)
2419 usleep(1);
2420
2421 //nothing left to do
2422 if (gj.readStat < -10 && numWait == 0)
2423 {
2424 factPrintf(kInfo, -1, "Finish Write Process ...");
2425 gw_runStat = -22; //==> we should exit
2426 gj.writStat = -22; //==> we should exit
2427 break;
2428 }
2429
2430 gw_runStat = gi_runStat;
2431 gj.writStat = gj.readStat;
2432 }
2433
2434 factPrintf(kInfo, -1, "Close all open files ...");
2435 for (int j=0; j<MAX_RUN; j++)
2436 {
2437 if (runCtrl[j].fileId == 0)
2438 checkAndCloseRun(j, runCtrl[j].runId, 1, 3);
2439 }
2440
2441 gw_runStat = -99;
2442 gj.writStat = -99;
2443
2444 factPrintf(kInfo, -1, "Exit Writing Process ...");
2445
2446 return 0;
2447} /*-----------------------------------------------------------------*/
2448
2449
2450
2451
2452void
2453StartEvtBuild ()
2454{
2455
2456 int i, /*j,*/ imax, status/*, th_ret[50]*/;
2457 pthread_t thread[50];
2458 struct timespec xwait;
2459
2460 gi_runStat = gp_runStat = gw_runStat = 0;
2461 gj.readStat = gj.procStat = gj.writStat = 0;
2462
2463 factPrintf(kInfo, -1, "Starting EventBuilder V15.07 A");
2464
2465//initialize run control logics
2466 for (i = 0; i < MAX_RUN; i++) {
2467 runCtrl[i].runId = 0;
2468 runCtrl[i].fileId = -2;
2469 }
2470
2471//prepare for subProcesses
2472 gi_maxSize = g_maxSize;
2473 if (gi_maxSize <= 0)
2474 gi_maxSize = 1;
2475
2476 gi_maxProc = g_maxProc;
2477 if (gi_maxProc <= 0 || gi_maxProc > 90) {
2478 factPrintf(kFatal, 301, "Illegal number of processes %d", gi_maxProc);
2479 gi_maxProc = 1;
2480 }
2481//partially initialize event control logics
2482 evtCtrl_frstPtr = 0;
2483 evtCtrl_lastPtr = 0;
2484
2485//start all threads (more to come) when we are allowed to ....
2486 while (g_runStat == 0) {
2487 xwait.tv_sec = 0;
2488 xwait.tv_nsec = 10000000; // sleep for ~10 msec
2489 nanosleep (&xwait, NULL);
2490 }
2491
2492 i = 0;
2493 /*th_ret[i] =*/ pthread_create (&thread[i], NULL, readFAD, NULL);
2494 i++;
2495 /*th_ret[i] =*/ pthread_create (&thread[i], NULL, procEvt, NULL);
2496 i++;
2497 /*th_ret[i] =*/ pthread_create (&thread[i], NULL, writeEvt, NULL);
2498 i++;
2499 imax = i;
2500
2501
2502#ifdef BILAND
2503 xwait.tv_sec = 30;;
2504 xwait.tv_nsec = 0; // sleep for ~20sec
2505 nanosleep (&xwait, NULL);
2506
2507 printf ("close all runs in 2 seconds\n");
2508
2509 CloseRunFile (0, time (NULL) + 2, 0);
2510
2511 xwait.tv_sec = 1;;
2512 xwait.tv_nsec = 0; // sleep for ~20sec
2513 nanosleep (&xwait, NULL);
2514
2515 printf ("setting g_runstat to -1\n");
2516
2517 g_runStat = -1;
2518#endif
2519
2520
2521//wait for all threads to finish
2522 for (i = 0; i < imax; i++) {
2523 /*j =*/ pthread_join (thread[i], (void **) &status);
2524 }
2525
2526} /*-----------------------------------------------------------------*/
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542 /*-----------------------------------------------------------------*/
2543 /*-----------------------------------------------------------------*/
2544 /*-----------------------------------------------------------------*/
2545 /*-----------------------------------------------------------------*/
2546 /*-----------------------------------------------------------------*/
2547
2548#ifdef BILAND
2549
2550int
2551subProcEvt (int threadID, PEVNT_HEADER * fadhd, EVENT * event,
2552 int8_t * buffer)
2553{
2554 printf ("called subproc %d\n", threadID);
2555 return threadID + 1;
2556}
2557
2558
2559
2560
2561 /*-----------------------------------------------------------------*/
2562 /*-----------------------------------------------------------------*/
2563 /*-----------------------------------------------------------------*/
2564 /*-----------------------------------------------------------------*/
2565 /*-----------------------------------------------------------------*/
2566
2567
2568
2569
2570FileHandle_t
2571runOpen (uint32_t irun, RUN_HEAD * runhd, size_t len)
2572{
2573 return 1;
2574};
2575
2576int
2577runWrite (FileHandle_t fileHd, EVENT * event, size_t len)
2578{
2579 return 1;
2580 usleep (10000);
2581 return 1;
2582}
2583
2584
2585//{ return 1; } ;
2586
2587int
2588runClose (FileHandle_t fileHd, RUN_TAIL * runth, size_t len)
2589{
2590 return 1;
2591};
2592
2593
2594
2595
2596int
2597eventCheck (uint32_t runNr, PEVNT_HEADER * fadhd, EVENT * event)
2598{
2599 int i = 0;
2600
2601// printf("------------%d\n",ntohl(fadhd[7].fad_evt_counter) );
2602// for (i=0; i<NBOARDS; i++) {
2603// printf("b=%2d,=%5d\n",i,fadhd[i].board_id);
2604// }
2605 return 0;
2606}
2607
2608
2609void
2610factStatNew (EVT_STAT gi)
2611{
2612 int i;
2613
2614//for (i=0;i<MAX_SOCK;i++) {
2615// printf("%4d",gi.numRead[i]);
2616// if (i%20 == 0 ) printf("\n");
2617//}
2618}
2619
2620void
2621gotNewRun (int runnr, PEVNT_HEADER * headers)
2622{
2623 printf ("got new run %d\n", runnr);
2624 return;
2625}
2626
2627void
2628factStat (GUI_STAT gj)
2629{
2630// printf("stat: bfr%5lu skp%4lu free%4lu (tot%7lu) mem%12lu rd%12lu %3lu\n",
2631// array[0],array[1],array[2],array[3],array[4],array[5],array[6]);
2632}
2633
2634
2635void
2636debugRead (int isock, int ibyte, int32_t event, int32_t ftmevt, int32_t runnr,
2637 int state, uint32_t tsec, uint32_t tusec)
2638{
2639// printf("%3d %5d %9d %3d %12d\n",isock, ibyte, event, state, tusec) ;
2640}
2641
2642
2643
2644void
2645debugStream (int isock, void *buf, int len)
2646{
2647}
2648
2649void
2650debugHead (int i, int j, void *buf)
2651{
2652}
2653
2654
2655void
2656factOut (int severity, int err, char *message)
2657{
2658 static FILE *fd;
2659 static int file = 0;
2660
2661 if (file == 0) {
2662 printf ("open file\n");
2663 fd = fopen ("x.out", "w+");
2664 file = 999;
2665 }
2666
2667 fprintf (fd, "%3d %3d | %s \n", severity, err, message);
2668
2669 if (severity != kDebug)
2670 printf ("%3d %3d | %s\n", severity, err, message);
2671}
2672
2673
2674
2675int
2676main ()
2677{
2678 int i, b, c, p;
2679 char ipStr[100];
2680 struct in_addr IPaddr;
2681
2682 g_maxMem = 1024 * 1024; //MBytes
2683//g_maxMem = g_maxMem * 1024 *10 ; //10GBytes
2684 g_maxMem = g_maxMem * 200; //100MBytes
2685
2686 g_maxProc = 20;
2687 g_maxSize = 30000;
2688
2689 g_runStat = 40;
2690
2691 i = 0;
2692
2693// version for standard crates
2694//for (c=0; c<4,c++) {
2695// for (b=0; b<10; b++) {
2696// sprintf(ipStr,"10.0.%d.%d",128+c,128+b)
2697//
2698// inet_pton(PF_INET, ipStr, &IPaddr) ;
2699//
2700// g_port[i].sockAddr.sin_family = PF_INET;
2701// g_port[i].sockAddr.sin_port = htons(5000) ;
2702// g_port[i].sockAddr.sin_addr = IPaddr ;
2703// g_port[i].sockDef = 1 ;
2704// i++ ;
2705// }
2706//}
2707//
2708//version for PC-test *
2709 for (c = 0; c < 4; c++) {
2710 for (b = 0; b < 10; b++) {
2711 sprintf (ipStr, "10.0.%d.11", 128 + c);
2712 if (c < 2)
2713 sprintf (ipStr, "10.0.%d.11", 128);
2714 else
2715 sprintf (ipStr, "10.0.%d.11", 131);
2716// if (c==0) sprintf(ipStr,"10.0.100.11") ;
2717
2718 inet_pton (PF_INET, ipStr, &IPaddr);
2719 p = 31919 + 100 * c + 10 * b;
2720
2721
2722 g_port[i].sockAddr.sin_family = PF_INET;
2723 g_port[i].sockAddr.sin_port = htons (p);
2724 g_port[i].sockAddr.sin_addr = IPaddr;
2725 g_port[i].sockDef = 1;
2726
2727 i++;
2728 }
2729 }
2730
2731
2732//g_port[17].sockDef =-1 ;
2733//g_actBoards-- ;
2734
2735 StartEvtBuild ();
2736
2737 return 0;
2738
2739}
2740#endif
Note: See TracBrowser for help on using the repository browser.