]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Make paramgrill use bench.c benchmarking
authorGeorge Lu <gclu@fb.com>
Mon, 4 Jun 2018 23:32:37 +0000 (16:32 -0700)
committerGeorge Lu <gclu@fb.com>
Fri, 8 Jun 2018 19:01:05 +0000 (12:01 -0700)
programs/bench.c
programs/bench.h
tests/Makefile
tests/paramgrill.c
tests/playTests.sh

index 014a4fd41b1cf01b00baa8ad228f88ae8dd6a9a4..6a81cc8f2b3755292ab602782c764fd9af3bd1ea 100644 (file)
@@ -41,6 +41,7 @@
 #include "zstd.h"
 #include "datagen.h"     /* RDG_genBuffer */
 #include "xxhash.h"
+#include "bench.h"
 
 
 /* *************************************
@@ -71,6 +72,7 @@ static U32 g_compressibilityDefault = 50;
 ***************************************/
 #define DISPLAY(...)         fprintf(stderr, __VA_ARGS__)
 #define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
+#define DISPLAYLEVELP(l, ...) if (g_displayLevel>=l && printable) { DISPLAY(__VA_ARGS__); }
 static int g_displayLevel = 2;   /* 0 : no display;   1: errors;   2 : + result + interaction + warnings;   3 : + progression;   4 : + information */
 
 static const U64 g_refreshRate = SEC_TO_MICRO / 6;
@@ -91,9 +93,9 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
 #define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
 #define EXM_THROW(error, ...)  {                      \
     DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__);    \
-    DISPLAYLEVEL(1, "Error %i : ", error);            \
-    DISPLAYLEVEL(1, __VA_ARGS__);                     \
-    DISPLAYLEVEL(1, " \n");                           \
+    DISPLAYLEVELP(1, "Error %i : ", error);            \
+    DISPLAYLEVELP(1, __VA_ARGS__);                     \
+    DISPLAYLEVELP(1, " \n");                           \
     exit(error);                                      \
 }
 
@@ -168,7 +170,6 @@ void BMK_setLdmHashEveryLog(unsigned ldmHashEveryLog) {
     g_ldmHashEveryLog = ldmHashEveryLog;
 }
 
-
 /* ********************************************************
 *  Bench functions
 **********************************************************/
@@ -182,18 +183,17 @@ typedef struct {
     size_t resSize;
 } blockParam_t;
 
-
-
 #undef MIN
 #undef MAX
 #define MIN(a,b)    ((a) < (b) ? (a) : (b))
 #define MAX(a,b)    ((a) > (b) ? (a) : (b))
 
-static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
+BMK_result_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
                         const char* displayName, int cLevel,
                         const size_t* fileSizes, U32 nbFiles,
                         const void* dictBuffer, size_t dictBufferSize,
-                        const ZSTD_compressionParameters* const comprParams)
+                        const ZSTD_compressionParameters* const comprParams, 
+                        ZSTD_CCtx* ctx, ZSTD_DCtx* dctx, int printable)
 {
     size_t const blockSize = ((g_blockSize>=32 && !g_decodeOnly) ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ;
     U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles;
@@ -201,13 +201,16 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
     size_t const maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024);   /* add some room for safety */
     void* const compressedBuffer = malloc(maxCompressedSize);
     void* resultBuffer = malloc(srcSize);
-    ZSTD_CCtx* const ctx = ZSTD_createCCtx();
-    ZSTD_DCtx* const dctx = ZSTD_createDCtx();
+    BMK_result_t results;
+
     size_t const loadedCompressedSize = srcSize;
     size_t cSize = 0;
     double ratio = 0.;
     U32 nbBlocks;
 
+    assert(ctx != NULL);
+    assert(dctx != NULL);
+
     /* checks */
     if (!compressedBuffer || !resultBuffer || !blockTable || !ctx || !dctx)
         EXM_THROW(31, "allocation error : not enough memory");
@@ -281,19 +284,19 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
         U32 markNb = 0;
 
         coolTime = UTIL_getTime();
-        DISPLAYLEVEL(2, "\r%79s\r", "");
+        DISPLAYLEVELP(2, "\r%79s\r", "");
         while (!cCompleted || !dCompleted) {
 
             /* overheat protection */
             if (UTIL_clockSpanMicro(coolTime) > ACTIVEPERIOD_MICROSEC) {
-                DISPLAYLEVEL(2, "\rcooling down ...    \r");
+                DISPLAYLEVELP(2, "\rcooling down ...    \r");
                 UTIL_sleep(COOLPERIOD_SEC);
                 coolTime = UTIL_getTime();
             }
 
             if (!g_decodeOnly) {
                 /* Compression */
-                DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize);
+                DISPLAYLEVELP(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize);
                 if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize);  /* warm up and erase result buffer */
 
                 UTIL_sleepMilli(5);  /* give processor time to other processes */
@@ -369,11 +372,13 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                 cSize = 0;
                 { U32 blockNb; for (blockNb=0; blockNb<nbBlocks; blockNb++) cSize += blockTable[blockNb].cSize; }
                 ratio = (double)srcSize / (double)cSize;
+                results.cSize = cSize;
                 markNb = (markNb+1) % NB_MARKS;
                 {   int const ratioAccuracy = (ratio < 10.) ? 3 : 2;
                     double const compressionSpeed = ((double)srcSize / fastestC) * 1000;
                     int const cSpeedAccuracy = (compressionSpeed < 10.) ? 2 : 1;
-                    DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s\r",
+                    results.cSpeed = compressionSpeed * 1000000;
+                    DISPLAYLEVELP(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s\r",
                             marks[markNb], displayName, (U32)srcSize, (U32)cSize,
                             ratioAccuracy, ratio,
                             cSpeedAccuracy, compressionSpeed );
@@ -428,7 +433,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                 double const compressionSpeed = ((double)srcSize / fastestC) * 1000;
                 int const cSpeedAccuracy = (compressionSpeed < 10.) ? 2 : 1;
                 double const decompressionSpeed = ((double)srcSize / fastestD) * 1000;
-                DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s ,%6.1f MB/s \r",
+                results.cSpeed = compressionSpeed * 1000000;
+                results.dSpeed = decompressionSpeed * 1000000;
+                DISPLAYLEVELP(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s ,%6.1f MB/s \r",
                         marks[markNb], displayName, (U32)srcSize, (U32)cSize,
                         ratioAccuracy, ratio,
                         cSpeedAccuracy, compressionSpeed,
@@ -483,19 +490,68 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
             else
                 DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s  %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName);
         }
-        DISPLAYLEVEL(2, "%2i#\n", cLevel);
+        DISPLAYLEVELP(2, "%2i#\n", cLevel);
     }   /* Bench */
 
     /* clean up */
     free(blockTable);
     free(compressedBuffer);
     free(resultBuffer);
+    return results;
+}
+
+/* 
+ *  combines multiple results into single 
+ *  currently normal averaging
+ *  consider weighing by file size? or maybe by total time? 
+ *  size is cumulative though
+ */
+static BMK_result_t BMK_average(BMK_result_t* results, const int count, const size_t* sampleSizes) {
+    double cSpeedTotal = 0;
+    double dSpeedTotal = 0;
+    size_t cSizeTotal = 0;
+    BMK_result_t returnval;
+    int i;
+    if (sampleSizes == NULL) {
+        for(i = 0; i < count; i++) {
+            cSpeedTotal += results[i].cSpeed;
+            dSpeedTotal += results[i].dSpeed;
+            cSizeTotal += results[i].cSize;
+        }
+        returnval.cSpeed = cSpeedTotal / count;
+        returnval.dSpeed = dSpeedTotal / count;
+        returnval.cSize = cSizeTotal;
+    } else {
+        size_t sSizeTotal = 0;
+        /* in this case, SpeedTotal will keep track of total time used */
+        for(i = 0; i < count; i++) {
+            cSpeedTotal += sampleSizes[i] / results[i].cSpeed;
+            dSpeedTotal += sampleSizes[i] / results[i].cSpeed;
+            cSizeTotal += results[i].cSize;
+            sSizeTotal += sampleSizes[i];
+        }
+        returnval.cSpeed = (double)sSizeTotal / cSpeedTotal;
+        returnval.dSpeed = (double)sSizeTotal / dSpeedTotal;
+        returnval.cSize = cSizeTotal;
+    }
+    return returnval;
+}
+
+static BMK_result_t BMK_benchMemCtxless(const void* srcBuffer, size_t srcSize,
+                        const char* displayName, int cLevel,
+                        const size_t* fileSizes, U32 nbFiles,
+                        const void* dictBuffer, size_t dictBufferSize,
+                        const ZSTD_compressionParameters* const comprParams, int printable) 
+{
+    BMK_result_t returnval;
+    ZSTD_CCtx* ctx = ZSTD_createCCtx();
+    ZSTD_DCtx* dctx = ZSTD_createDCtx();
+    returnval = BMK_benchMem(srcBuffer, srcSize, displayName, cLevel, fileSizes, nbFiles, dictBuffer, dictBufferSize, comprParams, ctx, dctx, printable);
     ZSTD_freeCCtx(ctx);
     ZSTD_freeDCtx(dctx);
-    return 0;
+    return returnval;
 }
 
-
 static size_t BMK_findMaxMem(U64 requiredMem)
 {
     size_t const step = 64 MB;
@@ -514,20 +570,28 @@ static size_t BMK_findMaxMem(U64 requiredMem)
     return (size_t)(requiredMem);
 }
 
-static void BMK_benchCLevel(const void* srcBuffer, size_t benchedSize,
+/* returns average stats over all range [cLevel, cLevelLast] */
+static BMK_result_t BMK_benchCLevel(const void* srcBuffer, size_t benchedSize,
                             const char* displayName, int cLevel, int cLevelLast,
                             const size_t* fileSizes, unsigned nbFiles,
                             const void* dictBuffer, size_t dictBufferSize,
-                            const ZSTD_compressionParameters* const compressionParams)
+                            const ZSTD_compressionParameters* const compressionParams,
+                            int printable)
 {
     int l;
+    BMK_result_t returnval;
+    BMK_result_t* resultarray = (BMK_result_t*)malloc(sizeof(BMK_result_t) * (cLevelLast - cLevel + 1));
 
     const char* pch = strrchr(displayName, '\\'); /* Windows */
     if (!pch) pch = strrchr(displayName, '/'); /* Linux */
     if (pch) displayName = pch+1;
+    if(resultarray == NULL) EXM_THROW(12, "Not enough memory"); 
+    returnval.cSpeed = 0;
+    returnval.dSpeed = 0;
+    returnval.cSize = 0;
 
     if (g_realTime) {
-        DISPLAYLEVEL(2, "Note : switching to real-time priority \n");
+        DISPLAYLEVELP(2, "Note : switching to real-time priority \n");
         SET_REALTIME_PRIORITY;
     }
 
@@ -536,11 +600,13 @@ static void BMK_benchCLevel(const void* srcBuffer, size_t benchedSize,
 
     for (l=cLevel; l <= cLevelLast; l++) {
         if (l==0) continue;  /* skip level 0 */
-        BMK_benchMem(srcBuffer, benchedSize,
-                     displayName, l,
-                     fileSizes, nbFiles,
-                     dictBuffer, dictBufferSize, compressionParams);
+        resultarray[l - cLevel] = BMK_benchMemCtxless(srcBuffer, benchedSize,
+                    displayName, l, fileSizes, nbFiles,
+                    dictBuffer, dictBufferSize, compressionParams, printable);
     }
+    returnval = BMK_average(resultarray, cLevelLast - cLevel + 1, NULL);
+    free(resultarray);
+    return returnval;
 }
 
 
@@ -548,8 +614,8 @@ static void BMK_benchCLevel(const void* srcBuffer, size_t benchedSize,
  *  Loads `buffer` with content of files listed within `fileNamesTable`.
  *  At most, fills `buffer` entirely. */
 static void BMK_loadFiles(void* buffer, size_t bufferSize,
-                          size_t* fileSizes,
-                          const char* const * const fileNamesTable, unsigned nbFiles)
+                          size_t* fileSizes, const char* const * const fileNamesTable, 
+                          unsigned nbFiles, int printable)
 {
     size_t pos = 0, totalSize = 0;
     unsigned n;
@@ -557,12 +623,12 @@ static void BMK_loadFiles(void* buffer, size_t bufferSize,
         FILE* f;
         U64 fileSize = UTIL_getFileSize(fileNamesTable[n]);
         if (UTIL_isDirectory(fileNamesTable[n])) {
-            DISPLAYLEVEL(2, "Ignoring %s directory...       \n", fileNamesTable[n]);
+            DISPLAYLEVELP(2, "Ignoring %s directory...       \n", fileNamesTable[n]);
             fileSizes[n] = 0;
             continue;
         }
         if (fileSize == UTIL_FILESIZE_UNKNOWN) {
-            DISPLAYLEVEL(2, "Cannot evaluate size of %s, ignoring ... \n", fileNamesTable[n]);
+            DISPLAYLEVELP(2, "Cannot evaluate size of %s, ignoring ... \n", fileNamesTable[n]);
             fileSizes[n] = 0;
             continue;
         }
@@ -581,16 +647,16 @@ static void BMK_loadFiles(void* buffer, size_t bufferSize,
     if (totalSize == 0) EXM_THROW(12, "no data to bench");
 }
 
-static void BMK_benchFileTable(const char* const * const fileNamesTable, unsigned const nbFiles,
-                               const char* const dictFileName,
-                               int const cLevel, int const cLevelLast,
-                               const ZSTD_compressionParameters* const compressionParams)
+static BMK_result_t BMK_benchFileTable(const char* const * const fileNamesTable, unsigned const nbFiles,
+                               const char* const dictFileName, int const cLevel, int const cLevelLast,
+                               const ZSTD_compressionParameters* const compressionParams, int printable)
 {
     void* srcBuffer;
     size_t benchedSize;
     void* dictBuffer = NULL;
     size_t dictBufferSize = 0;
     size_t* const fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
+    BMK_result_t returnval;
     U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
 
     if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes");
@@ -605,7 +671,7 @@ static void BMK_benchFileTable(const char* const * const fileNamesTable, unsigne
         if (dictBuffer==NULL)
             EXM_THROW(11, "not enough memory for dictionary (%u bytes)",
                             (U32)dictBufferSize);
-        BMK_loadFiles(dictBuffer, dictBufferSize, fileSizes, &dictFileName, 1);
+        BMK_loadFiles(dictBuffer, dictBufferSize, fileSizes, &dictFileName, 1, printable);
     }
 
     /* Memory allocation & restrictions */
@@ -617,43 +683,50 @@ static void BMK_benchFileTable(const char* const * const fileNamesTable, unsigne
     if (!srcBuffer) EXM_THROW(12, "not enough memory");
 
     /* Load input buffer */
-    BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
+    BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles, printable);
 
     /* Bench */
     if (g_separateFiles) {
         const BYTE* srcPtr = (const BYTE*)srcBuffer;
         U32 fileNb;
+        BMK_result_t* resultarray = (BMK_result_t*)malloc(sizeof(BMK_result_t) * nbFiles);
+        if(resultarray == NULL) EXM_THROW(12, "not enough memory");
         for (fileNb=0; fileNb<nbFiles; fileNb++) {
             size_t const fileSize = fileSizes[fileNb];
-            BMK_benchCLevel(srcPtr, fileSize,
+            resultarray[fileNb] = BMK_benchCLevel(srcPtr, fileSize,
                             fileNamesTable[fileNb], cLevel, cLevelLast,
-                            fileSizes+fileNb, 1,
-                            dictBuffer, dictBufferSize, compressionParams);
+                            fileSizes+fileNb, 1, dictBuffer, dictBufferSize, 
+                            compressionParams,printable);
             srcPtr += fileSize;
         }
+        returnval =  BMK_average(resultarray, nbFiles, fileSizes);
+        free(resultarray);
     } else {
         char mfName[20] = {0};
         snprintf (mfName, sizeof(mfName), " %u files", nbFiles);
         {   const char* const displayName = (nbFiles > 1) ? mfName : fileNamesTable[0];
-            BMK_benchCLevel(srcBuffer, benchedSize,
+            returnval =  BMK_benchCLevel(srcBuffer, benchedSize,
                             displayName, cLevel, cLevelLast,
-                            fileSizes, nbFiles,
-                            dictBuffer, dictBufferSize, compressionParams);
+                            fileSizes, nbFiles, dictBuffer, dictBufferSize, 
+                            compressionParams, printable);
     }   }
 
     /* clean up */
     free(srcBuffer);
     free(dictBuffer);
     free(fileSizes);
+    return returnval;
 }
 
 
-static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility,
-                              const ZSTD_compressionParameters* compressionParams)
+static BMK_result_t BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility,
+                              const ZSTD_compressionParameters* compressionParams,
+                              int printable)
 {
     char name[20] = {0};
     size_t benchedSize = 10000000;
     void* const srcBuffer = malloc(benchedSize);
+    BMK_result_t returnval;
 
     /* Memory allocation */
     if (!srcBuffer) EXM_THROW(21, "not enough memory");
@@ -663,17 +736,17 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility
 
     /* Bench */
     snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100));
