-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathload_avg.c
More file actions
129 lines (108 loc) · 3.76 KB
/
load_avg.c
File metadata and controls
129 lines (108 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*------------------------------------------------------------------------
* load_avg.c
* System load average information
*
* Copyright (c) 2020, EnterpriseDB Corporation. All Rights Reserved.
*
*------------------------------------------------------------------------
*/
#include "postgres.h"
#include "system_stats.h"
#include <windows.h>
#include <pdh.h>
#pragma comment(lib, "Pdh.lib")
/* logic will be same as linux */
#define SAMPLING_INTERVAL 5
/* This has been calculated as 1/exp(5/60) , As 5 is sampling interval 5 second and 60 is for load avg of 1 minute ( 60 Seconds ) */
#define LOAD_AVG_1F 0.920044
/* This has been calculated as 1/exp(5/300) , As 5 is sampling interval 5 second and for load avg of 5 minutes ( 300 Seconds ) */
#define LOAD_AVG_5F 0.983471
/* This has been calculated as 1/exp(5/900) , As 5 is sampling interval 5 second and for load avg of 15 minutes ( 900 Seconds ) */
#define LOAD_AVG_15F 0.994459
bool load_avg_initialized = false;
double load_avg_1m = 0;
double load_avg_5m = 0;
double load_avg_10m = 0;
double load_avg_15m = 0;
VOID CALLBACK LoadAvgCallback(PVOID hCounter)
{
PDH_FMT_COUNTERVALUE displayValue;
double currentLoad;
PDH_STATUS err;
err = PdhGetFormattedCounterValue(
(PDH_HCOUNTER)hCounter, PDH_FMT_DOUBLE, 0, &displayValue);
// Skip updating the load if we can't get the value successfully
if (err != ERROR_SUCCESS) {
return;
}
currentLoad = displayValue.doubleValue;
load_avg_1m = load_avg_1m * LOAD_AVG_1F + currentLoad * (1.0 - LOAD_AVG_1F);
load_avg_5m = load_avg_5m * LOAD_AVG_5F + currentLoad * (1.0 - LOAD_AVG_5F);
load_avg_15m = load_avg_15m * LOAD_AVG_15F + currentLoad * (1.0 - LOAD_AVG_15F);
}
void initialize_load_avg_info()
{
WCHAR *szCounterPath = L"\\System\\Processor Queue Length";
PDH_STATUS s;
BOOL ret;
HQUERY hQuery;
HCOUNTER hCounter;
HANDLE event;
HANDLE waitHandle;
if ((PdhOpenQueryW(NULL, 0, &hQuery)) != ERROR_SUCCESS)
{
ereport(DEBUG1, (errmsg("[initialize_load_avg_info]: PdhOpenQueryW is failed")));
return;
}
s = PdhAddEnglishCounterW(hQuery, szCounterPath, 0, &hCounter);
if (s != ERROR_SUCCESS)
{
ereport(DEBUG1, (errmsg("[initialize_load_avg_info]: PdhAddEnglishCounterW is failed")));
return;
}
event = CreateEventW(NULL, FALSE, FALSE, L"LoadUpdateEvent");
if (event == NULL)
{
ereport(DEBUG1, (errmsg("[initialize_load_avg_info]: CreateEventW is failed")));
return;
}
s = PdhCollectQueryDataEx(hQuery, SAMPLING_INTERVAL, event);
if (s != ERROR_SUCCESS)
{
ereport(DEBUG1, (errmsg("[initialize_load_avg_info]: PdhCollectQueryDataEx is failed")));
return;
}
ret = RegisterWaitForSingleObject(
&waitHandle,
event,
(WAITORTIMERCALLBACK)LoadAvgCallback,
(PVOID)
hCounter,
INFINITE,
WT_EXECUTEDEFAULT);
if (ret == 0)
{
ereport(DEBUG1, (errmsg("[initialize_load_avg_info]: RegisterWaitForSingleObject is failed")));
return;
}
}
void ReadLoadAvgInformations(Tuplestorestate *tupstore, TupleDesc tupdesc)
{
Datum values[Natts_load_avg_info];
bool nulls[Natts_load_avg_info];
memset(nulls, 0, sizeof(nulls));
/* InitialiZe the count to get the samples */
if (!load_avg_initialized)
{
ereport(DEBUG1, (errmsg("[ReadLoadAvgInformations]: Initializing counter for load average")));
initialize_load_avg_info();
load_avg_initialized = true;
}
else
ereport(DEBUG1, (errmsg("[ReadLoadAvgInformations]: Counter already initializing for load average")));
values[Anum_load_avg_one_minute] = Float4GetDatum((float4)load_avg_1m);
values[Anum_load_avg_five_minutes] = Float4GetDatum((float4)load_avg_5m);
values[Anum_load_avg_ten_minutes] = Float4GetDatum((float4)load_avg_10m);
values[Anum_load_avg_fifteen_minutes] = Float4GetDatum((float4)load_avg_15m);
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
}