]>
Commit | Line | Data |
---|---|---|
a6755701 CP |
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> | |
8186335d | 9 | #include <string.h> |
a6755701 | 10 | |
8186335d CP |
11 | static fsample_t version = 1; |
12 | ||
45eadff3 CP |
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) { | |
d4e7ae7a | 19 | int flags = 0; |
8186335d | 20 | int new = 0; |
a6755701 CP |
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 | ||
8186335d CP |
28 | if(!lseek(f->fd, 0, SEEK_END)) |
29 | new = 1; | |
30 | ||
a6755701 CP |
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 | ||
d4e7ae7a CP |
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); | |
8186335d CP |
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))) { | |
45eadff3 | 50 | munmap(f->header, f->len); |
a6755701 CP |
51 | close(f->fd); |
52 | free(f); | |
53 | return NULL; | |
54 | } | |
55 | ||
be606ed1 | 56 | if(chafn && chdfn) { |
45eadff3 CP |
57 | f->corehandler = chafn(fscorefree, f); |
58 | f->corehandlerdel = chdfn; | |
59 | } else { | |
60 | f->corehandler = NULL; | |
61 | f->corehandlerdel = NULL; | |
62 | } | |
63 | ||
8186335d CP |
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); | |
a6755701 CP |
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) { | |
45eadff3 | 77 | munmap(f->header, f->len); |
a6755701 | 78 | close(f->fd); |
45eadff3 CP |
79 | |
80 | if(f->corehandlerdel && f->corehandler) | |
81 | (f->corehandlerdel)(f->corehandler); | |
82 | ||
a6755701 CP |
83 | free(f); |
84 | } | |
85 | ||
a6755701 | 86 | int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag) { |
45eadff3 | 87 | fsample_m_entry *p = &f->entry[f->pos]; |
a6755701 | 88 | |
45eadff3 CP |
89 | p->f = fsopen(filename, f->samples / freq, f->chafn, f->chdfn); |
90 | if(!p->f) | |
a6755701 CP |
91 | return 0; |
92 | ||
b88719fa | 93 | p->freq = freq; |
45eadff3 CP |
94 | p->derive = derive; |
95 | p->tag = tag; | |
a6755701 CP |
96 | f->pos++; |
97 | return 1; | |
98 | } | |
99 | ||
45eadff3 | 100 | fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) { |
a6755701 CP |
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; | |
45eadff3 CP |
107 | n->chafn = chafn; |
108 | n->chdfn = chdfn; | |
a6755701 CP |
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 | ||
a6755701 CP |
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 | } |