-    BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, NULL, 0, compressionParams);
+    returnval = BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, NULL, 0, compressionParams, printable);
 
     /* clean up */
     free(srcBuffer);
+    return returnval;
 }
 
 
-int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
-                   const char* dictFileName,
-                   int cLevel, int cLevelLast,
-                   const ZSTD_compressionParameters* compressionParams)
+BMK_result_t BMK_benchFilesFull(const char** fileNamesTable, unsigned nbFiles,
+                   const char* dictFileName, int cLevel, int cLevelLast, 
+                   const ZSTD_compressionParameters* compressionParams, int printable)
 {
     double const compressibility = (double)g_compressibilityDefault / 100;
 
@@ -681,11 +754,18 @@ int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
     if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
     if (cLevelLast < cLevel) cLevelLast = cLevel;
     if (cLevelLast > cLevel)
-        DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast);
+        DISPLAYLEVELP(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast);
 
     if (nbFiles == 0)
-        BMK_syntheticTest(cLevel, cLevelLast, compressibility, compressionParams);
+        return BMK_syntheticTest(cLevel, cLevelLast, compressibility, compressionParams, printable);
     else
-        BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast, compressionParams);
+        return BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast, compressionParams, printable);
+}
+
+int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
+                   const char* dictFileName,
+                   int cLevel, int cLevelLast,
+                   const ZSTD_compressionParameters* compressionParams) {
+    BMK_benchFilesFull(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast, compressionParams, 1);
     return 0;
 }
index bf1087013feb1686b76889ca6c185c4cd0add598..3bb725243546ef92e66691721146c5233cf13d4c 100644 (file)
 #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_compressionParameters */
 #include "zstd.h"     /* ZSTD_compressionParameters */
 
+typedef struct {
+    size_t cSize;
+    double cSpeed;   /* bytes / sec */
+    double dSpeed;
+} BMK_result_t;
+
+/* called in cli */
 int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName,
                    int cLevel, int cLevelLast, const ZSTD_compressionParameters* compressionParams);
 
+/* more options */
+BMK_result_t BMK_benchFilesFull(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName,
+                   int cLevel, int cLevelLast, const ZSTD_compressionParameters* compressionParams,
+                   int printable);
+
+/* basic benchmarking function, called in paramgrill
+ * results, cctx, dctx, dictbuffer can be null or passed in */
+BMK_result_t BMK_benchMem(const void* srcBuffer, size_t srcSize, const char* displayName, int cLevel,
+                 const size_t* fileSizes, unsigned nbFiles, const void* dictBuffer, size_t dictBufferSize,
+                 const ZSTD_compressionParameters* const comprParams, ZSTD_CCtx* ctx, ZSTD_DCtx* dctx,
+                 int printable);
+
 /* Set Parameters */
 void BMK_setNbSeconds(unsigned nbLoops);
 void BMK_setBlockSize(size_t blockSize);
index c4cbe1bdfcd8f555d29867a41198a444d93ffe10..602bbe3351171957eeac466c716b26ef7a2d6fbf 100644 (file)
@@ -203,7 +203,7 @@ zstreamtest-dll : $(ZSTREAM_LOCAL_FILES)
        $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
 
 paramgrill : DEBUGFLAGS =   # turn off assert() for speed measurements
-paramgrill : $(ZSTD_FILES) $(PRGDIR)/datagen.c paramgrill.c
+paramgrill : $(ZSTD_FILES) $(PRGDIR)/bench.c $(PRGDIR)/datagen.c paramgrill.c
        $(CC) $(FLAGS) $^ -lm -o $@$(EXT)
 
 datagen : $(PRGDIR)/datagen.c datagencli.c
index 44e3cb37bdd7f49e114ebee2b368d83df67b3a74..7fd4513c41713dba2e41086d6b1599bf46a0604a 100644 (file)
@@ -26,6 +26,7 @@
 #include "datagen.h"
 #include "xxhash.h"
 #include "util.h"
+#include "bench.h"
 
 
 /*-************************************
@@ -48,12 +49,9 @@ static const size_t maxMemory = (sizeof(size_t)==4)  ?  (2 GB - 64 MB) : (size_t
 
 #define COMPRESSIBILITY_DEFAULT 0.50
 
-static const double g_grillDuration_s = 99999;   /* about 27 hours */
-static const U64 g_maxParamTime = 15 * SEC_TO_MICRO;
 static const U64 g_maxVariationTime = 60 * SEC_TO_MICRO;
 static const int g_maxNbVariations = 64;
 
-
 /*-************************************
 *  Macros
 **************************************/
@@ -63,11 +61,13 @@ static const int g_maxNbVariations = 64;
 #undef MAX
 #define MIN(a,b)   ( (a) < (b) ? (a) : (b) )
 #define MAX(a,b)   ( (a) > (b) ? (a) : (b) )
-
+#define CUSTOM_LEVEL 99
 
 /*-************************************
 *  Benchmark Parameters
 **************************************/
+
+static double g_grillDuration_s = 99999;   /* about 27 hours */
 static U32 g_nbIterations = NBLOOPS;
 static double g_compressibility = COMPRESSIBILITY_DEFAULT;
 static U32 g_blockSize = 0;
@@ -83,7 +83,6 @@ void BMK_SetNbIterations(int nbLoops)
     DISPLAY("- %u iterations -\n", g_nbIterations);
 }
 
-
 /*-*******************************************************
 *  Private functions
 *********************************************************/
@@ -144,11 +143,6 @@ static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
 /*-*******************************************************
 *  Bench functions
 *********************************************************/
-typedef struct {
-    size_t cSize;
-    double cSpeed;   /* bytes / sec */
-    double dSpeed;
-} BMK_result_t;
 
 typedef struct
 {
@@ -162,176 +156,39 @@ typedef struct
 } blockParam_t;
 
 
+const char* g_stratName[ZSTD_btultra+1] = {
+                "(none)       ", "ZSTD_fast    ", "ZSTD_dfast   ",
+                "ZSTD_greedy  ", "ZSTD_lazy    ", "ZSTD_lazy2   ",
+                "ZSTD_btlazy2 ", "ZSTD_btopt   ", "ZSTD_btultra "};
+
+/* TODO: support additional parameters (more files, fileSizes) */
+
+//TODO: benchMem dctx can't = NULL in new system
 static size_t
 BMK_benchParam(BMK_result_t* resultPtr,
                const void* srcBuffer, size_t srcSize,
-               ZSTD_CCtx* ctx,
-               const ZSTD_compressionParameters cParams)
-{
-    const size_t blockSize = g_blockSize ? g_blockSize : srcSize;
-    const U32 nbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize);
-    blockParam_t* const blockTable = (blockParam_t*) malloc(nbBlocks * sizeof(blockParam_t));
-    const size_t maxCompressedSize = (size_t)nbBlocks * ZSTD_compressBound(blockSize);
-    void* const compressedBuffer = malloc(maxCompressedSize);
-    void* const resultBuffer = malloc(srcSize);
-    ZSTD_parameters params;
-    U32 Wlog = cParams.windowLog;
-    U32 Clog = cParams.chainLog;
-    U32 Hlog = cParams.hashLog;
-    U32 Slog = cParams.searchLog;
-    U32 Slength = cParams.searchLength;
-    U32 Tlength = cParams.targetLength;
-    ZSTD_strategy strat = cParams.strategy;
-    char name[30] = { 0 };
-    U64 crcOrig;
-
-    /* init result for early exit */
-    resultPtr->cSize = srcSize;
-    resultPtr->cSpeed = 0.;
-    resultPtr->dSpeed = 0.;
-
-    /* Memory allocation & restrictions */
-    snprintf(name, 30, "Sw%02uc%02uh%02us%02ul%1ut%03uS%1u", Wlog, Clog, Hlog, Slog, Slength, Tlength, strat);
-    if (!compressedBuffer || !resultBuffer || !blockTable) {
-        DISPLAY("\nError: not enough memory!\n");
-        free(compressedBuffer);
-        free(resultBuffer);
-        free(blockTable);
-        return 12;
-    }
+               ZSTD_CCtx* ctx, ZSTD_DCtx* dctx, 
+               const ZSTD_compressionParameters cParams) {
 
-    /* Calculating input Checksum */
-    crcOrig = XXH64(srcBuffer, srcSize, 0);
-
-    /* Init blockTable data */
-    {   U32 i;
-        size_t remaining = srcSize;
-        const char* srcPtr = (const char*)srcBuffer;
-        char* cPtr = (char*)compressedBuffer;
-        char* resPtr = (char*)resultBuffer;
-        for (i=0; i<nbBlocks; i++) {
-            size_t thisBlockSize = MIN(remaining, blockSize);
-            blockTable[i].srcPtr = srcPtr;
-            blockTable[i].cPtr = cPtr;
-            blockTable[i].resPtr = resPtr;
-            blockTable[i].srcSize = thisBlockSize;
-            blockTable[i].cRoom = ZSTD_compressBound(thisBlockSize);
-            srcPtr += thisBlockSize;
-            cPtr += blockTable[i].cRoom;
-            resPtr += thisBlockSize;
-            remaining -= thisBlockSize;
-    }   }
-
-    /* warmimg up memory */
-    RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.10, 1);
-
-    /* Bench */
-    {   U32 loopNb;
-        size_t cSize = 0;
-        double fastestC = 100000000., fastestD = 100000000.;
-        double ratio = 0.;
-        UTIL_time_t const benchStart = UTIL_getTime();
+    *resultPtr = BMK_benchMem(srcBuffer,srcSize, "File", 0, &srcSize, 1, 
+        NULL, 0, &cParams, ctx, dctx, 0);
 
-        DISPLAY("\r%79s\r", "");
-        memset(&params, 0, sizeof(params));
-        params.cParams = cParams;
-        for (loopNb = 1; loopNb <= g_nbIterations; loopNb++) {
-            int nbLoops;
-            U32 blockNb;
-            UTIL_time_t roundStart;
-            U64 roundClock;
-
-            { U64 const benchTime = UTIL_clockSpanMicro(benchStart);
-              if (benchTime > g_maxParamTime) break; }
-
-            /* Compression */
-            DISPLAY("\r%1u-%s : %9u ->", loopNb, name, (U32)srcSize);
-            memset(compressedBuffer, 0xE5, maxCompressedSize);
-
-            nbLoops = 0;
-            UTIL_waitForNextTick();
-            roundStart = UTIL_getTime();
-            while (UTIL_clockSpanMicro(roundStart) < TIMELOOP) {
-                for (blockNb=0; blockNb<nbBlocks; blockNb++)
-                    blockTable[blockNb].cSize = ZSTD_compress_advanced(ctx,
-                                                    blockTable[blockNb].cPtr,  blockTable[blockNb].cRoom,
-                                                    blockTable[blockNb].srcPtr, blockTable[blockNb].srcSize,
-                                                    NULL, 0,
-                                                    params);
-                nbLoops++;
-            }
-            roundClock = UTIL_clockSpanMicro(roundStart);
-
-            cSize = 0;
-            for (blockNb=0; blockNb<nbBlocks; blockNb++)
-                cSize += blockTable[blockNb].cSize;
-            ratio = (double)srcSize / (double)cSize;
-            if ((double)roundClock < fastestC * SEC_TO_MICRO * nbLoops) fastestC = ((double)roundClock / SEC_TO_MICRO) / nbLoops;
-            DISPLAY("\r");
-            DISPLAY("%1u-%s : %9u ->", loopNb, name, (U32)srcSize);
-            DISPLAY(" %9u (%4.3f),%7.1f MB/s", (U32)cSize, ratio, (double)srcSize / fastestC / 1000000.);
-            resultPtr->cSize = cSize;
-            resultPtr->cSpeed = (double)srcSize / fastestC;
-
-#if 1
-            /* Decompression */
-            memset(resultBuffer, 0xD6, srcSize);
-
-            nbLoops = 0;
-            UTIL_waitForNextTick();
-            roundStart = UTIL_getTime();
-            for ( ; UTIL_clockSpanMicro(roundStart) < TIMELOOP; nbLoops++) {
-                for (blockNb=0; blockNb<nbBlocks; blockNb++)
-                    blockTable[blockNb].resSize = ZSTD_decompress(blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
-                                                                  blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
-            }
-            roundClock = UTIL_clockSpanMicro(roundStart);
-
-            if ((double)roundClock < fastestD * SEC_TO_MICRO * nbLoops) fastestD = ((double)roundClock / SEC_TO_MICRO) / nbLoops;
-            DISPLAY("\r");
-            DISPLAY("%1u-%s : %9u -> ", loopNb, name, (U32)srcSize);
-            DISPLAY("%9u (%4.3f),%7.1f MB/s, ", (U32)cSize, ratio, (double)srcSize / fastestC / 1000000.);
-            DISPLAY("%7.1f MB/s", (double)srcSize / fastestD / 1000000.);
-            resultPtr->dSpeed = (double)srcSize / fastestD;
-
-            /* CRC Checking */
-            {   U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
-                if (crcOrig!=crcCheck) {
-                    unsigned u;
-                    unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize));
-                    DISPLAY("\n!!! WARNING !!! Invalid Checksum : %x != %x\n", (unsigned)crcOrig, (unsigned)crcCheck);
-                    for (u=0; u<srcSize; u++) {
-                        if (((const BYTE*)srcBuffer)[u] != ((BYTE*)resultBuffer)[u]) {
-                            printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize);
-                            break;
-                    }   }
-                    break;
-            }   }
-#endif
-    }   }
-
-    /* End cleaning */
-    DISPLAY("\r");
-    free(compressedBuffer);
-    free(resultBuffer);
     return 0;
 }
 
-
-const char* g_stratName[ZSTD_btultra+1] = {
-                "(none)       ", "ZSTD_fast    ", "ZSTD_dfast   ",
-                "ZSTD_greedy  ", "ZSTD_lazy    ", "ZSTD_lazy2   ",
-                "ZSTD_btlazy2 ", "ZSTD_btopt   ", "ZSTD_btultra "};
-
 static void BMK_printWinner(FILE* f, U32 cLevel, BMK_result_t result, ZSTD_compressionParameters params, size_t srcSize)
 {
+    char lvlstr[15] = "Custom Level";
     DISPLAY("\r%79s\r", "");
     fprintf(f,"    {%3u,%3u,%3u,%3u,%3u,%3u, %s },  ",
             params.windowLog, params.chainLog, params.hashLog, params.searchLog, params.searchLength,
             params.targetLength, g_stratName[(U32)(params.strategy)]);
+    if(cLevel != CUSTOM_LEVEL) {
+        snprintf(lvlstr, 15, "  Level %2u  ", cLevel);
+    }
     fprintf(f,
-            "/* level %2u */   /* R:%5.3f at %5.1f MB/s - %5.1f MB/s */\n",
-            cLevel, (double)srcSize / result.cSize, result.cSpeed / 1000000., result.dSpeed / 1000000.);
+        "/* %s */   /* R:%5.3f at %5.1f MB/s - %5.1f MB/s */\n",
+        lvlstr, (double)srcSize / result.cSize, result.cSpeed / 1000000., result.dSpeed / 1000000.);
 }
 
 
@@ -391,13 +248,13 @@ static void BMK_init_level_constraints(int bytePerSec_level1)
 
 static int BMK_seed(winnerInfo_t* winners, const ZSTD_compressionParameters params,
               const void* srcBuffer, size_t srcSize,
-                    ZSTD_CCtx* ctx)
+                    ZSTD_CCtx* ctx, ZSTD_DCtx* dctx)
 {
     BMK_result_t testResult;
     int better = 0;
     int cLevel;
 
-    BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, params);
+    BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, dctx, params);
 
 
     for (cLevel = 1; cLevel <= NB_LEVELS_TRACKED; cLevel++) {
@@ -560,7 +417,7 @@ static BYTE g_alreadyTested[PARAMTABLESIZE] = {0};   /* init to zero */
 static void playAround(FILE* f, winnerInfo_t* winners,
                        ZSTD_compressionParameters params,
                        const void* srcBuffer, size_t srcSize,
-                       ZSTD_CCtx* ctx)
+                       ZSTD_CCtx* ctx, ZSTD_DCtx* dctx)
 {
     int nbVariations = 0;
     UTIL_time_t const clockStart = UTIL_getTime();
@@ -577,11 +434,11 @@ static void playAround(FILE* f, winnerInfo_t* winners,
 
         /* test */
         NB_TESTS_PLAYED(p)++;
-        if (!BMK_seed(winners, p, srcBuffer, srcSize, ctx)) continue;
+        if (!BMK_seed(winners, p, srcBuffer, srcSize, ctx, dctx)) continue;
 
         /* improvement found => search more */
         BMK_printWinners(f, winners, srcSize);
-        playAround(f, winners, p, srcBuffer, srcSize, ctx);
+        playAround(f, winners, p, srcBuffer, srcSize, ctx, dctx);
     }
 
 }
@@ -608,29 +465,30 @@ static ZSTD_compressionParameters randomParams(void)
 static void BMK_selectRandomStart(
                        FILE* f, winnerInfo_t* winners,
                        const void* srcBuffer, size_t srcSize,
-                       ZSTD_CCtx* ctx)
+                       ZSTD_CCtx* ctx, ZSTD_DCtx* dctx)
 {
     U32 const id = FUZ_rand(&g_rand) % (NB_LEVELS_TRACKED+1);
     if ((id==0) || (winners[id].params.windowLog==0)) {
         /* use some random entry */
         ZSTD_compressionParameters const p = ZSTD_adjustCParams(randomParams(), srcSize, 0);
-        playAround(f, winners, p, srcBuffer, srcSize, ctx);
+        playAround(f, winners, p, srcBuffer, srcSize, ctx, dctx);
     } else {
-        playAround(f, winners, winners[id].params, srcBuffer, srcSize, ctx);
+        playAround(f, winners, winners[id].params, srcBuffer, srcSize, ctx, dctx);
     }
 }
 
 
-static void BMK_benchOnce(ZSTD_CCtx* cctx, const void* srcBuffer, size_t srcSize)
+static void BMK_benchOnce(ZSTD_CCtx* cctx, ZSTD_DCtx* dctx, const void* srcBuffer, size_t srcSize)
 {
     BMK_result_t testResult;
     g_params = ZSTD_adjustCParams(g_params, srcSize, 0);
-    BMK_benchParam(&testResult, srcBuffer, srcSize, cctx, g_params);
-    DISPLAY("\n");
+    BMK_benchParam(&testResult, srcBuffer, srcSize, cctx, dctx, g_params);
+    DISPLAY("Compression Ratio: %.3f  Compress Speed: %.1f MB/s Decompress Speed: %.1f MB/s\n", (double)srcSize / testResult.cSize, 
+        testResult.cSpeed / 1000000, testResult.dSpeed / 1000000);
     return;
 }
 
-static void BMK_benchFullTable(ZSTD_CCtx* cctx, const void* srcBuffer, size_t srcSize)
+static void BMK_benchFullTable(ZSTD_CCtx* cctx, ZSTD_DCtx* dctx, const void* srcBuffer, size_t srcSize)
 {
     ZSTD_compressionParameters params;
     winnerInfo_t winners[NB_LEVELS_TRACKED+1];
@@ -649,7 +507,7 @@ static void BMK_benchFullTable(ZSTD_CCtx* cctx, const void* srcBuffer, size_t sr
         /* baseline config for level 1 */
         ZSTD_compressionParameters const l1params = ZSTD_getCParams(1, blockSize, 0);
         BMK_result_t testResult;
-        BMK_benchParam(&testResult, srcBuffer, srcSize, cctx, l1params);
+        BMK_benchParam(&testResult, srcBuffer, srcSize, cctx, dctx, l1params);
         BMK_init_level_constraints((int)((testResult.cSpeed * 31) / 32));
     }
 
@@ -658,14 +516,14 @@ static void BMK_benchFullTable(ZSTD_CCtx* cctx, const void* srcBuffer, size_t sr
         int i;
         for (i=0; i<=maxSeeds; i++) {
             params = ZSTD_getCParams(i, blockSize, 0);
-            BMK_seed(winners, params, srcBuffer, srcSize, cctx);
+            BMK_seed(winners, params, srcBuffer, srcSize, cctx, dctx);
     }   }
     BMK_printWinners(f, winners, srcSize);
 
     /* start tests */
     {   const time_t grillStart = time(NULL);
         do {
-            BMK_selectRandomStart(f, winners, srcBuffer, srcSize, cctx);
+            BMK_selectRandomStart(f, winners, srcBuffer, srcSize, cctx, dctx);
         } while (BMK_timeSpan(grillStart) < g_grillDuration_s);
     }
 
@@ -677,19 +535,20 @@ static void BMK_benchFullTable(ZSTD_CCtx* cctx, const void* srcBuffer, size_t sr
     fclose(f);
 }
 
-static void BMK_benchMem_usingCCtx(ZSTD_CCtx* cctx, const void* srcBuffer, size_t srcSize)
+static void BMK_benchMem_usingCCtx(ZSTD_CCtx* const cctx, ZSTD_DCtx* const dctx, const void* srcBuffer, size_t srcSize)
 {
     if (g_singleRun)
-        return BMK_benchOnce(cctx, srcBuffer, srcSize);
+        return BMK_benchOnce(cctx, dctx, srcBuffer, srcSize);
     else
-        return BMK_benchFullTable(cctx, srcBuffer, srcSize);
+        return BMK_benchFullTable(cctx, dctx, srcBuffer, srcSize);
 }
 
-static void BMK_benchMem(const void* srcBuffer, size_t srcSize)
+static void BMK_benchMemCCtxInit(const void* srcBuffer, size_t srcSize)
 {
     ZSTD_CCtx* const cctx = ZSTD_createCCtx();
-    if (cctx==NULL) { DISPLAY("ZSTD_createCCtx() failed \n"); exit(1); }
-    BMK_benchMem_usingCCtx(cctx, srcBuffer, srcSize);
+    ZSTD_DCtx* const dctx = ZSTD_createDCtx();
+    if (cctx==NULL || dctx==NULL) { DISPLAY("Context Creation failed \n"); exit(1); }
+    BMK_benchMem_usingCCtx(cctx, dctx, srcBuffer, srcSize);
     ZSTD_freeCCtx(cctx);
 }
 
@@ -708,7 +567,7 @@ static int benchSample(void)
     /* bench */
     DISPLAY("\r%79s\r", "");
     DISPLAY("using %s %i%%: \n", name, (int)(g_compressibility*100));
-    BMK_benchMem(origBuff, benchedSize);
+    BMK_benchMemCCtxInit(origBuff, benchedSize);
 
     free(origBuff);
     return 0;
@@ -766,7 +625,7 @@ int benchFiles(const char** fileNamesTable, int nbFiles)
         /* bench */
         DISPLAY("\r%79s\r", "");
         DISPLAY("using %s : \n", inFileName);
-        BMK_benchMem(origBuff, benchedSize);
+        BMK_benchMemCCtxInit(origBuff, benchedSize);
 
         /* clean */
         free(origBuff);
@@ -790,7 +649,6 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
     U64 const inFileSize = UTIL_getFileSize(inFileName);
     size_t benchedSize = BMK_findMaxMem(inFileSize*3) / 3;
     void* origBuff;
-
     /* Init */
     if (inFile==NULL) { DISPLAY( "Pb opening %s\n", inFileName); return 11; }
     if (inFileSize == UTIL_FILESIZE_UNKNOWN) {
@@ -829,8 +687,8 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
     DISPLAY("\r%79s\r", "");
     DISPLAY("optimizing for %s - limit speed %u MB/s \n", inFileName, targetSpeed);
     targetSpeed *= 1000000;
-
     {   ZSTD_CCtx* const ctx = ZSTD_createCCtx();
+        ZSTD_DCtx* const dctx = ZSTD_createDCtx();
         winnerInfo_t winner;
         BMK_result_t candidate;
         const size_t blockSize = g_blockSize ? g_blockSize : benchedSize;
@@ -845,9 +703,10 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
             int i;
             for (i=1; i<=maxSeeds; i++) {
                 ZSTD_compressionParameters const CParams = ZSTD_getCParams(i, blockSize, 0);
-                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, CParams);
-                if (candidate.cSpeed < targetSpeed)
+                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, dctx, CParams);
+                if (candidate.cSpeed < (double)targetSpeed) {
                     break;
+                }
                 if ( (candidate.cSize < winner.result.cSize)
                    | ((candidate.cSize == winner.result.cSize) & (candidate.cSpeed > winner.result.cSpeed)) )
                 {
@@ -856,7 +715,9 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
                     BMK_printWinner(stdout, i, winner.result, winner.params, benchedSize);
             }   }
         }
