Produce an octal escape code for \177
[libs/core.git] / tests / thread.cpp
1 #include <list>
2 #include <vector>
3 #include <msp/core/thread.h>
4 #include <msp/time/timedelta.h>
5 #include <msp/time/utils.h>
6 #include <msp/test/test.h>
7
8 using namespace std;
9 using namespace Msp;
10
11 class ThreadTests: public Test::RegisteredTest<ThreadTests>
12 {
13 private:
14         std::vector<int> data;
15
16 public:
17         ThreadTests();
18
19         static const char *get_name() { return "Thread"; }
20
21 private:
22         void single();
23         void multiple();
24 };
25
26
27 class TestThread: public Thread
28 {
29 private:
30         int *start;
31         unsigned count;
32         unsigned step;
33         int value;
34         bool done;
35
36 public:
37         TestThread(int *, unsigned, unsigned, int);
38
39 private:
40         virtual void main();
41
42 public:
43         bool is_done() const { return done; }
44 };
45
46
47 ThreadTests::ThreadTests():
48         data(1000000)
49 {
50         add(&ThreadTests::single, "Single thread");
51         add(&ThreadTests::multiple, "Multiple threads");
52 }
53
54 void ThreadTests::single()
55 {
56         fill(data.begin(), data.end(), -1);
57
58         TestThread thread(&data[0], data.size(), 1, 1);
59         unsigned wait = 100;
60         while(wait && !thread.is_done())
61         {
62                 Time::sleep(100*Time::msec);
63                 --wait;
64         }
65
66         if(!wait)
67                 fail("Thread did not finish");
68
69         thread.join();
70
71         for(vector<int>::iterator i=data.begin(); i!=data.end(); ++i)
72                 if(*i!=1)
73                         fail("Invalid data");
74 }
75
76 void ThreadTests::multiple()
77 {
78         fill(data.begin(), data.end(), -1);
79
80         list<TestThread *> threads;
81         for(unsigned i=0; i<10; ++i)
82                 threads.push_back(new TestThread(&data[i], data.size()/10, 10, i+1));
83         unsigned wait = 100;
84         while(wait && !threads.empty())
85         {
86                 Time::sleep(100*Time::msec);
87                 for(list<TestThread *>::iterator i=threads.begin(); i!=threads.end();)
88                 {
89                         if((*i)->is_done())
90                         {
91                                 (*i)->join();
92                                 delete *i;
93                                 threads.erase(i++);
94                         }
95                         else
96                                 ++i;
97                 }
98                 --wait;
99         }
100
101         if(!wait)
102                 fail("Threads did not finish");
103
104         for(unsigned i=0; i<data.size(); ++i)
105                 if(data[i]!=static_cast<int>(i%10+1))
106                         fail("Invalid data");
107 }
108
109
110 TestThread::TestThread(int *s, unsigned c, unsigned t, int v):
111         start(s),
112         count(c),
113         step(t),
114         value(v),
115         done(false)
116 {
117         launch();
118 }
119
120 void TestThread::main()
121 {
122         int *ptr = start;
123         for(unsigned i=0; i<count; ++i)
124         {
125                 *ptr = value;
126                 ptr += step;
127         }
128         done = true;
129 }