reworked adaptCompressionLevel to only account for completion information

dev
Paul Cruz 2017-07-20 16:19:16 -07:00
parent 7ab758a640
commit a19916425d
1 changed files with 119 additions and 148 deletions

View File

@ -29,7 +29,6 @@
static int g_displayLevel = DEFAULT_DISPLAY_LEVEL; static int g_displayLevel = DEFAULT_DISPLAY_LEVEL;
static unsigned g_compressionLevel = DEFAULT_COMPRESSION_LEVEL; static unsigned g_compressionLevel = DEFAULT_COMPRESSION_LEVEL;
static unsigned g_displayStats = 0;
static UTIL_time_t g_startTime; static UTIL_time_t g_startTime;
static size_t g_streamedSize = 0; static size_t g_streamedSize = 0;
static unsigned g_useProgressBar = 0; static unsigned g_useProgressBar = 0;
@ -47,15 +46,6 @@ typedef struct {
buffer_t buffer; buffer_t buffer;
} inBuff_t; } inBuff_t;
typedef struct {
unsigned waitCompressed;
unsigned waitReady;
unsigned waitWrite;
unsigned readyCounter;
unsigned compressedCounter;
unsigned writeCounter;
} cStat_t;
typedef struct { typedef struct {
buffer_t src; buffer_t src;
buffer_t dst; buffer_t dst;
@ -102,10 +92,9 @@ typedef struct {
mutex_t jobWrite_mutex; mutex_t jobWrite_mutex;
cond_t jobWrite_cond; cond_t jobWrite_cond;
mutex_t completion_mutex; mutex_t completion_mutex;
mutex_t stats_mutex; mutex_t wait_mutex;
size_t lastDictSize; size_t lastDictSize;
inBuff_t input; inBuff_t input;
cStat_t stats;
jobDescription* jobs; jobDescription* jobs;
ZSTD_CCtx* cctx; ZSTD_CCtx* cctx;
} adaptCCtx; } adaptCCtx;
@ -163,7 +152,7 @@ static int freeCCtx(adaptCCtx* ctx)
error |= destroyMutex(&ctx->jobWrite_mutex); error |= destroyMutex(&ctx->jobWrite_mutex);
error |= destroyCond(&ctx->jobWrite_cond); error |= destroyCond(&ctx->jobWrite_cond);
error |= destroyMutex(&ctx->completion_mutex); error |= destroyMutex(&ctx->completion_mutex);
error |= destroyMutex(&ctx->stats_mutex); error |= destroyMutex(&ctx->wait_mutex);
error |= ZSTD_isError(ZSTD_freeCCtx(ctx->cctx)); error |= ZSTD_isError(ZSTD_freeCCtx(ctx->cctx));
free(ctx->input.buffer.start); free(ctx->input.buffer.start);
if (ctx->jobs){ if (ctx->jobs){
@ -203,7 +192,7 @@ static int initCCtx(adaptCCtx* ctx, unsigned numJobs)
pthreadError |= initMutex(&ctx->jobWrite_mutex); pthreadError |= initMutex(&ctx->jobWrite_mutex);
pthreadError |= initCond(&ctx->jobWrite_cond); pthreadError |= initCond(&ctx->jobWrite_cond);
pthreadError |= initMutex(&ctx->completion_mutex); pthreadError |= initMutex(&ctx->completion_mutex);
pthreadError |= initMutex(&ctx->stats_mutex); pthreadError |= initMutex(&ctx->wait_mutex);
if (pthreadError) return pthreadError; if (pthreadError) return pthreadError;
} }
ctx->numJobs = numJobs; ctx->numJobs = numJobs;
@ -211,6 +200,10 @@ static int initCCtx(adaptCCtx* ctx, unsigned numJobs)
ctx->jobCompressedID = 0; ctx->jobCompressedID = 0;
ctx->jobWriteID = 0; ctx->jobWriteID = 0;
ctx->lastDictSize = 0; ctx->lastDictSize = 0;
ctx->createCompletionMeasured = 1;
ctx->compressionCompletionMeasured = 1;
ctx->writeCompletionMeasured = 1;
ctx->jobs = calloc(1, numJobs*sizeof(jobDescription)); ctx->jobs = calloc(1, numJobs*sizeof(jobDescription));
if (!ctx->jobs) { if (!ctx->jobs) {
@ -305,17 +298,6 @@ static void waitUntilAllJobsCompleted(adaptCCtx* ctx)
pthread_mutex_unlock(&ctx->allJobsCompleted_mutex.pMutex); pthread_mutex_unlock(&ctx->allJobsCompleted_mutex.pMutex);
} }
/* this function normalizes counters when compression level is changing */
static void reduceCounters(adaptCCtx* ctx)
{
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
unsigned const min = MIN(ctx->stats.compressedCounter, MIN(ctx->stats.writeCounter, ctx->stats.readyCounter));
ctx->stats.writeCounter -= min;
ctx->stats.compressedCounter -= min;
ctx->stats.readyCounter -= min;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
}
/* /*
* Compression level is changed depending on which part of the compression process is lagging * Compression level is changed depending on which part of the compression process is lagging
* Currently, three theads exist for job creation, compression, and file writing respectively. * Currently, three theads exist for job creation, compression, and file writing respectively.
@ -330,67 +312,42 @@ static void adaptCompressionLevel(adaptCCtx* ctx)
ctx->compressionLevel = g_compressionLevel; ctx->compressionLevel = g_compressionLevel;
} }
else { else {
unsigned reset = 0; DEBUG(2, "compression level %u\n", ctx->compressionLevel);
unsigned allSlow; /* check if compression is too slow */
unsigned compressWaiting; unsigned createChange;
unsigned writeWaiting; unsigned writeChange;
unsigned createWaiting; unsigned compressionChange;
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
createChange = MAX_COMPRESSION_LEVEL_CHANGE - ctx->createCompletionMeasured * MAX_COMPRESSION_LEVEL_CHANGE;
writeChange = MAX_COMPRESSION_LEVEL_CHANGE - ctx->writeCompletionMeasured * MAX_COMPRESSION_LEVEL_CHANGE;
compressionChange = MAX_COMPRESSION_LEVEL_CHANGE - ctx->compressionCompletionMeasured * MAX_COMPRESSION_LEVEL_CHANGE;
DEBUG(2, "createCompletionMeasured %f\n", ctx->createCompletionMeasured);
DEBUG(2, "compressionCompletionMeasured %f\n", ctx->compressionCompletionMeasured);
DEBUG(2, "writeCompletionMeasured %f\n", ctx->writeCompletionMeasured);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
allSlow = ctx->adaptParam < ctx->stats.compressedCounter && ctx->adaptParam < ctx->stats.writeCounter && ctx->adaptParam < ctx->stats.readyCounter;
compressWaiting = ctx->adaptParam < ctx->stats.readyCounter;
writeWaiting = ctx->adaptParam < ctx->stats.compressedCounter;
createWaiting = ctx->adaptParam < ctx->stats.writeCounter;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
DEBUG(2, "createWaiting %u\n", createWaiting);
DEBUG(2, "compressWaiting %u\n", compressWaiting);
DEBUG(2, "writeWaiting %u\n\n", writeWaiting);
{ {
unsigned const writeSlow = (compressWaiting && createWaiting); unsigned const compressionFastChange = MIN(MIN(createChange, writeChange), ZSTD_maxCLevel() - ctx->compressionLevel);
unsigned const compressSlow = (writeWaiting && createWaiting); DEBUG(2, "compressionFastChange %u\n", compressionFastChange);
unsigned const createSlow = (compressWaiting && writeWaiting);
DEBUG(3, "createWaiting: %u, compressWaiting: %u, writeWaiting: %u\n", createWaiting, compressWaiting, writeWaiting); if (compressionFastChange) {
if (allSlow) { DEBUG(2, "compression level too low\n");
reset = 1; ctx->compressionLevel += compressionFastChange;
} }
else if ((writeSlow || createSlow) && ctx->compressionLevel < (unsigned)ZSTD_maxCLevel()) { else {
DEBUG(2, "increasing compression level %u\n", ctx->compressionLevel); unsigned const compressionSlowChange = MIN(compressionChange, ctx->compressionLevel-1);
double completion; DEBUG(2, "compression level too high\n");
pthread_mutex_lock(&ctx->completion_mutex.pMutex); ctx->compressionLevel -= compressionSlowChange;
completion = writeSlow ? ctx->writeCompletionMeasured : ctx->createCompletionMeasured;
DEBUG(2, "write completion: %f, create completion: %f\n", ctx->writeCompletionMeasured, ctx->createCompletionMeasured);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
{
unsigned const maxChange = MAX_COMPRESSION_LEVEL_CHANGE - (unsigned)(completion*MAX_COMPRESSION_LEVEL_CHANGE);
unsigned const change = MIN(maxChange, ZSTD_maxCLevel() - ctx->compressionLevel);
DEBUG(3, "writeSlow: %u, change: %u\n", writeSlow, change);
DEBUG(3, "write completion: %f\n", completion);
ctx->compressionLevel += change;
reset = 1;
}
}
else if (compressSlow && ctx->compressionLevel > 1) {
double completion;
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
completion = ctx->compressionCompletionMeasured;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
{
unsigned const maxChange = MAX_COMPRESSION_LEVEL_CHANGE - (unsigned)(completion*MAX_COMPRESSION_LEVEL_CHANGE);
unsigned const change = MIN(maxChange, ctx->compressionLevel - 1);
DEBUG(2, "decreasing compression level %u\n", ctx->compressionLevel);
DEBUG(2, "completion: %f\n", completion);
ctx->compressionLevel -= change;
reset = 1;
}
}
if (reset) {
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
ctx->stats.readyCounter = 0;
ctx->stats.writeCounter = 0;
ctx->stats.compressedCounter = 0;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
} }
} }
/* reset */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->createCompletionMeasured = 1;
ctx->compressionCompletionMeasured = 1;
ctx->writeCompletionMeasured = 1;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(2, "\n");
} }
} }
@ -410,21 +367,31 @@ static void* compressionThread(void* arg)
unsigned const currJobIndex = currJob % ctx->numJobs; unsigned const currJobIndex = currJob % ctx->numJobs;
jobDescription* job = &ctx->jobs[currJobIndex]; jobDescription* job = &ctx->jobs[currJobIndex];
DEBUG(3, "compressionThread(): waiting on job ready\n"); DEBUG(3, "compressionThread(): waiting on job ready\n");
/* new job, reset completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->compressionCompletion = 0;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
pthread_mutex_lock(&ctx->jobReady_mutex.pMutex); pthread_mutex_lock(&ctx->jobReady_mutex.pMutex);
while(currJob + 1 > ctx->jobReadyID && !ctx->threadError) { while(currJob + 1 > ctx->jobReadyID && !ctx->threadError) {
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
ctx->stats.waitReady++;
ctx->stats.readyCounter++;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
reduceCounters(ctx);
pthread_mutex_lock(&ctx->completion_mutex.pMutex); pthread_mutex_lock(&ctx->completion_mutex.pMutex);
/* compression thread is waiting, take measurements of write completion and read completion */
ctx->createCompletionMeasured = ctx->createCompletion; ctx->createCompletionMeasured = ctx->createCompletion;
ctx->writeCompletionMeasured = ctx->writeCompletion;
DEBUG(2, "compression thread waiting : createCompletionMeasured %f : writeCompletionMeasured %f\n", ctx->createCompletionMeasured, ctx->writeCompletionMeasured);
DEBUG(3, "create completion: %f\n", ctx->createCompletion); DEBUG(3, "create completion: %f\n", ctx->createCompletion);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex); pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "waiting on job ready, nextJob: %u\n", currJob); DEBUG(3, "waiting on job ready, nextJob: %u\n", currJob);
pthread_cond_wait(&ctx->jobReady_cond.pCond, &ctx->jobReady_mutex.pMutex); pthread_cond_wait(&ctx->jobReady_cond.pCond, &ctx->jobReady_mutex.pMutex);
} }
pthread_mutex_unlock(&ctx->jobReady_mutex.pMutex); pthread_mutex_unlock(&ctx->jobReady_mutex.pMutex);
/* reset create completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->createCompletion = 0;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "compressionThread(): continuing after job ready\n"); DEBUG(3, "compressionThread(): continuing after job ready\n");
DEBUG(3, "DICTIONARY ENDED\n"); DEBUG(3, "DICTIONARY ENDED\n");
DEBUG(3, "%.*s", (int)job->src.size, (char*)job->src.start); DEBUG(3, "%.*s", (int)job->src.size, (char*)job->src.start);
@ -497,7 +464,7 @@ static void* compressionThread(void* arg)
/* update completion */ /* update completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex); pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->compressionCompletion = 1 - (double)remaining/job->src.size; ctx->compressionCompletion = 1 - (double)remaining/job->src.size;
DEBUG(2, "update on job %u: compression completion %f\n", currJob, ctx->compressionCompletion); DEBUG(3, "update on job %u: compression completion %f\n", currJob, ctx->compressionCompletion);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex); pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
} }
} while (remaining != 0); } while (remaining != 0);
@ -547,21 +514,29 @@ static void* outputThread(void* arg)
unsigned const currJobIndex = currJob % ctx->numJobs; unsigned const currJobIndex = currJob % ctx->numJobs;
jobDescription* job = &ctx->jobs[currJobIndex]; jobDescription* job = &ctx->jobs[currJobIndex];
DEBUG(3, "outputThread(): waiting on job compressed\n"); DEBUG(3, "outputThread(): waiting on job compressed\n");
/* new job, reset completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->writeCompletion = 0;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
pthread_mutex_lock(&ctx->jobCompressed_mutex.pMutex); pthread_mutex_lock(&ctx->jobCompressed_mutex.pMutex);
while (currJob + 1 > ctx->jobCompressedID && !ctx->threadError) { while (currJob + 1 > ctx->jobCompressedID && !ctx->threadError) {
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
ctx->stats.waitCompressed++;
ctx->stats.compressedCounter++;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
reduceCounters(ctx);
pthread_mutex_lock(&ctx->completion_mutex.pMutex); pthread_mutex_lock(&ctx->completion_mutex.pMutex);
/* write thread is waiting, take measurement of compression completion */
ctx->compressionCompletionMeasured = ctx->compressionCompletion; ctx->compressionCompletionMeasured = ctx->compressionCompletion;
DEBUG(2, "waited on job %u: compressionCompletion %f\n", currJob, ctx->compressionCompletion); DEBUG(2, "write thread waiting : compressionCompletionMeasured %f\n", ctx->compressionCompletionMeasured);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex); pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "waiting on job compressed, nextJob: %u\n", currJob); DEBUG(3, "waiting on job compressed, nextJob: %u\n", currJob);
pthread_cond_wait(&ctx->jobCompressed_cond.pCond, &ctx->jobCompressed_mutex.pMutex); pthread_cond_wait(&ctx->jobCompressed_cond.pCond, &ctx->jobCompressed_mutex.pMutex);
} }
pthread_mutex_unlock(&ctx->jobCompressed_mutex.pMutex); pthread_mutex_unlock(&ctx->jobCompressed_mutex.pMutex);
/* reset compression completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->compressionCompletion = 0;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "outputThread(): continuing after job compressed\n"); DEBUG(3, "outputThread(): continuing after job compressed\n");
{ {
size_t const compressedSize = job->compressedSize; size_t const compressedSize = job->compressedSize;
@ -615,6 +590,7 @@ static void* outputThread(void* arg)
pthread_mutex_unlock(&ctx->allJobsCompleted_mutex.pMutex); pthread_mutex_unlock(&ctx->allJobsCompleted_mutex.pMutex);
break; break;
} }
} }
return arg; return arg;
} }
@ -628,19 +604,21 @@ static int createCompressionJob(adaptCCtx* ctx, size_t srcSize, int last)
pthread_mutex_lock(&ctx->jobWrite_mutex.pMutex); pthread_mutex_lock(&ctx->jobWrite_mutex.pMutex);
DEBUG(3, "Creating new compression job -- nextJob: %u, jobCompressedID: %u, jobWriteID: %u, numJObs: %u\n", nextJob,ctx->jobCompressedID, ctx->jobWriteID, ctx->numJobs); DEBUG(3, "Creating new compression job -- nextJob: %u, jobCompressedID: %u, jobWriteID: %u, numJObs: %u\n", nextJob,ctx->jobCompressedID, ctx->jobWriteID, ctx->numJobs);
while (nextJob - ctx->jobWriteID >= ctx->numJobs && !ctx->threadError) { while (nextJob - ctx->jobWriteID >= ctx->numJobs && !ctx->threadError) {
pthread_mutex_lock(&ctx->stats_mutex.pMutex);
ctx->stats.waitWrite++;
ctx->stats.writeCounter++;
pthread_mutex_unlock(&ctx->stats_mutex.pMutex);
reduceCounters(ctx);
pthread_mutex_lock(&ctx->completion_mutex.pMutex); pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->writeCompletionMeasured = ctx->writeCompletion; /* creation thread is waiting, take measurement of compression completion */
ctx->compressionCompletionMeasured = ctx->compressionCompletion;
DEBUG(2, "creation thread waiting : compression completion measured : %f\n", ctx->compressionCompletionMeasured);
DEBUG(3, "writeCompletion: %f\n", ctx->writeCompletion); DEBUG(3, "writeCompletion: %f\n", ctx->writeCompletion);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex); pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "waiting on job Write, nextJob: %u\n", nextJob); DEBUG(3, "waiting on job Write, nextJob: %u\n", nextJob);
pthread_cond_wait(&ctx->jobWrite_cond.pCond, &ctx->jobWrite_mutex.pMutex); pthread_cond_wait(&ctx->jobWrite_cond.pCond, &ctx->jobWrite_mutex.pMutex);
} }
pthread_mutex_unlock(&ctx->jobWrite_mutex.pMutex); pthread_mutex_unlock(&ctx->jobWrite_mutex.pMutex);
/* reset write completion */
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->writeCompletion = 0;
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
DEBUG(3, "createCompressionJob(): continuing after job write\n"); DEBUG(3, "createCompressionJob(): continuing after job write\n");
DEBUG(3, "filled: %zu, srcSize: %zu\n", ctx->input.filled, srcSize); DEBUG(3, "filled: %zu, srcSize: %zu\n", ctx->input.filled, srcSize);
@ -677,14 +655,6 @@ static int createCompressionJob(adaptCCtx* ctx, size_t srcSize, int last)
return 0; return 0;
} }
static void printStats(cStat_t stats)
{
DISPLAY("========STATISTICS========\n");
DISPLAY("# times waited on job ready: %u\n", stats.waitReady);
DISPLAY("# times waited on job compressed: %u\n", stats.waitCompressed);
DISPLAY("# times waited on job Write: %u\n\n", stats.waitWrite);
}
static int performCompression(adaptCCtx* ctx, FILE* const srcFile, outputThreadArg* otArg) static int performCompression(adaptCCtx* ctx, FILE* const srcFile, outputThreadArg* otArg)
{ {
if (!ctx || !srcFile || !otArg) { if (!ctx || !srcFile || !otArg) {
@ -710,48 +680,56 @@ static int performCompression(adaptCCtx* ctx, FILE* const srcFile, outputThreadA
return 1; return 1;
} }
} }
{
unsigned currJob = 0;
/* creating jobs */
for ( ; ; ) {
size_t pos = 0;
size_t const readBlockSize = 1 << 15;
size_t remaining = FILE_CHUNK_SIZE;
/* creating jobs */ /* new job reset completion */
for ( ; ; ) { pthread_mutex_lock(&ctx->completion_mutex.pMutex);
size_t pos = 0; ctx->createCompletion = 0;
size_t const readBlockSize = 1 << 15; pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
size_t remaining = FILE_CHUNK_SIZE;
while (remaining != 0 && !feof(srcFile)) { while (remaining != 0 && !feof(srcFile)) {
size_t const ret = fread(ctx->input.buffer.start + ctx->input.filled + pos, 1, readBlockSize, srcFile); size_t const ret = fread(ctx->input.buffer.start + ctx->input.filled + pos, 1, readBlockSize, srcFile);
if (ret != readBlockSize && !feof(srcFile)) { if (ret != readBlockSize && !feof(srcFile)) {
/* error could not read correct number of bytes */ /* error could not read correct number of bytes */
DISPLAY("Error: problem occurred during read from src file\n");
signalErrorToThreads(ctx);
return 1;
}
pos += ret;
remaining -= ret;
pthread_mutex_lock(&ctx->completion_mutex.pMutex);
ctx->createCompletion = 1 - (double)remaining/((size_t)FILE_CHUNK_SIZE);
DEBUG(3, "create completion: %f\n", ctx->createCompletion);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex);
}
if (remaining != 0 && !feof(srcFile)) {
DISPLAY("Error: problem occurred during read from src file\n"); DISPLAY("Error: problem occurred during read from src file\n");
signalErrorToThreads(ctx); signalErrorToThreads(ctx);
return 1; return 1;
} }
pos += ret; g_streamedSize += pos;
remaining -= ret; /* reading was fine, now create the compression job */
pthread_mutex_lock(&ctx->completion_mutex.pMutex); {
ctx->createCompletion = 1 - (double)remaining/((size_t)FILE_CHUNK_SIZE); int const last = feof(srcFile);
DEBUG(3, "create completion: %f\n", ctx->createCompletion); int const error = createCompressionJob(ctx, pos, last);
pthread_mutex_unlock(&ctx->completion_mutex.pMutex); if (error != 0) {
} signalErrorToThreads(ctx);
if (remaining != 0 && !feof(srcFile)) { return error;
DISPLAY("Error: problem occurred during read from src file\n"); }
signalErrorToThreads(ctx); }
return 1; currJob++;
} if (feof(srcFile)) {
g_streamedSize += pos; DEBUG(3, "THE STREAM OF DATA ENDED %u\n", ctx->nextJobID);
/* reading was fine, now create the compression job */ break;
{
int const last = feof(srcFile);
int const error = createCompressionJob(ctx, pos, last);
if (error != 0) {
signalErrorToThreads(ctx);
return error;
} }
} }
if (feof(srcFile)) {
DEBUG(3, "THE STREAM OF DATA ENDED %u\n", ctx->nextJobID);
break;
}
} }
/* success -- created all jobs */ /* success -- created all jobs */
return 0; return 0;
} }
@ -803,9 +781,6 @@ static int freeFileCompressionResources(fcResources* fcr)
{ {
int ret = 0; int ret = 0;
waitUntilAllJobsCompleted(fcr->ctx); waitUntilAllJobsCompleted(fcr->ctx);
pthread_mutex_lock(&fcr->ctx->stats_mutex.pMutex);
if (g_displayStats) printStats(fcr->ctx->stats);
pthread_mutex_unlock(&fcr->ctx->stats_mutex.pMutex);
ret |= (fcr->srcFile != NULL) ? fclose(fcr->srcFile) : 0; ret |= (fcr->srcFile != NULL) ? fclose(fcr->srcFile) : 0;
ret |= (fcr->ctx != NULL) ? freeCCtx(fcr->ctx) : 0; ret |= (fcr->ctx != NULL) ? freeCCtx(fcr->ctx) : 0;
if (fcr->otArg) { if (fcr->otArg) {
@ -873,7 +848,6 @@ static void help()
PRINT(" -oFILE : specify the output file name\n"); PRINT(" -oFILE : specify the output file name\n");
PRINT(" -v : display debug information\n"); PRINT(" -v : display debug information\n");
PRINT(" -i# : provide initial compression level\n"); PRINT(" -i# : provide initial compression level\n");
PRINT(" -s : display information stats\n");
PRINT(" -h : display help/information\n"); PRINT(" -h : display help/information\n");
PRINT(" -f : force the compression level to stay constant\n"); PRINT(" -f : force the compression level to stay constant\n");
} }
@ -913,9 +887,6 @@ int main(int argCount, const char* argv[])
g_compressionLevel = readU32FromChar(&argument); g_compressionLevel = readU32FromChar(&argument);
DEBUG(3, "g_compressionLevel: %u\n", g_compressionLevel); DEBUG(3, "g_compressionLevel: %u\n", g_compressionLevel);
break; break;
case 's':
g_displayStats = 1;
break;
case 'h': case 'h':
help(); help();
goto _main_exit; goto _main_exit;