2 * Copyright (c) 2008-2013 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
23 struct __dispatch_benchmark_data_s
{
24 #if HAVE_MACH_ABSOLUTE_TIME
25 mach_timebase_info_data_t tbi
;
34 _dispatch_benchmark_init(void *context
)
36 struct __dispatch_benchmark_data_s
*bdata
= context
;
37 // try and simulate performance of real benchmark as much as possible
38 // keep 'f', 'c' and 'cnt' in registers
39 register void (*f
)(void *) = bdata
->func
;
40 register void *c
= bdata
->ctxt
;
41 register size_t cnt
= bdata
->count
;
43 uint64_t start
, delta
;
49 #if HAVE_MACH_ABSOLUTE_TIME
52 kr
= mach_timebase_info(&bdata
->tbi
);
53 dispatch_assert_zero(kr
);
56 start
= _dispatch_absolute_time();
61 delta
= _dispatch_absolute_time() - start
;
64 #if HAVE_MACH_ABSOLUTE_TIME
65 lcost
*= bdata
->tbi
.numer
;
66 lcost
/= bdata
->tbi
.denom
;
70 bdata
->loop_cost
= lcost
> UINT64_MAX
? UINT64_MAX
: (uint64_t)lcost
;
75 dispatch_benchmark(size_t count
, void (^block
)(void))
77 return dispatch_benchmark_f(count
, block
, _dispatch_Block_invoke(block
));
82 _dispatch_benchmark_dummy_function(void *ctxt DISPATCH_UNUSED
)
87 dispatch_benchmark_f(size_t count
, register void *ctxt
,
88 register void (*func
)(void *))
90 static struct __dispatch_benchmark_data_s bdata
= {
91 .func
= _dispatch_benchmark_dummy_function
,
92 .count
= 10000000ul, // ten million
94 static dispatch_once_t pred
;
95 uint64_t ns
, start
, delta
;
97 __uint128_t conversion
, big_denom
;
99 long double conversion
, big_denom
;
103 dispatch_once_f(&pred
, &bdata
, _dispatch_benchmark_init
);
105 if (slowpath(count
== 0)) {
109 start
= _dispatch_absolute_time();
114 delta
= _dispatch_absolute_time() - start
;
117 #if HAVE_MACH_ABSOLUTE_TIME
118 conversion
*= bdata
.tbi
.numer
;
119 big_denom
= bdata
.tbi
.denom
;
124 conversion
/= big_denom
;
125 ns
= conversion
> UINT64_MAX
? UINT64_MAX
: (uint64_t)conversion
;
127 return ns
- bdata
.loop_cost
;