Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Task_Test.cpp
blob60310043fd4e8b36a2ab5a2c2d75d92f15d420e6
2 //=============================================================================
3 /**
4 * @file Task_Test.cpp
6 * This test program illustrates how the ACE barrier
7 * synchronization mechanisms work in conjunction with the
8 * <ACE_Task> and the <ACE_Thread_Manager>. This also illustrates
9 * how the <ACE_Thread_Hook> mechanism works.
11 * @author Prashant Jain <pjain@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
13 //=============================================================================
15 #include "test_config.h"
16 #include "ace/Task.h"
17 #include "ace/Thread_Hook.h"
19 #if defined (ACE_HAS_THREADS)
20 #include "ace/Atomic_Op.h"
21 #include "ace/Barrier.h"
23 // Make sure that only one thread sees the "time to clean up" condition
24 // in Barrier_Task::close()
25 static ACE_Atomic_Op<ACE_Thread_Mutex, int> close_cleanups (0);
27 class My_Thread_Hook : public ACE_Thread_Hook
29 public:
30 ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func,
31 void *arg) override;
34 class Barrier_Task : public ACE_Task<ACE_MT_SYNCH>
36 public:
37 Barrier_Task (ACE_Thread_Manager *thr_mgr,
38 int n_threads,
39 int n_iterations);
41 //FUZZ: disable check_for_lack_ACE_OS
42 ///FUZZ: enable check_for_lack_ACE_OS
43 int close (u_long flags = 0) override;
45 /// Iterate <n_iterations> time printing off a message and "waiting"
46 /// for all other threads to complete this iteration.
47 int svc () override;
49 private:
50 /// Reference to the tester barrier. This controls each iteration of
51 /// the tester function running in every thread.
52 ACE_Barrier barrier_;
54 /// Number of iterations to run.
55 int n_iterations_;
58 ACE_THR_FUNC_RETURN
59 My_Thread_Hook::start (ACE_THR_FUNC func,
60 void *arg)
62 ACE_DEBUG ((LM_DEBUG,
63 ACE_TEXT ("(%t) starting the thread!\n")));
64 return (func) (arg);
67 Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr,
68 int n_threads,
69 int n_iterations)
70 : ACE_Task<ACE_MT_SYNCH> (thr_mgr),
71 barrier_ (n_threads),
72 n_iterations_ (n_iterations)
74 // Create worker threads.
75 if (this->activate (THR_NEW_LWP, n_threads) == -1)
76 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("activate failed")));
79 // Check to see if it's time to clean up by examining last_thread().
80 int
81 Barrier_Task::close (u_long)
83 if (ACE_OS::thr_equal (ACE_Thread::self (),
84 this->last_thread ()))
86 ++close_cleanups;
88 return 0;
91 // Iterate <n_iterations> time printing off a message and "waiting"
92 // for all other threads to complete this iteration.
93 int
94 Barrier_Task::svc ()
96 for (int iterations = 1;
97 iterations <= this->n_iterations_;
98 iterations++)
100 ACE_DEBUG ((LM_DEBUG,
101 ACE_TEXT ("(%t) in iteration %d\n"),
102 iterations));
104 // Block until all other threads have waited, then continue.
105 this->barrier_.wait ();
108 // Note that the <ACE_Task::svc_run> method automatically removes us
109 // from the Thread_Manager when the thread exits.
111 return 0;
114 #endif /* ACE_HAS_THREADS */
117 run_main (int, ACE_TCHAR *[])
119 ACE_START_TEST (ACE_TEXT ("Task_Test"));
121 #if defined (ACE_HAS_THREADS)
122 // Set the thread hook!
123 ACE_Thread_Hook::thread_hook (new My_Thread_Hook);
125 int n_threads = ACE_MAX_THREADS;
126 int n_iterations = ACE_MAX_ITERATIONS;
128 Barrier_Task barrier_task (ACE_Thread_Manager::instance (),
129 n_threads,
130 n_iterations);
132 ACE_Thread_Manager::instance ()->wait ();
134 // Only one of the threads should see a cleanup...
135 if (close_cleanups != 1)
136 ACE_ERROR ((LM_ERROR,
137 ACE_TEXT ("%d threads saw cleanup indication; ")
138 ACE_TEXT ("should be 1\n"),
139 close_cleanups.value ()));
141 // Cleanup the thread hook so it doesn't leak.
142 delete ACE_Thread_Hook::thread_hook ();
143 #else
144 ACE_ERROR ((LM_INFO,
145 ACE_TEXT ("threads not supported on this platform\n")));
146 #endif /* ACE_HAS_THREADS */
147 ACE_END_TEST;
148 return 0;