Annotation of parser3/src/types/pa_vstatus.C, revision 1.40
1.1 paf 1: /** @file
2: Parser: @b status class impl.
3:
1.36 moko 4: Copyright (c) 2001-2020 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.40 ! moko 16: volatile const char * IDENT_PA_VSTATUS_C="$Id: pa_vstatus.C,v 1.39 2023/08/08 21:52:27 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 {
1.40 ! moko 51: unsigned __int64 ft_scalar;
! 52: FILETIME ft_struct;
! 53: } FT;
! 54:
! 55: typedef struct {
! 56: long tv_sec;
! 57: long tv_usec;
! 58: } timeval;
! 59:
! 60: int gettimeofday(timeval *tv, void *) {
! 61: FT ft;
! 62: GetSystemTimeAsFileTime( &(ft.ft_struct) );
! 63: ft.ft_scalar -= EPOCH_BIAS;
! 64: tv->tv_sec = ft.ft_scalar/10000000i64;
! 65: tv->tv_usec = (ft.ft_scalar-tv_sec*10000000i64)/10i64;
! 66: return 0;
! 67: }
1.16 paf 68:
69: #endif
70:
1.17 paf 71: Value& rusage_element() {
72: VHash& rusage=*new VHash;
73: HashStringValue& hash=rusage.hash();
1.16 paf 74:
1.30 moko 75: #ifdef _MSC_VER
1.17 paf 76: double d1;
77: HANDLE hProc = GetCurrentProcess();
1.16 paf 78:
1.17 paf 79: HMODULE hMod = LoadLibrary("kernel32.dll");
80: if(hMod){
81: // NT/2K/XP
82: PGETPROCESSTIMES pGetProcessTimes = (PGETPROCESSTIMES)GetProcAddress(hMod, "GetProcessTimes");
83: if(pGetProcessTimes){
84: FILETIME CreationTime, ExitTime;
85: FT KernelTime, UserTime;
86: if(pGetProcessTimes(hProc, &CreationTime, &ExitTime, &KernelTime.ft_struct, &UserTime.ft_struct)){
87: // dwHighDateTime & dwLowDateTime - 1/10 000 000 seconds in 64 bit
88: /* the amount of time that the process has executed in user mode */
89: d1 = double((LONGLONG)UserTime.ft_scalar)/10000000.0;
1.31 moko 90: hash.put("utime", new VDouble(d1));
1.17 paf 91:
92: /* the amount of time that the process has executed in kernel mode */
93: d1 = double((LONGLONG)KernelTime.ft_scalar)/10000000.0;
1.31 moko 94: hash.put("stime", new VDouble(d1));
1.16 paf 95: }
1.17 paf 96: }
1.16 paf 97:
1.17 paf 98: // NT/2K/XP
99: GETPROCESSIOCOUNTERS pGetProcessIoCounters = (GETPROCESSIOCOUNTERS)GetProcAddress(hMod, "GetProcessIoCounters");
100: if(pGetProcessIoCounters){
101: IO_COUNTERS_ ioc;
102: if(pGetProcessIoCounters(hProc, &ioc)){
103: /* Specifies the number of I/O operations performed, other than read and write operations */
1.31 moko 104: hash.put("OtherOperationCount", new VDouble(double((LONGLONG)ioc.OtherOperationCount)));
1.17 paf 105: /* Specifies the number of bytes transferred during operations other than read and write operations */
1.31 moko 106: hash.put("OtherTransferCount", new VDouble(double((LONGLONG)ioc.OtherTransferCount)/1024.0));
1.17 paf 107: /* Specifies the number of read operations performed */
1.31 moko 108: hash.put("ReadOperationCount", new VDouble(double((LONGLONG)ioc.ReadOperationCount)));
1.17 paf 109: /* Specifies the number of bytes read */
1.31 moko 110: hash.put("ReadTransferCount", new VDouble(double((LONGLONG)ioc.ReadTransferCount)/1024.0));
1.17 paf 111: /* Specifies the number of write operations performed */
1.31 moko 112: hash.put("WriteOperationCount", new VDouble(double((LONGLONG)ioc.WriteOperationCount)));
1.17 paf 113: /* Specifies the number of bytes written */
1.31 moko 114: hash.put("WriteTransferCount", 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.31 moko 135: hash.put("maxrss", new VDouble(d1));
1.17 paf 136: /* The peak nonpaged pool usage */
137: d1 = double(pmc.QuotaPeakNonPagedPoolUsage)/1024.0;
1.31 moko 138: hash.put("QuotaPeakNonPagedPoolUsage", new VDouble(d1));
1.17 paf 139: /* The peak paged pool usage */
140: d1 = double(pmc.QuotaPeakPagedPoolUsage)/1024.0;
1.31 moko 141: hash.put("QuotaPeakPagedPoolUsage", new VDouble(d1));
1.17 paf 142: /* The peak pagefile usage */
143: d1 = double(pmc.PeakPagefileUsage)/1024.0;
1.31 moko 144: hash.put("PeakPagefileUsage", new VDouble(d1));
1.16 paf 145: }
146: }
1.17 paf 147: FreeLibrary(hMod);
148: }
1.16 paf 149:
150: #else
151:
152: #ifdef HAVE_GETRUSAGE
1.17 paf 153: struct rusage u;
154: if(getrusage(RUSAGE_SELF,&u)<0)
1.39 moko 155: throw Exception(0, 0, "getrusage failed (#%d)", errno);
1.17 paf 156:
1.31 moko 157: hash.put("utime", new VDouble(u.ru_utime.tv_sec+u.ru_utime.tv_usec/1000000.0));
158: hash.put("stime", new VDouble(u.ru_stime.tv_sec+u.ru_stime.tv_usec/1000000.0));
159: hash.put("maxrss", new VDouble(u.ru_maxrss));
160: hash.put("ixrss", new VDouble(u.ru_ixrss));
161: hash.put("idrss", new VDouble(u.ru_idrss));
162: hash.put("isrss", new VDouble(u.ru_isrss));
1.16 paf 163: #endif
1.13 paf 164:
1.40 ! moko 165: #endif
! 166:
1.17 paf 167: struct timeval tp;
168: if(gettimeofday(&tp, NULL)<0)
1.38 moko 169: throw Exception(0, 0, "gettimeofday failed (#%d)", errno);
1.17 paf 170:
1.31 moko 171: hash.put("tv_sec", new VDouble(tp.tv_sec));
172: hash.put("tv_usec", new VDouble(tp.tv_usec));
1.1 paf 173:
1.17 paf 174: return rusage;
175: }
176:
177: #ifndef PA_DEBUG_DISABLE_GC
178: Value& memory_element() {
179: VHash& memory=*new VHash;
180: HashStringValue& hash=memory.hash();
181: size_t heap_size=GC_get_heap_size();
182: size_t free_bytes=GC_get_free_bytes();
183: size_t bytes_since_gc=GC_get_bytes_since_gc();
184: size_t total_bytes=GC_get_total_bytes();
185:
1.31 moko 186: hash.put("used", new VDouble((heap_size-free_bytes)/1024.0));
187: hash.put("free", new VDouble(free_bytes/1024.0));
188: hash.put("ever_allocated_since_compact", new VDouble(bytes_since_gc/1024.0));
189: hash.put("ever_allocated_since_start", new VDouble(total_bytes/1024.0));
1.17 paf 190:
191: return memory;
192: }
1.16 paf 193: #endif
194:
1.27 misha 195: Value* VStatus::get_element(const String& aname) {
1.34 moko 196: #ifndef OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL
197: // CLASS, CLASS_NAME
1.33 moko 198: if(Value* result=VStateless_class::get_element(aname))
199: return result;
1.34 moko 200: #endif
1.33 moko 201:
1.17 paf 202: // getstatus
1.22 paf 203: if(Cache_manager* manager=cache_managers->get(aname))
1.17 paf 204: return manager->get_status();
205:
1.23 paf 206: // $pid
207: if(aname=="pid")
208: return new VInt(getpid());
209:
210: // $tid
211: if(aname=="tid")
212: return new VInt(pa_get_thread_id());
213:
214: // $rusage
1.17 paf 215: if(aname=="rusage")
216: return &rusage_element();
217:
218: #ifndef PA_DEBUG_DISABLE_GC
1.23 paf 219: // $memory
1.17 paf 220: if(aname=="memory")
221: return &memory_element();
222: #endif
1.1 paf 223:
224: return 0;
225: }
E-mail: