xref: /freebsd-src/sys/contrib/zstd/programs/zstdcli_trace.c (revision 5ff13fbc199bdf5f0572845351c68ee5ca828e71)
1*5ff13fbcSAllan Jude /*
2*5ff13fbcSAllan Jude  * Copyright (c) Facebook, Inc.
3*5ff13fbcSAllan Jude  * All rights reserved.
4*5ff13fbcSAllan Jude  *
5*5ff13fbcSAllan Jude  * This source code is licensed under both the BSD-style license (found in the
6*5ff13fbcSAllan Jude  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*5ff13fbcSAllan Jude  * in the COPYING file in the root directory of this source tree).
8*5ff13fbcSAllan Jude  * You may select, at your option, one of the above-listed licenses.
9*5ff13fbcSAllan Jude  */
10*5ff13fbcSAllan Jude 
11*5ff13fbcSAllan Jude #include "zstdcli_trace.h"
12*5ff13fbcSAllan Jude 
13*5ff13fbcSAllan Jude #include <stdio.h>
14*5ff13fbcSAllan Jude #include <stdlib.h>
15*5ff13fbcSAllan Jude 
16*5ff13fbcSAllan Jude #include "timefn.h"
17*5ff13fbcSAllan Jude #include "util.h"
18*5ff13fbcSAllan Jude 
19*5ff13fbcSAllan Jude #define ZSTD_STATIC_LINKING_ONLY
20*5ff13fbcSAllan Jude #include "../lib/zstd.h"
21*5ff13fbcSAllan Jude /* We depend on the trace header to avoid duplicating the ZSTD_trace struct.
22*5ff13fbcSAllan Jude  * But, we check the version so it is compatible with dynamic linking.
23*5ff13fbcSAllan Jude  */
24*5ff13fbcSAllan Jude #include "../lib/common/zstd_trace.h"
25*5ff13fbcSAllan Jude /* We only use macros from threading.h so it is compatible with dynamic linking */
26*5ff13fbcSAllan Jude #include "../lib/common/threading.h"
27*5ff13fbcSAllan Jude 
28*5ff13fbcSAllan Jude #if ZSTD_TRACE
29*5ff13fbcSAllan Jude 
30*5ff13fbcSAllan Jude static FILE* g_traceFile = NULL;
31*5ff13fbcSAllan Jude static int g_mutexInit = 0;
32*5ff13fbcSAllan Jude static ZSTD_pthread_mutex_t g_mutex;
33*5ff13fbcSAllan Jude static UTIL_time_t g_enableTime = UTIL_TIME_INITIALIZER;
34*5ff13fbcSAllan Jude 
TRACE_enable(char const * filename)35*5ff13fbcSAllan Jude void TRACE_enable(char const* filename)
36*5ff13fbcSAllan Jude {
37*5ff13fbcSAllan Jude     int const writeHeader = !UTIL_isRegularFile(filename);
38*5ff13fbcSAllan Jude     if (g_traceFile)
39*5ff13fbcSAllan Jude         fclose(g_traceFile);
40*5ff13fbcSAllan Jude     g_traceFile = fopen(filename, "a");
41*5ff13fbcSAllan Jude     if (g_traceFile && writeHeader) {
42*5ff13fbcSAllan Jude         /* Fields:
43*5ff13fbcSAllan Jude         * algorithm
44*5ff13fbcSAllan Jude         * version
45*5ff13fbcSAllan Jude         * method
46*5ff13fbcSAllan Jude         * streaming
47*5ff13fbcSAllan Jude         * level
48*5ff13fbcSAllan Jude         * workers
49*5ff13fbcSAllan Jude         * dictionary size
50*5ff13fbcSAllan Jude         * uncompressed size
51*5ff13fbcSAllan Jude         * compressed size
52*5ff13fbcSAllan Jude         * duration nanos
53*5ff13fbcSAllan Jude         * compression ratio
54*5ff13fbcSAllan Jude         * speed MB/s
55*5ff13fbcSAllan Jude         */
56*5ff13fbcSAllan Jude         fprintf(g_traceFile, "Algorithm, Version, Method, Mode, Level, Workers, Dictionary Size, Uncompressed Size, Compressed Size, Duration Nanos, Compression Ratio, Speed MB/s\n");
57*5ff13fbcSAllan Jude     }
58*5ff13fbcSAllan Jude     g_enableTime = UTIL_getTime();
59*5ff13fbcSAllan Jude     if (!g_mutexInit) {
60*5ff13fbcSAllan Jude         if (!ZSTD_pthread_mutex_init(&g_mutex, NULL)) {
61*5ff13fbcSAllan Jude             g_mutexInit = 1;
62*5ff13fbcSAllan Jude         } else {
63*5ff13fbcSAllan Jude             TRACE_finish();
64*5ff13fbcSAllan Jude         }
65*5ff13fbcSAllan Jude     }
66*5ff13fbcSAllan Jude }
67*5ff13fbcSAllan Jude 
TRACE_finish(void)68*5ff13fbcSAllan Jude void TRACE_finish(void)
69*5ff13fbcSAllan Jude {
70*5ff13fbcSAllan Jude     if (g_traceFile) {
71*5ff13fbcSAllan Jude         fclose(g_traceFile);
72*5ff13fbcSAllan Jude     }
73*5ff13fbcSAllan Jude     g_traceFile = NULL;
74*5ff13fbcSAllan Jude     if (g_mutexInit) {
75*5ff13fbcSAllan Jude         ZSTD_pthread_mutex_destroy(&g_mutex);
76*5ff13fbcSAllan Jude         g_mutexInit = 0;
77*5ff13fbcSAllan Jude     }
78*5ff13fbcSAllan Jude }
79*5ff13fbcSAllan Jude 
TRACE_log(char const * method,PTime duration,ZSTD_Trace const * trace)80*5ff13fbcSAllan Jude static void TRACE_log(char const* method, PTime duration, ZSTD_Trace const* trace)
81*5ff13fbcSAllan Jude {
82*5ff13fbcSAllan Jude     int level = 0;
83*5ff13fbcSAllan Jude     int workers = 0;
84*5ff13fbcSAllan Jude     double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
85*5ff13fbcSAllan Jude     double const speed = ((double)trace->uncompressedSize * 1000) / (double)duration;
86*5ff13fbcSAllan Jude     if (trace->params) {
87*5ff13fbcSAllan Jude         ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
88*5ff13fbcSAllan Jude         ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
89*5ff13fbcSAllan Jude     }
90*5ff13fbcSAllan Jude     assert(g_traceFile != NULL);
91*5ff13fbcSAllan Jude 
92*5ff13fbcSAllan Jude     ZSTD_pthread_mutex_lock(&g_mutex);
93*5ff13fbcSAllan Jude     /* Fields:
94*5ff13fbcSAllan Jude      * algorithm
95*5ff13fbcSAllan Jude      * version
96*5ff13fbcSAllan Jude      * method
97*5ff13fbcSAllan Jude      * streaming
98*5ff13fbcSAllan Jude      * level
99*5ff13fbcSAllan Jude      * workers
100*5ff13fbcSAllan Jude      * dictionary size
101*5ff13fbcSAllan Jude      * uncompressed size
102*5ff13fbcSAllan Jude      * compressed size
103*5ff13fbcSAllan Jude      * duration nanos
104*5ff13fbcSAllan Jude      * compression ratio
105*5ff13fbcSAllan Jude      * speed MB/s
106*5ff13fbcSAllan Jude      */
107*5ff13fbcSAllan Jude     fprintf(g_traceFile,
108*5ff13fbcSAllan Jude         "zstd, %u, %s, %s, %d, %d, %llu, %llu, %llu, %llu, %.2f, %.2f\n",
109*5ff13fbcSAllan Jude         trace->version,
110*5ff13fbcSAllan Jude         method,
111*5ff13fbcSAllan Jude         trace->streaming ? "streaming" : "single-pass",
112*5ff13fbcSAllan Jude         level,
113*5ff13fbcSAllan Jude         workers,
114*5ff13fbcSAllan Jude         (unsigned long long)trace->dictionarySize,
115*5ff13fbcSAllan Jude         (unsigned long long)trace->uncompressedSize,
116*5ff13fbcSAllan Jude         (unsigned long long)trace->compressedSize,
117*5ff13fbcSAllan Jude         (unsigned long long)duration,
118*5ff13fbcSAllan Jude         ratio,
119*5ff13fbcSAllan Jude         speed);
120*5ff13fbcSAllan Jude     ZSTD_pthread_mutex_unlock(&g_mutex);
121*5ff13fbcSAllan Jude }
122*5ff13fbcSAllan Jude 
123*5ff13fbcSAllan Jude /**
124*5ff13fbcSAllan Jude  * These symbols override the weak symbols provided by the library.
125*5ff13fbcSAllan Jude  */
126*5ff13fbcSAllan Jude 
ZSTD_trace_compress_begin(ZSTD_CCtx const * cctx)127*5ff13fbcSAllan Jude ZSTD_TraceCtx ZSTD_trace_compress_begin(ZSTD_CCtx const* cctx)
128*5ff13fbcSAllan Jude {
129*5ff13fbcSAllan Jude     (void)cctx;
130*5ff13fbcSAllan Jude     if (g_traceFile == NULL)
131*5ff13fbcSAllan Jude         return 0;
132*5ff13fbcSAllan Jude     return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
133*5ff13fbcSAllan Jude }
134*5ff13fbcSAllan Jude 
ZSTD_trace_compress_end(ZSTD_TraceCtx ctx,ZSTD_Trace const * trace)135*5ff13fbcSAllan Jude void ZSTD_trace_compress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
136*5ff13fbcSAllan Jude {
137*5ff13fbcSAllan Jude     PTime const beginNanos = (PTime)ctx;
138*5ff13fbcSAllan Jude     PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
139*5ff13fbcSAllan Jude     PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
140*5ff13fbcSAllan Jude     assert(g_traceFile != NULL);
141*5ff13fbcSAllan Jude     assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
142*5ff13fbcSAllan Jude     TRACE_log("compress", durationNanos, trace);
143*5ff13fbcSAllan Jude }
144*5ff13fbcSAllan Jude 
ZSTD_trace_decompress_begin(ZSTD_DCtx const * dctx)145*5ff13fbcSAllan Jude ZSTD_TraceCtx ZSTD_trace_decompress_begin(ZSTD_DCtx const* dctx)
146*5ff13fbcSAllan Jude {
147*5ff13fbcSAllan Jude     (void)dctx;
148*5ff13fbcSAllan Jude     if (g_traceFile == NULL)
149*5ff13fbcSAllan Jude         return 0;
150*5ff13fbcSAllan Jude     return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
151*5ff13fbcSAllan Jude }
152*5ff13fbcSAllan Jude 
ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx,ZSTD_Trace const * trace)153*5ff13fbcSAllan Jude void ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
154*5ff13fbcSAllan Jude {
155*5ff13fbcSAllan Jude     PTime const beginNanos = (PTime)ctx;
156*5ff13fbcSAllan Jude     PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
157*5ff13fbcSAllan Jude     PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
158*5ff13fbcSAllan Jude     assert(g_traceFile != NULL);
159*5ff13fbcSAllan Jude     assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
160*5ff13fbcSAllan Jude     TRACE_log("decompress", durationNanos, trace);
161*5ff13fbcSAllan Jude }
162*5ff13fbcSAllan Jude 
163*5ff13fbcSAllan Jude #else /* ZSTD_TRACE */
164*5ff13fbcSAllan Jude 
TRACE_enable(char const * filename)165*5ff13fbcSAllan Jude void TRACE_enable(char const* filename)
166*5ff13fbcSAllan Jude {
167*5ff13fbcSAllan Jude     (void)filename;
168*5ff13fbcSAllan Jude }
169*5ff13fbcSAllan Jude 
TRACE_finish(void)170*5ff13fbcSAllan Jude void TRACE_finish(void) {}
171*5ff13fbcSAllan Jude 
172*5ff13fbcSAllan Jude #endif /* ZSTD_TRACE */
173