#include #include #include #include #include #include #include #include #include #include "returncode.h" #include "monano.h" #include "monano_data.h" #include "measure.h" #include "time_conversion.h" #include "task_parameter.h" #include "nthread.h" #include "benchmark.h" void* benchmark_my_callback(int anomaly_number, pthread_monano_id_t id) { printf("Type anomaly : %d Anomaly is detected of thread number %d\n", anomaly_number, id); return 0; } void* benchmark_periodic_activation(void* arg){ struct periodic_activation_parameters params = *(periodic_activation_parameters*)arg; int status; struct timespec measure_ts_start; pthread_monano_attr_t attr; //block the thread for precedence constraints if (params.precedency_blocking==1) { // printf("SEMAPHORE : BLOCKING OF THREAD N°EGO== %d WAITING T3 EXECUTION \n", params.ego); status=sem_wait(&prec_const); if(status<0) returncode("sem_wait",status); } //lock the thread for no preemption if (params.non_preemptive==1){ // printf("MUTEX LOCK OF THREAD N°EGO=%d\n", params.ego); status=pthread_mutex_lock(&non_preemptive); if (status<0) returncode("pthread_mutex_lock", status); } measure_start(&measure_ts_start); status=pthread_monano_signal_departure_time(&my_monano, my_monano_id[params.ego]); measure_end(measure_ts_start, "end_time_signal_departure_time"); if(status<0) returncode("pthread_monano_signal_departure_time",status); // printf("EXECUTION OF THREAD N°EGO== %d \n", params.ego); attr=pthread_monano_get_attribute(&my_monano, my_monano_id[params.ego]); status=benchmark_simulate_thread_execution(&my_monano, my_monano_id[params.ego]); if(status<0) returncode("pthread_monano_thread_execution",status); measure_start(&measure_ts_start); status=pthread_monano_signal_end_time(&my_monano, my_monano_id[params.ego]); measure_end(measure_ts_start, "end_time_signal_end_time"); if(status<0) returncode("pthread_monano_signal_end_time",status); //unlock the thread for no preemption if (params.non_preemptive==1){ // printf("MUTEX UNLOCK OF THREAD N°EGO=%d\n", params.ego); status=pthread_mutex_unlock(&non_preemptive); if (status<0) returncode("pthread_mutex_unlock", status); } int j=0, sortie=0; //unblock the thread of precedence constraints if (my_monano.nb_precedencies!=0) do{ if (params.ego == my_monano.pthread_precedencies[j].source){ // printf("SEMAPHORE : EXECUTION OF THREAD N°EGO== %d AND UNBLOCKING THE SEMAPHORE \n", params.ego); status=sem_post(&prec_const); sortie=1; } j++; }while ( j< my_monano.nb_precedencies && sortie ==0); return 0; } int benchmark_simulate_thread_execution(pthread_monano_t* t, pthread_monano_id_t id) { struct timespec starttime, currenttime, endtime, measure_ts_start; pthread_monano_attr_t attr; struct timespec wcet, delay, self_suspension; struct timespec execution_time; int i, status; clock_gettime(CLOCK_REALTIME, &starttime); printf("debut de thread_execution de %x \n",pthread_self() ); attr=pthread_monano_get_attribute(t, id); wcet=pthread_monano_attr_getwcet(attr); delay=pthread_monano_attr_getdelay(attr); self_suspension=pthread_monano_attr_getdeparture_selfsuspension(attr); // on tire entre 1 et wcet execution_time=benchmark_random_execution_time(wcet); do{ clock_gettime(CLOCK_REALTIME, ¤ttime); attr=pthread_monano_get_attribute(t, id); }while (ts_compare(ts_substract(currenttime,starttime),ts_add(ts_add(execution_time,pthread_monano_attr_getpreemption_time(attr)),delay))<0); endtime=ts_substract(currenttime,starttime); printf("fin de thread_execution de %x wcet=%d:%d et temps execution global = %d:%d\n ",pthread_self(), (int)wcet.tv_sec, (int)wcet.tv_nsec,(int)endtime.tv_sec, (int)endtime.tv_nsec ); return 0; } int benchmark_simulate_thread_interruption(struct timespec h) { struct timespec starttime_interruption, currenttime; clock_gettime(CLOCK_REALTIME, &starttime_interruption); do{ clock_gettime(CLOCK_REALTIME, ¤ttime); }while (ts_compare(ts_substract(currenttime,starttime_interruption),h)<0); return 0; } long long benchmark_timespec_to_nanoseconds(struct timespec ts){ return ((long long)ts.tv_sec * 1000000000LL) + ts.tv_nsec; } struct timespec benchmark_nanoseconds_to_timespec(long long ns){ struct timespec ts; ts.tv_sec = ns / 1000000000; ts.tv_nsec = ns % 1000000000; return ts; } struct timespec benchmark_random_execution_time(struct timespec ts){ long long ns = benchmark_timespec_to_nanoseconds(ts); long long range, rs; //initialize the generator srand(time(NULL)+999876543210); //generate a random number between 1000 and ns-1 range = ns - (ns / 2 + 300000000) +1 ; rs = rand() % range; rs = rs + (ns / 2 +300000000); return benchmark_nanoseconds_to_timespec(rs); }