1 // g2o - General Graph Optimization 2 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright notice, 10 // this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the distribution. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #ifndef G2O_OPENMP_MUTEX 28 #define G2O_OPENMP_MUTEX 29 30 #include "g2o/config.h" 31 32 #ifdef G2O_OPENMP 33 #include <omp.h> 34 #else 35 #include <cassert> 36 #endif 37 38 namespace g2o { 39 40 #ifdef G2O_OPENMP 41 42 /** 43 * \brief Mutex realized via OpenMP 44 */ 45 class OpenMPMutex 46 { 47 public: OpenMPMutex()48 OpenMPMutex() { omp_init_lock(&_lock); } ~OpenMPMutex()49 ~OpenMPMutex() { omp_destroy_lock(&_lock); } lock()50 void lock() { omp_set_lock(&_lock); } unlock()51 void unlock() { omp_unset_lock(&_lock); } 52 protected: 53 omp_lock_t _lock; 54 }; 55 56 #else 57 58 /* 59 * dummy which does nothing in case we don't have OpenMP support. 60 * In debug mode, the mutex allows to verify the correct lock and unlock behavior 61 */ 62 class OpenMPMutex 63 { 64 public: 65 #ifdef NDEBUG 66 OpenMPMutex() {} 67 #else 68 OpenMPMutex() : _cnt(0) {} 69 #endif 70 ~OpenMPMutex() { assert(_cnt == 0 && "Freeing locked mutex");} 71 void lock() { assert(++_cnt == 1 && "Locking already locked mutex");} 72 void unlock() { assert(--_cnt == 0 && "Trying to unlock a mutex which is not locked");} 73 protected: 74 #ifndef NDEBUG 75 char _cnt; 76 #endif 77 }; 78 79 #endif 80 81 /** 82 * \brief lock a mutex within a scope 83 */ 84 class ScopedOpenMPMutex 85 { 86 public: ScopedOpenMPMutex(OpenMPMutex * mutex)87 explicit ScopedOpenMPMutex(OpenMPMutex* mutex) : _mutex(mutex) { _mutex->lock(); } ~ScopedOpenMPMutex()88 ~ScopedOpenMPMutex() { _mutex->unlock(); } 89 private: 90 OpenMPMutex* const _mutex; 91 ScopedOpenMPMutex(const ScopedOpenMPMutex&); 92 void operator=(const ScopedOpenMPMutex&); 93 }; 94 95 } 96 97 #endif 98