Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jens Krüger
Lima
Commits
ccaf48f1
Commit
ccaf48f1
authored
Oct 23, 2012
by
Sebastien Petitdemange
Browse files
Add HwBufferMgr which manage tmpfs (memory filesystem)
parent
32b7417b
Changes
3
Hide whitespace changes
Inline
Side-by-side
hardware/include/HwFileEventMgr.h
0 → 100644
View file @
ccaf48f1
//###########################################################################
// 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 HWFILEEVENT_H
#define HWFILEEVENT_H
#ifdef __linux__
#include
"DirectoryEventUtils.h"
#include
"HwFrameInfo.h"
#include
"HwFrameCallback.h"
#include
"HwBufferCtrlObj.h"
namespace
lima
{
class
HwFileEventCallbackHelper
:
public
DirectoryEvent
::
Callback
{
public:
class
Callback
{
public:
virtual
void
prepare
(
const
DirectoryEvent
::
Parameters
&
)
{}
virtual
bool
getFrameInfo
(
int
image_number
,
const
char
*
full_path
,
HwFrameInfoType
&
)
=
0
;
virtual
bool
newFrameReady
(
const
HwFrameInfoType
&
)
=
0
;
};
HwFileEventCallbackHelper
(
Callback
&
cbk
)
:
m_cbk
(
cbk
)
{};
virtual
void
prepare
(
const
DirectoryEvent
::
Parameters
&
params
);
virtual
bool
nextFileExpected
(
int
file_number
,
const
char
*
full_path
,
int
&
next_file_number_expected
)
throw
();
virtual
bool
newFile
(
int
file_number
,
const
char
*
full_path
)
throw
();
private:
typedef
std
::
map
<
int
,
HwFrameInfoType
>
DatasPendingType
;
DatasPendingType
m_pending_frame_infos
;
Callback
&
m_cbk
;
};
class
HwTmpfsBufferMgr
:
public
HwBufferCtrlObj
,
public
HwFrameCallbackGen
{
DEB_CLASS_NAMESPC
(
DebModHardware
,
"HwTmpfsBufferMgr"
,
"Hardware"
);
public:
class
Callback
{
public:
virtual
bool
getFrameInfo
(
int
image_number
,
const
char
*
full_path
,
HwFrameInfoType
&
)
=
0
;
virtual
void
getFrameDim
(
FrameDim
&
frame_dim
)
=
0
;
};
HwTmpfsBufferMgr
(
const
char
*
tmpfs_path
,
const
char
*
file_pattern
,
Callback
&
cbk
);
~
HwTmpfsBufferMgr
();
void
setMemoryPercent
(
double
);
void
setNextExpectedImageNumber
(
int
);
void
prepare
();
void
start
();
void
stop
();
bool
isStopped
()
const
;
int
getLastAcquiredFrame
()
const
;
//methodes used by Lima core
virtual
void
setFrameDim
(
const
FrameDim
&
frame_dim
);
virtual
void
getFrameDim
(
FrameDim
&
frame_dim
);
virtual
void
setNbBuffers
(
int
nb_buffers
);
virtual
void
getNbBuffers
(
int
&
nb_buffers
);
virtual
void
setNbConcatFrames
(
int
nb_concat_frames
);
virtual
void
getNbConcatFrames
(
int
&
nb_concat_frames
);
virtual
void
getMaxNbBuffers
(
int
&
max_nb_buffers
);
virtual
void
*
getBufferPtr
(
int
buffer_nb
,
int
concat_frame_nb
=
0
);
virtual
void
*
getFramePtr
(
int
acq_frame_nb
);
virtual
void
getStartTimestamp
(
Timestamp
&
start_ts
);
virtual
void
getFrameInfo
(
int
acq_frame_nb
,
HwFrameInfoType
&
info
);
virtual
void
registerFrameCallback
(
HwFrameCallback
&
frame_cb
);
virtual
void
unregisterFrameCallback
(
HwFrameCallback
&
frame_cb
);
private:
class
_CBK
;
friend
class
_CBK
;
int
_calcNbMaxImages
();
bool
_getFrameInfo
(
int
image_number
,
const
char
*
full_path
,
HwFrameInfoType
&
frame_info
);
std
::
string
m_tmpfs_path
;
std
::
string
m_file_pattern
;
int
m_next_expected_image_number
;
int
m_keep_nb_images
;
double
m_memory_percent
;
_CBK
*
m_internal_cbk
;
HwFileEventCallbackHelper
m_directory_cbk
;
DirectoryEvent
m_directory_event
;
Callback
&
m_cbk
;
Timestamp
m_start_time
;
};
}
#endif
#endif
hardware/src/HwFileEventMgr.cpp
0 → 100644
View file @
ccaf48f1
//###########################################################################
// 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
<dirent.h>
#include
<stdlib.h>
#include
<sys/statvfs.h>
#include
<sys/types.h>
#include
"HwFileEventMgr.h"
using
namespace
lima
;
void
HwFileEventCallbackHelper
::
prepare
(
const
DirectoryEvent
::
Parameters
&
params
)
{
//Clean all pending Data
for
(
DatasPendingType
::
iterator
i
=
m_pending_frame_infos
.
begin
();
i
!=
m_pending_frame_infos
.
end
();
m_pending_frame_infos
.
erase
(
i
++
))
if
(
i
->
second
.
buffer_owner_ship
!=
HwFrameInfoType
::
Managed
)
free
(
i
->
second
.
frame_ptr
);
m_pending_frame_infos
.
clear
();
m_cbk
.
prepare
(
params
);
}
bool
HwFileEventCallbackHelper
::
nextFileExpected
(
int
file_number
,
const
char
*
full_path
,
int
&
next_file_number_expected
)
throw
()
{
HwFrameInfoType
aNewFrameInfo
;
bool
continueFlag
=
true
;
try
{
continueFlag
=
m_cbk
.
getFrameInfo
(
file_number
,
full_path
,
aNewFrameInfo
);
bool
continueAcq
=
!
m_cbk
.
newFrameReady
(
aNewFrameInfo
);
if
(
continueFlag
)
continueFlag
=
continueAcq
;
DatasPendingType
::
iterator
i
=
m_pending_frame_infos
.
begin
();
while
(
i
!=
m_pending_frame_infos
.
end
()
&&
continueFlag
)
{
++
file_number
;
if
(
i
->
first
==
file_number
)
{
next_file_number_expected
=
file_number
;
continueFlag
=
m_cbk
.
newFrameReady
(
i
->
second
);
m_pending_frame_infos
.
erase
(
i
);
}
else
break
;
i
=
m_pending_frame_infos
.
begin
();
}
}
catch
(...)
// File reading problem
{
next_file_number_expected
=
file_number
;
}
return
continueFlag
;
}
bool
HwFileEventCallbackHelper
::
newFile
(
int
file_number
,
const
char
*
full_path
)
throw
()
{
bool
continueFlag
=
true
;
DatasPendingType
::
iterator
i
=
m_pending_frame_infos
.
find
(
file_number
);
if
(
i
==
m_pending_frame_infos
.
end
())
{
try
{
HwFrameInfoType
aNewFrameInfo
;
continueFlag
=
m_cbk
.
getFrameInfo
(
file_number
,
full_path
,
aNewFrameInfo
);
m_pending_frame_infos
[
file_number
]
=
aNewFrameInfo
;
}
catch
(...)
{
}
}
return
continueFlag
;
}
/** @brief callback class of HwTmpfsBufferMgr
*/
class
HwTmpfsBufferMgr
::
_CBK
:
public
HwFileEventCallbackHelper
::
Callback
{
public:
_CBK
(
HwTmpfsBufferMgr
&
cnt
)
:
m_cnt
(
cnt
)
{}
virtual
void
prepare
(
const
DirectoryEvent
::
Parameters
&
params
)
{
//Clean watch directory
const
char
*
path
=
params
.
watch_path
.
c_str
();
DIR
*
aWatchDir
=
opendir
(
path
);
if
(
aWatchDir
)
{
while
(
1
)
{
char
fullPath
[
1024
];
struct
dirent
aDirentStruct
,
*
result
;
int
status
=
readdir_r
(
aWatchDir
,
&
aDirentStruct
,
&
result
);
if
(
status
||
!
result
)
break
;
snprintf
(
fullPath
,
sizeof
(
fullPath
),
"%s/%s"
,
path
,
result
->
d_name
);
unlink
(
fullPath
);
}
closedir
(
aWatchDir
);
}
}
virtual
bool
getFrameInfo
(
int
image_number
,
const
char
*
full_path
,
HwFrameInfoType
&
frame_info
)
{
return
m_cnt
.
_getFrameInfo
(
image_number
,
full_path
,
frame_info
);
}
virtual
bool
newFrameReady
(
const
HwFrameInfoType
&
frame_info
)
{
int
imageId2Remove
=
frame_info
.
acq_frame_nb
-
m_cnt
.
m_keep_nb_images
;
if
(
imageId2Remove
>=
0
)
{
char
aFileName
[
128
];
snprintf
(
aFileName
,
sizeof
(
aFileName
),
m_cnt
.
m_file_pattern
.
c_str
(),
imageId2Remove
);
char
aFullPathBuffer
[
1024
];
snprintf
(
aFullPathBuffer
,
sizeof
(
aFullPathBuffer
),
"%s/%s"
,
m_cnt
.
m_tmpfs_path
.
c_str
(),
aFileName
);
unlink
(
aFullPathBuffer
);
}
return
m_cnt
.
newFrameReady
(
frame_info
);
}
private:
HwTmpfsBufferMgr
&
m_cnt
;
};
/** @brief Buffer manager for tmp file system.
*
* This manager can be used when you can't get (from API) image from the
* detector. The only possible way is to read image back from a file.
*/
HwTmpfsBufferMgr
::
HwTmpfsBufferMgr
(
const
char
*
tmpfs_path
,
const
char
*
file_pattern
,
Callback
&
cbk
)
:
m_tmpfs_path
(
tmpfs_path
),
m_file_pattern
(
file_pattern
),
m_next_expected_image_number
(
0
),
m_keep_nb_images
(
1
),
m_memory_percent
(
0.5
),
m_internal_cbk
(
new
_CBK
(
*
this
)),
m_directory_cbk
(
*
m_internal_cbk
),
m_directory_event
(
true
,
m_directory_cbk
),
m_cbk
(
cbk
)
{
}
HwTmpfsBufferMgr
::~
HwTmpfsBufferMgr
()
{
m_directory_event
.
stop
();
delete
m_internal_cbk
;
}
void
HwTmpfsBufferMgr
::
setMemoryPercent
(
double
percent
)
{
DEB_MEMBER_FUNCT
();
if
(
percent
>=
0.
&&
percent
<=
1.
)
m_memory_percent
=
percent
;
else
THROW_HW_ERROR
(
Error
)
<<
"percent should be between 0. and 1."
;
}
/** @brief next image number should we expected
* This parameters will be take into account after prepare
*/
void
HwTmpfsBufferMgr
::
setNextExpectedImageNumber
(
int
image_nb
)
{
m_next_expected_image_number
=
image_nb
;
}
void
HwTmpfsBufferMgr
::
prepare
()
{
DirectoryEvent
::
Parameters
params
;
params
.
watch_path
=
m_tmpfs_path
;
params
.
file_pattern
=
m_file_pattern
;
params
.
next_file_number_expected
=
m_next_expected_image_number
;
m_directory_event
.
prepare
(
params
);
m_keep_nb_images
=
_calcNbMaxImages
();
}
void
HwTmpfsBufferMgr
::
start
()
{
m_directory_event
.
start
();
m_start_time
=
Timestamp
::
now
();
}
void
HwTmpfsBufferMgr
::
stop
()
{
m_directory_event
.
stop
();
}
bool
HwTmpfsBufferMgr
::
isStopped
()
const
{
return
m_directory_event
.
isStopped
();
}
int
HwTmpfsBufferMgr
::
getLastAcquiredFrame
()
const
{
return
m_directory_event
.
getNextFileNumberExpected
()
-
1
;
}
void
HwTmpfsBufferMgr
::
setFrameDim
(
const
FrameDim
&
)
{
DEB_MEMBER_FUNCT
();
}
void
HwTmpfsBufferMgr
::
getFrameDim
(
FrameDim
&
frame_dim
)
{
m_cbk
.
getFrameDim
(
frame_dim
);
}
void
HwTmpfsBufferMgr
::
setNbBuffers
(
int
)
{
DEB_MEMBER_FUNCT
();
}
void
HwTmpfsBufferMgr
::
getNbBuffers
(
int
&
nb_buffers
)
{
nb_buffers
=
m_keep_nb_images
;
}
void
HwTmpfsBufferMgr
::
setNbConcatFrames
(
int
nb_concat_frames
)
{
DEB_MEMBER_FUNCT
();
if
(
nb_concat_frames
!=
1
)
THROW_HW_ERROR
(
NotSupported
)
<<
"Not managed"
;
}
void
HwTmpfsBufferMgr
::
getNbConcatFrames
(
int
&
nb_concat_frames
)
{
nb_concat_frames
=
1
;
}
void
HwTmpfsBufferMgr
::
getMaxNbBuffers
(
int
&
max_nb_buffers
)
{
max_nb_buffers
=
_calcNbMaxImages
();
}
void
*
HwTmpfsBufferMgr
::
getBufferPtr
(
int
,
int
)
{
return
NULL
;
}
void
*
HwTmpfsBufferMgr
::
getFramePtr
(
int
)
{
return
NULL
;
}
void
HwTmpfsBufferMgr
::
getStartTimestamp
(
Timestamp
&
start_ts
)
{
start_ts
=
m_start_time
;
}
void
HwTmpfsBufferMgr
::
getFrameInfo
(
int
acq_frame_nb
,
HwFrameInfoType
&
info
)
{
DEB_MEMBER_FUNCT
();
char
filename
[
1024
];
snprintf
(
filename
,
sizeof
(
filename
),
m_file_pattern
.
c_str
(),
acq_frame_nb
);
std
::
string
fullPath
=
m_tmpfs_path
+
"/"
;
fullPath
+=
filename
;
m_cbk
.
getFrameInfo
(
acq_frame_nb
,
fullPath
.
c_str
(),
info
);
}
void
HwTmpfsBufferMgr
::
registerFrameCallback
(
HwFrameCallback
&
frame_cb
)
{
HwFrameCallbackGen
::
registerFrameCallback
(
frame_cb
);
}
void
HwTmpfsBufferMgr
::
unregisterFrameCallback
(
HwFrameCallback
&
frame_cb
)
{
HwFrameCallbackGen
::
unregisterFrameCallback
(
frame_cb
);
}
int
HwTmpfsBufferMgr
::
_calcNbMaxImages
()
{
DEB_MEMBER_FUNCT
();
struct
statvfs
fsstat
;
if
(
statvfs
(
m_tmpfs_path
.
c_str
(),
&
fsstat
))
THROW_HW_ERROR
(
Error
)
<<
"Can't figure out what is the size of that filesystem: "
<<
m_tmpfs_path
;
FrameDim
anImageDim
;
getFrameDim
(
anImageDim
);
int
nb_block_for_image
=
anImageDim
.
getMemSize
()
/
fsstat
.
f_bsize
;
int
aTotalImage
=
fsstat
.
f_blocks
/
nb_block_for_image
;
return
aTotalImage
*
m_memory_percent
;
}
bool
HwTmpfsBufferMgr
::
_getFrameInfo
(
int
image_number
,
const
char
*
full_path
,
HwFrameInfoType
&
frame_info
)
{
return
m_cbk
.
getFrameInfo
(
image_number
,
full_path
,
frame_info
);
}
hardware/src/Makefile
View file @
ccaf48f1
...
...
@@ -23,7 +23,8 @@ hw-objs := HwInterface.o HwCap.o HwSyncCtrlObj.o HwFrameInfo.o \
HwFrameCallback.o HwBufferCtrlObj.o HwBufferMgr.o
\
HwShutterCtrlObj.o HwMaxImageSizeCallback.o HwDetInfoCtrlObj.o
\
HwBinCtrlObj.o HwRoiCtrlObj.o HwFlipCtrlObj.o HwSerialLine.o
\
HwBufferSave.o HwVideoCtrlObj.o HwEventCtrlObj.o HwSavingCtrlObj.o
HwBufferSave.o HwVideoCtrlObj.o HwEventCtrlObj.o HwSavingCtrlObj.o
\
HwFileEventMgr.o
SRCS
=
$
(
hw-objs:.o
=
.cpp
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment