-
Notifications
You must be signed in to change notification settings - Fork 11
/
psi-notify.h
111 lines (92 loc) · 3.16 KB
/
psi-notify.h
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
#include <stdbool.h>
#include <stdio.h>
#include <strings.h>
#include <time.h>
/* Data structures */
typedef enum ResourceType { RT_CPU, RT_MEMORY, RT_IO } ResourceType;
typedef enum AlertState {
A_INACTIVE,
A_ACTIVE,
A_STABILISING,
A_ERROR
} AlertState;
typedef struct {
double some;
double full;
} TimeResourcePressure;
typedef struct {
TimeResourcePressure avg10;
TimeResourcePressure avg60;
TimeResourcePressure avg300;
} Pressure;
typedef struct {
char *filename;
const char *human_name;
unsigned int has_full;
ResourceType type;
Pressure thresholds;
} Resource;
typedef struct {
Resource cpu;
Resource memory;
Resource io;
time_t update_interval;
bool log_pressures;
int psi_dir_fd;
int io_min_blocked_tasks;
} Config;
typedef struct {
NotifyNotification *notif;
time_t remaining_intervals;
AlertState last_state;
} Alert;
/* Utility macros and functions */
#define info(format, ...) printf("INFO: " format, __VA_ARGS__)
#define warn(format, ...) fprintf(stderr, "WARN: " format, __VA_ARGS__)
#define die(format, ...) \
do { \
fprintf(stderr, "FATAL: " format, __VA_ARGS__); \
abort(); \
} while (0)
#define unreachable() die("%s\n", "Allegedly unreachable code reached\n")
#define expect(x) \
do { \
if (!(x)) { \
die("!(%s) at %s:%s:%d\n", #x, __FILE__, __func__, __LINE__); \
} \
} while (0)
#define snprintf_check(buf, len, fmt, ...) \
do { \
int needed = snprintf(buf, len, fmt, __VA_ARGS__); \
expect(needed >= 0 && (size_t)needed < (len)); \
} while (0)
#define for_each_arr(i, items) \
for (i = 0; i < sizeof(items) / sizeof(items[0]); i++)
#define streq(a, b) (strcmp((a), (b)) == 0)
#define strceq(a, b) (strcasecmp((a), (b)) == 0)
#define strnull(s) s ? s : "[null]"
static inline int blank_line_or_comment(const char *s) {
while (isspace((unsigned char)*s)) {
++s;
}
return *s == '\0' || *s == '#';
}
static inline int parse_boolean(const char *s) {
size_t i;
const char *const truthy[] = {"1", "y", "yes", "true", "on"};
const char *const falsy[] = {"0", "n", "no", "false", "off"};
for_each_arr(i, truthy) {
if (strceq(s, truthy[i])) {
return 1;
}
}
for_each_arr(i, falsy) {
if (strceq(s, falsy[i])) {
return 0;
}
}
return -EINVAL;
}
static inline const char *active_inactive(Alert *a) {
return a->notif ? "active" : "inactive";
}