Index: src/IceThreading.h |
diff --git a/src/IceThreading.h b/src/IceThreading.h |
index f59f46e3bad590a55b23ba71732a95f6e2a864d9..b0bcc013931aea245257ec16e9a218f0e95de538 100644 |
--- a/src/IceThreading.h |
+++ b/src/IceThreading.h |
@@ -22,31 +22,29 @@ |
namespace Ice { |
-/// BoundedProducerConsumerQueue is a work queue that allows multiple |
-/// producers and multiple consumers. A producer adds entries using |
-/// blockingPush(), and may block if the queue is "full". A producer |
-/// uses notifyEnd() to indicate that no more entries will be added. A |
-/// consumer removes an item using blockingPop(), which will return |
-/// nullptr if notifyEnd() has been called and the queue is empty (it |
-/// never returns nullptr if the queue contained any items). |
+/// BoundedProducerConsumerQueue is a work queue that allows multiple producers |
+/// and multiple consumers. A producer adds entries using blockingPush(), and |
+/// may block if the queue is "full". A producer uses notifyEnd() to indicate |
+/// that no more entries will be added. A consumer removes an item using |
+/// blockingPop(), which will return nullptr if notifyEnd() has been called and |
+/// the queue is empty (it never returns nullptr if the queue contained any |
+/// items). |
/// |
-/// The MaxSize ctor arg controls the maximum size the queue can grow |
-/// to (subject to a hard limit of MaxStaticSize-1). The Sequential |
-/// arg indicates purely sequential execution in which the single |
-/// thread should never wait(). |
+/// The MaxSize ctor arg controls the maximum size the queue can grow to |
+/// (subject to a hard limit of MaxStaticSize-1). The Sequential arg indicates |
+/// purely sequential execution in which the single thread should never wait(). |
/// |
-/// Two condition variables are used in the implementation. |
-/// GrewOrEnded signals a waiting worker that a producer has changed |
-/// the state of the queue. Shrunk signals a blocked producer that a |
-/// consumer has changed the state of the queue. |
+/// Two condition variables are used in the implementation. GrewOrEnded signals |
+/// a waiting worker that a producer has changed the state of the queue. Shrunk |
+/// signals a blocked producer that a consumer has changed the state of the |
+/// queue. |
/// |
-/// The methods begin with Sequential-specific code to be most clear. |
-/// The lock and condition variables are not used in the Sequential |
-/// case. |
+/// The methods begin with Sequential-specific code to be most clear. The lock |
+/// and condition variables are not used in the Sequential case. |
/// |
/// Internally, the queue is implemented as a circular array of size |
-/// MaxStaticSize, where the queue boundaries are denoted by the Front |
-/// and Back fields. Front==Back indicates an empty queue. |
+/// MaxStaticSize, where the queue boundaries are denoted by the Front and Back |
+/// fields. Front==Back indicates an empty queue. |
template <typename T, size_t MaxStaticSize = 128> |
class BoundedProducerConsumerQueue { |
BoundedProducerConsumerQueue() = delete; |
@@ -60,8 +58,8 @@ public: |
void blockingPush(T *Item) { |
{ |
std::unique_lock<GlobalLockType> L(Lock); |
- // If the work queue is already "full", wait for a consumer to |
- // grab an element and shrink the queue. |
+ // If the work queue is already "full", wait for a consumer to grab an |
+ // element and shrink the queue. |
Shrunk.wait(L, [this] { return size() < MaxSize || Sequential; }); |
push(Item); |
} |
@@ -103,27 +101,23 @@ private: |
GlobalLockType Lock; |
ICE_CACHELINE_BOUNDARY; |
- /// GrewOrEnded is written by the producers and read by the |
- /// consumers. It is notified (by the producer) when something is |
- /// added to the queue, in case consumers are waiting for a non-empty |
- /// queue. |
+ /// GrewOrEnded is written by the producers and read by the consumers. It is |
+ /// notified (by the producer) when something is added to the queue, in case |
+ /// consumers are waiting for a non-empty queue. |
std::condition_variable GrewOrEnded; |
- /// Back is the index into WorkItems[] of where the next element will |
- /// be pushed. (More precisely, Back&MaxStaticSize is the index.) |
- /// It is written by the producers, and read by all via size() and |
- /// empty(). |
+ /// Back is the index into WorkItems[] of where the next element will be |
+ /// pushed. (More precisely, Back&MaxStaticSize is the index.) It is written |
+ /// by the producers, and read by all via size() and empty(). |
size_t Back = 0; |
ICE_CACHELINE_BOUNDARY; |
- /// Shrunk is notified (by the consumer) when something is removed |
- /// from the queue, in case a producer is waiting for the queue to |
- /// drop below maximum capacity. It is written by the consumers and |
- /// read by the producers. |
+ /// Shrunk is notified (by the consumer) when something is removed from the |
+ /// queue, in case a producer is waiting for the queue to drop below maximum |
+ /// capacity. It is written by the consumers and read by the producers. |
std::condition_variable Shrunk; |
- /// Front is the index into WorkItems[] of the oldest element, |
- /// i.e. the next to be popped. (More precisely Front&MaxStaticSize |
- /// is the index.) It is written by the consumers, and read by all |
- /// via size() and empty(). |
+ /// Front is the index into WorkItems[] of the oldest element, i.e. the next |
+ /// to be popped. (More precisely Front&MaxStaticSize is the index.) It is |
+ /// written by the consumers, and read by all via size() and empty(). |
size_t Front = 0; |
ICE_CACHELINE_BOUNDARY; |
@@ -131,8 +125,7 @@ private: |
/// MaxSize and Sequential are read by all and written by none. |
const size_t MaxSize; |
const bool Sequential; |
- /// IsEnded is read by the consumers, and only written once by the |
- /// producer. |
+ /// IsEnded is read by the consumers, and only written once by the producer. |
bool IsEnded = false; |
/// The lock must be held when the following methods are called. |
@@ -148,15 +141,14 @@ private: |
} |
}; |
-/// EmitterWorkItem is a simple wrapper around a pointer that |
-/// represents a work item to be emitted, i.e. a function or a set of |
-/// global declarations and initializers, and it includes a sequence |
-/// number so that work items can be emitted in a particular order for |
-/// deterministic output. It acts like an interface class, but instead |
-/// of making the classes of interest inherit from EmitterWorkItem, it |
-/// wraps pointers to these classes. Some space is wasted compared to |
-/// storing the pointers in a union, but not too much due to the work |
-/// granularity. |
+/// EmitterWorkItem is a simple wrapper around a pointer that represents a work |
+/// item to be emitted, i.e. a function or a set of global declarations and |
+/// initializers, and it includes a sequence number so that work items can be |
+/// emitted in a particular order for deterministic output. It acts like an |
+/// interface class, but instead of making the classes of interest inherit from |
+/// EmitterWorkItem, it wraps pointers to these classes. Some space is wasted |
+/// compared to storing the pointers in a union, but not too much due to the |
+/// work granularity. |
class EmitterWorkItem { |
EmitterWorkItem() = delete; |
EmitterWorkItem(const EmitterWorkItem &) = delete; |
@@ -165,20 +157,19 @@ class EmitterWorkItem { |
public: |
/// ItemKind can be one of the following: |
/// |
- /// WI_Nop: No actual work. This is a placeholder to maintain |
- /// sequence numbers in case there is a translation error. |
+ /// WI_Nop: No actual work. This is a placeholder to maintain sequence numbers |
+ /// in case there is a translation error. |
/// |
/// WI_GlobalInits: A list of global declarations and initializers. |
/// |
- /// WI_Asm: A function that has already had emitIAS() called on it. |
- /// The work is transferred via the Assembler buffer, and the |
- /// originating Cfg has been deleted (to recover lots of memory). |
+ /// WI_Asm: A function that has already had emitIAS() called on it. The work |
+ /// is transferred via the Assembler buffer, and the originating Cfg has been |
+ /// deleted (to recover lots of memory). |
/// |
- /// WI_Cfg: A Cfg that has not yet had emit() or emitIAS() called on |
- /// it. This is only used as a debugging configuration when we want |
- /// to emit "readable" assembly code, possibly annotated with |
- /// liveness and other information only available in the Cfg and not |
- /// in the Assembler buffer. |
+ /// WI_Cfg: A Cfg that has not yet had emit() or emitIAS() called on it. This |
+ /// is only used as a debugging configuration when we want to emit "readable" |
+ /// assembly code, possibly annotated with liveness and other information only |
+ /// available in the Cfg and not in the Assembler buffer. |
enum ItemKind { WI_Nop, WI_GlobalInits, WI_Asm, WI_Cfg }; |
/// Constructor for a WI_Nop work item. |
explicit EmitterWorkItem(uint32_t Seq); |