diff --git a/src/AIS/AIS_GlobalStatus.cxx b/src/AIS/AIS_GlobalStatus.cxx index 22e8297c4e..bcf2c6adfa 100755 --- a/src/AIS/AIS_GlobalStatus.cxx +++ b/src/AIS/AIS_GlobalStatus.cxx @@ -3,15 +3,9 @@ // Author: Robert COUBLANC // - #include #include - - -static TColStd_ListIteratorOfListOfInteger It; - - AIS_GlobalStatus::AIS_GlobalStatus(): myStatus(AIS_DS_None), myLayerIndex(0), @@ -37,22 +31,32 @@ mySubInt(Standard_False) mySelModes.Append(SMode); } - void AIS_GlobalStatus::RemoveDisplayMode(const Standard_Integer aMode) { - for(It.Initialize(myDispModes);It.More();It.Next()){ - if(It.Value()==aMode){ myDispModes.Remove(It); - return;} + TColStd_ListIteratorOfListOfInteger anIt (myDispModes); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value() == aMode) + { + myDispModes.Remove (anIt); + return; + } } } void AIS_GlobalStatus::RemoveSelectionMode(const Standard_Integer aMode) { - for(It.Initialize(mySelModes);It.More();It.Next()){ - if(It.Value()==aMode){ mySelModes.Remove(It); - return;} + TColStd_ListIteratorOfListOfInteger anIt (mySelModes); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value() == aMode) + { + mySelModes.Remove (anIt); + return; + } } } + void AIS_GlobalStatus::ClearSelectionModes() { mySelModes.Clear(); @@ -60,16 +64,26 @@ void AIS_GlobalStatus::ClearSelectionModes() Standard_Boolean AIS_GlobalStatus::IsDModeIn(const Standard_Integer aMode) const { - for(It.Initialize(myDispModes);It.More();It.Next()) - if(It.Value()==aMode) return Standard_True; + TColStd_ListIteratorOfListOfInteger anIt (myDispModes); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value() == aMode) + { + return Standard_True; + } + } return Standard_False; - } Standard_Boolean AIS_GlobalStatus::IsSModeIn(const Standard_Integer aMode) const { - for(It.Initialize(mySelModes);It.More();It.Next()) - if(It.Value()==aMode) return Standard_True; + TColStd_ListIteratorOfListOfInteger anIt (mySelModes); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value() == aMode) + { + return Standard_True; + } + } return Standard_False; } - diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index 53c278b999..577102cf0c 100755 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -91,28 +92,23 @@ static Standard_Boolean AISDebugModeOn() return (isDebugMode != 0); } -static TCollection_AsciiString AIS_Context_NewSelName() +namespace { - static Standard_Integer index_sel = 1; - TCollection_AsciiString name("AIS_SelContext_"); - TCollection_AsciiString theind(index_sel); - name += theind; - index_sel++; - return name; -} + static volatile Standard_Integer THE_AIS_INDEX_SEL = 0; + static volatile Standard_Integer THE_AIS_INDEX_CUR = 0; -static TCollection_AsciiString AIS_Context_NewCurName() -{ - static Standard_Integer index_cur = 1; - TCollection_AsciiString name("AIS_CurContext_"); - TCollection_AsciiString theind(index_cur); - name += theind; - index_cur++; - return name; -} - -static TColStd_ListIteratorOfListOfInteger ItL; + static TCollection_AsciiString AIS_Context_NewSelName() + { + return TCollection_AsciiString ("AIS_SelContext_") + + TCollection_AsciiString (Standard_Atomic_Increment (&THE_AIS_INDEX_SEL)); + } + static TCollection_AsciiString AIS_Context_NewCurName() + { + return TCollection_AsciiString ("AIS_CurContext_") + + TCollection_AsciiString (Standard_Atomic_Increment (&THE_AIS_INDEX_CUR)); + } +}; //======================================================================= //function : AIS_InteractiveContext @@ -504,7 +500,8 @@ void AIS_InteractiveContext::Display(const Handle(AIS_InteractiveObject)& anIObj updcol = updateviewer; }// attention on fait expres de ne pas mettre de break.. case AIS_DS_FullErased:{ - for (ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes()); + for (;ItL.More();ItL.Next()){ myMainPM->Display(anIObj,ItL.Value()); if(STATUS->IsSubIntensityOn()) myMainPM->Color(anIObj,mySubIntensity,ItL.Value()); @@ -523,7 +520,8 @@ void AIS_InteractiveContext::Display(const Handle(AIS_InteractiveObject)& anIObj // Finally, activate selection mode if not yet activated. case AIS_DS_Displayed:{ TColStd_ListOfInteger aModesToRemove; - for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes()); + for(;ItL.More();ItL.Next()){ Standard_Integer OldMode = ItL.Value(); @@ -1817,7 +1815,8 @@ void AIS_InteractiveContext::SetDisplayMode(const Handle(AIS_InteractiveObject)& // SAN : erase presentations for all display modes different from if(STATUS->GraphicStatus()==AIS_DS_Displayed){ TColStd_ListOfInteger aModesToRemove; - for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes()); + for(;ItL.More();ItL.Next()){ Standard_Integer OldMode = ItL.Value(); @@ -2092,7 +2091,7 @@ void AIS_InteractiveContext::SetDeviationAngle( if(!anIObj->HasInteractiveContext()) anIObj->SetContext(this); -// To be modified after the related methods of AIS_Shape are passed to InteractiveObject + // To be modified after the related methods of AIS_Shape are passed to InteractiveObject if(anIObj->Type()!=AIS_KOI_Shape) return; if(anIObj->Signature()!=0) return; (*((Handle(AIS_Shape)*)&anIObj))->SetOwnDeviationAngle(anAngle); @@ -2134,7 +2133,7 @@ void AIS_InteractiveContext::SetAngleAndDeviation( if(!anIObj->HasInteractiveContext()) anIObj->SetContext(this); -// To be modified after the related methods of AIS_Shape are passed to InteractiveObject + // To be modified after the related methods of AIS_Shape are passed to InteractiveObject if(anIObj->Type()!=AIS_KOI_Shape) return; if(anIObj->Signature()!=0) return; (*((Handle(AIS_Shape)*)&anIObj))->SetAngleAndDeviation(anAngle); @@ -2162,7 +2161,7 @@ void AIS_InteractiveContext::SetHLRAngleAndDeviation( if(!anIObj->HasInteractiveContext()) anIObj->SetContext(this); -// To be modified after the related methods of AIS_Shape are passed to InteractiveObject + // To be modified after the related methods of AIS_Shape are passed to InteractiveObject if(anIObj->Type()!=AIS_KOI_Shape) return; if(anIObj->Signature()!=0) return; (*((Handle(AIS_Shape)*)&anIObj))->SetHLRAngleAndDeviation(anAngle); @@ -2205,7 +2204,7 @@ void AIS_InteractiveContext::SetHLRDeviationAngle( if(!anIObj->HasInteractiveContext()) anIObj->SetContext(this); -// To be modified after the related methods of AIS_Shape are passed to InteractiveObject + // To be modified after the related methods of AIS_Shape are passed to InteractiveObject if( anIObj->Type()!=AIS_KOI_Shape) return; if(anIObj->Signature()!=0) return; (*((Handle(AIS_Shape)*)&anIObj))->SetOwnHLRDeviationAngle(anAngle); @@ -2626,7 +2625,8 @@ void AIS_InteractiveContext::Status(const Handle(AIS_InteractiveObject)& anIObj, break; } astatus += "\t| Active Display Modes in the MainViewer :\n"; - for(ItL.Initialize(ST->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (ST->DisplayedModes()); + for(;ItL.More();ItL.Next()){ astatus += "\t|\t Mode "; astatus += TCollection_AsciiString(ItL.Value()); astatus+="\n"; @@ -2688,7 +2688,8 @@ void AIS_InteractiveContext::EraseGlobal(const Handle(AIS_InteractiveObject)& an Standard_Integer Dmode = anIObj->HasHilightMode() ? anIObj->HilightMode() : 0; if(STATUS->GraphicStatus()==AIS_DS_Displayed){ - for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes()); + for(;ItL.More();ItL.Next()){ if(myMainPM->IsHighlighted(anIObj,ItL.Value())) myMainPM->Unhighlight(anIObj,ItL.Value()); myMainPM->Erase(anIObj,ItL.Value()); @@ -2732,7 +2733,8 @@ void AIS_InteractiveContext::ClearGlobal(const Handle(AIS_InteractiveObject)& an // const Handle(AIS_GlobalStatus)& STATUS = myObjects(anIObj); Handle(AIS_GlobalStatus) STATUS = myObjects(anIObj); // ENDCLE - for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){ + TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes()); + for(;ItL.More();ItL.Next()){ if(STATUS->IsHilighted()){ if(IsCurrent(anIObj)) #ifdef OCC204 diff --git a/src/Standard/Handle_Standard_Transient.cxx b/src/Standard/Handle_Standard_Transient.cxx index 23442414e8..bad55c3a87 100755 --- a/src/Standard/Handle_Standard_Transient.cxx +++ b/src/Standard/Handle_Standard_Transient.cxx @@ -23,12 +23,9 @@ void Handle(Standard_Transient)::Assign (const Standard_Transient *anItem) void Handle(Standard_Transient)::BeginScope() { - if (entity != UndefinedHandleAddress) + if (entity != UndefinedHandleAddress) { - if ( Standard::IsReentrant() ) - Standard_Atomic_Increment (&entity->count); - else - entity->count++; + Standard_Atomic_Increment (&entity->count); } } @@ -36,11 +33,9 @@ void Handle(Standard_Transient)::BeginScope() void Handle(Standard_Transient)::EndScope() { - if (entity == UndefinedHandleAddress) + if (entity == UndefinedHandleAddress) return; - if ( Standard::IsReentrant() ? - Standard_Atomic_DecrementTest (&entity->count) : - (--entity->count == 0) ) + if (Standard_Atomic_Decrement (&entity->count) == 0) entity->Delete(); entity = UndefinedHandleAddress; } diff --git a/src/Standard/Standard_Atomic.hxx b/src/Standard/Standard_Atomic.hxx index 93f80ecd84..4208ae26ec 100755 --- a/src/Standard/Standard_Atomic.hxx +++ b/src/Standard/Standard_Atomic.hxx @@ -10,91 +10,95 @@ //! By the moment, only operations necessary for reference counter //! in Standard_Transient objects are implemented. //! -//! Currently only two x86-based configurations (Windows NT with -//! MS VC++ compiler and Linix with GCC) are really supported. -//! Other configurations use non-atomic C equivalent. +//! This is preffered to use fixed size types "int32_t" / "int64_t" for +//! correct function declarations however we leave "int" assuming it is 32bits for now. -//! @fn void Standard_Atomic_Increment (int volatile* var) -//! @brief Increments atomically integer variable pointed by var +#ifndef _Standard_Atomic_HeaderFile +#define _Standard_Atomic_HeaderFile -//! @fn int Standard_Atomic_DecrementTest (int volatile* var) -//! @brief Decrements atomically integer variable pointed by var; -//! returns 1 if result is zero, 0 otherwise - -//=================================================== -// Windows NT, MSVC++ compiler -//=================================================== -#if defined(WNT) +#include +#if (defined(_WIN32) || defined(__WIN32__)) extern "C" { -long _InterlockedIncrement(long volatile* lpAddend); -long _InterlockedDecrement(long volatile* lpAddend); + long _InterlockedIncrement(long volatile* lpAddend); + long _InterlockedDecrement(long volatile* lpAddend); } - -#pragma intrinsic (_InterlockedIncrement) -#pragma intrinsic (_InterlockedDecrement) - -inline void Standard_Atomic_Increment (int volatile* var) -{ - _InterlockedIncrement (reinterpret_cast(var)); -} - -inline int Standard_Atomic_DecrementTest (int volatile* var) -{ - return _InterlockedDecrement (reinterpret_cast(var)) == 0; -} - -//=================================================== -// Linux, GCC compiler -// Note: Linux kernel 2.6x provides definitions for atomic operators -// in the header file /usr/include/asm/atomic.h, -// however these definitions involve specific type atomic_t -// Note: The same code probably would work for Intel compiler -//=================================================== -#elif defined(LIN) - -inline void Standard_Atomic_Increment (int volatile* var) -{ - // C equivalent: - // ++(*var); - - __asm__ __volatile__ - ( - "lock incl %0" - : "=m"(*var) // out - : "m" (*var) // in - ); -} - -inline int Standard_Atomic_DecrementTest (int volatile* var) -{ - // C equivalent: - // return --(*var) == 0; - - unsigned char c; - __asm__ __volatile__ - ( - "lock decl %0; sete %1" - : "=m"(*var), "=qm"(c) // out - : "m" (*var) // in - : "memory" - ); - return c != 0; -} - -//=================================================== -// Default stub implementation, not atomic actually -//=================================================== -#else - -inline void Standard_Atomic_Increment (int volatile* var) -{ - ++(*var); -} - -inline int Standard_Atomic_DecrementTest (int volatile* var) -{ - return --(*var) == 0; -} - #endif + +#if defined(_MSC_VER) + // force intrinsic instead of WinAPI calls + #pragma intrinsic (_InterlockedIncrement) + #pragma intrinsic (_InterlockedDecrement) +#endif + +//! Increments atomically integer variable pointed by theValue +//! and returns resulting incremented value. +static int Standard_Atomic_Increment (volatile int* theValue) +{ +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + // mordern g++ compiler (gcc4.4+) + // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform) + return __sync_add_and_fetch (theValue, 1); +#elif (defined(_WIN32) || defined(__WIN32__)) + // WinAPI function or MSVC intrinsic + return _InterlockedIncrement(reinterpret_cast(theValue)); +#elif defined(LIN) + // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC) + int anIncResult; + __asm__ __volatile__ ( + #if defined(_OCC64) + "lock xaddl %%ebx, (%%rax) \n\t" + "incl %%ebx \n\t" + : "=b" (anIncResult) + : "a" (theValue), "b" (1) + : "cc", "memory"); + #else + "lock xaddl %%eax, (%%ecx) \n\t" + "incl %%eax \n\t" + : "=a" (anIncResult) + : "c" (theValue), "a" (1) + : "memory"); + #endif + return anIncResult; +#else + //#error "Atomic operation doesn't implemented for current platform!" + return ++(*theValue); +#endif +} + +//! Decrements atomically integer variable pointed by theValue +//! and returns resulting decremented value. +static int Standard_Atomic_Decrement (volatile int* theValue) +{ +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + // mordern g++ compiler (gcc4.4+) + // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform) + return __sync_sub_and_fetch (theValue, 1); +#elif (defined(_WIN32) || defined(__WIN32__)) + // WinAPI function or MSVC intrinsic + return _InterlockedDecrement(reinterpret_cast(theValue)); +#elif defined(LIN) + // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC) + int aDecResult; + __asm__ __volatile__ ( + #if defined(_OCC64) + "lock xaddl %%ebx, (%%rax) \n\t" + "decl %%ebx \n\t" + : "=b" (aDecResult) + : "a" (theValue), "b" (-1) + : "cc", "memory"); + #else + "lock xaddl %%eax, (%%ecx) \n\t" + "decl %%eax \n\t" + : "=a" (aDecResult) + : "c" (theValue), "a" (-1) + : "memory"); + #endif + return aDecResult; +#else + //#error "Atomic operation doesn't implemented for current platform!" + return --(*theValue); +#endif +} + +#endif //_Standard_Atomic_HeaderFile diff --git a/src/Standard/Standard_Transient_proto.hxx b/src/Standard/Standard_Transient_proto.hxx index f771a6e5bb..aedc3d0819 100755 --- a/src/Standard/Standard_Transient_proto.hxx +++ b/src/Standard/Standard_Transient_proto.hxx @@ -86,7 +86,7 @@ class Standard_Transient private: - Standard_Integer count; + volatile Standard_Integer count; }; Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(Standard_Transient);