2 * Copyright (c) 2016 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@
24 #include <Availability.h>
25 #include <sys/cdefs.h>
31 OS_ASSUME_NONNULL_BEGIN
37 #define OS_LOCK_API_VERSION 20160309
41 #define OS_UNFAIR_LOCK_AVAILABILITY \
42 __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \
43 __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
46 * @typedef os_unfair_lock
49 * Low-level lock that allows waiters to block efficiently on contention.
51 * In general, higher level synchronization primitives such as those provided by
52 * the pthread or dispatch subsystems should be preferred.
54 * The values stored in the lock should be considered opaque and implementation
55 * defined, they contain thread ownership information that the system may use
56 * to attempt to resolve priority inversions.
58 * This lock must be unlocked from the same thread that locked it, attemps to
59 * unlock from a different thread will cause an assertion aborting the process.
61 * This lock must not be accessed from multiple processes or threads via shared
62 * or multiply-mapped memory, the lock implementation relies on the address of
63 * the lock value and owning process.
65 * Must be initialized with OS_UNFAIR_LOCK_INIT
68 * Replacement for the deprecated OSSpinLock. Does not spin on contention but
69 * waits in the kernel to be woken up by an unlock.
71 * As with OSSpinLock there is no attempt at fairness or lock ordering, e.g. an
72 * unlocker can potentially immediately reacquire the lock before a woken up
73 * waiter gets an opportunity to attempt to acquire the lock. This may be
74 * advantageous for performance reasons, but also makes starvation of waiters a
77 OS_UNFAIR_LOCK_AVAILABILITY
78 typedef struct os_unfair_lock_s
{
79 uint32_t _os_unfair_lock_opaque
;
80 } os_unfair_lock
, *os_unfair_lock_t
;
82 #ifndef OS_UNFAIR_LOCK_INIT
83 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
84 #define OS_UNFAIR_LOCK_INIT ((os_unfair_lock){0})
85 #elif defined(__cplusplus) && __cplusplus >= 201103L
86 #define OS_UNFAIR_LOCK_INIT (os_unfair_lock{})
87 #elif defined(__cplusplus)
88 #define OS_UNFAIR_LOCK_INIT (os_unfair_lock())
90 #define OS_UNFAIR_LOCK_INIT {0}
92 #endif // OS_UNFAIR_LOCK_INIT
95 * @function os_unfair_lock_lock
98 * Locks an os_unfair_lock.
101 * Pointer to an os_unfair_lock.
103 OS_UNFAIR_LOCK_AVAILABILITY
104 OS_EXPORT OS_NOTHROW OS_NONNULL_ALL
105 void os_unfair_lock_lock(os_unfair_lock_t lock
);
108 * @function os_unfair_lock_trylock
111 * Locks an os_unfair_lock if it is not already locked.
114 * It is invalid to surround this function with a retry loop, if this function
115 * returns false, the program must be able to proceed without having acquired
116 * the lock, or it must call os_unfair_lock_lock() directly (a retry loop around
117 * os_unfair_lock_trylock() amounts to an inefficient implementation of
118 * os_unfair_lock_lock() that hides the lock waiter from the system and prevents
119 * resolution of priority inversions).
122 * Pointer to an os_unfair_lock.
125 * Returns true if the lock was succesfully locked and false if the lock was
128 OS_UNFAIR_LOCK_AVAILABILITY
129 OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_NONNULL_ALL
130 bool os_unfair_lock_trylock(os_unfair_lock_t lock
);
133 * @function os_unfair_lock_unlock
136 * Unlocks an os_unfair_lock.
139 * Pointer to an os_unfair_lock.
141 OS_UNFAIR_LOCK_AVAILABILITY
142 OS_EXPORT OS_NOTHROW OS_NONNULL_ALL
143 void os_unfair_lock_unlock(os_unfair_lock_t lock
);
147 OS_ASSUME_NONNULL_END
149 #endif // __OS_LOCK__