-        BMK_printWinner(stdout, 99, winner.result, winner.params, benchedSize);
+
+        BMK_printWinner(stdout, CUSTOM_LEVEL, winner.result, winner.params, benchedSize);
+
         BMK_translateAdvancedParams(winner.params);
 
         /* start tests */
@@ -872,7 +733,7 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
 
                 /* test */
                 NB_TESTS_PLAYED(params)++;
-                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, params);
+                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, dctx, params);
 
                 /* improvement found => new winner */
                 if ( (candidate.cSpeed > targetSpeed)
@@ -881,19 +742,20 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)
                 {
                     winner.params = params;
                     winner.result = candidate;
-                    BMK_printWinner(stdout, 99, winner.result, winner.params, benchedSize);
+                    BMK_printWinner(stdout, CUSTOM_LEVEL, winner.result, winner.params, benchedSize);
                     BMK_translateAdvancedParams(winner.params);
                 }
             } while (BMK_timeSpan(grillStart) < g_grillDuration_s);
         }
-
         /* end summary */
-        BMK_printWinner(stdout, 99, winner.result, winner.params, benchedSize);
+
+        BMK_printWinner(stdout, CUSTOM_LEVEL, winner.result, winner.params, benchedSize);
         BMK_translateAdvancedParams(winner.params);
         DISPLAY("grillParams size - optimizer completed \n");
 
         /* clean up*/
         ZSTD_freeCCtx(ctx);
+        ZSTD_freeDCtx(dctx);
     }
 
     free(origBuff);
@@ -954,6 +816,8 @@ static int usage_advanced(void)
     DISPLAY( " -S     : Single run \n");
     DISPLAY( " --zstd : Single run, parameter selection same as zstdcli \n");
     DISPLAY( " -P#    : generated sample compressibility (default : %.1f%%) \n", COMPRESSIBILITY_DEFAULT * 100);
+    DISPLAY( " -t#    : Caps runtime of operation in seconds (default : %u seconds (%.1f hours)) \n", (U32)g_grillDuration_s, g_grillDuration_s / 3600);
+    DISPLAY( " -v     : Prints Benchmarking output\n");
     return 0;
 }
 
@@ -1007,7 +871,7 @@ int main(int argc, const char** argv)
                 DISPLAY("invalid --zstd= format\n");
                 return 1; /* check the end of string */
             }
-            //if not return, success
+            /* if not return, success */
         } else if (argument[0]=='-') {
             argument++;
 
@@ -1021,8 +885,8 @@ int main(int argc, const char** argv)
 
                     /* Pause at the end (hidden option) */
                 case 'p': main_pause = 1; argument++; break;
-
                     /* Modify Nb Iterations */
+
                 case 'i':
                     argument++;
                     g_nbIterations = readU32FromChar(&argument);
@@ -1103,6 +967,12 @@ int main(int argc, const char** argv)
                     DISPLAY("using %u KB block size \n", g_blockSize>>10);
                     break;
 
+                    /* caps runtime (in seconds) */
+                case 't':
+                    argument++;
+                    g_grillDuration_s = (double)readU32FromChar(&argument);
+                    break;
+
                     /* Unknown command */
                 default : return badusage(exename);
                 }
index 48001c2eb8e529cc9ec2df08d580e83e8bf62ef2..2a6e13a0531af1961b2e0d6714275f12bb109f41 100755 (executable)
@@ -186,6 +186,7 @@ $ZSTD -f tmp && die "tmp not present : should have failed"
 test ! -f tmp.zst  # tmp.zst should not be created
 
 $ECHO "test : compress multiple files"
+rm tmp*
 $ECHO hello > tmp1
 $ECHO world > tmp2
 $ZSTD tmp1 tmp2 -o "$INTOVOID"