mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-23 15:00:02 +02:00
117 lines
3.3 KiB
C++
117 lines
3.3 KiB
C++
/************************************************
|
|
* @file Fifo.cpp
|
|
* @short constructs the fifo structure
|
|
* which is a circular buffer with pointers to
|
|
* parts of allocated memory
|
|
***********************************************/
|
|
|
|
#include "Fifo.h"
|
|
#include "sls/sls_detector_exceptions.h"
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
|
|
Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth)
|
|
: index(ind), memory(nullptr), fifoBound(nullptr), fifoFree(nullptr),
|
|
fifoStream(nullptr), fifoDepth(depth), status_fifoBound(0),
|
|
status_fifoFree(depth) {
|
|
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
|
CreateFifos(fifoItemSize);
|
|
}
|
|
|
|
Fifo::~Fifo() {
|
|
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
|
DestroyFifos();
|
|
}
|
|
|
|
void Fifo::CreateFifos(uint32_t fifoItemSize) {
|
|
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
|
|
|
// destroy if not already
|
|
DestroyFifos();
|
|
|
|
// create fifos
|
|
fifoBound = new sls::CircularFifo<char>(fifoDepth);
|
|
fifoFree = new sls::CircularFifo<char>(fifoDepth);
|
|
fifoStream = new sls::CircularFifo<char>(fifoDepth);
|
|
// allocate memory
|
|
size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char);
|
|
memory = (char *)malloc(mem_len);
|
|
if (memory == nullptr) {
|
|
throw sls::RuntimeError("Could not allocate memory for fifos");
|
|
}
|
|
memset(memory, 0, mem_len);
|
|
int pagesize = getpagesize();
|
|
for (size_t i = 0; i < mem_len; i += pagesize) {
|
|
strcpy(memory + i, "memory");
|
|
}
|
|
LOG(logDEBUG) << "Memory Allocated " << index << ": "
|
|
<< (double)mem_len / (double)(1024 * 1024) << " MB";
|
|
|
|
{ // push free addresses into fifoFree fifo
|
|
char *buffer = memory;
|
|
for (int i = 0; i < fifoDepth; ++i) {
|
|
// sprintf(buffer,"memory");
|
|
FreeAddress(buffer);
|
|
buffer += fifoItemSize;
|
|
}
|
|
}
|
|
LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): "
|
|
<< fifoFree->getDataValue();
|
|
}
|
|
|
|
void Fifo::DestroyFifos() {
|
|
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
|
|
|
if (memory) {
|
|
free(memory);
|
|
memory = nullptr;
|
|
}
|
|
delete fifoBound;
|
|
fifoBound = nullptr;
|
|
delete fifoFree;
|
|
fifoFree = nullptr;
|
|
delete fifoStream;
|
|
fifoStream = nullptr;
|
|
}
|
|
|
|
void Fifo::FreeAddress(char *&address) { fifoFree->push(address); }
|
|
|
|
void Fifo::GetNewAddress(char *&address) {
|
|
int temp = fifoFree->getDataValue();
|
|
if (temp < status_fifoFree)
|
|
status_fifoFree = temp;
|
|
fifoFree->pop(address);
|
|
}
|
|
|
|
void Fifo::PushAddress(char *&address) {
|
|
int temp = fifoBound->getDataValue();
|
|
if (temp > status_fifoBound)
|
|
status_fifoBound = temp;
|
|
while (!fifoBound->push(address))
|
|
;
|
|
/*temp = fifoBound->getDataValue();
|
|
if (temp > status_fifoBound)
|
|
status_fifoBound = temp;*/
|
|
}
|
|
|
|
void Fifo::PopAddress(char *&address) { fifoBound->pop(address); }
|
|
|
|
void Fifo::PushAddressToStream(char *&address) { fifoStream->push(address); }
|
|
|
|
void Fifo::PopAddressToStream(char *&address) { fifoStream->pop(address); }
|
|
|
|
int Fifo::GetMaxLevelForFifoBound() {
|
|
int temp = status_fifoBound;
|
|
status_fifoBound = 0;
|
|
return temp;
|
|
}
|
|
|
|
int Fifo::GetMinLevelForFifoFree() {
|
|
int temp = status_fifoFree;
|
|
status_fifoFree = fifoDepth;
|
|
return temp;
|
|
}
|