/* fifo queue management */ #define fifo_used_bytes(used) (used) #define fifo_free_bytes(used, len) ((len)-(used)) /* amount of free bytes in the first and last parts */ #define fifo_free_first_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
? (len)-((cur)+(used)) : 0) #define fifo_free_last_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
? (cur) : (len)-(used)) /* amount of used bytes in the first and last parts */ #define fifo_used_first_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
? (used) : (len)-(cur)) #define fifo_used_last_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
? 0 : ((used)+(cur))-(len)) /* first and last free parts start here */ #define fifo_free_first_offset(cur, used) ((cur)+(used)) #define fifo_free_last_offset(cur, used, len) \
fifo_used_last_bytes(cur, used, len) /* first and last used parts start here */ #define fifo_used_first_offset(cur) (cur) #define fifo_used_last_offset(cur) (0)
/* Make a new file name to write to. Ignoring '.gz' */
wp = (NULL != (wp = strrchr(argv[1], '/'))) ? (wp+1) : argv[1];
strcpy(w, wp);
strcat(w, ".nx.gunzip");
/* We read in to fifo_in in two steps: first: read in to from *cur_intotheendofthebuffer.last:iffreespacewrapped *around,readfromfifo_inoffset0tooffsetcur_in.
*/
/* Reset fifo head to reduce unnecessary wrap arounds */
cur_in = (used_in == 0) ? 0 : cur_in;
/* Free space total is reduced by a gap */
free_space = NX_MAX(0, fifo_free_bytes(used_in, fifo_in_len)
- line_sz);
/* Free space may wrap around as first and last */
first_free = fifo_free_first_bytes(cur_in, used_in, fifo_in_len);
last_free = fifo_free_last_bytes(cur_in, used_in, fifo_in_len);
/* Start offsets of the free memory */
first_offset = fifo_free_first_offset(cur_in, used_in);
last_offset = fifo_free_last_offset(cur_in, used_in, fifo_in_len);
/* Reduce read_sz because of the line_sz gap */
read_sz = NX_MIN(free_space, first_free);
n = 0; if (read_sz > 0) { /* Read in to offset cur_in + used_in */
n = fread(fifo_in + first_offset, 1, read_sz, inpf);
used_in = used_in + n;
free_space = free_space - n;
assert(n <= read_sz); if (n != read_sz) { /* Either EOF or error; exit the read loop */
is_eof = 1; goto write_state;
}
}
/* If free space wrapped around */ if (last_free > 0) { /* Reduce read_sz because of the line_sz gap */
read_sz = NX_MIN(free_space, last_free);
n = 0; if (read_sz > 0) {
n = fread(fifo_in + last_offset, 1, read_sz, inpf);
used_in = used_in + n; /* Increase used space */
free_space = free_space - n; /* Decrease free space */
assert(n <= read_sz); if (n != read_sz) { /* Either EOF or error; exit the read loop */
is_eof = 1; goto write_state;
}
}
}
/* At this point we have used_in bytes in fifo_in with the *dataheadstartingatcur_inandpossiblywrappingaround.
*/
write_state:
/* Write decompressed data to output file */
NXPRT(fprintf(stderr, "write_state:\n"));
if (used_out == 0) goto decomp_state;
/* If fifo_out has data waiting, write it out to the file to *makefreetargetspacefortheacceleratorusedbytesin *thefirstandlastpartsoffifo_out.
*/
n = 0; if (write_sz > 0) {
n = fwrite(fifo_out + cur_out, 1, write_sz, outf);
used_out = used_out - n; /* Move head of the fifo */
cur_out = (cur_out + n) % fifo_out_len;
assert(n <= write_sz); if (n != write_sz) {
fprintf(stderr, "error: write\n");
rc = -1; goto err5;
}
}
if (last_used > 0) { /* If more data available in the last part */
write_sz = last_used; /* Keep it here for later */
n = 0; if (write_sz > 0) {
n = fwrite(fifo_out, 1, write_sz, outf);
used_out = used_out - n;
cur_out = (cur_out + n) % fifo_out_len;
assert(n <= write_sz); if (n != write_sz) {
fprintf(stderr, "error: write\n");
rc = -1; goto err5;
}
}
}
/* Round up the history size to quadword. Section 2.10 */
history_len = (history_len + 15) / 16;
putnn(cmdp->cpb, in_histlen, history_len);
history_len = history_len * 16; /* bytes */
if (history_len > 0) { /* Chain in the history buffer to the DDE list */ if (cur_out >= history_len) {
nx_append_dde(ddl_in, fifo_out
+ (cur_out - history_len),
history_len);
} else {
nx_append_dde(ddl_in, fifo_out
+ ((fifo_out_len + cur_out)
- history_len),
history_len - cur_out); /* Up to 32KB history wraps around fifo_out */
nx_append_dde(ddl_in, fifo_out, cur_out);
}
}
} else { /* First decompress job */
fc = GZIP_FC_DECOMPRESS;
history_len = 0; /* Writing 0 clears out subc as well */
cmdp->cpb.in_histlen = 0;
total_out = 0;
/* Target buffer size is used to limit the source data size *basedonpreviousmeasurementsofcompressionratio.
*/
/* source_sz includes history */
source_sz = getp32(ddl_in, ddebc);
assert(source_sz > history_len);
source_sz = source_sz - history_len;
/* Estimating how much source is needed to 3/4 fill a *target_maxsizetargetbuffer.Ifweovershoot,thenNX *mustrepeatthejobwithsmallerinputandwewaste *bandwidth.IfweundershootthenweusemoreNXcallsthan *necessary.
*/
/* Send job to NX */
cc = nx_submit_job(ddl_in, ddl_out, cmdp, devhandle);
switch (cc) {
case ERR_NX_AT_FAULT:
/* We touched the pages ahead of time. In the most common case *weshouldn'tbehere.Butmaybesomepageswerepagedout. *Kernelshouldhaveplacedthefaultingaddresstofsaddr.
*/
NXPRT(fprintf(stderr, "ERR_NX_AT_FAULT %p\n",
(void *)cmdp->crb.csb.fsaddr));
if (pgfault_retries == NX_MAX_FAULTS) { /* Try once with exact number of pages */
--pgfault_retries; goto restart_nx;
} elseif (pgfault_retries > 0) { /* If still faulting try fewer input pages *assumingmemoryoutage
*/ if (source_sz > page_sz)
source_sz = NX_MAX(source_sz / 2, page_sz);
--pgfault_retries; goto restart_nx;
} else {
fprintf(stderr, "cannot make progress; too many ");
fprintf(stderr, "page fault retries cc= %d\n", cc);
rc = -1; goto err5;
}
case ERR_NX_DATA_LENGTH:
NXPRT(fprintf(stderr, "ERR_NX_DATA_LENGTH; "));
NXPRT(fprintf(stderr, "stream may have trailing data\n"));
/* Not an error in the most common case; it just says *thereistrailingdatathatwemustexamine. * *CC=3CE(1)=0CE(0)=1indicatespartialcompletion *Fig.6-7andTable6-8.
*/
nx_ce = get_csb_ce_ms3b(cmdp->crb.csb);
if (!csb_ce_termination(nx_ce) &&
csb_ce_partial_completion(nx_ce)) { /* Check CPB for more information *spbcandtpbcarevalid
*/
sfbt = getnn(cmdp->cpb, out_sfbt); /* Table 6-4 */
subc = getnn(cmdp->cpb, out_subc); /* Table 6-4 */
spbc = get32(cmdp->cpb, out_spbc_decomp);
tpbc = get32(cmdp->crb.csb, tpbc);
assert(target_max >= tpbc);
goto ok_cc3; /* not an error */
} else { /* History length error when CE(1)=1 CE(0)=0. */
rc = -1;
fprintf(stderr, "history length error cc= %d\n", cc); goto err5;
}
/* Round up to a qword */
dhtlen = (dhtlen + 127) / 128;
while (dhtlen > 0) { /* Copy dht from cpb.out to cpb.in */
--dhtlen;
cmdp->cpb.in_dht[dhtlen] = cmdp->cpb.out_dht[dhtlen];
} break;
case0xE: /* Within a block header; bfinal=0; */ /* Also given if source data exactly ends (SUBC=0) with *EOBcodewithBFINAL=0.Meansthenextbytewill *containablockheader.
*/ case0xF: /* within a block header with BFINAL=1. */
/* Add output data to fifo_out */
used_out = used_out + tpbc;
assert(used_out <= fifo_out_len);
total_out = total_out + tpbc;
/* Deflate history is 32KB max. No need to supply more *than32KBonaresume.
*/
history_len = (total_out > window_max) ? window_max : total_out;
/* To estimate expected expansion in the next NX job; 500 means 50%. *Deflatebestcaseisaround1to1000.
*/
last_comp_ratio = (1000UL * ((uint64_t)source_sz + 1))
/ ((uint64_t)tpbc + 1);
last_comp_ratio = NX_MAX(NX_MIN(1000UL, last_comp_ratio), 1);
NXPRT(fprintf(stderr, "comp_ratio %ld source_sz %d spbc %d tpbc %d\n",
last_comp_ratio, source_sz, spbc, tpbc));
resuming = 1;
finish_state:
NXPRT(fprintf(stderr, "finish_state:\n"));
if (is_final) { if (used_out) goto write_state; /* More data to write out */ elseif (used_in < 8) { /* Need at least 8 more bytes containing gzip crc *andisize.
*/
rc = -1; goto err4;
} else { /* Compare checksums and exit */ int i; unsignedchar tail[8];
uint32_t cksum, isize;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.