]> jfr.im git - irc/quakenet/newserv.git/blob - graphing/fsample.c
Add ping timeout diagnostic message to irc module.
[irc/quakenet/newserv.git] / graphing / fsample.c
1 #include "fsample.h"
2
3 #include <sys/types.h>
4 #include <sys/uio.h>
5 #include <unistd.h>
6 #include <sys/mman.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 static fsample_t version = 1;
12
13 static void fscorefree(void *arg) {
14 fsample *f = (fsample *)arg;
15 munmap(f->header, f->len);
16 }
17
18 fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
19 int flags = 0;
20 int new = 0;
21 fsample *f = (fsample *)malloc(sizeof(fsample));
22 if(!f)
23 return NULL;
24
25 f->len = samples * sizeof(struct fsample_p) + sizeof(struct fsample_header);
26 f->fd = open(filename, O_RDWR|O_CREAT, 0600);
27
28 if(!lseek(f->fd, 0, SEEK_END))
29 new = 1;
30
31 if((f->fd == -1) || (lseek(f->fd, f->len - 1, SEEK_SET) == -1)) {
32 free(f);
33 return NULL;
34 }
35 write(f->fd, "", 1);
36
37 flags = MAP_SHARED;
38 #ifdef MAP_NOCORE
39 flags|=MAP_NOCORE;
40 #endif
41
42 f->header = mmap(NULL, f->len, PROT_READ|PROT_WRITE, flags, f->fd, 0);
43 if(f->header == MAP_FAILED) {
44 close(f->fd);
45 free(f);
46 return NULL;
47 }
48
49 if(!new && (memcmp(f->header->magic, "FSAMP", sizeof(f->header->magic)) || (version != f->header->version))) {
50 munmap(f->header, f->len);
51 close(f->fd);
52 free(f);
53 return NULL;
54 }
55
56 if(chafn && chdfn) {
57 f->corehandler = chafn(fscorefree, f);
58 f->corehandlerdel = chdfn;
59 } else {
60 f->corehandler = NULL;
61 f->corehandlerdel = NULL;
62 }
63
64 memcpy(f->header->magic, "FSAMP", sizeof(f->header->magic));
65 f->header->version = version;
66
67 f->m = (struct fsample_p *)(f->header + 1);
68 f->samples = samples;
69
70 if(f->header->iteration == 0)
71 f->header->iteration = 1;
72
73 return f;
74 }
75
76 void fsclose(fsample *f) {
77 munmap(f->header, f->len);
78 close(f->fd);
79
80 if(f->corehandlerdel && f->corehandler)
81 (f->corehandlerdel)(f->corehandler);
82
83 free(f);
84 }
85
86 int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag) {
87 fsample_m_entry *p = &f->entry[f->pos];
88
89 p->f = fsopen(filename, f->samples / freq, f->chafn, f->chdfn);
90 if(!p->f)
91 return 0;
92
93 p->freq = freq;
94 p->derive = derive;
95 p->tag = tag;
96 f->pos++;
97 return 1;
98 }
99
100 fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
101 fsample_m *n = (fsample_m *)malloc(sizeof(fsample_m) + (count + 1) * sizeof(fsample_m_entry));
102 if(!n)
103 return NULL;
104
105 n->samples = samples;
106 n->pos = 0;
107 n->chafn = chafn;
108 n->chdfn = chdfn;
109
110 if(!fsadd_m(n, filename, 1, NULL, 0)) {
111 free(n);
112 return NULL;
113 }
114
115 return n;
116 }
117
118 void fsset_m(fsample_m *f, fsample_t pos, fsample_t value) {
119 int i;
120
121 for(i=0;i<f->pos;i++) {
122 fsample_t v;
123
124 if((pos + 1) % f->entry[i].freq != 0)
125 continue;
126
127 if(f->entry[i].derive) {
128 v = (f->entry[i].derive)(f, i, pos, f->entry[i].tag);
129 } else {
130 v = value;
131 }
132
133 fsset(f->entry[i].f, pos / f->entry[i].freq, v);
134 }
135 }
136
137 void fsclose_m(fsample_m *f) {
138 int i;
139
140 for(i=0;i<f->pos;i++)
141 fsclose(f->entry[i].f);
142 free(f);
143 }
144
145 fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag) {
146 fsample_t c = 0;
147 long samples = (long)tag;
148 int count = 0;
149 int rpos = pos / f->entry[0].freq;
150 int i;
151 fsample_t t;
152
153 for(i=0;i<samples;i++) {
154 if(__fsget_m(f, 0, rpos - i, &t)) {
155 c+=t;
156 count++;
157 } else {
158 /* printf("bad :(\n");*/
159 }
160 }
161
162 if(count == 0)
163 return 0;
164
165 return c / count;
166 }
167
168 fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag) {
169 fsample_t c = 0;
170 long samples = (long)tag;
171 int count = 0;
172 int rpos = pos / f->entry[entry - 1].freq;
173 int i;
174 fsample_t t;
175
176 for(i=0;i<=samples;i++) {
177 if(__fsget(f->entry[entry - 1].f, rpos - i, &t)) {
178 c+=t;
179 count++;
180 } else {
181 /*printf("bad :(\n");*/
182 }
183 }
184
185 if(count == 0)
186 return 0;
187
188 return c / count;
189 }