diff options
author | Adam Cozzette <acozzette@google.com> | 2018-03-13 16:37:29 -0700 |
---|---|---|
committer | Adam Cozzette <acozzette@google.com> | 2018-03-13 16:37:29 -0700 |
commit | 0400cca3236de1ca303af38bf81eab332d042b7c (patch) | |
tree | a8a9b19853f64567c96750a1c7d253926471daa5 /src/google/protobuf/arena.cc | |
parent | 96b535cc2f4f7b7e22a1b8622149f7c26a5a3f63 (diff) | |
download | protobuf-0400cca3236de1ca303af38bf81eab332d042b7c.tar.gz protobuf-0400cca3236de1ca303af38bf81eab332d042b7c.tar.bz2 protobuf-0400cca3236de1ca303af38bf81eab332d042b7c.zip |
Integrated internal changes from Google
Diffstat (limited to 'src/google/protobuf/arena.cc')
-rwxr-xr-x | src/google/protobuf/arena.cc | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index e53d7219..c117c9e5 100755 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -48,7 +48,7 @@ namespace protobuf { namespace internal { -google::protobuf::internal::SequenceNumber ArenaImpl::lifecycle_id_generator_; +std::atomic<int64> ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ = @@ -65,9 +65,10 @@ GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL} #endif void ArenaImpl::Init() { - lifecycle_id_ = lifecycle_id_generator_.GetNext(); - google::protobuf::internal::NoBarrier_Store(&hint_, 0); - google::protobuf::internal::NoBarrier_Store(&threads_, 0); + lifecycle_id_ = + lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); + hint_.store(nullptr, std::memory_order_relaxed); + threads_.store(nullptr, std::memory_order_relaxed); if (initial_block_) { // Thread which calls Init() owns the first block. This allows the @@ -77,13 +78,12 @@ void ArenaImpl::Init() { SerialArena* serial = SerialArena::New(initial_block_, &thread_cache(), this); serial->set_next(NULL); - google::protobuf::internal::NoBarrier_Store(&threads_, - reinterpret_cast<google::protobuf::internal::AtomicWord>(serial)); - google::protobuf::internal::NoBarrier_Store(&space_allocated_, - options_.initial_block_size); + threads_.store(serial, std::memory_order_relaxed); + space_allocated_.store(options_.initial_block_size, + std::memory_order_relaxed); CacheSerialArena(serial); } else { - google::protobuf::internal::NoBarrier_Store(&space_allocated_, 0); + space_allocated_.store(0, std::memory_order_relaxed); } } @@ -118,7 +118,7 @@ ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) { void* mem = options_.block_alloc(size); Block* b = new (mem) Block(size, last_block); - google::protobuf::internal::NoBarrier_AtomicIncrement(&space_allocated_, size); + space_allocated_.fetch_add(size, std::memory_order_relaxed); return b; } @@ -142,6 +142,7 @@ void ArenaImpl::SerialArena::AddCleanupFallback(void* elem, AddCleanup(elem, cleanup); } +GOOGLE_PROTOBUF_ATTRIBUTE_FUNC_ALIGN(32) void* ArenaImpl::AllocateAligned(size_t n) { SerialArena* arena; if (GOOGLE_PREDICT_TRUE(GetSerialArenaFast(&arena))) { @@ -199,8 +200,7 @@ bool ArenaImpl::GetSerialArenaFast(ArenaImpl::SerialArena** arena) { // Check whether we own the last accessed SerialArena on this arena. This // fast path optimizes the case where a single thread uses multiple arenas. - SerialArena* serial = - reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&hint_)); + SerialArena* serial = hint_.load(std::memory_order_acquire); if (GOOGLE_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) { *arena = serial; return true; @@ -235,12 +235,11 @@ void* ArenaImpl::SerialArena::AllocateAlignedFallback(size_t n) { } uint64 ArenaImpl::SpaceAllocated() const { - return google::protobuf::internal::NoBarrier_Load(&space_allocated_); + return space_allocated_.load(std::memory_order_relaxed); } uint64 ArenaImpl::SpaceUsed() const { - SerialArena* serial = - reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&threads_)); + SerialArena* serial = threads_.load(std::memory_order_acquire); uint64 space_used = 0; for ( ; serial; serial = serial->next()) { space_used += serial->SpaceUsed(); @@ -264,8 +263,7 @@ uint64 ArenaImpl::FreeBlocks() { uint64 space_allocated = 0; // By omitting an Acquire barrier we ensure that any user code that doesn't // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = - reinterpret_cast<SerialArena*>(google::protobuf::internal::NoBarrier_Load(&threads_)); + SerialArena* serial = threads_.load(std::memory_order_relaxed); while (serial) { // This is inside a block we are freeing, so we need to read it now. @@ -311,8 +309,7 @@ uint64 ArenaImpl::SerialArena::Free(ArenaImpl::SerialArena* serial, void ArenaImpl::CleanupList() { // By omitting an Acquire barrier we ensure that any user code that doesn't // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = - reinterpret_cast<SerialArena*>(google::protobuf::internal::NoBarrier_Load(&threads_)); + SerialArena* serial = threads_.load(std::memory_order_relaxed); for ( ; serial; serial = serial->next()) { serial->CleanupList(); @@ -368,8 +365,7 @@ ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner, GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { // Look for this SerialArena in our linked list. - SerialArena* serial = - reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&threads_)); + SerialArena* serial = threads_.load(std::memory_order_acquire); for ( ; serial; serial = serial->next()) { if (serial->owner() == me) { break; @@ -382,12 +378,11 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { Block* b = NewBlock(NULL, kSerialArenaSize); serial = SerialArena::New(b, me, this); - google::protobuf::internal::AtomicWord head; + SerialArena* head = threads_.load(std::memory_order_relaxed); do { - head = google::protobuf::internal::NoBarrier_Load(&threads_); - serial->set_next(reinterpret_cast<SerialArena*>(head)); - } while (google::protobuf::internal::Release_CompareAndSwap( - &threads_, head, reinterpret_cast<google::protobuf::internal::AtomicWord>(serial)) != head); + serial->set_next(head); + } while (!threads_.compare_exchange_weak( + head, serial, std::memory_order_release, std::memory_order_relaxed)); } CacheSerialArena(serial); |