Skip to content

Commit

Permalink
Added stdc++11 mutex locking and added a Read Write lock support
Browse files Browse the repository at this point in the history
  • Loading branch information
Garrett Potts committed Sep 18, 2017
1 parent e1ca2cb commit 2a7ae41
Show file tree
Hide file tree
Showing 73 changed files with 453 additions and 326 deletions.
4 changes: 0 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ include(CMakeDetermineSystem)
INCLUDE(OssimVersion)
INCLUDE(OssimCommonVariables)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Expose some build options
set(LIB_NAME ossim CACHE STRING "Name of ossim libray (default is ossim).")
OPTION(BUILD_OSSIM_FREETYPE_SUPPORT "Set to ON to build OSSIM with freetype support. Use OFF to turn off freetype support." ON)
Expand Down
4 changes: 2 additions & 2 deletions apps/curl_apps/omarDataMgrUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#include <ossim/base/ossimRefPtr.h>
#include <ossim/util/ossimImageUtil.h>

#include <OpenThreads/Mutex>
#include <ostream>
#include <vector>
#include <mutex>

class ossimArgumentParser;
class ossimFileWalker;
Expand Down Expand Up @@ -268,7 +268,7 @@ class omarDataMgrUtil :
ossimRefPtr<ossimKeywordlist> m_kwl;

ossimFileWalker* m_fileWalker;
OpenThreads::Mutex m_mutex;
std::mutex m_mutex;

ossimRefPtr<ossimImageUtil> m_imageUtil;
ossim_int32 m_errorStatus;
Expand Down
29 changes: 16 additions & 13 deletions cmake/CMakeModules/OssimCommonVariables.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@

##################################################################################
# This currently sets up the options for the WARNING FLAGS for the compiler we are generating for.
# Currently only have gnu
##################################################################################
MACRO(OSSIM_ADD_COMMON_LIBRARY_FLAGS)
OPTION(OSSIM_COMPILE_WITH_FULL_WARNING "OSSIM developers : Compilation with FULL warning (use only for ossim developers)." OFF)
MARK_AS_ADVANCED(OSSIM_COMPILE_WITH_FULL_WARNING)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

IF(OSSIM_COMPILE_WITH_FULL_WARNING)
IF(CMAKE_COMPILER_IS_GNUCXX)
Expand Down Expand Up @@ -70,17 +73,17 @@ MACRO(OSSIM_ADD_COMMON_LIBRARY_FLAGS)
MARK_AS_ADVANCED(OSSIM_COMMON_COMPILER_FLAGS)
ENDMACRO(OSSIM_ADD_COMMON_LIBRARY_FLAGS)

MACRO(USE_CXX11)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
elseif (APPLE)
set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
endif()
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
ENDMACRO(USE_CXX11)
#MACRO(USE_CXX11)
# if (CMAKE_VERSION VERSION_LESS "3.1")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
# elseif (APPLE)
# set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
# endif()
# else ()
# set (CMAKE_CXX_STANDARD 11)
# endif ()
#ENDMACRO(USE_CXX11)

MACRO(OSSIM_ADD_COMMON_SETTINGS)
###################################################################################
Expand All @@ -94,7 +97,7 @@ MACRO(OSSIM_ADD_COMMON_SETTINGS)
# Seems like a good place to add version specific compiler flags too.
###################################################################################

USE_CXX11()
#USE_CXX11()

IF(APPLE)
# use, i.e. don't skip the full RPATH for the build tree
Expand Down
189 changes: 189 additions & 0 deletions include/ossim/base/RWLock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/**
* This code was derived from https://gist.github.com/mshockwave
*
*/

#ifndef ossimRWm_lockHEADER
#define ossimRWm_lockHEADER

#include <condition_variable>
#include <mutex>
#include <atomic>
#include <limits>

