23#include <spot/bricks/brick-hashset>
27#include <spot/misc/common.hh>
28#include <spot/kripke/kripke.hh>
29#include <spot/misc/fixpool.hh>
30#include <spot/misc/timer.hh>
31#include <spot/twacube/twacube.hh>
32#include <spot/twacube/fwd.hh>
33#include <spot/mc/mc.hh>
43 template<
typename State,
typename SuccIterator,
44 typename StateHash,
typename StateEqual,
66 pair_hasher(
const deadlock_pair*)
69 pair_hasher() =
default;
71 brick::hash::hash128_t
72 hash(
const deadlock_pair* lhs)
const
76 unsigned u = hash(lhs->st) % (1<<30);
80 bool equal(
const deadlock_pair* lhs,
81 const deadlock_pair* rhs)
const
84 return equal(lhs->st, rhs->st);
88 static constexpr bool compute_deadlock =
89 std::is_same<std::true_type, Deadlock>::value;
94 using shared_map = brick::hashset::FastConcurrent <deadlock_pair*,
110 std::atomic<bool>& stop):
111 sys_(sys), tid_(tid), map_(map),
112 nb_th_(std::thread::hardware_concurrency()),
113 p_(sizeof(int)*std::thread::hardware_concurrency()),
114 p_pair_(sizeof(deadlock_pair)),
118 State, SuccIterator>::value,
119 "error: does not match the kripkecube requirements");
120 SPOT_ASSERT(nb_th_ > tid);
125 while (!todo_.empty())
127 sys_.recycle(todo_.back().it, tid_);
136 State initial = sys_.initial(tid_);
137 if (SPOT_LIKELY(push(initial)))
139 todo_.push_back({initial, sys_.succ(initial, tid_), transitions_});
141 while (!todo_.empty() && !stop_.load(std::memory_order_relaxed))
143 if (todo_.back().it->done())
145 if (SPOT_LIKELY(pop()))
147 deadlock_ = todo_.back().current_tr == transitions_;
148 if (compute_deadlock && deadlock_)
150 sys_.recycle(todo_.back().it, tid_);
157 State dst = todo_.back().it->state();
159 if (SPOT_LIKELY(push(dst)))
161 todo_.back().it->next();
162 todo_.push_back({dst, sys_.succ(dst, tid_), transitions_});
166 todo_.back().it->next();
176 tm_.start(
"DFS thread " + std::to_string(tid_));
183 int* ref = (
int*) p_.allocate();
184 for (
unsigned i = 0; i < nb_th_; ++i)
188 deadlock_pair* v = (deadlock_pair*) p_pair_.allocate();
191 auto it = map_.insert(v);
200 for (
unsigned i = 0; !b && i < nb_th_; ++i)
201 if ((*it)->colors[i] ==
static_cast<int>(CLOSED))
205 if ((*it)->colors[tid_] ==
static_cast<int>(OPEN))
209 refs_.push_back((*it)->colors);
212 (*it)->colors[tid_] = OPEN;
221 dfs_ = todo_.size() > dfs_ ? todo_.size() : dfs_;
225 refs_.back()[tid_] = CLOSED;
233 bool tst_val =
false;
235 bool exchanged = stop_.compare_exchange_strong(tst_val, new_val);
238 tm_.stop(
"DFS thread " + std::to_string(tid_));
262 return tm_.timer(
"DFS thread " + std::to_string(tid_)).walltime();
268 if (compute_deadlock)
270 return "reachability";
282 if (compute_deadlock)
283 return deadlock_ ? mc_rvalue::DEADLOCK : mc_rvalue::NO_DEADLOCK;
284 return mc_rvalue::SUCCESS;
292 result += sys_.to_string(e.s, tid_);
303 kripkecube<State, SuccIterator>& sys_;
304 std::vector<todo_element> todo_;
305 unsigned transitions_ = 0;
309 unsigned states_ = 0;
313 fixed_size_pool<pool_type::Unsafe> p_;
314 fixed_size_pool<pool_type::Unsafe> p_pair_;
315 bool deadlock_ =
false;
316 std::atomic<bool>& stop_;
319 std::vector<int*> refs_;
320 bool finisher_ =
false;
This class allows to ensure (at compile time) if a given parameter is of type kripkecube....
Definition kripke.hh:71
This class is a template representation of a Kripke structure. It is composed of two template paramet...
Definition kripke.hh:40
This class aims to explore a model to detect whether it contains a deadlock. This deadlock detection ...
Definition deadlock.hh:47
unsigned transitions()
Return number of transitions traversed.
Definition deadlock.hh:254
mc_rvalue result()
Return deadlock detection result.
Definition deadlock.hh:280
bool pop()
Pop state from stack.
Definition deadlock.hh:218
static shared_struct * make_shared_structure(shared_map, unsigned)
Create shared structure for thread tid.
Definition deadlock.hh:100
void finalize()
Finalize thread resources.
Definition deadlock.hh:231
std::string trace()
Return trace.
Definition deadlock.hh:288
swarmed_deadlock(kripkecube< State, SuccIterator > &sys, twacube_ptr, shared_map &map, shared_struct *, unsigned tid, std::atomic< bool > &stop)
Constructor for parallel deadlock detection.
Definition deadlock.hh:106
std::string name()
Return algorithm name.
Definition deadlock.hh:266
int sccs()
Return number of SCCs found (returns -1)
Definition deadlock.hh:274
shared_map shared_struct
Type alias for shared structure.
Definition deadlock.hh:97
bool push(State s)
Push state onto stack.
Definition deadlock.hh:180
void run()
Run the algorithm.
Definition deadlock.hh:133
void setup()
Setup thread resources.
Definition deadlock.hh:174
unsigned states()
Return number of states visited.
Definition deadlock.hh:248
bool finisher()
Check if this thread finished the search.
Definition deadlock.hh:242
unsigned walltime()
Return wall time in milliseconds.
Definition deadlock.hh:260
brick::hashset::FastConcurrent< deadlock_pair *, pair_hasher > shared_map
Concurrent hashset for shared state storage.
Definition deadlock.hh:95
A map of timer, where each timer has a name.
Definition timer.hh:231
std::shared_ptr< twacube > twacube_ptr
Definition fwd.hh:28
Definition automata.hh:26
mc_rvalue
Return value of a parallel model-checking algorithm.
Definition mc.hh:50