diff options
Diffstat (limited to 'runtime/barrier.h')
-rw-r--r-- | runtime/barrier.h | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/runtime/barrier.h b/runtime/barrier.h index 5ca88e8..0e7f61e 100644 --- a/runtime/barrier.h +++ b/runtime/barrier.h @@ -14,6 +14,16 @@ * limitations under the License. */ +// CAUTION: THIS IS NOT A FULLY GENERAL BARRIER API. + +// It may either be used as a "latch" or single-use barrier, or it may be reused under +// very limited conditions, e.g. if only Pass(), but not Wait() is called. Unlike a standard +// latch API, it is possible to initialize the latch to a count of zero, repeatedly call +// Pass() or Wait(), and only then set the count using the Increment() method. Threads at +// a Wait() are only awoken if the count reaches zero AFTER the decrement is applied. +// This works because, also unlike most latch APIs, there is no way to Wait() without +// decrementing the count, and thus nobody can spuriosly wake up on the initial zero. + #ifndef ART_RUNTIME_BARRIER_H_ #define ART_RUNTIME_BARRIER_H_ @@ -22,20 +32,23 @@ namespace art { +// TODO: Maybe give this a better name. class Barrier { public: explicit Barrier(int count); virtual ~Barrier(); - // Pass through the barrier, decrements the count but does not block. + // Pass through the barrier, decrement the count but do not block. void Pass(Thread* self); // Wait on the barrier, decrement the count. void Wait(Thread* self); - // Set the count to a new value, if the value is 0 then everyone waiting on the condition - // variable is resumed. - void Init(Thread* self, int count); + // The following three calls are only safe if we somehow know that no other thread both + // - has been woken up, and + // - has not left the Wait() or Increment() call. + // If these calls are made in that situation, the offending thread is likely to go back + // to sleep, resulting in a deadlock. // Increment the count by delta, wait on condition if count is non zero. void Increment(Thread* self, int delta) LOCKS_EXCLUDED(lock_); @@ -44,6 +57,10 @@ class Barrier { // true if time out occurred. bool Increment(Thread* self, int delta, uint32_t timeout_ms) LOCKS_EXCLUDED(lock_); + // Set the count to a new value. This should only be used if there is no possibility that + // another thread is still in Wait(). See above. + void Init(Thread* self, int count); + private: void SetCountLocked(Thread* self, int count) EXCLUSIVE_LOCKS_REQUIRED(lock_); |