summaryrefslogtreecommitdiffstats
path: root/libfreerdp/primitives/test/measure.h
blob: ee04abda9554ae61e15c3e0e1adece90c9f28ef5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* measure.h
 * Macros to help with performance measurement.
 * vi:ts=4 sw=4
 *
 * (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.  Algorithms used by
 * this code may be covered by patents by HP, Microsoft, or other parties.
 *
 * MEASURE_LOOP_START("measurement", 2000)
 *   code to be measured
 * MEASURE_LOOP_STOP
 *   buffer flush and such
 * MEASURE_SHOW_RESULTS
 *
 * Define GOOGLE_PROFILER if you want gperftools included.
 */

#ifndef TEST_MEASURE_H_INCLUDED
#define TEST_MEASURE_H_INCLUDED

#include <freerdp/config.h>

#include <time.h>
#include <winpr/string.h>

#ifndef _WIN32
#include <sys/param.h>
#endif

#include <winpr/crt.h>

#ifdef _WIN32

#define PROFILER_START(_prefix_)
#define PROFILER_STOP

#define MEASURE_LOOP_START(_prefix_, _count_)
#define MEASURE_LOOP_STOP
#define MEASURE_GET_RESULTS(_result_)
#define MEASURE_SHOW_RESULTS(_result_)
#define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_)
#define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_)

#else

#ifdef GOOGLE_PROFILER
#include <gperftools/profiler.h>
#define PROFILER_START(_prefix_)                                  \
	do                                                            \
	{                                                             \
		char _path[PATH_MAX];                                     \
		sprintf_s(_path, sizeof(_path), "./%s.prof", (_prefix_)); \
		ProfilerStart(_path);                                     \
	} while (0);
#define PROFILER_STOP   \
	do                  \
	{                   \
		ProfilerStop(); \
	} while (0);
#else
#define PROFILER_START(_prefix_)
#define PROFILER_STOP
#endif // GOOGLE_PROFILER

extern float _delta_time(const struct timespec* t0, const struct timespec* t1);
extern void _floatprint(float t, char* output);

#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW 4
#endif // !CLOCK_MONOTONIC_RAW

#define MEASURE_LOOP_START(_prefix_, _count_)        \
	{                                                \
		struct timespec _start, _stop;               \
		char* _prefix;                               \
		int _count = (_count_);                      \
		int _loop;                                   \
		float _delta;                                \
		char _str1[32], _str2[32];                   \
		_prefix = _strdup(_prefix_);                 \
		_str1[0] = '\0';                             \
		_str2[0] = '\0';                             \
		clock_gettime(CLOCK_MONOTONIC_RAW, &_start); \
		PROFILER_START(_prefix);                     \
		_loop = (_count);                            \
		do                                           \
		{

#define MEASURE_LOOP_STOP \
	}                     \
	while (--_loop)       \
		;

#define MEASURE_GET_RESULTS(_result_)           \
	PROFILER_STOP;                              \
	clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \
	_delta = _delta_time(&_start, &_stop);      \
	(_result_) = (float)_count / _delta;        \
	free(_prefix);                              \
	}

#define MEASURE_SHOW_RESULTS(_result_)                                                       \
	PROFILER_STOP;                                                                           \
	clock_gettime(CLOCK_MONOTONIC_RAW, &_stop);                                              \
	_delta = _delta_time(&_start, &_stop);                                                   \
	(_result_) = (float)_count / _delta;                                                     \
	_floatprint((float)_count / _delta, _str1);                                              \
	printf("%s: %9d iterations in %5.1f seconds = %s/s \n", _prefix, _count, _delta, _str1); \
	free(_prefix);                                                                           \
	}

#define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_)                                              \
	PROFILER_STOP;                                                                                 \
	clock_gettime(CLOCK_MONOTONIC_RAW, &_stop);                                                    \
	_delta = _delta_time(&_start, &_stop);                                                         \
	_floatprint((float)_count / _delta, _str1);                                                    \
	_floatprint((float)_count / _delta * (_scale_), _str2);                                        \
	printf("%s: %9d iterations in %5.1f seconds = %s/s = %s%s \n", _prefix, _count, _delta, _str1, \
	       _str2, _label_);                                                                        \
	free(_prefix);                                                                                 \
	}

#define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_) \
	{                                                                      \
		float _r;                                                          \
		MEASURE_LOOP_START(_label_, _init_iter_);                          \
		_call_;                                                            \
		MEASURE_LOOP_STOP;                                                 \
		MEASURE_GET_RESULTS(_r);                                           \
		MEASURE_LOOP_START(_label_, _r* _test_time_);                      \
		_call_;                                                            \
		MEASURE_LOOP_STOP;                                                 \
		MEASURE_SHOW_RESULTS(_result_);                                    \
	}

#endif

#endif // __MEASURE_H_INCLUDED__