Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: rstzipif.H | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | // ========== Copyright Header Begin ========================================== | |
24 | // | |
25 | // OpenSPARC T2 Processor File: rstzipif.H | |
26 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
27 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
28 | // | |
29 | // The above named program is free software; you can redistribute it and/or | |
30 | // modify it under the terms of the GNU General Public | |
31 | // License version 2 as published by the Free Software Foundation. | |
32 | // | |
33 | // The above named program is distributed in the hope that it will be | |
34 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36 | // General Public License for more details. | |
37 | // | |
38 | // You should have received a copy of the GNU General Public | |
39 | // License along with this work; if not, write to the Free Software | |
40 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
41 | // | |
42 | // ========== Copyright Header End ============================================ | |
43 | // File: rstzipif.H | |
44 | // | |
45 | ||
46 | #ifndef _RSTZIPIF_H | |
47 | #define _RSTZIPIF_H | |
48 | ||
49 | enum { | |
50 | RSTZIP_MAJOR_VERSION = 2, | |
51 | RSTZIP_MINOR_VERSION = 1, | |
52 | ||
53 | RSTZIP_MAXCPUS = 64 | |
54 | }; | |
55 | ||
56 | #ifdef __cplusplus | |
57 | ||
58 | #include <stdio.h> | |
59 | #include <string.h> | |
60 | ||
61 | #include "rstzip.H" | |
62 | #include "cpuid.h" | |
63 | #include "buffer.H" | |
64 | #include "header.H" | |
65 | #include "footer.H" | |
66 | ||
67 | typedef struct { | |
68 | int cpu; | |
69 | uint8_t count8; | |
70 | uint16_t count16; | |
71 | uint32_t count32; | |
72 | } CpuCount; | |
73 | ||
74 | class RstzipIF { | |
75 | public: | |
76 | RstzipIF() { | |
77 | infp = NULL; | |
78 | outfp = NULL; | |
79 | dbgfp = NULL; | |
80 | gzfile = NULL; | |
81 | ||
82 | for (int i = 0; i < RSTZIP_MAXCPUS; i++) { | |
83 | rstzip[i] = NULL; | |
84 | rstunzip[i] = NULL; | |
85 | } | |
86 | ||
87 | unirst = (RstSplit*) calloc(RSTZIP_MAXCPUS, sizeof(RstSplit)); | |
88 | ||
89 | curcpu = 0; | |
90 | ||
91 | header = new RstzipHeader; | |
92 | footer = new RstzipFooter; | |
93 | stats = 0; | |
94 | ncpus = 0; | |
95 | decompress_done = 0; | |
96 | buffersize = 0; | |
97 | } | |
98 | ||
99 | ~RstzipIF() { | |
100 | free(unirst); | |
101 | delete header; | |
102 | delete footer; | |
103 | } | |
104 | ||
105 | int openRstzip(const char* outfile, int bufsize, int gzip, int stat, int numcpus) { | |
106 | // Get numcpu and initialize the individual RST buffers for each cpu. | |
107 | char text[80] = { 0 }; | |
108 | ||
109 | rstbuf = new RstzipBuffer(bufsize); | |
110 | cpucount = (CpuCount*) calloc(bufsize, sizeof(CpuCount));; | |
111 | zbuffer = (uint8_t*) calloc(bufsize, sizeof(rstf_unionT)); | |
112 | ||
113 | int retval = openFiles(NULL, outfile, gzip); | |
114 | ||
115 | if (retval == 1) { | |
116 | if (numcpus == 1) { | |
117 | ncpus = 1; | |
118 | rstzip[0] = new Rstzipv2; | |
119 | } | |
120 | ||
121 | // Write the file header. | |
122 | sprintf(text, "Rstzip2 version: %d.%02d.\n", RSTZIP_MAJOR_VERSION, RSTZIP_MINOR_VERSION); | |
123 | strcat(header->getHeader(), text); | |
124 | header->setNumcpus(ncpus); | |
125 | zfwrite(header->getHeader(), header->getMaxHeaderSize()); | |
126 | ||
127 | stats = stat; | |
128 | buffersize = bufsize; | |
129 | } | |
130 | ||
131 | return retval; | |
132 | } | |
133 | ||
134 | void closeRstzip() { | |
135 | // Write a zero record MPchunck to indicate the end of the compressed file. | |
136 | while (compress(NULL, 0) != 0) { | |
137 | //fprintf(stderr, "Hello!\n"); | |
138 | } | |
139 | //compress(NULL, 0); | |
140 | ||
141 | calcFooter(footer); | |
142 | writeFooter(); | |
143 | ||
144 | if (stats == 1) { | |
145 | footer->fprint(stderr); | |
146 | } | |
147 | ||
148 | closeFiles(); | |
149 | ||
150 | for (int i = 0; i < RSTZIP_MAXCPUS; i++) { | |
151 | free(unirst[i].rst); | |
152 | delete rstzip[i]; | |
153 | } | |
154 | ||
155 | delete rstbuf; | |
156 | free(cpucount); | |
157 | free(zbuffer); | |
158 | } | |
159 | ||
160 | int openRstunzip(const char* infile, int bufsize, int gzip, int stat) { | |
161 | int retval = -1; | |
162 | ||
163 | // Test and open files. | |
164 | if (gzip == 1) { | |
165 | if (strcmp(infile, "-") != 0 && strcmp(infile, "stdin") != 0) { | |
166 | uint8_t magic[2] = { 0 }; | |
167 | ||
168 | FILE* fp = fopen(infile, "r"); | |
169 | if (fp == NULL) { | |
170 | return retval; | |
171 | } | |
172 | ||
173 | fread(magic, sizeof(char), 2, fp); | |
174 | fclose(fp); | |
175 | ||
176 | if (magic[0] != 0x1f || magic[1] != 0x8b) { | |
177 | fprintf(stderr, "Error: %s is not gzip compressed.\n", infile); | |
178 | return retval; | |
179 | } | |
180 | } | |
181 | } | |
182 | ||
183 | rstbuf = new RstzipBuffer(bufsize); | |
184 | cpucount = (CpuCount*) calloc(bufsize, sizeof(CpuCount));; | |
185 | zbuffer = (uint8_t*) calloc(bufsize, sizeof(rstf_unionT)); | |
186 | ||
187 | retval = openFiles(infile, NULL, gzip); | |
188 | ||
189 | if (retval == 1) { | |
190 | // Read file header. | |
191 | zfread(header->getHeader(), header->getMaxHeaderSize()); | |
192 | ||
193 | if (header->isValid() == 0) { | |
194 | fprintf(stderr, "Error: %s is not rstzip2 compressed.\n", infile); | |
195 | exit(1); | |
196 | } | |
197 | ||
198 | ncpus = header->getNumcpus(); | |
199 | ||
200 | if (ncpus == 1) { | |
201 | unirst[0].rst = (rstf_unionT*) calloc(bufsize, sizeof(rstf_unionT)); | |
202 | rstunzip[0] = new Rstunzip; | |
203 | } | |
204 | ||
205 | stats = stat; | |
206 | buffersize = bufsize; | |
207 | } | |
208 | ||
209 | return retval; | |
210 | } | |
211 | ||
212 | void closeRstunzip() { | |
213 | // You may want to fix this. | |
214 | // Problem occurs when partial file is decompressed (using -n flag). | |
215 | //readFooter(); | |
216 | //checkFooter(); | |
217 | ||
218 | if (stats == 1) { | |
219 | footer->init(); | |
220 | calcFooter(footer); | |
221 | footer->fprint(stderr); | |
222 | } | |
223 | ||
224 | closeFiles(); | |
225 | ||
226 | for (int i = 0; i < RSTZIP_MAXCPUS; i++) { | |
227 | free(unirst[i].rst); | |
228 | delete rstunzip[i]; | |
229 | } | |
230 | ||
231 | delete rstbuf; | |
232 | free(cpucount); | |
233 | free(zbuffer); | |
234 | } | |
235 | ||
236 | #if 0 | |
237 | ||
238 | int compress(rstf_unionT* rst, int nrecs) { | |
239 | int zrecs = 0; | |
240 | int i; | |
241 | ||
242 | for (i = 0; i < nrecs / buffersize; i++) { | |
243 | zrecs += compressX(&rst[i * buffersize], buffersize); | |
244 | } | |
245 | ||
246 | if (nrecs % buffersize != 0 || nrecs == 0) { | |
247 | zrecs += compressX(&rst[i * buffersize], nrecs % buffersize); | |
248 | } | |
249 | ||
250 | return zrecs; | |
251 | } | |
252 | ||
253 | #else | |
254 | ||
255 | int compress(rstf_unionT* rst, int nrecs) { | |
256 | return compressX(rst, nrecs); | |
257 | } | |
258 | ||
259 | #endif | |
260 | ||
261 | // Decompress exactly nrecs RST records to buf. | |
262 | int decompress(rstf_unionT* buf, int nrecs) { | |
263 | int totalrecs = 0; | |
264 | ||
265 | if (nrecs > buffersize) { | |
266 | totalrecs += decompress(buf, buffersize); | |
267 | totalrecs += decompress(buf, nrecs - buffersize); | |
268 | ||
269 | #if 0 | |
270 | fprintf(stderr, "Error: RST buffer size argument must <= %d.\n", buffersize); | |
271 | exit(1); | |
272 | #endif | |
273 | } else if (nrecs <= rstbuf->nrecs) { | |
274 | // Easy case; rstbuf has sufficient records. | |
275 | memcpy(buf, &rstbuf->rstbuf[rstbuf->curindex], nrecs * sizeof(rstf_unionT)); | |
276 | totalrecs += nrecs; | |
277 | ||
278 | // Update buffer info. | |
279 | rstbuf->shiftBuffer(rstbuf->curindex + nrecs); | |
280 | } else { | |
281 | rstf_unionT* pbuf = (rstf_unionT*) buf; | |
282 | ||
283 | // Copy buffer contexts; refill buffer; call decompress(). | |
284 | memcpy(pbuf, &rstbuf->rstbuf[rstbuf->curindex], rstbuf->nrecs * sizeof(rstf_unionT)); | |
285 | totalrecs += rstbuf->nrecs; | |
286 | ||
287 | nrecs -= rstbuf->nrecs; | |
288 | pbuf += rstbuf->nrecs; | |
289 | ||
290 | // Update buffer info. | |
291 | rstbuf->shiftBuffer(0); | |
292 | ||
293 | // Call decompressX() to refill rstbuf. | |
294 | rstbuf->nrecs = decompressX(rstbuf->rstbuf, buffersize); | |
295 | ||
296 | if (rstbuf->nrecs != 0) { | |
297 | totalrecs += decompress(pbuf, nrecs); | |
298 | } | |
299 | } | |
300 | ||
301 | return totalrecs; | |
302 | } | |
303 | ||
304 | protected: | |
305 | FILE* infp; // Compressed input file pointer; NULL if none | |
306 | FILE* outfp; // Compressed output file pointer; NULL if none | |
307 | FILE* dbgfp; // Debugging file pointer; NULL if none | |
308 | gzFile gzfile; // Gzip compressor pointer; NULL if none | |
309 | ||
310 | Rstzipv2* rstzip[RSTZIP_MAXCPUS]; | |
311 | Rstunzip* rstunzip[RSTZIP_MAXCPUS]; | |
312 | ||
313 | RstzipBuffer* rstbuf; | |
314 | ||
315 | RstSplit* unirst; | |
316 | int curcpu; | |
317 | ||
318 | CpuCount* cpucount; | |
319 | uint8_t* zbuffer; | |
320 | ||
321 | RstzipHeader* header; | |
322 | RstzipFooter* footer; | |
323 | int stats; | |
324 | int ncpus; | |
325 | int decompress_done; | |
326 | int buffersize; | |
327 | ||
328 | // Compress RST buffer to file. | |
329 | int compressX(rstf_unionT* rst, int nrecs) { | |
330 | //uint8_t size8; | |
331 | uint16_t size16; | |
332 | uint32_t size32; | |
333 | int i, zbytes; | |
334 | ||
335 | if (ncpus == 1) { | |
336 | // Just compress the whole buffer in this case. | |
337 | zbytes = rstzip[0]->rstz_compress(zbuffer, rst, nrecs); | |
338 | ||
339 | // Write size of compressed RST records plus footers. | |
340 | zbuffer[zbytes] = z_FOOTER_T; | |
341 | zbytes++; | |
342 | zfwrite(&zbytes, sizeof(zbytes)); | |
343 | ||
344 | // Write compressed RST records. | |
345 | zfwrite(zbuffer, zbytes); | |
346 | } else { | |
347 | // Sort the records in rst into unirst buffers and return the number of cpucount recs used. | |
348 | size16 = sortRstTrace(rst, nrecs); | |
349 | ||
350 | // Compress the CpuCount records to buffer and write to file. | |
351 | size32 = compressCpuCount(zbuffer, cpucount, size16); | |
352 | ||
353 | #if _DEBUG1 | |
354 | fprintf(stderr, "number of cpucount recs=%d (0x%x)\n", size16, size16); | |
355 | fprintf(stderr, "size of cpucount recs=%d (0x%x)\n\n", size32, size32); | |
356 | #endif | |
357 | ||
358 | // Write size of compressed CpuCount records to file. | |
359 | zfwrite(&size32, sizeof(uint32_t)); | |
360 | ||
361 | zfwrite(zbuffer, size32); | |
362 | ||
363 | // Compress the individual cpu rst buffers to file. | |
364 | zbytes = 0; | |
365 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
366 | if (unirst[i].nrecs > 0) { | |
367 | zbytes += rstzip[i]->rstz_compress(&zbuffer[zbytes], unirst[i].rst, unirst[i].nrecs); | |
368 | zbuffer[zbytes] = z_FOOTER_T; | |
369 | zbytes++; | |
370 | } | |
371 | } | |
372 | ||
373 | // Write size of compressed RST records plus footers. | |
374 | zfwrite(&zbytes, sizeof(zbytes)); | |
375 | ||
376 | // Write compressed RST records. | |
377 | zfwrite(zbuffer, zbytes); | |
378 | } | |
379 | ||
380 | return nrecs; | |
381 | } | |
382 | ||
383 | // Decompress file to RST buffer; return number of records decompressed. | |
384 | int decompressX(rstf_unionT* buf, int nrecs) { | |
385 | //rstf_cpuT rstcpu = { CPU_T, 0, 0, 0, 0, 0 }; | |
386 | uint8_t* zbufptr = NULL; | |
387 | int index[RSTZIP_MAXCPUS] = { 0 }; | |
388 | int decompressed_recs = 0; | |
389 | int count, ncpurecs; | |
390 | //uint16_t size16; | |
391 | uint32_t size32; | |
392 | int i, j, zbytes; | |
393 | ||
394 | if (decompress_done == 0) { | |
395 | if (buffersize > nrecs) { | |
396 | fprintf(stderr, "Error: buf size must be >= %d in RstzipIF::decompressX().\n", buffersize); | |
397 | exit(1); | |
398 | } | |
399 | ||
400 | if (ncpus == 1) { | |
401 | // Read the compressed RST records into zbuffer. | |
402 | zfread(&zbytes, sizeof(zbytes)); | |
403 | zfread(zbuffer, zbytes); | |
404 | zbufptr = zbuffer; | |
405 | ||
406 | decompressed_recs = rstunzip[0]->rstz_decompress(&zbufptr, buf, nrecs); | |
407 | ||
408 | // Set cpuid to 0. | |
409 | for (i = 0; i < nrecs; i++) { | |
410 | setRstCpuID(&buf[i], 0); | |
411 | } | |
412 | } else { | |
413 | // Get the size of the compressed CpuCount records. | |
414 | zfread(&size32, sizeof(uint32_t)); | |
415 | ||
416 | // Get the CpuCount records. | |
417 | zfread(zbuffer, size32); | |
418 | ||
419 | ncpurecs = decompressCpuCount(zbuffer, cpucount, size32); | |
420 | ||
421 | #if _DEBUG1 | |
422 | fprintf(stderr, "number of cpucount recs=%d\n", ncpurecs); | |
423 | fprintf(stderr, "size of cpucount recs=%d\n\n", size32); | |
424 | #endif | |
425 | ||
426 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
427 | unirst[i].nrecs = 0; | |
428 | } | |
429 | ||
430 | for (i = 0; i < ncpurecs; i++) { | |
431 | unirst[cpucount[i].cpu].nrecs += cpucount[i].count32; | |
432 | } | |
433 | ||
434 | decompressed_recs = 0; | |
435 | ||
436 | // Read the compressed RST records into zbuffer. | |
437 | zfread(&zbytes, sizeof(zbytes)); | |
438 | zfread(zbuffer, zbytes); | |
439 | zbufptr = zbuffer; | |
440 | ||
441 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
442 | if (unirst[i].nrecs != 0) { | |
443 | if (rstunzip[i] == NULL) { | |
444 | rstunzip[i] = new Rstunzip; | |
445 | unirst[i].rst = (rstf_unionT*) calloc(buffersize, sizeof(rstf_unionT)); | |
446 | } | |
447 | ||
448 | rstunzip[i]->rstz_decompress(&zbufptr, unirst[i].rst, unirst[i].nrecs); | |
449 | ||
450 | // Set the cpuid fields. | |
451 | for (j = 0; j < unirst[i].nrecs; j++) { | |
452 | setRstCpuID(&unirst[i].rst[j], i); | |
453 | } | |
454 | } | |
455 | } | |
456 | ||
457 | for (i = 0; i < ncpurecs; i++) { | |
458 | curcpu = cpucount[i].cpu; | |
459 | count = cpucount[i].count32; | |
460 | ||
461 | memcpy(&buf[decompressed_recs], &unirst[curcpu].rst[index[curcpu]], count * sizeof(rstf_unionT)); | |
462 | index[curcpu] += count; | |
463 | decompressed_recs += count; | |
464 | } | |
465 | } | |
466 | ||
467 | if (decompressed_recs == 0) { | |
468 | decompress_done = 1; | |
469 | } | |
470 | } | |
471 | ||
472 | return decompressed_recs; | |
473 | } | |
474 | ||
475 | int openFiles(const char* infile, const char* outfile, int gzip) { | |
476 | if (infile != NULL) { | |
477 | if (strcmp("-", infile) != 0 && strcmp("stdin", infile) != 0) { | |
478 | infp = fopen(infile, "r"); | |
479 | if (infp == NULL) { | |
480 | return -1; | |
481 | } | |
482 | } else { | |
483 | infp = stdin; | |
484 | } | |
485 | ||
486 | if (gzip == 1) { | |
487 | gzfile = gzdopen(fileno(infp), "r"); | |
488 | if (gzfile == NULL) { | |
489 | fprintf(stderr, "Error: unable to create gzfile for decompressing stdin.\n"); | |
490 | return -1; | |
491 | } | |
492 | } | |
493 | } | |
494 | ||
495 | if (outfile != NULL) { | |
496 | if (strcmp("-", outfile) != 0 && strcmp("stdout", outfile) != 0) { | |
497 | outfp = fopen(outfile, "w"); | |
498 | if (outfp == NULL) { | |
499 | return -1; | |
500 | } | |
501 | } else { | |
502 | outfp = stdout; | |
503 | } | |
504 | ||
505 | if (gzip == 1) { | |
506 | gzfile = gzdopen(fileno(outfp), "w"); | |
507 | if (gzfile == NULL) { | |
508 | fprintf(stderr, "Error: unable to create gzfile for decompressing stdin.\n"); | |
509 | return -1; | |
510 | } | |
511 | } | |
512 | } | |
513 | ||
514 | return 1; | |
515 | } | |
516 | ||
517 | void closeFiles() { | |
518 | gzclose(gzfile); | |
519 | fclose(infp); | |
520 | fclose(outfp); | |
521 | } | |
522 | ||
523 | int zfread(void* buf, long size) { | |
524 | int ret = -1; | |
525 | ||
526 | if (gzfile != NULL) { | |
527 | ret = gzread(gzfile, buf, size); | |
528 | } else if (infp != NULL) { | |
529 | ret = fread(buf, 1, size, infp); | |
530 | } else { | |
531 | fprintf(stderr, "Error: nothing to read from; all inputs are NULL.\n"); | |
532 | exit(1); | |
533 | } | |
534 | ||
535 | return ret; | |
536 | } | |
537 | ||
538 | int zfwrite(void* buf, long size) { | |
539 | int ret = -1; | |
540 | ||
541 | if (gzfile != NULL) { | |
542 | ret = gzwrite(gzfile, buf, size); | |
543 | } else if (outfp != NULL) { | |
544 | ret = fwrite(buf, 1, size, outfp); | |
545 | } else { | |
546 | fprintf(stderr, "Error: nothing to write to; all outputs are NULL.\n"); | |
547 | exit(1); | |
548 | } | |
549 | ||
550 | return ret; | |
551 | } | |
552 | ||
553 | // Sort the rst records in buffer by their cpu, into the unirst buffers. | |
554 | // The total number of CpuRecCount records is returned. | |
555 | int sortRstTrace(rstf_unionT* rst, int nrecs) { | |
556 | int total_recs = 0; | |
557 | int prevcpu = -1; | |
558 | int count = 0; | |
559 | int i, j; | |
560 | ||
561 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
562 | unirst[i].nrecs = 0; | |
563 | } | |
564 | ||
565 | for (i = 0, j = 0; i < nrecs; i++) { | |
566 | curcpu = getRstCpuID(&rst[i]); | |
567 | if (curcpu == -1) { | |
568 | curcpu = 0; | |
569 | } | |
570 | ||
571 | if (prevcpu == -1) { | |
572 | prevcpu = curcpu; | |
573 | count++; | |
574 | } else if (prevcpu != curcpu) { | |
575 | cpucount[j].cpu = prevcpu; | |
576 | cpucount[j].count32 = count; | |
577 | j++; | |
578 | ||
579 | prevcpu = curcpu; | |
580 | count = 1; | |
581 | } else { | |
582 | count++; | |
583 | } | |
584 | ||
585 | if (unirst[curcpu].rst == NULL) { | |
586 | unirst[curcpu].rst = (rstf_unionT*) calloc(buffersize, sizeof(rstf_unionT)); | |
587 | rstzip[curcpu] = new Rstzipv2; | |
588 | } | |
589 | ||
590 | unirst[curcpu].rst[unirst[curcpu].nrecs] = rst[i]; | |
591 | unirst[curcpu].nrecs++; | |
592 | } | |
593 | ||
594 | cpucount[j].cpu = prevcpu; | |
595 | cpucount[j].count32 = count; | |
596 | j++; | |
597 | ||
598 | return (j); | |
599 | } | |
600 | ||
601 | int compressCpuCount(uint8_t* zbuf, CpuCount* cpucnt, int ncpurecs) { | |
602 | int zbytes = 0; | |
603 | int i; | |
604 | ||
605 | for (i = 0; i < ncpurecs; i++) { | |
606 | if (cpucnt[i].count32 <= UINT8_MAX) { | |
607 | cpucnt[i].count8 = cpucnt[i].count32; | |
608 | ||
609 | zbuf[zbytes] = cpucnt[i].cpu; | |
610 | zbytes++; | |
611 | ||
612 | zbuf[zbytes] = cpucnt[i].count8; | |
613 | zbytes++; | |
614 | } else if (cpucnt[i].count32 <= UINT16_MAX) { | |
615 | cpucnt[i].count16 = cpucnt[i].count32; | |
616 | ||
617 | zbuf[zbytes] = cpucnt[i].cpu; | |
618 | zbytes++; | |
619 | ||
620 | zbuf[zbytes] = 0; | |
621 | zbytes++; | |
622 | ||
623 | memcpy(&zbuf[zbytes], &cpucnt[i].count16, sizeof(uint16_t)); | |
624 | zbytes += 2; | |
625 | } else { | |
626 | zbuf[zbytes] = cpucnt[i].cpu; | |
627 | zbytes++; | |
628 | ||
629 | zbuf[zbytes] = 0; | |
630 | zbytes++; | |
631 | ||
632 | zbuf[zbytes] = 0; | |
633 | zbytes++; | |
634 | ||
635 | zbuf[zbytes] = 0; | |
636 | zbytes++; | |
637 | ||
638 | memcpy(&zbuf[zbytes], &cpucnt[i].count32, sizeof(uint32_t)); | |
639 | zbytes += 4; | |
640 | } | |
641 | } | |
642 | ||
643 | return zbytes; | |
644 | } | |
645 | ||
646 | int decompressCpuCount(uint8_t* zbuf, CpuCount* cpucnt, int zcpurecsize) { | |
647 | int i, j; | |
648 | ||
649 | i = 0; | |
650 | j = 0; | |
651 | while (i < zcpurecsize) { | |
652 | cpucnt[j].cpu = zbuf[i]; | |
653 | i++; | |
654 | cpucnt[j].count32 = zbuf[i]; | |
655 | i++; | |
656 | ||
657 | if (cpucnt[j].count32 == 0 && i != zcpurecsize && i != 1) { | |
658 | memcpy(&cpucnt[j].count16, &zbuf[i], sizeof(uint16_t)); | |
659 | cpucnt[j].count32 = cpucnt[j].count16; | |
660 | i += 2; | |
661 | } | |
662 | ||
663 | if (cpucnt[j].count32 == 0 && i != zcpurecsize && i != 1) { | |
664 | memcpy(&cpucnt[j].count32, &zbuf[i], sizeof(uint32_t)); | |
665 | i += 4; | |
666 | } | |
667 | ||
668 | j++; | |
669 | } | |
670 | ||
671 | return j; | |
672 | } | |
673 | ||
674 | void readFooter() { | |
675 | zfread(footer, sizeof(RstzipFooter)); | |
676 | } | |
677 | ||
678 | void writeFooter() { | |
679 | zfwrite(footer, sizeof(RstzipFooter)); | |
680 | } | |
681 | ||
682 | RstzipFooter* calcFooter(RstzipFooter* foot) { | |
683 | int i, j; | |
684 | ||
685 | foot->init(); | |
686 | ||
687 | if (decompress_done == 0) { | |
688 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
689 | if (rstzip[i] != NULL) { | |
690 | foot->max_chunksize += rstzip[i]->max_chunksize; | |
691 | foot->total_instr += rstzip[i]->total_instr; | |
692 | foot->total_noninstr += rstzip[i]->total_noninstr; | |
693 | foot->total_loop_chunk += rstzip[i]->total_loop_chunk; | |
694 | foot->total_nonloop_chunk += rstzip[i]->total_nonloop_chunk; | |
695 | foot->total_zpavadiff += rstzip[i]->total_zpavadiff; | |
696 | foot->total_pavadiff += rstzip[i]->total_pavadiff; | |
697 | foot->zero_offset_count += rstzip[i]->zero_offset_count; | |
698 | ||
699 | for (j = 0; j < OFFSET_64BITS_IDX + 1; j++) { | |
700 | foot->offset_count[j] += rstzip[i]->offset_count[j]; | |
701 | } | |
702 | ||
703 | for (j = 0; j < CHUNKSIZE_RES; j++) { | |
704 | foot->chunksize_count[j] += rstzip[i]->chunksize_count[j]; | |
705 | } | |
706 | } | |
707 | } | |
708 | } else { | |
709 | for (i = 0; i < RSTZIP_MAXCPUS; i++) { | |
710 | if (rstunzip[i] != NULL) { | |
711 | foot->max_chunksize += rstunzip[i]->max_chunksize; | |
712 | foot->total_instr += rstunzip[i]->total_instr; | |
713 | foot->total_noninstr += rstunzip[i]->total_noninstr; | |
714 | foot->total_loop_chunk += rstunzip[i]->total_loop_chunk; | |
715 | foot->total_nonloop_chunk += rstunzip[i]->total_nonloop_chunk; | |
716 | foot->total_zpavadiff += rstunzip[i]->total_zpavadiff; | |
717 | foot->total_pavadiff += rstunzip[i]->total_pavadiff; | |
718 | foot->zero_offset_count += rstunzip[i]->zero_offset_count; | |
719 | ||
720 | for (j = 0; j < OFFSET_64BITS_IDX + 1; j++) { | |
721 | foot->offset_count[j] += rstunzip[i]->offset_count[j]; | |
722 | } | |
723 | ||
724 | for (j = 0; j < CHUNKSIZE_RES; j++) { | |
725 | foot->chunksize_count[j] += rstunzip[i]->chunksize_count[j]; | |
726 | } | |
727 | } | |
728 | } | |
729 | } | |
730 | ||
731 | return foot; | |
732 | } | |
733 | ||
734 | int checkFooter() { | |
735 | RstzipFooter calc_footer; | |
736 | int numerr = 0; | |
737 | ||
738 | calcFooter(&calc_footer); | |
739 | ||
740 | if (footer->max_chunksize != calc_footer.max_chunksize) { | |
741 | fprintf(stderr, "Warning: decompressed max chunksize (%d) != compressed (%d).\n", | |
742 | calc_footer.max_chunksize, footer->max_chunksize); | |
743 | numerr++; | |
744 | } | |
745 | if (footer->total_instr != calc_footer.total_instr) { | |
746 | fprintf(stderr, "Warning: decompressed instr recs (%llu) != compressed (%llu).\n", | |
747 | calc_footer.total_instr, footer->total_instr); | |
748 | numerr++; | |
749 | } | |
750 | if (footer->total_noninstr != calc_footer.total_noninstr) { | |
751 | fprintf(stderr, "Warning: decompressed non-instr recs (%llu) != compressed (%llu).\n", | |
752 | calc_footer.total_noninstr, footer->total_noninstr); | |
753 | numerr++; | |
754 | } | |
755 | if (footer->total_loop_chunk != calc_footer.total_loop_chunk) { | |
756 | fprintf(stderr, "Warning: decompressed loop chunks (%llu) != compressed (%llu).\n", | |
757 | calc_footer.total_loop_chunk, footer->total_loop_chunk); | |
758 | numerr++; | |
759 | } | |
760 | if (footer->total_nonloop_chunk != calc_footer.total_nonloop_chunk) { | |
761 | fprintf(stderr, "Warning: decompressed non-loop chunks (%llu) != compressed (%llu).\n", | |
762 | calc_footer.total_nonloop_chunk, footer->total_nonloop_chunk); | |
763 | numerr++; | |
764 | } | |
765 | if (footer->total_zpavadiff != calc_footer.total_zpavadiff) { | |
766 | fprintf(stderr, "Warning: decompressed compressed pavadiff recs (%llu) != compressed (%llu).\n", | |
767 | calc_footer.total_zpavadiff, footer->total_zpavadiff); | |
768 | numerr++; | |
769 | } | |
770 | if (footer->total_pavadiff != calc_footer.total_pavadiff) { | |
771 | fprintf(stderr, "Warning: decompressed pavadiffs (%llu) != compressed (%llu).\n", | |
772 | calc_footer.total_pavadiff, footer->total_pavadiff); | |
773 | numerr++; | |
774 | } | |
775 | if (footer->zero_offset_count != calc_footer.zero_offset_count) { | |
776 | fprintf(stderr, "Warning: decompressed zero EA offsets (%llu) != compressed (%llu).\n", | |
777 | calc_footer.zero_offset_count, footer->zero_offset_count); | |
778 | numerr++; | |
779 | } | |
780 | ||
781 | return numerr; | |
782 | } | |
783 | }; // class RstzipIF | |
784 | ||
785 | #endif // __cplusplus | |
786 | ||
787 | #endif // _RSTZIPIF_H |