Annotation of parser3/src/types/pa_vstatus.C, revision 1.28
1.1 paf 1: /** @file
2: Parser: @b status class impl.
3:
1.28 ! moko 4: Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.6 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.16 paf 6:
7: Win32 rusage author: Victor Fedoseev <vvf_ru@mail.ru>
1.8 paf 8: */
1.1 paf 9:
10: #include "pa_vstatus.h"
11: #include "pa_cache_managers.h"
1.2 paf 12: #include "pa_vhash.h"
13: #include "pa_vdouble.h"
1.23 paf 14: #include "pa_threads.h"
1.2 paf 15:
1.28 ! moko 16: volatile const char * IDENT_PA_VSTATUS_C="$Id: 2009-08-08 13:30:22 $" IDENT_PA_VSTATUS_H;
! 17:
1.2 paf 18: #ifdef HAVE_SYS_RESOURCE_H
19: // rusage
20: #include <sys/resource.h>
21: #endif
1.1 paf 22:
1.16 paf 23: #ifdef WIN32
1.26 paf 24: #define WINVER 0x0400
1.16 paf 25: #include <windows.h>
26: #include "psapi.h"
27:
28: // should be in windows.h, but were't
29: typedef struct _IO_COUNTERS_ {
30: ULONGLONG ReadOperationCount;
31: ULONGLONG WriteOperationCount;
32: ULONGLONG OtherOperationCount;
33: ULONGLONG ReadTransferCount;
34: ULONGLONG WriteTransferCount;
35: ULONGLONG OtherTransferCount;
36: } IO_COUNTERS_;
37: typedef IO_COUNTERS_ *PIO_COUNTERS_;
38:
39: typedef unsigned __int64 ui64;
40: // kernel32.dll (NT/2K/XP)
41: typedef BOOL (WINAPI *PGETPROCESSTIMES)(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
42: //typedef BOOL (WINAPI *PGETPROCESSHEAPS)(DWORD,PHANDLE);
43: typedef BOOL (WINAPI *GETPROCESSIOCOUNTERS)(HANDLE,PIO_COUNTERS_);
44: // psapi.dll (2K/XP)
45: typedef BOOL (WINAPI *PGETPROCESSMEMORYINFO)(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD);
46:
47: // from CRT time.c
48: /*
49: * Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
50: */
51: #define EPOCH_BIAS 116444736000000000i64
52:
53: /*
54: * Union to facilitate converting from FILETIME to unsigned __int64
55: */
56: typedef union {
57: unsigned __int64 ft_scalar;
58: FILETIME ft_struct;
59: } FT;
60:
61: #endif
62:
1.17 paf 63: Value& rusage_element() {
64: VHash& rusage=*new VHash;
65: HashStringValue& hash=rusage.hash();
1.16 paf 66:
67: #ifdef WIN32
1.17 paf 68: double d1;
69: HANDLE hProc = GetCurrentProcess();
1.16 paf 70:
1.17 paf 71: HMODULE hMod = LoadLibrary("kernel32.dll");
72: if(hMod){
73: // NT/2K/XP
74: PGETPROCESSTIMES pGetProcessTimes = (PGETPROCESSTIMES)GetProcAddress(hMod, "GetProcessTimes");
75: if(pGetProcessTimes){
76: FILETIME CreationTime, ExitTime;
77: FT KernelTime, UserTime;
78: if(pGetProcessTimes(hProc, &CreationTime, &ExitTime, &KernelTime.ft_struct, &UserTime.ft_struct)){
79: // dwHighDateTime & dwLowDateTime - 1/10 000 000 seconds in 64 bit
80: /* the amount of time that the process has executed in user mode */
81: d1 = double((LONGLONG)UserTime.ft_scalar)/10000000.0;
1.21 paf 82: hash.put(String::Body("utime"), new VDouble(d1));
83: // hash.put(String::Body("UserTime"), new VDouble(d1));
1.17 paf 84:
85: /* the amount of time that the process has executed in kernel mode */
86: d1 = double((LONGLONG)KernelTime.ft_scalar)/10000000.0;
1.21 paf 87: hash.put(String::Body("stime"), new VDouble(d1));
88: // hash.put(String::Body("KernelTime"), new VDouble( d1));
1.16 paf 89: }
1.17 paf 90: }
1.16 paf 91:
1.17 paf 92: // NT/2K/XP
93: GETPROCESSIOCOUNTERS pGetProcessIoCounters = (GETPROCESSIOCOUNTERS)GetProcAddress(hMod, "GetProcessIoCounters");
94: if(pGetProcessIoCounters){
95: IO_COUNTERS_ ioc;
96: if(pGetProcessIoCounters(hProc, &ioc)){
97: /* Specifies the number of I/O operations performed, other than read and write operations */
1.18 paf 98: hash.put(String::Body( "OtherOperationCount"),
1.17 paf 99: new VDouble(double((LONGLONG)ioc.OtherOperationCount)));
100: /* Specifies the number of bytes transferred during operations other than read and write operations */
1.18 paf 101: hash.put(String::Body( "OtherTransferCount"),
1.17 paf 102: new VDouble(double((LONGLONG)ioc.OtherTransferCount)/1024.0));
103: /* Specifies the number of read operations performed */
1.18 paf 104: hash.put(String::Body( "ReadOperationCount"),
1.17 paf 105: new VDouble(double((LONGLONG)ioc.ReadOperationCount)));
106: /* Specifies the number of bytes read */
1.18 paf 107: hash.put(String::Body( "ReadTransferCount"),
1.17 paf 108: new VDouble(double((LONGLONG)ioc.ReadTransferCount)/1024.0));
109: /* Specifies the number of write operations performed */
1.18 paf 110: hash.put(String::Body( "WriteOperationCount"),
1.17 paf 111: new VDouble(double((LONGLONG)ioc.WriteOperationCount)));
112: /* Specifies the number of bytes written */
1.18 paf 113: hash.put(String::Body( "WriteTransferCount"),
1.17 paf 114: new VDouble(double((LONGLONG)ioc.WriteTransferCount)/1024.0));
1.16 paf 115: }
116: }
1.17 paf 117: FreeLibrary(hMod);
118: /*
119: PGETPROCESSHEAPS pGetProcessHeaps = (PGETPROCESSHEAPS)GetProcAddress(hMod, "GetProcessHeaps");
120: if(pGetProcessHeaps){
121: }
122: */
123: }
1.16 paf 124:
1.17 paf 125: // 2K/XP
126: hMod = LoadLibrary("psapi.dll");
127: if(hMod){
128: PGETPROCESSMEMORYINFO pGetProcessMemoryInfo = (PGETPROCESSMEMORYINFO)GetProcAddress(hMod, "GetProcessMemoryInfo");
129: if(pGetProcessMemoryInfo){
130: PROCESS_MEMORY_COUNTERS pmc;
131: pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
132: if(pGetProcessMemoryInfo(hProc, &pmc, sizeof(PROCESS_MEMORY_COUNTERS))){
133: /* The peak working set size */
134: d1 = double(pmc.PeakWorkingSetSize)/1024.0;
1.21 paf 135: hash.put(String::Body("maxrss"), new VDouble(d1));
136: // hash.put(String::Body("PeakWorkingSetSize")), new VDouble( d1)));
1.17 paf 137: /* The peak nonpaged pool usage */
138: d1 = double(pmc.QuotaPeakNonPagedPoolUsage)/1024.0;
1.21 paf 139: // hash.put(String::Body("ixrss"), new VDouble(d1));
140: hash.put(String::Body("QuotaPeakNonPagedPoolUsage"), new VDouble( d1));
1.17 paf 141: /* The peak paged pool usage */
142: d1 = double(pmc.QuotaPeakPagedPoolUsage)/1024.0;
1.21 paf 143: // hash.put(String::Body("idrss"), new VDouble( d1));
144: hash.put(String::Body("QuotaPeakPagedPoolUsage"), new VDouble( d1));
1.17 paf 145: /* The peak pagefile usage */
146: d1 = double(pmc.PeakPagefileUsage)/1024.0;
1.21 paf 147: // hash.put(String::Body("isrss"), new VDouble( d1));
148: hash.put(String::Body("PeakPagefileUsage"), new VDouble( d1));
1.16 paf 149: }
150: }
1.17 paf 151: FreeLibrary(hMod);
152: }
1.16 paf 153:
1.17 paf 154: // all windows.
155: FT ft;
156: GetSystemTimeAsFileTime( &(ft.ft_struct) );
157: ft.ft_scalar -= EPOCH_BIAS;
158: ui64 tv_sec = ft.ft_scalar/10000000i64;
159: ui64 tv_usec = (ft.ft_scalar-tv_sec*10000000i64)/10i64;
1.21 paf 160: hash.put(String::Body("tv_sec"), new VDouble(double((LONGLONG)tv_sec)));
161: hash.put(String::Body("tv_usec"), new VDouble(double((LONGLONG)tv_usec)));
1.16 paf 162:
163: #else
164:
165: #ifdef HAVE_GETRUSAGE
1.17 paf 166: struct rusage u;
167: if(getrusage(RUSAGE_SELF,&u)<0)
168: throw Exception(0,
169: 0,
170: "getrusage failed (#%d)", errno);
171:
1.21 paf 172: hash.put(String::Body("utime"), new VDouble(
1.17 paf 173: u.ru_utime.tv_sec+u.ru_utime.tv_usec/1000000.0));
1.21 paf 174: hash.put(String::Body("stime"), new VDouble(
1.17 paf 175: u.ru_stime.tv_sec+u.ru_stime.tv_usec/1000000.0));
1.21 paf 176: hash.put(String::Body("maxrss"), new VDouble(u.ru_maxrss));
177: hash.put(String::Body("ixrss"), new VDouble(u.ru_ixrss));
178: hash.put(String::Body("idrss"), new VDouble(u.ru_idrss));
179: hash.put(String::Body("isrss"), new VDouble(u.ru_isrss));
1.16 paf 180: #endif
1.13 paf 181:
182: #ifdef HAVE_GETTIMEOFDAY
1.17 paf 183: struct timeval tp;
184: if(gettimeofday(&tp, NULL)<0)
185: throw Exception(0,
186: 0,
187: "gettimeofday failed (#%d)", errno);
188:
1.21 paf 189: hash.put(String::Body("tv_sec"), new VDouble(tp.tv_sec));
190: hash.put(String::Body("tv_usec"), new VDouble(tp.tv_usec));
1.17 paf 191: #endif
1.16 paf 192:
1.13 paf 193: #endif
1.1 paf 194:
1.17 paf 195: return rusage;
196: }
197:
198: #ifndef PA_DEBUG_DISABLE_GC
199: Value& memory_element() {
200: VHash& memory=*new VHash;
201: HashStringValue& hash=memory.hash();
202: size_t heap_size=GC_get_heap_size();
203: size_t free_bytes=GC_get_free_bytes();
204: size_t bytes_since_gc=GC_get_bytes_since_gc();
205: size_t total_bytes=GC_get_total_bytes();
206:
1.21 paf 207: hash.put(String::Body("used"), new VDouble((heap_size-free_bytes)/1024.0));
208: hash.put(String::Body("free"), new VDouble(free_bytes/1024.0));
209: hash.put(String::Body("ever_allocated_since_compact"), new VDouble(bytes_since_gc/1024.0));
210: hash.put(String::Body("ever_allocated_since_start"), new VDouble(total_bytes/1024.0));
1.17 paf 211:
212: return memory;
213: }
1.16 paf 214: #endif
215:
1.27 misha 216: Value* VStatus::get_element(const String& aname) {
1.17 paf 217: // getstatus
1.22 paf 218: if(Cache_manager* manager=cache_managers->get(aname))
1.17 paf 219: return manager->get_status();
220:
1.23 paf 221: // $pid
222: if(aname=="pid")
223: return new VInt(getpid());
224:
225: // $tid
226: if(aname=="tid")
227: return new VInt(pa_get_thread_id());
228:
229: // $rusage
1.17 paf 230: if(aname=="rusage")
231: return &rusage_element();
232:
233: #ifndef PA_DEBUG_DISABLE_GC
1.23 paf 234: // $memory
1.17 paf 235: if(aname=="memory")
236: return &memory_element();
237: #endif
1.1 paf 238:
239: return 0;
240: }
E-mail: