1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
25 #define __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
26 
27 //*************************************************************************************************************
28 //  special macros for time measures
29 //  1) LOGFILE_MEMORYMEASURE                  used it to define log file for this operations (default will be set automaticly)
30 //  2) MAKE_MEMORY_SNAPSHOT                   make snapshot of currently set memory informations of OS
31 //  3) LOG_MEMORYMEASURE                      write measured time to logfile
32 //*************************************************************************************************************
33 
34 #ifdef ENABLE_MEMORYMEASURE
35 
36     #if !defined( WNT )
37         #error "Macros to measure memory access not available under platforms different from windows!"
38     #endif
39 
40 	//_________________________________________________________________________________________________________________
41 	//	includes
42 	//_________________________________________________________________________________________________________________
43 
44 	#ifndef _RTL_STRBUF_HXX_
45 	#include <rtl/strbuf.hxx>
46 	#endif
47 
48     #ifndef __SGI_STL_VECTOR
49     #include <vector>
50     #endif
51 
52 	/*_____________________________________________________________________________________________________________
53         LOGFILE_MEMORYMEASURE
54 
55 		For follow macros we need a special log file. If user forget to specify anyone, we must do it for him!
56 	_____________________________________________________________________________________________________________*/
57 
58     #ifndef LOGFILE_MEMORYMEASURE
59         #define LOGFILE_MEMORYMEASURE "memorymeasure.log"
60 	#endif
61 
62     /*_____________________________________________________________________________________________________________
63         class MemoryMeasure
64 
65         We use this baseclass to collect all snapshots in one object and analyze this information at one point.
66         Macros of this file are used to enable using of this class by special compile-parameter only!
67 	_____________________________________________________________________________________________________________*/
68 
69     class _DBGMemoryMeasure
70     {
71         //---------------------------------------------------------------------------------------------------------
72         private:
73             struct _MemoryInfo
74             {
75                 MEMORYSTATUS        aStatus     ;
76                 ::rtl::OString      sComment    ;
77             };
78 
79         //---------------------------------------------------------------------------------------------------------
80         public:
81             //_____________________________________________________________________________________________________
_DBGMemoryMeasure()82             inline _DBGMemoryMeasure()
83             {
84             }
85 
86             //_____________________________________________________________________________________________________
87             // clear used container!
~_DBGMemoryMeasure()88             inline ~_DBGMemoryMeasure()
89             {
90                 ::std::vector< _MemoryInfo >().swap( m_lSnapshots );
91             }
92 
93             //_____________________________________________________________________________________________________
makeSnapshot(const::rtl::OString & sComment)94             inline void makeSnapshot( const ::rtl::OString& sComment )
95             {
96                 _MemoryInfo aInfo;
97                 aInfo.sComment = sComment;
98                 GlobalMemoryStatus    ( &(aInfo.aStatus) );
99                 m_lSnapshots.push_back( aInfo            );
100             }
101 
102             //_____________________________________________________________________________________________________
getLog()103             inline ::rtl::OString getLog()
104             {
105                 ::rtl::OStringBuffer sBuffer( 10000 );
106 
107                 if( !m_lSnapshots.empty() )
108                 {
109                     // Write informations to return buffer
110                     ::std::vector< _MemoryInfo >::const_iterator pItem1;
111                     ::std::vector< _MemoryInfo >::const_iterator pItem2;
112 
113                     pItem1 = m_lSnapshots.begin();
114                     pItem2 = pItem1;
115                     ++pItem2;
116 
117                     while( pItem1!=m_lSnapshots.end() )
118                     {
119                         sBuffer.append( "snap [ "                                   );
120                         sBuffer.append( pItem1->sComment                            );
121                         sBuffer.append( " ]\n\tavail phys\t=\t"                     );
122                         sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPhys      );
123                         sBuffer.append( "\n\tavail page\t=\t"                       );
124                         sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPageFile  );
125                         sBuffer.append( "\n\tavail virt\t=\t"                       );
126                         sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailVirtual   );
127                         sBuffer.append( "\n\tdifference\t=\t[ "                     );
128 
129                         if( pItem1 == m_lSnapshots.begin() )
130                         {
131                             sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPhys      );
132                             sBuffer.append( ", "                                        );
133                             sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPageFile  );
134                             sBuffer.append( ", "                                        );
135                             sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailVirtual   );
136                             sBuffer.append( " ]\n\n"                                    );
137                         }
138                         else if( pItem2 != m_lSnapshots.end() )
139                         {
140                             sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailPhys     - pItem1->aStatus.dwAvailPhys       ) );
141                             sBuffer.append( ", "                                                                              );
142                             sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailPageFile - pItem1->aStatus.dwAvailPageFile   ) );
143                             sBuffer.append( ", "                                                                              );
144                             sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailVirtual  - pItem1->aStatus.dwAvailVirtual    ) );
145                             sBuffer.append( " ]\n\n"                                                                          );
146                         }
147                         else
148                         {
149                             sBuffer.append( "0, 0, 0 ]\n\n" );
150                         }
151                         if( pItem1!=m_lSnapshots.end() ) ++pItem1;
152                         if( pItem2!=m_lSnapshots.end() ) ++pItem2;
153                     }
154                     // clear current list ... make it empty for further snapshots!
155                     ::std::vector< _MemoryInfo >().swap( m_lSnapshots );
156                 }
157 
158                 return sBuffer.makeStringAndClear();
159             }
160 
161         //---------------------------------------------------------------------------------------------------------
162         private:
163             ::std::vector< _MemoryInfo > m_lSnapshots;
164     };
165 
166 	/*_____________________________________________________________________________________________________________
167         START_MEMORY_MEASURE
168 
169         Create new object to measure memory access.
170     _____________________________________________________________________________________________________________*/
171 
172     #define START_MEMORYMEASURE( AOBJECT )                                                                      \
173                 _DBGMemoryMeasure AOBJECT;
174 
175 	/*_____________________________________________________________________________________________________________
176         MAKE_MEMORY_SNAPSHOT
177 
178         Make snapshot of currently set memory informations of OS.
179         see _DBGMemoryMeasure for further informations
180     _____________________________________________________________________________________________________________*/
181 
182     #define MAKE_MEMORY_SNAPSHOT( AOBJECT, SCOMMENT )                                                           \
183                 AOBJECT.makeSnapshot( SCOMMENT );
184 
185 	/*_____________________________________________________________________________________________________________
186         LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT )
187 
188         Write measured values to logfile.
189     _____________________________________________________________________________________________________________*/
190 
191     #define LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT )                                                  \
192                 {                                                                                               \
193                     ::rtl::OStringBuffer _sBuffer( 256 );                                                       \
194                     _sBuffer.append( SOPERATION         );                                                      \
195                     _sBuffer.append( "\n"               );                                                      \
196                     _sBuffer.append( SCOMMENT           );                                                      \
197                     _sBuffer.append( "\n\n"             );                                                      \
198                     _sBuffer.append( AOBJECT.getLog()   );                                                      \
199                     WRITE_LOGFILE( LOGFILE_MEMORYMEASURE, _sBuffer.makeStringAndClear() )                       \
200                 }
201 
202 #else   // #ifdef ENABLE_MEMORYMEASURE
203 
204 	/*_____________________________________________________________________________________________________________
205 		If right testmode is'nt set - implements these macros empty!
206 	_____________________________________________________________________________________________________________*/
207 
208     #undef  LOGFILE_MEMORYMEASURE
209     #define START_MEMORYMEASURE( AOBJECT )
210     #define MAKE_MEMORY_SNAPSHOT( AOBJECT, SCOMMENT )
211     #define LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT )
212 
213 #endif  // #ifdef ENABLE_MEMORYMEASURE
214 
215 //*****************************************************************************************************************
216 //	end of file
217 //*****************************************************************************************************************
218 
219 #endif  // #ifndef __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
220