* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: rstzipif.H
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: rstzipif.H
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
RSTZIP_MAJOR_VERSION = 2,
RSTZIP_MINOR_VERSION = 1,
for (int i = 0; i < RSTZIP_MAXCPUS; i++) {
unirst = (RstSplit*) calloc(RSTZIP_MAXCPUS, sizeof(RstSplit));
header = new RstzipHeader;
footer = new RstzipFooter;
int openRstzip(const char* outfile, int bufsize, int gzip, int stat, int numcpus) {
// Get numcpu and initialize the individual RST buffers for each cpu.
rstbuf = new RstzipBuffer(bufsize);
cpucount = (CpuCount*) calloc(bufsize, sizeof(CpuCount));;
zbuffer = (uint8_t*) calloc(bufsize, sizeof(rstf_unionT));
int retval = openFiles(NULL, outfile, gzip);
rstzip[0] = new Rstzipv2;
// Write the file header.
sprintf(text, "Rstzip2 version: %d.%02d.\n", RSTZIP_MAJOR_VERSION, RSTZIP_MINOR_VERSION);
strcat(header->getHeader(), text);
header->setNumcpus(ncpus);
zfwrite(header->getHeader(), header->getMaxHeaderSize());
// Write a zero record MPchunck to indicate the end of the compressed file.
while (compress(NULL, 0) != 0) {
//fprintf(stderr, "Hello!\n");
for (int i = 0; i < RSTZIP_MAXCPUS; i++) {
int openRstunzip(const char* infile, int bufsize, int gzip, int stat) {
if (strcmp(infile, "-") != 0 && strcmp(infile, "stdin") != 0) {
uint8_t magic[2] = { 0 };
FILE* fp = fopen(infile, "r");
fread(magic, sizeof(char), 2, fp);
if (magic[0] != 0x1f || magic[1] != 0x8b) {
fprintf(stderr, "Error: %s is not gzip compressed.\n", infile);
rstbuf = new RstzipBuffer(bufsize);
cpucount = (CpuCount*) calloc(bufsize, sizeof(CpuCount));;
zbuffer = (uint8_t*) calloc(bufsize, sizeof(rstf_unionT));
retval = openFiles(infile, NULL, gzip);
zfread(header->getHeader(), header->getMaxHeaderSize());
if (header->isValid() == 0) {
fprintf(stderr, "Error: %s is not rstzip2 compressed.\n", infile);
ncpus = header->getNumcpus();
unirst[0].rst = (rstf_unionT*) calloc(bufsize, sizeof(rstf_unionT));
rstunzip[0] = new Rstunzip;
// You may want to fix this.
// Problem occurs when partial file is decompressed (using -n flag).
for (int i = 0; i < RSTZIP_MAXCPUS; i++) {
int compress(rstf_unionT* rst, int nrecs) {
for (i = 0; i < nrecs / buffersize; i++) {
zrecs += compressX(&rst[i * buffersize], buffersize);
if (nrecs % buffersize != 0 || nrecs == 0) {
zrecs += compressX(&rst[i * buffersize], nrecs % buffersize);
int compress(rstf_unionT* rst, int nrecs) {
return compressX(rst, nrecs);
// Decompress exactly nrecs RST records to buf.
int decompress(rstf_unionT* buf, int nrecs) {
if (nrecs > buffersize) {
totalrecs += decompress(buf, buffersize);
totalrecs += decompress(buf, nrecs - buffersize);
fprintf(stderr, "Error: RST buffer size argument must <= %d.\n", buffersize);
} else if (nrecs <= rstbuf->nrecs) {
// Easy case; rstbuf has sufficient records.
memcpy(buf, &rstbuf->rstbuf[rstbuf->curindex], nrecs * sizeof(rstf_unionT));
rstbuf->shiftBuffer(rstbuf->curindex + nrecs);
rstf_unionT* pbuf = (rstf_unionT*) buf;
// Copy buffer contexts; refill buffer; call decompress().
memcpy(pbuf, &rstbuf->rstbuf[rstbuf->curindex], rstbuf->nrecs * sizeof(rstf_unionT));
totalrecs += rstbuf->nrecs;
// Call decompressX() to refill rstbuf.
rstbuf->nrecs = decompressX(rstbuf->rstbuf, buffersize);
if (rstbuf->nrecs != 0) {
totalrecs += decompress(pbuf, nrecs);
FILE* infp; // Compressed input file pointer; NULL if none
FILE* outfp; // Compressed output file pointer; NULL if none
FILE* dbgfp; // Debugging file pointer; NULL if none
gzFile gzfile; // Gzip compressor pointer; NULL if none
Rstzipv2* rstzip[RSTZIP_MAXCPUS];
Rstunzip* rstunzip[RSTZIP_MAXCPUS];
// Compress RST buffer to file.
int compressX(rstf_unionT* rst, int nrecs) {
// Just compress the whole buffer in this case.
zbytes = rstzip[0]->rstz_compress(zbuffer, rst, nrecs);
// Write size of compressed RST records plus footers.
zbuffer[zbytes] = z_FOOTER_T;
zfwrite(&zbytes, sizeof(zbytes));
// Write compressed RST records.
zfwrite(zbuffer, zbytes);
// Sort the records in rst into unirst buffers and return the number of cpucount recs used.
size16 = sortRstTrace(rst, nrecs);
// Compress the CpuCount records to buffer and write to file.
size32 = compressCpuCount(zbuffer, cpucount, size16);
fprintf(stderr, "number of cpucount recs=%d (0x%x)\n", size16, size16);
fprintf(stderr, "size of cpucount recs=%d (0x%x)\n\n", size32, size32);
// Write size of compressed CpuCount records to file.
zfwrite(&size32, sizeof(uint32_t));
zfwrite(zbuffer, size32);
// Compress the individual cpu rst buffers to file.
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
if (unirst[i].nrecs > 0) {
zbytes += rstzip[i]->rstz_compress(&zbuffer[zbytes], unirst[i].rst, unirst[i].nrecs);
zbuffer[zbytes] = z_FOOTER_T;
// Write size of compressed RST records plus footers.
zfwrite(&zbytes, sizeof(zbytes));
// Write compressed RST records.
zfwrite(zbuffer, zbytes);
// Decompress file to RST buffer; return number of records decompressed.
int decompressX(rstf_unionT* buf, int nrecs) {
//rstf_cpuT rstcpu = { CPU_T, 0, 0, 0, 0, 0 };
int index[RSTZIP_MAXCPUS] = { 0 };
int decompressed_recs = 0;
if (decompress_done == 0) {
if (buffersize > nrecs) {
fprintf(stderr, "Error: buf size must be >= %d in RstzipIF::decompressX().\n", buffersize);
// Read the compressed RST records into zbuffer.
zfread(&zbytes, sizeof(zbytes));
decompressed_recs = rstunzip[0]->rstz_decompress(&zbufptr, buf, nrecs);
for (i = 0; i < nrecs; i++) {
// Get the size of the compressed CpuCount records.
zfread(&size32, sizeof(uint32_t));
// Get the CpuCount records.
ncpurecs = decompressCpuCount(zbuffer, cpucount, size32);
fprintf(stderr, "number of cpucount recs=%d\n", ncpurecs);
fprintf(stderr, "size of cpucount recs=%d\n\n", size32);
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
for (i = 0; i < ncpurecs; i++) {
unirst[cpucount[i].cpu].nrecs += cpucount[i].count32;
// Read the compressed RST records into zbuffer.
zfread(&zbytes, sizeof(zbytes));
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
if (unirst[i].nrecs != 0) {
if (rstunzip[i] == NULL) {
rstunzip[i] = new Rstunzip;
unirst[i].rst = (rstf_unionT*) calloc(buffersize, sizeof(rstf_unionT));
rstunzip[i]->rstz_decompress(&zbufptr, unirst[i].rst, unirst[i].nrecs);
for (j = 0; j < unirst[i].nrecs; j++) {
setRstCpuID(&unirst[i].rst[j], i);
for (i = 0; i < ncpurecs; i++) {
curcpu = cpucount[i].cpu;
count = cpucount[i].count32;
memcpy(&buf[decompressed_recs], &unirst[curcpu].rst[index[curcpu]], count * sizeof(rstf_unionT));
decompressed_recs += count;
if (decompressed_recs == 0) {
return decompressed_recs;
int openFiles(const char* infile, const char* outfile, int gzip) {
if (strcmp("-", infile) != 0 && strcmp("stdin", infile) != 0) {
infp = fopen(infile, "r");
gzfile = gzdopen(fileno(infp), "r");
fprintf(stderr, "Error: unable to create gzfile for decompressing stdin.\n");
if (strcmp("-", outfile) != 0 && strcmp("stdout", outfile) != 0) {
outfp = fopen(outfile, "w");
gzfile = gzdopen(fileno(outfp), "w");
fprintf(stderr, "Error: unable to create gzfile for decompressing stdin.\n");
int zfread(void* buf, long size) {
ret = gzread(gzfile, buf, size);
} else if (infp != NULL) {
ret = fread(buf, 1, size, infp);
fprintf(stderr, "Error: nothing to read from; all inputs are NULL.\n");
int zfwrite(void* buf, long size) {
ret = gzwrite(gzfile, buf, size);
} else if (outfp != NULL) {
ret = fwrite(buf, 1, size, outfp);
fprintf(stderr, "Error: nothing to write to; all outputs are NULL.\n");
// Sort the rst records in buffer by their cpu, into the unirst buffers.
// The total number of CpuRecCount records is returned.
int sortRstTrace(rstf_unionT* rst, int nrecs) {
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
for (i = 0, j = 0; i < nrecs; i++) {
curcpu = getRstCpuID(&rst[i]);
} else if (prevcpu != curcpu) {
cpucount[j].cpu = prevcpu;
cpucount[j].count32 = count;
if (unirst[curcpu].rst == NULL) {
unirst[curcpu].rst = (rstf_unionT*) calloc(buffersize, sizeof(rstf_unionT));
rstzip[curcpu] = new Rstzipv2;
unirst[curcpu].rst[unirst[curcpu].nrecs] = rst[i];
cpucount[j].cpu = prevcpu;
cpucount[j].count32 = count;
int compressCpuCount(uint8_t* zbuf, CpuCount* cpucnt, int ncpurecs) {
for (i = 0; i < ncpurecs; i++) {
if (cpucnt[i].count32 <= UINT8_MAX) {
cpucnt[i].count8 = cpucnt[i].count32;
zbuf[zbytes] = cpucnt[i].cpu;
zbuf[zbytes] = cpucnt[i].count8;
} else if (cpucnt[i].count32 <= UINT16_MAX) {
cpucnt[i].count16 = cpucnt[i].count32;
zbuf[zbytes] = cpucnt[i].cpu;
memcpy(&zbuf[zbytes], &cpucnt[i].count16, sizeof(uint16_t));
zbuf[zbytes] = cpucnt[i].cpu;
memcpy(&zbuf[zbytes], &cpucnt[i].count32, sizeof(uint32_t));
int decompressCpuCount(uint8_t* zbuf, CpuCount* cpucnt, int zcpurecsize) {
while (i < zcpurecsize) {
cpucnt[j].count32 = zbuf[i];
if (cpucnt[j].count32 == 0 && i != zcpurecsize && i != 1) {
memcpy(&cpucnt[j].count16, &zbuf[i], sizeof(uint16_t));
cpucnt[j].count32 = cpucnt[j].count16;
if (cpucnt[j].count32 == 0 && i != zcpurecsize && i != 1) {
memcpy(&cpucnt[j].count32, &zbuf[i], sizeof(uint32_t));
zfread(footer, sizeof(RstzipFooter));
zfwrite(footer, sizeof(RstzipFooter));
RstzipFooter* calcFooter(RstzipFooter* foot) {
if (decompress_done == 0) {
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
foot->max_chunksize += rstzip[i]->max_chunksize;
foot->total_instr += rstzip[i]->total_instr;
foot->total_noninstr += rstzip[i]->total_noninstr;
foot->total_loop_chunk += rstzip[i]->total_loop_chunk;
foot->total_nonloop_chunk += rstzip[i]->total_nonloop_chunk;
foot->total_zpavadiff += rstzip[i]->total_zpavadiff;
foot->total_pavadiff += rstzip[i]->total_pavadiff;
foot->zero_offset_count += rstzip[i]->zero_offset_count;
for (j = 0; j < OFFSET_64BITS_IDX + 1; j++) {
foot->offset_count[j] += rstzip[i]->offset_count[j];
for (j = 0; j < CHUNKSIZE_RES; j++) {
foot->chunksize_count[j] += rstzip[i]->chunksize_count[j];
for (i = 0; i < RSTZIP_MAXCPUS; i++) {
if (rstunzip[i] != NULL) {
foot->max_chunksize += rstunzip[i]->max_chunksize;
foot->total_instr += rstunzip[i]->total_instr;
foot->total_noninstr += rstunzip[i]->total_noninstr;
foot->total_loop_chunk += rstunzip[i]->total_loop_chunk;
foot->total_nonloop_chunk += rstunzip[i]->total_nonloop_chunk;
foot->total_zpavadiff += rstunzip[i]->total_zpavadiff;
foot->total_pavadiff += rstunzip[i]->total_pavadiff;
foot->zero_offset_count += rstunzip[i]->zero_offset_count;
for (j = 0; j < OFFSET_64BITS_IDX + 1; j++) {
foot->offset_count[j] += rstunzip[i]->offset_count[j];
for (j = 0; j < CHUNKSIZE_RES; j++) {
foot->chunksize_count[j] += rstunzip[i]->chunksize_count[j];
RstzipFooter calc_footer;
calcFooter(&calc_footer);
if (footer->max_chunksize != calc_footer.max_chunksize) {
fprintf(stderr, "Warning: decompressed max chunksize (%d) != compressed (%d).\n",
calc_footer.max_chunksize, footer->max_chunksize);
if (footer->total_instr != calc_footer.total_instr) {
fprintf(stderr, "Warning: decompressed instr recs (%llu) != compressed (%llu).\n",
calc_footer.total_instr, footer->total_instr);
if (footer->total_noninstr != calc_footer.total_noninstr) {
fprintf(stderr, "Warning: decompressed non-instr recs (%llu) != compressed (%llu).\n",
calc_footer.total_noninstr, footer->total_noninstr);
if (footer->total_loop_chunk != calc_footer.total_loop_chunk) {
fprintf(stderr, "Warning: decompressed loop chunks (%llu) != compressed (%llu).\n",
calc_footer.total_loop_chunk, footer->total_loop_chunk);
if (footer->total_nonloop_chunk != calc_footer.total_nonloop_chunk) {
fprintf(stderr, "Warning: decompressed non-loop chunks (%llu) != compressed (%llu).\n",
calc_footer.total_nonloop_chunk, footer->total_nonloop_chunk);
if (footer->total_zpavadiff != calc_footer.total_zpavadiff) {
fprintf(stderr, "Warning: decompressed compressed pavadiff recs (%llu) != compressed (%llu).\n",
calc_footer.total_zpavadiff, footer->total_zpavadiff);
if (footer->total_pavadiff != calc_footer.total_pavadiff) {
fprintf(stderr, "Warning: decompressed pavadiffs (%llu) != compressed (%llu).\n",
calc_footer.total_pavadiff, footer->total_pavadiff);
if (footer->zero_offset_count != calc_footer.zero_offset_count) {
fprintf(stderr, "Warning: decompressed zero EA offsets (%llu) != compressed (%llu).\n",
calc_footer.zero_offset_count, footer->zero_offset_count);