int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { int result = parse_args (argc, argv); if (result != 0) { return result; } move_to_rt_class (); ACE_High_Res_Timer::calibrate (); size_t i = 0; ACE_NEW_RETURN (data_block, ACE_Locked_Data_Block<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> >, -1); for (i = 0; i < number_of_messages; ++i) { data_block->duplicate (); } ACE_Message_Queue<ACE_SYNCH> message_queue; // Workers. Worker_Task **workers = 0; ACE_NEW_RETURN (workers, Worker_Task *[number_of_workers], -1); ACE_Profile_Timer timer; timer.start (); int priority = (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO) + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2; // priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO, priority); long flags = THR_BOUND | THR_SCHED_FIFO; // Create and activate them. for (i = 0; i < number_of_workers; ++i) { ACE_NEW_RETURN (workers[i], Worker_Task (&message_queue), -1); // Activate the workers. result = workers[i]->activate (flags, 1, 1, priority); if (result != 0) { flags = THR_BOUND; priority = ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, ACE_SCOPE_THREAD); result = workers[i]->activate (flags, 1, 1, priority); if (result != 0) { return result; } } } // IO Task. IO_Task io (&message_queue); // Activate the workers. priority = (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO) + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2; priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO, priority); flags = THR_BOUND | THR_SCHED_FIFO; result = io.activate (THR_BOUND); if (result != 0) { flags = THR_BOUND; priority = ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, ACE_SCOPE_THREAD); result = io.activate (flags, 1, 1, priority); if (result != 0) { return result; } } // Wait for all threads to terminate. result = ACE_Thread_Manager::instance ()->wait (); timer.stop (); ACE_Rusage rusage; timer.elapsed_rusage (rusage); Latency_Stats latency; Throughput_Stats throughput; for (i = 0; i < number_of_workers; ++i) { latency.accumulate (workers[i]->latency_stats_); throughput.accumulate (workers[i]->throughput_stats_); ACE_DEBUG ((LM_DEBUG, "Thread[%d]: ", i)); workers[i]->throughput_stats_.dump_results (ACE_TEXT(""), ACE_TEXT("")); } ACE_DEBUG ((LM_DEBUG, "\nTotals for latency:\n")); latency.dump_results (argv[0], ACE_TEXT("latency")); ACE_DEBUG ((LM_DEBUG, "\nTotals for throughput:\n")); throughput.dump_results (argv[0], ACE_TEXT("throughput")); #if defined(ACE_HAS_PRUSAGE_T) ACE_DEBUG ((LM_DEBUG, "\n(%t) Context switches %d/%d\n", rusage.pr_vctx, rusage.pr_ictx)); #endif /* ACE_HAS_PRUSAGE_T */ for (i = 0; i < number_of_workers; ++i) { delete workers[i]; } delete[] workers; delete data_block; return result; }
int Invoker_Task::svc (void) { // Note that the ACE_Task::svc_run () method automatically adds us // to the Thread_Manager when the thread begins. ACE_Thread_Manager *thr_mgr = ACE_Thread_Manager::instance (); Worker_Task **worker_task; ACE_NEW_RETURN (worker_task, Worker_Task *[n_tasks_], -1); size_t task; for (task = 0; task < this->n_tasks_; task++) { ACE_DEBUG ((LM_DEBUG, " (%t) in task %d\n", task + 1)); ACE_NEW_RETURN (worker_task[task], Worker_Task (thr_mgr, n_threads_, n_iterations_), -1); if (worker_task[task]->open () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open failed"), -1); } // Set all tasks to be one group ACE_DEBUG ((LM_DEBUG, " (%t) setting tasks group id\n")); for (task = 0; task < this->n_tasks_; task++) if (thr_mgr->set_grp (worker_task[task], 1) == -1) ACE_ERROR ((LM_DEBUG, " (%t) %p\n", "set_grp")); size_t n_tasks = thr_mgr->num_tasks_in_group (1); ACE_DEBUG ((LM_DEBUG, "Number of tasks in group 1: %d\n", n_tasks)) ; // Wait for 1 second and then suspend every thread in the group. ACE_OS::sleep (1); ACE_DEBUG ((LM_DEBUG, " (%t) suspending group\n")); if (thr_mgr->suspend_grp (1) == -1) ACE_ERROR ((LM_DEBUG, " (%t) %p\n", "suspend_grp")); // Wait for 3 more second and then resume every thread in the group. ACE_OS::sleep (ACE_Time_Value (2)); ACE_DEBUG ((LM_DEBUG, " (%t) resuming group\n")); if (thr_mgr->resume_grp (1) == -1) ACE_ERROR ((LM_DEBUG, " (%t) %p\n", "resume_grp")); // Wait for all the tasks to reach their exit point. thr_mgr->wait (); // Note that the ACE_Task::svc_run () method automatically removes // us from the Thread_Manager when the thread exits. return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { int result = parse_args (argc, argv); if (result != 0) { return result; } ACE_High_Res_Timer::calibrate (); // Create the message queue Message_Queue input_message_queue; Message_Queue output_message_queue; // Create the datablocks. IF we use the default Message Blocks Ctor, // it is going to do an extra allocation for the data block ACE_NEW_RETURN (data_block, ACE_Locked_Data_Block<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> >, -1); // Increment the reference count so that we can share the // datablock. This is donw twice the number of messages for the // input and output queues. size_t i = 0; for (i = 0; i < 2*number_of_messages; ++i) { data_block->duplicate (); } // Create the Synchronisers Synchronisers synch; // Workers. Worker_Task **workers = 0; ACE_NEW_RETURN (workers, Worker_Task *[number_of_workers], -1); // Input Task Input_Task input_task (&input_message_queue, synch); // Output Task Output_Task output_task (&output_message_queue, synch); int priority = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO); long flags = THR_SCHED_FIFO | THR_SCOPE_PROCESS; // Create and activate the worker threads for (i = 0; i < number_of_workers; ++i) { ACE_NEW_RETURN (workers[i], Worker_Task (&input_message_queue, synch), -1); workers[i]->next (&output_task); // Activate the workers. result = workers[i]->activate (flags, 1, 1, priority); if (result != 0) { flags = THR_BOUND; priority = ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, ACE_SCOPE_THREAD); result = workers[i]->activate (flags, 1, 1, priority); if (result != 0) { return result; } } } // Activate the input and output threads result = input_task.activate (flags, 1, 1, priority); if (result != 0) return result; // Activate the workers. result = output_task.activate (flags, 1, 1, priority); if (result != 0) return result; // Wait for all threads to terminate. result = ACE_Thread_Manager::instance ()->wait (); ACE_hrtime_t elapsed_time = 0; test_timer.elapsed_time (elapsed_time); # if !defined (ACE_WIN32) double elapsed_time_per_invocation = (double) elapsed_time / number_of_messages; ACE_DEBUG ((LM_DEBUG, "(%P|%t) Throughput is [%f] \n", elapsed_time_per_invocation)); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Throughput is [%f] \n", 1000000000/ elapsed_time_per_invocation)); #endif /*ACE_WIN32 */ for (i = 0; i < number_of_workers; ++i) { ACE_DEBUG ((LM_DEBUG, "Message process for thread [%d] is [%d] \n", i, workers[i]->processed ())); delete workers[i]; } delete[] workers; return result; }