Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: src/IceThreading.h

Issue 876083007: Subzero: Emit functions and global initializers in a separate thread. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: More code review changes Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX8632.cpp ('k') | src/IceTranslator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceUtils.h - Utility functions ---------------*- C++ -*-===// 1 //===- subzero/src/IceThreading.h - Threading functions ---------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares some utility functions. 10 // This file defines threading-related functions.
11 // 11 //
12 //===----------------------------------------------------------------------===// 12 //===----------------------------------------------------------------------===//
13 13
14 #ifndef SUBZERO_SRC_ICEUTILS_H 14 #ifndef SUBZERO_SRC_ICETHREADING_H
15 #define SUBZERO_SRC_ICEUTILS_H 15 #define SUBZERO_SRC_ICETHREADING_H
16 16
17 #include <climits>
18 #include <condition_variable> 17 #include <condition_variable>
18 #include <mutex>
19
20 #include "IceDefs.h"
19 21
20 namespace Ice { 22 namespace Ice {
21 23
22 // Similar to bit_cast, but allows copying from types of unrelated
23 // sizes. This method was introduced to enable the strict aliasing
24 // optimizations of GCC 4.4. Basically, GCC mindlessly relies on
25 // obscure details in the C++ standard that make reinterpret_cast
26 // virtually useless.
27 template <class D, class S> inline D bit_copy(const S &source) {
28 D destination;
29 // This use of memcpy is safe: source and destination cannot overlap.
30 memcpy(&destination, reinterpret_cast<const void *>(&source),
31 sizeof(destination));
32 return destination;
33 }
34
35 class Utils {
36 public:
37 // Check whether an N-bit two's-complement representation can hold value.
38 template <typename T> static inline bool IsInt(int N, T value) {
39 assert((0 < N) &&
40 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
41 T limit = static_cast<T>(1) << (N - 1);
42 return (-limit <= value) && (value < limit);
43 }
44
45 template <typename T> static inline bool IsUint(int N, T value) {
46 assert((0 < N) &&
47 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
48 T limit = static_cast<T>(1) << N;
49 return (0 <= value) && (value < limit);
50 }
51
52 template <typename T> static inline bool WouldOverflowAdd(T X, T Y) {
53 return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
54 (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
55 }
56
57 static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) {
58 assert(llvm::isPowerOf2_64(Align));
59 uint64_t Mod = Pos & (Align - 1);
60 if (Mod == 0)
61 return 0;
62 return Align - Mod;
63 }
64 };
65
66 // BoundedProducerConsumerQueue is a work queue that allows multiple 24 // BoundedProducerConsumerQueue is a work queue that allows multiple
67 // producers and multiple consumers. A producer adds entries using 25 // producers and multiple consumers. A producer adds entries using
68 // blockingPush(), and may block if the queue is "full". A producer 26 // blockingPush(), and may block if the queue is "full". A producer
69 // uses notifyEnd() to indicate that no more entries will be added. A 27 // uses notifyEnd() to indicate that no more entries will be added. A
70 // consumer removes an item using blockingPop(), which will return 28 // consumer removes an item using blockingPop(), which will return
71 // nullptr if notifyEnd() has been called and the queue is empty (it 29 // nullptr if notifyEnd() has been called and the queue is empty (it
72 // never returns nullptr if the queue contained any items). 30 // never returns nullptr if the queue contained any items).
73 // 31 //
74 // The MaxSize ctor arg controls the maximum size the queue can grow 32 // The MaxSize ctor arg controls the maximum size the queue can grow
75 // to (subject to a hard limit of MaxStaticSize-1). The Sequential 33 // to (subject to a hard limit of MaxStaticSize-1). The Sequential
(...skipping 13 matching lines...) Expand all
89 // MaxStaticSize, where the queue boundaries are denoted by the Front 47 // MaxStaticSize, where the queue boundaries are denoted by the Front
90 // and Back fields. Front==Back indicates an empty queue. 48 // and Back fields. Front==Back indicates an empty queue.
91 template <typename T, size_t MaxStaticSize = 128> 49 template <typename T, size_t MaxStaticSize = 128>
92 class BoundedProducerConsumerQueue { 50 class BoundedProducerConsumerQueue {
93 BoundedProducerConsumerQueue() = delete; 51 BoundedProducerConsumerQueue() = delete;
94 BoundedProducerConsumerQueue(const BoundedProducerConsumerQueue &) = delete; 52 BoundedProducerConsumerQueue(const BoundedProducerConsumerQueue &) = delete;
95 BoundedProducerConsumerQueue & 53 BoundedProducerConsumerQueue &
96 operator=(const BoundedProducerConsumerQueue &) = delete; 54 operator=(const BoundedProducerConsumerQueue &) = delete;
97 55
98 public: 56 public:
99 BoundedProducerConsumerQueue(size_t MaxSize, bool Sequential) 57 BoundedProducerConsumerQueue(bool Sequential, size_t MaxSize = MaxStaticSize)
100 : Back(0), Front(0), MaxSize(std::min(MaxSize, MaxStaticSize)), 58 : Back(0), Front(0), MaxSize(std::min(MaxSize, MaxStaticSize)),
101 Sequential(Sequential), IsEnded(false) {} 59 Sequential(Sequential), IsEnded(false) {}
102 void blockingPush(T *Item) { 60 void blockingPush(T *Item) {
103 { 61 {
104 std::unique_lock<GlobalLockType> L(Lock); 62 std::unique_lock<GlobalLockType> L(Lock);
105 // If the work queue is already "full", wait for a consumer to 63 // If the work queue is already "full", wait for a consumer to
106 // grab an element and shrink the queue. 64 // grab an element and shrink the queue.
107 Shrunk.wait(L, [this] { return size() < MaxSize || Sequential; }); 65 Shrunk.wait(L, [this] { return size() < MaxSize || Sequential; });
108 push(Item); 66 push(Item);
109 } 67 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 void push(T *Item) { 141 void push(T *Item) {
184 WorkItems[Back++ & MaxStaticSizeMask] = Item; 142 WorkItems[Back++ & MaxStaticSizeMask] = Item;
185 assert(size() <= MaxStaticSize); 143 assert(size() <= MaxStaticSize);
186 } 144 }
187 T *pop() { 145 T *pop() {
188 assert(!empty()); 146 assert(!empty());
189 return WorkItems[Front++ & MaxStaticSizeMask]; 147 return WorkItems[Front++ & MaxStaticSizeMask];
190 } 148 }
191 }; 149 };
192 150
151 // EmitterWorkItem is a simple wrapper around a pointer that
152 // represents a work item to be emitted, i.e. a function or a set of
153 // global declarations and initializers, and it includes a sequence
154 // number so that work items can be emitted in a particular order for
155 // deterministic output. It acts like an interface class, but instead
156 // of making the classes of interest inherit from EmitterWorkItem, it
157 // wraps pointers to these classes. Some space is wasted compared to
158 // storing the pointers in a union, but not too much due to the work
159 // granularity.
160 class EmitterWorkItem {
161 EmitterWorkItem() = delete;
162 EmitterWorkItem(const EmitterWorkItem &) = delete;
163 EmitterWorkItem &operator=(const EmitterWorkItem &) = delete;
164
165 public:
166 // ItemKind can be one of the following:
167 //
168 // WI_Nop: No actual work. This is a placeholder to maintain
169 // sequence numbers in case there is a translation error.
170 //
171 // WI_GlobalInits: A list of global declarations and initializers.
172 //
173 // WI_Asm: A function that has already had emitIAS() called on it.
174 // The work is transferred via the Assembler buffer, and the
175 // originating Cfg has been deleted (to recover lots of memory).
176 //
177 // WI_Cfg: A Cfg that has not yet had emit() or emitIAS() called on
178 // it. This is only used as a debugging configuration when we want
179 // to emit "readable" assembly code, possibly annotated with
180 // liveness and other information only available in the Cfg and not
181 // in the Assembler buffer.
182 enum ItemKind { WI_Nop, WI_GlobalInits, WI_Asm, WI_Cfg };
183 // Constructor for a WI_Nop work item.
184 explicit EmitterWorkItem(uint32_t Seq)
185 : Sequence(Seq), Kind(WI_Nop), GlobalInits(nullptr), Function(nullptr),
186 RawFunc(nullptr) {}
187 // Constructor for a WI_GlobalInits work item.
188 EmitterWorkItem(uint32_t Seq, VariableDeclarationList *D)
189 : Sequence(Seq), Kind(WI_GlobalInits), GlobalInits(D), Function(nullptr),
190 RawFunc(nullptr) {}
191 // Constructor for a WI_Asm work item.
192 EmitterWorkItem(uint32_t Seq, Assembler *A)
193 : Sequence(Seq), Kind(WI_Asm), GlobalInits(nullptr), Function(A),
194 RawFunc(nullptr) {}
195 // Constructor for a WI_Cfg work item.
196 EmitterWorkItem(uint32_t Seq, Cfg *F)
197 : Sequence(Seq), Kind(WI_Cfg), GlobalInits(nullptr), Function(nullptr),
198 RawFunc(F) {}
199 uint32_t getSequenceNumber() const { return Sequence; }
200 ItemKind getKind() const { return Kind; }
201 VariableDeclarationList *getGlobalInits() const {
202 assert(getKind() == WI_GlobalInits);
203 return GlobalInits;
204 }
205 Assembler *getAsm() const {
206 assert(getKind() == WI_Asm);
207 return Function;
208 }
209 Cfg *getCfg() const {
210 assert(getKind() == WI_Cfg);
211 return RawFunc;
212 }
213 ~EmitterWorkItem();
214
215 private:
216 const uint32_t Sequence;
217 const ItemKind Kind;
218 VariableDeclarationList *const GlobalInits;
219 Assembler *const Function;
220 Cfg *const RawFunc;
221 };
222
193 } // end of namespace Ice 223 } // end of namespace Ice
194 224
195 #endif // SUBZERO_SRC_ICEUTILS_H 225 #endif // SUBZERO_SRC_ICETHREADING_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.cpp ('k') | src/IceTranslator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698