*
* Complete rewrite from the original version made by XangXiu Yang.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
*
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
void ltt_update_event_size(LttTracefile *tf);
-void precompute_offsets(LttTracefile *tf, LttEventType *event);
+void precompute_offsets(LttFacility *fac, LttEventType *event);
#if 0
/* Functions to parse system.xml file (using glib xml parser) */
t->ltt_minor_version = any->minor_version;
t->flight_recorder = any->flight_recorder;
t->has_heartbeat = any->has_heartbeat;
- t->has_tsc = any->has_tsc;
+ t->freq_scale = any->freq_scale;
}
return 1;
}
break;
- case 6:
+ case 7:
{
- struct ltt_trace_header_0_5 *vheader =
- (struct ltt_trace_header_0_5 *)header;
+ struct ltt_trace_header_0_7 *vheader =
+ (struct ltt_trace_header_0_7 *)header;
tf->buffer_header_size =
sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_0_5);
+ + sizeof(struct ltt_trace_header_0_7);
if(t) {
t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
&vheader->start_freq);
const gchar *text;
guint textlen;
gint err;
+ gint arch_spec;
+ gint fac_name_len;
text = g_quark_to_string(t->pathname);
textlen = strlen(text);
strcat(desc_file_name, text);
text = g_quark_to_string(f->name);
- textlen+=strlen(text);
+ fac_name_len = strlen(text);
+ textlen+=fac_name_len;
if(textlen >= PATH_MAX) goto name_error;
strcat(desc_file_name, text);
+
+ /* arch specific facilities are named like this : name_arch */
+ if(fac_name_len+1 < sizeof("_arch"))
+ arch_spec = 0;
+ else {
+ if(!strcmp(&text[fac_name_len+1-sizeof("_arch")], "_arch"))
+ arch_spec = 1;
+ else
+ arch_spec = 0;
+ }
+
#if 0
text = "_";
textlen+=strlen(text);
textlen=strlen(desc_file_name);
#endif //0
+
+ if(arch_spec) {
+ switch(t->arch_type) {
+ case LTT_ARCH_TYPE_I386:
+ text = "_i386";
+ break;
+ case LTT_ARCH_TYPE_PPC:
+ text = "_ppc";
+ break;
+ case LTT_ARCH_TYPE_SH:
+ text = "_sh";
+ break;
+ case LTT_ARCH_TYPE_S390:
+ text = "_s390";
+ break;
+ case LTT_ARCH_TYPE_MIPS:
+ text = "_mips";
+ break;
+ case LTT_ARCH_TYPE_ARM:
+ text = "_arm";
+ break;
+ case LTT_ARCH_TYPE_PPC64:
+ text = "_ppc64";
+ break;
+ case LTT_ARCH_TYPE_X86_64:
+ text = "_x86_64";
+ break;
+ default:
+ g_error("Trace from unsupported architecture.");
+ }
+ textlen+=strlen(text);
+ if(textlen >= PATH_MAX) goto name_error;
+ strcat(desc_file_name, text);
+ }
+
text = ".xml";
textlen+=strlen(text);
if(textlen >= PATH_MAX) goto name_error;
struct LttFacilityLoad *fac_load_data;
struct LttStateDumpFacilityLoad *fac_state_dump_load_data;
char *fac_name;
+ void *pos;
// FIXME align
switch((enum ltt_core_events)tf->event.event_id) {
fac_name = (char*)(tf->event.data);
g_debug("Doing LTT_EVENT_FACILITY_LOAD of facility %s",
fac_name);
- fac_load_data =
- (struct LttFacilityLoad *)
- (tf->event.data + strlen(fac_name) + 1);
+ pos = (tf->event.data + strlen(fac_name) + 1);
+ pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment);
+ fac_load_data = (struct LttFacilityLoad *)pos;
+
fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id));
/* facility may already exist if trace is paused/unpaused */
/* Preset the field offsets */
for(i=0; i<fac->events->len; i++){
et = &g_array_index(fac->events, LttEventType, i);
- precompute_offsets(tf, et);
+ precompute_offsets(fac, et);
}
fac->exists = 1;
fac_name = (char*)(tf->event.data);
g_debug("Doing LTT_EVENT_STATE_DUMP_FACILITY_LOAD of facility %s",
fac_name);
- fac_state_dump_load_data =
- (struct LttStateDumpFacilityLoad *)
- (tf->event.data + strlen(fac_name) + 1);
+ pos = (tf->event.data + strlen(fac_name) + 1);
+ pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment);
+ fac_state_dump_load_data = (struct LttStateDumpFacilityLoad *)pos;
+
fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
ltt_get_uint32(LTT_GET_BO(tf), &fac_state_dump_load_data->id));
/* facility may already exist if trace is paused/unpaused */
/* Preset the field offsets */
for(i=0; i<fac->events->len; i++){
et = &g_array_index(fac->events, LttEventType, i);
- precompute_offsets(tf, et);
+ precompute_offsets(fac, et);
}
fac->exists = 1;
tf->event.offset = ep->offset;
+ /* Put back the event real tsc */
+ tf->event.tsc = ep->tsc;
+ tf->buffer.tsc = ep->tsc;
+
err = ltt_tracefile_read_update_event(tf);
if(err) goto fail;
err = ltt_tracefile_read_op(tf);
{
LttTime time;
- g_assert(tf->trace->has_tsc);
-
// time = ltt_time_from_uint64(
// cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
time = ltt_time_from_uint64(
- (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0
+ (double)(tf->buffer.tsc - tf->trace->start_tsc)
+ * (1000000000.0 / tf->trace->freq_scale)
/ (double)tf->trace->start_freq);
//time = ltt_time_add(tf->buffer.begin.timestamp, time);
time = ltt_time_add(tf->trace->start_time_from_tsc, time);
/* Align the head */
pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
- if(tf->trace->has_tsc) {
- if(tf->trace->has_heartbeat) {
- event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf),
- pos);
- /* 32 bits -> 64 bits tsc */
- /* note : still works for seek and non seek cases. */
- if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
- tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
- + 0x100000000ULL)
- | (guint64)event->time.timestamp;
- event->tsc = tf->buffer.tsc;
- } else {
- /* no overflow */
- tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL)
- | (guint64)event->time.timestamp;
- event->tsc = tf->buffer.tsc;
- }
- pos += sizeof(guint32);
- } else {
- event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
- tf->buffer.tsc = event->tsc;
- pos += sizeof(guint64);
- }
-
- event->event_time = ltt_interpolate_time(tf, event);
- } else {
- event->time.delta.tv_sec = 0;
- event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf),
- pos) * NSEC_PER_USEC;
- tf->buffer.tsc = 0;
- event->tsc = tf->buffer.tsc;
-
- event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
- event->time.delta);
- pos += sizeof(guint32);
- }
-
+ if(tf->trace->has_heartbeat) {
+ event->timestamp = ltt_get_uint32(LTT_GET_BO(tf),
+ pos);
+ /* 32 bits -> 64 bits tsc */
+ /* note : still works for seek and non seek cases. */
+ if(event->timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
+ tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+ + 0x100000000ULL)
+ | (guint64)event->timestamp;
+ event->tsc = tf->buffer.tsc;
+ } else {
+ /* no overflow */
+ tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+ | (guint64)event->timestamp;
+ event->tsc = tf->buffer.tsc;
+ }
+ pos += sizeof(guint32);
+ } else {
+ event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
+ tf->buffer.tsc = event->tsc;
+ pos += sizeof(guint64);
+ }
+ event->event_time = ltt_interpolate_time(tf, event);
event->facility_id = *(guint8*)pos;
pos += sizeof(guint8);
case LTT_EVENT_FACILITY_LOAD:
size = strlen((char*)tf->event.data) + 1;
//g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
+ size += ltt_align(size, sizeof(guint32), tf->has_alignment);
size += sizeof(struct LttFacilityLoad);
break;
case LTT_EVENT_FACILITY_UNLOAD:
break;
case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
size = strlen((char*)tf->event.data) + 1;
+ size += ltt_align(size, sizeof(guint32), tf->has_alignment);
//g_debug("Update Event facility load state dump of facility %s",
// (char*)tf->event.data);
size += sizeof(struct LttStateDumpFacilityLoad);
}
/* Compute the dynamic offsets */
- compute_offsets(tf, event_type, &size, tf->event.data);
+ compute_offsets(tf, f, event_type, &size, tf->event.data);
//g_debug("Event root field : f.e %hhu.%hhu size %zd",
// tf->event.facility_id,
tf->event.data_size = size;
/* Check consistency between kernel and LTTV structure sizes */
+ if(tf->event.event_size == 0xFFFF) {
+ /* Event size too big to fit in the event size field */
+ tf->event.event_size = tf->event.data_size;
+ }
g_assert(tf->event.data_size == tf->event.event_size);
return;
*Function name
* get_alignment : Get the alignment needed for a field.
*Input params
- * tf : tracefile
* field : field
*
* returns : The size on which it must be aligned.
*
****************************************************************************/
-off_t get_alignment(LttTracefile *tf, LttField *field)
+off_t get_alignment(LttField *field)
{
LttType *type = &field->field_type;
g_assert(type->fields->len == 1);
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- return get_alignment(tf, child);
+ return get_alignment(child);
}
break;
case LTT_SEQUENCE:
off_t localign = 0;
LttField *child = &g_array_index(type->fields, LttField, 0);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
child = &g_array_index(type->fields, LttField, 1);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
return localign;
}
for(i=0; i<type->fields->len; i++) {
LttField *child = &g_array_index(type->fields, LttField, i);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
}
return localign;
}
*
****************************************************************************/
-void field_compute_static_size(LttTracefile *tf, LttField *field)
+void field_compute_static_size(LttFacility *fac, LttField *field)
{
LttType *type = &field->field_type;
g_assert(type->fields->len == 1);
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
if(child->field_size != 0) {
field->field_size = type->size * child->field_size;
{
off_t local_offset = 0;
LttField *child = &g_array_index(type->fields, LttField, 1);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
field->field_size = 0;
type->size = 0;
if(child->field_size != 0) {
guint i;
for(i=0;i<type->fields->len;i++) {
LttField *child = &g_array_index(type->fields, LttField, i);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
if(child->field_size != 0) {
- type->size += ltt_align(type->size, get_alignment(tf, child),
- tf->has_alignment);
+ type->size += ltt_align(type->size, get_alignment(child),
+ fac->alignment);
type->size += child->field_size;
} else {
/* As soon as we find a child with variable size, we have
*Function name
* precompute_fields_offsets : set the precomputable offset of the fields
*Input params
- * tf : tracefile
+ * fac : facility
* field : the field
* offset : pointer to the current offset, must be incremented
*
****************************************************************************/
-gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
+gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
{
LttType *type = &field->field_type;
case LTT_OFF_T:
case LTT_FLOAT:
case LTT_ENUM:
+ g_assert(field->field_size != 0);
/* Align offset on type size */
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
LttField *child;
guint ret;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
child = &g_array_index(type->fields, LttField, 0);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
g_assert(ret == 0); /* Seq len cannot have variable len */
child = &g_array_index(type->fields, LttField, 1);
- *offset += ltt_align(*offset, get_alignment(tf, child),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(child),
+ fac->alignment);
field->array_offset = *offset;
- /* Set the offset position at position 0 */
- ret = precompute_fields_offsets(tf, child, offset);
+ /* Let the child be variable. */
+ //ret = precompute_fields_offsets(fac, child, offset);
/* Cannot precompute fields offsets of sequence members, and has
* variable length. */
guint i;
gint ret=0;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
for(i=0; i< type->fields->len; i++) {
child = &g_array_index(type->fields, LttField, i);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
if(ret) break;
}
guint i;
gint ret=0;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
for(i=0; i< type->fields->len; i++) {
*offset = field->offset_root;
child = &g_array_index(type->fields, LttField, i);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
if(ret) break;
}
* event : event type
*
****************************************************************************/
-void precompute_offsets(LttTracefile *tf, LttEventType *event)
+void precompute_offsets(LttFacility *fac, LttEventType *event)
{
guint i;
off_t offset = 0;
* arrays, struct and unions, which is not done by the parser */
for(i=0; i<event->fields->len; i++) {
LttField *field = &g_array_index(event->fields, LttField, i);
- field_compute_static_size(tf, field);
+ field_compute_static_size(fac, field);
}
/* Precompute all known offsets */
for(i=0; i<event->fields->len; i++) {
LttField *field = &g_array_index(event->fields, LttField, i);
- ret = precompute_fields_offsets(tf, field, &offset);
+ ret = precompute_fields_offsets(fac, field, &offset);
if(ret) break;
}
}
different = 1;
goto end;
}
+ if(type1->network != type2->network) {
+ different = 1;
+ goto end;
+ }
switch(type1->type_class) {
case LTT_INT_FIXED: