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

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

E-mail: