/** @details -# If the #freeze_command flag is true, set the simulation mode to Freeze. -# The scheduler sets the mode to Run. Requirement [@ref r_exec_mode_1] -# The scheduler calls Executive::loop_single_thread if only one thread of execution is present. Requirement [@ref r_exec_mode_0] -# The scheduler calls Executive::loop_multi_thread() if more than one thread of execution is present. Requirement [@ref r_exec_mode_1] -# If an exception is caught, the return code, file where the exception occured, and the reason for the exception is saved. The exception return code is returned. -# If an unknown exception is caught, set the exception return code to -1, the file to unknown, and the reason for the exception as unknown. The exception return code is returned. -# If no execption is caught return 0 */ int Trick::Executive::loop() { try { /* If no threads are present, the simulation did not initialize correctly, return */ if ( threads.size() == 0 ) { return(0) ; } /* If the #freeze_command flag is true, set the simulation mode to Freeze. */ if ( freeze_command ) { exec_command = FreezeCmd ; } /* Set the simulation mode to Run. */ mode = Run ; if ( threads.size() == 1 ) { /* Call loop_single_thread() if there is a single thread. */ loop_single_thread() ; } else { /* Call loop_multi_thread() if there is more than one thread. */ loop_multi_thread() ; } } catch (Trick::ExecutiveException & ex ) { /* Handle exception type Trick::ExecutiveException. Set the file name and error message. Return the exception return code. */ except_return = ex.ret_code ; except_file = ex.file ; except_message = ex.message ; return(ex.ret_code) ; } catch (const std::exception &ex) { if ( curr_job != NULL ) { except_file = curr_job->name ; } else { except_file = "somewhere in Executive::run" ; } fprintf(stderr, "\nExecutive::loop terminated with std::exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n" " STOP TIME: %f\n" , except_file.c_str() , ex.what() , get_sim_time()) ; exit(-1) ; } catch (...) { /* Handle unknown exceptions. Set the file name and error message to unknown. exit -1. */ if ( curr_job != NULL ) { except_file = curr_job->name ; } else { except_file = "somewhere in Executive::run" ; } except_message = "unknown error" ; fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n" " STOP TIME: %f\n" , except_file.c_str() , except_message.c_str() , get_sim_time()) ; exit(-1) ; } /* return 0 if there are no errors. */ return(0) ; }
/*Function update elements in TimerList during timeout and starts Timer*/ void updateTimerList() { //Make second element as head, find elapsed time, start timer with new timeout value struct ListNode *current = myTimerList.head; myTimerList.head = myTimerList.head->next; free(current); if (myTimerList.head != NULL ) { float elapsedTime = get_sim_time() - myTimerList.head->time; float newTimout = timeout - elapsedTime; starttimer(A, newTimout); } else //only one element is in list, and there is a timeout. restart timer here { //printf("One Element Only, Timer started at %f \n",get_sim_time()); starttimer(A,timeout); } myTimerList.size--; }
/** @details -# If real-time is active: -# Stop the real-time clock hardware -# Stop the sleep timer hardware */ int Trick::RealtimeSync::shutdown() { if ( active ) { /* Stop the clock */ rt_clock->clock_stop() ; /* If a sleep timer has been defined, stop the timer */ sleep_timer->shutdown() ; #if 0 if (clock_time == 0.0) { sim_to_actual = 0.0; } else { sim_to_actual = (sim_elapsed_time / clock_time); } //TODO: move to Clock class shutdown job if (software_frame < 1.0e36) { /* There were any overruns during the sim & in rt mode. Calculate and print out overrun percentage */ if (time_tics != 0) { overrun_percentage = total_overrun / (get_sim_time() / software_frame); } else { overrun_percentage = 0.0; } *message_publisher() << " TOTAL OVERRUNS: " << setw(12) << total_overrun << "\n" << "PERCENTAGE REALTIME OVERRUNS: " << setw(12) << (overrun_percentage * 100.0) << "%\n" ; } #endif } return(0) ; }
// check if process wait time has exceeded limit and increment its priority // if it has extern void check_limit() { for (int n = 0; n < PROCESS_COUNT; n++) { if (processes[n].state == PROCESS_READY) { if (processes[n].wait_limit >= get_sim_time()) { if (processes[n].static_priority < 4) processes[n].static_priority++; } } } }
/*Function sends packet with "Id" nextSeqNumber, Also add event to timer List*/ void A_sendPacket(int sequence) { insertLinkedList(sequence, get_sim_time()); tolayer3(A, senderBuffer[sequence]); //printf("Packet sent from A to B Sequence Number : %d \n",sequence); if (nextSequenceNum == base) //whenever it starts fresh after receiving all Acks, start the timer { //printf("TIMER HAS BEEN STARTED at %f\n",get_sim_time()); //stoptimer(A); starttimer(A, timeout); } }
int Trick::Executive::freeze(double in_time) { long long new_time ; new_time = (long long)(in_time * time_tic_value) ; if (new_time > time_tics ) { freeze_times.push(new_time) ; if ( new_time < freeze_job->next_tics ) { freeze_job->next_tics = new_time ; } //std::cout << "\033[33mSET FREEZE TIME " << in_time << " " << new_time << "\033[0m" << std::endl ; } else { message_publish(MSG_ERROR, "Freeze time specified in the past. specified %f, current_time %f\n", in_time , get_sim_time()) ; } return(0) ; }
/*Function update elements in TimerList during acknowledgment and starts Timer*/ void updateTimerListForAcknowledgement(int SequenceNum) { struct ListNode *current, *prev, *temp; current = malloc(sizeof(struct ListNode)); // node for traversal prev = malloc(sizeof(struct ListNode)); temp = myTimerList.head; prev = myTimerList.head; current = myTimerList.head->next; //printf("Inside Update Timer with ACKKKKK Function : received SequenceNumber is %d , current time is %f\n",SequenceNum,get_sim_time()); //First value is Ack'ed if (myTimerList.head->seqNum == SequenceNum) { if (current != NULL ) { float elapsedTime = get_sim_time() - current->time; //Taking values from next element float newTimout = timeout - elapsedTime; //printf("Inside Update Timer with ACKKKKK Function : new timeout is %f\n",newTimout); //printf("Stopping timer and starting again at %f\n", newTimout); stoptimer(A); starttimer(A, newTimout); myTimerList.head = current; //update head } //only one element, stop the timer and remove head else { //printf("One Element Only, Timer stopped at %f \n",get_sim_time()); stoptimer(A); myTimerList.head = current; } free(temp); } //remove any other node just like that else { while (current != NULL ) { //if its a tail element, update tail if (current->seqNum == SequenceNum && myTimerList.tail->seqNum == current->seqNum) { prev->next = NULL; myTimerList.tail = prev; //updating tail //printf("updated tail is %d at time %f\n", myTimerList.tail->seqNum,get_sim_time()); break; } else if (current->seqNum == SequenceNum) { prev->next = current->next; //printf("It comes to Else loop too at time %f",get_sim_time()); break; } current = current->next; prev = prev->next; } //END of While Loop } //END of Else Loop }
/** @details -# Set the mode to Initialization Requirement [@ref r_exec_mode_0]. -# Start the cpu usage meter -# Call the default_data jobs -# Call the initialization jobs. -# Record the cpu usage during initialization -# The scheduler initializes simulation timers. Requirement [@ref r_exec_time_1]. -# If an exception is caught, print as much error information available based on execption type caught and exit. -# If no execption is caught return 0 */ int Trick::Executive::init() { double cpu_time ; try { mode = Initialization ; /* Start the cpu usage meter */ struct rusage cpu_usage_buf ; getrusage(RUSAGE_SELF, &cpu_usage_buf); cpu_start = ((double) cpu_usage_buf.ru_utime.tv_sec) + ((double) cpu_usage_buf.ru_utime.tv_usec / 1000000.0); call_default_data() ; call_input_processor() ; // If we are starting from a checkpoint, restart_called will be true. Skip init routines in this case. if ( ! restart_called ) { call_initialization() ; } /* Set the initial values for the scheduler times. */ next_frame_check_tics = software_frame_tics + time_tics ; job_call_time_tics = next_frame_check_tics ; sim_start = get_sim_time(); /* Record the cpu usage for initialization */ getrusage(RUSAGE_SELF, &cpu_usage_buf); cpu_time = ((double) cpu_usage_buf.ru_utime.tv_sec) + ((double) cpu_usage_buf.ru_utime.tv_usec / 1000000.0); cpu_init = cpu_time - cpu_start; initialization_complete = true ; /* Print as much error information avaiable for all exception and exit. */ } catch (Trick::Exec_exception & ex ) { /* Set the exit return code, file name, and error message. Return -1 so we go to shutdown */ except_return = ex.ret_code ; except_file = ex.file ; except_message = ex.message ; return(-1) ; } catch (const std::exception &ex) { if ( curr_job != NULL ) { except_file = curr_job->name ; } else { except_file = "somewhere in Executive::init" ; } fprintf(stderr, "\nExecutive::loop terminated with std::exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n", except_file.c_str(), ex.what()) ; exit(-1) ; } catch (...) { if ( curr_job != NULL ) { except_file = curr_job->name ; } else { except_file = "somewhere in Executive::init" ; } except_message = "unknown error" ; fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n ROUTINE: %s\n DIAGNOSTIC: %s\n", except_file.c_str() , except_message.c_str()) ; exit(-1) ; } /* return 0 if there are no errors. */ return(0) ; }