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