72 inline uint enter(); 73 74 // Exit a critical section for this synchronizer. 75 // Precondition: enter_value must be the result of the corresponding 76 // enter() for the critical section. 77 inline void exit(uint enter_value); 78 79 // Wait until all threads currently in a critical section for this 80 // synchronizer have exited their critical section. Threads that 81 // enter a critical section after the synchronization has started 82 // are not considered in the wait. 83 // Precondition: No other thread may be synchronizing on this 84 // synchronizer. 85 void synchronize(); 86 87 // RAII class for managing enter/exit pairs. 88 class CriticalSection; 89 }; 90 91 inline uint SingleWriterSynchronizer::enter() { 92 return Atomic::add(2u, &_enter); 93 } 94 95 inline void SingleWriterSynchronizer::exit(uint enter_value) { 96 uint exit_value = Atomic::add(2u, &_exit[enter_value & 1]); 97 // If this exit completes a synchronize request, wakeup possibly 98 // waiting synchronizer. Read of _waiting_for must follow the _exit 99 // update. 100 if (exit_value == _waiting_for) { 101 _wakeup.signal(); 102 } 103 } 104 105 class SingleWriterSynchronizer::CriticalSection : public StackObj { 106 SingleWriterSynchronizer* _synchronizer; 107 uint _enter_value; 108 109 public: 110 // Enter synchronizer's critical section. 111 explicit CriticalSection(SingleWriterSynchronizer* synchronizer) : 112 _synchronizer(synchronizer), 113 _enter_value(synchronizer->enter()) 114 {} 115 116 // Exit synchronizer's critical section. | 72 inline uint enter(); 73 74 // Exit a critical section for this synchronizer. 75 // Precondition: enter_value must be the result of the corresponding 76 // enter() for the critical section. 77 inline void exit(uint enter_value); 78 79 // Wait until all threads currently in a critical section for this 80 // synchronizer have exited their critical section. Threads that 81 // enter a critical section after the synchronization has started 82 // are not considered in the wait. 83 // Precondition: No other thread may be synchronizing on this 84 // synchronizer. 85 void synchronize(); 86 87 // RAII class for managing enter/exit pairs. 88 class CriticalSection; 89 }; 90 91 inline uint SingleWriterSynchronizer::enter() { 92 return Atomic::add(&_enter, 2u); 93 } 94 95 inline void SingleWriterSynchronizer::exit(uint enter_value) { 96 uint exit_value = Atomic::add(&_exit[enter_value & 1], 2u); 97 // If this exit completes a synchronize request, wakeup possibly 98 // waiting synchronizer. Read of _waiting_for must follow the _exit 99 // update. 100 if (exit_value == _waiting_for) { 101 _wakeup.signal(); 102 } 103 } 104 105 class SingleWriterSynchronizer::CriticalSection : public StackObj { 106 SingleWriterSynchronizer* _synchronizer; 107 uint _enter_value; 108 109 public: 110 // Enter synchronizer's critical section. 111 explicit CriticalSection(SingleWriterSynchronizer* synchronizer) : 112 _synchronizer(synchronizer), 113 _enter_value(synchronizer->enter()) 114 {} 115 116 // Exit synchronizer's critical section. |