| 137 | } |
| 138 | |
| 139 | void ThreadResourcePool::ReleaseThreadToken( |
| 140 | bool required, bool skip_callbacks) { |
| 141 | if (required) { |
| 142 | DCHECK_GT(num_required_threads(), 0); |
| 143 | num_threads_.Add(-1); |
| 144 | } else { |
| 145 | DCHECK_GT(num_optional_threads(), 0); |
| 146 | while (true) { |
| 147 | int64_t previous_num_threads = num_threads_.Load(); |
| 148 | int64_t new_optional_threads = (previous_num_threads >> OPTIONAL_SHIFT) - 1; |
| 149 | int64_t new_required_threads = previous_num_threads & REQUIRED_MASK; |
| 150 | int64_t new_value = new_optional_threads << OPTIONAL_SHIFT | new_required_threads; |
| 151 | if (num_threads_.CompareAndSwap(previous_num_threads, new_value)) break; |
| 152 | } |
| 153 | } |
| 154 | if (!skip_callbacks) InvokeCallbacks(); |
| 155 | } |