2 * Copyright (c) 2008-2009 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
;
75 dispatch_benchmark(size_t count
, void (^block
)(void))
77 struct Block_basic
*bb
= (void *)block
;
78 return dispatch_benchmark_f(count
, block
, (void *)bb
->Block_invoke
);
83 dispatch_benchmark_f(size_t count
, register void *ctxt
,
84 register void (*func
)(void *))
86 static struct __dispatch_benchmark_data_s bdata
= {
87 .func
= (void *)dummy_function
,
88 .count
= 10000000ul, // ten million
90 static dispatch_once_t pred
;
91 uint64_t ns
, start
, delta
;
93 __uint128_t conversion
, big_denom
;
95 long double conversion
, big_denom
;
99 dispatch_once_f(&pred
, &bdata
, _dispatch_benchmark_init
);
101 if (slowpath(count
== 0)) {
105 start
= _dispatch_absolute_time();
110 delta
= _dispatch_absolute_time() - start
;
113 #if HAVE_MACH_ABSOLUTE_TIME
114 conversion
*= bdata
.tbi
.numer
;
115 big_denom
= bdata
.tbi
.denom
;
120 conversion
/= big_denom
;
123 return ns
- bdata
.loop_cost
;