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