Exemplo n.º 1
0
void* timer_main(void* arg){

    gd_thread_data_t *tdata = (gd_thread_data_t *) arg;
    thread_common(pthread_self(), tdata);
    long duration_usec = (tdata->duration * 1e6);
    int nperiods = (int) ceil( duration_usec /
            (double) timespec_to_usec(&tdata->period));
    int period = 0;
    struct timespec t_next, t_now;
    t_next = tdata->main_start;
    int subframe_id;

    while(running && (period < nperiods)){

        subframe_id = period%(num_cores_bs);
        t_next = timespec_add(&t_next, &tdata->period);
        clock_gettime(CLOCK_MONOTONIC, &t_now);
        common_time[subframe_id] = t_now;
        common_time_ref = t_now;
        common_time_next = t_next;

        if (timespec_lower(&t_now, &t_next)){
            // sleep for remaining time
            clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
        }else{
            printf("timer is screwed\n");
        }

        period++;
    }
    running = 0;

    pthread_exit(NULL);
}
Exemplo n.º 2
0
static inline int busy_wait(struct timespec *to, struct timespec *dl)
{
	struct timespec t_step, t_wall;
	while(1)
	{
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_step);
		if (!timespec_lower(&t_step, to))
		{
			return 0;
		}	
		clock_gettime(CLOCK_REALTIME, &t_wall);
		if (!timespec_lower(&t_wall, dl))
		{
			return 1;
		}
	}
}
Exemplo n.º 3
0
static inline busywait(struct timespec *to) {
  struct timespec t_step;
  while (1) {
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_step);
    if (!timespec_lower(&t_step, to))
      break;
  }
}
Exemplo n.º 4
0
static inline busywait(__u64 len)
{
	struct timespec t_len, t_now, t_exec, t_step;
	__u64 real_exec = (len / 100) * RTIME_URUN;

	t_len = nsec_to_timespec(&real_exec);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_now);
	t_exec = timespec_add(&t_now, &t_len);
	while (1) {
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_step);
		if (!timespec_lower(&t_step, &t_exec))
			break;
	}
}
Exemplo n.º 5
0
static inline void process_log(task_data_t *p_task, task_result_t *p_rst)
{
	static int first = 1;
	int64_t i_offset, i_diff, i_slack, i_thread_run, i_thread_remain;
	int after_middle;
	i_offset = timespec_to_nsec(&p_task->t_offset);
	i_diff = timespec_to_nsec(&p_task->t_diff);
	i_slack = timespec_to_nsec(&p_task->t_slack);
	i_thread_run = timespec_to_nsec(&p_task->t_thread_run);
	i_thread_remain = timespec_to_nsec(&p_task->t_thread_remain);

	after_middle = timespec_lower(&p_rst->t_middle, &p_task->t_begin);
	++p_rst->cnt;
	if (after_middle)
	{
		++p_rst->cnt_after_middle;
	}
	if (i_thread_remain > 0)
	{	
		++p_rst->lack_cnt;
	}
	if (i_slack < 0)
	{
		++p_rst->miss_cnt;
		if (after_middle)
		{
			++p_rst->miss_cnt_after_middle;
		}

	}
	p_rst->i_whole_thread_runtime += i_thread_run;
	
	if (first)
	{
		printf("%12s\t%12s\t%12s\t%12s\t%12s\n", "offset", "diff", "slack", "exec_time", "unfinished"); 
		first = 0;
	}
	if (g_log)
	{
		printf("%12lld\t%12lld\t%12lld\t%12lld\t%12lld\n",
					i_offset,
					i_diff,
					i_slack,
					i_thread_run,
					i_thread_remain);
	}
}
Exemplo n.º 6
0
int main(int argc, char* argv[])
{	
	pid_t pid;
	long long period, budget, exec;
	char* token;
	struct sched_attr dl_attr;
	int ret;
	unsigned int flags = 0;
	struct sigaction sa;
	struct itimerval timer;

	memset(&task, 0, sizeof(task));
	memset(&task_rst, 0, sizeof(task_rst));

	ret = atexit(bye);
	if (ret != 0)
	{
		perror("atexit");
		exit(1);
	}
	if (argc >= 3)
	{
		pid = getpid();
		printf("%d\t===pid===\n", (int)pid);

		printf("lock pages in memory\n");
		ret = mlockall(MCL_CURRENT | MCL_FUTURE);
		if (ret < 0)
		{
			perror("mlockall");
			exit(1);
		}
	
		token = strtok(argv[1], ":");
		period = strtoll(token, NULL, 10);
		token = strtok(NULL, ":");
		budget = strtoll(token, NULL, 10);
		token = strtok(NULL, ":");
		exec = strtoll(token, NULL, 10);
		printf("period = %lld ns, budget = %lld ns, exec = %lld ns\n", period, budget, exec);
	
		if (exec == 0)
		{
			pure_overhead = 1;
		}
		else
		{
			pure_overhead = 0;
		}
		//duration is a must
		duration = atoi(argv[2]);
		clock_gettime(CLOCK_REALTIME, &task_rst.t_exit);
		memcpy((void*)&task_rst.t_middle, (void*)&task_rst.t_exit, sizeof(task_rst.t_middle));
		task_rst.t_exit.tv_sec = task_rst.t_exit.tv_sec + duration;
		task_rst.t_middle.tv_sec = task_rst.t_middle.tv_sec + duration / 2;//set halfway timestamp

		if (argc >= 4)
		{
			g_log = atoi(argv[3]);
		}
		if (argc >= 5)
		{
			g_scheduler = atoi(argv[4]);	
		}

		//set deadline scheduling
		pid = 0;

		assert(period >= budget && budget >= exec);
//		task_rst.dl_period = usec_to_timespec(period);
//		task_rst.dl_budget = usec_to_timespec(budget);
//		task_rst.dl_exec = usec_to_timespec(exec);
		task_rst.dl_period = nsec_to_timespec((unsigned long long)period);
		task_rst.dl_budget = nsec_to_timespec((unsigned long long)budget);
		task_rst.dl_exec = nsec_to_timespec((unsigned long long)exec);
		dl_attr.size = sizeof(dl_attr);
		dl_attr.sched_flags = 0;
		dl_attr.sched_policy = SCHED_DEADLINE;
		dl_attr.sched_priority = 0;
		dl_attr.sched_runtime = timespec_to_nsec(&task_rst.dl_budget);
		dl_attr.sched_deadline = timespec_to_nsec(&task_rst.dl_period);
		dl_attr.sched_period = timespec_to_nsec(&task_rst.dl_period);
	
		task_rst.correct_cnt =(int)((int64_t)(duration * 1E9) / timespec_to_nsec(&task_rst.dl_period));
		task_rst.i_corrent_whole_thread_runtime = (int64_t)task_rst.correct_cnt * timespec_to_nsec(&task_rst.dl_exec);
	
		if (g_scheduler == 0)
		{
			printf("using sched_deadline\n");
			ret = sched_setattr(pid, &dl_attr, flags);
			if (ret != 0)
			{
				perror("sched_setattr");
				exit(1);
			}
		}
		else if (g_scheduler == 1)
		{
			printf("using cfs\n");
		}
		else
		{
			printf("not implemented\n");
			exit(1);
		}
#if 0
		memset(&sa, 0, sizeof(sa));
		sa.sa_handler = &signal_handler;
		sigaction(SIGALRM, &sa, NULL);
		sigaction(SIGINT, &sa, NULL);
		timer.it_value.tv_sec = dl_period.tv_sec;
		timer.it_value.tv_usec = dl_period.tv_nsec / 1000;
		timer.it_interval.tv_sec = dl_period.tv_sec;
		timer.it_interval.tv_usec = dl_period.tv_nsec / 1000;
		setitimer(ITIMER_REAL, &timer, NULL);
#endif
		struct timespec t_exec;

		clock_gettime(CLOCK_REALTIME, &task.t_period);
		task.t_period = timespec_add(&task.t_period, &task_rst.dl_period);//start from next period 
		task.t_deadline = timespec_add(&task.t_period, &task_rst.dl_period);
		clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &task.t_period, NULL);
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &task_rst.t_whole_thread_start);	
		while(1)
		{
			clock_gettime(CLOCK_REALTIME, &task.t_begin);
			clock_gettime(CLOCK_THREAD_CPUTIME_ID, &task.t_thread_start);
			t_exec = timespec_add(&task.t_thread_start, &task_rst.dl_exec);
			if (!pure_overhead)
			{
				busy_wait(&t_exec, &task.t_deadline);
			}
			clock_gettime(CLOCK_THREAD_CPUTIME_ID, &task.t_thread_finish);
			clock_gettime(CLOCK_REALTIME, &task.t_end);


			task.t_thread_run = timespec_sub(&task.t_thread_finish, &task.t_thread_start);
			task.t_thread_remain = timespec_sub(&t_exec, &task.t_thread_finish);
			task.t_diff = timespec_sub(&task.t_end, &task.t_begin);
			task.t_slack = timespec_sub(&task.t_deadline, &task.t_end);
			task.t_offset = timespec_sub(&task.t_begin, &task.t_period);
			process_log(&task, &task_rst);

			task.t_period = timespec_add(&task.t_period, &task_rst.dl_period);
			task.t_deadline = timespec_add(&task.t_deadline, &task_rst.dl_period);

			//check total test time
			struct timespec t_now;
			clock_gettime(CLOCK_REALTIME, &t_now);
			if (duration && timespec_lower(&task_rst.t_exit, &t_now))
			{
				print_result_exit(&t_now, &task, &task_rst);
								
			}

			clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &task.t_period, NULL);
		}

	}
	else
	{
		printf("usage: rt_task <period>:<budget>:<exec> <duration> [<log_switch>] [<scheduler>]\n");
	}
	return 0;
}
Exemplo n.º 7
0
void* trans_main(void* arg){

    gd_thread_data_t *tdata = (gd_thread_data_t *) arg;
    int id = tdata->ind;

    thread_common(pthread_self(), tdata);
    unsigned long abs_period_start = timespec_to_usec(&tdata->main_start);


    gd_timing_meta_t *timings;
    long duration_usec = (tdata->duration * 1e6);
    int nperiods = (int) ceil( duration_usec /
            (double) timespec_to_usec(&tdata->period));
    timings = (gd_timing_meta_t*) malloc ( nperiods * sizeof(gd_timing_meta_t));
    gd_timing_meta_t* timing;


    struct timespec t_next, t_deadline, trans_start, trans_end, t_temp, t_now;

    t_next = tdata->main_start;
    int period = 0;
    int bs_id  = ((int)(id/num_ants));
    int subframe_id;

    while(running && (period < nperiods)){


        subframe_id = period%(num_cores_bs);

        // get current deadline and next period
        t_deadline = timespec_add(&t_next, &tdata->deadline);
        t_next = timespec_add(&t_next, &tdata->period);

        clock_gettime(CLOCK_MONOTONIC, &trans_start);
        /******* Main transport ******/
        if (debug_trans==1) {
            int j, k;
            for(j=0; j <60000; j++){k=k+1;}
        } else {
            gd_trans_read(tdata->conn_desc);
        }
        /******* Main transport ******/


        pthread_mutex_lock(&subframe_mutex[bs_id*num_cores_bs + subframe_id]);
        // subframe_avail[bs_id*num_cores_bs + subframe_id] = (subframe_avail[bs_id*num_cores_bs + subframe_id]+1)%(num_ants);
        subframe_avail[bs_id*num_cores_bs + subframe_id] ++;
		// printf("subframe_avail:%d %d\n",bs_id*num_cores_bs + subframe_id,subframe_avail[bs_id*num_cores_bs + subframe_id]);


        // hanging fix -- if trans misses a proc, reset the subframe available counter
        if (subframe_avail[bs_id*num_cores_bs + subframe_id] == (num_ants+1)) {
               subframe_avail[bs_id*num_cores_bs + subframe_id] = 1;
        }

        pthread_cond_signal(&subframe_cond[bs_id*num_cores_bs + subframe_id]);
        pthread_mutex_unlock(&subframe_mutex[bs_id*num_cores_bs + subframe_id]);


        clock_gettime(CLOCK_MONOTONIC, &trans_end);
        /*****************************/

        timing = &timings[period];
        timing->ind = id;
        timing->period = period;
        timing->abs_period_time = timespec_to_usec(&t_next);
        timing->rel_period_time = timing->abs_period_time - abs_period_start;

        timing->abs_start_time = timespec_to_usec(&trans_start);
        timing->rel_start_time = timing->abs_start_time - abs_period_start;
        timing->abs_end_time = timespec_to_usec(&trans_end);
        timing->rel_end_time = timing->abs_end_time - abs_period_start;
        timing->abs_deadline = timespec_to_usec(&t_deadline);
        timing->rel_deadline = timing->abs_deadline - abs_period_start;
        timing->actual_duration = timing->rel_end_time - timing->rel_start_time;
        timing->miss = (timing->rel_deadline - timing->rel_end_time >= 0) ? 0 : 1;

        if (timing->actual_duration > 1000){
            // log_critical("Transport overload. Thread[%d] Duration= %lu us. Reduce samples or increase threads",
                // tdata->ind, timing->actual_duration);
        }

        clock_gettime(CLOCK_MONOTONIC, &t_now);

        // check if deadline was missed
        if (timespec_lower(&t_now, &t_next)){
            // sleep for remaining time
            clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
        }else{
            printf("Transport %d is too slow\n", id);
        }

        period ++;

    }
    clock_gettime(CLOCK_MONOTONIC, &t_temp);
    log_notice("Trans thread [%d] ran for %f s", id, ((float) (timespec_to_usec(&t_temp)-abs_period_start))/1e6);


    fprintf(tdata->log_handler, "#idx\t\tabs_period\t\tabs_deadline\t\tabs_start\t\tabs_end"
                   "\t\trel_period\t\trel_start\t\trel_end\t\tduration\t\tmiss\n");


    int i;
    for (i=0; i < nperiods; i++){
        log_timing(tdata->log_handler, &timings[i]);
    }
    fclose(tdata->log_handler);
    log_notice("Exit trans thread %d", id);

    running = 0;
    for (i=0;i<proc_nthreads;i++) {
            pthread_mutex_lock(&subframe_mutex[i]);
            subframe_avail[i]=-1;
            pthread_cond_signal(&subframe_cond[i]);
            pthread_mutex_unlock(&subframe_mutex[i]);
    }

    pthread_exit(NULL);
}