Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / ACE / tests / Task_Test.cpp
blob967fa03f5fb0b949529296e2732957cd82d09423
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 //=============================================================================
16 #include "test_config.h"
17 #include "ace/Task.h"
18 #include "ace/Thread_Hook.h"
22 #if defined (ACE_HAS_THREADS)
23 #include "ace/Atomic_Op.h"
24 #include "ace/Barrier.h"
26 // Make sure that only one thread sees the "time to clean up" condition
27 // in Barrier_Task::close()
28 static ACE_Atomic_Op<ACE_Thread_Mutex, int> close_cleanups (0);
30 class My_Thread_Hook : public ACE_Thread_Hook
32 public:
33 virtual ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func,
34 void *arg);
37 class Barrier_Task : public ACE_Task<ACE_MT_SYNCH>
39 public:
40 Barrier_Task (ACE_Thread_Manager *thr_mgr,
41 int n_threads,
42 int n_iterations);
44 //FUZZ: disable check_for_lack_ACE_OS
45 ///FUZZ: enable check_for_lack_ACE_OS
46 virtual int close (u_long flags = 0);
48 /// Iterate <n_iterations> time printing off a message and "waiting"
49 /// for all other threads to complete this iteration.
50 virtual int svc (void);
52 private:
53 /// Reference to the tester barrier. This controls each iteration of
54 /// the tester function running in every thread.
55 ACE_Barrier barrier_;
57 /// Number of iterations to run.
58 int n_iterations_;
61 ACE_THR_FUNC_RETURN
62 My_Thread_Hook::start (ACE_THR_FUNC func,
63 void *arg)
65 ACE_DEBUG ((LM_DEBUG,
66 ACE_TEXT ("(%t) starting the thread!\n")));
67 return (func) (arg);
70 Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr,
71 int n_threads,
72 int n_iterations)
73 : ACE_Task<ACE_MT_SYNCH> (thr_mgr),
74 barrier_ (n_threads),
75 n_iterations_ (n_iterations)
77 // Create worker threads.
78 if (this->activate (THR_NEW_LWP, n_threads) == -1)
79 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("activate failed")));
82 // Check to see if it's time to clean up by examining last_thread().
83 int
84 Barrier_Task::close (u_long)
86 if (ACE_OS::thr_equal (ACE_Thread::self (),
87 this->last_thread ()))
89 ++close_cleanups;
91 return 0;
94 // Iterate <n_iterations> time printing off a message and "waiting"
95 // for all other threads to complete this iteration.
96 int
97 Barrier_Task::svc (void)
99 for (int iterations = 1;
100 iterations <= this->n_iterations_;
101 iterations++)
103 ACE_DEBUG ((LM_DEBUG,
104 ACE_TEXT ("(%t) in iteration %d\n"),
105 iterations));
107 // Block until all other threads have waited, then continue.
108 this->barrier_.wait ();
111 // Note that the <ACE_Task::svc_run> method automatically removes us
112 // from the Thread_Manager when the thread exits.
114 return 0;
117 #endif /* ACE_HAS_THREADS */
120 run_main (int, ACE_TCHAR *[])
122 ACE_START_TEST (ACE_TEXT ("Task_Test"));
124 #if defined (ACE_HAS_THREADS)
125 // Set the thread hook!
126 ACE_Thread_Hook::thread_hook (new My_Thread_Hook);
128 int n_threads = ACE_MAX_THREADS;
129 int n_iterations = ACE_MAX_ITERATIONS;
131 Barrier_Task barrier_task (ACE_Thread_Manager::instance (),
132 n_threads,
133 n_iterations);
135 ACE_Thread_Manager::instance ()->wait ();
137 // Only one of the threads should see a cleanup...
138 if (close_cleanups != 1)
139 ACE_ERROR ((LM_ERROR,
140 ACE_TEXT ("%d threads saw cleanup indication; ")
141 ACE_TEXT ("should be 1\n"),
142 close_cleanups.value ()));
144 // Cleanup the thread hook so it doesn't leak.
145 delete ACE_Thread_Hook::thread_hook ();
146 #else
147 ACE_ERROR ((LM_INFO,
148 ACE_TEXT ("threads not supported on this platform\n")));
149 #endif /* ACE_HAS_THREADS */
150 ACE_END_TEST;
151 return 0;