| /* |
| * Copyright (c) 2008-2013 Apple Inc. All rights reserved. |
| * |
| * @APPLE_APACHE_LICENSE_HEADER_START@ |
| * |
| * 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. |
| * |
| * @APPLE_APACHE_LICENSE_HEADER_END@ |
| */ |
| |
| /* |
| * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch |
| * which are subject to change in future releases of Mac OS X. Any applications |
| * relying on these interfaces WILL break. |
| */ |
| |
| #ifndef __DISPATCH_SEMAPHORE_INTERNAL__ |
| #define __DISPATCH_SEMAPHORE_INTERNAL__ |
| |
| struct dispatch_queue_s; |
| |
| DISPATCH_CLASS_DECL(semaphore, OBJECT); |
| struct dispatch_semaphore_s { |
| DISPATCH_OBJECT_HEADER(semaphore); |
| intptr_t volatile dsema_value; |
| intptr_t dsema_orig; |
| _dispatch_sema4_t dsema_sema; |
| }; |
| |
| /* |
| * Dispatch Group State: |
| * |
| * Generation (32 - 63): |
| * 32 bit counter that is incremented each time the group value reaaches |
| * 0 after a dispatch_group_leave. This 32bit word is used to block waiters |
| * (threads in dispatch_group_wait) in _dispatch_wait_on_address() until the |
| * generation changes. |
| * |
| * Value (2 - 31): |
| * 30 bit value counter of the number of times the group was entered. |
| * dispatch_group_enter counts downward on 32bits, and dispatch_group_leave |
| * upward on 64bits, which causes the generation to bump each time the value |
| * reaches 0 again due to carry propagation. |
| * |
| * Has Notifs (1): |
| * This bit is set when the list of notifications on the group becomes non |
| * empty. It is also used as a lock as the thread that successfuly clears this |
| * bit is the thread responsible for firing the notifications. |
| * |
| * Has Waiters (0): |
| * This bit is set when there are waiters (threads in dispatch_group_wait) |
| * that need to be woken up the next time the value reaches 0. Waiters take |
| * a snapshot of the generation before waiting and will wait for the |
| * generation to change before they return. |
| */ |
| #define DISPATCH_GROUP_GEN_MASK 0xffffffff00000000ULL |
| #define DISPATCH_GROUP_VALUE_MASK 0x00000000fffffffcULL |
| #define DISPATCH_GROUP_VALUE_INTERVAL 0x0000000000000004ULL |
| #define DISPATCH_GROUP_VALUE_1 DISPATCH_GROUP_VALUE_MASK |
| #define DISPATCH_GROUP_VALUE_MAX DISPATCH_GROUP_VALUE_INTERVAL |
| #define DISPATCH_GROUP_HAS_NOTIFS 0x0000000000000002ULL |
| #define DISPATCH_GROUP_HAS_WAITERS 0x0000000000000001ULL |
| DISPATCH_CLASS_DECL(group, OBJECT); |
| struct dispatch_group_s { |
| DISPATCH_OBJECT_HEADER(group); |
| DISPATCH_UNION_LE(uint64_t volatile dg_state, |
| uint32_t dg_bits, |
| uint32_t dg_gen |
| ) DISPATCH_ATOMIC64_ALIGN; |
| struct dispatch_continuation_s *volatile dg_notify_head; |
| struct dispatch_continuation_s *volatile dg_notify_tail; |
| }; |
| |
| DISPATCH_ALWAYS_INLINE |
| static inline uint32_t |
| _dg_state_value(uint64_t dg_state) |
| { |
| return (uint32_t)(-((uint32_t)dg_state & DISPATCH_GROUP_VALUE_MASK)) >> 2; |
| } |
| |
| DISPATCH_ALWAYS_INLINE |
| static inline uint32_t |
| _dg_state_gen(uint64_t dg_state) |
| { |
| return (uint32_t)(dg_state >> 32); |
| } |
| |
| dispatch_group_t _dispatch_group_create_and_enter(void); |
| void _dispatch_group_dispose(dispatch_object_t dou, bool *allow_free); |
| DISPATCH_COLD |
| size_t _dispatch_group_debug(dispatch_object_t dou, char *buf, |
| size_t bufsiz); |
| |
| void _dispatch_semaphore_dispose(dispatch_object_t dou, bool *allow_free); |
| DISPATCH_COLD |
| size_t _dispatch_semaphore_debug(dispatch_object_t dou, char *buf, |
| size_t bufsiz); |
| |
| #endif |