gem5  v20.1.0.0
futex_map.cc
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 
29 #include <sim/futex_map.hh>
30 
31 FutexKey::FutexKey(uint64_t addr_in, uint64_t tgid_in)
32  : addr(addr_in), tgid(tgid_in) {}
33 
34 bool
36 {
37  return addr == in.addr && tgid == in.tgid;
38 }
39 
40 namespace std {
41  size_t hash<FutexKey>::operator()(const FutexKey& in) const
42  {
43  size_t hash = 65521;
44  for (int i = 0; i < sizeof(uint64_t) / sizeof(size_t); i++) {
45  hash ^= (size_t)(in.addr >> sizeof(size_t) * i) ^
46  (size_t)(in.tgid >> sizeof(size_t) * i);
47  }
48  return hash;
49  }
50 }
51 
53  : tc(_tc), bitmask(_bitmask) { }
54 
55 bool
56 WaiterState::checkMask(int wakeup_bitmask) const
57 {
58  return bitmask & wakeup_bitmask;
59 }
60 
61 void
63 {
64  suspend_bitset(addr, tgid, tc, 0xffffffff);
65 }
66 
67 int
68 FutexMap::wakeup(Addr addr, uint64_t tgid, int count)
69 {
70  FutexKey key(addr, tgid);
71  auto it = find(key);
72 
73  if (it == end())
74  return 0;
75 
76  int woken_up = 0;
77  auto &waiterList = it->second;
78 
79  while (!waiterList.empty() && woken_up < count) {
80  // Threads may be woken up by access to locked
81  // memory addresses outside of syscalls, so we
82  // must only count threads that were actually
83  // woken up by this syscall.
84  auto& tc = waiterList.front().tc;
85  tc->activate();
86  woken_up++;
87  waiterList.pop_front();
88  waitingTcs.erase(tc);
89  }
90 
91  if (waiterList.empty())
92  erase(it);
93 
94  return woken_up;
95 }
96 
97 void
99  int bitmask)
100 {
101  FutexKey key(addr, tgid);
102  auto it = find(key);
103 
104  if (it == end()) {
105  WaiterList waiterList {WaiterState(tc, bitmask)};
106  insert({key, waiterList});
107  } else {
108  it->second.push_back(WaiterState(tc, bitmask));
109  }
110  waitingTcs.emplace(tc);
111 
113  tc->suspend();
114 }
115 
116 int
117 FutexMap::wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
118 {
119  FutexKey key(addr, tgid);
120  auto it = find(key);
121 
122  if (it == end())
123  return 0;
124 
125  int woken_up = 0;
126 
127  auto &waiterList = it->second;
128  auto iter = waiterList.begin();
129 
130  while (iter != waiterList.end()) {
131  WaiterState& waiter = *iter;
132 
133  if (waiter.checkMask(bitmask)) {
134  waiter.tc->activate();
135  iter = waiterList.erase(iter);
136  waitingTcs.erase(waiter.tc);
137  woken_up++;
138  } else {
139  ++iter;
140  }
141  }
142 
143  if (waiterList.empty())
144  erase(it);
145 
146  return woken_up;
147 }
148 
149 int
150 FutexMap::requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
151 {
152  FutexKey key1(addr1, tgid);
153  auto it1 = find(key1);
154 
155  if (it1 == end())
156  return 0;
157 
158  int woken_up = 0;
159  auto &waiterList1 = it1->second;
160 
161  while (!waiterList1.empty() && woken_up < count) {
162  waiterList1.front().tc->activate();
163  waiterList1.pop_front();
164  woken_up++;
165  }
166 
167  WaiterList tmpList;
168  int requeued = 0;
169 
170  while (!waiterList1.empty() && requeued < count2) {
171  auto w = waiterList1.front();
172  waiterList1.pop_front();
173  tmpList.push_back(w);
174  requeued++;
175  }
176 
177  FutexKey key2(addr2, tgid);
178  auto it2 = find(key2);
179 
180  if (it2 == end() && requeued > 0) {
181  insert({key2, tmpList});
182  } else {
183  it2->second.insert(it2->second.end(),
184  tmpList.begin(), tmpList.end());
185  }
186 
187  if (waiterList1.empty())
188  erase(it1);
189 
190  return woken_up + requeued;
191 }
192 
193 bool
195 {
196  return waitingTcs.find(tc) != waitingTcs.end();
197 }
FutexMap::suspend
void suspend(Addr addr, uint64_t tgid, ThreadContext *tc)
Inserts a futex into the map with one waiting TC.
Definition: futex_map.cc:62
ArmISA::it2
Bitfield< 15, 10 > it2
Definition: miscregs_types.hh:59
FutexMap::wakeup
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
Definition: futex_map.cc:68
FutexMap::waitingTcs
std::unordered_set< ThreadContext * > waitingTcs
Definition: futex_map.hh:124
ThreadContext::activate
virtual void activate()=0
Set the status to Active.
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
FutexKey::operator==
bool operator==(const FutexKey &in) const
Definition: futex_map.cc:35
FutexKey::addr
uint64_t addr
Definition: futex_map.hh:43
FutexMap::suspend_bitset
void suspend_bitset(Addr addr, uint64_t tgid, ThreadContext *tc, int bitmask)
Definition: futex_map.cc:98
ThreadContext::suspend
virtual void suspend()=0
Set the status to Suspended.
WaiterState::checkMask
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's inte...
Definition: futex_map.cc:56
futex_map.hh
X86ISA::count
count
Definition: misc.hh:703
FutexMap::is_waiting
bool is_waiting(ThreadContext *tc)
Determine if the given thread context is currently waiting on a futex wait operation on any of the fu...
Definition: futex_map.cc:194
FutexKey
FutexKey class defines an unique identifier for a particular futex in the system.
Definition: futex_map.hh:41
WaiterState::bitmask
int bitmask
Definition: futex_map.hh:71
FutexKey::tgid
uint64_t tgid
Definition: futex_map.hh:44
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
MipsISA::w
Bitfield< 0 > w
Definition: pra_constants.hh:278
std::hash< FutexKey >::operator()
size_t operator()(const FutexKey &in) const
Definition: futex_map.cc:41
ArmISA::it1
Bitfield< 26, 25 > it1
Definition: miscregs_types.hh:53
WaiterState::WaiterState
WaiterState(ThreadContext *_tc, int _bitmask)
this constructor is used if futex ops with bitset are used
Definition: futex_map.cc:52
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
FutexKey::FutexKey
FutexKey(uint64_t addr_in, uint64_t tgid_in)
Definition: futex_map.cc:31
FutexMap::requeue
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.cc:150
WaiterState
WaiterState defines internal state of a waiter thread.
Definition: futex_map.hh:68
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
FutexMap::wakeup_bitset
int wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
Definition: futex_map.cc:117
addr
ip6_addr_t addr
Definition: inet.hh:423
std::list
STL list class.
Definition: stl.hh:51
WaiterState::tc
ThreadContext * tc
Definition: futex_map.hh:70

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17