ML Reference
MeVis/Foundation/Sources/MLUtilities/mlTrace.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //----------------------------------------------------------------------------------
00010 
00016 //----------------------------------------------------------------------------------
00017 
00018 #ifndef __mlTrace_H
00019 #define __mlTrace_H
00020 
00021 #ifndef __mlUtilsSystem_H
00022 #include "mlUtilsSystem.h"
00023 #endif
00024 
00025 
00026 ML_UTILS_START_NAMESPACE
00027 
00028   //-------------------------------------------------------------------------
00050   //-------------------------------------------------------------------------
00051   template <typename INDEXTYPE> class TraceBuffer {
00052   public:
00053     //-----------------------------------------------------------
00056     //-----------------------------------------------------------
00057     inline TraceBuffer()
00058     {
00059       // Initialize both buffers with NULL pointers.
00060       memset(_traceStack, 0, _numBufBytes);
00061       memset(_traceList,  0, _numBufBytes);
00062 
00063       // Reset indices into stack and list.
00064       _traceStackTop = 0;
00065       _traceListEnd  = 0;
00066     }
00067 
00068     //-----------------------------------------------------------
00075     //-----------------------------------------------------------
00076     inline void add(const char* const traceInString){
00077       // Push string address onto the stack. Be sure that 
00078       // _stackTop is incremented after storing pointer to 
00079       // make memory access and incrementation of index independent. 
00080       // So the CPU can execute both statements in parallel.
00081       // Also be sure to increment index NOT within "[" and "]"
00082       // to avoid that indexing works on 32bit integers which would 
00083       // access areas outside buffers
00084       _traceStack[_traceStackTop] = traceInString;
00085 
00086       // Do not increment inside [ and ] because that could be evaluated
00087       // to an integer which would lead to illegal out of range accesses.
00088       ++_traceStackTop;
00089 
00090       // Append string address to end of trace list. For optimizing 
00091       // performance also see _traceStack push above.
00092       _traceList[_traceListEnd] = traceInString;
00093 
00094       // Do not increment inside [ and ] because that could be evaluated
00095       // to an integer which would lead to illegal out of range accesses.
00096       ++_traceListEnd;
00097     }
00098 
00099     //-----------------------------------------------------------
00103     //-----------------------------------------------------------
00104     inline void remove(){
00105       // Decrement trace stack top. Be sure that integer index 
00106       // is really limited to size of INDEXTYPE since passing 
00107       // decremented _traceStackTop without masking it could 
00108       // lead to usage of 32 bit index in index "[" "]" and 
00109       // accesses outside buffers. Note that mask calculation 
00110       // is constant and probably will be evaluated on compile 
00111       // time.
00112       _traceStackTop = static_cast<INDEXTYPE>((_traceStackTop - 1) & _bufferIndexMask);
00113 
00114       // Reset stack entry. So unused entries do not use 
00115       // invalid information.
00116       _traceStack[_traceStackTop] = NULL;
00117     }
00118 
00119     //-----------------------------------------------------------
00122     //-----------------------------------------------------------
00123     inline INDEXTYPE getTraceStackTop() const { return _traceStackTop; }
00124 
00125     //-----------------------------------------------------------
00128     //-----------------------------------------------------------
00129     inline INDEXTYPE getTraceListEnd()  const { return _traceListEnd;  }
00130 
00131     //-----------------------------------------------------------
00133     //-----------------------------------------------------------
00134     inline const char* const *getTraceStack()    const { return _traceStack;    }
00135 
00136     //-----------------------------------------------------------
00138     //-----------------------------------------------------------
00139     inline const char* const *getTraceList()     const { return _traceList;     }
00140 
00141   private:
00142 
00147     enum { _numBufEntries   = (1L << (sizeof(INDEXTYPE) << 3)) ,
00148            _numBufBytes     = _numBufEntries * sizeof(const char *),
00149            _bufferIndexMask = _numBufEntries - 1
00150     };
00151     
00153     INDEXTYPE   _traceStackTop;
00154     
00156     INDEXTYPE   _traceListEnd;
00157 
00159     const char *_traceStack[_numBufEntries];
00160 
00162     const char *_traceList[_numBufEntries];
00163   };
00164 
00165   //-------------------------------------------------------------------------
00178   //-------------------------------------------------------------------------
00179   template <typename INDEXTYPE> class Trace {
00180   public:
00181 
00182     //-----------------------------------------------------------
00193     //-----------------------------------------------------------
00194     inline Trace(const char * const traceInString, TraceBuffer<INDEXTYPE> &traceBuf) : 
00195       _traceBuf(traceBuf)
00196     {
00197       // Push string address on stack and at end of trace list.
00198       traceBuf.add(traceInString);
00199     }
00200 
00201     //-----------------------------------------------------------
00208     //-----------------------------------------------------------
00209     inline ~Trace()
00210     {
00211       _traceBuf.remove();
00212     }
00213 
00214   private:
00215 
00219     TraceBuffer<INDEXTYPE> &_traceBuf;
00220 
00221 
00224     inline Trace(const Trace &trace) : _traceBuf(trace._traceBuf){ }
00225 
00229     inline Trace<INDEXTYPE> &operator=(const Trace & /* trace */){ return *this; }
00230   };
00231 
00232 
00233   //---------------------------------------------------------------------------
00235   //---------------------------------------------------------------------------
00236   typedef MLuint16 MLGlobalTraceBufferType;
00237 
00238   //---------------------------------------------------------------------------
00242   //---------------------------------------------------------------------------
00243   extern ML_UTILS_EXPORT TraceBuffer<MLGlobalTraceBufferType> MLGlobalTraceBuffer;
00244 
00245 
00246 ML_UTILS_END_NAMESPACE
00247 
00248 
00249 #endif // __mlTrace_H
00250