Ejemplo n.º 1
0
int _rtapi_task_update_stats_hook(void)
{
    int task_id = _rtapi_task_self();

    // paranoia
    if ((task_id < 0) || (task_id > RTAPI_MAX_TASKS)) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"_rtapi_task_update_stats_hook: BUG -"
			" task_id out of range: %d\n",
			task_id);
	return -ENOENT;
    }

    RT_TASK_INFO rtinfo;
    int retval = rt_task_inquire(ostask_array[task_id], &rtinfo);
    if (retval) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"rt_task_inquire() failed: %d\n",
			retval);
	return -ESRCH;
    }

    rtapi_threadstatus_t *ts = &global_data->thread_status[task_id];

    ts->flavor.xeno.modeswitches = rtinfo.modeswitches;
    ts->flavor.xeno.ctxswitches = rtinfo.ctxswitches;
    ts->flavor.xeno.pagefaults = rtinfo.pagefaults;
    ts->flavor.xeno.exectime = rtinfo.exectime;
    ts->flavor.xeno.modeswitches = rtinfo.modeswitches;
    ts->flavor.xeno.status = rtinfo.status;

    ts->num_updates++;

    return task_id;
}
Ejemplo n.º 2
0
int _rtapi_wait_hook(const int flags) {

    if (flags & TF_NOWAIT)
	return 0;

    int result = rt_task_wait_period();
    if (result != 0) {
	int task_id = _rtapi_task_self();
	if ((task_id < 0) || (task_id > RTAPI_MAX_TASKS)) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "_rtapi_wait_hook: BUG - task_id out of range: %d\n",
			    task_id);
	    return;
	}
	rtapi_exception_detail_t detail = {0};
	rtapi_threadstatus_t *ts = &global_data->thread_status[task_id];
	rtapi_exception_t type;

	detail.task_id = task_id;
	detail.error_code = result;

	switch (result) {

	case RTE_TMROVRN:
	    // an immediate return was taken because the time
	    // deadline has already expired
	    ts->flavor.rtai.wait_errors++;
	    type = RTAI_RTE_TMROVRN;
	    break;

	case RTE_UNBLKD:
	    // the task was unblocked while sleeping
	    // an API usage error
	    ts->api_errors++;
	    type = RTAI_RTE_UNBLKD;
	    break;

	default:
	    // whzat?
	    ts->other_errors++;
	    type = RTAI_RTE_UNCLASSIFIED;
	}

	if (rt_exception_handler)
	    rt_exception_handler(type, &detail, ts);

    }
}
Ejemplo n.º 3
0
static int _rtapi_trap_handler(int vec, int signo, struct pt_regs *regs,
			      void *task) {
    int task_id = _rtapi_task_self();

    rtapi_exception_detail_t detail = {0};

    detail.task_id = task_id;
    detail.flavor.rtai.vector = vec;
    detail.flavor.rtai.signo = signo;
    detail.flavor.rtai.ip = (exc_register_t) IP(regs);

    if (rt_exception_handler)
	rt_exception_handler(RTAI_TRAP, &detail,
			     (task_id > -1) ?
			     &global_data->thread_status[task_id] : NULL);

    _rtapi_task_pause(task_id);
    return 0;
}
Ejemplo n.º 4
0
void _rtapi_wait_hook(void) {
    unsigned long overruns = 0;
    int result =  rt_task_wait_period(&overruns);

    if (result) {
	// something went wrong:

	// update stats counters in thread status
	_rtapi_task_update_stats_hook();

	// inquire, fill in
	// exception descriptor, and call exception handler

	int task_id = _rtapi_task_self();

	// paranoid, but you never know; this index off and
	// things will go haywire really fast
	if ((task_id < 0) || (task_id > RTAPI_MAX_TASKS)) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "_rtapi_wait_hook: BUG - task_id out of range: %d\n",
			    task_id);
	    // maybe should call a BUG exception here
	    return;
	}

	// task_data *task = &(task_array[task_id]);
	rtapi_exception_detail_t detail = {0};
	rtapi_threadstatus_t *ts = &global_data->thread_status[task_id];
	rtapi_exception_t type;

	// exception descriptor
	detail.task_id = task_id;
	detail.error_code = result;

	switch (result) {

	case -ETIMEDOUT:
	    // release point was missed
	    detail.flavor.xeno.overruns = overruns;

	    // update thread status in global_data
	    ts->flavor.xeno.wait_errors++;
	    ts->flavor.xeno.total_overruns += overruns;
	    type = XK_ETIMEDOUT;
	    break;

	case -EWOULDBLOCK:
	    // returned if rt_task_set_periodic() has not previously
	    // been called for the calling task. This is clearly
	    // a Xenomai API usage error.
	    ts->api_errors++;
	    type = XK_EWOULDBLOCK;
	    break;

	case -EINTR:
	    // returned if rt_task_unblock() has been called for
	    // the waiting task before the next periodic release
	    // point has been reached. In this case, the overrun
	    // counter is reset too.
	    // a Xenomai API usage error.
	    ts->api_errors++;
	    type = XK_EINTR;
	    break;

	case -EPERM:
	    // returned if this service was called from a
	    // context which cannot sleep (e.g. interrupt,
	    // non-realtime or scheduler locked).
	    // a Xenomai API usage error.
	    ts->api_errors++;
	    type = XK_EPERM;
	    break;

	default:
	    // the above should handle all possible returns
	    // as per manual, so at least leave a scent
	    // (or what Jeff calls a 'canary value')
	    ts->other_errors++;
	    type = XK_UNDOCUMENTED;
	}
	if (rt_exception_handler)
		rt_exception_handler(type, &detail, ts);
    }  // else: ok - no overruns;
}