~ubuntu-branches/ubuntu/karmic/wmcpuload/karmic

« back to all changes in this revision

Viewing changes to src/cpu_cygwin.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Aichinger
  • Date: 2005-02-13 18:42:41 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050213184241-yk2o743d8rkp23t9
Tags: 1.0.1-2
* New Maintainer
* Added proper Linux 2.6 support, thanks to Peter Colberg for the patch.
  (Closes: #238684)
* debian/control: Standards-Version to 3.6.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: cpu_cygwin.c,v 1.1.1.1 2002/10/14 09:31:17 sch Exp $ */
 
2
 
1
3
/*
2
4
 * cpu_cygwin.c - module to get cpu usage, for Cygwin
3
5
 *
19
21
#include <w32api/windows.h>
20
22
#include <w32api/windef.h>
21
23
#include <w32api/winreg.h>
22
 
 
23
 
HKEY hkey;
24
 
DWORD dwType = REG_DWORD;
25
 
DWORD dwDust;
26
 
DWORD dw = 4;
27
 
 
28
 
void cpu_init(void)
29
 
{
30
 
    LONG ret;
31
 
 
32
 
    ret = RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StartStat", 0, KEY_READ, &hkey);
33
 
    if (!ret) {
34
 
        ret = RegQueryValueEx(hkey, "KERNEL\\CPUUsage", 0, &dwType,
35
 
                              (unsigned char *) &dwDust, &dw);
36
 
        ret = RegCloseKey(hkey);
37
 
    }
38
 
 
39
 
    if (ret)
40
 
        exit(1);
41
 
 
42
 
}
43
 
 
44
 
/* returns current CPU usage in percent */
45
 
int cpu_get_usage(struct cpu_options *opts)
46
 
{
47
 
    int result = 0;
48
 
 
49
 
    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StatData", 0, KEY_READ, &hkey);
50
 
    RegQueryValueEx(hkey, "KERNEL\\CPUUsage", 0, &dwType,
51
 
                    (unsigned char *) &result, &dw);
52
 
    RegCloseKey(hkey);
53
 
 
54
 
    return result;
 
24
#include <w32api/winbase.h>
 
25
 
 
26
#define WIN32_9x 1              /* 95, 98, Me   */
 
27
#define WIN32_NT 2              /* NT, 2000, XP */
 
28
 
 
29
/* NT, 2000, XP */
 
30
#define LONGINT2DOUBLE(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
 
31
/*
 
32
 * The following both data structures aren't defined anywhere in the Microsoft
 
33
 * header files. Taken from DNA's libraly licensed under GPL.
 
34
 * (http://estu.nit.ac.jp/~e982457/freesoft/freesoft.html)
 
35
 */
 
36
typedef struct _SYSTEM_BASIC_INFORMATION {              /* Info Class 0 */
 
37
    DWORD   unused1;
 
38
    ULONG   unused2[6];
 
39
    PVOID   unused3[2];
 
40
    ULONG   unused4;
 
41
    BYTE    bKeNumberProcessors;
 
42
    BYTE    unused5;
 
43
    WORD    unused6;
 
44
} SYSTEM_BASIC_INFORMATION;
 
45
 
 
46
typedef struct _SYSTEM_PERFORMANCE_INFORMATION {        /* Info Class 2 */
 
47
    LARGE_INTEGER IdleTime;
 
48
    DWORD unused[76];
 
49
} SYSTEM_PERFORMANCE_INFORMATION;
 
50
 
 
51
typedef struct _SYSTEM_TIME_INFORMATION {               /* Info Class 3 */
 
52
    LARGE_INTEGER liKeBootTime;
 
53
    LARGE_INTEGER liKeSystemTime;
 
54
    LARGE_INTEGER liExpTimeZoneBias;
 
55
    ULONG uCurrentTimeZoneId;
 
56
    DWORD dwReserved;
 
57
} SYSTEM_TIME_INFORMATION;
 
58
 
 
59
#define SystemBasicInformation          0
 
60
#define SystemPerformanceInformation    2
 
61
#define SystemTimeInformation           3
 
62
/* end of NT, 2000, XP */
 
63
 
 
64
static int platform = 0;
 
65
 
 
66
void
 
67
cpu_init(void)
 
68
{
 
69
    OSVERSIONINFO os_ver_info;
 
70
 
 
71
    /* which version? */
 
72
    os_ver_info.dwOSVersionInfoSize = sizeof(os_ver_info);
 
73
    GetVersionEx(&os_ver_info);
 
74
    platform = os_ver_info.dwPlatformId;
 
75
 
 
76
    if ((platform != WIN32_9x) && (platform != WIN32_NT)) {
 
77
        fprintf(stderr, "%s: unknown platform\n", PACKAGE);
 
78
        exit (1);
 
79
    }
 
80
}
 
81
 
 
82
/*
 
83
 * cpu_get_usage_9x(): get cpu usage in percent via registry
 
84
 *
 
85
 * How to get:
 
86
 *  1. query 'PerfStats.StartStat.KERNEL.CPUUsage' to start monitoring
 
87
 *  2. get usage from 'PerfStats.StatData.KERNEL.CPUUsage'
 
88
 *  3. query 'PerfStats.StopStat.KERNEL.CPUUsage' to stop monitoring
 
89
 *
 
90
 * If cpu usage is 100% evry time, please reboot.;(
 
91
 */
 
92
static int
 
93
cpu_get_usage_9x(cpu_options *opts)
 
94
{
 
95
    int usage = 0;
 
96
 
 
97
    HKEY hkeys; /* for monitoring (start, stop) */
 
98
    HKEY hkeyr; /* for reading usage            */
 
99
    DWORD dummy;
 
100
    DWORD dwsize = sizeof(DWORD);
 
101
 
 
102
    if (RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StatData",
 
103
                     0, KEY_READ, &hkeyr) != ERROR_SUCCESS) {
 
104
        fprintf(stderr, "%s: can't open registry 'PerfStats\\StatData'\n", PACKAGE);
 
105
        return 0;
 
106
    }
 
107
 
 
108
    /* start monitoring */
 
109
    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StartStat", 0, KEY_READ, &hkeys);
 
110
    RegQueryValueEx(hkeys, "KERNEL\\CPUUsage", 0, NULL, (LPBYTE)&dummy,
 
111
                    &dwsize);
 
112
    RegCloseKey(hkeys);
 
113
 
 
114
    /* get usage */
 
115
    RegQueryValueEx(hkeyr, "KERNEL\\CPUUsage", 0, NULL, (LPBYTE)&usage,
 
116
                    &dwsize);
 
117
    RegCloseKey(hkeyr);
 
118
 
 
119
    /* stop monitoring */
 
120
    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StopStat", 0, KEY_READ, &hkeys);
 
121
    RegQueryValueEx(hkeys, "KERNEL\\CPUUsage", 0, NULL, (LPBYTE)&dummy,
 
122
                    &dwsize);
 
123
    RegCloseKey(hkeys);
 
124
 
 
125
    return usage;
 
126
}
 
127
 
 
128
/*
 
129
 * cpu_get_usage_NT:
 
130
 *
 
131
 * How to get:
 
132
 *  1. Load NTDLL.DLL (should use dlopen?)
 
133
 *  2. Get addresses of NtQuerySystemInformation (should use dlsym?)
 
134
 *  3. Get system time and idle time
 
135
 *  4. Calculate cpu usage
 
136
 *  5. Unload NTDLL.DLL (should use dlclose?)
 
137
 *
 
138
 * I do not test this function with SMP system, since I do not have SMP system.
 
139
 */
 
140
static int
 
141
cpu_get_usage_NT(cpu_options *opts)
 
142
{
 
143
    int usage;
 
144
    double total, used;
 
145
    static double pre_total = 0, pre_used = 0;
 
146
 
 
147
    HINSTANCE h_ntdll;
 
148
    FARPROC NtQuerySystemInformation = NULL;
 
149
 
 
150
    SYSTEM_BASIC_INFORMATION       sbi;
 
151
    SYSTEM_TIME_INFORMATION        sti;
 
152
    SYSTEM_PERFORMANCE_INFORMATION spi;
 
153
 
 
154
    if ((h_ntdll = LoadLibraryEx("NTDLL.DLL", NULL, 0)) == NULL) {
 
155
        fprintf(stderr, "%s: can't load NTDLL.DLL\n", PACKAGE);
 
156
        exit (1);
 
157
    }
 
158
 
 
159
    NtQuerySystemInformation = GetProcAddress(h_ntdll,
 
160
                                              "NtQuerySystemInformation");
 
161
    if (!NtQuerySystemInformation) {
 
162
        fprintf(stderr, "%s: can't find NtQuerySystemInformation()\n", PACKAGE);
 
163
        FreeLibrary(h_ntdll);
 
164
        return 0;
 
165
    }
 
166
 
 
167
    if ((NtQuerySystemInformation(SystemBasicInformation,
 
168
                                  &sbi,
 
169
                                  sizeof(SYSTEM_BASIC_INFORMATION),
 
170
                                  NULL)) != NO_ERROR)
 
171
        return 0;
 
172
 
 
173
    if ((NtQuerySystemInformation(SystemTimeInformation,
 
174
                                  &sti,
 
175
                                  sizeof(SYSTEM_TIME_INFORMATION),
 
176
                                  0)) != NO_ERROR)
 
177
        return 0;
 
178
 
 
179
    if ((NtQuerySystemInformation(SystemPerformanceInformation,
 
180
                                  &spi,
 
181
                                  sizeof(SYSTEM_PERFORMANCE_INFORMATION),
 
182
                                  0)) != NO_ERROR)
 
183
        return 0;
 
184
 
 
185
    total = LONGINT2DOUBLE(sti.liKeSystemTime);
 
186
    used = total - LONGINT2DOUBLE(spi.IdleTime);
 
187
 
 
188
    if ((pre_total == 0) || !(total - pre_total > 0))  {
 
189
        usage = 0;
 
190
    } else {
 
191
        usage = (100 * (used - pre_used)) / (total - pre_total);
 
192
    }
 
193
 
 
194
    if (sbi.bKeNumberProcessors > 1) {
 
195
        usage = usage / sbi.bKeNumberProcessors;
 
196
    }
 
197
 
 
198
    pre_used = used;
 
199
    pre_total = total;
 
200
 
 
201
    FreeLibrary(h_ntdll);
 
202
 
 
203
    return usage;
 
204
}
 
205
 
 
206
/* return current cpu usage in percent */
 
207
int
 
208
cpu_get_usage(cpu_options *opts)
 
209
{
 
210
    switch (platform) {
 
211
        case WIN32_9x:
 
212
            return cpu_get_usage_9x(opts);
 
213
        case WIN32_NT:
 
214
            return cpu_get_usage_NT(opts);
 
215
        default: /* make gcc happy */
 
216
            break;
 
217
    }
 
218
    return 0;
55
219
}