diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index 02f09aed2b41f0c03f349ee1e7ae5a9dd7aa1b3a..bcd9f083fed433347c793d4c4dfff26a42b0c66a 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -55,7 +55,7 @@ int Msg::_commRank = 0; int Msg::_commSize = 1; int Msg::_verbosity = 5; int Msg::_progressMeterStep = 10; -int Msg::_progressMeterCurrent = -1; +std::atomic<int> Msg::_progressMeterCurrent(-1); int Msg::_progressMeterTotal = 0; std::map<std::string, double> Msg::_timers; bool Msg::_infoCpu = false; @@ -595,8 +595,10 @@ void Msg::Info(const char *fmt, ...) if(CTX::instance()->terminal){ if(_progressMeterCurrent >= 0 && _progressMeterTotal > 1 && - _commSize == 1) - fprintf(stdout, "Info : [%3d%%] %s\n", _progressMeterCurrent, str); + _commSize == 1) { + int p = _progressMeterCurrent; + fprintf(stdout, "Info : [%3d%%] %s\n", p, str); + } else if(_commSize > 1) fprintf(stdout, "Info : [rank %3d] %s\n", GetCommRank(), str); else @@ -773,24 +775,18 @@ void Msg::ProgressMeter(int n, bool log, const char *fmt, ...) while(p < percent) p += _progressMeterStep; if(p >= 100) p = 100; -#if defined(_OPENMP) -#pragma omp critical -#endif - { - _progressMeterCurrent = p; - } + _progressMeterCurrent = p; // TODO With C++11 use std::string (contiguous layout) and avoid all these C // problems // str2 needs to have at least 5018 bytes or buffer overflow will occur - char str[5000], str2[5018]; + char str[5000], str2[5100]; va_list args; va_start(args, fmt); vsnprintf(str, sizeof(str), fmt, args); va_end(args); int l = strlen(str); if(str[l - 1] == '\n') str[l - 1] = '\0'; - - sprintf(str2, "Info : [%3d%%] %s", _progressMeterCurrent, str); + sprintf(str2, "Info : [%3d%%] %s", p, str); if(_client) _client->Progress(str2); diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h index 939738542e7c1ac539d048b810930341c3a87541..3ca21a84f9e92d57201afbcace27d22eae2fe05c 100644 --- a/Common/GmshMessage.h +++ b/Common/GmshMessage.h @@ -9,6 +9,7 @@ #include <map> #include <vector> #include <string> +#include <atomic> #include <stdarg.h> #include "GmshConfig.h" @@ -35,7 +36,8 @@ private: // 3: +direct, 4: +info, 5 (=normal): +statusbar, 99: debug) static int _verbosity; // step (in %) of the progress meter and current progress (in %) - static int _progressMeterStep, _progressMeterCurrent; + static int _progressMeterStep; + static std::atomic<int> _progressMeterCurrent; // total number of items considered in the current progress meter calculation static int _progressMeterTotal; // timers diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 365f3adc0008f311afb8260860fbda33090c591a..8915b2a333992b70e7dc5cd19be11580ab76fc41 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -210,18 +210,26 @@ void GModel::destroy(bool keepName) void GModel::destroyMeshCaches() { - _vertexVectorCache.clear(); - std::vector<MVertex *>().swap(_vertexVectorCache); - _vertexMapCache.clear(); - std::map<int, MVertex *>().swap(_vertexMapCache); - _elementVectorCache.clear(); - std::vector<MElement *>().swap(_elementVectorCache); - _elementMapCache.clear(); - std::map<int, MElement *>().swap(_elementMapCache); - _elementIndexCache.clear(); - std::map<int, int>().swap(_elementIndexCache); - delete _elementOctree; - _elementOctree = nullptr; + // this is called in GEntity::deleteMesh() +#if defined(_OPENMP) +#pragma omp critical +#endif + { + _vertexVectorCache.clear(); + std::vector<MVertex *>().swap(_vertexVectorCache); + _vertexMapCache.clear(); + std::map<int, MVertex *>().swap(_vertexMapCache); + _elementVectorCache.clear(); + std::vector<MElement *>().swap(_elementVectorCache); + _elementMapCache.clear(); + std::map<int, MElement *>().swap(_elementMapCache); + _elementIndexCache.clear(); + std::map<int, int>().swap(_elementIndexCache); + if(_elementOctree) { + delete _elementOctree; + _elementOctree = nullptr; + } + } } void GModel::deleteMesh() @@ -1946,6 +1954,14 @@ void GModel::scaleMesh(double factor) } } +void GModel::setCurrentMeshEntity(GEntity *e) +{ +#if defined(_OPENMP) +#pragma omp critical +#endif + _currentMeshEntity = e; +} + int GModel::partitionMesh(int numPart) { #if defined(HAVE_MESH) && (defined(HAVE_METIS)) diff --git a/Geo/GModel.h b/Geo/GModel.h index 7367c0441a369b69617d97e7dfbcaca0129acbfd..cdd281ca39777fc3f5f78f374231ea835c56b805 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -561,7 +561,7 @@ public: void scaleMesh(double factor); // set/get entity that is currently being meshed (for error reporting) - void setCurrentMeshEntity(GEntity *e) { _currentMeshEntity = e; } + void setCurrentMeshEntity(GEntity *e); GEntity *getCurrentMeshEntity() { return _currentMeshEntity; } // set/get entities/vertices linked meshing errors diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 79f2924447c558524db7a215c571c15c613751b8..38ea85701d3d95db8b96f0f6287fa69e3e9fcb9d 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -379,17 +379,16 @@ static void Mesh1D(GModel *m) #pragma omp parallel for schedule(dynamic) #endif for(size_t K = 0; K < sss; K++) { + int localPending = 0; GEdge *ed = temp[K]; if(ed->meshStatistics.status == GEdge::PENDING) { ed->mesh(true); #if defined(_OPENMP) #pragma omp critical #endif - { - nPending++; - } + localPending = ++nPending; } - if(!nIter) Msg::ProgressMeter(nPending, false, "Meshing 1D..."); + if(!nIter) Msg::ProgressMeter(localPending, false, "Meshing 1D..."); } if(!nPending) break; @@ -530,17 +529,16 @@ static void Mesh2D(GModel *m) #pragma omp parallel for schedule(dynamic) #endif for(size_t K = 0; K < temp.size(); K++) { + int localPending = 0; if(temp[K]->meshStatistics.status == GFace::PENDING) { backgroundMesh::current()->unset(); temp[K]->mesh(true); #if defined(_OPENMP) #pragma omp critical #endif - { - nPending++; - } + localPending = ++nPending; } - if(!nIter) Msg::ProgressMeter(nPending, false, "Meshing 2D..."); + if(!nIter) Msg::ProgressMeter(localPending, false, "Meshing 2D..."); } if(!nPending) break; // iter == 2 is for meshing re-parametrized surfaces; after that, we