2 //=============================================================================
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"
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
33 virtual ACE_THR_FUNC_RETURN
start (ACE_THR_FUNC func
,
37 class Barrier_Task
: public ACE_Task
<ACE_MT_SYNCH
>
40 Barrier_Task (ACE_Thread_Manager
*thr_mgr
,
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);
53 /// Reference to the tester barrier. This controls each iteration of
54 /// the tester function running in every thread.
57 /// Number of iterations to run.
62 My_Thread_Hook::start (ACE_THR_FUNC func
,
66 ACE_TEXT ("(%t) starting the thread!\n")));
70 Barrier_Task::Barrier_Task (ACE_Thread_Manager
*thr_mgr
,
73 : ACE_Task
<ACE_MT_SYNCH
> (thr_mgr
),
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().
84 Barrier_Task::close (u_long
)
86 if (ACE_OS::thr_equal (ACE_Thread::self (),
87 this->last_thread ()))
94 // Iterate <n_iterations> time printing off a message and "waiting"
95 // for all other threads to complete this iteration.
97 Barrier_Task::svc (void)
99 for (int iterations
= 1;
100 iterations
<= this->n_iterations_
;
103 ACE_DEBUG ((LM_DEBUG
,
104 ACE_TEXT ("(%t) in iteration %d\n"),
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.
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 (),
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 ();
148 ACE_TEXT ("threads not supported on this platform\n")));
149 #endif /* ACE_HAS_THREADS */