Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / examples / Threads / task_four.cpp
blob200aa17f52cb40fa298041880ec5b238f6ec5f0e
1 // The following test was written by Hamutal Yanay & Ari Erev's
2 // (Ari_Erev@comverse.com).
3 //
4 // This test program test enhancements to the thread_manager and task
5 // classes. The purpose of these enhancements was to allow the
6 // thread_manager to recognize the concept of an ACE_Task and to be
7 // able to group ACE_Tasks in groups.
8 //
9 // There are two main ACE_Tasks in this sample:
11 // Invoker_Task - is run from main (). It's purpose is to run a number of
12 // ACE_Tasks of type Worker_Task. The number can be specified
13 // on the command line.
14 // After starting the tasks, the Invoker_Task groups all the tasks
15 // in one group and then uses the
16 // num_tasks_in_group () to find out if the real number of tasks
17 // that are now running (should be the same as the number of tasks
18 // started).
19 // It also, suspends and resumes all the threads in the group to
20 // test the suspend_grp () and resume_grp () methods.
21 // Then it waits for all the tasks to end.
23 // Worker_Task - ACE_Tasks that are started by the Invoker_Task.
24 // Each Worker_Task can start a number of threads.
25 // The Worker_Task threads perform some work (iteration). The number
26 // of the iterations can be specified on the command line.
28 // The command line syntax is:
30 // test_task [num_tasks] [num_threads] [num_iterations]
32 #include "ace/OS_NS_unistd.h"
33 #include "ace/OS_main.h"
34 #include "ace/Task.h"
35 #include "ace/Service_Config.h"
37 #if defined (ACE_HAS_THREADS)
39 #include "ace/Task.h"
41 class Invoker_Task : public ACE_Task<ACE_MT_SYNCH>
43 public:
44 Invoker_Task (ACE_Thread_Manager *thr_mgr,
45 size_t n_tasks,
46 size_t n_threads,
47 size_t n_iterations);
48 virtual int svc ();
49 // creats <n_tasks> and wait for them to finish
51 private:
52 size_t n_tasks_;
53 // Number of tasks to start.
54 size_t n_threads_;
55 // Number of threads per task.
56 size_t n_iterations_;
57 // Number of iterations per thread.
60 class Worker_Task : public ACE_Task<ACE_MT_SYNCH>
62 public:
63 Worker_Task (ACE_Thread_Manager *thr_mgr,
64 size_t n_threads,
65 size_t n_iterations);
66 virtual int svc ();
68 //FUZZ: disable check_for_lack_ACE_OS
69 // Does a small work...
70 virtual int open (void * = NULL);
71 //FUZZ: enable check_for_lack_ACE_OS
73 private:
74 static size_t workers_count_;
75 size_t index_;
76 size_t n_threads_;
77 size_t n_iterations_;
79 //FUZZ: disable check_for_lack_ACE_OS
80 // = Not needed for this test.
81 virtual int close (u_long);
82 //FUZZ: enable check_for_lack_ACE_OS
84 virtual int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; }
87 size_t Worker_Task::workers_count_ = 1;
89 int
90 Worker_Task::close (u_long)
92 ACE_DEBUG ((LM_DEBUG,
93 "(%t) closing task %d\n",
94 this->index_));
95 delete this;
96 return 0;
99 Worker_Task::Worker_Task (ACE_Thread_Manager *thr_mgr,
100 size_t n_threads,
101 size_t n_iterations)
102 : ACE_Task<ACE_MT_SYNCH> (thr_mgr),
103 index_ (Worker_Task::workers_count_++),
104 n_threads_ (n_threads),
105 n_iterations_ (n_iterations)
110 Worker_Task::open (void *)
112 // Create the pool of worker threads.
113 return this->activate (THR_NEW_LWP,
114 ACE_Utils::truncate_cast<int> (this->n_threads_),
118 this);
122 Worker_Task::svc ()
124 ACE_DEBUG ((LM_DEBUG,
125 " (%t) in worker %d\n",
126 index_));
128 for (size_t iterations = 1;
129 iterations <= this->n_iterations_;
130 iterations++)
132 ACE_DEBUG ((LM_DEBUG,
133 " (%t) in iteration %d\n",
134 iterations));
135 ACE_OS::sleep (0);
138 ACE_DEBUG ((LM_DEBUG,
139 " (%t) worker %d ends\n",
140 index_));
142 return 0;
145 Invoker_Task::Invoker_Task (ACE_Thread_Manager *thr_mgr,
146 size_t n_tasks,
147 size_t n_threads,
148 size_t n_iterations)
149 : ACE_Task<ACE_MT_SYNCH> (thr_mgr),
150 n_tasks_ (n_tasks),
151 n_threads_ (n_threads),
152 n_iterations_ (n_iterations)
154 // Create a single worker thread.
155 if (this->activate (THR_NEW_LWP,
160 this) == -1)
161 ACE_ERROR ((LM_ERROR,
162 "%p\n",
163 "activate failed"));
166 // Iterate <n_iterations> time printing off a message and "waiting"
167 // for all other threads to complete this iteration.
170 Invoker_Task::svc ()
172 // Note that the ACE_Task::svc_run () method automatically adds us
173 // to the Thread_Manager when the thread begins.
175 ACE_Thread_Manager *thr_mgr =
176 ACE_Thread_Manager::instance ();
177 Worker_Task **worker_task = 0;
179 ACE_NEW_RETURN (worker_task,
180 Worker_Task *[n_tasks_],
181 -1);
182 size_t task = 0;
184 for (task = 0;
185 task < this->n_tasks_;
186 task++)
188 ACE_DEBUG ((LM_DEBUG,
189 " (%t) in task %d\n",
190 task + 1));
192 ACE_NEW_RETURN (worker_task[task],
193 Worker_Task (thr_mgr,
194 n_threads_,
195 n_iterations_),
196 -1);
198 if (worker_task[task]->open () == -1)
199 ACE_ERROR_RETURN ((LM_ERROR,
200 "%p\n",
201 "open failed"),
202 -1);
205 // Set all tasks to be one group
206 ACE_DEBUG ((LM_DEBUG,
207 " (%t) setting tasks group id\n"));
209 for (task = 0;
210 task < this->n_tasks_;
211 task++)
212 if (thr_mgr->set_grp (worker_task[task],
213 1) == -1)
214 ACE_ERROR ((LM_DEBUG,
215 " (%t) %p\n",
216 "set_grp"));
218 size_t n_tasks =
219 thr_mgr->num_tasks_in_group (1);
220 ACE_DEBUG ((LM_DEBUG,
221 "Number of tasks in group 1: %d\n",
222 n_tasks)) ;
224 // Wait for 1 second and then suspend every thread in the group.
225 ACE_OS::sleep (1);
226 ACE_DEBUG ((LM_DEBUG,
227 " (%t) suspending group\n"));
229 if (thr_mgr->suspend_grp (1) == -1)
230 ACE_ERROR ((LM_DEBUG,
231 " (%t) %p\n",
232 "suspend_grp"));
234 // Wait for 3 more second and then resume every thread in the group.
235 ACE_OS::sleep (ACE_Time_Value (2));
237 ACE_DEBUG ((LM_DEBUG,
238 " (%t) resuming group\n"));
240 if (thr_mgr->resume_grp (1) == -1)
241 ACE_ERROR ((LM_DEBUG,
242 " (%t) %p\n",
243 "resume_grp"));
245 // Wait for all the tasks to reach their exit point.
246 thr_mgr->wait ();
248 // Note that the ACE_Task::svc_run () method automatically removes
249 // us from the Thread_Manager when the thread exits.
250 return 0;
253 // Default number of tasks and iterations.
254 static const size_t DEFAULT_TASKS = 4;
255 static const size_t DEFAULT_ITERATIONS = 5;
258 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
260 size_t n_tasks = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_TASKS;
261 size_t n_threads = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_THREADS;
262 size_t n_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : DEFAULT_ITERATIONS;
264 // Since ACE_Thread_Manager can only wait for all threads, we'll
265 // have special manager for the Invoker_Task.
266 ACE_Thread_Manager invoker_manager;
268 Invoker_Task invoker (&invoker_manager,
269 n_tasks,
270 n_threads,
271 n_iterations);
273 // Wait for 1 second and then suspend the invoker task
274 ACE_OS::sleep (1);
275 ACE_DEBUG ((LM_DEBUG,
276 " (%t) suspending invoker task\n"));
278 if (invoker_manager.suspend_task (&invoker) == -1)
279 ACE_ERROR ((LM_DEBUG,
280 " (%t) %p\n",
281 "suspend_task"));
283 // Wait for 3 more second and then resume the invoker task.
284 ACE_OS::sleep (ACE_Time_Value (3));
286 ACE_DEBUG ((LM_DEBUG,
287 " (%t) resuming invoker task\n"));
289 if (invoker_manager.resume_task (&invoker) == -1)
290 ACE_ERROR ((LM_DEBUG,
291 " (%t) %p\n",
292 "resume_task"));
294 // Wait for all the threads to reach their exit point.
295 invoker_manager.wait ();
297 ACE_DEBUG ((LM_DEBUG,
298 " (%t) done\n"));
299 return 0;
301 #else
303 ACE_TMAIN (int, ACE_TCHAR *[])
305 ACE_ERROR ((LM_ERROR,
306 "threads not supported on this platform\n"));
307 return 0;
309 #endif /* ACE_HAS_THREADS */