1 #include <lttv/option.h>
2 #include <lttv/module.h>
4 #include <lttv/attribute.h>
5 #include <lttv/iattribute.h>
6 #include <lttv/stats.h>
7 #include <lttv/filter.h>
10 #include <ltt/trace.h>
16 long period_sec
, period_nsec
, running_time_sec
, running_time_nsec
;
19 struct timeval
*tv1
, *tv2
;
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
;
26 struct marker_field
*f
= lttv_trace_get_hook_field(th
,0);
27 guint32 prev_pid
= ltt_event_get_long_unsigned(e
, f
);
29 f
= lttv_trace_get_hook_field(th
, 1);
30 guint32 next_pid
= ltt_event_get_long_unsigned(e
, f
);
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
40 for(i
=0; i
<fsm_list
->len
; i
++)
42 rtstruct
= g_array_index(fsm_list
, struct realtime
*, i
);
43 if(rtstruct
->pid
==next_pid
){
45 realtimeContext_schedule_in(&rtstruct
->_fsm
, t2_sec
, t2_nsec
);
48 else if(rtstruct
->pid
==prev_pid
){
50 realtimeContext_schedule_out(&rtstruct
->_fsm
, t2_sec
, t2_nsec
);
56 rtstruct
= realtime_Init(next_pid
, DEFAULT_PERIOD_SEC
,
58 DEFAULT_RUNNING_TIME_SEC
,
59 DEFAULT_RUNNING_TIME_NSEC
);
60 g_array_append_val(fsm_list
, rtstruct
);
62 realtimeContext_schedule_in(&rtstruct
->_fsm
, t2_sec
, t2_nsec
);
67 else//we might have already created the fsm so check @ first
70 rtstruct
= realtime_Init(application_pid
, period_sec
, period_nsec
, running_time_sec
, running_time_nsec
);
71 g_array_append_val(fsm_list
, rtstruct
);
75 rtstruct
= g_array_index(fsm_list
, struct realtime
*, 0);
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
);
85 void removefsm(struct realtime
*rtstruct
){
87 for(i
=0; i
<fsm_list
->len
; i
++){
88 struct realtime
*tmp
= g_array_index(fsm_list
,struct realtime
*, i
);
90 g_array_remove_index(fsm_list
,i
);
96 static int add_events_by_id_hooks(void *hook_data
, void *call_data
){
97 LttvTraceContext
*tc
= (LttvTraceContext
*) call_data
;
101 GQuark LTT_FACILITY_KERNEL
= g_quark_from_string("kernel");
102 GQuark LTT_EVENT_SCHED_SCHEDULE
= g_quark_from_string("sched_schedule");
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");
109 GArray
*hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 1);
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
),
117 int nb_tracefiles
= tc
->tracefiles
->len
;
118 LttvTracefileContext
**tfc
;
119 LttvHooks
*needed_hooks
;
120 LttvTraceHook
*th
= (LttvTraceHook
*)hook_data
;
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
);
135 LttvAttributeValue value
;
137 LttvIAttribute
*attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
139 static LttvHooks
*before_trace
;
141 result
= lttv_iattribute_find_by_path(attributes
, "hooks/trace/before", LTTV_POINTER
, &value
);
143 before_trace
= *(value
.v_pointer
);
144 g_assert(before_trace
);
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
);
150 printf("Enter your real-time application ip (-1 for all)\n");
151 scanf("%d", &application_pid
);
152 if(application_pid
!=-1)
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);
159 running_time_nsec
=500000;
162 tv1
= (struct timeval
*)malloc(sizeof(struct timeval
));
163 gettimeofday(tv1
, NULL
);
165 fsm_list
= g_array_new(FALSE
, FALSE
, sizeof(struct realtime
*));
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
);
176 LTTV_MODULE("rt_checker", "Detects scheduling latencies",
178 init
, destroy
, "stats", "batchAnalysis", "option")