Commit 9a953711 authored by dino's avatar dino
Browse files

Modified CrystalProducerATCA (mainly fileATCA) to avoid DAQ blocking when...

Modified CrystalProducerATCA (mainly fileATCA) to avoid DAQ blocking when shooting long-traces if the validation rate has been set to small values.
Not yet tested in "real" use

git-svn-id: svn://gal-serv.lnl.infn.it/agata/trunk/narval_emulator@1108 170316e4-aea8-4b27-aad4-0380ec0519c9
parent 92684812
......@@ -895,6 +895,13 @@ bool CrystalProducerATCA::InitATCA(unsigned int wmask, unsigned int wsplit)
writeDataSplit = wsplit;
bool ok;
int cps = max(1, (int)fValidationRate);
// Performance on my laptop, reading from "raw" files
// cps = 0 ==> reading mezzanine-by-mezzanine ==> 300 evs/s (slow)
// cps = 1 ==> reading event-by-event ==> 1500 evs/s
// cps = 10 ==> reading blocks of 10 events ==> 6000 evs/s
// cps = 100 ==> reading blocks of 100 events ==> 8000 evs/s
// On-line performance should be checked (in the past we had ~20 kHz)
// Still to be tested is why shooting long traces kills the DAQ when cps < ~100 (?)
for(int nn = 0; nn < DAQ_NFILE; nn++) {
//ok = FA[nn].Reset(fTraceLengthRaw, 6, writeDataMask&1, odir, cps);
ok = FA[nn].Reset(fTraceLengthRaw, MZ[FA[nn].oneMezz].nChan, writeDataMask&1, odir, cps);
......@@ -939,7 +946,7 @@ unsigned int CrystalProducerATCA::NextEventATCA(unsigned int *pTimeout)
{
int retVal = EvNormal;
if(!mezzToGet) {
if(mezzToGet==0) {
// only if not yet partly filled
//DEBUG_LINE << " resetting mezzToGet " << endl;
for(int nn = 0; nn < DAQ_NMEZZ; ) mezzFound[nn++] = false;
......
......@@ -77,31 +77,33 @@ bool fileATCA::Reset(int nsamp, int nchan, bool save, std::string odirPrefix, in
int mxmezz = SIZEDMABUFF/(lenMezzTotal*2); // max number of mezzanines fitting in the buffer
int mxevts = mxmezz/max(MAXMEZZATCA,numMezz); // actual number of events (blocks of numMezz) fitting in the buffer
int nnevts = max(1, min(mxevts, cps)); // limited by cps
int nnevts = max(0, min(mxevts, cps)); // limited by cps
int lbuff = nnevts*numMezz * lenMezzTotal; // actual length needed (unsigned short)
if(lbuff < (int)lenMezzTotal) // is zero if nnevts==0
lbuff = (int)lenMezzTotal; // to read mezzanine-by-mezzanine (rather slow), also enable (#if 0-->1) limiting read to lenDataBuffer in ReadNextBuffer
if(rawDataBuffer)
delete [] rawDataBuffer;
// note that the real length of rawDataBuff is rawBuffs time the calculated value
rawDataBuffer = new unsigned short [rawBuffs*lbuff];
// note that the real length of rawDataBuffer is numRawBuffs time the calculated value
// data in the rawDataBuffer of the "other" fileDescriptor is compacted only if less than lenDataBuffer space after uMezz
lenDataBuffer = lbuff;
uBuff = NULL;
rawDataBuffer = new unsigned short [lenDataBuffer*numRawBuffs];
uMezz = nMezz = 0;
for(unsigned int nn = 0; nn < numBuffs; nn++) {
if(catched[nn].buff)
delete [] catched[nn].buff;
for(unsigned int nn = 0; nn < cacheLength; nn++) {
if(mezzCache[nn].buff)
delete [] mezzCache[nn].buff;
}
for(unsigned int nn = 0; nn < numBuffs; nn++) {
catched[nn].slot = 0xFFFFFFFF;
catched[nn].addr = NULL;
catched[nn].buff = new unsigned short [lenMezzTotal];
for(unsigned int nn = 0; nn < cacheLength; nn++) {
mezzCache[nn].slot = 0xFFFFFFFF;
mezzCache[nn].addr = NULL;
mezzCache[nn].buff = new unsigned short [lenMezzTotal];
}
totData = fixData = 0;
memset(numData, 0, sizeof(numData));
memset(indData, 0, sizeof(indData));
//memset(enabled, false, sizeof(enabled)); // contains already the values
//memset(enabled, false, sizeof(enabled)); // it should already contain the proper values
memset(dropped, 0, sizeof(dropped));
mezzSlotId_old = 0;
......@@ -149,12 +151,11 @@ int fileATCA::GetMezzanine(unsigned int slot, unsigned short *buffer)
// to retry after flushing the local cache
while(true) {
// read into empty slots of the local cache until the requested mezzanine is found
mbuff *pmb = catched;
for(unsigned int nn = 0; nn < numBuffs; nn++, pmb++) {
while(pmb->slot == 0xFFFFFFFF) {
// read into empty slots of mezzCache until the requested mezzanine is found
for(unsigned int nn = 0; nn < cacheLength; nn++) {
while(mezzCache[nn].slot == 0xFFFFFFFF) {
// Get a pointer to next mezzanine;
int retVal = GetNextMezzanine(&pmb->addr);
int retVal = GetNextMezzanine(&mezzCache[nn].addr);
if(retVal==EvAgain) {
//DEBUG_LINE << " returning " << retVal << endl;
return retVal;
......@@ -164,24 +165,24 @@ int fileATCA::GetMezzanine(unsigned int slot, unsigned short *buffer)
return retVal;
}
if(bStatistics) {
if(!CheckSequence(pmb->addr))
if(!CheckSequence(mezzCache[nn].addr))
return EvFinish;
}
unsigned int newSlot = pmb->addr[0] & 0xF;
unsigned int newSlot = mezzCache[nn].addr[0] & 0xF;
if(newSlot == slot) {
// found the right one
memcpy(buffer, pmb->addr, sizeof(unsigned short)*lenMezzTotal);
memcpy(buffer, mezzCache[nn].addr, sizeof(unsigned short)*lenMezzTotal);
return retVal;
}
else if(enabled[newSlot]) {
// not the right one; store its pointer in the cache only the mezz is enabled
pmb->slot = newSlot;
// not the right one; store its pointer in the cache only if the mezz is enabled
mezzCache[nn].slot = newSlot;
indData[newSlot][numData[newSlot]] = nn;
numData[newSlot]++;
totData++;
fixData++;
//if(nn > maxind)
// maxind = nn;
fixData++; // how many mezzanines to move from the rawDataBuffer to mezzCache
if(nn > maxCached)
maxCached = nn;
break;
}
else {
......@@ -193,25 +194,24 @@ int fileATCA::GetMezzanine(unsigned int slot, unsigned short *buffer)
numFlushed++;
bool doPrint = ( (numFlushed<10) || (numFlushed<100 && (numFlushed%10)==0) || ((numFlushed%100)==0) ) ? true : false;
pmb = catched;
if(doPrint) {
LOCK_COUT;
cout << " fileATCA_" << fileID << "{" << crystID << "} flushing catched ";
for(unsigned int nn = 0; nn < numBuffs; nn++, pmb++) {
if(pmb->slot != 0xFFFFFFFF) {
cout << " " << pmb->slot;
dropped[pmb->slot]++;
cout << " fileATCA_" << fileID << "{" << crystID << "} flushing buffer of cached mezzanines";
for(unsigned int nn = 0; nn < cacheLength; nn++) {
if(mezzCache[nn].slot != 0xFFFFFFFF) {
cout << " " << mezzCache[nn].slot;
dropped[mezzCache[nn].slot]++;
}
pmb->slot = 0xFFFFFFFF;
mezzCache[nn].slot = 0xFFFFFFFF;
}
cout << " {" << numFlushed << "}" << endl;
}
else {
for(unsigned int nn = 0; nn < numBuffs; nn++, pmb++) {
if(pmb->slot != 0xFFFFFFFF) {
dropped[pmb->slot]++;
for(unsigned int nn = 0; nn < cacheLength; nn++) {
if(mezzCache[nn].slot != 0xFFFFFFFF) {
dropped[mezzCache[nn].slot]++;
}
pmb->slot = 0xFFFFFFFF;
mezzCache[nn].slot = 0xFFFFFFFF;
}
}
memset(numData, 0, sizeof(numData));
......@@ -223,13 +223,13 @@ int fileATCA::GetMezzanine(unsigned int slot, unsigned short *buffer)
int fileATCA::GetMezzFromCache(unsigned int slot, unsigned short *buff)
{
mbuff *good = NULL;
mezzCache_t *good = NULL;
unsigned int seen = 0;
unsigned int isel = 0;
good = catched + indData[slot][0];
good = mezzCache + indData[slot][0];
if(good->slot != slot)
cout << "error" << endl;
cout << "Inconsistency in mezzCache !!!!!" << endl;
else
seen = 1;
if(numData[slot] > 1) {
......@@ -237,16 +237,16 @@ int fileATCA::GetMezzFromCache(unsigned int slot, unsigned short *buff)
unsigned short *pdat = good->addr ? good->addr : good->buff;
unsigned long long told = getTstamp(pdat);
for(unsigned int nn = 1; nn < numData[slot]; nn++) {
mbuff * pmb = catched + indData[slot][nn];
if(pmb->slot != slot)
cout << "error" << endl;
mezzCache_t * pCached = mezzCache + indData[slot][nn];
if(pCached->slot != slot)
cout << "Inconsistency in mezzCache !!!!!" << endl;
else
seen++;
unsigned short *pdat = pmb->addr ? pmb->addr : pmb->buff;
unsigned short *pdat = pCached->addr ? pCached->addr : pCached->buff;
unsigned long long tnew = getTstamp(pdat);
if(tnew < told) {
told = tnew;
good = pmb;
good = pCached;
isel = nn;
}
}
......@@ -276,7 +276,7 @@ int fileATCA::GetMezzFromCache(unsigned int slot, unsigned short *buff)
}
}
// Saving the original data and Capturing the long traces has been moved here.
// Capturing the long traces has been moved here.
int fileATCA::GetNextMezzanine(unsigned short **pmezz)
{
// Capture of long traces is limited to maxLong contiguous mezzanines to avoid
......@@ -284,54 +284,65 @@ int fileATCA::GetNextMezzanine(unsigned short **pmezz)
const int maxLong = 10;
int nLong = 0;
// continue reading until a data mezzanine is found or EvAgain (or EvFinish) have been set.
while(true) {
if(nMezz == uMezz) { // all mezzanines have been consumed
if(nMezz == uMezz) {
// all mezzanines have been consumed and we have to et the next bunch of data from this device
if(fixData)
FixCache();
uMezz = nMezz = 0;
// get next bunch of data
// In principle we could just read from the fileID ATCA-carrier (or file). However this does not work well in NRV_ONLINE case.
// First of all there could be no data to read so that we should implement non-blocking read; instead we read after polling the device
// for the presence of data so that the read always gets something (guaranteed to be an integer number of mezzanines).
// But the absence of data could be due to "backpressure" from "other" ATCA carrier if it got full awaiting its turn to be readout
// To avoid this "system hangs" situation we read the via a pollReader object which polls both carriers for data availability and
// calls fileATCA::ReadNextBuffer for those which have data.
// ReadNextBuffer called for the "fileID" board should produce data without problems because its rawDataBuffer is guaranteed to be empty
// ReadNextBuffer called for the "other" board has to check if its rawDataBuffer has enough space to read at least one mezzanine.
do {
int rval = thePR->ReadAvailableData(fileID);
int rval = thePR->ReadAvailableData(fileID); // try reading all those that have data
if(rval != EvNormal) {
//DEBUG_LINE << " returning0 " << rval << endl;
return rval;
}
if(rnb_stat==EvAgain) {
// rnb_state is set by fileATCA::ReadNextBuffer called by pollReader::ReadAvailableData
if(rnb_state==EvAgain) {
// no data produced for this fileID
//DEBUG_LINE << " returning1 " << rval << endl;
return rnb_stat;
return rnb_state;
}
if(rnb_stat==EvFinish) {
if(rnb_state==EvFinish) {
DEBUG_LINE << " returning2 " << rval << endl;
return rnb_stat;
return rnb_state;
}
}
while(uMezz == 0);
} // if(nMezz == uMezz)
// rawDataBuffer[nMezz...uMezz] contain valid mezzanines
unsigned short *uu = rawDataBuffer + nMezz*lenMezzTotal;
nMezz++;
nMezz++; // mezzanine out of rawDataBuffer
if( (uu[0]&0xFFF0) == 0xDA50 ) {
// this is mezzanine from "long trace"
if(!TraceCapture(uu)) {
DEBUG_LINE << " returning3 " << EvFinish << endl;
return EvFinish;
}
if(++nLong >= maxLong) {
//DEBUG_LINE << " returning4 " << EvAgain << endl;
return EvAgain; // give-up after a max of 10 trace-capture mezzanines
}
}
else {
// give back a pointer to the mezzanine
if( (uu[0]&0xFFF0) != 0xDA50 ) {
// unless it is a trace-capture mezzanine, pass its address back to the caller
*pmezz = uu;
return EvNewBuffer;
}
// trace-capture mezzanines are diverted to file
bool uuOK = TraceCapture(uu);
if(!uuOK) {
DEBUG_LINE << " returning3 " << EvFinish << endl;
return EvFinish;
}
if(++nLong >= maxLong) {
//DEBUG_LINE << " returning4 " << EvAgain << endl;
return EvAgain; // give-up after maxLong consecutive trace-capture mezzanines
}
} // while(true)
}
......@@ -339,13 +350,12 @@ int fileATCA::GetNextMezzanine(unsigned short **pmezz)
void fileATCA::FixCache()
{
if(fixData) {
mbuff *pmb = catched;
unsigned int seen = 0;
for(unsigned int nn = 0; nn < numBuffs; nn++, pmb++) {
if(pmb->slot != 0xFFFFFFFF) {
if(pmb->addr) {
memcpy(pmb->buff, pmb->addr, sizeof(unsigned short)*lenMezzTotal);
pmb->addr = NULL;
for(unsigned int nn = 0; nn < cacheLength; nn++) {
if(mezzCache[nn].slot != 0xFFFFFFFF) {
if(mezzCache[nn].addr) {
memcpy(mezzCache[nn].buff, mezzCache[nn].addr, sizeof(unsigned short)*lenMezzTotal);
mezzCache[nn].addr = NULL;
fixData--;
}
if(++seen == totData)
......@@ -355,79 +365,111 @@ void fileATCA::FixCache()
}
}
// dove e quanto leggere va gestito dalla classe
// se la chiamata e' stata triggerata da questo fileATCA si puo leggere tutto il buffer
// altrimenti bisogna verificare quanto 1e disponibile
// ATTENZIONE che rawDataBuffer non un buffer circolare e dunque ogni tanto
// bisogna spostare all'inizio i residui dei dati precedenti.
// If the call refers to this FileATCA (which==fileID) we can read a full buffer,
// Otherwise we must verify how much space is still available in rawDataBuffer, skipping the read if there is less than one full mezzanine.
// NOTICE: rawDataBuffer is not a circular buffer and if needed the previous data has to be shifted to its beginning
// Takes also care of writing the raw data (wmask 1)
int fileATCA::ReadNextBuffer(int which)
{
//cout << "\nReadNextBuffer - " << fileID << endl;
if(ifd < 0)
return EvFinish;
int nn = 0;
unsigned short *startFrom;
unsigned int available;
if(which == fileID) {
// the buffer is empty
startFrom = rawDataBuffer;
available = lenDataBuffer;
if(fromDAQ)
nn = aREAD(ifd, startFrom, sizeof(unsigned short)*available);
else
nn = fileREAD(ifd, startFrom, sizeof(unsigned short)*available); // to manage possible compression
if(nn<=0) {
DEBUG_LINE_N << " fileID=" << fileID << " requested=" << sizeof(unsigned short)*available << " obtained=" << nn << endl;
}
available = lenDataBuffer*numRawBuffs;
}
else {
// the buffer could already contain data
unsigned int next = CheckRawBuffer();
startFrom = rawDataBuffer + next;
available = rawBuffs*lenDataBuffer - next;
available = lenDataBuffer*numRawBuffs - next;
if(available<lenMezzTotal) {
//DEBUG_LINE_N << " fileID=" << fileID << " needed=" << lenMezzTotal << " available=" << available << endl;
rnb_state = EvAgain;
return EvAgain; // nothing has been read
}
#if 0 // enable to limit read to lenDataBuffer (meaningful only to test short reads)
if(available > lenDataBuffer)
available = lenDataBuffer;
if(fromDAQ)
nn = aREAD(ifd, startFrom, sizeof(unsigned short)*available);
else
nn = fileREAD(ifd, startFrom, sizeof(unsigned short)*available); // to manage possible compression
if(nn<=0) {
DEBUG_LINE_N << " fileID=" << fileID << " requested=" << sizeof(unsigned short)*available << " obtained=" << nn << endl;
}
#endif
// should we also check that available is a multiple of lenMezzTotal??
}
unsigned int requested = sizeof(unsigned short)*available;
int obtained = 0;
if(fromDAQ) {
obtained = aREAD(ifd, startFrom, requested);
}
else {
#if 0
// enable to test behaviour for trace-capture data
if(numCapture > 0 && enabled[indCapture])
obtained = captREAD(indCapture, startFrom, requested); // will generate fake trace-capture data
else
#endif
obtained = fileREAD(ifd, startFrom, requested); // with compressed files obtained can be smaller than requested
}
if(obtained<=0) {
DEBUG_LINE_N << " fileID=" << fileID << " (" << which << ") requested=" << requested << " obtained=" << obtained << endl;
}
// check how much was read
//DEBUG_LINE_N " fileID=" << fileID << " return value = " << nn << endl;
//// check how much was read
//DEBUG_LINE_N " fileID=" << fileID << " (" << which << ") requested=" << requested << " obtained= " << obtained << endl;
if(nn > 0) {
rnb_nbytes = nn;
uMezz += rnb_nbytes/(sizeof(unsigned short)*lenMezzTotal);
rnb_stat = EvNormal;
if(obtained > 0) {
int nmezz = obtained/(sizeof(unsigned short)*lenMezzTotal);
uMezz += nmezz;
rnb_state = EvNormal;
if(bWrite) {
if( !WriteRawData(startFrom, rnb_nbytes/sizeof(unsigned short)) ) // save the original buffer
bool OK = WriteRawData(startFrom, obtained/sizeof(unsigned short)); // save the original buffer
if( !OK) {
rnb_state = EvFinish;
return EvFinish;
}
}
#if 1
// we remove trace-capture data starting from nMezz and continuing
// until a regular mezzanine is found or all mezzanines have been consumed
while(true) {
unsigned short *uu = rawDataBuffer + nMezz*lenMezzTotal;
if( (uu[0]&0xFFF0) != 0xDA50 )
break; // not a trace-capture mezz
bool uuOK = TraceCapture(uu);
if(!uuOK) {
DEBUG_LINE << " returning3 " << EvFinish << endl;
rnb_state = EvFinish;
return EvFinish;
}
nMezz++;
if(nMezz==uMezz) {
rnb_state = EvAgain;
break;
}
}
#endif
return EvNormal;
}
// as the file did not produce data try to reopen it
// No data produced means EOF for regualr files or EOD for ATCA read
// Try reopening the file works only for regular files
DEBUG_LINE << " nn=" << nn << endl;
DEBUG_LINE " fileID=" << fileID << " requested=" << requested << " obtained=" << obtained << endl;
rnb_nbytes = 0;
int rmask = NextDataFile();
if(rmask&EvFinish) {
rnb_stat = EvFinish;
rnb_state = EvFinish;
DEBUG_LINE << " fileID=" << fileID << " EvFinish " << endl;
return EvFinish;
}
else {
rnb_stat = EvAgain; // try again on the new file
rnb_state = EvAgain; // try again on the new file
DEBUG_LINE << " fileID=" << fileID << " EvAgain " << endl;
return EvAgain;
return EvNormal;
}
}
......@@ -437,13 +479,14 @@ unsigned int fileATCA::CheckRawBuffer()
if(fixData)
FixCache();
if(nMezz<uMezz) {
if(nMezz && (rawBuffs*lenDataBuffer-uMezz*lenMezzTotal < lenDataBuffer)) {
// must shift because there is not enough space for another full buffer
memcpy(rawDataBuffer, rawDataBuffer+nMezz*lenMezzTotal, (uMezz-nMezz)*sizeof(unsigned short)*lenMezzTotal);
if(nMezz && (lenDataBuffer*numRawBuffs-lenMezzTotal*uMezz < lenDataBuffer)) {
// shift data to the beginning of the rawDataBuffer because there is not enough space after uMezz for another full buffer
// As source and destination can overlap, we must use memmove (same syntax as memcpy)
memmove(rawDataBuffer, rawDataBuffer+lenMezzTotal*nMezz, (uMezz-nMezz)*sizeof(unsigned short)*lenMezzTotal);
//DEBUG_LINE_N << " fileID=" << fileID << " nMezz=" << nMezz << " uMezz=" << uMezz << " nmezz=" << uMezz-nMezz << endl;
uMezz -= nMezz;
nMezz = 0;
// there can still be less than a full buffer
// there can still be less than a full buffer and the caller should be check for this!
}
}
else {
......@@ -680,7 +723,7 @@ bool fileATCA::DataFileOpen()
return false;
}
unsigned int dmaSize = sizeof(unsigned short)*lenDataBuffer;
cout << " Setting DMA_SIZE to " << dmaSize << endl;
cout << " Setting DMA_SIZE to " << dmaSize << "bytes" << endl;
if(ioctl(ifd, XDEV_IOCTL_DMA_SIZE, &dmaSize) == -1) {
LOCK_COUT;
cout << "IOCTL erorr on XDEV_IOCTL_DMA_SIZE " << device << endl;
......@@ -793,3 +836,19 @@ int fileATCA::fileREAD(int ifd, unsigned short *startFrom, int numbytes) {
//else
return 2*totread;
}
// setting just the first word of the header, but should try to be more realistic;
int fileATCA::captREAD(int imz, unsigned short *startFrom, int numbytes) {
unsigned short *extBuffer = startFrom;
int numMezz = numbytes/(2*lenMezzTotal);
int totDone = 0;
for(int nr = 0; nr<numMezz && numCapture>0; nr++) {
memset(extBuffer, 0, lenMezzTotal*sizeof(short));
extBuffer[0] = 0xda50 | imz&0xF;
extBuffer += lenMezzTotal;
totDone += lenMezzTotal;
numCapture--;
}
return sizeof(short)*totDone;
}
......@@ -5,10 +5,10 @@
//#include "commonDefs.h"
#include "sAppend.h"
const unsigned int MAXMEZZATCA = 4; // max number of mezzanines per carrier
const unsigned int MAXMEZZATCA = 4; // max number of mezzanines per carrier
const unsigned int SIZEDMABUFF = 4*1024*1024; // bytes (defined in the PCI-EXPRESS driver)
const unsigned int numBuffs = 32; // twice the number of slots of 2 ATCA carriers
const unsigned int rawBuffs = 4; // multiplier for the length of the read buffer
const unsigned int numRawBuffs = 4; // multiplier for the length of the read buffer
const unsigned int cacheLength = 64; // several times the number of slots of 2 ATCA carriers
// bit values used in various places
enum retValue {
......@@ -38,22 +38,23 @@ public:
numMezz(0), oneMezz(0), numChan(0), lenTrace(0), lenMezzData(0), lenMezzTotal(0),
nfiles(0), fnstep(1),
bIncrLast(false), bWrite(false), iFILE(NULL), rFILE(NULL), oldmezz(0xFFFFFFFF),
rawDataBuffer(NULL), uBuff(NULL), uMezz(0), nMezz(0),
rawDataBuffer(NULL), uMezz(0), nMezz(0),
bStatistics(false), firstevent(true), sstat1(NULL), sstat2(NULL), sstat3(NULL),
mezzSlotId_old(0), mezzEvNumb_old(0), mezzTstamp_old(0)
{
totData = fixData = 0;
memset(numData, 0, sizeof(numData));
memset(indData, 0, sizeof(indData));
memset(catched, 0, sizeof(catched));
memset(mezzCache, 0, sizeof(mezzCache));
memset(enabled, false, sizeof(enabled));
memset(dropped, 0, sizeof(dropped));
numFlushed = 0;
maxCached = 0;
rnb_state = 0;
for(int nn = 0; nn < 16; nn++)
tFILE[nn] = NULL;
//maxind = 0;
rnb_nbytes = 0;
rnb_stat = 0;
numCapture = 0;
indCapture = 0;
}
virtual ~fileATCA() {
......@@ -71,6 +72,7 @@ public:
void Enable(int nslot) { if(nslot >=0 && nslot < 16) enabled[nslot] = true; }
int Written(int nn) {return nn==0? wWritten[0] : wWritten[1];}
int Dropped(int nn) {return (nn>=0 && nn<16) ? dropped[nn] : 0;}
bool RawBuffFull() {return (nMezz!=uMezz)&&(uMezz>=numRawBuffs)?true:false;}
int fileID; // which file
int crystID; // of which crystal
......@@ -87,10 +89,9 @@ public:
private:
unsigned short *rawDataBuffer;
unsigned int lenDataBuffer; // length of rawDataBuffer (ushort)
unsigned short *uBuff; // address of data into rawDataBuffer
unsigned int lenDataBuffer; // real length of rawDataBuffer is lenDataBuffer*numRawBuffs (ushort)
unsigned int uMezz; // how many mezzanines in the consumer slot
unsigned int nMezz; // mezzanine index into uBuff
unsigned int nMezz; // index (units of lenMezzTotal) into rawDataBuffer of the next valid mezzanine
int GetMezzFromCache(unsigned int slot, unsigned short * buff);
int GetNextMezzanine(unsigned short **pmezz);
......@@ -114,7 +115,7 @@ private:
std::string ifname; // the actual data file name;
std::string rfname; // the file for writing original data;
std::string tfname; // the file for writing captured long traces;
bool enabled[16]; // will cache only valid mezzanines
bool enabled[16]; // to cache only valid mezzanines
public:
bool bWrite; // flag to write the original mezzanines to ofname
......@@ -126,19 +127,19 @@ public:
private:
typedef struct {
unsigned int slot;
unsigned short *addr;
unsigned short *buff;
} mbuff;
unsigned int numData[16]; // there are at most 16 mezzanines
unsigned int indData[16][numBuffs];// index of the stored mezzanines
unsigned int totData; // total number of cached mezzanines
unsigned int fixData; // number of entries with pointers to data, instead of data
unsigned int dropped[16]; // count number of dropped mezzanines
unsigned int numFlushed;
mbuff catched[numBuffs]; // local cache of mezzanines
//unsigned int maxind;
unsigned int slot; // identifier of cached mezzanine slot==0xFFFFFFFF if empty