]>
git.saurik.com Git - apple/libdispatch.git/blob - src/shims/atomic_sfb.h
2 * Copyright (c) 2012-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_ATOMIC_SFB__
28 #define __DISPATCH_SHIMS_ATOMIC_SFB__
30 #if __clang__ && __clang_major__ < 5 // <rdar://problem/13833871>
31 #define __builtin_ffs(x) __builtin_ffs((unsigned int)(x))
34 // Returns UINT_MAX if all the bits in p were already set.
35 #define dispatch_atomic_set_first_bit(p,m) _dispatch_atomic_set_first_bit(p,m)
37 // TODO: rdar://11477843
38 DISPATCH_ALWAYS_INLINE
39 static inline unsigned int
40 _dispatch_atomic_set_first_bit(volatile uint32_t *p
, unsigned int max_index
)
43 typeof(*p
) b
, mask
, b_masked
;
47 // ffs returns 1 + index, or 0 if none set.
48 index
= (unsigned int)__builtin_ffs((int)~b
);
49 if (slowpath(index
== 0)) {
53 if (slowpath(index
> max_index
)) {
56 mask
= ((typeof(b
))1) << index
;
58 if (__sync_bool_compare_and_swap(p
, b
, b_masked
)) {
64 #if defined(__x86_64__) || defined(__i386__)
66 #undef dispatch_atomic_set_first_bit
67 // TODO: rdar://11477843 uint64_t -> long
68 DISPATCH_ALWAYS_INLINE
69 static inline unsigned int
70 dispatch_atomic_set_first_bit(volatile uint64_t *p
, unsigned int max
)
73 if (max
> (sizeof(val
) * 8)) {
76 "mov %[_p], %[_val] \n\t"
78 "bsf %[_val], %[_bit] \n\t" /* val is 0 => set zf */
81 "bts %[_bit], %[_p] \n\t" /* cf = prev bit val */
82 "jc 1b \n\t" /* lost race, retry */
85 "mov %[_all_ones], %[_bit]" "\n\t"
87 : [_p
] "=m" (*p
), [_val
] "=&r" (val
), [_bit
] "=&r" (bit
)
88 : [_all_ones
] "i" ((typeof(bit
))UINT_MAX
) : "memory", "cc");
92 "mov %[_p], %[_val] \n\t"
94 "bsf %[_val], %[_bit] \n\t" /* val is 0 => set zf */
96 "cmp %[_max], %[_bit] \n\t"
99 "bts %[_bit], %[_p] \n\t" /* cf = prev bit val */
100 "jc 1b \n\t" /* lost race, retry */
103 "mov %[_all_ones], %[_bit]" "\n\t"
105 : [_p
] "=m" (*p
), [_val
] "=&r" (val
), [_bit
] "=&r" (bit
)
106 : [_all_ones
] "i" ((typeof(bit
))UINT_MAX
),
107 [_max
] "g" ((typeof(bit
))max
) : "memory", "cc");
109 return (unsigned int)bit
;
115 #endif // __DISPATCH_SHIMS_ATOMIC_SFB__