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