(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.13

version 1.1, 2008/09/02 17:33:37 version 1.13, 2008/12/16 18:56:00
Line 1 
Line 1 
 //%2006////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  
 // EMC Corporation; Symantec Corporation; The Open Group.  
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy  // Permission is hereby granted, free of charge, to any person obtaining a
 // of this software and associated documentation files (the "Software"), to  // copy of this software and associated documentation files (the "Software"),
 // deal in the Software without restriction, including without limitation the  // to deal in the Software without restriction, including without limitation
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 // sell copies of the Software, and to permit persons to whom the Software is  // and/or sell copies of the Software, and to permit persons to whom the
 // furnished to do so, subject to the following conditions:  // Software is furnished to do so, subject to the following conditions:
 // //
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  // The above copyright notice and this permission notice shall be included
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  // in all copies or substantial portions of the Software.
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 // //
 //==============================================================================  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   //
   //////////////////////////////////////////////////////////////////////////
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM  // This _ISOC99_SOURCE definition and inclusion of stdio.h and stdarg.h
   // must precede the other file contents on z/OS.
   #if defined(PEGASUS_OS_ZOS)
 #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 173 
             // 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 257 
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 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 340 
         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 402 
         // 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 492 
                               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 529 
         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 550 
 } }
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 //  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.13

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2