Changeset 16382 for trunk


Ignore:
Timestamp:
05/28/13 13:50:50 (11 years ago)
Author:
tbretz
Message:
Some more performance improvements (e.g. emplace instead of post, memset instead of for); moved the close request from the run-ctrl (where it would be executed immediately) to the evt-ctrl; removed some shared_ptrs where not necessary because the object cannot go out of scope while the shared_ptr does not go out of scope
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/EventBuilder.cc

    r16108 r16382  
     1#include <poll.h>
    12#include <sys/time.h>
    23#include <sys/epoll.h>
     
    67#include <cstdarg>
    78#include <list>
    8 #include <forward_list>
    99
    1010#include <boost/algorithm/string/join.hpp>
     
    2121
    2222//#define COMPLETE_EVENTS
     23//#define USE_POLL
    2324//#define USE_EPOLL
    2425//#define USE_SELECT
    2526//#define COMPLETE_EPOLL
    2627
     28// Reading only 1024: 13:  77Hz, 87%
     29// Reading only 1024: 12:  78Hz, 46%
     30// Reading only  300:  4: 250Hz, 92%
     31// Reading only  300:  3: 258Hz, 40%
     32
     33// Reading only four threads 1024: 13:  77Hz, 60%
     34// Reading only four threads 1024: 12:  78Hz, 46%
     35// Reading only four threads  300:  4: 250Hz, 92%
     36// Reading only four threads  300:  3: 258Hz, 40%
     37
     38// Default  300:  4: 249Hz, 92%
     39// Default  300:  3: 261Hz, 40%
     40// Default 1024: 13:  76Hz, 93%
     41// Default 1024: 12:  79Hz, 46%
     42
     43// Poll [selected] 1024: 13:  63Hz, 45%
     44// Poll [selected] 1024: 14:  63Hz, 63%
     45// Poll [selected] 1024: 15:  64Hz, 80%
     46// Poll [selected]  300:  4: 230Hz, 47%
     47// Poll [selected]  300:  3: 200Hz, 94%
     48
     49// Poll [all]      1024: 13:  65Hz, 47%
     50// Poll [all]      1024: 14:  64Hz, 59%
     51// Poll [all]      1024: 15:  62Hz, 67%
     52// Poll [all]       300:  4: 230Hz, 47%
     53// Poll [all]       300:  3: 230Hz, 35%
     54
    2755// ==========================================================================
    2856
    29 bool runOpen(const shared_ptr<EVT_CTRL2> &evt);
    30 bool runWrite(const shared_ptr<EVT_CTRL2> &evt);
     57bool runOpen(const EVT_CTRL2 &evt);
     58bool runWrite(const EVT_CTRL2 &evt);
    3159void runClose();
    3260void applyCalib(const shared_ptr<EVT_CTRL2> &evt);
     
    3664void runFinished();
    3765void factStat(GUI_STAT gj);
    38 bool eventCheck(const shared_ptr<EVT_CTRL2> &evt);
     66bool eventCheck(const EVT_CTRL2 &evt);
    3967void debugHead(void *buf);
    4068
     
    5280
    5381// ==========================================================================
    54 
    55 void factPrintf(int severity, const char *fmt, ...)
    56 {
    57     char str[1000];
    58 
    59     va_list ap;
    60     va_start(ap, fmt);
    61     vsnprintf(str, 1000, fmt, ap);
    62     va_end(ap);
    63 
    64     factOut(severity, str);
    65 }
    66 
    67 // ==========================================================================
    68 
    69 #define MAX_HEAD_MEM (NBOARDS * sizeof(PEVNT_HEADER))
    70 #define MAX_TOT_MEM (sizeof(EVENT) + (NPIX+NTMARK)*1024*2 + MAX_HEAD_MEM)
    7182
    7283namespace Memory
     
    7788    uint64_t max_inuse = 0;
    7889
    79     mutex mtx;
    80 
    81     forward_list<void*> memory;
     90    std::mutex mtx;
     91
     92    std::forward_list<void*> memory;
    8293
    8394    void *malloc()
     
    104115        {
    105116            // Get the next free slot from the stack and return it
    106             const lock_guard<mutex> lock(mtx);
     117            const std::lock_guard<std::mutex> lock(mtx);
    107118            mem = memory.front();
    108119            memory.pop_front();
     
    130141        }
    131142
    132         const lock_guard<mutex> lock(mtx);
     143        const std::lock_guard<std::mutex> lock(mtx);
    133144        memory.push_front(mem);
    134145    }
     146
    135147};
     148
     149// ==========================================================================
     150
     151void factPrintf(int severity, const char *fmt, ...)
     152{
     153    char str[1000];
     154
     155    va_list ap;
     156    va_start(ap, fmt);
     157    vsnprintf(str, 1000, fmt, ap);
     158    va_end(ap);
     159
     160    factOut(severity, str);
     161}
    136162
    137163// ==========================================================================
     
    185211    };
    186212
     213    timeval  time;
    187214    uint64_t rateBytes;
    188215    uint32_t skip;     // number of bytes skipped before start of event
    189     bool     repmem;   // reportet no mmemory free
    190216
    191217    uint32_t len() const { return uint32_t(H.package_length)*2; }
     
    215241{
    216242    // wait for something to do...
    217     const int rc = epoll_wait(fd_epoll, events, NBOARDS, 10); // max, timeout[ms]
     243    const int rc = epoll_wait(fd_epoll, events, NBOARDS, 100); // max, timeout[ms]
    218244    if (rc>=0)
    219245        return rc;
     
    363389    bufPos = B;  // no byte read so far
    364390    skip   = 0;       // start empty
    365     repmem = false;
    366391
    367392    factPrintf(MessageImp::kInfo, "Connected socket %d (%d)", sockId, socket);
     
    380405bool READ_STRUCT::read()
    381406{
     407    if (!connected)
     408        return false;
     409
    382410    if (bufLen==0)
    383411        return true;
     
    409437    if (bufTyp==kStream)
    410438        return false;
     439
     440    if (bufPos==B)
     441        gettimeofday(&time, NULL);
    411442
    412443    bufPos += jrd;  //==> prepare for continuation
     
    437468    I[11] = ntohl(I[11]);   // time;
    438469
     470    // Use back inserter??
    439471    for (int s=24; s<24+NTemp+NDAC; s++)
    440472        S[s] = ntohs(S[s]); // drs_temperature / dac
     
    523555shared_ptr<EVT_CTRL2> mBufEvt(const READ_STRUCT &rd, shared_ptr<RUN_CTRL2> &actrun)
    524556{
     557    /*
     558     checkroi consistence
     559     find existing entry
     560     if no entry, try to allocate memory
     561     if entry and memory, init event structure
     562     */
     563
    525564    uint16_t nRoi[9];
    526565    if (!checkRoiConsistency(rd, nRoi))
     
    562601            evt->Errors[2]++;
    563602
     603        // It is maybe not likely, but the header of this board might have
     604        // arrived earlier. (We could also update the run-info, but
     605        // this should not make a difference here)
     606        if ((rd.time.tv_sec==evt->time.tv_sec && rd.time.tv_usec<evt->time.tv_usec) ||
     607            rd.time.tv_sec<evt->time.tv_sec)
     608            evt->time = rd.time;
     609
    564610        //everything seems fine so far ==> use this slot ....
    565611        return evt;
     
    573619    }
    574620
    575     shared_ptr<EVT_CTRL2> evt(new EVT_CTRL2);
    576 
    577     gettimeofday(&evt->time, NULL);
     621    EVT_CTRL2 *evt = new EVT_CTRL2;
     622
     623    evt->time   = rd.time;
    578624
    579625    evt->runNum = rd.H.runnumber;
     
    613659    }
    614660
     661    // Keep pointer to run of this event
     662    evt->runCtrl = actrun;
     663
    615664    // Increase the number of events we have started to receive in this run
    616665    actrun->lastTime = evt->time.tv_sec;  // Time when the last event was received
    617666    actrun->lastEvt++;
    618 
    619     // Keep pointer to run of this event
    620     evt->runCtrl = actrun;
    621 
    622     // Secure access to evtCtrl against access in CloseRunFile
    623     // This should be the last... otherwise we can run into threading issues
    624     // if the event is accessed before it is fully initialized.
    625     evtCtrl.push_back(evt);
    626667
    627668    // An event can be the first and the last, but not the last and the first.
     
    629670    // runFinished signals that the last event of a run was just received. Processing
    630671    // might still be ongoing, but we can start a new run.
    631     const bool cond1 = actrun->lastEvt < actrun->maxEvt;      // max number of events not reached
     672    const bool cond1 = actrun->lastEvt  < actrun->maxEvt;     // max number of events not reached
    632673    const bool cond2 = actrun->lastTime < actrun->closeTime;  // max time not reached
    633674    if (!cond1 || !cond2)
    634675        runFinished();
    635676
    636     return evt;
     677    // We don't mind here that this is not common to all events,
     678    // because every coming event will fullfil the condition as well.
     679    if (!cond1)
     680        evt->closeRequest |= kRequestMaxEvtsReached;
     681    if (!cond2)
     682        evt->closeRequest |= kRequestMaxTimeReached;
     683
     684    // Secure access to evtCtrl against access in CloseRunFile
     685    // This should be the last... otherwise we can run into threading issues
     686    // if the event is accessed before it is fully initialized.
     687    evtCtrl.emplace_back(evt);
     688    return evtCtrl.back();
    637689}
    638690
     
    642694    const int i = rBuf.sockId;
    643695
    644     memcpy(evt->FADhead.get()+i, &rBuf.H, sizeof(PEVNT_HEADER));
     696    memcpy(evt->FADhead+i, &rBuf.H, sizeof(PEVNT_HEADER));
    645697
    646698    int src = sizeof(PEVNT_HEADER) / 2;  // Header is 72 byte = 36 shorts
     
    743795void writeEvt(const shared_ptr<EVT_CTRL2> &evt)
    744796{
    745     const shared_ptr<RUN_CTRL2> &run = evt->runCtrl;
     797    //const shared_ptr<RUN_CTRL2> &run = evt->runCtrl;
     798    RUN_CTRL2 &run = *evt->runCtrl;
    746799
    747800    // Is this a valid event or just an empty event to trigger run close?
    748801    // If this is not an empty event open the new run-file
    749802    // Empty events are there to trigger run-closing conditions
    750     if (evt->runNum>=0)
     803    if (evt->valid())
    751804    {
    752805        // File not yet open
    753         if (run->fileStat==kFileNotYetOpen)
     806        if (run.fileStat==kFileNotYetOpen)
    754807        {
    755808            // runOpen will close a previous run, if still open
    756             if (!runOpen(evt))
     809            if (!runOpen(*evt))
    757810            {
    758811                factPrintf(MessageImp::kError, "Could not open new file for run %d (evt=%d, runOpen failed)", evt->runNum, evt->evNum);
    759                 run->fileStat = kFileClosed;
     812                run.fileStat = kFileClosed;
    760813                return;
    761814            }
    762815
    763816            factPrintf(MessageImp::kInfo, "Opened new file for run %d (evt=%d)", evt->runNum, evt->evNum);
    764             run->fileStat = kFileOpen;
     817            run.fileStat = kFileOpen;
    765818        }
    766819
    767820        // Here we have a valid calibration and can go on with that.
     821        // It is important that _all_ events are sent for calibration (except broken ones)
    768822        processingQueue1.post(evt);
    769823    }
    770824
    771825    // File already closed
    772     if (run->fileStat==kFileClosed)
     826    if (run.fileStat==kFileClosed)
    773827        return;
    774828
    775829    bool rc1 = true;
    776     if (evt->runNum>=0)
    777     {
    778         rc1 = runWrite(evt);
     830    if (evt->valid())
     831    {
     832        rc1 = runWrite(*evt);
    779833        if (!rc1)
    780834            factPrintf(MessageImp::kError, "Writing event %d for run %d failed (runWrite)", evt->evNum, evt->runNum);
    781835    }
    782836
    783     const bool cond1 =  run->lastEvt < run->maxEvt;      // max number of events not reached
    784     const bool cond2 =  run->lastTime < run->closeTime;  // max time not reached
    785     const bool cond3 =  run->closeRequest==kRequestNone; // file signaled to be closed
    786     const bool cond4 =  rc1;                             // Write successfull
     837    // File not open... no need to close or to check for close
     838    // ... this is the case if CloseRunFile was called before any file was opened.
     839    if (run.fileStat!=kFileOpen)
     840        return;
    787841
    788842    // File is not yet to be closed.
    789     if (cond1 && cond2 && cond3 && cond4)
     843    if (rc1 && evt->closeRequest==kRequestNone)
    790844        return;
    791845
    792846    runClose();
    793     run->fileStat = kFileClosed;
     847    run.fileStat = kFileClosed;
    794848
    795849    vector<string> reason;
    796     if (!cond1)
    797         reason.push_back(to_string(run->maxEvt)+" evts reached");
    798     if (!cond2)
    799         reason.push_back(to_string(run->closeTime-run->openTime)+"s reached");
    800     if (!cond3)
    801     {
    802         if (run->closeRequest&kRequestManual)
    803             reason.push_back("close requested");
    804         if (run->closeRequest&kRequestTimeout)
    805             reason.push_back("receive timeout");
    806         if (run->closeRequest&kRequestConnectionChange)
    807             reason.push_back("connection changed");
    808         if (run->closeRequest&kRequestEventCheckFailed)
    809             reason.push_back("event check failed");
    810     }
    811     if (!cond4)
    812         reason.push_back("runWrite failed");
     850    if (evt->closeRequest&kRequestManual)
     851        reason.emplace_back("close requested");
     852    if (evt->closeRequest&kRequestTimeout)
     853        reason.emplace_back("receive timeout");
     854    if (evt->closeRequest&kRequestConnectionChange)
     855        reason.emplace_back("connection changed");
     856    if (evt->closeRequest&kRequestEventCheckFailed)
     857        reason.emplace_back("event check failed");
     858    if (evt->closeRequest&kRequestMaxTimeReached)
     859        reason.push_back(to_string(run.closeTime-run.openTime)+"s reached");
     860    if (evt->closeRequest&kRequestMaxEvtsReached)
     861        reason.push_back(to_string(run.maxEvt)+" evts reached");
     862    if (!rc1)
     863        reason.emplace_back("runWrite failed");
    813864
    814865    const string str = boost::algorithm::join(reason, ", ");
     
    820871void procEvt(const shared_ptr<EVT_CTRL2> &evt)
    821872{
    822     if (evt->runNum>=0)
     873    if (evt->valid())
    823874    {
    824875        evt->fEvent->Errors[0] = evt->Errors[0];
     
    827878        evt->fEvent->Errors[3] = evt->Errors[3];
    828879
     880        evt->fEvent->PCTime = evt->time.tv_sec;
     881        evt->fEvent->PCUsec = evt->time.tv_usec;
     882
     883        evt->fEvent->NumBoards = evt->nBoard;
     884
    829885        for (int ib=0; ib<NBOARDS; ib++)
    830             evt->fEvent->BoardTime[ib] = evt->FADhead.get()[ib].time;
    831 
    832         if (!eventCheck(evt))
    833         {
    834             evt->runCtrl->closeRequest = kRequestEventCheckFailed;
     886            evt->fEvent->BoardTime[ib] = evt->FADhead[ib].time;
     887
     888        if (!eventCheck(*evt))
     889        {
     890            secondaryQueue.emplace(new EVT_CTRL2(kRequestEventCheckFailed, evt->runCtrl));
    835891            return;
    836892        }
     
    843899// ==========================================================================
    844900// ==========================================================================
    845 
    846 shared_ptr<RUN_CTRL2> actrun; // needed in CloseRunFile
    847901
    848902/*
     
    937991*/
    938992
     993Queue<shared_ptr<EVT_CTRL2>> primaryQueue(bind(&procEvt, placeholders::_1));
     994
     995// This corresponds more or less to fFile... should we merge both?
     996shared_ptr<RUN_CTRL2> actrun;
     997
    939998void CloseRunFile()
    940999{
    941     // Create a copy of the shared_ptr to ensure
    942     // is not replaced in the middle of the action
    943     const shared_ptr<RUN_CTRL2> run = actrun;
    944     if (run)
    945         run->closeRequest |= kRequestManual;
     1000    // Currently we need actrun here, to be able to set kFileClosed.
     1001    // Apart from that we have to ensure that there is an open file at all
     1002    // which we can close.
     1003    // Submission to the primary queue ensures that the event
     1004    // is placed at the right place in the processing chain.
     1005    // (Corresponds to the correct run)
     1006    primaryQueue.emplace(new EVT_CTRL2(kRequestManual, actrun));
    9461007}
    9471008
     
    9491010{
    9501011    factPrintf(MessageImp::kInfo, "Starting EventBuilder main loop");
    951 
    952     Queue<shared_ptr<EVT_CTRL2>> primaryQueue(bind(&procEvt, placeholders::_1));
    9531012
    9541013    primaryQueue.start();
    9551014    secondaryQueue.start();
     1015    processingQueue1.start();;
    9561016
    9571017    actrun = shared_ptr<RUN_CTRL2>(new RUN_CTRL2);
     
    9641024    while (g_reset == 0)
    9651025    {
     1026#ifdef USE_POLL
     1027        int    pp[40];
     1028        int    nn = 0;
     1029        pollfd fds[40];
     1030        for (int i=0; i<40; i++)
     1031        {
     1032            if (rd[i].socket>=0 && rd[i].connected && rd[i].bufLen>0)
     1033            {
     1034                fds[nn].fd = rd[i].socket;
     1035                fds[nn].events = POLLIN;
     1036                pp[nn] = i;
     1037                nn++;
     1038            }
     1039        }
     1040
     1041        const int rc_epoll = poll(fds, nn, 100);
     1042        if (rc_epoll<0)
     1043            break;
     1044#endif
     1045
    9661046#ifdef USE_SELECT
    9671047        fd_set readfs;
     
    9781058        timeval tv;
    9791059        tv.tv_sec = 0;
    980         tv.tv_usec = 100;
     1060        tv.tv_usec = 100000;
    9811061        const int rc_select = select(nfsd+1, &readfs, NULL, NULL, &tv);
    9821062        // 0: timeout
     
    9951075#endif
    9961076
    997 #ifdef USE_EPOLL
     1077#if defined(USE_POLL)
     1078        for (int jj=0; jj<nn; jj++)
     1079#endif
     1080#if defined(USE_EPOLL)
    9981081        for (int jj=0; jj<rc_epoll; jj++)
    999 #else
     1082#endif
     1083#if !defined(USE_EPOLL) && !defined(USE_POLL)
    10001084        for (int jj=0; jj<NBOARDS; jj++)
    10011085#endif
    10021086        {
     1087#ifdef USE_SELECT
     1088            if (!FD_ISSET(rs->socket, &readfs))
     1089                continue;
     1090#endif
     1091
     1092#ifdef USE_POLL
     1093            if ((fds[jj].revents&POLLIN)==0)
     1094                continue;
     1095#endif
     1096
    10031097#ifdef USE_EPOLL
    10041098            // FIXME: How to get i?
    10051099            READ_STRUCT *rs = READ_STRUCT::get(jj);
    1006 #else
    1007 
     1100#endif
     1101
     1102#ifdef USE_POLL
     1103            // FIXME: How to get i?
     1104            READ_STRUCT *rs = &rd[pp[jj]];
     1105#endif
     1106
     1107#if !defined(USE_POLL) && !defined(USE_EPOLL)
    10081108            const int i = (jj%4)*10 + (jj/4);
    10091109            READ_STRUCT *rs = &rd[i];
    1010             if (!rs->connected)
    1011                 continue;
    1012 #endif
    1013 
    1014 #ifdef USE_SELECT
    1015             if (!FD_ISSET(rs->socket, &readfs))
    1016                 continue;
    1017 #endif
    1018 
     1110#endif
    10191111
    10201112#ifdef COMPLETE_EVENTS
     
    11061198
    11071199            // We have a valid entry, but no memory has yet been allocated
    1108             if (evt && !evt->FADhead)
     1200            if (evt && !evt->initMemory())
    11091201            {
    1110                 // Try to get memory from the big buffer
    1111                 PEVNT_HEADER *mem = (PEVNT_HEADER*)Memory::malloc();
    1112                 if (!mem)
    1113                 {
    1114                     // If this works properly, this is a hack which can be removed, or
    1115                     // replaced by a signal or dim message
    1116                     if (!rs->repmem)
    1117                     {
    1118                         factPrintf(MessageImp::kError, "No free memory left for %d (run=%d)", evt->evNum, evt->runNum);
    1119                         rs->repmem = true;
    1120                     }
     1202                if (evt->reportMem)
    11211203                    continue;
    1122                 }
    1123 
    1124                 evt->initEvent(shared_ptr<PEVNT_HEADER>(mem, Memory::free));
     1204
     1205                factPrintf(MessageImp::kError, "No free memory left for %d (run=%d)", evt->evNum, evt->runNum);
     1206                evt->reportMem = true;
     1207                continue;
    11251208            }
    11261209
     
    11331216            if (!evt)
    11341217                continue;
    1135 
    1136             /*
    1137              const int fad = (i/10)<<8)|(i%10);
    1138              if (fad != rs->H.board_id)
    1139              {
    1140                  factPrintf(MessageImp::kWarn, "Board ID mismatch. Expected %x, got %x", fad, rs->H.board_id);
    1141              }*/
    11421218
    11431219            // This should never happen
     
    11611237#endif
    11621238            // now we have stored a new board contents into Event structure
    1163             evt->fEvent->NumBoards++;
    11641239            evt->board[rs->sockId] = rs->sockId;
     1240            evt->header = evt->FADhead+rs->sockId;
    11651241            evt->nBoard++;
    11661242
    11671243#ifdef COMPLETE_EPOLL
    11681244            if (epoll_ctl(READ_STRUCT::fd_epoll, EPOLL_CTL_DEL, rs->socket, NULL)<0)
     1245            {
    11691246                factPrintf(MessageImp::kError, "epoll_ctrl failed: %m (EPOLL_CTL_DEL,rc=%d)", errno);
     1247                break;
     1248            }
    11701249#endif
    11711250            // event not yet complete
     
    11991278                ev.data.ptr = &rd[j];  // user data (union: ev.ptr)
    12001279                if (epoll_ctl(READ_STRUCT::fd_epoll, EPOLL_CTL_ADD, rd[j].socket, &ev)<0)
     1280                {
    12011281                    factPrintf(MessageImp::kError, "epoll_ctl failed: %m (EPOLL_CTL_ADD,rc=%d)", errno);
     1282                    return;
     1283                }
    12021284            }
    12031285#endif
     
    12291311        if (actTime == gi_SecTime)
    12301312        {
    1231 #if !defined(USE_SELECT) && !defined(USE_EPOLL)
     1313#if !defined(USE_SELECT) && !defined(USE_EPOLL) && !defined(USE_POLL)
    12321314            if (evtCtrl.empty())
    12331315                usleep(1);
     
    12631345        }
    12641346
    1265         // If nothing was received for more than 5min, close file
    1266         if (actTime-actrun->lastTime>300)
    1267             actrun->closeRequest |= kRequestTimeout;
    1268 
    12691347        // =================================================================
    12701348
     
    12751353        gj.deltaT = 1000; // temporary, must be improved
    12761354
     1355        bool changed = false;
     1356
    12771357        for (int ib=0; ib<NBOARDS; ib++)
    12781358        {
     
    12811361
    12821362            if (rd[ib].check(g_port[ib].sockDef, g_port[ib].sockAddr))
    1283                 actrun->closeRequest |= kRequestConnectionChange;
     1363                changed = true;
    12841364
    12851365            gi_NumConnect[ib] = rd[ib].connected;
     
    12871367        }
    12881368
    1289 
    12901369        factStat(gj);
    12911370
    12921371        Memory::max_inuse = 0;
    12931372        gj.maxEvt = 0;
     1373
    12941374        for (int ib=0; ib<NBOARDS; ib++)
    12951375            rd[ib].rateBytes = 0;
     
    13011381        //        if a new file has been started and no events of the new file
    13021382        //        have been received yet
     1383        int request = kRequestNone;
     1384
     1385        // If nothing was received for more than 5min, close file
     1386        if (actTime-actrun->lastTime>300)
     1387            request |= kRequestTimeout;
     1388
     1389        // If connection status has changed
     1390        if (changed)
     1391            request |= kRequestConnectionChange;
     1392
     1393        if (request!=kRequestNone)
     1394            runFinished();
     1395
    13031396        if (actrun->fileStat==kFileOpen)
    1304             primaryQueue.post(shared_ptr<EVT_CTRL2>(new EVT_CTRL2(actrun)));
     1397            primaryQueue.emplace(new EVT_CTRL2(request, actrun));
    13051398    }
    13061399
     
    13221415    // Here we also destroy all runCtrl structures and hence close all open files
    13231416    evtCtrl.clear();
     1417    actrun.reset();
    13241418
    13251419    factPrintf(MessageImp::kInfo, "Exit read Process...");
     
    13381432    factPrintf(MessageImp::kInfo, "Starting EventBuilder++");
    13391433
    1340 
    1341     for (int k=0; k<NBOARDS; k++)
    1342     {
    1343         gi_NumConnect[k] = 0;
    1344         gj.numConn[k] = 0;
    1345         gj.totBytes[k] = 0;
    1346     }
     1434    memset(gi_NumConnect, 0, NBOARDS*sizeof(*gi_NumConnect));
     1435    memset(gj.numConn,    0, NBOARDS*sizeof(*gj.numConn));
     1436    memset(gj.totBytes,   0, NBOARDS*sizeof(*gj.totBytes));
    13471437
    13481438    gj.bufTot   = gj.maxEvt = gj.xxxEvt = 0;
Note: See TracChangeset for help on using the changeset viewer.