Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved resource releasing #71

Merged
merged 12 commits into from
Feb 25, 2020
2 changes: 1 addition & 1 deletion src/application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.0)
project(PopsiftDemo)
project(PopsiftDemo LANGUAGES CXX)

if(TARGET popsift)
# when compiled in the repository the target is already defined
Expand Down
77 changes: 49 additions & 28 deletions src/popsift/popsift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ PopSift::PopSift( const popsift::Config& config, popsift::Config::ProcessingMode
_pipe._unused.push( new popsift::ImageFloat );
_pipe._unused.push( new popsift::ImageFloat );
}
_pipe._pyramid = 0;

configure( config, true );

_pipe._thread_stage1 = new boost::thread( &PopSift::uploadImages, this );
_pipe._thread_stage1.reset( new boost::thread( &PopSift::uploadImages, this ));
if( mode == popsift::Config::ExtractingMode )
_pipe._thread_stage2 = new boost::thread( &PopSift::extractDownloadLoop, this );
_pipe._thread_stage2.reset( new boost::thread( &PopSift::extractDownloadLoop, this ));
else
_pipe._thread_stage2 = new boost::thread( &PopSift::matchPrepareLoop, this );
_pipe._thread_stage2.reset( new boost::thread( &PopSift::matchPrepareLoop, this ));
}

PopSift::PopSift( ImageMode imode )
Expand All @@ -50,19 +49,22 @@ PopSift::PopSift( ImageMode imode )
_pipe._unused.push( new popsift::ImageFloat );
_pipe._unused.push( new popsift::ImageFloat );
}
_pipe._pyramid = 0;

_pipe._thread_stage1 = new boost::thread( &PopSift::uploadImages, this );
_pipe._thread_stage2 = new boost::thread( &PopSift::extractDownloadLoop, this );
_pipe._thread_stage1.reset( new boost::thread( &PopSift::uploadImages, this ));
_pipe._thread_stage2.reset( new boost::thread( &PopSift::extractDownloadLoop, this ));
}

PopSift::~PopSift()
{
if(_isInit)
{
uninit();
}
}

bool PopSift::configure( const popsift::Config& config, bool force )
{
if( _pipe._pyramid != 0 ) {
if( _pipe._pyramid != nullptr ) {
return false;
}

Expand Down Expand Up @@ -97,7 +99,7 @@ bool PopSift::private_init( int w, int h )
float upscaleFactor = _config.getUpscaleFactor();
float scaleFactor = 1.0f / powf( 2.0f, -upscaleFactor );

if( p._pyramid != 0 ) {
if( p._pyramid != nullptr ) {
p._pyramid->resetDimensions( _config,
ceilf( w * scaleFactor ),
ceilf( h * scaleFactor ) );
Expand All @@ -121,19 +123,14 @@ bool PopSift::private_init( int w, int h )

void PopSift::uninit( )
{
_pipe._queue_stage1.push( 0 );
_pipe._thread_stage2->join();
_pipe._thread_stage1->join();
delete _pipe._thread_stage2;
delete _pipe._thread_stage1;

while( !_pipe._unused.empty() ) {
popsift::ImageBase* img = _pipe._unused.pull();
delete img;
if(!_isInit)
{
std::cout << "[warning] Attempt to release resources from an uninitialized instance" << std::endl;
return;
}
_pipe.uninit();

delete _pipe._pyramid;
_pipe._pyramid = 0;
_isInit = false;
}

SiftJob* PopSift::enqueue( int w,
Expand Down Expand Up @@ -171,20 +168,20 @@ SiftJob* PopSift::enqueue( int w,
void PopSift::uploadImages( )
{
SiftJob* job;
while( ( job = _pipe._queue_stage1.pull() ) != 0 ) {
while( ( job = _pipe._queue_stage1.pull() ) != nullptr ) {
popsift::ImageBase* img = _pipe._unused.pull();
job->setImg( img );
_pipe._queue_stage2.push( job );
}
_pipe._queue_stage2.push( 0 );
_pipe._queue_stage2.push( nullptr );
}

void PopSift::extractDownloadLoop( )
{
Pipe& p = _pipe;

SiftJob* job;
while( ( job = p._queue_stage2.pull() ) != 0 ) {
while( ( job = p._queue_stage2.pull() ) != nullptr ) {
popsift::ImageBase* img = job->getImg();

private_init( img->getWidth(), img->getHeight() );
Expand Down Expand Up @@ -217,7 +214,7 @@ void PopSift::matchPrepareLoop( )
Pipe& p = _pipe;

SiftJob* job;
while( ( job = p._queue_stage2.pull() ) != 0 ) {
while( ( job = p._queue_stage2.pull() ) != nullptr ) {
popsift::ImageBase* img = job->getImg();

private_init( img->getWidth(), img->getHeight() );
Expand All @@ -238,12 +235,12 @@ void PopSift::matchPrepareLoop( )
SiftJob::SiftJob( int w, int h, const unsigned char* imageData )
: _w(w)
, _h(h)
, _img(0)
, _img(nullptr)
{
_f = _p.get_future();

_imageData = (unsigned char*)malloc( w*h );
if( _imageData != 0 ) {
if( _imageData != nullptr ) {
memcpy( _imageData, imageData, w*h );
} else {
cerr << __FILE__ << ":" << __LINE__ << " Memory limitation" << endl
Expand All @@ -255,12 +252,12 @@ SiftJob::SiftJob( int w, int h, const unsigned char* imageData )
SiftJob::SiftJob( int w, int h, const float* imageData )
: _w(w)
, _h(h)
, _img(0)
, _img(nullptr)
{
_f = _p.get_future();

_imageData = (unsigned char*)malloc( w*h*sizeof(float) );
if( _imageData != 0 ) {
if( _imageData != nullptr ) {
memcpy( _imageData, imageData, w*h*sizeof(float) );
} else {
cerr << __FILE__ << ":" << __LINE__ << " Memory limitation" << endl
Expand Down Expand Up @@ -317,3 +314,27 @@ popsift::FeaturesDev* SiftJob::getDev()
return dynamic_cast<popsift::FeaturesDev*>( _f.get() );
}

void PopSift::Pipe::uninit()
{
griwodz marked this conversation as resolved.
Show resolved Hide resolved
_queue_stage1.push( nullptr );
if(_thread_stage2 != nullptr)
{
_thread_stage2->join();
_thread_stage2.reset(nullptr);
}
if(_thread_stage1 != nullptr)
{
_thread_stage1->join();
_thread_stage1.reset(nullptr);
}

while( !_unused.empty() )
{
popsift::ImageBase* img = _unused.pull();
delete img;
}

delete _pyramid;
_pyramid = nullptr;

}
35 changes: 25 additions & 10 deletions src/popsift/popsift.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,18 @@ class PopSift
{
struct Pipe
{
boost::thread* _thread_stage1;
boost::thread* _thread_stage2;
std::unique_ptr<boost::thread> _thread_stage1;
std::unique_ptr<boost::thread> _thread_stage2;
boost::sync_queue<SiftJob*> _queue_stage1;
boost::sync_queue<SiftJob*> _queue_stage2;
boost::sync_queue<popsift::ImageBase*> _unused;
popsift::ImageBase* _current;

popsift::Pyramid* _pyramid;
popsift::Pyramid* _pyramid{nullptr};

/**
* @brief Release the allocated resources, if any.
*/
void uninit();
};

public:
Expand All @@ -92,11 +96,15 @@ class PopSift
};

public:

PopSift() = delete;
PopSift(const PopSift&) = delete;

/* We support more than 1 streams, but we support only one sigma and one
* level parameters.
*/
PopSift( ImageMode imode = ByteImages );
PopSift( const popsift::Config& config,
explicit PopSift( ImageMode imode = ByteImages );
explicit PopSift( const popsift::Config& config,
popsift::Config::ProcessingMode mode = popsift::Config::ExtractingMode,
ImageMode imode = ByteImages );
~PopSift();
Expand All @@ -118,10 +126,14 @@ class PopSift
int h,
const float* imageData );

/** deprecated */
/**
* @deprecated
* */
inline void uninit( int /*pipe*/ ) { uninit(); }

/** deprecated */
/**
* @deprecated
**/
inline bool init( int /*pipe*/, int w, int h ) {
_last_init_w = w;
_last_init_h = h;
Expand Down Expand Up @@ -161,8 +173,11 @@ class PopSift
*/
popsift::Config _shadow_config;

int _last_init_w; /* to support depreacted interface */
int _last_init_h; /* to support depreacted interface */
int _last_init_w{}; /* to support deprecated interface */
int _last_init_h{}; /* to support deprecated interface */
ImageMode _image_mode;

/// whether the object is initialized
bool _isInit{true};
};