namespace ossim {

enum WaitGenre {
SPIN=0,
SLEEP=1
};
/**
* Code was derived from https://gist.github.com/mshockwave
*
* Has a pure c++11 implementation for read/write locks
* allowing one to choose the locking technique to use.
*
* You currently can choose between a SLEEP or SPIN technique
* for locking
*
* At the bottom we added typedefs so you do not have
* to specify the template values.
*
*
* Example:
* @code
* ossim::RWSleepLock mutex;
* // enter a section that just needs read only access
* {
* ossim::ScopeReadSleepLock lock(mutex);
* }
* // enter some section that requires write
* {
* ossim::ScopeWriteSleepLock lock(mutex);
* }
* @endCode
*/
template <WaitGenre WAIT_GENRE>
class RWLock {

std::mutex m_waitMutex;
std::condition_variable m_waitConditional;
std::atomic_int m_refCounter;
const int MIN_INT;

public:

RWLock();

void lockWrite();

bool tryLockWrite();

void unlockWrite();

void lockRead();

bool tryLockRead();

void unlockRead();
};

template <WaitGenre WAIT_GENRE>
RWLock<WAIT_GENRE>::RWLock() :
m_refCounter(0),
MIN_INT(std::numeric_limits<int>::min()){}

template <>
void RWLock<SPIN>::lockWrite() {

int expected = 0;
while(!m_refCounter.compare_exchange_weak(expected, MIN_INT,
std::memory_order_acquire,
std::memory_order_relaxed)){
expected = 0;
}
}
template <>
void RWLock<SLEEP>::lockWrite(){
int expected = 0;
if(!m_refCounter.compare_exchange_strong(expected, MIN_INT,
std::memory_order_acquire,
std::memory_order_relaxed)){
expected = 0;

std::unique_lock<std::mutex> lk(m_waitMutex);
m_waitConditional.wait(lk, [this,&expected] {
if(!m_refCounter.compare_exchange_strong(expected, MIN_INT,
std::memory_order_acquire,
std::memory_order_relaxed)){
expected = 0;
return false;
}
return true;
});
lk.unlock();
}
}

template <WaitGenre WAIT_GENRE>
bool RWLock<WAIT_GENRE>::tryLockWrite() {
int expected = 0;
return m_refCounter.compare_exchange_strong(expected, MIN_INT,
std::memory_order_acquire,
std::memory_order_relaxed);
}

template <WaitGenre WAIT_GENRE>
void RWLock<WAIT_GENRE>::unlockWrite() {
m_refCounter.store(0, std::memory_order_release);
if(WAIT_GENRE == SLEEP)
m_waitConditional.notify_all();
}

template <>
void RWLock<SPIN>::lockRead() {
while(m_refCounter.fetch_add(1, std::memory_order_acquire) < 0){
m_refCounter.fetch_sub(1, std::memory_order_release);
}
}
template <>
void RWLock<SLEEP>::lockRead() {
if(m_refCounter.fetch_add(1, std::memory_order_acquire) < 0){
m_refCounter.fetch_sub(1, std::memory_order_release);

std::unique_lock<std::mutex> lk(m_waitMutex);
m_waitConditional.wait(lk, [this]{
return m_refCounter.fetch_add(1, std::memory_order_acquire) >= 0;
});
lk.unlock();
}
}

template <WaitGenre WAIT_GENRE>
bool RWLock<WAIT_GENRE>::tryLockRead() {
return m_refCounter.fetch_add(1, std::memory_order_acquire) >= 0;
}

template <WaitGenre WAIT_GENRE>
void RWLock<WAIT_GENRE>::unlockRead() {
m_refCounter.fetch_sub(1, std::memory_order_release);
if(WAIT_GENRE == SLEEP)
m_waitConditional.notify_one();
}

template <WaitGenre WAIT_GENRE>
class ScopeReadLock {
RWLock<WAIT_GENRE> &m_lock;
public:
ScopeReadLock(RWLock<WAIT_GENRE> &lock) : m_lock(lock) {
m_lock.lockRead();
}

~ScopeReadLock() {
m_lock.unlockRead();
}
};

template <WaitGenre WAIT_GENRE>
class ScopeWriteLock {
RWLock<WAIT_GENRE> &m_lock;
public:
ScopeWriteLock(RWLock<WAIT_GENRE> &lock) : m_lock(lock) {
m_lock.lockWrite();
}

~ScopeWriteLock() {
m_lock.unlockWrite();
}
};

typedef RWLock<SLEEP> RWSleepLock;
typedef RWLock<SPIN> RWSpinLock;
typedef ScopeWriteLock<SLEEP> ScopeWriteSleepLock;
typedef ScopeWriteLock<SPIN> ScopeWriteSpinLock;
typedef ScopeReadLock<SLEEP> ScopeReadSleepLock;
typedef ScopeReadLock<SPIN> ScopeReadSpinLock;

};

#endif
5 changes: 2 additions & 3 deletions include/ossim/base/ossimDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
#include <iosfwd>
#include <ossim/base/ossimConstants.h>
#include <ossim/base/ossimXmlNode.h>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
#include <mutex>

class OSSIM_DLL ossimLocalTm : public std::tm
{
Expand Down Expand Up @@ -233,7 +232,7 @@ class OSSIM_DLL ossimLocalTm : public std::tm
void pYear(std::ostream & os, int fmt) const;

void setTimezoneOffsetFromGmt();
static OpenThreads::Mutex m_mutex;
static std::mutex m_mutex;
double theFractionalSecond;
mutable int m_timezoneOffset;
};
Expand Down
5 changes: 2 additions & 3 deletions include/ossim/base/ossimDatumFactoryRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
#include <vector>
#include <ossim/base/ossimConstants.h> /* for OSSIM_DLL macro */
#include <ossim/base/ossimDatumFactoryInterface.h>
#include <OpenThreads/ReadWriteMutex>

#include <mutex>
// Forward class declarations.
class ossimDatumFactoryInterface;
class ossimString;
Expand Down Expand Up @@ -68,7 +67,7 @@ class OSSIM_DLL ossimDatumFactoryRegistry : public ossimDatumFactoryInterface
/** Single static instance of this class. */
//static ossimDatumFactoryRegistry* theInstance;

mutable OpenThreads::ReadWriteMutex theFactoryListMutex;
mutable std::mutex theFactoryListMutex;
std::vector<ossimDatumFactoryInterface*> theFactoryList;
};

Expand Down
Loading

0 comments on commit 2a7ae41

Please sign in to comment.