Commit 55fd8a23 authored by ahoms's avatar ahoms
Browse files

* moved GetSystemMemory to MemUtils, added GetPageSize

* added virtual buffer management in Espia class



git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@54 45c4679d-1946-429d-baad-37912b19538b
parent a9eec1a2
#ifndef ESPIA_H
#define ESPIA_H
#include "SizeUtils.h"
#include "Exceptions.h"
#include "HwFrameInfo.h"
#include "espia_lib.h"
#include <string>
namespace lima
......@@ -18,6 +22,18 @@ class Espia
Espia(int dev_nr);
~Espia();
void bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
int buffer_frames);
void bufferFree();
void getFrameDim(FrameDim& frame_dim);
void getNbBuffers(int& nb_buffers);
void getBufferFrames(int& buffer_frames);
void *getBufferFramePtr(int buffer_nb, int frame_nb = 0);
void *getAcqFramePtr(int acq_frame_nb);
void getFrameInfo(int acq_frame_nb, HwFrameInfoType& info);
void serWrite(const std::string& buffer,
int block_size = 0, double block_delay = 0,
bool no_wait = false);
......@@ -32,11 +48,25 @@ class Espia
private:
void open(int dev_nr);
void close();
unsigned long sec2us(double sec);
unsigned long sec2usec(double sec);
double usec2sec(unsigned long usec);
bool hasVirtualBuffers();
int realBufferNb(int virt_buffer, int virt_frame);
int realFrameNb (int virt_buffer, int virt_frame);
int virtBufferNb(int real_buffer, int real_frame);
int virtFrameNb (int real_buffer, int real_frame);
void real2virtFrameInfo(const struct img_frame_info& real_info,
HwFrameInfoType& virt_info);
int m_dev_nr;
espia_t m_dev;
FrameDim m_frame_dim;
int m_nb_buffers;
int m_buffer_frames;
int m_real_frame_factor;
int m_real_frame_size;
};
#define ESPIA_CHECK_CALL(ret) \
......@@ -48,11 +78,41 @@ class Espia
} while (0)
inline unsigned long Espia::sec2us(double sec)
inline unsigned long Espia::sec2usec(double sec)
{
return (unsigned long) (sec * 1e6);
}
inline double Espia::usec2sec(unsigned long usec)
{
return usec * 1e-6;
}
inline bool Espia::hasVirtualBuffers()
{
return m_real_frame_factor != 1;
}
inline int Espia::realBufferNb(int virt_buffer, int virt_frame)
{
return virt_buffer / m_real_frame_factor;
}
inline int Espia::realFrameNb (int virt_buffer, int virt_frame)
{
return virt_buffer % m_real_frame_factor + virt_frame;
}
inline int Espia::virtBufferNb(int real_buffer, int real_frame)
{
return (real_buffer * m_real_frame_factor +
real_frame / m_buffer_frames);
}
inline int Espia::virtFrameNb (int real_buffer, int real_frame)
{
return real_frame % m_buffer_frames;
}
} // namespace lima
......
#include "Espia.h"
#include "MemUtils.h"
using namespace lima;
using namespace std;
#define CHECK_CALL(ret) ESPIA_CHECK_CALL(ret)
#define ESPIA_MIN_BUFFER_SIZE (128 * 1024)
Espia::Espia(int dev_nr)
: m_dev_nr(Invalid), m_dev(ESPIA_DEV_INVAL)
{
m_dev_nr = Invalid;
m_dev = ESPIA_DEV_INVAL;
m_nb_buffers = m_buffer_frames = 0;
m_real_frame_factor = m_real_frame_size = 0;
open(dev_nr);
}
......@@ -32,18 +41,136 @@ void Espia::close()
if (m_dev_nr == Invalid)
return;
bufferFree();
CHECK_CALL(espia_close(m_dev));
m_dev = ESPIA_DEV_INVAL;
m_dev_nr = Invalid;
}
void Espia::bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
int buffer_frames)
{
if (!frame_dim.isValid() || (nb_buffers <= 0) || (buffer_frames <= 0))
throw LIMA_HW_EXC(InvalidValue, "Invalid frame_dim, "
"nb_buffers and/or buffer_frames");
if ((frame_dim == m_frame_dim) && (nb_buffers == m_nb_buffers) &&
(buffer_frames == m_buffer_frames))
return;
bufferFree();
int& virt_buffers = nb_buffers;
int& virt_frames = buffer_frames;
int real_buffers = virt_buffers;
int real_frames = virt_frames;
int real_frame_size = frame_dim.getMemSize();
if (virt_frames == 1) {
int page_size;
GetPageSize(page_size);
real_frame_size += page_size - 1;
real_frame_size &= ~(page_size - 1);
}
int real_buffer_size = real_frame_size * real_frames;
int frame_factor = 1;
if (real_buffer_size < ESPIA_MIN_BUFFER_SIZE) {
frame_factor = ESPIA_MIN_BUFFER_SIZE / real_buffer_size;
real_frames *= frame_factor;
real_buffers += frame_factor - 1;
real_buffers /= frame_factor;
virt_buffers = real_buffers * frame_factor;
}
CHECK_CALL(espia_buffer_alloc(m_dev, real_buffers, real_frames,
real_frame_size));
m_frame_dim = frame_dim;
m_nb_buffers = virt_buffers;
m_buffer_frames = virt_frames;
m_real_frame_factor = frame_factor;
m_real_frame_size = real_frame_size;
}
void Espia::bufferFree()
{
if ((m_nb_buffers == 0) || (m_buffer_frames == 0))
return;
CHECK_CALL(espia_buffer_free(m_dev));
m_frame_dim = FrameDim();
m_nb_buffers = m_buffer_frames = 0;
m_real_frame_factor = m_real_frame_size = 0;
}
void Espia::getFrameDim(FrameDim& frame_dim)
{
frame_dim = m_frame_dim;
}
void Espia::getNbBuffers(int& nb_buffers)
{
nb_buffers = m_nb_buffers;
}
void Espia::getBufferFrames(int& buffer_frames)
{
buffer_frames = m_buffer_frames;
}
void *Espia::getBufferFramePtr(int buffer_nb, int frame_nb)
{
int real_buffer = realBufferNb(buffer_nb, frame_nb);
int real_frame = realFrameNb(buffer_nb, frame_nb);
void *ptr;
CHECK_CALL(espia_frame_address(m_dev, real_buffer, real_frame, &ptr));
return ptr;
}
void *Espia::getAcqFramePtr(int acq_frame_nb)
{
int buffer_nb = ESPIA_ACQ_ANY;
void *ptr;
CHECK_CALL(espia_frame_address(m_dev, buffer_nb, acq_frame_nb, &ptr));
return ptr;
}
void Espia::getFrameInfo(int acq_frame_nb, HwFrameInfoType& info)
{
struct img_frame_info finfo;
finfo.buffer_nr = ESPIA_ACQ_ANY;
finfo.frame_nr = ESPIA_ACQ_ANY;
finfo.round_count = ESPIA_ACQ_ANY;
finfo.acq_frame_nr = acq_frame_nb;
CHECK_CALL(espia_get_frame(m_dev, &finfo, SCDXIPCI_NO_BLOCK));
real2virtFrameInfo(finfo, info);
}
void Espia::real2virtFrameInfo(const struct img_frame_info& real_info,
HwFrameInfoType& virt_info)
{
char *buffer_ptr = (char *) real_info.buffer_ptr;
int frame_offset = real_info.frame_nr * m_real_frame_size;
virt_info.acq_frame_nb = real_info.acq_frame_nr;
virt_info.frame_ptr = buffer_ptr + frame_offset;
virt_info.frame_dim = &m_frame_dim;
virt_info.frame_timestamp = usec2sec(real_info.time_us);
virt_info.valid_pixels = real_info.pixels;
}
void Espia::serWrite(const string& buffer, int block_size, double block_delay,
bool no_wait)
{
unsigned long len = buffer.length();
char *ptr = len ? (char *) buffer.data() : NULL;
CHECK_CALL(espia_ser_write(m_dev, ptr, &len, block_size,
sec2us(block_delay), !no_wait));
sec2usec(block_delay), !no_wait));
}
void Espia::serRead(string& buffer, int len, double timeout)
......@@ -51,7 +178,7 @@ void Espia::serRead(string& buffer, int len, double timeout)
buffer.resize(len);
char *ptr = len ? (char *) buffer.data() : NULL;
unsigned long ret_len = len;
CHECK_CALL(espia_ser_read(m_dev, ptr, &ret_len, sec2us(timeout)));
CHECK_CALL(espia_ser_read(m_dev, ptr, &ret_len, sec2usec(timeout)));
buffer.resize(ret_len);
}
......@@ -63,7 +190,7 @@ void Espia::serReadStr(string& buffer, int len, const string& term,
char *term_ptr = (char *) term.data();
unsigned long ret_len = len;
CHECK_CALL(espia_ser_read_str(m_dev, ptr, &ret_len, term_ptr,
term.length(), sec2us(timeout)));
term.length(), sec2usec(timeout)));
buffer.resize(ret_len);
}
......
#ifndef MEMUTILS_H
#define MEMUTILS_H
namespace lima
{
void GetSystemMem(int& mem_unit, int& system_mem);
void GetPageSize(int& page_size);
} // namespace lima
#endif // MEMUTILS_H
common-objs := Constants.o SizeUtils.o Timestamp.o ThreadUtils.o Exceptions.o \
BufferSave.o
BufferSave.o MemUtils.o
CXXFLAGS += -I../include -I../../hardware/include -Wall -pthread
......
#include "MemUtils.h"
#include "Exceptions.h"
#include <sys/sysinfo.h>
#include <limits.h>
#include <unistd.h>
using namespace lima;
void lima::GetSystemMem(int& mem_unit, int& system_mem)
{
if (mem_unit < 0)
throw LIMA_HW_EXC(InvalidValue, "Invalid mem_unit value");
struct sysinfo s_info;
if (sysinfo(&s_info) < 0)
throw LIMA_HW_EXC(Error, "Error calling sysinfo");
long long tot_mem = s_info.totalram;
tot_mem *= s_info.mem_unit;
if (mem_unit == 0)
mem_unit = s_info.mem_unit;
long long huge_blocks = tot_mem / mem_unit;
if (huge_blocks > INT_MAX)
throw LIMA_HW_EXC(Error, "Too much memory to be described "
"with the given mem_unit");
system_mem = huge_blocks;
}
void lima::GetPageSize(int& page_size)
{
page_size = getpagesize();
}
......@@ -48,8 +48,6 @@ class SoftBufferAllocMgr : public BufferAllocMgr
SoftBufferAllocMgr();
virtual ~SoftBufferAllocMgr();
static int getSystemMem(int& mem_unit);
virtual int getMaxNbBuffers(const FrameDim& frame_dim);
virtual void allocBuffers(int nb_buffers,
const FrameDim& frame_dim);
......@@ -102,7 +100,7 @@ class BufferCbMgr : public HwFrameCallbackGen
virtual void setStartTimestamp(Timestamp start_ts) = 0;
virtual void getStartTimestamp(Timestamp& start_ts) = 0;
virtual void getFrameInfo(int buffer_nb, HwFrameInfoType& info) = 0;
virtual void getFrameInfo(int acq_frame_nb, HwFrameInfoType& info) = 0;
};
......
#include <cstring>
#include "HwBufferMgr.h"
#include <sys/sysinfo.h>
#include <limits.h>
#include "MemUtils.h"
#include <cstring>
using namespace lima;
......@@ -41,36 +39,15 @@ SoftBufferAllocMgr::~SoftBufferAllocMgr()
releaseBuffers();
}
int SoftBufferAllocMgr::getSystemMem(int& mem_unit)
{
if (mem_unit < 0)
throw LIMA_HW_EXC(InvalidValue, "Invalid mem_unit value");
struct sysinfo s_info;
if (sysinfo(&s_info) < 0)
throw LIMA_HW_EXC(Error, "Error calling sysinfo");
long long tot_mem = s_info.totalram;
tot_mem *= s_info.mem_unit;
if (mem_unit == 0)
mem_unit = s_info.mem_unit;
long long mem_blocks = tot_mem / mem_unit;
if (mem_blocks > INT_MAX)
throw LIMA_HW_EXC(Error, "Too much memory to be described "
"with the given mem_unit");
return mem_blocks;
}
int SoftBufferAllocMgr::getMaxNbBuffers(const FrameDim& frame_dim)
{
int frame_size = frame_dim.getMemSize();
if (frame_size <= 0)
throw LIMA_HW_EXC(InvalidValue, "Invalid FrameDim");
long long tot_buffers = getSystemMem(frame_size);
return tot_buffers * 3 / 4;
int tot_buffers;
GetSystemMem(frame_size, tot_buffers);
return (long long) tot_buffers * 3 / 4;
}
void SoftBufferAllocMgr::allocBuffers(int nb_buffers,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment