Program Listing for File cmem_buffer.cpp
↰ Return to documentation for file (cmem_buffer.cpp)
#include <fstream>
#include <iostream>
#include <regex>
#include <cstdlib> // malloc/free
#include <cstdio>
#include <format>
#include "cmem_buffer.hpp"
#include "flxcard/FlxCard.h"
CmemBuffer::CmemBuffer(size_t mem_size, const std::string& cmem_name, bool free_prev_cmem): DmaBuffer(mem_size), free_previous_cmem(free_prev_cmem) {
int ret;
ret = CMEM_OpenNopage();
ERS_DEBUG(1, std::format("Allocating CMEM buffer {}", cmem_name.c_str()));
// free previous buffer if any and requested
if (!ret && free_prev_cmem) {
ret = CMEM_SegmentUnlockAndFree(cmem_name.c_str());
if (!ret) {
ERS_INFO(std::format("Freed previous CMEM buffer: {}", cmem_name));
} else if (RCC_ERROR_MINOR(ret) == CMEM_RCC_ILLNAME) {
ret = 0;
} else {
rcc_error_print(stdout, ret);
}
}
// allocate new one
if (!ret) {
ret = CMEM_GFPBPASegmentAllocate(mem_size, cmem_name.c_str(), &handle);
}
if (!ret) {
ret = CMEM_SegmentPhysicalAddress(handle, &paddr);
}
if (!ret) {
ret = CMEM_SegmentVirtualAddress(handle, &vaddr);
}
if (!ret) {
ret = CMEM_SegmentLock(handle);
}
if (ret) {
rcc_error_print(stdout, ret);
exit(1);
}
}
CmemBuffer::~CmemBuffer() {
ERS_DEBUG(1, std::format("Releasing CMEM buffer with handle {}", handle));
int ret = CMEM_SegmentUnlock(handle);
/* int ret = 0;
if(!ret)
ret = CMEM_GFPBPASegmentFree(handle);
if(!ret) {
ret = CMEM_Close();
}
*/
if (ret) {
rcc_error_print(stdout, ret);
exit(1);
}
}
bool CmemBuffer::cmem_buffer_exists(const std::string& cmem_name) {
// 2771 | 0 | 0x00000002ee800000 | 0x0000000010000000 | yes | 4 | felix-file2host-0-0
// \s?\d+\s+\|\s+\d+\s+\|\s+0x\w+\s+\|\s+0x\w+\s+\|\s+\w+\s+\|\s+\d+\s+\|\s
std::string regex("^"); // start
regex += "\\s?\\d+\\s+\\|"; // first number
regex += "\\s+\\d+\\s+\\|"; // number
regex += "\\s+0x\\w+\\s+\\|"; // hex-number
regex += "\\s+0x\\w+\\s+\\|"; // hex-number
regex += "\\s+\\w+\\s+\\|"; // string
regex += "\\s+\\d+\\s+\\|"; // number
regex += "\\s+"; // whitespace
regex.append(cmem_name); // cmem_name
regex += "$"; // end
std::ifstream file("/proc/cmem_rcc");
if (!file.is_open()) {
fprintf(stderr, "Can't open /proc/cmem_rcc\n" );
return false;
}
std::string line;
while (std::getline(file, line)) {
if (std::regex_match(line, std::regex(regex))) {
return true;
}
}
return false;
}
VmemBuffer::VmemBuffer(size_t mem_size) : DmaBuffer(mem_size) {
ptr = malloc(mem_size);
if (!ptr) {
ers::error(felix_log::cmem_beffer_issue(ERS_HERE, std::format("Error vmem memory allocation of {} failed", mem_size)));
throw std::runtime_error("Cannot allocate vmem buffer");
}
paddr = 0;
vaddr = reinterpret_cast<uint64_t>(ptr);
}
VmemBuffer::~VmemBuffer() {
if (vaddr) {
free(ptr);
vaddr = 0;
ptr = 0;
}
}