1 /*
2 * metriclist.c
3 *
4 * Copyright (c) 1997,2005 Silicon Graphics, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "pmapi.h"
22 #include "impl.h"
23 #include "logger.h"
24
25 extern int ilog;
26
27 /*
28 * extract the pmid in vsetp and all its instances, and put it in
29 * a pmResult of its own
30 */
31 void
32 extractpmid(pmValueSet *vsetp, struct timeval *timestamp, pmResult **resp)
33 {
34 int i;
35 int size;
36 pmResult *result;
37 pmValueBlock *vbp; /* value block pointer */
38
39
40 result = (pmResult *)malloc(sizeof(pmResult));
41 if (result == NULL) {
42 fprintf(stderr, "%s: Error: cannot malloc space in \"extractpmid\".\n",
43 pmProgname);
44 exit(1);
45 }
46
47 size = sizeof(pmValueSet) + (vsetp->numval-1) * sizeof(pmValue);
48 result->vset[0] = (pmValueSet *)malloc(size);
49 if (result->vset[0] == NULL) {
50 fprintf(stderr, "%s: Error: cannot malloc space in \"extractpmid\".\n",
51 pmProgname);
52 exit(1);
53 }
54
55
56 result->timestamp.tv_sec = timestamp->tv_sec;
57 result->timestamp.tv_usec = timestamp->tv_usec;
58 result->numpmid = 1;
59 result->vset[0]->pmid = vsetp->pmid;
60 result->vset[0]->numval = vsetp->numval;
61 result->vset[0]->valfmt = vsetp->valfmt;
62
63
64 for(i=0; i<vsetp->numval; i++) {
65 result->vset[0]->vlist[i].inst = vsetp->vlist[i].inst;
66 if (vsetp->valfmt == PM_VAL_INSITU)
67 result->vset[0]->vlist[i].value = vsetp->vlist[i].value;
68 else {
69 vbp = vsetp->vlist[i].value.pval;
70
71 size = (int)vbp->vlen;
72 result->vset[0]->vlist[i].value.pval = (pmValueBlock *)malloc(size);
73 if (result->vset[0]->vlist[i].value.pval == NULL) {
74 fprintf(stderr,
75 "%s: Error: cannot malloc space in \"extractpmid\".\n",
76 pmProgname);
77 exit(1);
78 }
79
80 result->vset[0]->vlist[i].value.pval->vtype = vbp->vtype;
81 result->vset[0]->vlist[i].value.pval->vlen = vbp->vlen;
82
83 /* in a pmValueBlock, the first byte is assigned to vtype,
84 * and the subsequent 3 bytes are assigned to vlen - that's
85 * a total of 4 bytes - the rest is used for vbuf
86 */
87 if (vbp->vlen < 4) {
88 fprintf(stderr, "%s: Warning: pmValueBlock vlen (%u) is too small\n", pmProgname, vbp->vlen);
89 }
90 memcpy(result->vset[0]->vlist[i].value.pval->vbuf,
91 vbp->vbuf, vbp->vlen-4);
92 }
93 } /*for(i)*/
94
95 *resp = result;
96 }
97
98 rlist_t *
99 mk_rlist_t(void)
100 {
101 rlist_t *rlist;
102 if ((rlist = (rlist_t *)malloc(sizeof(rlist_t))) == NULL) {
103 fprintf(stderr, "%s: Error: cannot malloc space in \"mk_rlist_t\"\n",
104 pmProgname);
105 exit(1);
106 }
107 rlist->res = NULL;
108 rlist->next = NULL;
109 return(rlist);
110 }
111
112
113 /*
114 * insert rlist element in rlist list
115 */
116 void
117 insertrlist(rlist_t **rlist, rlist_t *elm)
118 {
119 rlist_t *curr;
120 rlist_t *prev;
121
|
Event deref_ptr: |
Directly dereferencing pointer "elm". |
| Also see events: |
[check_after_deref] |
122 elm->next = NULL;
123
|
Event check_after_deref: |
Dereferencing "elm" before a null check. |
| Also see events: |
[deref_ptr] |
124 if (elm == NULL)
125 return;
126
127 if (*rlist == NULL) {
128 *rlist = elm;
129 return;
130 }
131
132 if (elm->res->timestamp.tv_sec < (*rlist)->res->timestamp.tv_sec ||
133 (elm->res->timestamp.tv_sec == (*rlist)->res->timestamp.tv_sec &&
134 elm->res->timestamp.tv_usec <= (*rlist)->res->timestamp.tv_usec)) {
135 curr = *rlist;
136 *rlist = elm;
137 (*rlist)->next = curr;
138 return;
139 }
140
141 curr = (*rlist)->next;
142 prev = *rlist;
143
144 while (curr != NULL) {
145 if (elm->res->timestamp.tv_sec < curr->res->timestamp.tv_sec ||
146 (elm->res->timestamp.tv_sec == curr->res->timestamp.tv_sec &&
147 elm->res->timestamp.tv_usec <= curr->res->timestamp.tv_usec)) {
148 break;
149 }
150 prev = curr;
151 curr = prev->next;
152 }
153
154 prev->next = elm;
155 elm->next = curr;
156 }
157
158
159 /*
160 * insert pmResult in rlist list
161 */
162 void
163 insertresult(rlist_t **rlist, pmResult *result)
164 {
165 rlist_t *elm;
166
167 elm = mk_rlist_t();
168 elm->res = result;
169 elm->next = NULL;
170
171 insertrlist (rlist, elm);
172 }
173
174 /*
175 * Find out whether the metrics in _result are in the metric list ml
176 */
177 pmResult *
178 searchmlist(pmResult *_Oresult)
179 {
180 int i;
181 int j;
182 int k;
183 int q;
184 int r;
185 int found = 0;
186 int maxinst = 0; /* max number of instances */
187 int numpmid = 0;
188 int *ilist;
189 int *jlist;
190 pmResult *_Nresult;
191 pmValue *vlistp = NULL; /* temporary list of instances */
192 pmValueSet *vsetp; /* value set pointer */
193
194 ilist = (int *) malloc(_Oresult->numpmid * sizeof(int));
195 if (ilist == NULL)
196 goto nomem;
197
198 jlist = (int *) malloc(_Oresult->numpmid * sizeof(int));
199 if (jlist == NULL)
200 goto nomem;
201
202 /* find out how many of the pmid's in _Oresult need to be written out
203 * (also, find out the maximum number of instances to write out)
204 */
205 numpmid = 0;
206 maxinst = 0;
207 for (i=0; i<_Oresult->numpmid; i++) {
208 vsetp = _Oresult->vset[i];
209
210 for (j=0; j<ml_numpmid; j++) {
211 if (vsetp->pmid == ml[j].idesc->pmid) {
212 /* pmid has been found in metric list
213 */
214 if (ml[j].numinst > maxinst)
215 maxinst = ml[j].numinst;
216
217 ++numpmid;
218 ilist[numpmid-1] = i; /* _Oresult index */
219 jlist[numpmid-1] = j; /* ml list index */
220 break;
221 }
222 }
223 }
224
225
226 /* if no matches (no pmid's are ready for writing), then return
227 */
228 if (numpmid == 0) {
229 free(ilist);
230 free(jlist);
231 return(NULL);
232 }
233
234
235 /* `numpmid' matches were found (some or all pmid's are ready for writing),
236 * then allocate space for new result
237 */
238 _Nresult = (pmResult *) malloc(sizeof(pmResult) +
239 (numpmid - 1) * sizeof(pmValueSet *));
240 if (_Nresult == NULL)
241 goto nomem;
242
243 _Nresult->timestamp.tv_sec = _Oresult->timestamp.tv_sec;
244 _Nresult->timestamp.tv_usec = _Oresult->timestamp.tv_usec;
245 _Nresult->numpmid = numpmid;
246
247
248 /* make array for indeces into vlist
249 */
250 if (maxinst > 0) {
251 vlistp = (pmValue *) malloc(maxinst * sizeof(pmValue));
252 if (vlistp == NULL)
253 goto nomem;
254 }
255
256
257 /* point _Nresult at the right pmValueSet(s)
258 */
259 for (k=0; k<numpmid; k++) {
260 i = ilist[k];
261 j = jlist[k];
262
263 /* point new result at the wanted pmid
264 */
265 _Nresult->vset[k] = _Oresult->vset[i];
266
267
268 /* allocate the right instances
269 */
270 vsetp = _Nresult->vset[k];
271
272 found = 0;
273 for (q=0; q<ml[j].numinst; q++) {
274 for (r=0; r<vsetp->numval; r++) {
275
276 /* if id in ml is -1, chances are that we haven't seen
277 * it before ... set the instance id
278 */
279 if (ml[j].instlist[q].id < 0)
280 ml[j].instlist[q].id = vsetp->vlist[r].inst;
281
282 if (ml[j].instlist[q].id == vsetp->vlist[r].inst) {
283 /* instance has been found
284 */
285 vlistp[found].inst = vsetp->vlist[r].inst;
286 vlistp[found].value = vsetp->vlist[r].value;
287 ++found;
288 break;
289 } /*if*/
290 } /*for(r)*/
291 } /*for(q)*/
292
293
294 /* note: found may be <= ml[j].numinst
295 * further more, found may be zero ... deal with this later?
296 * - NUMVAL
297 */
298 vsetp->numval = found;
299
300 for (q=0; q<vsetp->numval; q++) {
301 vsetp->vlist[q].inst = vlistp[q].inst;
302 vsetp->vlist[q].value = vlistp[q].value;
303 vlistp[q].inst = 0;
304 vlistp[q].value.lval = 0;
305 } /*for(q)*/
306 } /*for(k)*/
307
308 free(ilist);
309 free(jlist);
310 if (maxinst > 0) free(vlistp); /* free only if space was allocated */
311 return(_Nresult);
312
313 nomem:
314 fprintf(stderr, "%s: Error: cannot malloc space in \"searchmlist\".\n",
315 pmProgname);
316 exit(1);
317 }