X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FcreaImageIOMultiThreadImageReader.cpp;h=288c9e8bdd0bc9815b1330b41690bebb36694139;hb=refs%2Fheads%2Fvtk8itk5wx3-macos;hp=83908ad9c97e8a4eb67571e5bc96da0513f057d0;hpb=684add23b4f64cb3c6e39e12a4af20d2c2500df6;p=creaImageIO.git diff --git a/src/creaImageIOMultiThreadImageReader.cpp b/src/creaImageIOMultiThreadImageReader.cpp index 83908ad..288c9e8 100644 --- a/src/creaImageIOMultiThreadImageReader.cpp +++ b/src/creaImageIOMultiThreadImageReader.cpp @@ -1,7 +1,43 @@ +/* +# --------------------------------------------------------------------- +# +# Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image +# pour la Santé) +# Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton +# Previous Authors : Laurent Guigues, Jean-Pierre Roux +# CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil +# +# This software is governed by the CeCILL-B license under French law and +# abiding by the rules of distribution of free software. You can use, +# modify and/ or redistribute the software under the terms of the CeCILL-B +# license as circulated by CEA, CNRS and INRIA at the following URL +# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +# or in the file LICENSE.txt. +# +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. +# +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL-B license and that you accept its terms. +# ------------------------------------------------------------------------ +*/ + + #include #include #include +#include + + #include + +#include +#ifdef _DEBUG +#define new DEBUG_NEW +#endif namespace creaImageIO { @@ -16,53 +52,77 @@ namespace creaImageIO } //===================================================================== + class wxThreadEED2 + { + public: + void Delete() { printf("EED wxThreadEED2::Delete() \n"); } + int Run() { printf("EED wxThreadEED2::Run() \n"); return 0;} + void Pause() { printf("EED wxThreadEED2::Pause() \n"); } + void Create() { printf("EED wxThreadEED2::Create() \n"); } + bool IsAlive() { printf("EED wxThreadEED2::IsAlive() \n"); return false; } + bool TestDestroy() { printf("EED wxThreadEED2::TestDestroy() \n"); return false; } + int GetCurrentId() { printf("EED wxThreadEED2::GetCurrentId() \n"); return -999; } + }; + //===================================================================== - class ThreadedImageReader: public wxThread +//EED 2018-08-20 +// class ThreadedImageReader: public wxThread + class ThreadedImageReader: public wxThreadEED2 { public: ThreadedImageReader(MultiThreadImageReader* tir) : mMultiThreadImageReader(tir) {} - void* Entry(); void OnExit(); - vtkImageData* Read(const std::string& filename); - + struct deleter + { + void operator()(ThreadedImageReader* p) + { + p->Delete(); + } + }; + friend struct deleter; private: ImageReader mReader; MultiThreadImageReader* mMultiThreadImageReader; }; + //===================================================================== //===================================================================== MultiThreadImageReader::MultiThreadImageReader(int number_of_threads) : //mDoNotSignal(false), - mReader(0), + mReader(NULL), mTotalMem(0), - mTotalMemMax(10000) + mTotalMemMax(1000000) { // std::cout << "#### MultiThreadImageReader::MultiThreadImageReader(" // << " #threads= " << number_of_threads <<" )"< t(new ThreadedImageReader(this), ThreadedImageReader::deleter()); + mThreadedImageReaderList.push_back(t); + std::cout << " ===> Thread "< 0) return true; + ThreadedImageReaderListType::iterator i; for (i =mThreadedImageReaderList.begin(); i!=mThreadedImageReaderList.end(); i++) - { - (*i)->Create(); - if ( (*i)->Run() != wxTHREAD_NO_ERROR ) - { - std::cout << "ERROR starting a thread"<< std::endl; - return false; - } - else - { - // std::cout << " ===> Thread "<<(*i)->GetCurrentId() - // <<" successfully created"<< std::endl; - - } - } - wxMutexLocker locker(GetMultiThreadImageReaderUserMutex()); - // std::cout << "EO Start : #Threads running = " - // << mNumberOfThreadedReadersRunning<Create(); + if ( (*i)->Run() != wxTHREAD_NO_ERROR ) + { + std::cout << "ERROR starting a thread"<< std::endl; + return false; + } else { + std::cout << " ===> Thread "<<(*i)->GetCurrentId() + <<" successfully created"<< std::endl; + } // if + } // for + wxMutexLocker locker(GetMultiThreadImageReaderUserMutex()); + // std::cout << "EO Start : #Threads running = " + // << mNumberOfThreadedReadersRunning<Delete(); - } - mThreadedImageReaderList.clear(); + { + std::cout << " ===> Thread "<<(*i)->GetCurrentId() + <<" successfully stopped"<< std::endl; + if((*i)->IsAlive()) + { + (*i)->Pause(); + (*i).reset(); +// (*i)->Delete(); + } // if i + } // for + mThreadedImageReaderList.clear(); // Wait a little to be sure that all threads have stopped // A better way to do this ? // wxMilliSleep(1000); @@ -123,7 +189,7 @@ namespace creaImageIO do { // Sleep a little - wxMilliSleep(10); + wxMilliSleep(10); // Lock { wxMutexLocker locker(GetMultiThreadImageReaderUserMutex()); @@ -139,18 +205,25 @@ namespace creaImageIO while (true); // std::cout << "All threads stopped : OK "<first; - } - mImages.clear(); + CleanMImagesMap(); + + mDone = true; + } //===================================================================== + + void MultiThreadImageReader::CleanMImagesMap() + { + ImageMapType::iterator j; + for (j=mImages.begin(); j!=mImages.end(); ++j) + { + delete j->first; + } //for + mImages.clear(); + } + //===================================================================== MultiThreadImageReader::~MultiThreadImageReader() { @@ -158,6 +231,18 @@ namespace creaImageIO // <GetFilename() ); + } // for it +*/ + } //===================================================================== @@ -180,15 +265,22 @@ namespace creaImageIO } } //===================================================================== + // function to read attributes for a file + void MultiThreadImageReader::getAttributes(const std::string filename, + std::map &infos,std::vector i_attr) + { + mReader->getAttributes(filename, infos, i_attr); + } //===================================================================== void MultiThreadImageReader::Request( MultiThreadImageReaderUser* user, const std::string& filename, int priority ) { - wxMutexLocker lock(GetMultiThreadImageReaderUserMutex()); //mMutex); - - if (mThreadedImageReaderList.size()==0) + wxMutexLocker lock(GetMultiThreadImageReaderUserMutex()); //mMutex); + + if (mNumberOfThreadedReadersRunning==0) +// if (mThreadedImageReaderList.size()==0) { // no detached reader : use self reader ImageToLoad itl(user,filename); @@ -208,14 +300,13 @@ namespace creaImageIO } ImageToLoadPtr pitl = new ImageToLoad(user,filename,0); mImages[pitl] = 0; - pitl->SetImage(mReader->Read(filename)); + pitl->SetImage(mReader->ReadImage(filename)); UpdateUnloadPriority(pitl,priority); SignalImageRead(pitl,true); // return pitl->GetImage(); return; } - ImageToLoad itl(user,filename); ImageMapType::iterator i = mImages.find(&itl); if (i!=mImages.end()) @@ -271,7 +362,8 @@ namespace creaImageIO } else if (e==MultiThreadImageReaderUser::ThreadedReaderStopped) { - mNumberOfThreadedReadersRunning--; + + mNumberOfThreadedReadersRunning--; // std::cout << "#TR=" << mNumberOfThreadedReadersRunning << std::endl; } } @@ -280,38 +372,41 @@ namespace creaImageIO //===================================================================== vtkImageData* MultiThreadImageReader::GetImage(const std::string& filename) { - - // std::cout << "** MultiThreadImageReader::GetImage('"<(i->first); - // Already inserted - if (pitl->GetImage() != 0) - { - // Already read - UpdateUnloadPriority(pitl, - GetMaximalPriorityWithoutLocking()+1); - return pitl->GetImage(); - } - } + { + ImageToLoadPtr pitl = const_cast(i->first); + // Already inserted + if (pitl->GetImage() != NULL) + { + // Already read + UpdateUnloadPriority( pitl, GetMaximalPriorityWithoutLocking()+1 ); + return pitl->GetImage(); + } // if pitl->GetImage() + } // if i + ImageToLoadPtr pitl = new ImageToLoad(this,filename,0); - mImages[pitl] = 0; - pitl->SetImage(mReader->Read(filename)); - UpdateUnloadPriority(pitl, - GetMaximalPriorityWithoutLocking()+1); + mImages[pitl] = NULL; + pitl->SetImage( mReader->ReadImage(filename) ); + UpdateUnloadPriority( pitl, GetMaximalPriorityWithoutLocking()+1 ); return pitl->GetImage(); - } + } // if true + /* mRequestedFilename = filename; mRequestedImage = 0; ImageToLoad itl(this,filename); @@ -350,11 +445,13 @@ namespace creaImageIO mImages[pitl] = 0; mQueue.insert(pitl); } + */ } while (0); // std::cout << "Waiting..."<GetFilename()<<"' read"<GetImage()->UpdateInformation(); p->GetImage()->PropagateUpdateExtent(); long ImMem = p->GetImage()->GetEstimatedMemorySize(); +#else + int ext[6]; + int dim[3]; + p->GetImage()->GetExtent(ext); + dim[0] = ext[1]-ext[0]+1; + dim[1] = ext[3]-ext[2]+1; + dim[2] = ext[5]-ext[4]+1; + long ImMem = dim[0]*dim[1]*dim[2]*p->GetImage()->GetScalarSize();; +#endif mTotalMem += ImMem; - // std::cout << " ==> Total mem = "< Image in memory = "< Total mem = "< mTotalMemMax) { - // std::cout - // <<" ! Exceeded max of " - // << mTotalMemMax << " : unloading oldest image ... " - // << std::endl; + GimmickMessage(5, + " ! Exceeded max of " + << mTotalMemMax << " Ko : unloading oldest image ... " + << std::endl); if ( mUnloadQueue.size() <= 1 ) { - // std::cout << "Only one image : cannot load AND unload it !!" - // <GetUser(); + /* if ((user!=0)&&(user!=this)) { user->GetMultiThreadImageReaderUserMutex().Lock(); } + */ + + std::string filename = unload->GetFilename(); + GimmickMessage(5,"'" << filename << "'" << std::endl); - // std::cout << "'" << unload->GetFilename() << "'" << std::endl; +//EED 2017-01-01 Migration VTK7 +#if VTK_MAJOR_VERSION <= 5 mTotalMem -= unload->GetImage()->GetEstimatedMemorySize(); - // std::cout << " ==> Total mem = "<GetImage()->GetExtent(ext); + dim[0] = ext[1]-ext[0]+1; + dim[1] = ext[3]-ext[2]+1; + dim[2] = ext[5]-ext[4]+1; + mTotalMem -= dim[0]*dim[1]*dim[2]*unload->GetImage()->GetScalarSize(); +#endif + + GimmickMessage(5," ==> Total mem = "<GetMultiThreadImageReaderUserMutex().Unlock(); + // std::cout << "event"<MultiThreadImageReaderSendEvent + (filename, + MultiThreadImageReaderUser::ImageUnloaded, + 0); + // std::cout << "event ok"<GetFilename(); if (unload->Index()>=0) { - // std::cout << "still in queue"<Index() = -1; @@ -452,21 +599,7 @@ namespace creaImageIO delete unload; // std::cout << "delete ok."<GetMultiThreadImageReaderUserMutex().Unlock(); - // std::cout << "event"<MultiThreadImageReaderSendEvent - (filename, - MultiThreadImageReaderUser::ImageUnloaded, - 0); - // std::cout << "event ok"<MultiThreadImageReaderEventLock(); @@ -554,13 +686,11 @@ namespace creaImageIO // std::cout << "### Thread "<GetFilename() << "' : DONE" << std::endl; - } - else - { + } else { mMultiThreadImageReader->MultiThreadImageReaderEventUnlock(); //mMutex.Unlock(); // Wait a little to avoid blocking - Sleep(10); + wxMilliSleep(10); } }; // std::cout << "### Thread "<