sigar 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +4 -4
- data/bindings/SigarWrapper.pm +47 -0
- data/include/sigar.h +41 -0
- data/include/sigar_private.h +7 -2
- data/include/sigar_util.h +6 -0
- data/src/os/aix/aix_sigar.c +17 -0
- data/src/os/darwin/darwin_sigar.c +20 -13
- data/src/os/hpux/hpux_sigar.c +19 -0
- data/src/os/linux/linux_sigar.c +28 -0
- data/src/os/solaris/solaris_sigar.c +16 -1
- data/src/os/win32/sigar_os.h +2 -0
- data/src/os/win32/win32_sigar.c +50 -6
- data/src/sigar.c +131 -115
- data/src/sigar_cache.c +81 -7
- data/src/sigar_ptql.c +9 -0
- metadata +3 -23
- data/bindings/ruby/examples/arp.rb +0 -24
- data/bindings/ruby/examples/cpu_info.rb +0 -35
- data/bindings/ruby/examples/df.rb +0 -49
- data/bindings/ruby/examples/free.rb +0 -36
- data/bindings/ruby/examples/ifconfig.rb +0 -101
- data/bindings/ruby/examples/logging.rb +0 -58
- data/bindings/ruby/examples/net_info.rb +0 -31
- data/bindings/ruby/examples/netstat.rb +0 -71
- data/bindings/ruby/examples/pargs.rb +0 -35
- data/bindings/ruby/examples/penv.rb +0 -31
- data/bindings/ruby/examples/route.rb +0 -48
- data/bindings/ruby/examples/version.rb +0 -40
- data/bindings/ruby/examples/who.rb +0 -30
- data/bindings/ruby/test/cpu_test.rb +0 -40
- data/bindings/ruby/test/file_system_test.rb +0 -43
- data/bindings/ruby/test/helper.rb +0 -57
- data/bindings/ruby/test/loadavg_test.rb +0 -30
- data/bindings/ruby/test/mem_test.rb +0 -45
- data/bindings/ruby/test/swap_test.rb +0 -36
- data/bindings/ruby/test/uptime_test.rb +0 -26
data/src/sigar.c
CHANGED
@@ -30,6 +30,11 @@
|
|
30
30
|
#ifndef WIN32
|
31
31
|
#include <arpa/inet.h>
|
32
32
|
#endif
|
33
|
+
#if defined(HAVE_UTMPX_H)
|
34
|
+
# include <utmpx.h>
|
35
|
+
#elif defined(HAVE_UTMP_H)
|
36
|
+
# include <utmp.h>
|
37
|
+
#endif
|
33
38
|
|
34
39
|
#include "sigar.h"
|
35
40
|
#include "sigar_private.h"
|
@@ -59,6 +64,7 @@ SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
|
|
59
64
|
(*sigar)->net_listen = NULL;
|
60
65
|
(*sigar)->net_services_tcp = NULL;
|
61
66
|
(*sigar)->net_services_udp = NULL;
|
67
|
+
(*sigar)->proc_io = NULL;
|
62
68
|
}
|
63
69
|
|
64
70
|
return status;
|
@@ -91,6 +97,11 @@ SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
|
|
91
97
|
if (sigar->net_services_udp) {
|
92
98
|
sigar_cache_destroy(sigar->net_services_udp);
|
93
99
|
}
|
100
|
+
if (sigar->proc_io) {
|
101
|
+
sigar_cache_destroy(sigar->proc_io);
|
102
|
+
}
|
103
|
+
|
104
|
+
|
94
105
|
|
95
106
|
return sigar_os_close(sigar);
|
96
107
|
}
|
@@ -118,7 +129,7 @@ SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
|
|
118
129
|
int status;
|
119
130
|
|
120
131
|
if (!sigar->proc_cpu) {
|
121
|
-
sigar->proc_cpu =
|
132
|
+
sigar->proc_cpu = sigar_expired_cache_new(128, PID_CACHE_CLEANUP_PERIOD, PID_CACHE_ENTRY_EXPIRE_PERIOD);
|
122
133
|
}
|
123
134
|
|
124
135
|
entry = sigar_cache_get(sigar->proc_cpu, pid);
|
@@ -167,6 +178,106 @@ SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
|
|
167
178
|
|
168
179
|
return SIGAR_OK;
|
169
180
|
}
|
181
|
+
void copy_cached_disk_io_into_disk_io( sigar_cached_proc_disk_io_t *cached, sigar_proc_disk_io_t *proc_disk_io) {
|
182
|
+
proc_disk_io->bytes_read = cached->bytes_read_diff;
|
183
|
+
proc_disk_io->bytes_written = cached->bytes_written_diff;
|
184
|
+
proc_disk_io->bytes_total = cached->bytes_total_diff;
|
185
|
+
}
|
186
|
+
|
187
|
+
sigar_uint64_t get_io_diff(sigar_uint64_t current_value, sigar_uint64_t prev_value, sigar_uint64_t time_diff) {
|
188
|
+
double io_diff;
|
189
|
+
sigar_uint64_t int_io_diff;
|
190
|
+
if ( current_value == SIGAR_FIELD_NOTIMPL ) {
|
191
|
+
return SIGAR_FIELD_NOTIMPL;
|
192
|
+
}
|
193
|
+
io_diff = (( current_value - prev_value)/(double)time_diff)*SIGAR_MSEC;
|
194
|
+
int_io_diff = (sigar_uint64_t)io_diff;
|
195
|
+
if (int_io_diff >=0) {
|
196
|
+
return int_io_diff;
|
197
|
+
}
|
198
|
+
return 0;
|
199
|
+
}
|
200
|
+
|
201
|
+
void calculate_io_diff(sigar_proc_cumulative_disk_io_t * proc_disk_io, sigar_cached_proc_disk_io_t *cached, sigar_uint64_t time_diff, int is_first_time) {
|
202
|
+
/*calculate avg diff /read/write/total per second*/
|
203
|
+
if (!is_first_time) {
|
204
|
+
cached->bytes_written_diff = get_io_diff(proc_disk_io->bytes_written, cached->bytes_written, time_diff);
|
205
|
+
cached->bytes_read_diff = get_io_diff(proc_disk_io->bytes_read, cached->bytes_read, time_diff);
|
206
|
+
cached->bytes_total_diff = get_io_diff(proc_disk_io->bytes_total, cached->bytes_total, time_diff);
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
cached->bytes_total_diff = cached->bytes_read_diff = cached->bytes_written_diff = 0.0;
|
210
|
+
}
|
211
|
+
// now put in cache the current cumulative values
|
212
|
+
cached->bytes_written = proc_disk_io->bytes_written;
|
213
|
+
cached->bytes_read = proc_disk_io->bytes_read;
|
214
|
+
cached->bytes_total = proc_disk_io->bytes_total;
|
215
|
+
}
|
216
|
+
|
217
|
+
SIGAR_DECLARE(int) sigar_proc_disk_io_get(sigar_t *sigar, sigar_pid_t pid,
|
218
|
+
sigar_proc_disk_io_t *proc_disk_io)
|
219
|
+
{
|
220
|
+
sigar_cache_entry_t *entry;
|
221
|
+
sigar_cached_proc_disk_io_t *prev;
|
222
|
+
sigar_proc_cumulative_disk_io_t cumulative_proc_disk_io;
|
223
|
+
sigar_uint64_t time_now = sigar_time_now_millis();
|
224
|
+
sigar_uint64_t time_diff;
|
225
|
+
int status, is_first_time;
|
226
|
+
|
227
|
+
if (!sigar->proc_io) {
|
228
|
+
sigar->proc_io = sigar_expired_cache_new(128, PID_CACHE_CLEANUP_PERIOD, PID_CACHE_ENTRY_EXPIRE_PERIOD);
|
229
|
+
}
|
230
|
+
|
231
|
+
entry = sigar_cache_get(sigar->proc_io, pid);
|
232
|
+
if (entry->value) {
|
233
|
+
prev = (sigar_cached_proc_disk_io_t *)entry->value;
|
234
|
+
}
|
235
|
+
else {
|
236
|
+
prev = entry->value = malloc(sizeof(*prev));
|
237
|
+
SIGAR_ZERO(prev);
|
238
|
+
}
|
239
|
+
is_first_time = (prev->last_time == 0);
|
240
|
+
time_diff = time_now - prev->last_time;
|
241
|
+
|
242
|
+
if (time_diff < 1000) {
|
243
|
+
/* we were just called within < 1 second ago. */
|
244
|
+
copy_cached_disk_io_into_disk_io(prev, proc_disk_io);
|
245
|
+
if (time_diff < 0) {
|
246
|
+
// something is wrong at least from now on the time will be ok
|
247
|
+
prev->last_time = time_now;
|
248
|
+
}
|
249
|
+
return SIGAR_OK;
|
250
|
+
}
|
251
|
+
prev->last_time = time_now;
|
252
|
+
|
253
|
+
|
254
|
+
status =
|
255
|
+
sigar_proc_cumulative_disk_io_get(sigar, pid,
|
256
|
+
&cumulative_proc_disk_io);
|
257
|
+
|
258
|
+
if (status != SIGAR_OK) {
|
259
|
+
return status;
|
260
|
+
}
|
261
|
+
calculate_io_diff(&cumulative_proc_disk_io, prev, time_diff, is_first_time);
|
262
|
+
copy_cached_disk_io_into_disk_io(prev, proc_disk_io);
|
263
|
+
return SIGAR_OK;
|
264
|
+
}
|
265
|
+
|
266
|
+
void get_cache_info(sigar_cache_t * cache, char * name){
|
267
|
+
if (cache == NULL) {
|
268
|
+
return;
|
269
|
+
}
|
270
|
+
|
271
|
+
printf("******** %s *********\n", name);
|
272
|
+
sigar_cache_dump(cache);
|
273
|
+
}
|
274
|
+
|
275
|
+
SIGAR_DECLARE(int) sigar_dump_pid_cache_get(sigar_t *sigar, sigar_dump_pid_cache_t *info) {
|
276
|
+
|
277
|
+
get_cache_info(sigar->proc_cpu, "proc cpu cache");
|
278
|
+
get_cache_info(sigar->proc_io, "proc io cache");
|
279
|
+
return SIGAR_OK;
|
280
|
+
}
|
170
281
|
|
171
282
|
SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar,
|
172
283
|
sigar_proc_stat_t *procstat)
|
@@ -1024,40 +1135,7 @@ SIGAR_DECLARE(int) sigar_who_list_destroy(sigar_t *sigar,
|
|
1024
1135
|
return SIGAR_OK;
|
1025
1136
|
}
|
1026
1137
|
|
1027
|
-
#
|
1028
|
-
#include <AvailabilityMacros.h>
|
1029
|
-
#endif
|
1030
|
-
#ifdef MAC_OS_X_VERSION_10_5
|
1031
|
-
# if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
|
1032
|
-
# define SIGAR_NO_UTMP
|
1033
|
-
# endif
|
1034
|
-
/* else 10.4 and earlier or compiled with -mmacosx-version-min=10.3 */
|
1035
|
-
#endif
|
1036
|
-
|
1037
|
-
#if defined(__sun)
|
1038
|
-
# include <utmpx.h>
|
1039
|
-
# define SIGAR_UTMP_FILE _UTMPX_FILE
|
1040
|
-
# define ut_time ut_tv.tv_sec
|
1041
|
-
#elif defined(WIN32)
|
1042
|
-
/* XXX may not be the default */
|
1043
|
-
#define SIGAR_UTMP_FILE "C:\\cygwin\\var\\run\\utmp"
|
1044
|
-
#define UT_LINESIZE 16
|
1045
|
-
#define UT_NAMESIZE 16
|
1046
|
-
#define UT_HOSTSIZE 256
|
1047
|
-
#define UT_IDLEN 2
|
1048
|
-
#define ut_name ut_user
|
1049
|
-
|
1050
|
-
struct utmp {
|
1051
|
-
short ut_type;
|
1052
|
-
int ut_pid;
|
1053
|
-
char ut_line[UT_LINESIZE];
|
1054
|
-
char ut_id[UT_IDLEN];
|
1055
|
-
time_t ut_time;
|
1056
|
-
char ut_user[UT_NAMESIZE];
|
1057
|
-
char ut_host[UT_HOSTSIZE];
|
1058
|
-
long ut_addr;
|
1059
|
-
};
|
1060
|
-
#elif defined(NETWARE)
|
1138
|
+
#if defined(NETWARE)
|
1061
1139
|
static char *getpass(const char *prompt)
|
1062
1140
|
{
|
1063
1141
|
static char password[BUFSIZ];
|
@@ -1067,109 +1145,48 @@ static char *getpass(const char *prompt)
|
|
1067
1145
|
|
1068
1146
|
return (char *)&password;
|
1069
1147
|
}
|
1070
|
-
#elif !defined(SIGAR_NO_UTMP)
|
1071
|
-
# include <utmp.h>
|
1072
|
-
# ifdef UTMP_FILE
|
1073
|
-
# define SIGAR_UTMP_FILE UTMP_FILE
|
1074
|
-
# else
|
1075
|
-
# define SIGAR_UTMP_FILE _PATH_UTMP
|
1076
|
-
# endif
|
1077
|
-
#endif
|
1078
|
-
|
1079
|
-
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(DARWIN)
|
1080
|
-
# define ut_user ut_name
|
1081
|
-
#endif
|
1082
|
-
|
1083
|
-
#ifdef DARWIN
|
1084
|
-
/* XXX from utmpx.h; sizeof changed in 10.5 */
|
1085
|
-
/* additionally, utmpx does not work on 10.4 */
|
1086
|
-
#define SIGAR_HAS_UTMPX
|
1087
|
-
#define _PATH_UTMPX "/var/run/utmpx"
|
1088
|
-
#define _UTX_USERSIZE 256 /* matches MAXLOGNAME */
|
1089
|
-
#define _UTX_LINESIZE 32
|
1090
|
-
#define _UTX_IDSIZE 4
|
1091
|
-
#define _UTX_HOSTSIZE 256
|
1092
|
-
struct utmpx {
|
1093
|
-
char ut_user[_UTX_USERSIZE]; /* login name */
|
1094
|
-
char ut_id[_UTX_IDSIZE]; /* id */
|
1095
|
-
char ut_line[_UTX_LINESIZE]; /* tty name */
|
1096
|
-
pid_t ut_pid; /* process id creating the entry */
|
1097
|
-
short ut_type; /* type of this entry */
|
1098
|
-
struct timeval ut_tv; /* time entry was created */
|
1099
|
-
char ut_host[_UTX_HOSTSIZE]; /* host name */
|
1100
|
-
__uint32_t ut_pad[16]; /* reserved for future use */
|
1101
|
-
};
|
1102
|
-
#define ut_xtime ut_tv.tv_sec
|
1103
|
-
#define UTMPX_USER_PROCESS 7
|
1104
|
-
/* end utmpx.h */
|
1105
|
-
#define SIGAR_UTMPX_FILE _PATH_UTMPX
|
1106
1148
|
#endif
|
1107
1149
|
|
1108
|
-
#if !defined(NETWARE) && !defined(_AIX)
|
1109
|
-
|
1110
1150
|
#define WHOCPY(dest, src) \
|
1111
1151
|
SIGAR_SSTRCPY(dest, src); \
|
1112
1152
|
if (sizeof(src) < sizeof(dest)) \
|
1113
1153
|
dest[sizeof(src)] = '\0'
|
1114
1154
|
|
1115
|
-
|
1116
|
-
|
1117
|
-
sigar_who_list_t *wholist)
|
1155
|
+
static int sigar_who_utmp(sigar_t *sigar,
|
1156
|
+
sigar_who_list_t *wholist)
|
1118
1157
|
{
|
1119
|
-
|
1120
|
-
struct utmpx ut;
|
1158
|
+
#if defined(HAVE_UTMPX_H)
|
1159
|
+
struct utmpx *ut;
|
1121
1160
|
|
1122
|
-
|
1123
|
-
return errno;
|
1124
|
-
}
|
1161
|
+
setutxent();
|
1125
1162
|
|
1126
|
-
while (
|
1163
|
+
while ((ut = getutxent()) != NULL) {
|
1127
1164
|
sigar_who_t *who;
|
1128
1165
|
|
1129
|
-
if (*ut
|
1166
|
+
if (*ut->ut_user == '\0') {
|
1130
1167
|
continue;
|
1131
1168
|
}
|
1132
1169
|
|
1133
|
-
|
1134
|
-
if (ut.ut_type != UTMPX_USER_PROCESS) {
|
1170
|
+
if (ut->ut_type != USER_PROCESS) {
|
1135
1171
|
continue;
|
1136
1172
|
}
|
1137
|
-
#endif
|
1138
1173
|
|
1139
1174
|
SIGAR_WHO_LIST_GROW(wholist);
|
1140
1175
|
who = &wholist->data[wholist->number++];
|
1141
1176
|
|
1142
|
-
WHOCPY(who->user, ut
|
1143
|
-
WHOCPY(who->device, ut
|
1144
|
-
WHOCPY(who->host, ut
|
1177
|
+
WHOCPY(who->user, ut->ut_user);
|
1178
|
+
WHOCPY(who->device, ut->ut_line);
|
1179
|
+
WHOCPY(who->host, ut->ut_host);
|
1145
1180
|
|
1146
|
-
who->time = ut.
|
1181
|
+
who->time = ut->ut_tv.tv_sec;
|
1147
1182
|
}
|
1148
1183
|
|
1149
|
-
|
1150
|
-
|
1151
|
-
return SIGAR_OK;
|
1152
|
-
}
|
1153
|
-
#endif
|
1154
|
-
|
1155
|
-
#if defined(SIGAR_NO_UTMP) && defined(SIGAR_HAS_UTMPX)
|
1156
|
-
#define sigar_who_utmp sigar_who_utmpx
|
1157
|
-
#else
|
1158
|
-
static int sigar_who_utmp(sigar_t *sigar,
|
1159
|
-
sigar_who_list_t *wholist)
|
1160
|
-
{
|
1184
|
+
endutxent();
|
1185
|
+
#elif defined(HAVE_UTMP_H)
|
1161
1186
|
FILE *fp;
|
1162
|
-
#ifdef __sun
|
1163
|
-
/* use futmpx w/ pid32_t for sparc64 */
|
1164
|
-
struct futmpx ut;
|
1165
|
-
#else
|
1166
1187
|
struct utmp ut;
|
1167
|
-
|
1168
|
-
if (!(fp = fopen(
|
1169
|
-
#ifdef SIGAR_HAS_UTMPX
|
1170
|
-
/* Darwin 10.5 */
|
1171
|
-
return sigar_who_utmpx(sigar, wholist);
|
1172
|
-
#endif
|
1188
|
+
|
1189
|
+
if (!(fp = fopen(_PATH_UTMP, "r"))) {
|
1173
1190
|
return errno;
|
1174
1191
|
}
|
1175
1192
|
|
@@ -1189,7 +1206,7 @@ static int sigar_who_utmp(sigar_t *sigar,
|
|
1189
1206
|
SIGAR_WHO_LIST_GROW(wholist);
|
1190
1207
|
who = &wholist->data[wholist->number++];
|
1191
1208
|
|
1192
|
-
WHOCPY(who->user, ut.
|
1209
|
+
WHOCPY(who->user, ut.ut_name);
|
1193
1210
|
WHOCPY(who->device, ut.ut_line);
|
1194
1211
|
WHOCPY(who->host, ut.ut_host);
|
1195
1212
|
|
@@ -1197,11 +1214,10 @@ static int sigar_who_utmp(sigar_t *sigar,
|
|
1197
1214
|
}
|
1198
1215
|
|
1199
1216
|
fclose(fp);
|
1217
|
+
#endif
|
1200
1218
|
|
1201
1219
|
return SIGAR_OK;
|
1202
1220
|
}
|
1203
|
-
#endif /* SIGAR_NO_UTMP */
|
1204
|
-
#endif /* NETWARE */
|
1205
1221
|
|
1206
1222
|
#if defined(WIN32)
|
1207
1223
|
|
data/src/sigar_cache.c
CHANGED
@@ -35,7 +35,7 @@ static void free_value(void *ptr)
|
|
35
35
|
free(ptr);
|
36
36
|
}
|
37
37
|
|
38
|
-
sigar_cache_t *
|
38
|
+
sigar_cache_t *sigar_expired_cache_new(int size, sigar_uint64_t cleanup_period_millis, sigar_uint64_t entry_expire_period)
|
39
39
|
{
|
40
40
|
sigar_cache_t *table = malloc(sizeof(*table));
|
41
41
|
table->count = 0;
|
@@ -43,16 +43,27 @@ sigar_cache_t *sigar_cache_new(int size)
|
|
43
43
|
table->entries = malloc(ENTRIES_SIZE(size));
|
44
44
|
memset(table->entries, '\0', ENTRIES_SIZE(size));
|
45
45
|
table->free_value = free_value;
|
46
|
+
table->cleanup_period_millis = cleanup_period_millis;
|
47
|
+
table->last_cleanup_time = sigar_time_now_millis();
|
48
|
+
table->entry_expire_period = entry_expire_period;
|
46
49
|
return table;
|
47
50
|
}
|
48
51
|
|
49
|
-
|
52
|
+
sigar_cache_t *sigar_cache_new(int size)
|
53
|
+
{
|
54
|
+
return sigar_expired_cache_new(size, SIGAR_FIELD_NOTIMPL, SIGAR_FIELD_NOTIMPL);
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
/*#ifdef DEBUG_CACHE*/
|
50
59
|
/* see how well entries are distributed */
|
51
|
-
|
60
|
+
void sigar_cache_dump(sigar_cache_t *table)
|
52
61
|
{
|
53
62
|
int i;
|
54
63
|
sigar_cache_entry_t **entries = table->entries;
|
55
|
-
|
64
|
+
printf("table size %lu\n", (long)table->size);
|
65
|
+
printf("table count %lu\n", (long)table->count);
|
66
|
+
|
56
67
|
for (i=0; i<table->size; i++) {
|
57
68
|
sigar_cache_entry_t *entry = *entries++;
|
58
69
|
|
@@ -68,12 +79,12 @@ static void sigar_cache_dump(sigar_cache_t *table)
|
|
68
79
|
printf("\n");
|
69
80
|
fflush(stdout);
|
70
81
|
}
|
71
|
-
|
82
|
+
/*#endif*/
|
72
83
|
|
73
84
|
static void sigar_cache_rehash(sigar_cache_t *table)
|
74
85
|
{
|
75
86
|
int i;
|
76
|
-
unsigned int new_size = table->
|
87
|
+
unsigned int new_size = table->count * 2 + 1;
|
77
88
|
sigar_cache_entry_t **entries = table->entries;
|
78
89
|
sigar_cache_entry_t **new_entries =
|
79
90
|
malloc(ENTRIES_SIZE(new_size));
|
@@ -101,16 +112,76 @@ static void sigar_cache_rehash(sigar_cache_t *table)
|
|
101
112
|
#define SIGAR_CACHE_IX(t, k) \
|
102
113
|
t->entries + (k % t->size)
|
103
114
|
|
115
|
+
void sigar_perform_cleanup_if_necessary(sigar_cache_t *table) {
|
116
|
+
sigar_uint64_t current_time;
|
117
|
+
int i;
|
118
|
+
sigar_cache_entry_t **entries;
|
119
|
+
if (table->cleanup_period_millis == SIGAR_FIELD_NOTIMPL) {
|
120
|
+
/* no cleanup for this cache) */
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
current_time = sigar_time_now_millis();
|
124
|
+
if ((current_time - table->last_cleanup_time) < table->cleanup_period_millis) {
|
125
|
+
/* not enough time has passed since last cleanup */
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
/* performing cleanup */
|
130
|
+
entries = table->entries;
|
131
|
+
|
132
|
+
table->last_cleanup_time = current_time;
|
133
|
+
|
134
|
+
for (i=0; i<table->size; i++) {
|
135
|
+
sigar_cache_entry_t *entry, *ptr, *entry_prev=NULL, **entry_in_table;
|
136
|
+
entry_in_table = entries;
|
137
|
+
entry = *entries++;
|
138
|
+
|
139
|
+
while (entry) {
|
140
|
+
sigar_uint64_t period_with_no_access = current_time - entry->last_access_time;
|
141
|
+
ptr = entry->next;
|
142
|
+
if (table->entry_expire_period < period_with_no_access) {
|
143
|
+
/* no one acess this entry for too long - we can delete it */
|
144
|
+
if (entry->value) {
|
145
|
+
table->free_value(entry->value);
|
146
|
+
}
|
147
|
+
free(entry);
|
148
|
+
table->count--;
|
149
|
+
if (entry_prev != NULL) {
|
150
|
+
entry_prev->next = ptr;
|
151
|
+
}
|
152
|
+
else {
|
153
|
+
/* removing first entry - head of list should point to next entry */
|
154
|
+
*entry_in_table = ptr;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
/* entry not expired - advance entry_prev to current entry*/
|
159
|
+
entry_prev = entry;
|
160
|
+
}
|
161
|
+
entry = ptr;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
if (table->count < (table->size/4)) {
|
165
|
+
/* hash table (the array size) too big for the amount of values it contains perform rehash */
|
166
|
+
sigar_cache_rehash(table);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
104
173
|
sigar_cache_entry_t *sigar_cache_find(sigar_cache_t *table,
|
105
174
|
sigar_uint64_t key)
|
106
175
|
{
|
107
176
|
sigar_cache_entry_t *entry, **ptr;
|
177
|
+
sigar_perform_cleanup_if_necessary(table);
|
108
178
|
|
109
179
|
for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
|
110
180
|
entry;
|
111
181
|
ptr = &entry->next, entry = *ptr)
|
112
182
|
{
|
113
183
|
if (entry->id == key) {
|
184
|
+
entry->last_access_time = sigar_time_now_millis();
|
114
185
|
return entry;
|
115
186
|
}
|
116
187
|
}
|
@@ -123,17 +194,19 @@ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
|
|
123
194
|
sigar_uint64_t key)
|
124
195
|
{
|
125
196
|
sigar_cache_entry_t *entry, **ptr;
|
197
|
+
sigar_perform_cleanup_if_necessary(table);
|
126
198
|
|
127
199
|
for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
|
128
200
|
entry;
|
129
201
|
ptr = &entry->next, entry = *ptr)
|
130
202
|
{
|
131
203
|
if (entry->id == key) {
|
204
|
+
entry->last_access_time = sigar_time_now_millis();
|
132
205
|
return entry;
|
133
206
|
}
|
134
207
|
}
|
135
208
|
|
136
|
-
if (table->count
|
209
|
+
if (++table->count > table->size) {
|
137
210
|
sigar_cache_rehash(table);
|
138
211
|
|
139
212
|
for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
|
@@ -147,6 +220,7 @@ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
|
|
147
220
|
entry->id = key;
|
148
221
|
entry->value = NULL;
|
149
222
|
entry->next = NULL;
|
223
|
+
entry->last_access_time = sigar_time_now_millis();
|
150
224
|
|
151
225
|
return entry;
|
152
226
|
}
|