| David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 | 3 |  * or more contributor license agreements. See the NOTICE file | 
 | 4 |  * distributed with this work for additional information | 
 | 5 |  * regarding copyright ownership. The ASF licenses this file | 
 | 6 |  * to you under the Apache License, Version 2.0 (the | 
 | 7 |  * "License"); you may not use this file except in compliance | 
 | 8 |  * with the License. You may obtain a copy of the License at | 
 | 9 |  * | 
 | 10 |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
 | 11 |  * | 
 | 12 |  * Unless required by applicable law or agreed to in writing, | 
 | 13 |  * software distributed under the License is distributed on an | 
 | 14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | 15 |  * KIND, either express or implied. See the License for the | 
 | 16 |  * specific language governing permissions and limitations | 
 | 17 |  * under the License. | 
 | 18 |  */ | 
| Mark Slee | 9f0c651 | 2007-02-28 23:58:26 +0000 | [diff] [blame] | 19 |  | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 20 | #include <config.h> | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 21 | #include <concurrency/ThreadManager.h> | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 22 | #include <concurrency/PlatformThreadFactory.h> | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 23 | #include <concurrency/Monitor.h> | 
 | 24 | #include <concurrency/Util.h> | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 25 |  | 
 | 26 | #include <assert.h> | 
 | 27 | #include <set> | 
 | 28 | #include <iostream> | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 29 | #include <set> | 
 | 30 | #include <stdint.h> | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 31 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 32 | namespace apache { namespace thrift { namespace concurrency { namespace test { | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 33 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 34 | using namespace apache::thrift::concurrency; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 35 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 36 | /** | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 37 |  * ThreadManagerTests class | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 38 |  * | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 39 |  * @version $Id:$ | 
 | 40 |  */ | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 41 | class ThreadManagerTests { | 
 | 42 |  | 
 | 43 | public: | 
 | 44 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 45 |   static const double ERROR; | 
 | 46 |  | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 47 |   class Task: public Runnable { | 
 | 48 |  | 
 | 49 |   public: | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 50 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 51 |     Task(Monitor& monitor, size_t& count, int64_t timeout) : | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 52 |       _monitor(monitor), | 
 | 53 |       _count(count), | 
 | 54 |       _timeout(timeout), | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 55 |       _done(false) {} | 
 | 56 |  | 
 | 57 |     void run() { | 
 | 58 |  | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 59 |       _startTime = Util::currentTime(); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 60 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 61 |       { | 
 | 62 |         Synchronized s(_sleep); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 63 |  | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 64 |         try { | 
 | 65 |           _sleep.wait(_timeout); | 
 | 66 |         } catch(TimedOutException& e) { | 
 | 67 |           ; | 
 | 68 |         }catch(...) { | 
 | 69 |           assert(0); | 
 | 70 |         } | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 71 |       } | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 72 |  | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 73 |       _endTime = Util::currentTime(); | 
 | 74 |  | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 75 |       _done = true; | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 76 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 77 |       { | 
 | 78 |         Synchronized s(_monitor); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 79 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 80 |         // std::cout << "Thread " << _count << " completed " << std::endl; | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 81 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 82 |         _count--; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 83 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 84 |         if (_count == 0) { | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 85 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 86 |           _monitor.notify(); | 
 | 87 |         } | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 88 |       } | 
 | 89 |     } | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 90 |  | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 91 |     Monitor& _monitor; | 
 | 92 |     size_t& _count; | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 93 |     int64_t _timeout; | 
 | 94 |     int64_t _startTime; | 
 | 95 |     int64_t _endTime; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 96 |     bool _done; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 97 |     Monitor _sleep; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 98 |   }; | 
 | 99 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 100 |   /** | 
 | 101 |    * Dispatch count tasks, each of which blocks for timeout milliseconds then | 
 | 102 |    * completes. Verify that all tasks completed and that thread manager cleans | 
 | 103 |    * up properly on delete. | 
 | 104 |    */ | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 105 |   bool loadTest(size_t count=100, int64_t timeout=100LL, size_t workerCount=4) { | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 106 |  | 
 | 107 |     Monitor monitor; | 
 | 108 |  | 
 | 109 |     size_t activeCount = count; | 
 | 110 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 111 |     shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount); | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 112 |  | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 113 |     shared_ptr<PlatformThreadFactory> threadFactory = shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()); | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 114 |  | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 115 | #ifndef USE_BOOST_THREAD | 
| Marc Slemko | a647903 | 2007-06-05 22:20:14 +0000 | [diff] [blame] | 116 |     threadFactory->setPriority(PosixThreadFactory::HIGHEST); | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 117 | #endif | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 118 |     threadManager->threadFactory(threadFactory); | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 119 |  | 
 | 120 |     threadManager->start(); | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 121 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 122 |     std::set<shared_ptr<ThreadManagerTests::Task> > tasks; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 123 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 124 |     for (size_t ix = 0; ix < count; ix++) { | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 125 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 126 |       tasks.insert(shared_ptr<ThreadManagerTests::Task>(new ThreadManagerTests::Task(monitor, activeCount, timeout))); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 127 |     } | 
 | 128 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 129 |     int64_t time00 = Util::currentTime(); | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 130 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 131 |     for (std::set<shared_ptr<ThreadManagerTests::Task> >::iterator ix = tasks.begin(); ix != tasks.end(); ix++) { | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 132 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 133 |         threadManager->add(*ix); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 134 |     } | 
 | 135 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 136 |     { | 
 | 137 |       Synchronized s(monitor); | 
 | 138 |  | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 139 |       while(activeCount > 0) { | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 140 |  | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 141 |         monitor.wait(); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 142 |       } | 
 | 143 |     } | 
 | 144 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 145 |     int64_t time01 = Util::currentTime(); | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 146 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 147 |     int64_t firstTime = 9223372036854775807LL; | 
 | 148 |     int64_t lastTime = 0; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 149 |  | 
 | 150 |     double averageTime = 0; | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 151 |     int64_t minTime = 9223372036854775807LL; | 
 | 152 |     int64_t maxTime = 0; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 153 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 154 |     for (std::set<shared_ptr<ThreadManagerTests::Task> >::iterator ix = tasks.begin(); ix != tasks.end(); ix++) { | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 155 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 156 |       shared_ptr<ThreadManagerTests::Task> task = *ix; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 157 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 158 |       int64_t delta = task->_endTime - task->_startTime; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 159 |  | 
 | 160 |       assert(delta > 0); | 
 | 161 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 162 |       if (task->_startTime < firstTime) { | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 163 |         firstTime = task->_startTime; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 164 |       } | 
 | 165 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 166 |       if (task->_endTime > lastTime) { | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 167 |         lastTime = task->_endTime; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 168 |       } | 
 | 169 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 170 |       if (delta < minTime) { | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 171 |         minTime = delta; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 172 |       } | 
 | 173 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 174 |       if (delta > maxTime) { | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 175 |         maxTime = delta; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 176 |       } | 
 | 177 |  | 
 | 178 |       averageTime+= delta; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 179 |     } | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 180 |  | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 181 |     averageTime /= count; | 
 | 182 |  | 
 | 183 |     std::cout << "\t\t\tfirst start: " << firstTime << "ms Last end: " << lastTime << "ms min: " << minTime << "ms max: " << maxTime << "ms average: " << averageTime << "ms" << std::endl; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 184 |  | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 185 |     double expectedTime = ((count + (workerCount - 1)) / workerCount) * timeout; | 
 | 186 |  | 
 | 187 |     double error = ((time01 - time00) - expectedTime) / expectedTime; | 
 | 188 |  | 
| Mark Slee | f5f2be4 | 2006-09-05 21:05:31 +0000 | [diff] [blame] | 189 |     if (error < 0) { | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 190 |       error*= -1.0; | 
 | 191 |     } | 
 | 192 |  | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 193 |     bool success = error < ERROR; | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 194 |  | 
| Marc Slemko | fe5ba12e | 2006-07-20 21:16:27 +0000 | [diff] [blame] | 195 |     std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "! expected time: " << expectedTime << "ms elapsed time: "<< time01 - time00 << "ms error%: " << error * 100.0 << std::endl; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 196 |  | 
| Marc Slemko | c778297 | 2006-07-25 02:26:35 +0000 | [diff] [blame] | 197 |     return success; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 198 |   } | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 199 |  | 
 | 200 |   class BlockTask: public Runnable { | 
 | 201 |  | 
 | 202 |   public: | 
 | 203 |  | 
 | 204 |     BlockTask(Monitor& monitor, Monitor& bmonitor, size_t& count) : | 
 | 205 |       _monitor(monitor), | 
 | 206 |       _bmonitor(bmonitor), | 
 | 207 |       _count(count) {} | 
 | 208 |  | 
 | 209 |     void run() { | 
 | 210 |       { | 
 | 211 |         Synchronized s(_bmonitor); | 
 | 212 |  | 
 | 213 |         _bmonitor.wait(); | 
 | 214 |  | 
 | 215 |       } | 
 | 216 |  | 
 | 217 |       { | 
 | 218 |         Synchronized s(_monitor); | 
 | 219 |  | 
 | 220 |         _count--; | 
 | 221 |  | 
 | 222 |         if (_count == 0) { | 
 | 223 |  | 
 | 224 |           _monitor.notify(); | 
 | 225 |         } | 
 | 226 |       } | 
 | 227 |     } | 
 | 228 |  | 
 | 229 |     Monitor& _monitor; | 
 | 230 |     Monitor& _bmonitor; | 
 | 231 |     size_t& _count; | 
 | 232 |   }; | 
 | 233 |  | 
 | 234 |   /** | 
 | 235 |    * Block test.  Create pendingTaskCountMax tasks.  Verify that we block adding the | 
 | 236 |    * pendingTaskCountMax + 1th task.  Verify that we unblock when a task completes */ | 
 | 237 |  | 
