X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FProducerConsumerQueue.h;h=12f2bf427c33ce9485ac393d42097f6b1a1a1741;hb=0d38f5770ebf7e3ec987c55da719c29c2be3f3f2;hp=da9b93a4d57efd461185ece5ca7ea75d22e1519a;hpb=dee8a5180aa542d98d1b71c74f83a006e4627952;p=folly.git diff --git a/folly/ProducerConsumerQueue.h b/folly/ProducerConsumerQueue.h index da9b93a4..12f2bf42 100644 --- a/folly/ProducerConsumerQueue.h +++ b/folly/ProducerConsumerQueue.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,13 @@ #include #include #include +#include #include #include #include +#include + namespace folly { /* @@ -61,12 +64,12 @@ struct ProducerConsumerQueue { // (No real synchronization needed at destructor time: only one // thread can be doing this.) if (!std::is_trivially_destructible::value) { - size_t read = readIndex_; - size_t end = writeIndex_; - while (read != end) { - records_[read].~T(); - if (++read == size_) { - read = 0; + size_t readIndex = readIndex_; + size_t endIndex = writeIndex_; + while (readIndex != endIndex) { + records_[readIndex].~T(); + if (++readIndex == size_) { + readIndex = 0; } } } @@ -134,16 +137,16 @@ struct ProducerConsumerQueue { } bool isEmpty() const { - return readIndex_.load(std::memory_order_consume) == - writeIndex_.load(std::memory_order_consume); + return readIndex_.load(std::memory_order_acquire) == + writeIndex_.load(std::memory_order_acquire); } bool isFull() const { - auto nextRecord = writeIndex_.load(std::memory_order_consume) + 1; + auto nextRecord = writeIndex_.load(std::memory_order_acquire) + 1; if (nextRecord == size_) { nextRecord = 0; } - if (nextRecord != readIndex_.load(std::memory_order_consume)) { + if (nextRecord != readIndex_.load(std::memory_order_acquire)) { return false; } // queue is full @@ -156,8 +159,8 @@ struct ProducerConsumerQueue { // be removing items concurrently). // * It is undefined to call this from any other thread. size_t sizeGuess() const { - int ret = writeIndex_.load(std::memory_order_consume) - - readIndex_.load(std::memory_order_consume); + int ret = writeIndex_.load(std::memory_order_acquire) - + readIndex_.load(std::memory_order_acquire); if (ret < 0) { ret += size_; } @@ -165,11 +168,14 @@ struct ProducerConsumerQueue { } private: - const uint32_t size_; - T* const records_; + char pad0_[CacheLocality::kFalseSharingRange]; + const uint32_t size_; + T* const records_; + + FOLLY_ALIGN_TO_AVOID_FALSE_SHARING std::atomic readIndex_; + FOLLY_ALIGN_TO_AVOID_FALSE_SHARING std::atomic writeIndex_; - std::atomic readIndex_; - std::atomic writeIndex_; + char pad1_[CacheLocality::kFalseSharingRange - sizeof(writeIndex_)]; }; }