Annotation of parser3/src/types/pa_vstatus.C, revision 1.26

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.26    ! paf        10: static const char * const IDENT_VSTATUS_C="$Date: 2006/04/09 12:25:05 $";
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
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.17      paf       216: Value* VStatus::get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/) {
                    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: