add fsm checker by Gabriel Matni
[lttv.git] / contrib / fsm_checker / RT_CHECK / rt_checker.c
1 #include <lttv/option.h>
2 #include <lttv/module.h>
3 #include <lttv/hook.h>
4 #include <lttv/attribute.h>
5 #include <lttv/iattribute.h>
6 #include <lttv/stats.h>
7 #include <lttv/filter.h>
8 #include <ltt/ltt.h>
9 #include <ltt/event.h>
10 #include <ltt/trace.h>
11 #include <stdio.h>
12 #include <math.h>
13 #include "realtime.h"
14
15 int application_pid;
16 long period_sec, period_nsec, running_time_sec, running_time_nsec;
17 long t2_sec, t2_nsec;
18 GArray *fsm_list;
19 struct timeval *tv1, *tv2;
20
21 static gboolean schedule(void *hook_data, void *call_data){
22 LttvTracefileState *s = (LttvTracefileState *) call_data;
23 LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
24 LttvTraceHook *th = (LttvTraceHook *)hook_data;
25
26 struct marker_field *f = lttv_trace_get_hook_field(th,0);
27 guint32 prev_pid = ltt_event_get_long_unsigned(e, f);
28
29 f = lttv_trace_get_hook_field(th, 1);
30 guint32 next_pid = ltt_event_get_long_unsigned(e, f);
31
32 LttTime time = ltt_event_time(e);
33 t2_sec=(long)time.tv_sec;
34 t2_nsec=(long)time.tv_nsec;
35 struct realtime *rtstruct;
36 if(application_pid==-1){
37 //iterate over all fsms
38 int i, found=0;
39
40 for(i=0; i<fsm_list->len; i++)
41 {
42 rtstruct = g_array_index(fsm_list, struct realtime *, i);
43 if(rtstruct->pid==next_pid){
44 found=1;
45 realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec);
46 break;
47 }
48 else if(rtstruct->pid==prev_pid){
49 found=1;
50 realtimeContext_schedule_out(&rtstruct->_fsm, t2_sec, t2_nsec);
51 break;
52 }
53
54 }
55 if(!found){
56 rtstruct = realtime_Init(next_pid, DEFAULT_PERIOD_SEC,
57 DEFAULT_PERIOD_NSEC,
58 DEFAULT_RUNNING_TIME_SEC,
59 DEFAULT_RUNNING_TIME_NSEC);
60 g_array_append_val(fsm_list, rtstruct);
61 //call transition
62 realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec);
63
64 }
65 }
66
67 else//we might have already created the fsm so check @ first
68 {
69 if(fsm_list->len==0){
70 rtstruct = realtime_Init(application_pid, period_sec, period_nsec, running_time_sec, running_time_nsec);
71 g_array_append_val(fsm_list, rtstruct);
72
73 }
74 else
75 rtstruct = g_array_index(fsm_list, struct realtime *, 0);
76
77
78 if(rtstruct->pid==next_pid)
79 realtimeContext_schedule_in(&rtstruct->_fsm, t2_sec, t2_nsec);
80 else if(rtstruct->pid==prev_pid)
81 realtimeContext_schedule_out(&rtstruct->_fsm, t2_sec, t2_nsec);
82 }
83 return FALSE;
84 }
85 void removefsm(struct realtime *rtstruct){
86 int i;
87 for(i=0; i<fsm_list->len; i++){
88 struct realtime *tmp = g_array_index(fsm_list,struct realtime *, i);
89 if(tmp==rtstruct){
90 g_array_remove_index(fsm_list,i);
91 break;
92 }
93 }
94
95 }
96 static int add_events_by_id_hooks(void *hook_data, void *call_data){
97 LttvTraceContext *tc = (LttvTraceContext *) call_data;
98 LttTrace *t = tc->t;
99
100 //EVENT CHROOT
101 GQuark LTT_FACILITY_KERNEL = g_quark_from_string("kernel");
102 GQuark LTT_EVENT_SCHED_SCHEDULE = g_quark_from_string("sched_schedule");
103 //EVENT FIELDS
104 GQuark LTT_FIELD_PREV_PID = g_quark_from_string("prev_pid");
105 GQuark LTT_FIELD_NEXT_PID = g_quark_from_string("next_pid");
106 GQuark LTT_FIELD_PREV_STATE = g_quark_from_string("prev_state");
107
108
109 GArray *hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 1);
110
111 lttv_trace_find_hook(t, LTT_FACILITY_KERNEL, LTT_EVENT_SCHED_SCHEDULE,
112 FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE),
113 schedule,
114 NULL,
115 &hooks);
116
117 int nb_tracefiles = tc->tracefiles->len;
118 LttvTracefileContext **tfc;
119 LttvHooks *needed_hooks;
120 LttvTraceHook *th = (LttvTraceHook *)hook_data;
121 int i, j;
122 for(i=0; i<nb_tracefiles; i++){
123 tfc = &g_array_index(tc->tracefiles, LttvTracefileContext*, i);
124 for(j=0; j<hooks->len; j++){
125 th=&g_array_index(hooks, LttvTraceHook, j);
126 needed_hooks = lttv_hooks_by_id_find((*tfc)->event_by_id, th->id);
127 lttv_hooks_add(needed_hooks, th->h, th, LTTV_PRIO_DEFAULT);
128 }
129 }
130 }
131 static void init(){
132
133 gboolean result;
134
135 LttvAttributeValue value;
136
137 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
138
139 static LttvHooks *before_trace;
140
141 result = lttv_iattribute_find_by_path(attributes, "hooks/trace/before", LTTV_POINTER, &value);
142 g_assert(result);
143 before_trace = *(value.v_pointer);
144 g_assert(before_trace);
145
146 //Register add_events_by_id_hook to be called before starting to read the trace
147 //This function will be overwritten between checkers
148 lttv_hooks_add(before_trace, add_events_by_id_hooks, NULL, LTTV_PRIO_DEFAULT);
149
150 printf("Enter your real-time application ip (-1 for all)\n");
151 scanf("%d", &application_pid);
152 if(application_pid!=-1)
153 {
154 printf("Enter period_sec, period_nsec, running_time_sec, running_time_nsec:\n");
155 //scanf("%ld%ld%ld%ld", &period_sec, &period_nsec, &running_time_sec, &running_time_nsec);
156 period_sec=1;
157 period_nsec=0;
158 running_time_sec=0;
159 running_time_nsec=500000;
160
161 }
162 tv1 = (struct timeval *)malloc(sizeof(struct timeval));
163 gettimeofday(tv1, NULL);
164
165 fsm_list = g_array_new(FALSE, FALSE, sizeof(struct realtime *));
166 }
167 static void destroy(){
168 tv2 = (struct timeval *)malloc(sizeof(struct timeval));
169 gettimeofday(tv2, NULL);
170 int seconds = tv2->tv_sec - tv1->tv_sec;
171 printf("analysis took: %d seconds \n", seconds);
172
173
174 }
175
176 LTTV_MODULE("rt_checker", "Detects scheduling latencies",
177 "detects latencies",
178 init, destroy, "stats", "batchAnalysis", "option")
179
This page took 0.033622 seconds and 4 git commands to generate.