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

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