1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 /*========================================================================= 19 * 20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright. 21 * 22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 23 * 24 * For complete copyright, license and disclaimer of warranty information 25 * please refer to the NOTICE file at the top of the ITK source tree. 26 * 27 *=========================================================================*/ 28 #ifndef itkTimeStamp_h 29 #define itkTimeStamp_h 30 31 #include "itkMacro.h" 32 #include "itkIntTypes.h" 33 #include <atomic> 34 #include "itkSingletonMacro.h" 35 36 namespace itk 37 { 38 /** \class TimeStamp 39 * \brief Generate a unique, increasing time value. 40 * 41 * TimeStamp records a unique time when the method Modified() is 42 * executed. This time is guaranteed to be monotonically increasing. 43 * Classes use this object to record modified and/or execution time. 44 * There is built in support for the binary < and > comparison 45 * operators between two TimeStamp objects. 46 * 47 * \warning On most platforms, this class uses a lock-free incremental 48 * counter. The Modified function can safely be called simultaneously 49 * by multiple threads on different instances of the class. However, 50 * calling the Modified function by different threads on the same 51 * instance of the class can lead to some unexpected behavior. The 52 * global counter will always be correct but the local m_ModifiedTime 53 * might not (see 54 * https://www.itk.org/mailman/private/insight-developers/2009-February/011732.html 55 * for more detail). 56 * 57 * \ingroup ITKSystemObjects 58 * \ingroup ITKCommon 59 */ 60 class ITKCommon_EXPORT TimeStamp 61 { 62 public: 63 /** Standard class type aliases. */ 64 using Self = TimeStamp; 65 66 using GlobalTimeStampType = std::atomic< ModifiedTimeType >; 67 68 /** Create an instance of this class. We don't want to use reference 69 * counting. */ 70 static Self * New(); 71 72 /** Constructor must remain public because classes instantiate 73 * TimeStamps implicitly in their construction. */ TimeStamp()74 TimeStamp() 75 { m_ModifiedTime = 0; } 76 77 /** Destoy this instance. */ Delete()78 void Delete() 79 { delete this; } 80 81 /** The class name as a string. */ GetNameOfClass()82 static const char * GetNameOfClass() 83 { return "TimeStamp"; } 84 85 /** Set this objects time to the current time. The current time is just a 86 * monotonically increasing unsigned long integer. It is possible for this 87 * number to wrap around back to zero. This should only happen for 88 * processes that have been running for a very long time, while constantly 89 * changing objects within the program. When this does occur, the typical 90 * consequence should be that some filters will update themselves when 91 * really they don't need to. */ 92 void Modified(); 93 94 /** Return this object's Modified time. */ GetMTime()95 ModifiedTimeType GetMTime() const 96 { return m_ModifiedTime; } 97 98 /** Support comparisons of time stamp objects directly. */ 99 bool operator>(TimeStamp & ts) 100 { return ( m_ModifiedTime > ts.m_ModifiedTime ); } 101 bool operator<(TimeStamp & ts) 102 { return ( m_ModifiedTime < ts.m_ModifiedTime ); } 103 104 /** Allow for typcasting to unsigned long. */ ModifiedTimeType()105 operator ModifiedTimeType() const 106 { return m_ModifiedTime; } 107 108 /** Assignment operator, allows to initialize one time stamp by copying from 109 * another. */ 110 Self & operator=( const Self & other ) = default; 111 112 private: 113 /** Set/Get the pointer to GlobalTimeStamp. 114 * Note that SetGlobalTimeStamp is not concurrent thread safe. */ 115 itkGetGlobalDeclarationMacro(GlobalTimeStampType, GlobalTimeStamp); 116 117 ModifiedTimeType m_ModifiedTime; 118 119 /** The static GlobalTimeStamp. This is initialized to NULL as the first 120 * stage of static initialization. It is then populated on the first call to 121 * itk::TimeStamp::Modified() but it can be overridden with SetGlobalTimeStamp(). 122 * */ 123 static GlobalTimeStampType *m_GlobalTimeStamp; 124 }; 125 } // end namespace itk 126 127 #endif 128