]> OCCT Git - occt.git/commitdiff
Foundation Classes - Rework atomic and Standard_Condition (#598)
authorPasukhin Dmitry <dpasukhi@opencascade.com>
Thu, 10 Jul 2025 09:10:33 +0000 (10:10 +0100)
committerGitHub <noreply@github.com>
Thu, 10 Jul 2025 09:10:33 +0000 (10:10 +0100)
- 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`.

17 files changed:
src/Draw/TKQADraw/QABugs/QABugs_11.cxx
src/Draw/TKQADraw/QABugs/QABugs_19.cxx
src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.cxx
src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.hxx
src/FoundationClasses/TKernel/Standard/FILES.cmake
src/FoundationClasses/TKernel/Standard/Standard_Atomic.hxx
src/FoundationClasses/TKernel/Standard/Standard_Condition.cxx [deleted file]
src/FoundationClasses/TKernel/Standard/Standard_Condition.hxx
src/Visualization/TKService/Graphic3d/Graphic3d_CLight.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_Camera.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_ClipPlane.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_HatchStyle.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_MarkerImage.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_ShaderObject.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.cxx
src/Visualization/TKService/Graphic3d/Graphic3d_TextureRoot.cxx
src/Visualization/TKV3d/Select3D/Select3D_SensitivePrimitiveArray.cxx

index 56415326c5e542069d36dfef10e23de079d19fed..3b078e69d54450469c29268888e46a1bbe82290b 100644 (file)
@@ -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**)
index e201cdee7c4cb61eb77977382963c2cc992e4e7c..e35017fea36d8eaf2e0122d2cdde1603a0151ec3 100644 (file)
@@ -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;
 };
 
 //=======================================================================
index 543fdff6ba2144b47b6b291ce7a8ce8e2ddf99d0..140b3197b4166d4a31a0472492438d1b05bab721 100644 (file)
@@ -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);
 }
 
 //=================================================================================================
index 5fad395135d29785c2130f6f6a85495dba0a34bc..d551138c70ca1cf60919ca90bef57d7446c431f4 100644 (file)
 
 #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.
index c9c3505db37fdac71a1a4ddecf4961bff3a47cf5..5704ec18e1d2f088f1c7cb376992b6cfb3e19b16 100644 (file)
@@ -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
index 24173642f9cc17ca3436daa6300213239af988d1..21bc8d518b832d91475b56f06f029c8295577341 100644 (file)
 #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)
diff --git a/src/FoundationClasses/TKernel/Standard/Standard_Condition.cxx b/src/FoundationClasses/TKernel/Standard/Standard_Condition.cxx
deleted file mode 100644 (file)
index 57df2ef..0000000
+++ /dev/null
@@ -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
-}
index 279cdfad2d704530461295f1688eb69ad0c44d19..3bc627bd9335479eb3bf3370b1c7744327d0465b 100644 (file)
 #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
index 84247680fc04f9f38a64e0f420164675d01d3804..43f1955ecf0301b2b7f59039c3aac2ed020f57d8 100644 (file)
 
 #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);
 }
 
 //=================================================================================================
index b457591d8764d0276862880bd9bc6f309c9aa0d8..7640c1347a65c206bf0634c58f6c41d705f9e77c 100644 (file)
 #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;
 }
 
 //=================================================================================================
index eb5a677ee2e31e978fac7f0c511f33452340a769..920e0962b39184fe8f0bc1ff3d5aa48711dbffba 100755 (executable)
 
 #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);
 }
 
 //=================================================================================================
index 3e3d5a4ee64c47b622ac7457da2c696b49a10997..7a5ffd0409941e097434c2453cf792169f7d27f2 100644 (file)
 
 #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;
 }
 
 //=================================================================================================
index 837076d7704fb4007c847492f704116404b9f3d9..3b8fb7a3b71aa898c60d9ea3ee2388aa0d1b3185 100755 (executable)
 #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);
index 4ccfb15a8f0bf8f3bdcb71597c260f8b4f0cef94..7e7219124b92699ca5fe44e5d226a918519dc5d3 100755 (executable)
 #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);
 }
 
 // =======================================================================
index 980f2ef19e95ccfbc557ca49ba41c4d4fd8c230b..eedf0251f38ea46ee44c01f2c5beb347ec64926f 100755 (executable)
 #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);
 }
 
 // =======================================================================
index a16817c67317b316521d55d2b0c8aa4e88befb4a..a0e00a9600e8d21cf89312197c72321ab4a52399 100644 (file)
 #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);
 }
 
 //=================================================================================================
index 1d19822c5a3eace6b829b3b486e34891137b47c4..fc0842d88baaa2e6fc69637057b30f838e4a317a 100644 (file)
@@ -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.