int set_sched_dl(long period, long exec)
{	
	pid_t pid;
	struct sched_attr dl_attr;
	struct timespec dl_period, dl_exec;
	int ret;
	unsigned int flags = 0;

	pid = getpid();
	dl_period = usec_to_timespec(period);
	dl_exec = usec_to_timespec(exec);
	dl_attr.size = sizeof(dl_attr);
	dl_attr.sched_flags = 0;
	dl_attr.sched_policy = SCHED_DEADLINE;
	dl_attr.sched_runtime = timespec_to_nsec(&dl_exec) + (timespec_to_nsec(&dl_exec) / 100) * 5;
	dl_attr.sched_deadline = timespec_to_nsec(&dl_period);
	dl_attr.sched_period = timespec_to_nsec(&dl_period);


	ret = sched_setattr(pid, &dl_attr, flags);
	if (ret != 0)
	{
		perror("sched_setattr");
	}

	return ret;

}
Exemple #2
0
void bye(void)
{
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &task_rst.t_whole_thread_finish);
	task_rst.t_whole_thread_run = timespec_sub(&task_rst.t_whole_thread_finish, &task_rst.t_whole_thread_start);
	printf("thread_total= %lld ns\t%3.2f%%\t%3.2f%%\nthread_run= %lld ns\t%3.2f%%\t%3.2f%%\n===end===\n", 
			timespec_to_nsec(&task_rst.t_whole_thread_finish),
			(double)timespec_to_nsec(&task_rst.t_whole_thread_finish) / (double)timespec_to_nsec(&task_rst.dl_budget) / (double)task_rst.correct_cnt * 100.0,
			(double)timespec_to_nsec(&task_rst.t_whole_thread_finish) / (double)timespec_to_nsec(&task_rst.dl_period) / (double)task_rst.correct_cnt * 100.0,
			timespec_to_nsec(&task_rst.t_whole_thread_run),
			(double)timespec_to_nsec(&task_rst.t_whole_thread_run) / (double)timespec_to_nsec(&task_rst.dl_budget) / (double)task_rst.correct_cnt * 100.0,
			(double)timespec_to_nsec(&task_rst.t_whole_thread_run) / (double)timespec_to_nsec(&task_rst.dl_period) / (double)task_rst.correct_cnt * 100.0);
}
Exemple #3
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);
	}
}
Exemple #4
0
static uint64_t
perftime(void)
{
  struct timespec ts;
  int r;
  r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
  tor_assert(r == 0);
  return timespec_to_nsec(&ts) - nanostart;
}
Exemple #5
0
static void
reset_perftime(void)
{
  struct timespec ts;
  int r;
  r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
  tor_assert(r == 0);
  nanostart = timespec_to_nsec(&ts);
}
Exemple #6
0
static void accel_data_report_worker(void *arg)
{
    struct sensor_accel_info *info;
    struct report_info *rinfo;
    struct report_info_data *rinfo_data;
    struct sensor_event_data *event_data;
    struct timespec ts;
    uint16_t payload_size;

    payload_size = (PRESSURE_READING_NUM * sizeof(struct sensor_event_data))
                    + (REPORTING_SENSORS * sizeof(struct report_info));

    info = arg;
    if (info->callback) {
        rinfo_data = malloc(sizeof(struct report_info_data) + payload_size);
        if (!rinfo_data)
            goto out;
        rinfo_data->num_sensors_reporting = REPORTING_SENSORS;
        rinfo = rinfo_data->reportinfo;
        rinfo->id = info->sensor_id;
        rinfo->flags = 0;
        event_data = (struct sensor_event_data *)&rinfo->data_payload[0];

        up_rtc_gettime(&ts);
        rinfo->reference_time = timespec_to_nsec(&ts);
        gb_debug("[%u.%03u]\n", ts.tv_sec, (ts.tv_nsec / 1000000));
#ifdef BATCH_PROCESS_ENABLED
        /*
         * Batch sensor data values and its time_deltas
         * until max fifo event count
        */
#else
        /* Single sensor event data */
        rinfo->readings = PRESSURE_READING_NUM;
        event_data->time_delta = 0;
        event_data->data_value[0] = data++;
        event_data->data_value[1] = data++;
        event_data->data_value[2] = data++;
#endif
        gb_debug("report sensor: %d\n", rinfo->id);
        info->callback(info->sensor_id, rinfo_data, payload_size);

        free(rinfo_data);
    }

out:

     /* cancel any work and reset ourselves */
    if (!work_available(&info->data_report_work))
        work_cancel(LPWORK, &info->data_report_work);

    /* if not already scheduled, schedule start */
    if (work_available(&info->data_report_work))
        work_queue(LPWORK, &info->data_report_work, accel_data_report_worker, info, MSEC2TICK(1200));
}
Exemple #7
0
static int sensor_accel_op_flush(struct device *dev, uint8_t id)
{
    struct sensor_event_data *event_data;
    struct sensor_accel_info *info;
    struct report_info_data *rinfo_data;
    struct report_info *rinfo;
    struct timespec ts;
    uint16_t payload_size;

    payload_size = (PRESSURE_READING_NUM * sizeof(struct sensor_event_data))
                    + (REPORTING_SENSORS * sizeof(struct report_info));

    gb_debug("%s:\n", __func__);

    if (!dev || !device_get_private(dev)) {
        return -EINVAL;
    }
    info = device_get_private(dev);

    if (info->callback) {
        rinfo_data = malloc(sizeof(struct report_info) + payload_size);
        if (!rinfo_data)
            return -ENOMEM;

        rinfo_data->num_sensors_reporting = REPORTING_SENSORS;
        rinfo = rinfo_data->reportinfo;
        rinfo->id = info->sensor_id;
        event_data = (struct sensor_event_data *)&rinfo->data_payload[0];

        up_rtc_gettime(&ts);
        rinfo->reference_time = timespec_to_nsec(&ts);
        gb_debug("[%u.%03u]\n", ts.tv_sec, (ts.tv_nsec / 1000000));
        rinfo->flags = REPORT_INFO_FLAG_FLUSHING | REPORT_INFO_FLAG_FLUSH_COMPLETE;
#ifdef BATCH_PROCESS_ENABLED
        /*
         * Batch sensor data values and its time_deltas
         * until max fifo event count
        */
#else
        /* Single sensor event data */
        rinfo->readings = PRESSURE_READING_NUM;
        event_data->time_delta = 0;
        event_data->data_value[0] = data++;
        event_data->data_value[1] = data++;
        event_data->data_value[2] = data++;
#endif
        info->callback(info->sensor_id, rinfo_data, payload_size);

        free(rinfo_data);
    }

    return OK;
}
Exemple #8
0
void print_result_exit(struct timespec *t_now, task_data_t *p_task, task_result_t *p_rst)
{	
	struct timespec t_duration;
	int64_t i_duration;
	t_duration = timespec_sub(t_now, &p_rst->t_exit);
	i_duration = timespec_to_nsec(&t_duration) + (int64_t)duration * 1E9;
	p_rst->i_whole_duration = i_duration;
	printf("===begin===\nstart=\t%lld ns\nend=\t%lld ns\nduration=\t%lld ns\ncnt=\t%d\ncorrect_cnt=\t%d\nmiss_cnt=\t%d\t%3.2f%%\nmiss_cnt_after_middle=\t%d\t%3.2f%%\nthread_runtime=\t%lld ns\ncorrect_thread_runtime=\t%lld ns\navg_thread_runtime=\t%lldns\t%3.2f%%\t%3.2f%%\t%3.2f%%\n",
						timespec_to_nsec(&p_rst->t_exit) - (int64_t)(duration * 1E9),
						timespec_to_nsec(t_now),
						i_duration,
						p_rst->cnt,
						p_rst->correct_cnt,//(int64_t)(duration * 1E9) / timespec_to_nsec(&p_rst->dl_period),
						p_rst->miss_cnt,
						(double)p_rst->miss_cnt/(double)p_rst->cnt * 100.0,
						p_rst->miss_cnt_after_middle,
						(double)p_rst->miss_cnt_after_middle/(double)p_rst->cnt_after_middle * 100.0,
						p_rst->i_whole_thread_runtime,
						p_rst->i_corrent_whole_thread_runtime,
						p_rst->i_whole_thread_runtime / p_rst->cnt,
						(double)p_rst->i_whole_thread_runtime / p_rst->cnt / timespec_to_nsec(&p_rst->dl_exec) * 100.0,
						(double)p_rst->i_whole_thread_runtime / p_rst->cnt / timespec_to_nsec(&p_rst->dl_budget) * 100.0,
						(double)p_rst->i_whole_thread_runtime / p_rst->cnt / timespec_to_nsec(&p_rst->dl_period) * 100.0);

						

	exit(0);
	
}
Exemple #9
0
void signal_handler(int signum)
{
		switch(signum)
		{
			case SIGALRM:
			{
				struct timespec t_alarm;
						clock_gettime(CLOCK_REALTIME, &t_alarm);
						printf("got SIGALARM at %lld ns\n", timespec_to_nsec(&t_alarm));
				break;
			}
			case SIGINT:
			{
				struct timespec t_now;
				clock_gettime(CLOCK_REALTIME, &t_now);
				print_result_exit(&t_now, &task, &task_rst);
				break;
			}
			default:
			{
				break;
			}
		}
}
Exemple #10
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;
}
Exemple #11
0
int64_t nano_time(){
  return timespec_to_nsec(get_current_time());
}
Exemple #12
0
void *thread_body(void *arg) {
  
  int ret;
  int nperiods;
  struct sched_param param;
  timing_point_t *timings;
  pid_t tid;
  struct sched_attr attr;
  unsigned int flags = 0;
  struct timespec t, t_next;
  timing_point_t tmp_timing;
  timing_point_t *curr_timing;
  unsigned long t_start_usec;
  int i = 0;

  thread_data_t *data = (thread_data_t*) arg;

  /* set thread affinity */
  if (data->cpuset != NULL) {
    log_notice("[%d] setting cpu affinity to CPU(s) %s",
      data->ind, data->cpuset_str);
    ret = pthread_setaffinity_np(pthread_self(),
      sizeof(cpu_set_t), data->cpuset);
    if (ret < 0) {
      errno = ret;
      perror("pthread_setaffinity_np");
      exit(EXIT_FAILURE);
    }
  }

  /* set scheduling policy and print pretty info on stdout */
  log_notice("[%d] Using %s policy:", data->ind, data->sched_policy_descr);
  switch (data->sched_policy) {
    case rr:
    case fifo:
      fprintf(data->log_handler, "# Policy : %s\n",
        (data->sched_policy == rr ? "SCHED_RR" : "SCHED_FIFO"));
      param.sched_priority = data->sched_prio;
      ret = pthread_setschedparam(pthread_self(),
        data->sched_policy, &param);
      if (ret != 0) {
        errno = ret; 
        perror("pthread_setschedparam"); 
        exit(EXIT_FAILURE);
      }

      log_notice("[%d] starting thread with period: %" PRIu64 
        ", exec: %" PRIu64 ",""deadline: %" PRIu64 ", priority: %d",
        data->ind,
        timespec_to_usec(&data->period), 
        timespec_to_usec(&data->min_et),
        timespec_to_usec(&data->deadline),
        data->sched_prio
      );
      break;
    case other:
      fprintf(data->log_handler, "# Policy : SCHED_OTHER\n");
      log_notice("[%d] starting thread with period: %" PRIu64 
           ", exec: %" PRIu64 ",""deadline: %" PRIu64 "", data->ind,
        timespec_to_usec(&data->period), 
        timespec_to_usec(&data->min_et),
        timespec_to_usec(&data->deadline)
      );
      data->lock_pages = 0; /* forced off for SCHED_OTHER */
      break;
    case deadline:
      fprintf(data->log_handler, "# Policy : SCHED_DEADLINE\n");
      tid = gettid();
      attr.size = sizeof(attr);
      attr.sched_flags = data->sched_flags;
      if (data->sched_flags && SCHED_FLAG_SOFT_RSV)
        fprintf(data->log_handler, "# Type : SOFT_RSV\n");
      else
        fprintf(data->log_handler, "# Type : HARD_RSV\n");
      attr.sched_policy = SCHED_DEADLINE;
      attr.sched_priority = 0;
      attr.sched_runtime = timespec_to_nsec(&data->max_et) +
        (timespec_to_nsec(&data->max_et) /100) * BUDGET_OVERP;
      attr.sched_deadline = timespec_to_nsec(&data->period);
      attr.sched_period = timespec_to_nsec(&data->period);  
      break;
    default:
      log_error("Unknown scheduling policy %d",
        data->sched_policy);
      exit(EXIT_FAILURE);
  }

  if (data->lock_pages == 1) {
    log_notice("[%d] Locking pages in memory", data->ind);
    ret = mlockall(MCL_CURRENT | MCL_FUTURE);
    if (ret < 0) {
      errno = ret;
      perror("mlockall");
      exit(EXIT_FAILURE);
    }
  }

  /* if we know the duration we can calculate how many periods we will
   * do at most, and the log to memory, instead of logging to file.
   */
  timings = NULL;
  if (data->duration > 0) {
    nperiods = (int) ceil( (data->duration * 10e6) / 
              (double) timespec_to_usec(&data->period));
    timings = malloc ( nperiods * sizeof(timing_point_t));
  }

  fprintf(data->log_handler, "#idx\tperiod\tmin_et\tmax_et\trel_st\tstart"
           "\t\tend\t\tdeadline\tdur.\tslack\tresp_t"
           "\tBudget\tUsed Budget\n");

  if (data->ind == 0) {
    clock_gettime(CLOCK_MONOTONIC, &t_zero);
#ifdef TRACE_SETS_ZERO_TIME
    if (opts.ftrace)
      log_ftrace(ft_data.marker_fd,
           "[%d] sets zero time",
           data->ind);
#endif
  }

  pthread_barrier_wait(&threads_barrier);

  /*
   * Set the task to SCHED_DEADLINE as far as possible touching its
   * budget as little as possible for the first iteration.
   */
  if (data->sched_policy == SCHED_DEADLINE) {
    ret = sched_setattr(tid, &attr, flags);
    if (ret != 0) {
      log_critical("[%d] sched_setattr "
        "returned %d", data->ind, ret);
      errno = ret;
      perror("sched_setattr");
      exit(EXIT_FAILURE);
    }
  }

  t = t_zero;
  t_next = msec_to_timespec(1000LL);
  t_next = timespec_add(&t, &t_next);
  clock_nanosleep(CLOCK_MONOTONIC, 
    TIMER_ABSTIME, 
    &t_next,
    NULL);

  data->deadline = timespec_add(&t_next, &data->deadline);

  while (continue_running) {
    int pn;
    struct timespec t_start, t_end, t_diff, t_slack, t_resp;

    /* Thread numeration reported starts with 1 */
#ifdef TRACE_BEGINS_LOOP
    if (opts.ftrace)
      log_ftrace(ft_data.marker_fd, "[%d] begins job %d", data->ind+1, i);
#endif
    clock_gettime(CLOCK_MONOTONIC, &t_start);
    if (data->nphases == 0) {
      compute(data->ind, &data->min_et, NULL, 0);
    } else {
      for (pn = 0; pn < data->nphases; pn++) {
        log_notice("[%d] phase %d start", data->ind+1, pn);
        exec_phase(data, pn);
        log_notice("[%d] phase %d end", data->ind+1, pn);
      }
    }
    clock_gettime(CLOCK_MONOTONIC, &t_end);
    
    t_diff = timespec_sub(&t_end, &t_start);
    t_slack = timespec_sub(&data->deadline, &t_end);
    t_resp = timespec_sub(&t_end, &t_next);
    t_start_usec = timespec_to_usec(&t_start); 

    if (i < nperiods) {
      if (timings)
        curr_timing = &timings[i];
      else
        curr_timing = &tmp_timing;

      curr_timing->ind = data->ind;
      curr_timing->period = timespec_to_usec(&data->period);
      curr_timing->min_et = timespec_to_usec(&data->min_et);
      curr_timing->max_et = timespec_to_usec(&data->max_et);
      curr_timing->rel_start_time = 
        t_start_usec - timespec_to_usec(&data->main_app_start);
      curr_timing->abs_start_time = t_start_usec;
      curr_timing->end_time = timespec_to_usec(&t_end);
      curr_timing->deadline = timespec_to_usec(&data->deadline);
      curr_timing->duration = timespec_to_usec(&t_diff);
      curr_timing->slack =  timespec_to_lusec(&t_slack);
      curr_timing->resp_time =  timespec_to_usec(&t_resp);
    }
    if (!timings)
      log_timing(data->log_handler, curr_timing);

    t_next = timespec_add(&t_next, &data->period);
    data->deadline = timespec_add(&data->deadline, &data->period);
#ifdef TRACE_END_LOOP
    if (opts.ftrace)
      log_ftrace(ft_data.marker_fd, "[%d] end loop %d", data->ind, i);
#endif
    if (curr_timing->slack < 0)
      log_notice("[%d] DEADLINE MISS !!!", data->ind+1);
    i++;
  }

  free(timings);
}