blob: 61325717d56ee4221a5e0558d938a7b81cab714c [file] [log] [blame]
Marc Slemko740343d2006-07-20 00:31:02 +00001#include <ThreadManager.h>
2#include <PosixThreadFactory.h>
3#include <Monitor.h>
4#include <Util.h>
5
6#include <assert.h>
7#include <set>
8#include <iostream>
9
10namespace facebook { namespace thrift { namespace concurrency { namespace test {
11
12using namespace facebook::thrift::concurrency;
13
14/** ThreadManagerTests class
15
16 @author marc
17 @version $Id:$ */
18
19class ThreadManagerTests {
20
21public:
22
23 class Task: public Runnable {
24
25 public:
26
27 Task(Monitor& monitor, size_t& count, long long timeout) :
28 _monitor(monitor),
29 _count(count),
30 _timeout(timeout),
Marc Slemko740343d2006-07-20 00:31:02 +000031 _done(false) {}
32
33 void run() {
34
Marc Slemko740343d2006-07-20 00:31:02 +000035 Monitor sleep;
36
37 {Synchronized s(sleep);
38
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000039 long long time00 = Util::currentTime();
Marc Slemko740343d2006-07-20 00:31:02 +000040
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000041 sleep.wait(_timeout);
42
43 long long time01 = Util::currentTime();
44
45 double error = ((time01 - time00) - _timeout) / (double)_timeout;
46
47 if(error < 0.0) {
48
49 error*= -1.0;
50 }
51
Marc Slemko9d4a3e22006-07-21 19:53:48 +000052 if(error > .20) {
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000053
54 assert(false);
55 }
56 }
Marc Slemko740343d2006-07-20 00:31:02 +000057
58 _done = true;
59
Marc Slemko740343d2006-07-20 00:31:02 +000060 {Synchronized s(_monitor);
61
62 // std::cout << "Thread " << _count << " completed " << std::endl;
63
64 _count--;
65
66 if(_count == 0) {
67
68 _monitor.notify();
69 }
70 }
71 }
72
73 Monitor& _monitor;
74 size_t& _count;
75 long long _timeout;
Marc Slemko740343d2006-07-20 00:31:02 +000076 bool _done;
77 };
78
79 /** Dispatch count tasks, each of which blocks for timeout milliseconds then completes.
80 Verify that all tasks completed and that thread manager cleans up properly on delete. */
81
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000082 bool loadTest(size_t count=100, long long timeout=100LL, size_t workerCount=4) {
Marc Slemko740343d2006-07-20 00:31:02 +000083
84 Monitor monitor;
85
86 size_t activeCount = count;
87
88 ThreadManager* threadManager = ThreadManager::newSimpleThreadManager(workerCount);
89
90 threadManager->threadFactory(new PosixThreadFactory());
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000091
92 threadManager->start();
Marc Slemko740343d2006-07-20 00:31:02 +000093
94 std::set<ThreadManagerTests::Task*> tasks;
95
96 for(size_t ix = 0; ix < count; ix++) {
97
98 tasks.insert(new ThreadManagerTests::Task(monitor, activeCount, timeout));
99 }
100
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000101 long long time00 = Util::currentTime();
102
Marc Slemko740343d2006-07-20 00:31:02 +0000103 for(std::set<ThreadManagerTests::Task*>::iterator ix = tasks.begin(); ix != tasks.end(); ix++) {
104
105 threadManager->add(*ix);
106 }
107
108 {Synchronized s(monitor);
109
110 while(activeCount > 0) {
111
112 monitor.wait();
113 }
114 }
115
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000116 long long time01 = Util::currentTime();
Marc Slemko740343d2006-07-20 00:31:02 +0000117
118 for(std::set<ThreadManagerTests::Task*>::iterator ix = tasks.begin(); ix != tasks.end(); ix++) {
119
Marc Slemko740343d2006-07-20 00:31:02 +0000120 delete *ix;
121
122 }
123
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000124 double expectedTime = ((count + (workerCount - 1)) / workerCount) * timeout;
125
126 double error = ((time01 - time00) - expectedTime) / expectedTime;
127
128 if(error < 0) {
129 error*= -1.0;
130 }
131
132 bool success = error < .10;
133
Marc Slemko740343d2006-07-20 00:31:02 +0000134 delete threadManager;
135
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000136 std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "! expected time: " << expectedTime << "ms elapsed time: "<< time01 - time00 << "ms error%: " << error * 100.0 << std::endl;
Marc Slemko740343d2006-07-20 00:31:02 +0000137
138 return true;
139 }
140};
141
142}}}} // facebook::thrift::concurrency
143
144using namespace facebook::thrift::concurrency::test;
145