Doxygen changes
[ACE_TAO.git] / ACE / tests / Priority_Task_Test.cpp
blob056dc2adae6c9e4e2281734454fcef09598efce3
2 //=============================================================================
3 /**
4 * @file Priority_Task_Test.cpp
6 * This is a simple test to illustrate the priority mechanism of
7 * ACE Tasks. The test requires no options, but the -d option
8 * enables LM_DEBUG output.
10 * @author Carlos O'Ryan <coryan@cs.wustl.edu>
12 //=============================================================================
15 #include "test_config.h"
16 #include "ace/Task.h"
17 #include "ace/Sched_Params.h"
18 #include "ace/OS_NS_errno.h"
19 #include "ace/OS_NS_string.h"
21 static const ACE_TCHAR *usage = ACE_TEXT ("usage: %s [-d]\n");
23 #if defined (ACE_HAS_THREADS)
25 /**
26 * @class Priority_Task
28 * @brief A simple Task that runs itself a different priorities.
30 * This task uses the void* argument on open to run the svc()
31 * method at a different priority. The point is execise the thread
32 * priority features of ACE.
34 class Priority_Task : public ACE_Task<ACE_MT_SYNCH>
36 public:
37 /// The constructor
38 Priority_Task (void);
40 //FUZZ: disable check_for_lack_ACE_OS
41 /**
42 * Receives the priority and run svc() on a separate thread at that
43 * priority.
44 *FUZZ: enable check_for_lack_ACE_OS
46 int open (void *);
48 /// Runs on a separate thread an checks the priority.
49 int svc (void);
51 /// Returns 1 if priority was set properly, 0 otherwise.
52 int succeeded (void) { return error_ == 0; }
54 private:
55 int priority_;
56 u_int error_;
59 Priority_Task::Priority_Task (void)
60 : ACE_Task<ACE_MT_SYNCH> (ACE_Thread_Manager::instance ()),
61 priority_ (0),
62 error_ (0)
66 int
67 Priority_Task::open (void *arg)
69 this->priority_ = *(int *) arg;
71 long flags = THR_NEW_LWP;
73 // To get FIFO scheduling with PTHREADS.
74 ACE_SET_BITS (flags,
75 THR_SCHED_FIFO);
77 // Become an active object.
78 if (this->activate (flags,
81 this->priority_) == -1)
83 // On Linux, for example, only the superuser can set the policy
84 // to other than ACE_SCHED_OTHER. But with ACE_SCHED_OTHER,
85 // there is only one thread priority value, for example, 0. So,
86 // let the superuser run an interesting test, but for other
87 // users use the minimum ACE_SCHED_OTHER thread priority.
89 long fallback_priority =
90 ACE_Sched_Params::priority_min (ACE_SCHED_OTHER,
91 ACE_SCOPE_THREAD);
93 ACE_DEBUG ((LM_DEBUG,
94 ACE_TEXT ("(%t) task activation at priority %d with ")
95 ACE_TEXT ("flags 0x%X failed; retry at priority %d with ")
96 ACE_TEXT ("flags 0x%X (errno is %d%p)\n"),
97 this->priority_,
98 flags,
99 fallback_priority,
100 THR_NEW_LWP,
101 ACE_ERRNO_GET,
102 ACE_TEXT ("")));
104 flags = THR_NEW_LWP;
105 this->priority_ = fallback_priority;
107 if (this->activate (flags,
110 this->priority_) == -1)
112 if (ACE_OS::last_error () == EPERM)
113 ACE_ERROR_RETURN ((LM_INFO,
114 ACE_TEXT ("Insufficient privilege to run this test.\n")),
115 -1);
116 else
117 ACE_DEBUG ((LM_ERROR,
118 ACE_TEXT ("(%t) task activation at priority %d failed, ")
119 ACE_TEXT ("exiting!\n%a"),
120 this->priority_,
121 -1));
124 return 0;
128 Priority_Task::svc (void)
130 ACE_hthread_t thr_handle;
131 ACE_Thread::self (thr_handle);
132 int prio;
134 if (ACE_Thread::getprio (thr_handle, prio) == -1)
136 if (errno == ENOTSUP)
138 ACE_DEBUG((LM_DEBUG,
139 ACE_TEXT ("getprior not supported on this platform\n")
141 return 0;
143 ACE_ERROR_RETURN ((LM_ERROR,
144 ACE_TEXT ("%p\n"),
145 ACE_TEXT ("getprio failed")),
146 -1);
149 if (prio == this->priority_)
150 ACE_DEBUG ((LM_DEBUG,
151 ACE_TEXT ("(%t) actual prio of %d equals desired priority\n"),
152 prio));
153 else
155 ACE_DEBUG ((LM_ERROR,
156 ACE_TEXT ("(%t) actual prio = %d, desired priority_ = %d!\n"),
157 prio,
158 this->priority_));
159 ++error_;
162 return 0;
165 #endif /* ACE_HAS_THREADS */
168 run_main (int argc, ACE_TCHAR *argv[])
170 ACE_START_TEST (ACE_TEXT ("Priority_Task_Test"));
172 if (argc <= 1)
173 // Disable LM_DEBUG messages.
174 ACE_Log_Msg::instance ()->priority_mask
175 (ACE_Log_Msg::instance ()->priority_mask () &~ LM_DEBUG);
176 else if (argc == 2)
178 if (ACE_OS::strcmp (argv[1],
179 ACE_TEXT ("-d")) != 0)
180 ACE_ERROR_RETURN ((LM_ERROR,
181 usage,
182 argv [0]),
183 -1);
184 // else -d option: don't disable LM_DEBUG messages
186 else
187 ACE_ERROR_RETURN ((LM_ERROR,
188 usage,
189 argv [0]),
190 -1);
192 int status = 0;
194 #if defined (ACE_HAS_THREADS)
196 Priority_Task tasks[ACE_MAX_ITERATIONS];
198 size_t i;
200 // Spawn off ACE_MAX_ITERATIONS of tasks, passing each one their
201 // iteration number as their priority.
203 // NOTE: on Solaris, for example, this requests the min FIFO
204 // priority. But, this test doesn't use the Realtime scheduling
205 // class. The FIFO priorities are used because they're all
206 // nonnegative.
208 ACE_Sched_Priority_Iterator priority (ACE_SCHED_FIFO,
209 ACE_SCOPE_THREAD);
211 for (i = 0; i < ACE_MAX_ITERATIONS; i++)
213 int p = priority.priority ();
214 if (tasks[i].open ((void *) &p) == -1)
215 break; // Out of enclosing loop.
217 // If there are more priorities get the next one...
218 if (priority.more ())
219 priority.next ();
222 ACE_DEBUG ((LM_DEBUG,
223 ACE_TEXT ("(%t) %d tasks spawned, wait for them to exit . . .\n"),
224 ACE_MAX_ITERATIONS));
226 // Wait for all tasks to exit.
227 ACE_Thread_Manager::instance ()->wait ();
229 for (i = 0; i < ACE_MAX_ITERATIONS; i++)
230 if (!tasks[i].succeeded ())
232 ++status;
233 break;
236 #else
237 ACE_ERROR ((LM_DEBUG,
238 ACE_TEXT ("threads not supported on this platform\n")));
239 #endif /* ACE_HAS_THREADS */
241 // Re-enable LM_DEBUG messages.
242 ACE_Log_Msg::instance ()->priority_mask
243 (ACE_Log_Msg::instance ()->priority_mask () | LM_DEBUG);
245 ACE_END_TEST;
246 return status;