(file) Return to TraceMemoryHandler.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/TraceMemoryHandler.cpp between version 1.1 and 1.9

version 1.1, 2008/09/02 17:33:37 version 1.9, 2008/09/18 08:01:37
Line 31 
Line 31 
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
   // This _ISOC99_SOURCE definition and inclusion of stdio.h and stdarg.h
   // must precede the other file contents on z/OS.
 #ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM #ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM
 #define _ISOC99_SOURCE #define _ISOC99_SOURCE
   #endif
 #include <stdio.h> #include <stdio.h>
 #include <stdarg.h> #include <stdarg.h>
 #endif  
  
 #include <Pegasus/Common/TraceMemoryHandler.h> #include <Pegasus/Common/TraceMemoryHandler.h>
 #include <iostream> #include <iostream>
 #include <fstream> #include <fstream>
  
 #define PEGASUS_TRC_BUFFER_WRAP_MARKER ""  // ATTN: This is a workaround to allow HP-UX and Windows builds to succeed.
 #define PEGASUS_TRC_BUFFER_EOT_MARKER "*EOTRACE*"  // It appears to work, but it may not be reliable.  A better solution would be
 #define PEGASUS_TRC_BUFFER_EOT_MARKER_LEN 9  // preferred.
   #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_TYPE_WINDOWS)
   # ifndef va_copy
   #  define va_copy(dest, src) (void)((dest) = (src))
   # endif
   #endif
  
 //#define DBG(output) output  
 #define DBG(output)  
  
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 //  Constructs TraceMemoryHandler with a default buffer size  
 ////////////////////////////////////////////////////////////////////////////////  
 TraceMemoryHandler::TraceMemoryHandler()  
 {  
     Uint32 traceAreaSize = PEGASUS_TRC_DEFAULT_BUFFER_SIZE_KB * 1024;  
   
     _initialize(traceAreaSize);  
 }  
   
 ////////////////////////////////////////////////////////////////////////////////  
 //  Constructs TraceMemoryHandler with a custom buffer size //  Constructs TraceMemoryHandler with a custom buffer size
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 TraceMemoryHandler::TraceMemoryHandler( Uint32 bufferSize )  TraceMemoryHandler::TraceMemoryHandler():
       _overflowBuffer(0),
       _overflowBufferSize(0),
       _traceArea(0),
       _leftBytesInBuffer(0),
       _inUseCounter(0),
       _lockCounter(1),
       _dying(false),
       _contentionCount(0),
       _numberOfLocksObtained(0),
       _traceFileName(0)
 { {
     Uint32 traceAreaSize = bufferSize * 1024;  
  
     _initialize(traceAreaSize);  
 } }
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 //  Private method to (re-)initialize the memory buffer //  Private method to (re-)initialize the memory buffer
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 void TraceMemoryHandler::_initialize( Uint32 traceAreaSize )  void TraceMemoryHandler::_initializeTraceArea()
 { {
     _dying = false;      if (_traceArea)
     _inUseCounter = 0;      {
     _lockCounter  = 1;          delete _traceArea;
     _contentionCount = 0;      }
     _numberOfLocksObtained = 0;  
     _traceFileName = 0;  
   
  
     _overflowBuffer = 0;      // get the memory buffer size from the tracer instance.
     _overflowBufferSize = 0;      Uint32 traceAreaSize =
           Tracer::_getInstance()->_traceMemoryBufferSize * 1024;
  
     _traceArea = (struct traceArea_t*) new char[traceAreaSize];     _traceArea = (struct traceArea_t*) new char[traceAreaSize];
  
     // The final buffer size is the size of the allocated area, less the     // The final buffer size is the size of the allocated area, less the
     // size of the header struct, less one byte reseved for a terminating 0     // size of the header struct, less one byte reseved for a terminating 0
     _traceArea->bufferSize = traceAreaSize - sizeof(struct traceArea_t);      _traceArea->bufferSize = traceAreaSize - sizeof(struct traceArea_t) - 1;
     _traceArea->bufferSize--;  
     _traceArea->nextPos = 0;     _traceArea->nextPos = 0;
       _traceArea->traceBuffer = (char*) (&(_traceArea->traceBuffer) + 1);
     _leftBytesInBuffer = _traceArea->bufferSize-1;     _leftBytesInBuffer = _traceArea->bufferSize-1;
  
     memcpy(_traceArea->eyeCatcher,     memcpy(_traceArea->eyeCatcher,
Line 174 
Line 175 
             // The memory tracing is about to end.             // The memory tracing is about to end.
             // The caller will never get the lock.             // The caller will never get the lock.
             _inUseCounter.dec();             _inUseCounter.dec();
             return false;              break;
         }         }
  
         // If the lock counter not 1,an other caller is in the critical section.         // If the lock counter not 1,an other caller is in the critical section.
Line 258 
Line 259 
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 void TraceMemoryHandler::dumpTraceBuffer(const char* filename) void TraceMemoryHandler::dumpTraceBuffer(const char* filename)
 { {
       if (!filename)
       {
           // if the file name is empty/NULL pointer do nothing
           return;
       }
   #ifdef PEGASUS_DEBUG
     cerr << "Number of lock contentions is <"<< _contentionCount.get()     cerr << "Number of lock contentions is <"<< _contentionCount.get()
          << ">" << endl;          << ">" << endl;
     cerr << "Number of obtained locks is <"<< _numberOfLocksObtained     cerr << "Number of obtained locks is <"<< _numberOfLocksObtained
          << ">" << endl;          << ">" << endl;
   #endif
  
     ofstream ofile(filename,ios::app&ios::out);     ofstream ofile(filename,ios::app&ios::out);
     if( ofile.good() )     if( ofile.good() )
Line 334 
Line 342 
         return;         return;
     }     }
  
   
       // If the trace memory is not initialized.
       if(!_traceArea)
       {
           _initializeTraceArea();
       }
   
       Uint32 msgStart =  _traceArea->nextPos;
     // Handle the static part of the message     // Handle the static part of the message
     _appendSimpleMessage(message, msgLen);     _appendSimpleMessage(message, msgLen);
  
Line 388 
Line 404 
         // buffer.         // buffer.
         // To save memory allocations, the overflow buffer is kept around         // To save memory allocations, the overflow buffer is kept around
         // until it becomes to small and needs to be reallocated.         // until it becomes to small and needs to be reallocated.
         if ((Uint32)ttlMsgLen > _overflowBufferSize)          if (ttlMsgLen == -1 || (msgLen + ttlMsgLen) > _traceArea->bufferSize)
           {
               // The message does not fit in the remaining buffer and
               // vsnprintf() did not return the bytes needed
               // or the message is larger then the treace Buffer.
   
               // The message does not fit in the remaining buffer,
               // clean up the the message fragment.
               _traceArea->traceBuffer[msgStart] = 0;
   
               // Wrap the buffer
               _traceArea->nextPos = 0;
               _leftBytesInBuffer = _traceArea->bufferSize;
   
               // Rewrite the static part of the message
               _appendSimpleMessage(message, msgLen);
   
               // Rewrite the variable part of the message
   #ifdef PEGASUS_OS_TYPE_WINDOWS
               // Windows until VC 8 does not support vsnprintf
               // need to use Windows equivalent function with the underscore
               ttlMsgLen =
               _vsnprintf(&(_traceArea->traceBuffer[_traceArea->nextPos]),
                          _leftBytesInBuffer,
                          fmt,
                          argListCopy);
   #else
               ttlMsgLen =
               vsnprintf(&(_traceArea->traceBuffer[_traceArea->nextPos]),
                         _leftBytesInBuffer,
                         fmt,
                         argListCopy);
   #endif
               if (ttlMsgLen == -1 ||
                   (msgLen + ttlMsgLen) > _traceArea->bufferSize)
               {
                   // The message still does not fit in the buffer, but know
                   // we know that the most part of the message is in the buffer.
                   // Truncate the message using the truncation marker and leave
                   // space for the EOT marker + '\n'.
                   _leftBytesInBuffer = PEGASUS_TRC_BUFFER_TRUNC_MARKER_LEN +
                       PEGASUS_TRC_BUFFER_EOT_MARKER_LEN + 1 ;
   
                   _traceArea->nextPos =
                       _traceArea->bufferSize - _leftBytesInBuffer ;
   
                   // copy the marker including the trailing '0' !
                   memcpy(&(_traceArea->traceBuffer[_traceArea->nextPos]),
                       PEGASUS_TRC_BUFFER_TRUNC_MARKER,
                       PEGASUS_TRC_BUFFER_TRUNC_MARKER_LEN + 1 );
   
                   _traceArea->nextPos += PEGASUS_TRC_BUFFER_TRUNC_MARKER_LEN + 1;
               }
               else
               {
                   // Now the message fits into the buffer.
                   ttlMsgLen++;  //Include the '/0'
   
                   _traceArea->nextPos += ttlMsgLen;
                   _leftBytesInBuffer -= ttlMsgLen;
               }
           } // End of vsnprintf() == -1 or message > buffer size
           else
           {
               // vsnprintf() retuns number of bytes of the variable message and
               // the Message fits in the buffer.
           if ((Uint32)ttlMsgLen >= _overflowBufferSize)
         {         {
             if (_overflowBuffer != NULL )             if (_overflowBuffer != NULL )
             {             {
                 delete[] _overflowBuffer;                 delete[] _overflowBuffer;
             }             }
             _overflowBufferSize = ttlMsgLen;              _overflowBufferSize = ttlMsgLen+1;
             _overflowBuffer = new char[_overflowBufferSize];             _overflowBuffer = new char[_overflowBufferSize];
         }         }
  
Line 412 
Line 494 
                               argListCopy);                               argListCopy);
 #endif #endif
  
           // The actual number of characters written to the buffer is the
           // number of bytes left in the buffer minus the trailing '/0'.
           Uint32 numCharsWritten = _leftBytesInBuffer-1;
  
         // Now calculate how much data we have to copy from the overflow         // Now calculate how much data we have to copy from the overflow
         // buffer back to the trace buffer.         // buffer back to the trace buffer.
         ttlMsgLen -= _leftBytesInBuffer;          ttlMsgLen -= numCharsWritten;
  
         // Copy the remainder of the trace message to the trace buffer         // Copy the remainder of the trace message to the trace buffer
         memcpy(&(_traceArea->traceBuffer[0]),         memcpy(&(_traceArea->traceBuffer[0]),
                &(_overflowBuffer[_leftBytesInBuffer]),                 &(_overflowBuffer[numCharsWritten]),
                ttlMsgLen );                ttlMsgLen );
  
         _traceArea->nextPos = ttlMsgLen+1;         _traceArea->nextPos = ttlMsgLen+1;
         _leftBytesInBuffer = _traceArea->bufferSize - _traceArea->nextPos;         _leftBytesInBuffer = _traceArea->bufferSize - _traceArea->nextPos;
     }     }
       } // End of reached end of buffer and need to wrap.
  
     // replace null terminator with line break     // replace null terminator with line break
     _traceArea->traceBuffer[_traceArea->nextPos-1] = '\n';     _traceArea->traceBuffer[_traceArea->nextPos-1] = '\n';
Line 445 
Line 531 
         return;         return;
     }     }
  
       // If the trace memory is not initialized.
       if(!_traceArea)
       {
           _initializeTraceArea();
       }
   
     // We include the terminating 0 in the message for easier handling     // We include the terminating 0 in the message for easier handling
     msgLen++;     msgLen++;
  
Line 460 
Line 552 
 } }
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 //  Checks if a given message file is usable  
 ////////////////////////////////////////////////////////////////////////////////  
 Boolean TraceMemoryHandler::isValidMessageDestination(const char* traceFileName)  
 {  
     TraceFileHandler traceFileHandler;  
   
     return traceFileHandler.isValidMessageDestination( traceFileName );  
 }  
   
   
 ////////////////////////////////////////////////////////////////////////////////  
 //  Sets the message file in case we need to flush out the trace  
 ////////////////////////////////////////////////////////////////////////////////  
 Uint32 TraceMemoryHandler::setMessageDestination(const char* destination)  
 {  
     delete[] _traceFileName;  
   
     _traceFileName = new char[strlen(destination)+1];  
     strcpy(_traceFileName, destination);  
   
     return 0;  
 }  
   
 ////////////////////////////////////////////////////////////////////////////////  
 //  Flushes the trace //  Flushes the trace
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 void TraceMemoryHandler::flushTrace() void TraceMemoryHandler::flushTrace()
 { {
     dumpTraceBuffer(_traceFileName);      dumpTraceBuffer((const char*)Tracer::_getInstance()
                             ->_traceFile.getCString());
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.1  
changed lines
  Added in v.1.9

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2