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