56e97255ed4dee2f31b7100264a4113ea3218463
David Blume Added a routine to cause a...

David Blume authored 8 years ago

1) #include <iostream>
2) #include <string>
3) #include <vector>
4) #include <thread>
5) #include <mutex>
6) #include <unistd.h>
7) #include <random>
8) #include <chrono>
9) #include "deadlock.hpp"
10) 
11) using namespace std;
12) 
13) namespace {
14) 
15) std::mutex left_chopstick;
16) std::mutex right_chopstick;
17) 
18) std::vector<std::thread> workers;
19) 
20) void do_work_on_right(bool, int32_t);
21) 
22) int get_rnd()
23) {
24)     static std::random_device rd;
25)     static std::mt19937 gen(rd());
26)     static std::uniform_int_distribution<> dis(100, 200);
27)     return dis(gen);
28) }
29) 
30) void do_work_on_left(bool have_right, int32_t tick)
31) {
dblume Add .clang-format

dblume authored 1 year ago

32)     std::lock_guard<std::mutex> lm(left_chopstick);
David Blume Added a routine to cause a...

David Blume authored 8 years ago

33)     std::this_thread::sleep_for(std::chrono::milliseconds(get_rnd()));
34)     if (have_right) {
dblume Add .clang-format

dblume authored 1 year ago

35)         std::cout << "deadlock::thread " << std::hex << this_thread::get_id() << " "
36)                   << tick << endl;
David Blume Added a routine to cause a...

David Blume authored 8 years ago

37)     } else {
38)         do_work_on_right(true, tick);
39)     }
40) }
41) 
42) void do_work_on_right(bool have_left, int32_t tick)
43) {
dblume Add .clang-format

dblume authored 1 year ago

44)     std::lock_guard<std::mutex> rm(right_chopstick);
David Blume Added a routine to cause a...

David Blume authored 8 years ago

45)     std::this_thread::sleep_for(std::chrono::milliseconds(get_rnd()));
46)     if (have_left) {
dblume Add .clang-format

dblume authored 1 year ago

47)         std::cout << "deadlock::thread " << std::hex << this_thread::get_id() << " "
48)                   << tick << endl;
David Blume Added a routine to cause a...

David Blume authored 8 years ago

49)     } else {
50)         do_work_on_left(true, tick);
51)     }
52) }
53) 
54) void work(int32_t ticks)
55) {
dblume Add .clang-format

dblume authored 1 year ago

56)     for (int32_t tick = ticks; tick >= 0; tick--) {
David Blume Added a routine to cause a...

David Blume authored 8 years ago

57)         do_work_on_right(false, tick);
58)     }
59) }
60) 
dblume Add .clang-format

dblume authored 1 year ago

61) }; // namespace
David Blume Added a routine to cause a...

David Blume authored 8 years ago

62) 
63) int deadlock()
64) {
65)     uint32_t ticks = 10;
66)     cout << "The function " << __PRETTY_FUNCTION__ << " was called." << endl;
67)     cerr << "WARNING: Expect a deadlock. See http://wiki.dlma.com/gdb" << endl;
68) 
69)     // Construct the thread right into the push_back() call.
dblume Add .clang-format

dblume authored 1 year ago

70)     workers.push_back(std::thread([=] {
71)         for (uint32_t tick = 0; tick <= ticks; tick++) {
David Blume Added a routine to cause a...

David Blume authored 8 years ago

72)             do_work_on_left(false, tick);
73)             // usleep(get_rnd() * 1000);  // u for microseconds
74)         }
75)     }));
76) 
77)     // Or, move the thread into the array.
78)     std::thread t2(work, ticks);
79)     workers.push_back(move(t2));
80) 
81)     // Don't return before the other threads have finished.
dblume Add .clang-format

dblume authored 1 year ago

82)     for (auto& w : workers) {