gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
futex_map.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Authors: Brandon Potter
29  * Steve Reinhardt
30  * Alexandru Dutu
31  */
32 
33 #ifndef __FUTEX_MAP_HH__
34 #define __FUTEX_MAP_HH__
35 
36 #include <unordered_map>
37 
38 #include <cpu/thread_context.hh>
39 
44 class FutexKey {
45  public:
46  uint64_t addr;
47  uint64_t tgid;
48 
49  FutexKey(uint64_t addr_in, uint64_t tgid_in)
50  : addr(addr_in), tgid(tgid_in)
51  {
52  }
53 
54  bool
55  operator==(const FutexKey &in) const
56  {
57  return addr == in.addr && tgid == in.tgid;
58  }
59 };
60 
61 namespace std {
67  template <>
68  struct hash<FutexKey>
69  {
70  size_t operator()(const FutexKey& in) const
71  {
72  size_t hash = 65521;
73  for (int i = 0; i < sizeof(uint64_t) / sizeof(size_t); i++) {
74  hash ^= (size_t)(in.addr >> sizeof(size_t) * i) ^
75  (size_t)(in.tgid >> sizeof(size_t) * i);
76  }
77  return hash;
78  }
79  };
80 }
81 
86 class WaiterState {
87  public:
89  int bitmask;
90 
94  WaiterState(ThreadContext* _tc, int _bitmask)
95  : tc(_tc), bitmask(_bitmask)
96  { }
97 
102  : tc(_tc), bitmask(0xffffffff)
103  { }
104 
109  bool
110  checkMask(int wakeup_bitmask) const
111  {
112  return bitmask & wakeup_bitmask;
113  }
114 };
115 
117 
121 class FutexMap : public std::unordered_map<FutexKey, WaiterList>
122 {
123  public:
125  void
127  {
128  FutexKey key(addr, tgid);
129  auto it = find(key);
130 
131  if (it == end()) {
132  WaiterList waiterList {WaiterState(tc)};
133  insert({key, waiterList});
134  } else {
135  it->second.push_back(WaiterState(tc));
136  }
137 
139  tc->suspend();
140  }
141 
143  int
144  wakeup(Addr addr, uint64_t tgid, int count)
145  {
146  FutexKey key(addr, tgid);
147  auto it = find(key);
148 
149  if (it == end())
150  return 0;
151 
152  int woken_up = 0;
153  auto &waiterList = it->second;
154 
155  while (!waiterList.empty() && woken_up < count) {
156  // Threads may be woken up by access to locked
157  // memory addresses outside of syscalls, so we
158  // must only count threads that were actually
159  // woken up by this syscall.
160  auto& tc = waiterList.front().tc;
161  if (tc->status() == ThreadContext::Suspended) {
162  tc->activate();
163  woken_up++;
164  }
165  waiterList.pop_front();
166  }
167 
168  if (waiterList.empty())
169  erase(it);
170 
171  return woken_up;
172  }
173 
178  void
180  int bitmask)
181  {
182  FutexKey key(addr, tgid);
183  auto it = find(key);
184 
185  if (it == end()) {
186  WaiterList waiterList {WaiterState(tc, bitmask)};
187  insert({key, waiterList});
188  } else {
189  it->second.push_back(WaiterState(tc, bitmask));
190  }
191 
193  tc->suspend();
194  }
195 
200  int
201  wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
202  {
203  FutexKey key(addr, tgid);
204  auto it = find(key);
205 
206  if (it == end())
207  return 0;
208 
209  int woken_up = 0;
210 
211  auto &waiterList = it->second;
212  auto iter = waiterList.begin();
213 
214  while (iter != waiterList.end()) {
215  WaiterState& waiter = *iter;
216 
217  if (waiter.checkMask(bitmask)) {
218  waiter.tc->activate();
219  iter = waiterList.erase(iter);
220  woken_up++;
221  } else {
222  ++iter;
223  }
224  }
225 
226  if (waiterList.empty())
227  erase(it);
228 
229  return woken_up;
230  }
231 
242  int
243  requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
244  {
245  FutexKey key1(addr1, tgid);
246  auto it1 = find(key1);
247 
248  if (it1 == end())
249  return 0;
250 
251  int woken_up = 0;
252  auto &waiterList1 = it1->second;
253 
254  while (!waiterList1.empty() && woken_up < count) {
255  waiterList1.front().tc->activate();
256  waiterList1.pop_front();
257  woken_up++;
258  }
259 
260  WaiterList tmpList;
261  int requeued = 0;
262 
263  while (!waiterList1.empty() && requeued < count2) {
264  auto w = waiterList1.front();
265  waiterList1.pop_front();
266  tmpList.push_back(w);
267  requeued++;
268  }
269 
270  FutexKey key2(addr2, tgid);
271  auto it2 = find(key2);
272 
273  if (it2 == end() && requeued > 0) {
274  insert({key2, tmpList});
275  } else {
276  it2->second.insert(it2->second.end(),
277  tmpList.begin(), tmpList.end());
278  }
279 
280  if (waiterList1.empty())
281  erase(it1);
282 
283  return woken_up + requeued;
284  }
285 };
286 
287 #endif // __FUTEX_MAP_HH__
count
Definition: misc.hh:705
bool operator==(const FutexKey &in) const
Definition: futex_map.hh:55
std::list< WaiterState > WaiterList
Definition: futex_map.hh:116
Bitfield< 7 > i
size_t operator()(const FutexKey &in) const
Definition: futex_map.hh:70
WaiterState defines internal state of a waiter thread.
Definition: futex_map.hh:86
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
bool checkMask(int wakeup_bitmask) const
return true if the bit-wise AND of the wakeup_bitmask given by a waking thread and this thread&#39;s inte...
Definition: futex_map.hh:110
ThreadContext is the external interface to all thread state for anything outside of the CPU...
int requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
This operation wakes a given number (val) of waiters.
Definition: futex_map.hh:243
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
Definition: futex_map.hh:144
Bitfield< 26, 25 > it1
virtual void suspend()=0
Set the status to Suspended.
STL list class.
Definition: stl.hh:54
virtual void activate()=0
Set the status to Active.
Bitfield< 0 > w
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
uint64_t addr
Definition: futex_map.hh:46
WaiterState(ThreadContext *_tc)
if bitset is not defined, just set bitmask to 0xffffffff
Definition: futex_map.hh:101
WaiterState(ThreadContext *_tc, int _bitmask)
this constructor is used if futex ops with bitset are used
Definition: futex_map.hh:94
void suspend_bitset(Addr addr, uint64_t tgid, ThreadContext *tc, int bitmask)
inserts a futex into the map with one waiting TC associates the waiter with a given bitmask ...
Definition: futex_map.hh:179
int wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
Wakes up all waiters waiting on the addr and associated with the given bitset.
Definition: futex_map.hh:201
FutexKey(uint64_t addr_in, uint64_t tgid_in)
Definition: futex_map.hh:49
void suspend(Addr addr, uint64_t tgid, ThreadContext *tc)
Inserts a futex into the map with one waiting TC.
Definition: futex_map.hh:126
FutexMap class holds a map of all futexes used in the system.
Definition: futex_map.hh:121
Temporarily inactive.
ThreadContext * tc
Definition: futex_map.hh:88
FutexKey class defines an unique identifier for a particular futex in the system. ...
Definition: futex_map.hh:44
Bitfield< 15, 10 > it2
uint64_t tgid
Definition: futex_map.hh:47

Generated on Fri Feb 28 2020 16:27:02 for gem5 by doxygen 1.8.13