X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=contrib%2Ffsm_checker%2FRT_CHECK%2Frt_checker.c;fp=contrib%2Ffsm_checker%2FRT_CHECK%2Frt_checker.c;h=cec17822d365dc318a2091112694d2ab1c20b6b1;hb=e09e518ebf18d490dbeb72c6358968af7d05d675;hp=0000000000000000000000000000000000000000;hpb=58f53b56557577b64911d0e7a2bba3fbb521d71d;p=lttv.git diff --git a/contrib/fsm_checker/RT_CHECK/rt_checker.c b/contrib/fsm_checker/RT_CHECK/rt_checker.c new file mode 100755 index 00000000..cec17822 --- /dev/null +++ b/contrib/fsm_checker/RT_CHECK/rt_checker.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "realtime.h" + +int application_pid; +long period_sec, period_nsec, running_time_sec, running_time_nsec; +long t2_sec, t2_nsec; +GArray *fsm_list; +struct timeval *tv1, *tv2; + +static gboolean schedule(void *hook_data, void *call_data){ + LttvTracefileState *s = (LttvTracefileState *) call_data; + LttEvent *e = ltt_tracefile_get_event(s->parent.tf); + LttvTraceHook *th = (LttvTraceHook *)hook_data; + + struct marker_field *f = lttv_trace_get_hook_field(th,0); + guint32 prev_pid = ltt_event_get_long_unsigned(e, f); + + f = lttv_trace_get_hook_field(th, 1); + guint32 next_pid = ltt_event_get_long_unsigned(e, f); + + LttTime time = ltt_event_time(e); + t2_sec=(long)time.tv_sec; + t2_nsec=(long)time.tv_nsec; + struct realtime *rtstruct; + if(application_pid==-1){ + //iterate over all fsms + int i, found=0; + + for(i=0; ilen; i++) + { + rtstruct = g_array_index(fsm_list, struct realtime *, i); + if(rtstruct->pid==next_pid){ + found=1; + realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec); + break; + } + else if(rtstruct->pid==prev_pid){ + found=1; + realtimeContext_schedule_out(&rtstruct->_fsm, t2_sec, t2_nsec); + break; + } + + } + if(!found){ + rtstruct = realtime_Init(next_pid, DEFAULT_PERIOD_SEC, + DEFAULT_PERIOD_NSEC, + DEFAULT_RUNNING_TIME_SEC, + DEFAULT_RUNNING_TIME_NSEC); + g_array_append_val(fsm_list, rtstruct); + //call transition + realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec); + + } + } + + else//we might have already created the fsm so check @ first + { + if(fsm_list->len==0){ + rtstruct = realtime_Init(application_pid, period_sec, period_nsec, running_time_sec, running_time_nsec); + g_array_append_val(fsm_list, rtstruct); + + } + else + rtstruct = g_array_index(fsm_list, struct realtime *, 0); + + + if(rtstruct->pid==next_pid) + realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec); + else if(rtstruct->pid==prev_pid) + realtimeContext_schedule_out(&rtstruct->_fsm, t2_sec, t2_nsec); + } + return FALSE; +} +void removefsm(struct realtime *rtstruct){ + int i; + for(i=0; ilen; i++){ + struct realtime *tmp = g_array_index(fsm_list,struct realtime *, i); + if(tmp==rtstruct){ + g_array_remove_index(fsm_list,i); + break; + } + } + +} +static int add_events_by_id_hooks(void *hook_data, void *call_data){ + LttvTraceContext *tc = (LttvTraceContext *) call_data; + LttTrace *t = tc->t; + + //EVENT CHROOT + GQuark LTT_FACILITY_KERNEL = g_quark_from_string("kernel"); + GQuark LTT_EVENT_SCHED_SCHEDULE = g_quark_from_string("sched_schedule"); + //EVENT FIELDS + GQuark LTT_FIELD_PREV_PID = g_quark_from_string("prev_pid"); + GQuark LTT_FIELD_NEXT_PID = g_quark_from_string("next_pid"); + GQuark LTT_FIELD_PREV_STATE = g_quark_from_string("prev_state"); + + + GArray *hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 1); + + lttv_trace_find_hook(t, LTT_FACILITY_KERNEL, LTT_EVENT_SCHED_SCHEDULE, + FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE), + schedule, + NULL, + &hooks); + + int nb_tracefiles = tc->tracefiles->len; + LttvTracefileContext **tfc; + LttvHooks *needed_hooks; + LttvTraceHook *th = (LttvTraceHook *)hook_data; + int i, j; + for(i=0; itracefiles, LttvTracefileContext*, i); + for(j=0; jlen; j++){ + th=&g_array_index(hooks, LttvTraceHook, j); + needed_hooks = lttv_hooks_by_id_find((*tfc)->event_by_id, th->id); + lttv_hooks_add(needed_hooks, th->h, th, LTTV_PRIO_DEFAULT); + } + } +} +static void init(){ + + gboolean result; + + LttvAttributeValue value; + + LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); + + static LttvHooks *before_trace; + + result = lttv_iattribute_find_by_path(attributes, "hooks/trace/before", LTTV_POINTER, &value); + g_assert(result); +before_trace = *(value.v_pointer); +g_assert(before_trace); + + //Register add_events_by_id_hook to be called before starting to read the trace + //This function will be overwritten between checkers + lttv_hooks_add(before_trace, add_events_by_id_hooks, NULL, LTTV_PRIO_DEFAULT); + + printf("Enter your real-time application ip (-1 for all)\n"); + scanf("%d", &application_pid); + if(application_pid!=-1) + { + printf("Enter period_sec, period_nsec, running_time_sec, running_time_nsec:\n"); + //scanf("%ld%ld%ld%ld", &period_sec, &period_nsec, &running_time_sec, &running_time_nsec); + period_sec=1; + period_nsec=0; + running_time_sec=0; + running_time_nsec=500000; + + } + tv1 = (struct timeval *)malloc(sizeof(struct timeval)); + gettimeofday(tv1, NULL); + + fsm_list = g_array_new(FALSE, FALSE, sizeof(struct realtime *)); +} +static void destroy(){ + tv2 = (struct timeval *)malloc(sizeof(struct timeval)); + gettimeofday(tv2, NULL); + int seconds = tv2->tv_sec - tv1->tv_sec; + printf("analysis took: %d seconds \n", seconds); + + +} + +LTTV_MODULE("rt_checker", "Detects scheduling latencies", + "detects latencies", + init, destroy, "stats", "batchAnalysis", "option") +