| Mark Slee | 9b82d27 | 2007-05-23 05:16:07 +0000 | [diff] [blame] | 238 |   bool blockTest(int64_t timeout=100LL, size_t workerCount=2) { | 
| Roger Meier | 3b771a1 | 2010-11-17 22:11:26 +0000 | [diff] [blame] | 239 |     (void) timeout; | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 240 |     bool success = false; | 
 | 241 |  | 
 | 242 |     try { | 
 | 243 |  | 
 | 244 |       Monitor bmonitor; | 
 | 245 |       Monitor monitor; | 
 | 246 |  | 
 | 247 |       size_t pendingTaskMaxCount = workerCount; | 
 | 248 |  | 
 | 249 |       size_t activeCounts[] = {workerCount, pendingTaskMaxCount, 1}; | 
 | 250 |  | 
 | 251 |       shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount, pendingTaskMaxCount); | 
 | 252 |  | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 253 |       shared_ptr<PlatformThreadFactory> threadFactory = shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()); | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 254 |  | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 255 | #ifndef USE_BOOST_THREAD | 
| Marc Slemko | a647903 | 2007-06-05 22:20:14 +0000 | [diff] [blame] | 256 |       threadFactory->setPriority(PosixThreadFactory::HIGHEST); | 
| Roger Meier | 3faaedf | 2011-10-02 10:51:45 +0000 | [diff] [blame] | 257 | #endif | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 258 |       threadManager->threadFactory(threadFactory); | 
 | 259 |  | 
 | 260 |       threadManager->start(); | 
 | 261 |  | 
 | 262 |       std::set<shared_ptr<ThreadManagerTests::BlockTask> > tasks; | 
 | 263 |  | 
 | 264 |       for (size_t ix = 0; ix < workerCount; ix++) { | 
 | 265 |  | 
 | 266 |         tasks.insert(shared_ptr<ThreadManagerTests::BlockTask>(new ThreadManagerTests::BlockTask(monitor, bmonitor,activeCounts[0]))); | 
 | 267 |       } | 
 | 268 |  | 
 | 269 |       for (size_t ix = 0; ix < pendingTaskMaxCount; ix++) { | 
 | 270 |  | 
 | 271 |         tasks.insert(shared_ptr<ThreadManagerTests::BlockTask>(new ThreadManagerTests::BlockTask(monitor, bmonitor,activeCounts[1]))); | 
 | 272 |       } | 
 | 273 |  | 
 | 274 |       for (std::set<shared_ptr<ThreadManagerTests::BlockTask> >::iterator ix = tasks.begin(); ix != tasks.end(); ix++) { | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 275 |         threadManager->add(*ix); | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 276 |       } | 
 | 277 |  | 
 | 278 |       if(!(success = (threadManager->totalTaskCount() == pendingTaskMaxCount + workerCount))) { | 
 | 279 |         throw TException("Unexpected pending task count"); | 
 | 280 |       } | 
 | 281 |  | 
 | 282 |       shared_ptr<ThreadManagerTests::BlockTask> extraTask(new ThreadManagerTests::BlockTask(monitor, bmonitor, activeCounts[2])); | 
 | 283 |  | 
 | 284 |       try { | 
 | 285 |         threadManager->add(extraTask, 1); | 
 | 286 |         throw TException("Unexpected success adding task in excess of pending task count"); | 
| David Reiss | 9fcacc8 | 2009-06-04 00:32:54 +0000 | [diff] [blame] | 287 |       } catch(TooManyPendingTasksException& e) { | 
 | 288 |         throw TException("Should have timed out adding task in excess of pending task count"); | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 289 |       } catch(TimedOutException& e) { | 
| David Reiss | 9fcacc8 | 2009-06-04 00:32:54 +0000 | [diff] [blame] | 290 |         // Expected result | 
 | 291 |       } | 
 | 292 |  | 
 | 293 |       try { | 
 | 294 |         threadManager->add(extraTask, -1); | 
 | 295 |         throw TException("Unexpected success adding task in excess of pending task count"); | 
 | 296 |       } catch(TimedOutException& e) { | 
 | 297 |         throw TException("Unexpected timeout adding task in excess of pending task count"); | 
 | 298 |       } catch(TooManyPendingTasksException& e) { | 
 | 299 |         // Expected result | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 300 |       } | 
 | 301 |  | 
 | 302 |       std::cout << "\t\t\t" << "Pending tasks " << threadManager->pendingTaskCount()  << std::endl; | 
 | 303 |  | 
 | 304 |       { | 
 | 305 |         Synchronized s(bmonitor); | 
 | 306 |  | 
 | 307 |         bmonitor.notifyAll(); | 
 | 308 |       } | 
 | 309 |  | 
 | 310 |       { | 
 | 311 |         Synchronized s(monitor); | 
 | 312 |  | 
 | 313 |         while(activeCounts[0] != 0) { | 
 | 314 |           monitor.wait(); | 
 | 315 |         } | 
 | 316 |       } | 
 | 317 |  | 
 | 318 |       std::cout << "\t\t\t" << "Pending tasks " << threadManager->pendingTaskCount() << std::endl; | 
 | 319 |  | 
 | 320 |       try { | 
 | 321 |         threadManager->add(extraTask, 1); | 
 | 322 |       } catch(TimedOutException& e) { | 
 | 323 |         std::cout << "\t\t\t" << "add timed out unexpectedly"  << std::endl; | 
 | 324 |         throw TException("Unexpected timeout adding task"); | 
 | 325 |  | 
 | 326 |       } catch(TooManyPendingTasksException& e) { | 
 | 327 |         std::cout << "\t\t\t" << "add encountered too many pending exepctions" << std::endl; | 
 | 328 |         throw TException("Unexpected timeout adding task"); | 
 | 329 |       } | 
 | 330 |  | 
 | 331 |       // Wake up tasks that were pending before and wait for them to complete | 
 | 332 |  | 
 | 333 |       { | 
 | 334 |         Synchronized s(bmonitor); | 
 | 335 |  | 
 | 336 |         bmonitor.notifyAll(); | 
 | 337 |       } | 
 | 338 |  | 
 | 339 |       { | 
 | 340 |         Synchronized s(monitor); | 
 | 341 |  | 
 | 342 |         while(activeCounts[1] != 0) { | 
 | 343 |           monitor.wait(); | 
 | 344 |         } | 
 | 345 |       } | 
 | 346 |  | 
 | 347 |       // Wake up the extra task and wait for it to complete | 
 | 348 |  | 
 | 349 |       { | 
 | 350 |         Synchronized s(bmonitor); | 
 | 351 |  | 
 | 352 |         bmonitor.notifyAll(); | 
 | 353 |       } | 
 | 354 |  | 
 | 355 |       { | 
 | 356 |         Synchronized s(monitor); | 
 | 357 |  | 
 | 358 |         while(activeCounts[2] != 0) { | 
 | 359 |           monitor.wait(); | 
 | 360 |         } | 
 | 361 |       } | 
 | 362 |  | 
 | 363 |       if(!(success = (threadManager->totalTaskCount() == 0))) { | 
 | 364 |         throw TException("Unexpected pending task count"); | 
 | 365 |       } | 
 | 366 |  | 
 | 367 |     } catch(TException& e) { | 
| David Reiss | 9fcacc8 | 2009-06-04 00:32:54 +0000 | [diff] [blame] | 368 |       std::cout << "ERROR: " << e.what() << std::endl; | 
| Marc Slemko | 3a3b53b | 2007-05-22 23:59:54 +0000 | [diff] [blame] | 369 |     } | 
 | 370 |  | 
 | 371 |     std::cout << "\t\t\t" << (success ? "Success" : "Failure") << std::endl; | 
 | 372 |     return success; | 
 | 373 |  } | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 374 | }; | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 375 |  | 
 | 376 | const double ThreadManagerTests::ERROR = .20; | 
 | 377 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 378 | }}}} // apache::thrift::concurrency | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 379 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 380 | using namespace apache::thrift::concurrency::test; | 
| Marc Slemko | 740343d | 2006-07-20 00:31:02 +0000 | [diff] [blame] | 381 |  |