From 791dffa6f060fe553546337fde7ed58a16f41178 Mon Sep 17 00:00:00 2001 From: compudj Date: Tue, 13 Sep 2005 00:15:26 +0000 Subject: [PATCH] free bugfix git-svn-id: http://ltt.polymtl.ca/svn@1171 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/ltt/ltt-private.h | 7 +++- ltt/branches/poly/ltt/tracefile.c | 59 ++++++++++++++++++++++------- ltt/branches/poly/lttv/lttv/state.c | 39 +++++++++++-------- ltt/branches/poly/lttv/lttv/state.h | 3 +- 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/ltt/branches/poly/ltt/ltt-private.h b/ltt/branches/poly/ltt/ltt-private.h index 1bbe0a10..9e263c56 100644 --- a/ltt/branches/poly/ltt/ltt-private.h +++ b/ltt/branches/poly/ltt/ltt-private.h @@ -184,6 +184,8 @@ struct ltt_trace_header_0_4 { uint8_t has_heartbeat; uint8_t has_alignment; /* Event header alignment */ uint8_t has_tsc; + uint64_t start_freq; + uint64_t start_tsc; uint64_t start_monotonic; struct timespec start_time; } LTT_PACKED_STRUCT; @@ -354,7 +356,8 @@ typedef struct _LttBuffer { /* Timekeeping */ uint64_t tsc; /* Current timestamp counter */ uint64_t freq; /* Frequency in khz */ - double nsecs_per_cycle; /* Precalculated from freq */ + //double nsecs_per_cycle; /* Precalculated from freq */ + guint32 cyc2ns_scale; } LttBuffer; struct _LttTracefile{ @@ -411,6 +414,8 @@ struct _LttTrace{ guint8 has_heartbeat; guint8 has_alignment; guint8 has_tsc; + uint64_t start_freq; + uint64_t start_tsc; uint64_t start_monotonic; LttTime start_time; diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index 6500a2d2..470eb5e0 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -93,7 +93,10 @@ static inline void preset_field_type_size(LttTracefile *tf, static gint map_block(LttTracefile * tf, guint block_num); /* calculate nsec per cycles for current block */ -static double calc_nsecs_per_cycle(LttTracefile * t); +#if 0 +static guint32 calc_nsecs_per_cycle(LttTracefile * t); +static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles); +#endif //0 /* go to the next event */ static int ltt_seek_next_event(LttTracefile *tf); @@ -248,6 +251,10 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t) sizeof(struct ltt_block_start_header) + sizeof(struct ltt_trace_header_0_4); if(t) { + t->start_freq = ltt_get_uint64(LTT_GET_BO(tf), + &vheader->start_freq); + t->start_tsc = ltt_get_uint64(LTT_GET_BO(tf), + &vheader->start_tsc); t->start_monotonic = ltt_get_uint64(LTT_GET_BO(tf), &vheader->start_monotonic); t->start_time = ltt_get_time(LTT_GET_BO(tf), @@ -1523,10 +1530,12 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event) g_assert(tf->trace->has_tsc); - time = ltt_time_from_uint64( - (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count) * - tf->buffer.nsecs_per_cycle); - time = ltt_time_add(tf->buffer.begin.timestamp, time); +// time = ltt_time_from_uint64( +// cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count))); + time = ltt_time_from_uint64((tf->buffer.tsc - tf->trace->start_tsc) * 1000000 + / (double)tf->trace->start_freq); + //time = ltt_time_add(tf->buffer.begin.timestamp, time); + time = ltt_time_add(tf->trace->start_time, time); return time; } @@ -1741,25 +1750,35 @@ static gint map_block(LttTracefile * tf, guint block_num) header = (struct ltt_block_start_header*)tf->buffer.head; +#if 0 tf->buffer.begin.timestamp = ltt_time_add( ltt_time_from_uint64( ltt_get_uint64(LTT_GET_BO(tf), &header->begin.timestamp) - tf->trace->start_monotonic), tf->trace->start_time); +#endif //0 //g_debug("block %u begin : %lu.%lu", block_num, // tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec); tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf), &header->begin.cycle_count); tf->buffer.begin.freq = ltt_get_uint64(LTT_GET_BO(tf), &header->begin.freq); + tf->buffer.begin.timestamp = ltt_time_add( + ltt_time_from_uint64( + (tf->buffer.begin.cycle_count + - tf->trace->start_tsc) * 1000000 + / (double)tf->trace->start_freq), + tf->trace->start_time); +#if 0 + tf->buffer.end.timestamp = ltt_time_add( ltt_time_from_uint64( ltt_get_uint64(LTT_GET_BO(tf), &header->end.timestamp) - tf->trace->start_monotonic), tf->trace->start_time); - +#endif //0 //g_debug("block %u end : %lu.%lu", block_num, // tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec); tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf), @@ -1768,7 +1787,13 @@ static gint map_block(LttTracefile * tf, guint block_num) &header->end.freq); tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf), &header->lost_size); - + tf->buffer.end.timestamp = ltt_time_add( + ltt_time_from_uint64( + (tf->buffer.end.cycle_count + - tf->trace->start_tsc) * 1000000 + / (double)tf->trace->start_freq), + tf->trace->start_time); + tf->buffer.tsc = tf->buffer.begin.cycle_count; tf->event.tsc = tf->buffer.tsc; tf->buffer.freq = tf->buffer.begin.freq; @@ -1782,7 +1807,8 @@ static gint map_block(LttTracefile * tf, guint block_num) /* Now that the buffer is mapped, calculate the time interpolation for the * block. */ - tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf); +// tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf); + //tf->buffer.cyc2ns_scale = calc_nsecs_per_cycle(tf); /* Make the current event point to the beginning of the buffer : * it means that the event read must get the first event. */ @@ -1931,7 +1957,7 @@ error: return ENOPROTOOPT; } - +#if 0 /***************************************************************************** *Function name * calc_nsecs_per_cycle : calculate nsecs per cycle for current block @@ -1942,15 +1968,22 @@ error: ****************************************************************************/ /* from timer_tsc.c */ #define CYC2NS_SCALE_FACTOR 10 -static double calc_nsecs_per_cycle(LttTracefile * tf) +static guint32 calc_nsecs_per_cycle(LttTracefile * tf) { //return 1e6 / (double)tf->buffer.freq; - guint64 cpu_mhz = tf->buffer.freq / 1000; - guint64 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; + guint32 cpu_mhz = tf->buffer.freq / 1000; + guint32 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; - return cyc2ns_scale >> CYC2NS_SCALE_FACTOR; + return cyc2ns_scale; // return 1e6 / (double)tf->buffer.freq; } + +static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles) +{ + return (cycles * tf->buffer.cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} +#endif //0 + #if 0 void setFieldsOffset(LttTracefile *tf, LttEventType *evT,void *evD) { diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 56552b22..52815dd9 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -85,7 +85,8 @@ LttvProcessStatus LTTV_STATE_EXIT, LTTV_STATE_ZOMBIE, LTTV_STATE_WAIT, - LTTV_STATE_RUN; + LTTV_STATE_RUN, + LTTV_STATE_DEAD; static GQuark LTTV_STATE_TRACEFILES, @@ -1211,18 +1212,16 @@ static gboolean schedchange(void *hook_data, void *call_data) if(unlikely(process->state->s == LTTV_STATE_EXIT)) { process->state->s = LTTV_STATE_ZOMBIE; + process->state->change = s->parent.timestamp; } else { if(unlikely(state_out == 0)) process->state->s = LTTV_STATE_WAIT_CPU; else process->state->s = LTTV_STATE_WAIT; - } /* FIXME : we do not remove process here, because the kernel - * still has them : they may be zombies. We need to know - * exactly when release_task is executed on the PID to - * know when the zombie is destroyed. - */ - //else - // exit_process(s, process); - - process->state->change = s->parent.timestamp; + process->state->change = s->parent.timestamp; + } + + if(state_out == 32) + exit_process(s, process); /* EXIT_DEAD */ + /* see sched.h for states */ } process = ts->running_process[cpu] = lttv_state_find_process_or_create( @@ -1263,7 +1262,7 @@ static gboolean process_fork(void *hook_data, void *call_data) * in a SMP case where we don't have enough precision on the clocks. * * Test reenabled after precision fixes on time. (Mathieu) */ - +#if 0 zombie_process = lttv_state_find_process(ts, ANY_CPU, child_pid); if(unlikely(zombie_process != NULL)) { @@ -1278,7 +1277,7 @@ static gboolean process_fork(void *hook_data, void *call_data) exit_process(s, zombie_process); } - +#endif //0 g_assert(process->pid != child_pid); // FIXME : Add this test in the "known state" section // g_assert(process->pid == parent_pid); @@ -1288,10 +1287,13 @@ static gboolean process_fork(void *hook_data, void *call_data) child_pid, &s->parent.timestamp); } else { /* The process has already been created : due to time imprecision between - * multiple CPUs : it has been scheduled in before creation. + * multiple CPUs : it has been scheduled in before creation. Note that we + * shouldn't have this kind of imprecision. * * Simply put a correct parent. */ + g_assert(0); /* This is a problematic case : the process has been created + before the fork event */ child_process->ppid = process->pid; } @@ -1346,15 +1348,21 @@ static gboolean process_free(void *hook_data, void *call_data) //Clearly due to time imprecision, we disable it. (Mathieu) //If this weird case happen, we have no choice but to put the //Currently running process on the cpu to 0. + //I re-enable it following time precision fixes. (Mathieu) + //Well, in the case where an process is freed by a process on another CPU + //and still scheduled, it happens that this is the schedchange that will + //drop the last reference count. Do not free it here! guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t); guint i; for(i=0; i< num_cpus; i++) { //g_assert(process != ts->running_process[i]); if(process == ts->running_process[i]) { - ts->running_process[i] = lttv_state_find_process(ts, i, 0); + //ts->running_process[i] = lttv_state_find_process(ts, i, 0); + break; } } - exit_process(s, process); + if(i == num_cpus) /* process is not scheduled */ + exit_process(s, process); } return FALSE; @@ -2124,6 +2132,7 @@ static void module_init() LTTV_STATE_ZOMBIE = g_quark_from_string("zombie"); LTTV_STATE_WAIT = g_quark_from_string("wait for I/O"); LTTV_STATE_RUN = g_quark_from_string("running"); + LTTV_STATE_DEAD = g_quark_from_string("dead"); LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles"); LTTV_STATE_PROCESSES = g_quark_from_string("processes"); LTTV_STATE_PROCESS = g_quark_from_string("process"); diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h index 9d1598b4..69f35edf 100644 --- a/ltt/branches/poly/lttv/lttv/state.h +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -168,7 +168,8 @@ extern LttvProcessStatus LTTV_STATE_EXIT, LTTV_STATE_ZOMBIE, LTTV_STATE_WAIT, - LTTV_STATE_RUN; + LTTV_STATE_RUN, + LTTV_STATE_DEAD; typedef struct _LttvExecutionState { -- 2.34.1