mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-07-15 12:35:51 +03:00
Foundation Classes - Rework atomic and Standard_Condition (#598)
- Replace all `Standard_Atomic_Increment`/`Decrement` calls and `volatile` counters with `std::atomic` usage. - Rewrite `Standard_Condition` header to use `std::mutex`, `std::condition_variable`, and `std::atomic<bool>`. - Deprecate old atomic APIs in `Standard_Atomic.hxx`.
This commit is contained in:
parent
508700117c
commit
9707a155c0
@ -94,6 +94,8 @@
|
||||
#include <StepData_StepModel.hxx>
|
||||
#include <XSControl_WorkSession.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
|
||||
#else
|
||||
@ -2595,7 +2597,7 @@ struct TestParallelFunctor
|
||||
OCC_CATCH_SIGNALS
|
||||
int* pint = NULL;
|
||||
*pint = 4;
|
||||
Standard_Atomic_Increment(&myNbNotRaised);
|
||||
++myNbNotRaised;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
catch (OSD_Exception_ACCESS_VIOLATION const&)
|
||||
@ -2603,19 +2605,19 @@ struct TestParallelFunctor
|
||||
catch (OSD_SIGSEGV const&)
|
||||
#endif
|
||||
{
|
||||
Standard_Atomic_Increment(&myNbSigSegv);
|
||||
++myNbSigSegv;
|
||||
}
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
Standard_Atomic_Increment(&myNbUnknown);
|
||||
++myNbUnknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable volatile Standard_Integer myNbNotRaised;
|
||||
mutable volatile Standard_Integer myNbSigSegv;
|
||||
mutable volatile Standard_Integer myNbUnknown;
|
||||
mutable std::atomic<Standard_Integer> myNbNotRaised;
|
||||
mutable std::atomic<Standard_Integer> myNbSigSegv;
|
||||
mutable std::atomic<Standard_Integer> myNbUnknown;
|
||||
};
|
||||
|
||||
static Standard_Integer OCC30775(Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char**)
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include <XmlDrivers_DocumentRetrievalDriver.hxx>
|
||||
#include <XmlDrivers_DocumentStorageDriver.hxx>
|
||||
#include <TDataStd_Real.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Draw.hxx>
|
||||
#include <GeomInt_IntSS.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
@ -69,6 +68,7 @@ Standard_DISABLE_DEPRECATION_WARNINGS
|
||||
Standard_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
@ -133,7 +133,7 @@ static Standard_Integer OCC23361(Draw_Interpretor& di,
|
||||
class IncrementerDecrementer
|
||||
{
|
||||
public:
|
||||
IncrementerDecrementer(Standard_Integer* theVal, Standard_Boolean thePositive)
|
||||
IncrementerDecrementer(std::atomic<int>* theVal, Standard_Boolean thePositive)
|
||||
: myVal(theVal),
|
||||
myPositive(thePositive)
|
||||
{
|
||||
@ -142,13 +142,13 @@ public:
|
||||
void operator()(const size_t) const
|
||||
{
|
||||
if (myPositive)
|
||||
Standard_Atomic_Increment(myVal);
|
||||
++(*myVal);
|
||||
else
|
||||
Standard_Atomic_Decrement(myVal);
|
||||
--(*myVal);
|
||||
}
|
||||
|
||||
private:
|
||||
Standard_Integer* myVal;
|
||||
std::atomic<int>* myVal;
|
||||
Standard_Boolean myPositive;
|
||||
};
|
||||
|
||||
@ -156,13 +156,13 @@ static Standard_Integer OCC22980(Draw_Interpretor& di,
|
||||
Standard_Integer /*argc*/,
|
||||
const char** /*argv*/)
|
||||
{
|
||||
int aSum = 0;
|
||||
std::atomic<int> aSum(0);
|
||||
|
||||
// check returned value
|
||||
QCOMPARE(Standard_Atomic_Decrement(&aSum), -1);
|
||||
QCOMPARE(Standard_Atomic_Increment(&aSum), 0);
|
||||
QCOMPARE(Standard_Atomic_Increment(&aSum), 1);
|
||||
QCOMPARE(Standard_Atomic_Increment(&aSum), 2);
|
||||
QCOMPARE(aSum.fetch_sub(1) - 1, -1);
|
||||
QCOMPARE(aSum.fetch_add(1) + 1, 0);
|
||||
QCOMPARE(aSum.fetch_add(1) + 1, 1);
|
||||
QCOMPARE(aSum.fetch_add(1) + 1, 2);
|
||||
// QCOMPARE (Standard_Atomic_DecrementTest (&aSum), 0);
|
||||
// QCOMPARE (Standard_Atomic_DecrementTest (&aSum), 1);
|
||||
|
||||
@ -3127,13 +3127,13 @@ struct OCC25545_Functor
|
||||
gp_Pnt aP = BRep_Tool::Pnt(aV);
|
||||
if (aP.X() != static_cast<double>(i))
|
||||
{
|
||||
Standard_Atomic_Increment(&myIsRaceDetected);
|
||||
++myIsRaceDetected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<TopoDS_Shape>* myShapeVec;
|
||||
mutable volatile int myIsRaceDetected;
|
||||
mutable std::atomic<int> myIsRaceDetected;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include <OSD.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OSD_ThreadPool, Standard_Transient)
|
||||
@ -25,14 +24,14 @@ IMPLEMENT_STANDARD_RTTIEXT(OSD_ThreadPool, Standard_Transient)
|
||||
|
||||
bool OSD_ThreadPool::EnumeratedThread::Lock()
|
||||
{
|
||||
return Standard_Atomic_CompareAndSwap(&myUsageCounter, 0, 1);
|
||||
return myUsageCounter.exchange(1) == 0;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void OSD_ThreadPool::EnumeratedThread::Free()
|
||||
{
|
||||
Standard_Atomic_CompareAndSwap(&myUsageCounter, 1, 0);
|
||||
myUsageCounter.store(0);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -17,10 +17,11 @@
|
||||
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <OSD_Thread.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_Condition.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
//! Class defining a thread pool for executing algorithms in multi-threaded mode.
|
||||
//! Thread pool allocates requested amount of threads and keep them alive
|
||||
//! (in sleep mode when unused) during thread pool lifetime.
|
||||
@ -189,7 +190,7 @@ protected:
|
||||
Standard_Condition myWakeEvent;
|
||||
Standard_Condition myIdleEvent;
|
||||
int myThreadIndex;
|
||||
volatile int myUsageCounter;
|
||||
std::atomic<int> myUsageCounter;
|
||||
bool myIsStarted;
|
||||
bool myToCatchFpe;
|
||||
bool myIsSelfThread;
|
||||
@ -290,16 +291,16 @@ protected:
|
||||
|
||||
//! Returns first non processed element or end.
|
||||
//! Thread-safe method.
|
||||
int It() const { return Standard_Atomic_Increment(reinterpret_cast<volatile int*>(&myIt)) - 1; }
|
||||
int It() const { return myIt.fetch_add(1); }
|
||||
|
||||
private:
|
||||
JobRange(const JobRange& theCopy);
|
||||
JobRange& operator=(const JobRange& theCopy);
|
||||
|
||||
private:
|
||||
const int& myBegin; //!< First element of range
|
||||
const int& myEnd; //!< Last element of range
|
||||
mutable int myIt; //!< First non processed element of range
|
||||
const int& myBegin; //!< First element of range
|
||||
const int& myEnd; //!< Last element of range
|
||||
mutable std::atomic<int> myIt; //!< First non processed element of range
|
||||
};
|
||||
|
||||
//! Auxiliary wrapper class for thread function.
|
||||
|
@ -14,7 +14,6 @@ set(OCCT_Standard_FILES
|
||||
Standard_Character.hxx
|
||||
Standard_CLocaleSentry.cxx
|
||||
Standard_CLocaleSentry.hxx
|
||||
Standard_Condition.cxx
|
||||
Standard_Condition.hxx
|
||||
Standard_ConstructionError.hxx
|
||||
Standard_CString.cxx
|
||||
|
@ -27,12 +27,17 @@
|
||||
#ifndef _Standard_Atomic_HeaderFile
|
||||
#define _Standard_Atomic_HeaderFile
|
||||
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <atomic>
|
||||
|
||||
//! Increments atomically integer variable pointed by theValue
|
||||
//! and returns resulting incremented value.
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
inline int Standard_Atomic_Increment(volatile int* theValue);
|
||||
|
||||
//! Decrements atomically integer variable pointed by theValue
|
||||
//! and returns resulting decremented value.
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
inline int Standard_Atomic_Decrement(volatile int* theValue);
|
||||
|
||||
//! Perform an atomic compare and swap.
|
||||
@ -42,6 +47,7 @@ inline int Standard_Atomic_Decrement(volatile int* theValue);
|
||||
//! @param theOldValue expected value to perform modification
|
||||
//! @param theNewValue new value to set in case if *theValue was equal to theOldValue
|
||||
//! @return TRUE if theNewValue has been set to *theValue
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
inline bool Standard_Atomic_CompareAndSwap(volatile int* theValue,
|
||||
int theOldValue,
|
||||
int theNewValue);
|
||||
@ -56,16 +62,22 @@ inline bool Standard_Atomic_CompareAndSwap(volatile int* theValue,
|
||||
// making -march mandatory, check for __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* is
|
||||
// enforced.
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Increment(volatile int* theValue)
|
||||
{
|
||||
return __sync_add_and_fetch(theValue, 1);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Decrement(volatile int* theValue)
|
||||
{
|
||||
return __sync_sub_and_fetch(theValue, 1);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
|
||||
bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
|
||||
{
|
||||
return __sync_val_compare_and_swap(theValue, theOldValue, theNewValue) == theOldValue;
|
||||
@ -89,16 +101,22 @@ extern "C"
|
||||
// WinAPI function or MSVC intrinsic
|
||||
// Note that we safely cast int* to long*, as they have same size and endian-ness
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Increment(volatile int* theValue)
|
||||
{
|
||||
return _InterlockedIncrement(reinterpret_cast<volatile long*>(theValue));
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Decrement(volatile int* theValue)
|
||||
{
|
||||
return _InterlockedDecrement(reinterpret_cast<volatile long*>(theValue));
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
|
||||
bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
|
||||
{
|
||||
return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(theValue),
|
||||
@ -112,16 +130,22 @@ bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int
|
||||
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Increment(volatile int* theValue)
|
||||
{
|
||||
return OSAtomicIncrement32Barrier(theValue);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Decrement(volatile int* theValue)
|
||||
{
|
||||
return OSAtomicDecrement32Barrier(theValue);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
|
||||
bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
|
||||
{
|
||||
return OSAtomicCompareAndSwapInt(theOldValue, theNewValue, theValue);
|
||||
@ -136,16 +160,22 @@ bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int
|
||||
// It is strongly recommended to use newer versions of ndk.
|
||||
#include <sys/atomics.h>
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Increment(volatile int* theValue)
|
||||
{
|
||||
return __atomic_inc(theValue) + 1; // analog of __sync_fetch_and_add
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Decrement(volatile int* theValue)
|
||||
{
|
||||
return __atomic_dec(theValue) - 1; // analog of __sync_fetch_and_sub
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
|
||||
bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
|
||||
{
|
||||
return __atomic_cmpxchg(theOldValue, theNewValue, theValue) == 0;
|
||||
@ -156,16 +186,22 @@ bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int
|
||||
#ifndef IGNORE_NO_ATOMICS
|
||||
#error "Atomic operation isn't implemented for current platform!"
|
||||
#endif
|
||||
Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Increment(volatile int* theValue)
|
||||
{
|
||||
return ++(*theValue);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
|
||||
|
||||
int Standard_Atomic_Decrement(volatile int* theValue)
|
||||
{
|
||||
return --(*theValue);
|
||||
}
|
||||
|
||||
Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
|
||||
|
||||
bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
|
||||
{
|
||||
if (*theValue == theOldValue)
|
||||
|
@ -1,191 +0,0 @@
|
||||
// Created by: Kirill Gavrilov
|
||||
// Copyright (c) 2018 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "Standard_Condition.hxx"
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifndef _WIN32
|
||||
//! clock_gettime() wrapper.
|
||||
static void conditionGetRealTime(struct timespec& theTime)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
struct timeval aTime;
|
||||
gettimeofday(&aTime, NULL);
|
||||
theTime.tv_sec = aTime.tv_sec;
|
||||
theTime.tv_nsec = aTime.tv_usec * 1000;
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &theTime);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Condition::Standard_Condition(bool theIsSet)
|
||||
#ifdef _WIN32
|
||||
: myEvent((void*)::CreateEvent(0, true, theIsSet, NULL))
|
||||
#else
|
||||
: myFlag(theIsSet)
|
||||
#endif
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pthread_mutex_init(&myMutex, 0);
|
||||
pthread_cond_init(&myCond, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Condition::~Standard_Condition()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::CloseHandle((HANDLE)myEvent);
|
||||
#else
|
||||
pthread_mutex_destroy(&myMutex);
|
||||
pthread_cond_destroy(&myCond);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Standard_Condition::Set()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::SetEvent((HANDLE)myEvent);
|
||||
#else
|
||||
pthread_mutex_lock(&myMutex);
|
||||
myFlag = true;
|
||||
pthread_cond_broadcast(&myCond);
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Standard_Condition::Reset()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::ResetEvent((HANDLE)myEvent);
|
||||
#else
|
||||
pthread_mutex_lock(&myMutex);
|
||||
myFlag = false;
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Standard_Condition::Wait()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::WaitForSingleObject((HANDLE)myEvent, INFINITE);
|
||||
#else
|
||||
pthread_mutex_lock(&myMutex);
|
||||
if (!myFlag)
|
||||
{
|
||||
pthread_cond_wait(&myCond, &myMutex);
|
||||
}
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
bool Standard_Condition::Wait(int theTimeMilliseconds)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (::WaitForSingleObject((HANDLE)myEvent, (DWORD)theTimeMilliseconds) != WAIT_TIMEOUT);
|
||||
#else
|
||||
bool isSignalled = true;
|
||||
pthread_mutex_lock(&myMutex);
|
||||
if (!myFlag)
|
||||
{
|
||||
struct timespec aNow;
|
||||
struct timespec aTimeout;
|
||||
conditionGetRealTime(aNow);
|
||||
aTimeout.tv_sec = (theTimeMilliseconds / 1000);
|
||||
aTimeout.tv_nsec = (theTimeMilliseconds - aTimeout.tv_sec * 1000) * 1000000;
|
||||
if (aTimeout.tv_nsec > 1000000000)
|
||||
{
|
||||
aTimeout.tv_sec += 1;
|
||||
aTimeout.tv_nsec -= 1000000000;
|
||||
}
|
||||
aTimeout.tv_sec += aNow.tv_sec;
|
||||
aTimeout.tv_nsec += aNow.tv_nsec;
|
||||
isSignalled = (pthread_cond_timedwait(&myCond, &myMutex, &aTimeout) != ETIMEDOUT);
|
||||
}
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
return isSignalled;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
bool Standard_Condition::Check()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (::WaitForSingleObject((HANDLE)myEvent, (DWORD)0) != WAIT_TIMEOUT);
|
||||
#else
|
||||
bool isSignalled = true;
|
||||
pthread_mutex_lock(&myMutex);
|
||||
if (!myFlag)
|
||||
{
|
||||
struct timespec aNow;
|
||||
struct timespec aTimeout;
|
||||
conditionGetRealTime(aNow);
|
||||
aTimeout.tv_sec = aNow.tv_sec;
|
||||
aTimeout.tv_nsec = aNow.tv_nsec + 100;
|
||||
isSignalled = (pthread_cond_timedwait(&myCond, &myMutex, &aTimeout) != ETIMEDOUT);
|
||||
}
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
return isSignalled;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
bool Standard_Condition::CheckReset()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const bool wasSignalled = (::WaitForSingleObject((HANDLE)myEvent, (DWORD)0) != WAIT_TIMEOUT);
|
||||
::ResetEvent((HANDLE)myEvent);
|
||||
return wasSignalled;
|
||||
#else
|
||||
pthread_mutex_lock(&myMutex);
|
||||
bool wasSignalled = myFlag;
|
||||
if (!myFlag)
|
||||
{
|
||||
struct timespec aNow;
|
||||
struct timespec aTimeout;
|
||||
conditionGetRealTime(aNow);
|
||||
aTimeout.tv_sec = aNow.tv_sec;
|
||||
aTimeout.tv_nsec = aNow.tv_nsec + 100;
|
||||
wasSignalled = (pthread_cond_timedwait(&myCond, &myMutex, &aTimeout) != ETIMEDOUT);
|
||||
}
|
||||
myFlag = false;
|
||||
pthread_mutex_unlock(&myMutex);
|
||||
return wasSignalled;
|
||||
#endif
|
||||
}
|
@ -16,10 +16,12 @@
|
||||
#define _Standard_Condition_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
//! This is boolean flag intended for communication between threads.
|
||||
//! One thread sets this flag to TRUE to indicate some event happened
|
||||
@ -31,38 +33,62 @@ class Standard_Condition
|
||||
public:
|
||||
//! Default constructor.
|
||||
//! @param theIsSet Initial flag state
|
||||
Standard_EXPORT Standard_Condition(bool theIsSet);
|
||||
Standard_Condition(bool theIsSet = false)
|
||||
: myFlag(theIsSet)
|
||||
{
|
||||
}
|
||||
|
||||
//! Destructor.
|
||||
Standard_EXPORT ~Standard_Condition();
|
||||
~Standard_Condition() {}
|
||||
|
||||
//! Set event into signaling state.
|
||||
Standard_EXPORT void Set();
|
||||
void Set()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> aLock(myMutex);
|
||||
myFlag = true;
|
||||
}
|
||||
myCondition.notify_all();
|
||||
}
|
||||
|
||||
//! Reset event (unset signaling state)
|
||||
Standard_EXPORT void Reset();
|
||||
void Reset()
|
||||
{
|
||||
std::lock_guard<std::mutex> aLock(myMutex);
|
||||
myFlag = false;
|
||||
}
|
||||
|
||||
//! Wait for Event (infinity).
|
||||
Standard_EXPORT void Wait();
|
||||
void Wait()
|
||||
{
|
||||
std::unique_lock<std::mutex> aLock(myMutex);
|
||||
myCondition.wait(aLock, [this] { return myFlag.load(); });
|
||||
}
|
||||
|
||||
//! Wait for signal requested time.
|
||||
//! @param theTimeMilliseconds wait limit in milliseconds
|
||||
//! @return true if get event
|
||||
Standard_EXPORT bool Wait(int theTimeMilliseconds);
|
||||
bool Wait(int theTimeMilliseconds)
|
||||
{
|
||||
std::unique_lock<std::mutex> aLock(myMutex);
|
||||
auto aTimeout = std::chrono::milliseconds(theTimeMilliseconds);
|
||||
return myCondition.wait_for(aLock, aTimeout, [this] { return myFlag.load(); });
|
||||
}
|
||||
|
||||
//! Do not wait for signal - just test it state.
|
||||
//! @return true if get event
|
||||
Standard_EXPORT bool Check();
|
||||
bool Check() { return myFlag.load(); }
|
||||
|
||||
//! Method perform two steps at-once - reset the event object
|
||||
//! and returns true if it was in signaling state.
|
||||
//! @return true if event object was in signaling state.
|
||||
Standard_EXPORT bool CheckReset();
|
||||
|
||||
#ifdef _WIN32
|
||||
//! Access native HANDLE to Event object.
|
||||
void* getHandle() const { return myEvent; }
|
||||
#endif
|
||||
bool CheckReset()
|
||||
{
|
||||
std::lock_guard<std::mutex> aLock(myMutex);
|
||||
bool wasSignalled = myFlag.load();
|
||||
myFlag = false;
|
||||
return wasSignalled;
|
||||
}
|
||||
|
||||
private:
|
||||
//! This method should not be called (prohibited).
|
||||
@ -71,13 +97,9 @@ private:
|
||||
Standard_Condition& operator=(const Standard_Condition& theCopy);
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
void* myEvent;
|
||||
#else
|
||||
pthread_mutex_t myMutex;
|
||||
pthread_cond_t myCond;
|
||||
bool myFlag;
|
||||
#endif
|
||||
std::mutex myMutex;
|
||||
std::condition_variable myCondition;
|
||||
std::atomic<bool> myFlag;
|
||||
};
|
||||
|
||||
#endif // _Standard_Condition_HeaderFile
|
||||
|
@ -13,15 +13,16 @@
|
||||
|
||||
#include <Graphic3d_CLight.hxx>
|
||||
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_LIGHT_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_LIGHT_COUNTER(0);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -46,7 +47,7 @@ void Graphic3d_CLight::makeId()
|
||||
}
|
||||
|
||||
myId = TCollection_AsciiString("Graphic3d_CLight_") + aTypeSuffix
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_LIGHT_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_LIGHT_COUNTER);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -22,9 +22,10 @@
|
||||
#include <Graphic3d_WorldViewProjState.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <Standard_ShortReal.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_Assert.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera, Standard_Transient)
|
||||
|
||||
namespace
|
||||
@ -37,7 +38,7 @@ static const Standard_Real DEFAULT_ZNEAR = 0.001;
|
||||
static const Standard_Real DEFAULT_ZFAR = 3000.0;
|
||||
|
||||
// atomic state counter
|
||||
static volatile Standard_Integer THE_STATE_COUNTER = 0;
|
||||
static std::atomic<Standard_Size> THE_STATE_COUNTER(0);
|
||||
|
||||
// z-range tolerance compatible with for floating point.
|
||||
static Standard_Real zEpsilon()
|
||||
@ -95,9 +96,7 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
myIsCustomProjMatLR(false),
|
||||
myIsCustomFrustomLR(false)
|
||||
{
|
||||
myWorldViewProjState.Initialize((Standard_Size)Standard_Atomic_Increment(&THE_STATE_COUNTER),
|
||||
(Standard_Size)Standard_Atomic_Increment(&THE_STATE_COUNTER),
|
||||
this);
|
||||
myWorldViewProjState.Initialize(++THE_STATE_COUNTER, ++THE_STATE_COUNTER, this);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -1118,8 +1117,7 @@ void Graphic3d_Camera::InvalidateProjection()
|
||||
{
|
||||
myMatricesD.ResetProjection();
|
||||
myMatricesF.ResetProjection();
|
||||
myWorldViewProjState.ProjectionState() =
|
||||
(Standard_Size)Standard_Atomic_Increment(&THE_STATE_COUNTER);
|
||||
myWorldViewProjState.ProjectionState() = ++THE_STATE_COUNTER;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -1128,8 +1126,7 @@ void Graphic3d_Camera::InvalidateOrientation()
|
||||
{
|
||||
myMatricesD.ResetOrientation();
|
||||
myMatricesF.ResetOrientation();
|
||||
myWorldViewProjState.WorldViewState() =
|
||||
(Standard_Size)Standard_Atomic_Increment(&THE_STATE_COUNTER);
|
||||
myWorldViewProjState.WorldViewState() = ++THE_STATE_COUNTER;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_CLIP_PLANE_COUNTER(0);
|
||||
|
||||
static Handle(Graphic3d_AspectFillArea3d) defaultAspect()
|
||||
{
|
||||
@ -267,7 +268,7 @@ void Graphic3d_ClipPlane::setCappingFlag(bool theToUse, int theFlag)
|
||||
void Graphic3d_ClipPlane::makeId()
|
||||
{
|
||||
myId = TCollection_AsciiString("Graphic3d_ClipPlane_") // DynamicType()->Name()
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_CLIP_PLANE_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_CLIP_PLANE_COUNTER);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -15,9 +15,10 @@
|
||||
|
||||
#include <Graphic3d_HatchStyle.hxx>
|
||||
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_HatchStyle, Standard_Transient)
|
||||
|
||||
static const unsigned int myPredefinedPatterns[Aspect_HS_NB][32] = {
|
||||
@ -89,7 +90,7 @@ static const unsigned int myPredefinedPatterns[Aspect_HS_NB][32] = {
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_HATCH_STYLE_COUNTER = Aspect_HS_NB - 1;
|
||||
static std::atomic<Standard_Integer> THE_HATCH_STYLE_COUNTER(Aspect_HS_NB - 1);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -107,7 +108,7 @@ Graphic3d_HatchStyle::Graphic3d_HatchStyle(const Handle(Image_PixMap)& thePatter
|
||||
myPattern->Allocate(aByteSize);
|
||||
std::memcpy(myPattern->ChangeData(), thePattern->Data(), aByteSize);
|
||||
|
||||
myHatchType = Standard_Atomic_Increment(&THE_HATCH_STYLE_COUNTER);
|
||||
myHatchType = ++THE_HATCH_STYLE_COUNTER;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -16,16 +16,17 @@
|
||||
#include <Graphic3d_MarkerImage.hxx>
|
||||
|
||||
#include <Image_PixMap.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <TColStd_HArray1OfByte.hxx>
|
||||
|
||||
#include "Graphic3d_MarkerImage.pxx"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MarkerImage, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_MARKER_IMAGE_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_MARKER_IMAGE_COUNTER(0);
|
||||
|
||||
//! Names of built-in markers
|
||||
static const char* THE_MARKER_NAMES[Aspect_TOM_USERDEFINED] = {
|
||||
@ -180,7 +181,7 @@ Graphic3d_MarkerImage::Graphic3d_MarkerImage(const Handle(Image_PixMap)& theImag
|
||||
myHeight((Standard_Integer)theImage->Height())
|
||||
{
|
||||
myImageId = TCollection_AsciiString("Graphic3d_MarkerImage_")
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_MARKER_IMAGE_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_MARKER_IMAGE_COUNTER);
|
||||
|
||||
myImageAlphaId = TCollection_AsciiString("Graphic3d_MarkerImageAlpha_")
|
||||
+ TCollection_AsciiString(THE_MARKER_IMAGE_COUNTER);
|
||||
@ -238,7 +239,7 @@ Graphic3d_MarkerImage::Graphic3d_MarkerImage(const Handle(TColStd_HArray1OfByte)
|
||||
myHeight(theHeight)
|
||||
{
|
||||
myImageId = TCollection_AsciiString("Graphic3d_MarkerImage_")
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_MARKER_IMAGE_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_MARKER_IMAGE_COUNTER);
|
||||
|
||||
myImageAlphaId = TCollection_AsciiString("Graphic3d_MarkerImageAlpha_")
|
||||
+ TCollection_AsciiString(THE_MARKER_IMAGE_COUNTER);
|
||||
|
@ -18,13 +18,14 @@
|
||||
#include <Graphic3d_GraphicDriver.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_Protection.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderObject, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_SHADER_OBJECT_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_SHADER_OBJECT_COUNTER(0);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -35,7 +36,7 @@ Graphic3d_ShaderObject::Graphic3d_ShaderObject(const Graphic3d_TypeOfShaderObjec
|
||||
: myType(theType)
|
||||
{
|
||||
myID = TCollection_AsciiString("Graphic3d_ShaderObject_")
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_SHADER_OBJECT_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_SHADER_OBJECT_COUNTER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@ -22,13 +22,14 @@
|
||||
#include <OSD_Environment.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_PROGRAM_OBJECT_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_PROGRAM_OBJECT_COUNTER(0);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -87,7 +88,7 @@ Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
|
||||
myIsPBR(false)
|
||||
{
|
||||
myID = TCollection_AsciiString("Graphic3d_ShaderProgram_")
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_PROGRAM_OBJECT_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_PROGRAM_OBJECT_COUNTER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@ -25,13 +25,14 @@
|
||||
#include <OSD_Environment.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_OpenFile.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TextureRoot, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
static volatile Standard_Integer THE_TEXTURE_COUNTER = 0;
|
||||
static std::atomic<Standard_Integer> THE_TEXTURE_COUNTER(0);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@ -123,7 +124,7 @@ Graphic3d_TextureRoot::~Graphic3d_TextureRoot()
|
||||
void Graphic3d_TextureRoot::generateId()
|
||||
{
|
||||
myTexId = TCollection_AsciiString("Graphic3d_TextureRoot_")
|
||||
+ TCollection_AsciiString(Standard_Atomic_Increment(&THE_TEXTURE_COUNTER));
|
||||
+ TCollection_AsciiString(++THE_TEXTURE_COUNTER);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -16,7 +16,8 @@
|
||||
#include <Select3D_SensitivePrimitiveArray.hxx>
|
||||
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
|
||||
|
||||
@ -103,7 +104,7 @@ struct Select3D_SensitivePrimitiveArray::Select3D_SensitivePrimitiveArray_InitFu
|
||||
myToEvalMinMax,
|
||||
1))
|
||||
{
|
||||
Standard_Atomic_Increment(&myNbFailures);
|
||||
++myNbFailures;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -117,13 +118,13 @@ struct Select3D_SensitivePrimitiveArray::Select3D_SensitivePrimitiveArray_InitFu
|
||||
myToEvalMinMax,
|
||||
1))
|
||||
{
|
||||
Standard_Atomic_Increment(&myNbFailures);
|
||||
++myNbFailures;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Standard_Atomic_Increment(&myNbFailures);
|
||||
++myNbFailures;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -141,11 +142,11 @@ private:
|
||||
Select3D_SensitivePrimitiveArray_InitFunctor&);
|
||||
|
||||
private:
|
||||
Select3D_SensitivePrimitiveArray& myPrimArray;
|
||||
Standard_Integer myDivStep;
|
||||
Standard_Boolean myToEvalMinMax;
|
||||
Standard_Boolean myToComputeBvh;
|
||||
mutable volatile Standard_Integer myNbFailures;
|
||||
Select3D_SensitivePrimitiveArray& myPrimArray;
|
||||
Standard_Integer myDivStep;
|
||||
Standard_Boolean myToEvalMinMax;
|
||||
Standard_Boolean myToComputeBvh;
|
||||
mutable std::atomic<Standard_Integer> myNbFailures;
|
||||
};
|
||||
|
||||
//! Functor for computing BVH in parallel threads.
|
||||
|
Loading…
x
Reference in New Issue
Block a user