]>
git.saurik.com Git - apple/libdispatch.git/blob - src/shims/yield.h
2 * Copyright (c) 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@
22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23 * which are subject to change in future releases of Mac OS X. Any applications
24 * relying on these interfaces WILL break.
27 #ifndef __DISPATCH_SHIMS_YIELD__
28 #define __DISPATCH_SHIMS_YIELD__
31 #pragma mark _dispatch_wait_until
33 #if DISPATCH_HW_CONFIG_UP
34 #define _dispatch_wait_until(c) do { \
36 while (!fastpath(c)) { \
38 _dispatch_preemption_yield(_spins); \
40 #elif TARGET_OS_EMBEDDED
41 // <rdar://problem/15440575>
42 #ifndef DISPATCH_WAIT_SPINS
43 #define DISPATCH_WAIT_SPINS 1024
45 #define _dispatch_wait_until(c) do { \
46 int _spins = -(DISPATCH_WAIT_SPINS); \
47 while (!fastpath(c)) { \
48 if (slowpath(_spins++ >= 0)) { \
49 _dispatch_preemption_yield(_spins); \
51 dispatch_hardware_pause(); \
55 #define _dispatch_wait_until(c) do { \
56 while (!fastpath(c)) { \
57 dispatch_hardware_pause(); \
62 #pragma mark _dispatch_contention_wait_until
64 #if DISPATCH_HW_CONFIG_UP
65 #define _dispatch_contention_wait_until(c) false
67 #ifndef DISPATCH_CONTENTION_SPINS_MAX
68 #define DISPATCH_CONTENTION_SPINS_MAX (128 - 1)
70 #ifndef DISPATCH_CONTENTION_SPINS_MIN
71 #define DISPATCH_CONTENTION_SPINS_MIN (32 - 1)
73 #if TARGET_OS_EMBEDDED
74 #define _dispatch_contention_spins() \
75 ((DISPATCH_CONTENTION_SPINS_MIN) + ((DISPATCH_CONTENTION_SPINS_MAX) - \
76 (DISPATCH_CONTENTION_SPINS_MIN)) / 2)
78 // Use randomness to prevent threads from resonating at the same
79 // frequency and permanently contending. All threads sharing the same
80 // seed value is safe with the FreeBSD rand_r implementation.
81 #define _dispatch_contention_spins() ({ \
82 static unsigned int _seed; \
83 ((unsigned int)rand_r(&_seed) & (DISPATCH_CONTENTION_SPINS_MAX)) | \
84 (DISPATCH_CONTENTION_SPINS_MIN); })
86 #define _dispatch_contention_wait_until(c) ({ \
88 unsigned int _spins = _dispatch_contention_spins(); \
90 dispatch_hardware_pause(); \
91 if ((_out = fastpath(c))) break; \
96 #pragma mark dispatch_hardware_pause
98 #if defined(__x86_64__) || defined(__i386__)
99 #define dispatch_hardware_pause() __asm__("pause")
100 #elif (defined(__arm__) && defined(_ARM_ARCH_7) && defined(__thumb__)) || \
102 #define dispatch_hardware_pause() __asm__("yield")
103 #define dispatch_hardware_wfe() __asm__("wfe")
105 #define dispatch_hardware_pause() __asm__("")
109 #pragma mark _dispatch_preemption_yield
112 #if defined(SWITCH_OPTION_OSLOCK_DEPRESS)
113 #define DISPATCH_YIELD_THREAD_SWITCH_OPTION SWITCH_OPTION_OSLOCK_DEPRESS
115 #define DISPATCH_YIELD_THREAD_SWITCH_OPTION SWITCH_OPTION_DEPRESS
117 #define _dispatch_preemption_yield(n) thread_switch(MACH_PORT_NULL, \
118 DISPATCH_YIELD_THREAD_SWITCH_OPTION, (mach_msg_timeout_t)(n))
119 #define _dispatch_preemption_yield_to(th, n) thread_switch(th, \
120 DISPATCH_YIELD_THREAD_SWITCH_OPTION, (mach_msg_timeout_t)(n))
122 #define _dispatch_preemption_yield(n) pthread_yield_np()
123 #define _dispatch_preemption_yield_to(th, n) pthread_yield_np()
127 #pragma mark _dispatch_contention_usleep
129 #ifndef DISPATCH_CONTENTION_USLEEP_START
130 #define DISPATCH_CONTENTION_USLEEP_START 500
132 #ifndef DISPATCH_CONTENTION_USLEEP_MAX
133 #define DISPATCH_CONTENTION_USLEEP_MAX 100000
137 #if defined(SWITCH_OPTION_DISPATCH_CONTENTION)
138 #define _dispatch_contention_usleep(u) thread_switch(MACH_PORT_NULL, \
139 SWITCH_OPTION_DISPATCH_CONTENTION, (u))
141 #define _dispatch_contention_usleep(u) thread_switch(MACH_PORT_NULL, \
142 SWITCH_OPTION_WAIT, (((u)-1)/1000)+1)
145 #define _dispatch_contention_usleep(u) usleep((u))
148 #endif // __DISPATCH_SHIMS_YIELD__