| 124 | } |
| 125 | |
| 126 | bool ThreadResourcePool::TryAcquireThreadToken() { |
| 127 | while (true) { |
| 128 | int64_t previous_num_threads = num_threads_.Load(); |
| 129 | int64_t new_optional_threads = (previous_num_threads >> OPTIONAL_SHIFT) + 1; |
| 130 | int64_t new_required_threads = previous_num_threads & REQUIRED_MASK; |
| 131 | if (new_optional_threads + new_required_threads > quota()) return false; |
| 132 | int64_t new_value = new_optional_threads << OPTIONAL_SHIFT | new_required_threads; |
| 133 | // Atomically swap the new value if no one updated num_threads_. We do not |
| 134 | // care about the ABA problem here. |
| 135 | if (num_threads_.CompareAndSwap(previous_num_threads, new_value)) return true; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | void ThreadResourcePool::ReleaseThreadToken( |
| 140 | bool required, bool skip_callbacks) { |