//do the cpu if the queue or cpu node is not empty. add idle time if not //calculate times void FCFS::do_CPU() { if (!queue->empty() || CPUnode != 0) { CPU_FCFS(); } else { cout << "CPU IDLE "; idle++; } counter++; waiting_time(); }
std::string ScheduleMonitor::print_results() { std::string ScheduleTypeValues[3] = { "First Come First Serve", "Shortest Remaining Time First", "Round Robin" }; std::stringstream ss; ss << "*******************************************************************************\n"; if( schedule_type == RR ) { ss << "**** Scheduling Algorithm: " << ScheduleTypeValues[schedule_type] << " Time Quanta: " << time_quanta << "\n"; } else { ss << "**** Scheduling Algorithm: " << ScheduleTypeValues[schedule_type] << "\n"; } ss << "**** Number of tasks: " << process_list.size() << "\n"; ss << "*******************************************************************************\n"; ss << "PID Arrival CPU Finish Waiting Turn Response Context\n"; ss << " Time Burst Time Time Around Time Switches\n"; ss << " Time \n"; ss << "-------------------------------------------------------------------------------\n"; for( fw_list<ProcessLifetime>::iterator it = process_list.begin(); it != process_list.end(); ++ it ) { ss << std::setw( 3 ) << it->data.pcb.pid; ss << std::setw( 11 ) << float( it->data.arrival_time ) /MILLISECOND; ss << std::setw( 11 ) << float( it->data.pcb.burst_time ) /MILLISECOND; ss << std::setw( 11 ) << float( it->data.completion_time ) /MILLISECOND; ss << std::setw( 11 ) << float( waiting_time( it->data ) ) /MILLISECOND; ss << std::setw( 11 ) << float( turnaround_time( it->data ) ) /MILLISECOND; ss << std::setw( 11 ) << float( it->data.response_time ) /MILLISECOND; ss << std::setw( 10 ) << it->data.context_switches; ss << "\n"; } ss << "\n"; ss << "Average actual CPU burst time = " << cpu_burst_average() << "\n"; ss << "Average CPU burst time needed = " << process_burst_average() << "\n"; ss << "Average waiting time = " << waiting_time_average() << "\n"; ss << "Average turnaround time = " << turnaround_time_average() << "\n"; ss << "Average response time = " << response_time_average() << "\n"; ss << "Average context switches = " << context_switches << "\n"; std::cout << ss.str(); return ss.str(); }
/* * The worker thread function. Take a task from the queue and perform it if * there is any. Otherwise, put itself into the idle thread list and waiting * for signal to wake up. * The thread terminate directly by detach and exit when it is asked to stop * after finishing a task. Otherwise, the thread should be in idle thread list * and should be joined. */ static void *APR_THREAD_FUNC thread_pool_func(apr_thread_t * t, void *param) { apr_thread_pool_t *me = param; apr_thread_pool_task_t *task = NULL; apr_interval_time_t wait; struct apr_thread_list_elt *elt; apr_thread_mutex_lock(me->lock); --me->spawning_cnt; elt = elt_new(me, t); if (!elt) { apr_thread_mutex_unlock(me->lock); apr_thread_exit(t, APR_ENOMEM); } while (!me->terminated && elt->state != TH_STOP) { /* Test if not new element, it is awakened from idle */ if (APR_RING_NEXT(elt, link) != elt) { --me->idle_cnt; APR_RING_REMOVE(elt, link); } APR_RING_INSERT_TAIL(me->busy_thds, elt, apr_thread_list_elt, link); task = pop_task(me); while (NULL != task && !me->terminated) { ++me->tasks_run; elt->current_owner = task->owner; apr_thread_mutex_unlock(me->lock); apr_thread_data_set(task, "apr_thread_pool_task", NULL, t); task->func(t, task->param); apr_thread_mutex_lock(me->lock); APR_RING_INSERT_TAIL(me->recycled_tasks, task, apr_thread_pool_task, link); elt->current_owner = NULL; if (TH_STOP == elt->state) { break; } task = pop_task(me); } assert(NULL == elt->current_owner); if (TH_STOP != elt->state) APR_RING_REMOVE(elt, link); /* Test if a busy thread been asked to stop, which is not joinable */ if ((me->idle_cnt >= me->idle_max && !(me->scheduled_task_cnt && 0 >= me->idle_max) && !me->idle_wait) || me->terminated || elt->state != TH_RUN) { --me->thd_cnt; if ((TH_PROBATION == elt->state) && me->idle_wait) ++me->thd_timed_out; APR_RING_INSERT_TAIL(me->recycled_thds, elt, apr_thread_list_elt, link); apr_thread_mutex_unlock(me->lock); apr_thread_detach(t); apr_thread_exit(t, APR_SUCCESS); return NULL; /* should not be here, safe net */ } /* busy thread become idle */ ++me->idle_cnt; APR_RING_INSERT_TAIL(me->idle_thds, elt, apr_thread_list_elt, link); /* * If there is a scheduled task, always scheduled to perform that task. * Since there is no guarantee that current idle threads are scheduled * for next scheduled task. */ if (me->scheduled_task_cnt) wait = waiting_time(me); else if (me->idle_cnt > me->idle_max) { wait = me->idle_wait; elt->state = TH_PROBATION; } else wait = -1; if (wait >= 0) { apr_thread_cond_timedwait(me->cond, me->lock, wait); } else { apr_thread_cond_wait(me->cond, me->lock); } } /* idle thread been asked to stop, will be joined */ --me->thd_cnt; apr_thread_mutex_unlock(me->lock); apr_thread_exit(t, APR_SUCCESS); return NULL; /* should not be here, safe net */ }