Export of internal Abseil changes
-- 972333fe1e43427849b8a634aa35061e81be3642 by Abseil Team <absl-team@google.com>: Replace deprecated thread annotations macros. PiperOrigin-RevId: 267332619 -- 7039c6dc499a31c372b4872eda0772455931c360 by Gennadiy Rozental <rogeeff@google.com>: Internal change PiperOrigin-RevId: 267220271 -- a3f524d2afc2535686f206a7ce06961016349d7a by Abseil Team <absl-team@google.com>: Factor kernel_timeout out of synchronization. PiperOrigin-RevId: 267217304 -- 90287de4114ef9a06cafe50256a2d03349772c21 by Abseil Team <absl-team@google.com>: Fixed comment typo. PiperOrigin-RevId: 267198532 -- d312c1a1e52aeca1871ff0deead416d09a7f237e by Gennadiy Rozental <rogeeff@google.com>: Internal change PiperOrigin-RevId: 267185804 GitOrigin-RevId: 972333fe1e43427849b8a634aa35061e81be3642 Change-Id: Ia8a2f877c57cef9854aad48f1753af872fc04dc8
This commit is contained in:
		
							parent
							
								
									eb6b7bd23b
								
							
						
					
					
						commit
						83c1d65c90
					
				
					 27 changed files with 282 additions and 377 deletions
				
			
		|  | @ -30,11 +30,11 @@ absl::once_flag once; | ||||||
| 
 | 
 | ||||||
| ABSL_CONST_INIT Mutex counters_mu(absl::kConstInit); | ABSL_CONST_INIT Mutex counters_mu(absl::kConstInit); | ||||||
| 
 | 
 | ||||||
| int running_thread_count GUARDED_BY(counters_mu) = 0; | int running_thread_count ABSL_GUARDED_BY(counters_mu) = 0; | ||||||
| int call_once_invoke_count GUARDED_BY(counters_mu) = 0; | int call_once_invoke_count ABSL_GUARDED_BY(counters_mu) = 0; | ||||||
| int call_once_finished_count GUARDED_BY(counters_mu) = 0; | int call_once_finished_count ABSL_GUARDED_BY(counters_mu) = 0; | ||||||
| int call_once_return_count GUARDED_BY(counters_mu) = 0; | int call_once_return_count ABSL_GUARDED_BY(counters_mu) = 0; | ||||||
| bool done_blocking GUARDED_BY(counters_mu) = false; | bool done_blocking ABSL_GUARDED_BY(counters_mu) = false; | ||||||
| 
 | 
 | ||||||
| // Function to be called from absl::call_once.  Waits for a notification.
 | // Function to be called from absl::call_once.  Waits for a notification.
 | ||||||
