Commit 7b4ed52f authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by operator for beamline
Browse files

Move buffer management code to SlsDetector::BufferMgr:

* Implement Single & Dual modes for raw & processed
  image injection into Lima, respectively
* Support max_memory control similar to CtBuffer
parent dd036a08
Pipeline #41907 failed with stages
in 6 minutes and 46 seconds
......@@ -105,6 +105,7 @@ add_library(slsdetector SHARED
src/SlsDetectorReceiver.cpp
src/SlsDetectorCamera.cpp
src/SlsDetectorReconstruction.cpp
src/SlsDetectorBuffer.cpp
src/SlsDetectorEiger.cpp
src/SlsDetectorJungfrau.cpp
src/SlsDetectorInterface.cpp
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#ifndef __SLS_DETECTOR_BUFFER_H
#define __SLS_DETECTOR_BUFFER_H
#include "SlsDetectorCPUAffinity.h"
#include "lima/HwBufferMgr.h"
namespace lima
{
namespace SlsDetector
{
enum BufferType {
AcqBuffer, LimaBuffer
};
class BufferCtrlObj : public NumaSoftBufferCtrlObj {
public:
BufferCtrlObj() : m_type(AcqBuffer) {}
void releaseBuffers() { getBuffer().releaseBuffers(); }
void setType(BufferType type)
{
if (type == m_type)
return;
releaseBuffers();
m_type = type;
}
virtual void getMaxNbBuffers(int& max_nb_buffers)
{
if (m_type == LimaBuffer)
max_nb_buffers = 1024;
else
NumaSoftBufferCtrlObj::getMaxNbBuffers(max_nb_buffers);
}
Data getFrameData(FrameType frame)
{
Data d;
StdBufferCbMgr& buffer = getBuffer();
const FrameDim& frame_dim = buffer.getFrameDim();
switch (frame_dim.getImageType()) {
case Bpp8: d.type = Data::UINT8; break;
case Bpp16: d.type = Data::UINT16; break;
case Bpp32: d.type = Data::UINT32; break;
default: throw LIMA_HW_EXC(Error, "Invalid image type");
}
const Size& size = frame_dim.getSize();
d.dimensions = {size.getWidth(), size.getHeight()};
Buffer *b = new Buffer;
b->owner = Buffer::MAPPED;
b->data = buffer.getFrameBufferPtr(frame);;
d.setBuffer(b);
b->unref();
return d;
}
private:
BufferType m_type;
};
class BufferMgr
{
DEB_CLASS_NAMESPC(DebModCamera, "BufferMgr", "SlsDetector");
public:
enum Mode { Single, Dual };
void setLimaBufferCtrlObj(BufferCtrlObj *buffer_ctrl_obj);
void setAcqBufferCPUAffinity(CPUAffinity buffer_affinity);
char *getAcqFrameBufferPtr(FrameType frame_nb);
BufferCtrlObj *getBufferCtrlObj(BufferType type)
{
bool lima = ((type == LimaBuffer) || (m_mode == Single));
return lima ? m_lima_buffer_ctrl_obj :
m_acq_buffer_ctrl_obj.getPtr();
}
StdBufferCbMgr *getBufferCbMgr(BufferType type)
{
BufferCtrlObj *buffer = getBufferCtrlObj(type);
return buffer ? &buffer->getBuffer() : NULL;
}
void setMaxMemory(short max_memory);
void getMaxMemory(short& max_memory);
void getMaxNbBuffers(long& nb_buffers);
void setMode(Mode mode);
void getMode(Mode& mode);
void prepareAcq();
void clearAllBuffers();
void releaseBuffers();
private:
friend class Camera;
BufferMgr(Camera *cam);
Camera *m_cam;
Mode m_mode;
CPUAffinity m_buffer_affinity;
BufferCtrlObj *m_lima_buffer_ctrl_obj;
AutoPtr<BufferCtrlObj> m_acq_buffer_ctrl_obj;
int m_max_memory;
};
} // namespace SlsDetector
} // namespace lima
#endif // __SLS_DETECTOR_BUFFER_H
......@@ -29,7 +29,6 @@
#include "sls/Detector.h"
#include "lima/HwBufferMgr.h"
#include "lima/HwMaxImageSizeCallback.h"
#include "lima/Event.h"
......@@ -41,58 +40,6 @@ namespace lima
namespace SlsDetector
{
enum BufferType {
AcqBuffer, LimaBuffer
};
class BufferCtrlObj : public NumaSoftBufferCtrlObj {
public:
BufferCtrlObj() : m_type(AcqBuffer) {}
void releaseBuffers() { getBuffer().releaseBuffers(); }
void setType(BufferType type)
{
if (type == m_type)
return;
releaseBuffers();
m_type = type;
}
virtual void getMaxNbBuffers(int& max_nb_buffers)
{
if (m_type == LimaBuffer)
max_nb_buffers = 1024;
else
NumaSoftBufferCtrlObj::getMaxNbBuffers(max_nb_buffers);
}
Data getFrameData(FrameType frame)
{
Data d;
StdBufferCbMgr& buffer = getBuffer();
const FrameDim& frame_dim = buffer.getFrameDim();
switch (frame_dim.getImageType()) {
case Bpp8: d.type = Data::UINT8; break;
case Bpp16: d.type = Data::UINT16; break;
case Bpp32: d.type = Data::UINT32; break;
default: throw LIMA_HW_EXC(Error, "Invalid image type");
}
const Size& size = frame_dim.getSize();
d.dimensions = {size.getWidth(), size.getHeight()};
Buffer *b = new Buffer;
b->owner = Buffer::MAPPED;
b->data = buffer.getFrameBufferPtr(frame);;
d.setBuffer(b);
b->unref();
return d;
}
private:
BufferType m_type;
};
class Eiger;
class Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGen
......@@ -127,15 +74,12 @@ public:
Receiver* getRecv(int i)
{ return m_recv_list[i]; }
void setBufferCtrlObj(BufferCtrlObj *buffer_ctrl_obj,
BufferType type = LimaBuffer);
BufferMgr *getBuffer()
{ return &m_buffer; }
void setModuleActive(int mod_idx, bool active);
void getModuleActive(int mod_idx, bool& active);
void clearAllBuffers();
void releaseBuffers();
void setPixelDepth(PixelDepth pixel_depth);
void getPixelDepth(PixelDepth& pixel_depth);
......@@ -274,6 +218,7 @@ private:
FrameQueue m_frame_queue;
};
friend class BufferMgr;
friend class Model;
friend class Receiver;
friend class GlobalCPUAffinityMgr;
......@@ -298,21 +243,6 @@ private:
AcqState getEffectiveState();
BufferCtrlObj **getBufferCtrlObjPtr(BufferType type)
{
return (type == AcqBuffer) ? &m_acq_buffer_ctrl_obj :
&m_lima_buffer_ctrl_obj;
}
StdBufferCbMgr *getBufferCbMgr(BufferType type)
{
BufferCtrlObj *buffer = *getBufferCtrlObjPtr(type);
return buffer ? &buffer->getBuffer() : NULL;
}
void setAcqBufferCPUAffinity(CPUAffinity buffer_affinity);
char *getAcqFrameBufferPtr(FrameType frame_nb);
void removeSharedMem();
void createReceivers();
......@@ -367,9 +297,7 @@ private:
double m_lat_time;
double m_frame_period;
Settings m_settings;
CPUAffinity m_buffer_affinity;
BufferCtrlObj *m_acq_buffer_ctrl_obj;
BufferCtrlObj *m_lima_buffer_ctrl_obj;
BufferMgr m_buffer;
PixelDepth m_pixel_depth;
ImageType m_image_type;
bool m_raw_mode;
......
......@@ -538,7 +538,6 @@ class Jungfrau : public Model
std::string m_img_proc_config;
ImgProcList m_img_proc_list;
ImgSrc m_img_src;
BufferCtrlObj m_acq_buffer_ctrl_obj;
ModelReconstruction *m_reconstruction;
RecvList m_recv_list;
FrameType m_nb_frames;
......
......@@ -26,6 +26,7 @@
#include "SlsDetectorDefs.h"
#include "SlsDetectorCPUAffinity.h"
#include "SlsDetectorReconstruction.h"
#include "SlsDetectorBuffer.h"
#include "lima/SizeUtils.h"
......@@ -111,6 +112,8 @@ class Model
void processFinishInfo(const FinishInfo& finfo);
BufferMgr *getBuffer();
private:
friend class Camera;
friend class Receiver;
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
namespace SlsDetector
{
%TypeHeaderCode
#include "SlsDetectorBuffer.h"
%End
class BufferMgr
{
public:
enum Mode { Single, Dual };
void setMode(SlsDetector::BufferMgr::Mode mode);
void getMode(SlsDetector::BufferMgr::Mode& mode /Out/);
void setMaxMemory(short max_memory);
void getMaxMemory(short& max_memory /Out/);
void getMaxNbBuffers(long& nb_buffers /Out/);
void clearAllBuffers();
void releaseBuffers();
private:
BufferMgr(Camera *cam);
};
}; // namespace SlsDetector
......@@ -41,8 +41,7 @@ public:
void setModuleActive(int mod_idx, bool active);
void getModuleActive(int mod_idx, bool& active /Out/);
void clearAllBuffers();
void releaseBuffers();
SlsDetector::BufferMgr *getBuffer();
void setPixelDepth(SlsDetector::PixelDepth pixel_depth);
void getPixelDepth(SlsDetector::PixelDepth& pixel_depth /Out/);
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#include "SlsDetectorCamera.h"
using namespace std;
using namespace lima;
using namespace lima::SlsDetector;
BufferMgr::BufferMgr(Camera *cam)
: m_cam(cam), m_mode(Single), m_lima_buffer_ctrl_obj(NULL),
m_max_memory(70)
{
DEB_CONSTRUCTOR();
}
void BufferMgr::setMode(Mode mode)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(mode, m_mode);
if (mode == m_mode)
return;
m_mode = mode;
m_acq_buffer_ctrl_obj = (m_mode == Dual) ? new BufferCtrlObj() : NULL;
DEB_TRACE() << DEB_VAR2(m_lima_buffer_ctrl_obj, m_acq_buffer_ctrl_obj);
BufferCtrlObj *buffer;
buffer = getBufferCtrlObj(AcqBuffer);
if (buffer) {
buffer->setType(AcqBuffer);
buffer->setCPUAffinityMask(m_buffer_affinity);
}
buffer = getBufferCtrlObj(LimaBuffer);
if (buffer && (m_mode == Dual)) {
buffer->setType(LimaBuffer);
buffer->setCPUAffinityMask(CPUAffinity());
}
Model *model = m_cam->m_model;
if (!model)
return;
if (m_acq_buffer_ctrl_obj) {
FrameDim frame_dim;
model->getAcqFrameDim(frame_dim, m_cam->m_raw_mode);
m_acq_buffer_ctrl_obj->setFrameDim(frame_dim);
}
m_cam->updateImageSize();
}
void BufferMgr::getMode(Mode& mode)
{
DEB_MEMBER_FUNCT();
mode = m_mode;
DEB_RETURN() << DEB_VAR1(mode);
}
void BufferMgr::setLimaBufferCtrlObj(BufferCtrlObj *buffer_ctrl_obj)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(m_lima_buffer_ctrl_obj, buffer_ctrl_obj);
m_lima_buffer_ctrl_obj = buffer_ctrl_obj;
}
char *BufferMgr::getAcqFrameBufferPtr(FrameType frame_nb)
{
DEB_MEMBER_FUNCT();
StdBufferCbMgr *cb_mgr = getBufferCbMgr(AcqBuffer);
if (!cb_mgr)
THROW_HW_ERROR(InvalidValue) << "No BufferCbMgr defined";
void *ptr = cb_mgr->getFrameBufferPtr(frame_nb);
return static_cast<char *>(ptr);
}
void BufferMgr::setAcqBufferCPUAffinity(CPUAffinity buffer_affinity)
{
DEB_MEMBER_FUNCT();
DEB_ALWAYS() << DEB_VAR1(buffer_affinity);
BufferCtrlObj *buffer = getBufferCtrlObj(AcqBuffer);
if (buffer)
buffer->setCPUAffinityMask(buffer_affinity);
m_buffer_affinity = buffer_affinity;
}
void BufferMgr::setMaxMemory(short max_memory)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(max_memory);
if ((max_memory <= 0) || (max_memory > 100))
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(max_memory);
m_max_memory = max_memory;
}
void BufferMgr::getMaxMemory(short& max_memory)
{
DEB_MEMBER_FUNCT();
max_memory = m_max_memory;
DEB_RETURN() << DEB_VAR1(max_memory);
}
void BufferMgr::getMaxNbBuffers(long& nb_buffers)
{
DEB_MEMBER_FUNCT();
if (m_acq_buffer_ctrl_obj) {
int max_nb_buffers;
m_acq_buffer_ctrl_obj->getMaxNbBuffers(max_nb_buffers);
nb_buffers = int(max_nb_buffers * m_max_memory / 100.0);
DEB_TRACE() << DEB_VAR2(max_nb_buffers, nb_buffers);
} else {
nb_buffers = 0;
}
DEB_RETURN() << DEB_VAR1(nb_buffers);
}
void BufferMgr::prepareAcq()
{
DEB_MEMBER_FUNCT();
if (m_acq_buffer_ctrl_obj) {
FrameType nb_frames;
m_cam->getNbFrames(nb_frames);
long max_nb_buffers;
getMaxNbBuffers(max_nb_buffers);
int nb_buffers = (nb_frames < max_nb_buffers) ? nb_frames :
max_nb_buffers;
m_acq_buffer_ctrl_obj->setNbBuffers(nb_buffers);
}
}
void BufferMgr::releaseBuffers()
{
DEB_MEMBER_FUNCT();
bool prev_release_unused;
BufferCtrlObj::getBufferMgrResizePolicy(prev_release_unused);
BufferCtrlObj::setBufferMgrResizePolicy(true);
if (m_acq_buffer_ctrl_obj)
m_acq_buffer_ctrl_obj->releaseBuffers();
if (m_lima_buffer_ctrl_obj)
m_lima_buffer_ctrl_obj->releaseBuffers();
BufferCtrlObj::setBufferMgrResizePolicy(prev_release_unused);
}
void BufferMgr::clearAllBuffers()
{
DEB_MEMBER_FUNCT();
StdBufferCbMgr *buffer;
buffer = getBufferCbMgr(AcqBuffer);
if (buffer)
buffer->clearAllBuffers();
buffer = getBufferCbMgr(LimaBuffer);
if (buffer && (m_mode == Dual))
buffer->clearAllBuffers();
Camera::RecvList::iterator it, end = m_cam->m_recv_list.end();
for (it = m_cam->m_recv_list.begin(); it != end; ++it)
(*it)->clearAllBuffers();
}
......@@ -1621,7 +1621,7 @@ void GlobalCPUAffinityMgr::setModelAffinity(
m_cam->m_model->setThreadCPUAffinity(model_affinity_list);
CPUAffinity buffer_affinity = CPUAffinityList_all(model_affinity_list);
m_cam->setAcqBufferCPUAffinity(buffer_affinity);
m_cam->m_buffer.setAcqBufferCPUAffinity(buffer_affinity);
m_curr.model_threads = model_affinity_list;
}
......
......@@ -315,7 +315,7 @@ Camera::AcqThread::Status Camera::AcqThread::newFrameReady(FrameType frame)
DEB_MEMBER_FUNCT();
HwFrameInfoType frame_info;
frame_info.acq_frame_nb = frame;
StdBufferCbMgr *cb_mgr = m_cam->getBufferCbMgr(LimaBuffer);
StdBufferCbMgr *cb_mgr = m_cam->m_buffer.getBufferCbMgr(LimaBuffer);
bool cont_acq = cb_mgr->newFrameReady(frame_info);
bool acq_end = (frame == m_cam->m_lima_nb_frames - 1);
cont_acq &= !acq_end;
......@@ -331,8 +331,7 @@ Camera::Camera(string config_fname, int det_id)
m_skip_frame_freq(0),
m_last_skipped_frame_timeout(0.5),
m_lat_time(0),
m_acq_buffer_ctrl_obj(NULL),
m_lima_buffer_ctrl_obj(NULL),
m_buffer(this),
m_pixel_depth(PixelDepth16),
m_image_type(Bpp16),
m_raw_mode(false),
......@@ -442,76 +441,6 @@ void Camera::setModel(Model *model)
setPixelDepth(m_pixel_depth);
}
void Camera::setBufferCtrlObj(BufferCtrlObj *buffer_ctrl_obj, BufferType type)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR3(m_lima_buffer_ctrl_obj, m_acq_buffer_ctrl_obj,
buffer_ctrl_obj);
if (type == LimaBuffer) {
if (m_acq_buffer_ctrl_obj == m_lima_buffer_ctrl_obj) {
DEB_TRACE() << "Setting both Lima & Acq buffer";
m_acq_buffer_ctrl_obj = buffer_ctrl_obj;
} else {
DEB_TRACE() << "Setting only Lima buffer";
}
m_lima_buffer_ctrl_obj = buffer_ctrl_obj;
} else if (buffer_ctrl_obj) {
DEB_TRACE() << "Setting only Acq buffer";
m_acq_buffer_ctrl_obj = buffer_ctrl_obj;
} else {
DEB_TRACE() << "Resetting Acq buffer to LimaBuffer";
m_acq_buffer_ctrl_obj = m_lima_buffer_ctrl_obj;
}
DEB_TRACE() << DEB_VAR2(m_lima_buffer_ctrl_obj, m_acq_buffer_ctrl_obj);
BufferCtrlObj *buffer;
buffer = m_acq_buffer_ctrl_obj;
if (buffer) {
buffer->setType(AcqBuffer);
buffer->setCPUAffinityMask(m_buffer_affinity);
}
buffer = m_lima_buffer_ctrl_obj;
if (buffer && (buffer != m_acq_buffer_ctrl_obj)) {
buffer->setType(LimaBuffer);
buffer->setCPUAffinityMask(CPUAffinity());
}
if (m_model)