<LI> Polish the visual appearance: icons for the tabs and buttons,
background, lines and labels in the control flow viewer...
<LI> When a trace is opened, start a background thread to precompute
- the system state after each ~100 000 events. Have the option to save
- the precomputed state when a trace is closed. Use the precomputed
- state if available when opening a trace or seeking in a trace.
+ the system state and memorize it after each ~100 000 events.
+ Have the option to save the precomputed state when a trace is closed.
+ Use the precomputed state if available when opening a trace or
+ seeking in a trace. Use the same thread for computing statistics.
<LI> Update module.c to ease changing a module into a builtin feature.
+<LI> Split processTrace into tracecontext and processtrace.
<LI> Insure that g_info logging is generally available but off by default.
<LI> Document each header file such that developer documentation can
be extracted automatically using
<A href="http://www.doxygen.org">Doxygen</A>.
<LI> Complete the user and developer documentation.
<LI> Test the viewer on large SMP traces. Insure that 2GB files do not cause
- crashes. Note unduly long delays.
+ crashes. Note and fix unduly long delays.
</body>
#include <glib.h>
#include <lttv/processTrace.h>
-/* The operating system state kept during the trace analysis
+/* The operating system state, kept during the trace analysis,
contains a subset of the real operating system state,
sufficient for the analysis, and possibly organized quite differently.
void lttv_state_save_remove_event_hooks(LttvTracesetState *self);
-void lttv_state_restore_closest_state(LttvTracesetState *self, LttTime t);
+void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t);
/* The LttvProcessState structure defines the current state for each process.
A process can make system calls (in some rare cases nested) and receive
GQuark *syscall_names;
GQuark *trap_names;
GQuark *irq_names;
+ gboolean recompute_state_in_seek;
+ gboolean saved_state_available;
};
struct _LttvTraceStateClass {
tc = self->parent.traces[i];
tcs = (LttvTraceState *)tc;
tcs->save_interval = 100000;
+ tcs->recompute_state_in_seek = false;
+ tcs->saved_state_ready = false;
fill_name_tables(tcs);
nb_control = ltt_trace_control_tracefile_number(tc->t);
}
-void lttv_state_restore_closest_state(LttvTracesetState *self, LttTime t)
+void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t)
{
LttvTraceset *traceset = self->parent.ts;
for(i = 0 ; i < nb_trace ; i++) {
tcs = (LttvTraceState *)self->parent.traces[i];
- saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
- LTTV_STATE_SAVED_STATES);
- min_pos = -1;
- max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
- mid_pos = max_pos / 2;
- while(min_pos < max_pos) {
- type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
- g_assert(type == LTTV_GOBJECT);
- saved_state_tree = *((LttvAttribute **)(value.v_gobject));
- type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME,
- &value);
- g_assert(type == LTTV_TIME);
- if(ltt_time_compare(*(value.v_time), t) < 0) {
- min_pos = mid_pos;
- closest_tree = saved_state_tree;
+ if(tcs->recompute_state_in_seek) {
+ if(tcs->saved_state_available) {
+ saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
+ LTTV_STATE_SAVED_STATES);
+ min_pos = -1;
+ max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
+ mid_pos = max_pos / 2;
+ while(min_pos < max_pos) {
+ type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
+ g_assert(type == LTTV_GOBJECT);
+ saved_state_tree = *((LttvAttribute **)(value.v_gobject));
+ type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME,
+ &value);
+ g_assert(type == LTTV_TIME);
+ if(ltt_time_compare(*(value.v_time), t) < 0) {
+ min_pos = mid_pos;
+ closest_tree = saved_state_tree;
+ }
+ else max_pos = mid_pos - 1;
+
+ mid_pos = (min_pos + max_pos + 1) / 2;
+ }
+
+ /* restore the closest earlier saved state */
+ if(min_pos != -1) lttv_state_restore(tcs, closest_tree);
+
+ /* there is no earlier saved state, restart at T0 */
+ else {
+ restore_init_state(tcs);
+ lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
+ }
+
+ /* There is no saved state yet we want to have it. Restart at T0 */
+ else {
+ restore_init_state(tcs);
+ lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
}
- else max_pos = mid_pos - 1;
- mid_pos = (min_pos + max_pos + 1) / 2;
- }
- if(min_pos == -1) {
+ /* We want to seek quickly without restoring/updating the state */
+ else {
restore_init_state(tcs);
- lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
+ lttv_process_trace_seek_time(&(tcs->parent), t);
}
- else lttv_state_restore(tcs, closest_tree);
}
}