| void WaitAndIncrement() { | void WaitAndIncrement() { | ||||||
|  | @ -60,7 +60,7 @@ void ThreadBody() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Returns true if all threads are set up for the test.
 | // Returns true if all threads are set up for the test.
 | ||||||
| bool ThreadsAreSetup(void*) EXCLUSIVE_LOCKS_REQUIRED(counters_mu) { | bool ThreadsAreSetup(void*) ABSL_EXCLUSIVE_LOCKS_REQUIRED(counters_mu) { | ||||||
|   // All ten threads must be running, and WaitAndIncrement should be blocked.
 |   // All ten threads must be running, and WaitAndIncrement should be blocked.
 | ||||||
|   return running_thread_count == 10 && call_once_invoke_count == 1; |   return running_thread_count == 10 && call_once_invoke_count == 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -203,9 +203,9 @@ struct LowLevelAlloc::Arena { | ||||||
| 
 | 
 | ||||||
|   base_internal::SpinLock mu; |   base_internal::SpinLock mu; | ||||||
|   // Head of free list, sorted by address
 |   // Head of free list, sorted by address
 | ||||||
|   AllocList freelist GUARDED_BY(mu); |   AllocList freelist ABSL_GUARDED_BY(mu); | ||||||
|   // Count of allocated blocks
 |   // Count of allocated blocks
 | ||||||
|   int32_t allocation_count GUARDED_BY(mu); |   int32_t allocation_count ABSL_GUARDED_BY(mu); | ||||||
|   // flags passed to NewArena
 |   // flags passed to NewArena
 | ||||||
|   const uint32_t flags; |   const uint32_t flags; | ||||||
|   // Result of sysconf(_SC_PAGESIZE)
 |   // Result of sysconf(_SC_PAGESIZE)
 | ||||||
|  | @ -215,7 +215,7 @@ struct LowLevelAlloc::Arena { | ||||||
|   // Smallest allocation block size
 |   // Smallest allocation block size
 | ||||||
|   const size_t min_size; |   const size_t min_size; | ||||||
|   // PRNG state
 |   // PRNG state
 | ||||||
|   uint32_t random GUARDED_BY(mu); |   uint32_t random ABSL_GUARDED_BY(mu); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| namespace { | namespace { | ||||||
|  | @ -275,10 +275,10 @@ static const uintptr_t kMagicAllocated = 0x4c833e95U; | ||||||
| static const uintptr_t kMagicUnallocated = ~kMagicAllocated; | static const uintptr_t kMagicUnallocated = ~kMagicAllocated; | ||||||
| 
 | 
 | ||||||
| namespace { | namespace { | ||||||
| class SCOPED_LOCKABLE ArenaLock { | class ABSL_SCOPED_LOCKABLE ArenaLock { | ||||||
|  public: |  public: | ||||||
|   explicit ArenaLock(LowLevelAlloc::Arena *arena) |   explicit ArenaLock(LowLevelAlloc::Arena *arena) | ||||||
|       EXCLUSIVE_LOCK_FUNCTION(arena->mu) |       ABSL_EXCLUSIVE_LOCK_FUNCTION(arena->mu) | ||||||
|       : arena_(arena) { |       : arena_(arena) { | ||||||
| #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING | #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING | ||||||
|     if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { |     if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { | ||||||
|  | @ -290,7 +290,7 @@ class SCOPED_LOCKABLE ArenaLock { | ||||||
|     arena_->mu.Lock(); |     arena_->mu.Lock(); | ||||||
|   } |   } | ||||||
|   ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); } |   ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); } | ||||||
|   void Leave() UNLOCK_FUNCTION() { |   void Leave() ABSL_UNLOCK_FUNCTION() { | ||||||
|     arena_->mu.Unlock(); |     arena_->mu.Unlock(); | ||||||
| #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING | #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING | ||||||
|     if (mask_valid_) { |     if (mask_valid_) { | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ | ||||||
| namespace absl { | namespace absl { | ||||||
| namespace base_internal { | namespace base_internal { | ||||||
| 
 | 
 | ||||||
| class LOCKABLE SpinLock { | class ABSL_LOCKABLE SpinLock { | ||||||
|  public: |  public: | ||||||
|   SpinLock() : lockword_(kSpinLockCooperative) { |   SpinLock() : lockword_(kSpinLockCooperative) { | ||||||
|     ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); |     ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); | ||||||
|  | @ -79,7 +79,7 @@ class LOCKABLE SpinLock { | ||||||
|   ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); } |   ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); } | ||||||
| 
 | 
 | ||||||
|   // Acquire this SpinLock.
 |   // Acquire this SpinLock.
 | ||||||
|   inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { |   inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { | ||||||
|     ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); |     ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); | ||||||
|     if (!TryLockImpl()) { |     if (!TryLockImpl()) { | ||||||
|       SlowLock(); |       SlowLock(); | ||||||
|  | @ -91,7 +91,7 @@ class LOCKABLE SpinLock { | ||||||
|   // acquisition was successful.  If the lock was not acquired, false is
 |   // acquisition was successful.  If the lock was not acquired, false is
 | ||||||
|   // returned.  If this SpinLock is free at the time of the call, TryLock
 |   // returned.  If this SpinLock is free at the time of the call, TryLock
 | ||||||
|   // will return true with high probability.
 |   // will return true with high probability.
 | ||||||
|   inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { |   inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { | ||||||
|     ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); |     ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); | ||||||
|     bool res = TryLockImpl(); |     bool res = TryLockImpl(); | ||||||
|     ABSL_TSAN_MUTEX_POST_LOCK( |     ABSL_TSAN_MUTEX_POST_LOCK( | ||||||
|  | @ -101,7 +101,7 @@ class LOCKABLE SpinLock { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Release this SpinLock, which must be held by the calling thread.
 |   // Release this SpinLock, which must be held by the calling thread.
 | ||||||
|   inline void Unlock() UNLOCK_FUNCTION() { |   inline void Unlock() ABSL_UNLOCK_FUNCTION() { | ||||||
|     ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0); |     ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0); | ||||||
|     uint32_t lock_value = lockword_.load(std::memory_order_relaxed); |     uint32_t lock_value = lockword_.load(std::memory_order_relaxed); | ||||||
|     lock_value = lockword_.exchange(lock_value & kSpinLockCooperative, |     lock_value = lockword_.exchange(lock_value & kSpinLockCooperative, | ||||||
|  | @ -179,13 +179,13 @@ class LOCKABLE SpinLock { | ||||||
| 
 | 
 | ||||||
| // Corresponding locker object that arranges to acquire a spinlock for
 | // Corresponding locker object that arranges to acquire a spinlock for
 | ||||||
| // the duration of a C++ scope.
 | // the duration of a C++ scope.
 | ||||||
| class SCOPED_LOCKABLE SpinLockHolder { | class ABSL_SCOPED_LOCKABLE SpinLockHolder { | ||||||
|  public: |  public: | ||||||
|   inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l) |   inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l) | ||||||
|       : lock_(l) { |       : lock_(l) { | ||||||
|     l->Lock(); |     l->Lock(); | ||||||
|   } |   } | ||||||
|   inline ~SpinLockHolder() UNLOCK_FUNCTION() { lock_->Unlock(); } |   inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_->Unlock(); } | ||||||
| 
 | 
 | ||||||
|   SpinLockHolder(const SpinLockHolder&) = delete; |   SpinLockHolder(const SpinLockHolder&) = delete; | ||||||
|   SpinLockHolder& operator=(const SpinLockHolder&) = delete; |   SpinLockHolder& operator=(const SpinLockHolder&) = delete; | ||||||
|  |  | ||||||
|  | @ -65,7 +65,7 @@ struct HashtablezInfo { | ||||||
| 
 | 
 | ||||||
|   // Puts the object into a clean state, fills in the logically `const` members,
 |   // Puts the object into a clean state, fills in the logically `const` members,
 | ||||||
|   // blocking for any readers that are currently sampling the object.
 |   // blocking for any readers that are currently sampling the object.
 | ||||||
|   void PrepareForSampling() EXCLUSIVE_LOCKS_REQUIRED(init_mu); |   void PrepareForSampling() ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu); | ||||||
| 
 | 
 | ||||||
|   // These fields are mutated by the various Record* APIs and need to be
 |   // These fields are mutated by the various Record* APIs and need to be
 | ||||||
|   // thread-safe.
 |   // thread-safe.
 | ||||||
|  | @ -83,7 +83,7 @@ struct HashtablezInfo { | ||||||
|   // prevents races with sampling and resurrecting an object.
 |   // prevents races with sampling and resurrecting an object.
 | ||||||
|   absl::Mutex init_mu; |   absl::Mutex init_mu; | ||||||
|   HashtablezInfo* next; |   HashtablezInfo* next; | ||||||
|   HashtablezInfo* dead GUARDED_BY(init_mu); |   HashtablezInfo* dead ABSL_GUARDED_BY(init_mu); | ||||||
| 
 | 
 | ||||||
|   // All of the fields below are set by `PrepareForSampling`, they must not be
 |   // All of the fields below are set by `PrepareForSampling`, they must not be
 | ||||||
|   // mutated in `Record*` functions.  They are logically `const` in that sense.
 |   // mutated in `Record*` functions.  They are logically `const` in that sense.
 | ||||||
|  |  | ||||||
|  | @ -58,55 +58,55 @@ absl::Mutex* InitFlag(CommandLineFlag* flag) { | ||||||
|   { |   { | ||||||
|     absl::MutexLock lock(&init_lock); |     absl::MutexLock lock(&init_lock); | ||||||
| 
 | 
 | ||||||
|     if (flag->locks == nullptr) {  // Must initialize Mutexes for this flag.
 |     if (flag->locks_ == nullptr) {  // Must initialize Mutexes for this flag.
 | ||||||
|       flag->locks = new flags_internal::CommandLineFlagLocks; |       flag->locks_ = new flags_internal::CommandLineFlagLocks; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     mu = &flag->locks->primary_mu; |     mu = &flag->locks_->primary_mu; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   { |   { | ||||||
|     absl::MutexLock lock(mu); |     absl::MutexLock lock(mu); | ||||||
| 
 | 
 | ||||||
|     if (!flag->IsRetired() && flag->def == nullptr) { |     if (!flag->IsRetired() && flag->def_ == nullptr) { | ||||||
|       // Need to initialize def and cur fields.
 |       // Need to initialize def and cur fields.
 | ||||||
|       flag->def = (*flag->make_init_value)(); |       flag->def_ = (*flag->make_init_value_)(); | ||||||
|       flag->cur = Clone(flag->op, flag->def); |       flag->cur_ = Clone(flag->op_, flag->def_); | ||||||
|       UpdateCopy(flag); |       UpdateCopy(flag); | ||||||
|       flag->inited.store(true, std::memory_order_release); |       flag->inited_.store(true, std::memory_order_release); | ||||||
|       flag->InvokeCallback(); |       flag->InvokeCallback(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   flag->inited.store(true, std::memory_order_release); |   flag->inited_.store(true, std::memory_order_release); | ||||||
|   return mu; |   return mu; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Ensure that the lazily initialized fields of *flag have been initialized,
 | // Ensure that the lazily initialized fields of *flag have been initialized,
 | ||||||
| // and return &flag->locks->primary_mu.
 | // and return &flag->locks_->primary_mu.
 | ||||||
| absl::Mutex* CommandLineFlag::InitFlagIfNecessary() const | absl::Mutex* CommandLineFlag::InitFlagIfNecessary() const | ||||||
|     LOCK_RETURNED(locks->primary_mu) { |     ABSL_LOCK_RETURNED(locks_->primary_mu) { | ||||||
|   if (!this->inited.load(std::memory_order_acquire)) { |   if (!inited_.load(std::memory_order_acquire)) { | ||||||
|     return InitFlag(const_cast<CommandLineFlag*>(this)); |     return InitFlag(const_cast<CommandLineFlag*>(this)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // All fields initialized; this->locks is therefore safe to read.
 |   // All fields initialized; locks_ is therefore safe to read.
 | ||||||
|   return &this->locks->primary_mu; |   return &locks_->primary_mu; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool CommandLineFlag::IsModified() const { | bool CommandLineFlag::IsModified() const { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
|   return modified; |   return modified_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CommandLineFlag::SetModified(bool is_modified) { | void CommandLineFlag::SetModified(bool is_modified) { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
|   modified = is_modified; |   modified_ = is_modified; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool CommandLineFlag::IsSpecifiedOnCommandLine() const { | bool CommandLineFlag::IsSpecifiedOnCommandLine() const { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
|   return on_command_line; |   return on_command_line_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| absl::string_view CommandLineFlag::Typename() const { | absl::string_view CommandLineFlag::Typename() const { | ||||||
|  | @ -134,19 +134,19 @@ absl::string_view CommandLineFlag::Typename() const { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string CommandLineFlag::Filename() const { | std::string CommandLineFlag::Filename() const { | ||||||
|   return flags_internal::GetUsageConfig().normalize_filename(this->filename); |   return flags_internal::GetUsageConfig().normalize_filename(filename_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string CommandLineFlag::DefaultValue() const { | std::string CommandLineFlag::DefaultValue() const { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
| 
 | 
 | ||||||
|   return Unparse(this->marshalling_op, this->def); |   return Unparse(marshalling_op_, def_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string CommandLineFlag::CurrentValue() const { | std::string CommandLineFlag::CurrentValue() const { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
| 
 | 
 | ||||||
|   return Unparse(this->marshalling_op, this->cur); |   return Unparse(marshalling_op_, cur_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Attempts to parse supplied `value` string using parsing routine in the `flag`
 | // Attempts to parse supplied `value` string using parsing routine in the `flag`
 | ||||||
|  | @ -157,31 +157,31 @@ std::string CommandLineFlag::CurrentValue() const { | ||||||
| // in 'err'
 | // in 'err'
 | ||||||
| bool TryParseLocked(CommandLineFlag* flag, void* dst, absl::string_view value, | bool TryParseLocked(CommandLineFlag* flag, void* dst, absl::string_view value, | ||||||
|                     std::string* err) |                     std::string* err) | ||||||
|     EXCLUSIVE_LOCKS_REQUIRED(flag->locks->primary_mu) { |     ABSL_EXCLUSIVE_LOCKS_REQUIRED(flag->locks_->primary_mu) { | ||||||
|   void* tentative_value = Clone(flag->op, flag->def); |   void* tentative_value = Clone(flag->op_, flag->def_); | ||||||
|   std::string parse_err; |   std::string parse_err; | ||||||
|   if (!Parse(flag->marshalling_op, value, tentative_value, &parse_err)) { |   if (!Parse(flag->marshalling_op_, value, tentative_value, &parse_err)) { | ||||||
|     auto type_name = flag->Typename(); |     auto type_name = flag->Typename(); | ||||||
|     absl::string_view err_sep = parse_err.empty() ? "" : "; "; |     absl::string_view err_sep = parse_err.empty() ? "" : "; "; | ||||||
|     absl::string_view typename_sep = type_name.empty() ? "" : " "; |     absl::string_view typename_sep = type_name.empty() ? "" : " "; | ||||||
|     *err = absl::StrCat("Illegal value '", value, "' specified for", |     *err = absl::StrCat("Illegal value '", value, "' specified for", | ||||||
|                         typename_sep, type_name, " flag '", flag->Name(), "'", |                         typename_sep, type_name, " flag '", flag->Name(), "'", | ||||||
|                         err_sep, parse_err); |                         err_sep, parse_err); | ||||||
|     Delete(flag->op, tentative_value); |     Delete(flag->op_, tentative_value); | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!flag->InvokeValidator(tentative_value)) { |   if (!flag->InvokeValidator(tentative_value)) { | ||||||
|     *err = absl::StrCat("Failed validation of new value '", |     *err = absl::StrCat("Failed validation of new value '", | ||||||
|                         Unparse(flag->marshalling_op, tentative_value), |                         Unparse(flag->marshalling_op_, tentative_value), | ||||||
|                         "' for flag '", flag->Name(), "'"); |                         "' for flag '", flag->Name(), "'"); | ||||||
|     Delete(flag->op, tentative_value); |     Delete(flag->op_, tentative_value); | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   flag->counter++; |   flag->counter_++; | ||||||
|   Copy(flag->op, tentative_value, dst); |   Copy(flag->op_, tentative_value, dst); | ||||||
|   Delete(flag->op, tentative_value); |   Delete(flag->op_, tentative_value); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -201,38 +201,38 @@ bool CommandLineFlag::SetFromString(absl::string_view value, | ||||||
|   absl::MutexLock l(InitFlagIfNecessary()); |   absl::MutexLock l(InitFlagIfNecessary()); | ||||||
| 
 | 
 | ||||||
|   // Direct-access flags can be modified without going through the
 |   // Direct-access flags can be modified without going through the
 | ||||||
|   // flag API. Detect such changes and update the flag->modified bit.
 |   // flag API. Detect such changes and update the flag->modified_ bit.
 | ||||||
|   if (!IsAbseilFlag()) { |   if (!IsAbseilFlag()) { | ||||||
|     if (!this->modified && ChangedDirectly(this, this->cur, this->def)) { |     if (!modified_ && ChangedDirectly(this, cur_, def_)) { | ||||||
|       this->modified = true; |       modified_ = true; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   switch (set_mode) { |   switch (set_mode) { | ||||||
|     case SET_FLAGS_VALUE: { |     case SET_FLAGS_VALUE: { | ||||||
|       // set or modify the flag's value
 |       // set or modify the flag's value
 | ||||||
|       if (!TryParseLocked(this, this->cur, value, err)) return false; |       if (!TryParseLocked(this, cur_, value, err)) return false; | ||||||
|       this->modified = true; |       modified_ = true; | ||||||
|       UpdateCopy(this); |       UpdateCopy(this); | ||||||
|       InvokeCallback(); |       InvokeCallback(); | ||||||
| 
 | 
 | ||||||
|       if (source == kCommandLine) { |       if (source == kCommandLine) { | ||||||
|         this->on_command_line = true; |         on_command_line_ = true; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|     case SET_FLAG_IF_DEFAULT: { |     case SET_FLAG_IF_DEFAULT: { | ||||||
|       // set the flag's value, but only if it hasn't been set by someone else
 |       // set the flag's value, but only if it hasn't been set by someone else
 | ||||||
|       if (!this->modified) { |       if (!modified_) { | ||||||
|         if (!TryParseLocked(this, this->cur, value, err)) return false; |         if (!TryParseLocked(this, cur_, value, err)) return false; | ||||||
|         this->modified = true; |         modified_ = true; | ||||||
|         UpdateCopy(this); |         UpdateCopy(this); | ||||||
|         InvokeCallback(); |         InvokeCallback(); | ||||||
|       } else { |       } else { | ||||||
|         // TODO(rogeeff): review and fix this semantic. Currently we do not fail
 |         // TODO(rogeeff): review and fix this semantic. Currently we do not fail
 | ||||||
|         // in this case if flag is modified. This is misleading since the flag's
 |         // in this case if flag is modified. This is misleading since the flag's
 | ||||||
|         // value is not updated even though we return true.
 |         // value is not updated even though we return true.
 | ||||||
|         // *err = absl::StrCat(this->Name(), " is already set to ",
 |         // *err = absl::StrCat(Name(), " is already set to ",
 | ||||||
|         //                     CurrentValue(), "\n");
 |         //                     CurrentValue(), "\n");
 | ||||||
|         // return false;
 |         // return false;
 | ||||||
|         return true; |         return true; | ||||||
|  | @ -241,11 +241,11 @@ bool CommandLineFlag::SetFromString(absl::string_view value, | ||||||
|     } |     } | ||||||
|     case SET_FLAGS_DEFAULT: { |     case SET_FLAGS_DEFAULT: { | ||||||
|       // modify the flag's default-value
 |       // modify the flag's default-value
 | ||||||
|       if (!TryParseLocked(this, this->def, value, err)) return false; |       if (!TryParseLocked(this, def_, value, err)) return false; | ||||||
| 
 | 
 | ||||||
|       if (!this->modified) { |       if (!modified_) { | ||||||
|         // Need to set both defvalue *and* current, in this case
 |         // Need to set both defvalue *and* current, in this case
 | ||||||
|         Copy(this->op, this->def, this->cur); |         Copy(op_, def_, cur_); | ||||||
|         UpdateCopy(this); |         UpdateCopy(this); | ||||||
|         InvokeCallback(); |         InvokeCallback(); | ||||||
|       } |       } | ||||||
|  | @ -264,8 +264,8 @@ bool CommandLineFlag::SetFromString(absl::string_view value, | ||||||
| void CommandLineFlag::StoreAtomic(size_t size) { | void CommandLineFlag::StoreAtomic(size_t size) { | ||||||
|   int64_t t = 0; |   int64_t t = 0; | ||||||
|   assert(size <= sizeof(int64_t)); |   assert(size <= sizeof(int64_t)); | ||||||
|   memcpy(&t, this->cur, size); |   memcpy(&t, cur_, size); | ||||||
|   this->atomic.store(t, std::memory_order_release); |   atomic_.store(t, std::memory_order_release); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const { | void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const { | ||||||
|  | @ -273,9 +273,9 @@ void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const { | ||||||
| 
 | 
 | ||||||
|   absl::MutexLock lock(InitFlagIfNecessary()); |   absl::MutexLock lock(InitFlagIfNecessary()); | ||||||
| 
 | 
 | ||||||
|   void* dst = Clone(this->op, this->def); |   void* dst = Clone(op_, def_); | ||||||
|   std::string error; |   std::string error; | ||||||
|   if (!flags_internal::Parse(this->marshalling_op, v, dst, &error)) { |   if (!flags_internal::Parse(marshalling_op_, v, dst, &error)) { | ||||||
|     ABSL_INTERNAL_LOG( |     ABSL_INTERNAL_LOG( | ||||||
|         FATAL, |         FATAL, | ||||||
|         absl::StrCat("Flag ", Name(), " (from ", Filename(), |         absl::StrCat("Flag ", Name(), " (from ", Filename(), | ||||||
|  | @ -285,23 +285,23 @@ void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const { | ||||||
| 
 | 
 | ||||||
|   // We do not compare dst to def since parsing/unparsing may make
 |   // We do not compare dst to def since parsing/unparsing may make
 | ||||||
|   // small changes, e.g., precision loss for floating point types.
 |   // small changes, e.g., precision loss for floating point types.
 | ||||||
|   Delete(this->op, dst); |   Delete(op_, dst); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool CommandLineFlag::ValidateDefaultValue() const { | bool CommandLineFlag::ValidateDefaultValue() const { | ||||||
|   absl::MutexLock lock(InitFlagIfNecessary()); |   absl::MutexLock lock(InitFlagIfNecessary()); | ||||||
|   return InvokeValidator(this->def); |   return InvokeValidator(def_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool CommandLineFlag::ValidateInputValue(absl::string_view value) const { | bool CommandLineFlag::ValidateInputValue(absl::string_view value) const { | ||||||
|   absl::MutexLock l(InitFlagIfNecessary());  // protect default value access
 |   absl::MutexLock l(InitFlagIfNecessary());  // protect default value access
 | ||||||
| 
 | 
 | ||||||
|   void* obj = Clone(this->op, this->def); |   void* obj = Clone(op_, def_); | ||||||
|   std::string ignored_error; |   std::string ignored_error; | ||||||
|   const bool result = |   const bool result = | ||||||
|       flags_internal::Parse(this->marshalling_op, value, obj, &ignored_error) && |       flags_internal::Parse(marshalling_op_, value, obj, &ignored_error) && | ||||||
|       InvokeValidator(obj); |       InvokeValidator(obj); | ||||||
|   Delete(this->op, obj); |   Delete(op_, obj); | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -314,13 +314,13 @@ void CommandLineFlag::Read(void* dst, | ||||||
|   // `dst_op` is the unmarshaling operation corresponding to the declaration
 |   // `dst_op` is the unmarshaling operation corresponding to the declaration
 | ||||||
|   // visibile at the call site. `op` is the Flag's defined unmarshalling
 |   // visibile at the call site. `op` is the Flag's defined unmarshalling
 | ||||||
|   // operation. They must match for this operation to be well-defined.
 |   // operation. They must match for this operation to be well-defined.
 | ||||||
|   if (ABSL_PREDICT_FALSE(dst_op != op)) { |   if (ABSL_PREDICT_FALSE(dst_op != op_)) { | ||||||
|     ABSL_INTERNAL_LOG( |     ABSL_INTERNAL_LOG( | ||||||
|         ERROR, |         ERROR, | ||||||
|         absl::StrCat("Flag '", name, |         absl::StrCat("Flag '", Name(), | ||||||
|                      "' is defined as one type and declared as another")); |                      "' is defined as one type and declared as another")); | ||||||
|   } |   } | ||||||
|   CopyConstruct(op, cur, dst); |   CopyConstruct(op_, cur_, dst); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CommandLineFlag::Write(const void* src, | void CommandLineFlag::Write(const void* src, | ||||||
|  | @ -330,28 +330,28 @@ void CommandLineFlag::Write(const void* src, | ||||||
|   // `src_op` is the marshalling operation corresponding to the declaration
 |   // `src_op` is the marshalling operation corresponding to the declaration
 | ||||||
|   // visible at the call site. `op` is the Flag's defined marshalling operation.
 |   // visible at the call site. `op` is the Flag's defined marshalling operation.
 | ||||||
|   // They must match for this operation to be well-defined.
 |   // They must match for this operation to be well-defined.
 | ||||||
|   if (ABSL_PREDICT_FALSE(src_op != op)) { |   if (ABSL_PREDICT_FALSE(src_op != op_)) { | ||||||
|     ABSL_INTERNAL_LOG( |     ABSL_INTERNAL_LOG( | ||||||
|         ERROR, |         ERROR, | ||||||
|         absl::StrCat("Flag '", name, |         absl::StrCat("Flag '", Name(), | ||||||
|                      "' is defined as one type and declared as another")); |                      "' is defined as one type and declared as another")); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (ShouldValidateFlagValue(*this)) { |   if (ShouldValidateFlagValue(*this)) { | ||||||
|     void* obj = Clone(op, src); |     void* obj = Clone(op_, src); | ||||||
|     std::string ignored_error; |     std::string ignored_error; | ||||||
|     std::string src_as_str = Unparse(marshalling_op, src); |     std::string src_as_str = Unparse(marshalling_op_, src); | ||||||
|     if (!Parse(marshalling_op, src_as_str, obj, &ignored_error) || |     if (!Parse(marshalling_op_, src_as_str, obj, &ignored_error) || | ||||||
|         !InvokeValidator(obj)) { |         !InvokeValidator(obj)) { | ||||||
|       ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", name, |       ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(), | ||||||
|                                             "' to invalid value ", src_as_str)); |                                             "' to invalid value ", src_as_str)); | ||||||
|     } |     } | ||||||
|     Delete(op, obj); |     Delete(op_, obj); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   modified = true; |   modified_ = true; | ||||||
|   counter++; |   counter_++; | ||||||
|   Copy(op, src, cur); |   Copy(op_, src, cur_); | ||||||
| 
 | 
 | ||||||
|   UpdateCopy(this); |   UpdateCopy(this); | ||||||
|   InvokeCallback(); |   InvokeCallback(); | ||||||
|  |  | ||||||
|  | @ -69,8 +69,6 @@ using HelpGenFunc = std::string (*)(); | ||||||
| // based on default value supplied in flag's definition)
 | // based on default value supplied in flag's definition)
 | ||||||
| using InitialValGenFunc = void* (*)(); | using InitialValGenFunc = void* (*)(); | ||||||
| 
 | 
 | ||||||
| struct CommandLineFlagInfo; |  | ||||||
| 
 |  | ||||||
| extern const char kStrippedFlagHelp[]; | extern const char kStrippedFlagHelp[]; | ||||||
| 
 | 
 | ||||||
| // The per-type function
 | // The per-type function
 | ||||||
|  | @ -189,27 +187,28 @@ class HelpText { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Holds all information for a flag.
 | // Holds all information for a flag.
 | ||||||
| struct CommandLineFlag { | class CommandLineFlag { | ||||||
|  |  public: | ||||||
|   constexpr CommandLineFlag( |   constexpr CommandLineFlag( | ||||||
|       const char* name_arg, HelpText help_text, const char* filename_arg, |       const char* name, HelpText help_text, const char* filename, | ||||||
|       const flags_internal::FlagOpFn op_arg, |       const flags_internal::FlagOpFn op, | ||||||
|       const flags_internal::FlagMarshallingOpFn marshalling_op_arg, |       const flags_internal::FlagMarshallingOpFn marshalling_op, | ||||||
|       const flags_internal::InitialValGenFunc initial_value_gen, void* def_arg, |       const flags_internal::InitialValGenFunc initial_value_gen, void* def, | ||||||
|       void* cur_arg) |       void* cur) | ||||||
|       : name(name_arg), |       : name_(name), | ||||||
|         help(help_text), |         help_(help_text), | ||||||
|         filename(filename_arg), |         filename_(filename), | ||||||
|         op(op_arg), |         op_(op), | ||||||
|         marshalling_op(marshalling_op_arg), |         marshalling_op_(marshalling_op), | ||||||
|         make_init_value(initial_value_gen), |         make_init_value_(initial_value_gen), | ||||||
|         inited(false), |         inited_(false), | ||||||
|         modified(false), |         modified_(false), | ||||||
|         on_command_line(false), |         on_command_line_(false), | ||||||
|         def(def_arg), |         def_(def), | ||||||
|         cur(cur_arg), |         cur_(cur), | ||||||
|         counter(0), |         counter_(0), | ||||||
|         atomic(kAtomicInit), |         atomic_(kAtomicInit), | ||||||
|         locks(nullptr) {} |         locks_(nullptr) {} | ||||||
| 
 | 
 | ||||||
|   // Virtual destructor
 |   // Virtual destructor
 | ||||||
|   virtual void Destroy() const = 0; |   virtual void Destroy() const = 0; | ||||||
|  | @ -225,8 +224,8 @@ struct CommandLineFlag { | ||||||
|   // Returns true iff this is a handle to an Abseil Flag.
 |   // Returns true iff this is a handle to an Abseil Flag.
 | ||||||
|   virtual bool IsAbseilFlag() const { return true; } |   virtual bool IsAbseilFlag() const { return true; } | ||||||
| 
 | 
 | ||||||
|   absl::string_view Name() const { return name; } |   absl::string_view Name() const { return name_; } | ||||||
|   std::string Help() const { return help.GetHelpText(); } |   std::string Help() const { return help_.GetHelpText(); } | ||||||
|   bool IsModified() const; |   bool IsModified() const; | ||||||
|   void SetModified(bool is_modified); |   void SetModified(bool is_modified); | ||||||
|   bool IsSpecifiedOnCommandLine() const; |   bool IsSpecifiedOnCommandLine() const; | ||||||
|  | @ -247,15 +246,14 @@ struct CommandLineFlag { | ||||||
|   // Return true iff flag has type T.
 |   // Return true iff flag has type T.
 | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   inline bool IsOfType() const { |   inline bool IsOfType() const { | ||||||
|     return this->op == &flags_internal::FlagOps<T>; |     return op_ == &flags_internal::FlagOps<T>; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Attempts to retrieve the flag value. Returns value on success,
 |   // Attempts to retrieve the flag value. Returns value on success,
 | ||||||
|   // absl::nullopt otherwise.
 |   // absl::nullopt otherwise.
 | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   absl::optional<T> Get() const { |   absl::optional<T> Get() const { | ||||||
|     if (IsRetired() || flags_internal::FlagOps<T> != this->op) |     if (IsRetired() || flags_internal::FlagOps<T> != op_) return absl::nullopt; | ||||||
|       return absl::nullopt; |  | ||||||
| 
 | 
 | ||||||
|     T res; |     T res; | ||||||
|     Read(&res, flags_internal::FlagOps<T>); |     Read(&res, flags_internal::FlagOps<T>); | ||||||
|  | @ -286,36 +284,36 @@ struct CommandLineFlag { | ||||||
|  protected: |  protected: | ||||||
|   ~CommandLineFlag() = default; |   ~CommandLineFlag() = default; | ||||||
| 
 | 
 | ||||||
|   const char* const name; |   const char* const name_; | ||||||
|   const HelpText help; |   const HelpText help_; | ||||||
|   const char* const filename; |   const char* const filename_; | ||||||
| 
 | 
 | ||||||
|   const FlagOpFn op;                         // Type-specific handler
 |   const FlagOpFn op_;                         // Type-specific handler
 | ||||||
|   const FlagMarshallingOpFn marshalling_op;  // Marshalling ops handler
 |   const FlagMarshallingOpFn marshalling_op_;  // Marshalling ops handler
 | ||||||
|   const InitialValGenFunc make_init_value;   // Makes initial value for the flag
 |   const InitialValGenFunc make_init_value_;  // Makes initial value for the flag
 | ||||||
|   std::atomic<bool> inited;  // fields have been lazily initialized
 |   std::atomic<bool> inited_;  // fields have been lazily initialized
 | ||||||
| 
 | 
 | ||||||
|   // Mutable state (guarded by locks->primary_mu).
 |   // Mutable state (guarded by locks_->primary_mu).
 | ||||||
|   bool modified;            // Has flag value been modified?
 |   bool modified_;         // Has flag value been modified?
 | ||||||
|   bool on_command_line;     // Specified on command line.
 |   bool on_command_line_;  // Specified on command line.
 | ||||||
|   void* def;                // Lazily initialized pointer to default value
 |   void* def_;             // Lazily initialized pointer to default value
 | ||||||
|   void* cur;                // Lazily initialized pointer to current value
 |   void* cur_;             // Lazily initialized pointer to current value
 | ||||||
|   int64_t counter;            // Mutation counter
 |   int64_t counter_;         // Mutation counter
 | ||||||
| 
 | 
 | ||||||
|   // For some types, a copy of the current value is kept in an atomically
 |   // For some types, a copy of the current value is kept in an atomically
 | ||||||
|   // accessible field.
 |   // accessible field.
 | ||||||
|   static const int64_t kAtomicInit = 0xababababababababll; |   static const int64_t kAtomicInit = 0xababababababababll; | ||||||
|   std::atomic<int64_t> atomic; |   std::atomic<int64_t> atomic_; | ||||||
| 
 | 
 | ||||||
|   // Lazily initialized mutexes for this flag value.  We cannot inline a
 |   // Lazily initialized mutexes for this flag value.  We cannot inline a
 | ||||||
|   // SpinLock or Mutex here because those have non-constexpr constructors and
 |   // SpinLock or Mutex here because those have non-constexpr constructors and
 | ||||||
|   // so would prevent constant initialization of this type.
 |   // so would prevent constant initialization of this type.
 | ||||||
|   // TODO(rogeeff): fix it once Mutex has constexpr constructor
 |   // TODO(rogeeff): fix it once Mutex has constexpr constructor
 | ||||||
|   struct CommandLineFlagLocks* locks;  // locks, laziliy allocated.
 |   struct CommandLineFlagLocks* locks_;  // locks, laziliy allocated.
 | ||||||
| 
 | 
 | ||||||
|   // Ensure that the lazily initialized fields of *flag have been initialized,
 |   // Ensure that the lazily initialized fields of *flag have been initialized,
 | ||||||
|   // and return the lock which should be locked when flag's state is mutated.
 |   // and return the lock which should be locked when flag's state is mutated.
 | ||||||
|   absl::Mutex* InitFlagIfNecessary() const LOCK_RETURNED(locks->primary_mu); |   absl::Mutex* InitFlagIfNecessary() const ABSL_LOCK_RETURNED(locks_->primary_mu); | ||||||
| 
 | 
 | ||||||
|   // copy construct new value of flag's type in a memory referenced by dst
 |   // copy construct new value of flag's type in a memory referenced by dst
 | ||||||
|   // based on current flag's value
 |   // based on current flag's value
 | ||||||
|  | @ -326,8 +324,6 @@ struct CommandLineFlag { | ||||||
|   friend class FlagRegistry; |   friend class FlagRegistry; | ||||||
|   friend class FlagPtrMap; |   friend class FlagPtrMap; | ||||||
|   friend class FlagSaverImpl; |   friend class FlagSaverImpl; | ||||||
|   friend void FillCommandLineFlagInfo(CommandLineFlag* flag, |  | ||||||
|                                       CommandLineFlagInfo* result); |  | ||||||
|   friend bool TryParseLocked(CommandLineFlag* flag, void* dst, |   friend bool TryParseLocked(CommandLineFlag* flag, void* dst, | ||||||
|                              absl::string_view value, std::string* err); |                              absl::string_view value, std::string* err); | ||||||
|   friend absl::Mutex* InitFlag(CommandLineFlag* flag); |   friend absl::Mutex* InitFlag(CommandLineFlag* flag); | ||||||
|  | @ -335,7 +331,7 @@ struct CommandLineFlag { | ||||||
|   // This is a short term, until we completely rework persistent state
 |   // This is a short term, until we completely rework persistent state
 | ||||||
|   // storage API.
 |   // storage API.
 | ||||||
|   virtual void* GetValidator() const { return nullptr; } |   virtual void* GetValidator() const { return nullptr; } | ||||||
|   virtual void SetValidator(void*) {} |   virtual bool SetValidator(void*) { return false; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Update any copy of the flag value that is stored in an atomic word.
 | // Update any copy of the flag value that is stored in an atomic word.
 | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ namespace flags_internal { | ||||||
| // completed. Requires that *primary_lock be held in exclusive mode; it may be
 | // completed. Requires that *primary_lock be held in exclusive mode; it may be
 | ||||||
| // released and reacquired by the implementation.
 | // released and reacquired by the implementation.
 | ||||||
| void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu, | void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu, | ||||||
|                     FlagCallback cb) EXCLUSIVE_LOCKS_REQUIRED(primary_mu) { |                     FlagCallback cb) ABSL_EXCLUSIVE_LOCKS_REQUIRED(primary_mu) { | ||||||
|   if (!cb) return; |   if (!cb) return; | ||||||
| 
 | 
 | ||||||
|   // When executing the callback we need the primary flag's mutex to be
 |   // When executing the callback we need the primary flag's mutex to be
 | ||||||
|  |  | ||||||
|  | @ -28,23 +28,22 @@ namespace flags_internal { | ||||||
| using FlagCallback = void (*)(); | using FlagCallback = void (*)(); | ||||||
| 
 | 
 | ||||||
| void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu, | void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu, | ||||||
|                     FlagCallback cb) EXCLUSIVE_LOCKS_REQUIRED(primary_mu); |                     FlagCallback cb) ABSL_EXCLUSIVE_LOCKS_REQUIRED(primary_mu); | ||||||
| 
 | 
 | ||||||
| // This is "unspecified" implementation of absl::Flag<T> type.
 | // This is "unspecified" implementation of absl::Flag<T> type.
 | ||||||
| template <typename T> | template <typename T> | ||||||
| class Flag final : public flags_internal::CommandLineFlag { | class Flag final : public flags_internal::CommandLineFlag { | ||||||
|  public: |  public: | ||||||
|   constexpr Flag(const char* name_arg, |   constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen, | ||||||
|                  const flags_internal::HelpGenFunc help_gen, |                  const char* filename, | ||||||
|                  const char* filename_arg, |                  const flags_internal::FlagMarshallingOpFn marshalling_op, | ||||||
|                  const flags_internal::FlagMarshallingOpFn marshalling_op_arg, |  | ||||||
|                  const flags_internal::InitialValGenFunc initial_value_gen) |                  const flags_internal::InitialValGenFunc initial_value_gen) | ||||||
|       : flags_internal::CommandLineFlag( |       : flags_internal::CommandLineFlag( | ||||||
|             name_arg, flags_internal::HelpText::FromFunctionPointer(help_gen), |             name, flags_internal::HelpText::FromFunctionPointer(help_gen), | ||||||
|             filename_arg, &flags_internal::FlagOps<T>, marshalling_op_arg, |             filename, &flags_internal::FlagOps<T>, marshalling_op, | ||||||
|             initial_value_gen, |             initial_value_gen, | ||||||
|             /*def_arg=*/nullptr, |             /*def=*/nullptr, | ||||||
|             /*cur_arg=*/nullptr), |             /*cur=*/nullptr), | ||||||
|         callback_(nullptr) {} |         callback_(nullptr) {} | ||||||
| 
 | 
 | ||||||
|   T Get() const { |   T Get() const { | ||||||
|  | @ -71,12 +70,12 @@ class Flag final : public flags_internal::CommandLineFlag { | ||||||
|     }; |     }; | ||||||
|     U u; |     U u; | ||||||
| 
 | 
 | ||||||
|     this->Read(&u.value, &flags_internal::FlagOps<T>); |     Read(&u.value, &flags_internal::FlagOps<T>); | ||||||
|     return std::move(u.value); |     return std::move(u.value); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   bool AtomicGet(T* v) const { |   bool AtomicGet(T* v) const { | ||||||
|     const int64_t r = this->atomic.load(std::memory_order_acquire); |     const int64_t r = atomic_.load(std::memory_order_acquire); | ||||||
|     if (r != flags_internal::CommandLineFlag::kAtomicInit) { |     if (r != flags_internal::CommandLineFlag::kAtomicInit) { | ||||||
|       memcpy(v, &r, sizeof(T)); |       memcpy(v, &r, sizeof(T)); | ||||||
|       return true; |       return true; | ||||||
|  | @ -85,7 +84,7 @@ class Flag final : public flags_internal::CommandLineFlag { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void Set(const T& v) { this->Write(&v, &flags_internal::FlagOps<T>); } |   void Set(const T& v) { Write(&v, &flags_internal::FlagOps<T>); } | ||||||
| 
 | 
 | ||||||
|   void SetCallback(const flags_internal::FlagCallback mutation_callback) { |   void SetCallback(const flags_internal::FlagCallback mutation_callback) { | ||||||
|     absl::MutexLock l(InitFlagIfNecessary()); |     absl::MutexLock l(InitFlagIfNecessary()); | ||||||
|  | @ -95,18 +94,18 @@ class Flag final : public flags_internal::CommandLineFlag { | ||||||
|     InvokeCallback(); |     InvokeCallback(); | ||||||
|   } |   } | ||||||
|   void InvokeCallback() override |   void InvokeCallback() override | ||||||
|       EXCLUSIVE_LOCKS_REQUIRED(this->locks->primary_mu) { |       ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu) { | ||||||
|     flags_internal::InvokeCallback(&this->locks->primary_mu, |     flags_internal::InvokeCallback(&locks_->primary_mu, &locks_->callback_mu, | ||||||
|                                    &this->locks->callback_mu, callback_); |                                    callback_); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   void Destroy() const override { |   void Destroy() const override { | ||||||
|     // Values are heap allocated Abseil Flags.
 |     // Values are heap allocated Abseil Flags.
 | ||||||
|     if (this->cur) Delete(this->op, this->cur); |     if (cur_) Delete(op_, cur_); | ||||||
|     if (this->def) Delete(this->op, this->def); |     if (def_) Delete(op_, def_); | ||||||
| 
 | 
 | ||||||
|     delete this->locks; |     delete locks_; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Flag's data
 |   // Flag's data
 | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ namespace flags_internal { | ||||||
| 
 | 
 | ||||||
| ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit); | ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit); | ||||||
| ABSL_CONST_INIT static std::string* program_name | ABSL_CONST_INIT static std::string* program_name | ||||||
|     GUARDED_BY(program_name_guard) = nullptr; |     ABSL_GUARDED_BY(program_name_guard) = nullptr; | ||||||
| 
 | 
 | ||||||
| std::string ProgramInvocationName() { | std::string ProgramInvocationName() { | ||||||
|   absl::MutexLock l(&program_name_guard); |   absl::MutexLock l(&program_name_guard); | ||||||
|  |  | ||||||
|  | @ -54,8 +54,8 @@ class FlagRegistry { | ||||||
|   // Store a flag in this registry.  Takes ownership of *flag.
 |   // Store a flag in this registry.  Takes ownership of *flag.
 | ||||||
|   void RegisterFlag(CommandLineFlag* flag); |   void RegisterFlag(CommandLineFlag* flag); | ||||||
| 
 | 
 | ||||||
|   void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } |   void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } | ||||||
|   void Unlock() UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } |   void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } | ||||||
| 
 | 
 | ||||||
|   // Returns the flag object for the specified name, or nullptr if not found.
 |   // Returns the flag object for the specified name, or nullptr if not found.
 | ||||||
|   // Will emit a warning if a 'retired' flag is specified.
 |   // Will emit a warning if a 'retired' flag is specified.
 | ||||||
|  | @ -118,7 +118,7 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { | ||||||
|               (flag->IsRetired() ? old_flag->Filename() : flag->Filename()), |               (flag->IsRetired() ? old_flag->Filename() : flag->Filename()), | ||||||
|               "'."), |               "'."), | ||||||
|           true); |           true); | ||||||
|     } else if (flag->op != old_flag->op) { |     } else if (flag->op_ != old_flag->op_) { | ||||||
|       flags_internal::ReportUsageError( |       flags_internal::ReportUsageError( | ||||||
|           absl::StrCat("Flag '", flag->Name(), |           absl::StrCat("Flag '", flag->Name(), | ||||||
|                        "' was defined more than once but with " |                        "' was defined more than once but with " | ||||||
|  | @ -208,16 +208,16 @@ class FlagSaverImpl { | ||||||
|       if (flag->IsRetired()) return; |       if (flag->IsRetired()) return; | ||||||
| 
 | 
 | ||||||
|       saved.name = flag->Name(); |       saved.name = flag->Name(); | ||||||
|       saved.op = flag->op; |       saved.op = flag->op_; | ||||||
|       saved.marshalling_op = flag->marshalling_op; |       saved.marshalling_op = flag->marshalling_op_; | ||||||
|       { |       { | ||||||
|         absl::MutexLock l(flag->InitFlagIfNecessary()); |         absl::MutexLock l(flag->InitFlagIfNecessary()); | ||||||
|         saved.validator = flag->GetValidator(); |         saved.validator = flag->GetValidator(); | ||||||
|         saved.modified = flag->modified; |         saved.modified = flag->modified_; | ||||||
|         saved.on_command_line = flag->on_command_line; |         saved.on_command_line = flag->on_command_line_; | ||||||
|         saved.current = Clone(saved.op, flag->cur); |         saved.current = Clone(saved.op, flag->cur_); | ||||||
|         saved.default_value = Clone(saved.op, flag->def); |         saved.default_value = Clone(saved.op, flag->def_); | ||||||
|         saved.counter = flag->counter; |         saved.counter = flag->counter_; | ||||||
|       } |       } | ||||||
|       backup_registry_.push_back(saved); |       backup_registry_.push_back(saved); | ||||||
|     }); |     }); | ||||||
|  | @ -237,26 +237,28 @@ class FlagSaverImpl { | ||||||
| 
 | 
 | ||||||
|       bool restored = false; |       bool restored = false; | ||||||
|       { |       { | ||||||
|         absl::MutexLock l(flag->InitFlagIfNecessary()); |         // This function encapsulate the lock.
 | ||||||
|         flag->SetValidator(src.validator); |         flag->SetValidator(src.validator); | ||||||
|         flag->modified = src.modified; | 
 | ||||||
|         flag->on_command_line = src.on_command_line; |         absl::MutexLock l(flag->InitFlagIfNecessary()); | ||||||
|         if (flag->counter != src.counter || |         flag->modified_ = src.modified; | ||||||
|             ChangedDirectly(flag, src.default_value, flag->def)) { |         flag->on_command_line_ = src.on_command_line; | ||||||
|  |         if (flag->counter_ != src.counter || | ||||||
|  |             ChangedDirectly(flag, src.default_value, flag->def_)) { | ||||||
|           restored = true; |           restored = true; | ||||||
|           Copy(src.op, src.default_value, flag->def); |           Copy(src.op, src.default_value, flag->def_); | ||||||
|         } |         } | ||||||
|         if (flag->counter != src.counter || |         if (flag->counter_ != src.counter || | ||||||
|             ChangedDirectly(flag, src.current, flag->cur)) { |             ChangedDirectly(flag, src.current, flag->cur_)) { | ||||||
|           restored = true; |           restored = true; | ||||||
|           Copy(src.op, src.current, flag->cur); |           Copy(src.op, src.current, flag->cur_); | ||||||
|           UpdateCopy(flag); |           UpdateCopy(flag); | ||||||
|           flag->InvokeCallback(); |           flag->InvokeCallback(); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (restored) { |       if (restored) { | ||||||
|         flag->counter++; |         flag->counter_++; | ||||||
| 
 | 
 | ||||||
|         // Revalidate the flag because the validator might store state based
 |         // Revalidate the flag because the validator might store state based
 | ||||||
|         // on the flag's value, which just changed due to the restore.
 |         // on the flag's value, which just changed due to the restore.
 | ||||||
|  | @ -307,44 +309,6 @@ FlagSaver::~FlagSaver() { | ||||||
|   delete impl_; |   delete impl_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // --------------------------------------------------------------------
 |  | ||||||
| // GetAllFlags()
 |  | ||||||
| //    The main way the FlagRegistry class exposes its data.  This
 |  | ||||||
| //    returns, as strings, all the info about all the flags in
 |  | ||||||
| //    the main registry, sorted first by filename they are defined
 |  | ||||||
| //    in, and then by flagname.
 |  | ||||||
| // --------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| struct FilenameFlagnameLess { |  | ||||||
|   bool operator()(const CommandLineFlagInfo& a, |  | ||||||
|                   const CommandLineFlagInfo& b) const { |  | ||||||
|     int cmp = absl::string_view(a.filename).compare(b.filename); |  | ||||||
|     if (cmp != 0) return cmp < 0; |  | ||||||
|     return a.name < b.name; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void FillCommandLineFlagInfo(CommandLineFlag* flag, |  | ||||||
|                              CommandLineFlagInfo* result) { |  | ||||||
|   result->name = std::string(flag->Name()); |  | ||||||
|   result->type = std::string(flag->Typename()); |  | ||||||
|   result->description = flag->Help(); |  | ||||||
|   result->filename = flag->Filename(); |  | ||||||
| 
 |  | ||||||
|   if (!flag->IsAbseilFlag()) { |  | ||||||
|     if (!flag->IsModified() && ChangedDirectly(flag, flag->cur, flag->def)) { |  | ||||||
|       flag->modified = true; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   result->current_value = flag->CurrentValue(); |  | ||||||
|   result->default_value = flag->DefaultValue(); |  | ||||||
|   result->is_default = !flag->IsModified(); |  | ||||||
|   result->has_validator_fn = flag->HasValidatorFn(); |  | ||||||
|   absl::MutexLock l(flag->InitFlagIfNecessary()); |  | ||||||
|   result->flag_ptr = flag->IsAbseilFlag() ? nullptr : flag->cur; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // --------------------------------------------------------------------
 | // --------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| CommandLineFlag* FindCommandLineFlag(absl::string_view name) { | CommandLineFlag* FindCommandLineFlag(absl::string_view name) { | ||||||
|  | @ -380,21 +344,6 @@ void ForEachFlag(std::function<void(CommandLineFlag*)> visitor) { | ||||||
| 
 | 
 | ||||||
| // --------------------------------------------------------------------
 | // --------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT) { |  | ||||||
|   flags_internal::ForEachFlag([&](CommandLineFlag* flag) { |  | ||||||
|     if (flag->IsRetired()) return; |  | ||||||
| 
 |  | ||||||
|     CommandLineFlagInfo fi; |  | ||||||
|     FillCommandLineFlagInfo(flag, &fi); |  | ||||||
|     OUTPUT->push_back(fi); |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   // Now sort the flags, first by filename they occur in, then alphabetically
 |  | ||||||
|   std::sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameLess()); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // --------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| bool RegisterCommandLineFlag(CommandLineFlag* flag) { | bool RegisterCommandLineFlag(CommandLineFlag* flag) { | ||||||
|   FlagRegistry::GlobalRegistry()->RegisterFlag(flag); |   FlagRegistry::GlobalRegistry()->RegisterFlag(flag); | ||||||
|   return true; |   return true; | ||||||
|  | @ -406,24 +355,24 @@ namespace { | ||||||
| 
 | 
 | ||||||
| class RetiredFlagObj final : public flags_internal::CommandLineFlag { | class RetiredFlagObj final : public flags_internal::CommandLineFlag { | ||||||
|  public: |  public: | ||||||
|   constexpr RetiredFlagObj(const char* name_arg, FlagOpFn ops, |   constexpr RetiredFlagObj(const char* name, FlagOpFn ops, | ||||||
|                            FlagMarshallingOpFn marshalling_ops) |                            FlagMarshallingOpFn marshalling_ops) | ||||||
|       : flags_internal::CommandLineFlag( |       : flags_internal::CommandLineFlag( | ||||||
|             name_arg, flags_internal::HelpText::FromStaticCString(nullptr), |             name, flags_internal::HelpText::FromStaticCString(nullptr), | ||||||
|             /*filename_arg=*/"RETIRED", ops, marshalling_ops, |             /*filename=*/"RETIRED", ops, marshalling_ops, | ||||||
|             /*initial_value_gen=*/nullptr, |             /*initial_value_gen=*/nullptr, | ||||||
|             /*def_arg=*/nullptr, |             /*def=*/nullptr, | ||||||
|             /*cur_arg=*/nullptr) {} |             /*cur=*/nullptr) {} | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   bool IsRetired() const override { return true; } |   bool IsRetired() const override { return true; } | ||||||
| 
 | 
 | ||||||
|   void Destroy() const override { |   void Destroy() const override { | ||||||
|     // Values are heap allocated for Retired Flags.
 |     // Values are heap allocated for Retired Flags.
 | ||||||
|     if (this->cur) Delete(this->op, this->cur); |     if (cur_) Delete(op_, cur_); | ||||||
|     if (this->def) Delete(this->op, this->def); |     if (def_) Delete(op_, def_); | ||||||
| 
 | 
 | ||||||
|     if (this->locks) delete this->locks; |     if (locks_) delete locks_; | ||||||
| 
 | 
 | ||||||
|     delete this; |     delete this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -29,33 +29,6 @@ | ||||||
| namespace absl { | namespace absl { | ||||||
| namespace flags_internal { | namespace flags_internal { | ||||||
| 
 | 
 | ||||||
| // CommandLineFlagInfo holds all information for a flag.
 |  | ||||||
| struct CommandLineFlagInfo { |  | ||||||
|   std::string name;           // the name of the flag
 |  | ||||||
|   std::string type;           // DO NOT use. Use flag->IsOfType<T>() instead.
 |  | ||||||
|   std::string description;    // the "help text" associated with the flag
 |  | ||||||
|   std::string current_value;  // the current value, as a std::string
 |  | ||||||
|   std::string default_value;  // the default value, as a std::string
 |  | ||||||
|   std::string filename;       // 'cleaned' version of filename holding the flag
 |  | ||||||
|   bool has_validator_fn;  // true if RegisterFlagValidator called on this flag
 |  | ||||||
| 
 |  | ||||||
|   bool is_default;  // true if the flag has the default value and
 |  | ||||||
|                     // has not been set explicitly from the cmdline
 |  | ||||||
|                     // or via SetCommandLineOption.
 |  | ||||||
| 
 |  | ||||||
|   // nullptr for ABSL_FLAG.  A pointer to the flag's current value
 |  | ||||||
|   // otherwise.  E.g., for DEFINE_int32(foo, ...), flag_ptr will be
 |  | ||||||
|   // &FLAGS_foo.
 |  | ||||||
|   const void* flag_ptr; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //-----------------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| void FillCommandLineFlagInfo(CommandLineFlag* flag, |  | ||||||
|                              CommandLineFlagInfo* result); |  | ||||||
| 
 |  | ||||||
| //-----------------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| CommandLineFlag* FindCommandLineFlag(absl::string_view name); | CommandLineFlag* FindCommandLineFlag(absl::string_view name); | ||||||
| CommandLineFlag* FindRetiredFlag(absl::string_view name); | CommandLineFlag* FindRetiredFlag(absl::string_view name); | ||||||
| 
 | 
 | ||||||
|  | @ -68,11 +41,6 @@ void ForEachFlag(std::function<void(CommandLineFlag*)> visitor); | ||||||
| 
 | 
 | ||||||
| //-----------------------------------------------------------------------------
 | //-----------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| // Store the list of all flags in *OUTPUT, sorted by file.
 |  | ||||||
| void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT); |  | ||||||
| 
 |  | ||||||
| //-----------------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| bool RegisterCommandLineFlag(CommandLineFlag*); | bool RegisterCommandLineFlag(CommandLineFlag*); | ||||||
| 
 | 
 | ||||||
| //-----------------------------------------------------------------------------
 | //-----------------------------------------------------------------------------
 | ||||||
|  |  | ||||||
|  | @ -36,30 +36,6 @@ bool GetCommandLineOption(absl::string_view name, std::string* value) { | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool GetCommandLineFlagInfo(absl::string_view name, |  | ||||||
|                             CommandLineFlagInfo* OUTPUT) { |  | ||||||
|   if (name.empty()) return false; |  | ||||||
| 
 |  | ||||||
|   CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |  | ||||||
|   if (flag == nullptr || flag->IsRetired()) { |  | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   assert(OUTPUT); |  | ||||||
|   FillCommandLineFlagInfo(flag, OUTPUT); |  | ||||||
|   return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name) { |  | ||||||
|   CommandLineFlagInfo info; |  | ||||||
|   if (!GetCommandLineFlagInfo(name, &info)) { |  | ||||||
|     ABSL_INTERNAL_LOG(FATAL, absl::StrCat("Flag '", name, "' does not exist")); |  | ||||||
|   } |  | ||||||
|   return info; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // --------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| bool SetCommandLineOption(absl::string_view name, absl::string_view value) { | bool SetCommandLineOption(absl::string_view name, absl::string_view value) { | ||||||
|   return SetCommandLineOptionWithMode(name, value, |   return SetCommandLineOptionWithMode(name, value, | ||||||
|                                       flags_internal::SET_FLAGS_VALUE); |                                       flags_internal::SET_FLAGS_VALUE); | ||||||
|  |  | ||||||
|  | @ -32,17 +32,6 @@ namespace flags_internal { | ||||||
| // Thread-safe.
 | // Thread-safe.
 | ||||||
| bool GetCommandLineOption(absl::string_view name, std::string* value); | bool GetCommandLineOption(absl::string_view name, std::string* value); | ||||||
| 
 | 
 | ||||||
| // If a flag named "name" exists, store its information in *OUTPUT
 |  | ||||||
| // and return true.  Else return false without changing *OUTPUT.
 |  | ||||||
| // Thread-safe.
 |  | ||||||
| bool GetCommandLineFlagInfo(absl::string_view name, |  | ||||||
|                             CommandLineFlagInfo* OUTPUT); |  | ||||||
| 
 |  | ||||||
| // Returns the CommandLineFlagInfo of the flagname.  exit() with an
 |  | ||||||
| // error code if name not found.
 |  | ||||||
| // Thread-safe.
 |  | ||||||
| CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name); |  | ||||||
| 
 |  | ||||||
| // Set the value of the flag named "name" to value.  If successful,
 | // Set the value of the flag named "name" to value.  If successful,
 | ||||||
| // returns true.  If not successful (e.g., the flag was not found or
 | // returns true.  If not successful (e.g., the flag was not found or
 | ||||||
| // the value is not a valid value), returns false.
 | // the value is not a valid value), returns false.
 | ||||||
|  |  | ||||||
|  | @ -44,11 +44,11 @@ namespace { | ||||||
| ABSL_CONST_INIT absl::Mutex processing_checks_guard(absl::kConstInit); | ABSL_CONST_INIT absl::Mutex processing_checks_guard(absl::kConstInit); | ||||||
| 
 | 
 | ||||||
| ABSL_CONST_INIT bool flagfile_needs_processing | ABSL_CONST_INIT bool flagfile_needs_processing | ||||||
|     GUARDED_BY(processing_checks_guard) = false; |     ABSL_GUARDED_BY(processing_checks_guard) = false; | ||||||
| ABSL_CONST_INIT bool fromenv_needs_processing | ABSL_CONST_INIT bool fromenv_needs_processing | ||||||
|     GUARDED_BY(processing_checks_guard) = false; |     ABSL_GUARDED_BY(processing_checks_guard) = false; | ||||||
| ABSL_CONST_INIT bool tryfromenv_needs_processing | ABSL_CONST_INIT bool tryfromenv_needs_processing | ||||||
|     GUARDED_BY(processing_checks_guard) = false; |     ABSL_GUARDED_BY(processing_checks_guard) = false; | ||||||
| 
 | 
 | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| }  // namespace flags_internal
 | }  // namespace flags_internal
 | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ namespace flags_internal { | ||||||
| namespace { | namespace { | ||||||
| ABSL_CONST_INIT absl::Mutex usage_message_guard(absl::kConstInit); | ABSL_CONST_INIT absl::Mutex usage_message_guard(absl::kConstInit); | ||||||
| ABSL_CONST_INIT std::string* program_usage_message | ABSL_CONST_INIT std::string* program_usage_message | ||||||
|     GUARDED_BY(usage_message_guard) = nullptr; |     ABSL_GUARDED_BY(usage_message_guard) = nullptr; | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| }  // namespace flags_internal
 | }  // namespace flags_internal
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -94,7 +94,7 @@ std::string NormalizeFilename(absl::string_view filename) { | ||||||
| 
 | 
 | ||||||
| ABSL_CONST_INIT absl::Mutex custom_usage_config_guard(absl::kConstInit); | ABSL_CONST_INIT absl::Mutex custom_usage_config_guard(absl::kConstInit); | ||||||
| ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config | ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config | ||||||
|     GUARDED_BY(custom_usage_config_guard) = nullptr; |     ABSL_GUARDED_BY(custom_usage_config_guard) = nullptr; | ||||||
| 
 | 
 | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -59,13 +59,13 @@ class RandenPoolEntry { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Copy bytes into out.
 |   // Copy bytes into out.
 | ||||||
|   void Fill(uint8_t* out, size_t bytes) LOCKS_EXCLUDED(mu_); |   void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_); | ||||||
| 
 | 
 | ||||||
|   // Returns random bits from the buffer in units of T.
 |   // Returns random bits from the buffer in units of T.
 | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   inline T Generate() LOCKS_EXCLUDED(mu_); |   inline T Generate() ABSL_LOCKS_EXCLUDED(mu_); | ||||||
| 
 | 
 | ||||||
|   inline void MaybeRefill() EXCLUSIVE_LOCKS_REQUIRED(mu_) { |   inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { | ||||||
|     if (next_ >= kState) { |     if (next_ >= kState) { | ||||||
|       next_ = kCapacity; |       next_ = kCapacity; | ||||||
|       impl_.Generate(state_); |       impl_.Generate(state_); | ||||||
|  | @ -74,10 +74,10 @@ class RandenPoolEntry { | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   // Randen URBG state.
 |   // Randen URBG state.
 | ||||||
|   uint32_t state_[kState] GUARDED_BY(mu_);  // First to satisfy alignment.
 |   uint32_t state_[kState] ABSL_GUARDED_BY(mu_);  // First to satisfy alignment.
 | ||||||
|   SpinLock mu_; |   SpinLock mu_; | ||||||
|   const Randen impl_; |   const Randen impl_; | ||||||
|   size_t next_ GUARDED_BY(mu_); |   size_t next_ ABSL_GUARDED_BY(mu_); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <> | template <> | ||||||
|  |  | ||||||
|  | @ -49,6 +49,21 @@ cc_library( | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | cc_library( | ||||||
|  |     name = "kernel_timeout_internal", | ||||||
|  |     hdrs = ["internal/kernel_timeout.h"], | ||||||
|  |     copts = ABSL_DEFAULT_COPTS, | ||||||
|  |     linkopts = ABSL_DEFAULT_LINKOPTS, | ||||||
|  |     visibility = [ | ||||||
|  |         "//absl/synchronization:__pkg__", | ||||||
|  |     ], | ||||||
|  |     deps = [ | ||||||
|  |         "//absl/base:core_headers", | ||||||
|  |         "//absl/base:raw_logging_internal", | ||||||
|  |         "//absl/time", | ||||||
|  |     ], | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| cc_library( | cc_library( | ||||||
|     name = "synchronization", |     name = "synchronization", | ||||||
|     srcs = [ |     srcs = [ | ||||||
|  | @ -65,7 +80,6 @@ cc_library( | ||||||
|         "barrier.h", |         "barrier.h", | ||||||
|         "blocking_counter.h", |         "blocking_counter.h", | ||||||
|         "internal/create_thread_identity.h", |         "internal/create_thread_identity.h", | ||||||
|         "internal/kernel_timeout.h", |  | ||||||
|         "internal/mutex_nonprod.inc", |         "internal/mutex_nonprod.inc", | ||||||
|         "internal/per_thread_sem.h", |         "internal/per_thread_sem.h", | ||||||
|         "internal/waiter.h", |         "internal/waiter.h", | ||||||
|  | @ -79,6 +93,7 @@ cc_library( | ||||||
|     }) + ABSL_DEFAULT_LINKOPTS, |     }) + ABSL_DEFAULT_LINKOPTS, | ||||||
|     deps = [ |     deps = [ | ||||||
|         ":graphcycles_internal", |         ":graphcycles_internal", | ||||||
|  |         ":kernel_timeout_internal", | ||||||
|         "//absl/base", |         "//absl/base", | ||||||
|         "//absl/base:atomic_hook", |         "//absl/base:atomic_hook", | ||||||
|         "//absl/base:base_internal", |         "//absl/base:base_internal", | ||||||
|  |  | ||||||
|  | @ -31,6 +31,19 @@ absl_cc_library( | ||||||
|     absl::raw_logging_internal |     absl::raw_logging_internal | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | absl_cc_library( | ||||||
|  |   NAME | ||||||
|  |     kernel_timeout_internal | ||||||
|  |   HDRS | ||||||
|  |     "internal/kernel_timeout.h" | ||||||
|  |   COPTS | ||||||
|  |     ${ABSL_DEFAULT_COPTS} | ||||||
|  |   DEPS | ||||||
|  |     absl::core_headers | ||||||
|  |     absl::raw_logging_internal | ||||||
|  |     absl::time | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| absl_cc_library( | absl_cc_library( | ||||||
|   NAME |   NAME | ||||||
|     synchronization |     synchronization | ||||||
|  | @ -38,7 +51,6 @@ absl_cc_library( | ||||||
|     "barrier.h" |     "barrier.h" | ||||||
|     "blocking_counter.h" |     "blocking_counter.h" | ||||||
|     "internal/create_thread_identity.h" |     "internal/create_thread_identity.h" | ||||||
|     "internal/kernel_timeout.h" |  | ||||||
|     "internal/mutex_nonprod.inc" |     "internal/mutex_nonprod.inc" | ||||||
|     "internal/per_thread_sem.h" |     "internal/per_thread_sem.h" | ||||||
|     "internal/waiter.h" |     "internal/waiter.h" | ||||||
|  | @ -56,6 +68,7 @@ absl_cc_library( | ||||||
|     ${ABSL_DEFAULT_COPTS} |     ${ABSL_DEFAULT_COPTS} | ||||||
|   DEPS |   DEPS | ||||||
|     absl::graphcycles_internal |     absl::graphcycles_internal | ||||||
|  |     absl::kernel_timeout_internal | ||||||
|     absl::atomic_hook |     absl::atomic_hook | ||||||
|     absl::base |     absl::base | ||||||
|     absl::base_internal |     absl::base_internal | ||||||
|  |  | ||||||
|  | @ -69,8 +69,8 @@ class Barrier { | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex lock_; |   Mutex lock_; | ||||||
|   int num_to_block_ GUARDED_BY(lock_); |   int num_to_block_ ABSL_GUARDED_BY(lock_); | ||||||
|   int num_to_exit_ GUARDED_BY(lock_); |   int num_to_exit_ ABSL_GUARDED_BY(lock_); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }  // namespace absl
 | }  // namespace absl
 | ||||||
|  |  | ||||||
|  | @ -88,8 +88,8 @@ class BlockingCounter { | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex lock_; |   Mutex lock_; | ||||||
|   int count_ GUARDED_BY(lock_); |   int count_ ABSL_GUARDED_BY(lock_); | ||||||
|   int num_waiting_ GUARDED_BY(lock_); |   int num_waiting_ ABSL_GUARDED_BY(lock_); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }  // namespace absl
 | }  // namespace absl
 | ||||||
|  |  | ||||||
|  | @ -60,7 +60,7 @@ class ThreadPool { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   bool WorkAvailable() const EXCLUSIVE_LOCKS_REQUIRED(mu_) { |   bool WorkAvailable() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { | ||||||
|     return !queue_.empty(); |     return !queue_.empty(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -81,7 +81,7 @@ class ThreadPool { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   absl::Mutex mu_; |   absl::Mutex mu_; | ||||||
|   std::queue<std::function<void()>> queue_ GUARDED_BY(mu_); |   std::queue<std::function<void()>> queue_ ABSL_GUARDED_BY(mu_); | ||||||
|   std::vector<std::thread> threads_; |   std::vector<std::thread> threads_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -143,11 +143,11 @@ ABSL_CONST_INIT absl::Mutex early_const_init_mutex(absl::kConstInit); | ||||||
| // constructors of globals "happen at link time"; memory is pre-initialized,
 | // constructors of globals "happen at link time"; memory is pre-initialized,
 | ||||||
| // before the constructors of either grab_lock or check_still_locked are run.)
 | // before the constructors of either grab_lock or check_still_locked are run.)
 | ||||||
| extern absl::Mutex const_init_sanity_mutex; | extern absl::Mutex const_init_sanity_mutex; | ||||||
| OnConstruction grab_lock([]() NO_THREAD_SAFETY_ANALYSIS { | OnConstruction grab_lock([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
|   const_init_sanity_mutex.Lock(); |   const_init_sanity_mutex.Lock(); | ||||||
| }); | }); | ||||||
| ABSL_CONST_INIT absl::Mutex const_init_sanity_mutex(absl::kConstInit); | ABSL_CONST_INIT absl::Mutex const_init_sanity_mutex(absl::kConstInit); | ||||||
| OnConstruction check_still_locked([]() NO_THREAD_SAFETY_ANALYSIS { | OnConstruction check_still_locked([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
|   const_init_sanity_mutex.AssertHeld(); |   const_init_sanity_mutex.AssertHeld(); | ||||||
|   const_init_sanity_mutex.Unlock(); |   const_init_sanity_mutex.Unlock(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -207,8 +207,8 @@ static absl::base_internal::SpinLock deadlock_graph_mu( | ||||||
|     absl::base_internal::kLinkerInitialized); |     absl::base_internal::kLinkerInitialized); | ||||||
| 
 | 
 | ||||||
| // graph used to detect deadlocks.
 | // graph used to detect deadlocks.
 | ||||||
| static GraphCycles *deadlock_graph GUARDED_BY(deadlock_graph_mu) | static GraphCycles *deadlock_graph ABSL_GUARDED_BY(deadlock_graph_mu) | ||||||
|     PT_GUARDED_BY(deadlock_graph_mu); |     ABSL_PT_GUARDED_BY(deadlock_graph_mu); | ||||||
| 
 | 
 | ||||||
| //------------------------------------------------------------------
 | //------------------------------------------------------------------
 | ||||||
| // An event mechanism for debugging mutex use.
 | // An event mechanism for debugging mutex use.
 | ||||||
|  | @ -279,10 +279,10 @@ static const uint32_t kNSynchEvent = 1031; | ||||||
| 
 | 
 | ||||||
| static struct SynchEvent {     // this is a trivial hash table for the events
 | static struct SynchEvent {     // this is a trivial hash table for the events
 | ||||||
|   // struct is freed when refcount reaches 0
 |   // struct is freed when refcount reaches 0
 | ||||||
|   int refcount GUARDED_BY(synch_event_mu); |   int refcount ABSL_GUARDED_BY(synch_event_mu); | ||||||
| 
 | 
 | ||||||
|   // buckets have linear, 0-terminated  chains
 |   // buckets have linear, 0-terminated  chains
 | ||||||
|   SynchEvent *next GUARDED_BY(synch_event_mu); |   SynchEvent *next ABSL_GUARDED_BY(synch_event_mu); | ||||||
| 
 | 
 | ||||||
|   // Constant after initialization
 |   // Constant after initialization
 | ||||||
|   uintptr_t masked_addr;  // object at this address is called "name"
 |   uintptr_t masked_addr;  // object at this address is called "name"
 | ||||||
|  | @ -296,7 +296,7 @@ static struct SynchEvent {     // this is a trivial hash table for the events | ||||||
| 
 | 
 | ||||||
|   // Constant after initialization
 |   // Constant after initialization
 | ||||||
|   char name[1];         // actually longer---null-terminated std::string
 |   char name[1];         // actually longer---null-terminated std::string
 | ||||||
| } *synch_event[kNSynchEvent] GUARDED_BY(synch_event_mu); | } * synch_event[kNSynchEvent] ABSL_GUARDED_BY(synch_event_mu); | ||||||
| 
 | 
 | ||||||
| // Ensure that the object at "addr" has a SynchEvent struct associated with it,
 | // Ensure that the object at "addr" has a SynchEvent struct associated with it,
 | ||||||
| // set "bits" in the word there (waiting until lockbit is clear before doing
 | // set "bits" in the word there (waiting until lockbit is clear before doing
 | ||||||
|  | @ -1143,7 +1143,7 @@ PerThreadSynch *Mutex::Wakeup(PerThreadSynch *w) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static GraphId GetGraphIdLocked(Mutex *mu) | static GraphId GetGraphIdLocked(Mutex *mu) | ||||||
|     EXCLUSIVE_LOCKS_REQUIRED(deadlock_graph_mu) { |     ABSL_EXCLUSIVE_LOCKS_REQUIRED(deadlock_graph_mu) { | ||||||
|   if (!deadlock_graph) {  // (re)create the deadlock graph.
 |   if (!deadlock_graph) {  // (re)create the deadlock graph.
 | ||||||
|     deadlock_graph = |     deadlock_graph = | ||||||
|         new (base_internal::LowLevelAlloc::Alloc(sizeof(*deadlock_graph))) |         new (base_internal::LowLevelAlloc::Alloc(sizeof(*deadlock_graph))) | ||||||
|  | @ -1152,7 +1152,7 @@ static GraphId GetGraphIdLocked(Mutex *mu) | ||||||
|   return deadlock_graph->GetId(mu); |   return deadlock_graph->GetId(mu); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static GraphId GetGraphId(Mutex *mu) LOCKS_EXCLUDED(deadlock_graph_mu) { | static GraphId GetGraphId(Mutex *mu) ABSL_LOCKS_EXCLUDED(deadlock_graph_mu) { | ||||||
|   deadlock_graph_mu.Lock(); |   deadlock_graph_mu.Lock(); | ||||||
|   GraphId id = GetGraphIdLocked(mu); |   GraphId id = GetGraphIdLocked(mu); | ||||||
|   deadlock_graph_mu.Unlock(); |   deadlock_graph_mu.Unlock(); | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ struct SynchWaitParams; | ||||||
| //
 | //
 | ||||||
| // See also `MutexLock`, below, for scoped `Mutex` acquisition.
 | // See also `MutexLock`, below, for scoped `Mutex` acquisition.
 | ||||||
| 
 | 
 | ||||||
| class LOCKABLE Mutex { | class ABSL_LOCKABLE Mutex { | ||||||
|  public: |  public: | ||||||
|   // Creates a `Mutex` that is not held by anyone. This constructor is
 |   // Creates a `Mutex` that is not held by anyone. This constructor is
 | ||||||
|   // typically used for Mutexes allocated on the heap or the stack.
 |   // typically used for Mutexes allocated on the heap or the stack.
 | ||||||
|  | @ -164,27 +164,27 @@ class LOCKABLE Mutex { | ||||||
|   //
 |   //
 | ||||||
|   // Blocks the calling thread, if necessary, until this `Mutex` is free, and
 |   // Blocks the calling thread, if necessary, until this `Mutex` is free, and
 | ||||||
|   // then acquires it exclusively. (This lock is also known as a "write lock.")
 |   // then acquires it exclusively. (This lock is also known as a "write lock.")
 | ||||||
|   void Lock() EXCLUSIVE_LOCK_FUNCTION(); |   void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   // Mutex::Unlock()
 |   // Mutex::Unlock()
 | ||||||
|   //
 |   //
 | ||||||
|   // Releases this `Mutex` and returns it from the exclusive/write state to the
 |   // Releases this `Mutex` and returns it from the exclusive/write state to the
 | ||||||
|   // free state. Caller must hold the `Mutex` exclusively.
 |   // free state. Caller must hold the `Mutex` exclusively.
 | ||||||
|   void Unlock() UNLOCK_FUNCTION(); |   void Unlock() ABSL_UNLOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   // Mutex::TryLock()
 |   // Mutex::TryLock()
 | ||||||
|   //
 |   //
 | ||||||
|   // If the mutex can be acquired without blocking, does so exclusively and
 |   // If the mutex can be acquired without blocking, does so exclusively and
 | ||||||
|   // returns `true`. Otherwise, returns `false`. Returns `true` with high
 |   // returns `true`. Otherwise, returns `false`. Returns `true` with high
 | ||||||
|   // probability if the `Mutex` was free.
 |   // probability if the `Mutex` was free.
 | ||||||
|   bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); |   bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); | ||||||
| 
 | 
 | ||||||
|   // Mutex::AssertHeld()
 |   // Mutex::AssertHeld()
 | ||||||
|   //
 |   //
 | ||||||
|   // Return immediately if this thread holds the `Mutex` exclusively (in write
 |   // Return immediately if this thread holds the `Mutex` exclusively (in write
 | ||||||
|   // mode). Otherwise, may report an error (typically by crashing with a
 |   // mode). Otherwise, may report an error (typically by crashing with a
 | ||||||
|   // diagnostic), or may return immediately.
 |   // diagnostic), or may return immediately.
 | ||||||
|   void AssertHeld() const ASSERT_EXCLUSIVE_LOCK(); |   void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK(); | ||||||
| 
 | 
 | ||||||
|   // ---------------------------------------------------------------------------
 |   // ---------------------------------------------------------------------------
 | ||||||
|   // Reader-Writer Locking
 |   // Reader-Writer Locking
 | ||||||
|  | @ -225,28 +225,28 @@ class LOCKABLE Mutex { | ||||||
|   // `ReaderLock()` will block if some other thread has an exclusive/writer lock
 |   // `ReaderLock()` will block if some other thread has an exclusive/writer lock
 | ||||||
|   // on the mutex.
 |   // on the mutex.
 | ||||||
| 
 | 
 | ||||||
|   void ReaderLock() SHARED_LOCK_FUNCTION(); |   void ReaderLock() ABSL_SHARED_LOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   // Mutex::ReaderUnlock()
 |   // Mutex::ReaderUnlock()
 | ||||||
|   //
 |   //
 | ||||||
|   // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to
 |   // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to
 | ||||||
|   // the free state if this thread holds the last reader lock on the mutex. Note
 |   // the free state if this thread holds the last reader lock on the mutex. Note
 | ||||||
|   // that you cannot call `ReaderUnlock()` on a mutex held in write mode.
 |   // that you cannot call `ReaderUnlock()` on a mutex held in write mode.
 | ||||||
|   void ReaderUnlock() UNLOCK_FUNCTION(); |   void ReaderUnlock() ABSL_UNLOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   // Mutex::ReaderTryLock()
 |   // Mutex::ReaderTryLock()
 | ||||||
|   //
 |   //
 | ||||||
|   // If the mutex can be acquired without blocking, acquires this mutex for
 |   // If the mutex can be acquired without blocking, acquires this mutex for
 | ||||||
|   // shared access and returns `true`. Otherwise, returns `false`. Returns
 |   // shared access and returns `true`. Otherwise, returns `false`. Returns
 | ||||||
|   // `true` with high probability if the `Mutex` was free or shared.
 |   // `true` with high probability if the `Mutex` was free or shared.
 | ||||||
|   bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); |   bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); | ||||||
| 
 | 
 | ||||||
|   // Mutex::AssertReaderHeld()
 |   // Mutex::AssertReaderHeld()
 | ||||||
|   //
 |   //
 | ||||||
|   // Returns immediately if this thread holds the `Mutex` in at least shared
 |   // Returns immediately if this thread holds the `Mutex` in at least shared
 | ||||||
|   // mode (read mode). Otherwise, may report an error (typically by
 |   // mode (read mode). Otherwise, may report an error (typically by
 | ||||||
|   // crashing with a diagnostic), or may return immediately.
 |   // crashing with a diagnostic), or may return immediately.
 | ||||||
|   void AssertReaderHeld() const ASSERT_SHARED_LOCK(); |   void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK(); | ||||||
| 
 | 
 | ||||||
|   // Mutex::WriterLock()
 |   // Mutex::WriterLock()
 | ||||||
|   // Mutex::WriterUnlock()
 |   // Mutex::WriterUnlock()
 | ||||||
|  | @ -257,11 +257,11 @@ class LOCKABLE Mutex { | ||||||
|   // These methods may be used (along with the complementary `Reader*()`
 |   // These methods may be used (along with the complementary `Reader*()`
 | ||||||
|   // methods) to distingish simple exclusive `Mutex` usage (`Lock()`,
 |   // methods) to distingish simple exclusive `Mutex` usage (`Lock()`,
 | ||||||
|   // etc.) from reader/writer lock usage.
 |   // etc.) from reader/writer lock usage.
 | ||||||
|   void WriterLock() EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); } |   void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); } | ||||||
| 
 | 
 | ||||||
|   void WriterUnlock() UNLOCK_FUNCTION() { this->Unlock(); } |   void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); } | ||||||
| 
 | 
 | ||||||
|   bool WriterTryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { |   bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { | ||||||
|     return this->TryLock(); |     return this->TryLock(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -315,11 +315,11 @@ class LOCKABLE Mutex { | ||||||
|   // be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
 |   // be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
 | ||||||
|   // logically equivalent to `*Lock(); Await();` though they may have different
 |   // logically equivalent to `*Lock(); Await();` though they may have different
 | ||||||
|   // performance characteristics.
 |   // performance characteristics.
 | ||||||
|   void LockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION(); |   void LockWhen(const Condition &cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   void ReaderLockWhen(const Condition &cond) SHARED_LOCK_FUNCTION(); |   void ReaderLockWhen(const Condition &cond) ABSL_SHARED_LOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|   void WriterLockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION() { |   void WriterLockWhen(const Condition &cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() { | ||||||
|     this->LockWhen(cond); |     this->LockWhen(cond); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -361,11 +361,11 @@ class LOCKABLE Mutex { | ||||||
|   //
 |   //
 | ||||||
|   // Negative timeouts are equivalent to a zero timeout.
 |   // Negative timeouts are equivalent to a zero timeout.
 | ||||||
|   bool LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) |   bool LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) | ||||||
|       EXCLUSIVE_LOCK_FUNCTION(); |       ABSL_EXCLUSIVE_LOCK_FUNCTION(); | ||||||
|   bool ReaderLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) |   bool ReaderLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) | ||||||
|       SHARED_LOCK_FUNCTION(); |       ABSL_SHARED_LOCK_FUNCTION(); | ||||||
|   bool WriterLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) |   bool WriterLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) | ||||||
|       EXCLUSIVE_LOCK_FUNCTION() { |       ABSL_EXCLUSIVE_LOCK_FUNCTION() { | ||||||
|     return this->LockWhenWithTimeout(cond, timeout); |     return this->LockWhenWithTimeout(cond, timeout); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -381,11 +381,11 @@ class LOCKABLE Mutex { | ||||||
|   //
 |   //
 | ||||||
|   // Deadlines in the past are equivalent to an immediate deadline.
 |   // Deadlines in the past are equivalent to an immediate deadline.
 | ||||||
|   bool LockWhenWithDeadline(const Condition &cond, absl::Time deadline) |   bool LockWhenWithDeadline(const Condition &cond, absl::Time deadline) | ||||||
|       EXCLUSIVE_LOCK_FUNCTION(); |       ABSL_EXCLUSIVE_LOCK_FUNCTION(); | ||||||
|   bool ReaderLockWhenWithDeadline(const Condition &cond, absl::Time deadline) |   bool ReaderLockWhenWithDeadline(const Condition &cond, absl::Time deadline) | ||||||
|       SHARED_LOCK_FUNCTION(); |       ABSL_SHARED_LOCK_FUNCTION(); | ||||||
|   bool WriterLockWhenWithDeadline(const Condition &cond, absl::Time deadline) |   bool WriterLockWhenWithDeadline(const Condition &cond, absl::Time deadline) | ||||||
|       EXCLUSIVE_LOCK_FUNCTION() { |       ABSL_EXCLUSIVE_LOCK_FUNCTION() { | ||||||
|     return this->LockWhenWithDeadline(cond, deadline); |     return this->LockWhenWithDeadline(cond, deadline); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -535,9 +535,9 @@ class LOCKABLE Mutex { | ||||||
| // private:
 | // private:
 | ||||||
| //   Mutex lock_;
 | //   Mutex lock_;
 | ||||||
| // };
 | // };
 | ||||||
| class SCOPED_LOCKABLE MutexLock { | class ABSL_SCOPED_LOCKABLE MutexLock { | ||||||
|  public: |  public: | ||||||
|   explicit MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { |   explicit MutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { | ||||||
|     this->mu_->Lock(); |     this->mu_->Lock(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -546,7 +546,7 @@ class SCOPED_LOCKABLE MutexLock { | ||||||
|   MutexLock& operator=(const MutexLock&) = delete; |   MutexLock& operator=(const MutexLock&) = delete; | ||||||
|   MutexLock& operator=(MutexLock&&) = delete; |   MutexLock& operator=(MutexLock&&) = delete; | ||||||
| 
 | 
 | ||||||
|   ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); } |   ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); } | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex *const mu_; |   Mutex *const mu_; | ||||||
|  | @ -556,10 +556,9 @@ class SCOPED_LOCKABLE MutexLock { | ||||||
| //
 | //
 | ||||||
| // The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and
 | // The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and
 | ||||||
| // releases a shared lock on a `Mutex` via RAII.
 | // releases a shared lock on a `Mutex` via RAII.
 | ||||||
| class SCOPED_LOCKABLE ReaderMutexLock { | class ABSL_SCOPED_LOCKABLE ReaderMutexLock { | ||||||
|  public: |  public: | ||||||
|   explicit ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu) |   explicit ReaderMutexLock(Mutex *mu) ABSL_SHARED_LOCK_FUNCTION(mu) : mu_(mu) { | ||||||
|       :  mu_(mu) { |  | ||||||
|     mu->ReaderLock(); |     mu->ReaderLock(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -568,9 +567,7 @@ class SCOPED_LOCKABLE ReaderMutexLock { | ||||||
|   ReaderMutexLock& operator=(const ReaderMutexLock&) = delete; |   ReaderMutexLock& operator=(const ReaderMutexLock&) = delete; | ||||||
|   ReaderMutexLock& operator=(ReaderMutexLock&&) = delete; |   ReaderMutexLock& operator=(ReaderMutexLock&&) = delete; | ||||||
| 
 | 
 | ||||||
|   ~ReaderMutexLock() UNLOCK_FUNCTION() { |   ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); } | ||||||
|     this->mu_->ReaderUnlock(); |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex *const mu_; |   Mutex *const mu_; | ||||||
|  | @ -580,9 +577,9 @@ class SCOPED_LOCKABLE ReaderMutexLock { | ||||||
| //
 | //
 | ||||||
| // The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and
 | // The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and
 | ||||||
| // releases a write (exclusive) lock on a `Mutex` via RAII.
 | // releases a write (exclusive) lock on a `Mutex` via RAII.
 | ||||||
| class SCOPED_LOCKABLE WriterMutexLock { | class ABSL_SCOPED_LOCKABLE WriterMutexLock { | ||||||
|  public: |  public: | ||||||
|   explicit WriterMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) |   explicit WriterMutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) | ||||||
|       : mu_(mu) { |       : mu_(mu) { | ||||||
|     mu->WriterLock(); |     mu->WriterLock(); | ||||||
|   } |   } | ||||||
|  | @ -592,9 +589,7 @@ class SCOPED_LOCKABLE WriterMutexLock { | ||||||
|   WriterMutexLock& operator=(const WriterMutexLock&) = delete; |   WriterMutexLock& operator=(const WriterMutexLock&) = delete; | ||||||
|   WriterMutexLock& operator=(WriterMutexLock&&) = delete; |   WriterMutexLock& operator=(WriterMutexLock&&) = delete; | ||||||
| 
 | 
 | ||||||
|   ~WriterMutexLock() UNLOCK_FUNCTION() { |   ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->WriterUnlock(); } | ||||||
|     this->mu_->WriterUnlock(); |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex *const mu_; |   Mutex *const mu_; | ||||||
|  | @ -860,13 +855,18 @@ class CondVar { | ||||||
| // MutexLockMaybe
 | // MutexLockMaybe
 | ||||||
| //
 | //
 | ||||||
| // MutexLockMaybe is like MutexLock, but is a no-op when mu is null.
 | // MutexLockMaybe is like MutexLock, but is a no-op when mu is null.
 | ||||||
| class SCOPED_LOCKABLE MutexLockMaybe { | class ABSL_SCOPED_LOCKABLE MutexLockMaybe { | ||||||
|  public: |  public: | ||||||
|   explicit MutexLockMaybe(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) |   explicit MutexLockMaybe(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) | ||||||
|       : mu_(mu) { if (this->mu_ != nullptr) { this->mu_->Lock(); } } |       : mu_(mu) { | ||||||
|   ~MutexLockMaybe() UNLOCK_FUNCTION() { |     if (this->mu_ != nullptr) { | ||||||
|  |       this->mu_->Lock(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   ~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() { | ||||||
|     if (this->mu_ != nullptr) { this->mu_->Unlock(); } |     if (this->mu_ != nullptr) { this->mu_->Unlock(); } | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex *const mu_; |   Mutex *const mu_; | ||||||
|   MutexLockMaybe(const MutexLockMaybe&) = delete; |   MutexLockMaybe(const MutexLockMaybe&) = delete; | ||||||
|  | @ -879,17 +879,17 @@ class SCOPED_LOCKABLE MutexLockMaybe { | ||||||
| //
 | //
 | ||||||
| // ReleasableMutexLock is like MutexLock, but permits `Release()` of its
 | // ReleasableMutexLock is like MutexLock, but permits `Release()` of its
 | ||||||
| // mutex before destruction. `Release()` may be called at most once.
 | // mutex before destruction. `Release()` may be called at most once.
 | ||||||
| class SCOPED_LOCKABLE ReleasableMutexLock { | class ABSL_SCOPED_LOCKABLE ReleasableMutexLock { | ||||||
|  public: |  public: | ||||||
|   explicit ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) |   explicit ReleasableMutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) | ||||||
|       : mu_(mu) { |       : mu_(mu) { | ||||||
|     this->mu_->Lock(); |     this->mu_->Lock(); | ||||||
|   } |   } | ||||||
|   ~ReleasableMutexLock() UNLOCK_FUNCTION() { |   ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() { | ||||||
|     if (this->mu_ != nullptr) { this->mu_->Unlock(); } |     if (this->mu_ != nullptr) { this->mu_->Unlock(); } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void Release() UNLOCK_FUNCTION(); |   void Release() ABSL_UNLOCK_FUNCTION(); | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   Mutex *mu_; |   Mutex *mu_; | ||||||
|  |  | ||||||
|  | @ -425,10 +425,10 @@ TEST(Mutex, CondVarWaitSignalsAwait) { | ||||||
|   // Use a struct so the lock annotations apply.
 |   // Use a struct so the lock annotations apply.
 | ||||||
|   struct { |   struct { | ||||||
|     absl::Mutex barrier_mu; |     absl::Mutex barrier_mu; | ||||||
|     bool barrier GUARDED_BY(barrier_mu) = false; |     bool barrier ABSL_GUARDED_BY(barrier_mu) = false; | ||||||
| 
 | 
 | ||||||
|     absl::Mutex release_mu; |     absl::Mutex release_mu; | ||||||
|     bool release GUARDED_BY(release_mu) = false; |     bool release ABSL_GUARDED_BY(release_mu) = false; | ||||||
|     absl::CondVar released_cv; |     absl::CondVar released_cv; | ||||||
|   } state; |   } state; | ||||||
| 
 | 
 | ||||||
|  | @ -466,10 +466,10 @@ TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) { | ||||||
|   // Use a struct so the lock annotations apply.
 |   // Use a struct so the lock annotations apply.
 | ||||||
|   struct { |   struct { | ||||||
|     absl::Mutex barrier_mu; |     absl::Mutex barrier_mu; | ||||||
|     bool barrier GUARDED_BY(barrier_mu) = false; |     bool barrier ABSL_GUARDED_BY(barrier_mu) = false; | ||||||
| 
 | 
 | ||||||
|     absl::Mutex release_mu; |     absl::Mutex release_mu; | ||||||
|     bool release GUARDED_BY(release_mu) = false; |     bool release ABSL_GUARDED_BY(release_mu) = false; | ||||||
|     absl::CondVar released_cv; |     absl::CondVar released_cv; | ||||||
|   } state; |   } state; | ||||||
| 
 | 
 | ||||||
|  | @ -770,7 +770,7 @@ static void GetReadLock(ReaderDecrementBugStruct *x) { | ||||||
| 
 | 
 | ||||||
| // Test for reader counter being decremented incorrectly by waiter
 | // Test for reader counter being decremented incorrectly by waiter
 | ||||||
| // with false condition.
 | // with false condition.
 | ||||||
| TEST(Mutex, MutexReaderDecrementBug) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
|   ReaderDecrementBugStruct x; |   ReaderDecrementBugStruct x; | ||||||
|   x.cond = false; |   x.cond = false; | ||||||
|   x.waiting_on_cond = false; |   x.waiting_on_cond = false; | ||||||
|  | @ -819,7 +819,7 @@ TEST(Mutex, MutexReaderDecrementBug) NO_THREAD_SAFETY_ANALYSIS { | ||||||
| // TSAN reports errors when locked Mutexes are destroyed.
 | // TSAN reports errors when locked Mutexes are destroyed.
 | ||||||
| TEST(Mutex, DISABLED_LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, DISABLED_LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS { | ||||||
| #else | #else | ||||||
| TEST(Mutex, LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
| #endif | #endif | ||||||
|   for (int i = 0; i != 10; i++) { |   for (int i = 0; i != 10; i++) { | ||||||
|     // Create, lock and destroy 10 locks.
 |     // Create, lock and destroy 10 locks.
 | ||||||
|  | @ -1101,7 +1101,7 @@ TEST(Mutex, DeadlockDetectorBazelWarning) { | ||||||
| // annotation-based static thread-safety analysis is not currently
 | // annotation-based static thread-safety analysis is not currently
 | ||||||
| // predicate-aware and cannot tell if the two for-loops that acquire and
 | // predicate-aware and cannot tell if the two for-loops that acquire and
 | ||||||
| // release the locks have the same predicates.
 | // release the locks have the same predicates.
 | ||||||
| TEST(Mutex, DeadlockDetectorStessTest) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, DeadlockDetectorStessTest) ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
|   // Stress test: Here we create a large number of locks and use all of them.
 |   // Stress test: Here we create a large number of locks and use all of them.
 | ||||||
|   // If a deadlock detector keeps a full graph of lock acquisition order,
 |   // If a deadlock detector keeps a full graph of lock acquisition order,
 | ||||||
|   // it will likely be too slow for this test to pass.
 |   // it will likely be too slow for this test to pass.
 | ||||||
|  | @ -1123,7 +1123,7 @@ TEST(Mutex, DeadlockDetectorStessTest) NO_THREAD_SAFETY_ANALYSIS { | ||||||
| // TSAN reports errors when locked Mutexes are destroyed.
 | // TSAN reports errors when locked Mutexes are destroyed.
 | ||||||
| TEST(Mutex, DISABLED_DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, DISABLED_DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS { | ||||||
| #else | #else | ||||||
| TEST(Mutex, DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS { | TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS { | ||||||
| #endif | #endif | ||||||
|   // Test a scenario where a cached deadlock graph node id in the
 |   // Test a scenario where a cached deadlock graph node id in the
 | ||||||
|   // list of held locks is not invalidated when the corresponding
 |   // list of held locks is not invalidated when the corresponding
 | ||||||
|  |  | ||||||
|  | @ -1103,7 +1103,7 @@ inline Time FromCivil(CivilSecond ct, TimeZone tz) { | ||||||
| // An `absl::TimeConversion` represents the conversion of year, month, day,
 | // An `absl::TimeConversion` represents the conversion of year, month, day,
 | ||||||
| // hour, minute, and second values (i.e., a civil time), in a particular
 | // hour, minute, and second values (i.e., a civil time), in a particular
 | ||||||
| // `absl::TimeZone`, to a time instant (an absolute time), as returned by
 | // `absl::TimeZone`, to a time instant (an absolute time), as returned by
 | ||||||
| // `absl::ConvertDateTime()`. Lecacy version of `absl::TimeZone::TimeInfo`.
 | // `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`.
 | ||||||
| //
 | //
 | ||||||
| // Deprecated. Use `absl::TimeZone::TimeInfo`.
 | // Deprecated. Use `absl::TimeZone::TimeInfo`.
 | ||||||
| struct | struct | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue