X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=f2fd441349f55dae52228ce5ba0faed0b70f8e63;hb=937a4442a7f16b60535a43d88d22dae944430c66;hp=1aaccb5fc2b7423c5ae397720830a78dd334199d;hpb=bd4c3eca908cb5ef8a575848bb35a072bd8ed10a;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 1aaccb5f..f2fd4413 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -21,11 +21,10 @@ #endif #include +#include #include #include -#include #include -#include #include #include @@ -170,6 +169,7 @@ static void init_tracefile_context(LttTracefile *tracefile, tfc->event = lttv_hooks_new(); tfc->event_by_id = lttv_hooks_by_id_new(); tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + tfc->target_pid = -1; } @@ -691,8 +691,6 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, { GTree *pqueue = self->pqueue; - guint fac_id, ev_id, id; - LttvTracefileContext *tfc; LttEvent *e; @@ -703,7 +701,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, //enum read_state last_read_state = LAST_NONE; - gboolean last_ret = FALSE; /* return value of the last hook list called */ + gint last_ret = 0; /* return value of the last hook list called */ /* Get the next event from the pqueue, call its hooks, reinsert in the pqueue the following event from the same tracefile @@ -763,14 +761,24 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, * first pass (not if last read returned end of tracefile) */ count++; - fac_id = ltt_event_facility_id(e); - ev_id = ltt_event_eventtype_id(e); - id = GET_HOOK_ID(fac_id, ev_id); + tfc->target_pid = -1; /* unset target PID */ + /* Hooks : + * return values : 0 : continue read, 1 : go to next position and stop read, + * 2 : stay at the current position and stop read */ last_ret = lttv_hooks_call_merge(tfc->event, tfc, - lttv_hooks_by_id_get(tfc->event_by_id, id), tfc); - - read_ret = ltt_tracefile_read(tfc->tf); + lttv_hooks_by_id_get(tfc->event_by_id, e->event_id), tfc); +#if 0 + /* This is buggy : it won't work well with state computation */ + if(unlikely(last_ret == 2)) { + /* This is a case where we want to stay at this position and stop read. */ + g_tree_insert(pqueue, tfc, tfc); + return count - 1; + } +#endif //0 + read_ret = ltt_tracefile_read(tfc->tf); + + if(likely(!read_ret)) { //g_debug("An event is ready"); tfc->timestamp = ltt_event_time(e); @@ -936,154 +944,104 @@ gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, } - +#if 0 // pmf: temporary disable static LttField * find_field(LttEventType *et, const GQuark field) { - LttType *t; - LttField *f; - guint i, nb; - - GQuark name; - - /* Field is unset */ if(field == 0) return NULL; - f = ltt_eventtype_field(et); - t = ltt_eventtype_type(et); - g_assert(ltt_type_class(t) == LTT_STRUCT); - nb = ltt_type_member_number(t); - for(i = 0 ; i < nb ; i++) { - ltt_type_member_type(t, i, &name); - if(name == field) break; + f = ltt_eventtype_field_by_name(et, field); + if (!f) { + g_warning("Cannot find field %s in event %s.%s", g_quark_to_string(field), + g_quark_to_string(ltt_facility_name(ltt_eventtype_facility(et))), + g_quark_to_string(ltt_eventtype_name(et))); } - g_assert(i < nb); - return ltt_field_member(f, i); -} -LttvTraceHookByFacility *lttv_trace_hook_get_fac(LttvTraceHook *th, - guint facility_id) -{ - return &g_array_index(th->fac_index, LttvTraceHookByFacility, facility_id); + return f; } +#endif -/* Get the first facility corresponding to the name. As the types must be - * compatible, it is relevant to use the field name and sizes of the first - * facility to create data structures and assume the data will be compatible - * thorough the trace */ -LttvTraceHookByFacility *lttv_trace_hook_get_first(LttvTraceHook *th) +struct marker_info *lttv_trace_hook_get_marker(LttTrace *t, LttvTraceHook *th) { - g_assert(th->fac_list->len > 0); - return g_array_index(th->fac_list, LttvTraceHookByFacility*, 0); + return marker_get_info_from_id(t, th->id); } -/* Returns 0 on success, -1 if fails. */ -gint -lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, - GQuark field1, GQuark field2, GQuark field3, LttvHook h, gpointer hook_data, - LttvTraceHook *th) +GArray *lttv_trace_find_hook(LttTrace *t, GQuark marker_name, + GQuark fields[], LttvHook h, gpointer hook_data) { - LttFacility *f; + struct marker_info *info; + GQuark *pfieldname; + struct marker_field *field; + guint16 marker_id; - LttEventType *et, *first_et; + GArray * retval; - GArray *facilities; - - guint i, fac_id, ev_id; - - LttvTraceHookByFacility *thf, *first_thf; - - facilities = ltt_trace_facility_get_by_name(t, facility); - - if(unlikely(facilities == NULL)) goto facility_error; + info = marker_get_info_from_name(t, marker_name); + if(unlikely(info == NULL)) { + return NULL; + } - th->fac_index = g_array_sized_new(FALSE, TRUE, - sizeof(LttvTraceHookByFacility), - NUM_FACILITIES); - th->fac_index = g_array_set_size(th->fac_index, NUM_FACILITIES); + retval = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); - th->fac_list = g_array_sized_new(FALSE, TRUE, - sizeof(LttvTraceHookByFacility*), - facilities->len); - th->fac_list = g_array_set_size(th->fac_list, facilities->len); - fac_id = g_array_index(facilities, guint, 0); - f = ltt_trace_get_facility_by_num(t, fac_id); - et = ltt_facility_eventtype_get_by_name(f, event); - if(unlikely(et == NULL)) goto event_error; - - thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id); - g_array_index(th->fac_list, LttvTraceHookByFacility*, 0) = thf; + /* for each marker with the requested name */ + do { + LttvTraceHook tmpth; + int found; + + marker_id = marker_get_id_from_info(t, info); + + tmpth.h = h; + tmpth.id = marker_id; + tmpth.hook_data = hook_data; + tmpth.fields = g_ptr_array_new(); + + /* for each field requested */ + found = 0; + for(pfieldname = fields; pfieldname != NULL; pfieldname++) { + for_each_marker_field(field, info) { + if(field->name == *pfieldname) { + + found = 1; + g_ptr_array_add(tmpth.fields, field); + break; + } + } + if(!found) { + /* Did not find the one of the fields in this instance of the + marker. Skip it. */ + g_ptr_array_free(tmpth.fields, TRUE); + goto free_retval; + } + } - ev_id = ltt_eventtype_id(et); - - thf->h = h; - thf->id = GET_HOOK_ID(fac_id, ev_id); - thf->f1 = find_field(et, field1); - thf->f2 = find_field(et, field2); - thf->f3 = find_field(et, field3); - thf->hook_data = hook_data; - - first_thf = thf; - first_et = et; + /* all fields were found: add the tracehook to the array */ + g_array_append_val(retval, tmpth); - /* Check for type compatibility too */ - for(i=1;ilen;i++) { - fac_id = g_array_index(facilities, guint, i); - f = ltt_trace_get_facility_by_num(t, fac_id); + info = info->next; + } while(info != NULL); - et = ltt_facility_eventtype_get_by_name(f, event); - if(unlikely(et == NULL)) goto event_error; - - thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id); - g_array_index(th->fac_list, LttvTraceHookByFacility*, i) = thf; - ev_id = ltt_eventtype_id(et); - thf->h = h; - thf->id = GET_HOOK_ID(fac_id, ev_id); - thf->f1 = find_field(et, field1); - if(check_fields_compatibility(first_et, et, - first_thf->f1, thf->f1)) - goto type_error; - - thf->f2 = find_field(et, field2); - if(check_fields_compatibility(first_et, et, - first_thf->f2, thf->f2)) - goto type_error; - - thf->f3 = find_field(et, field3); - if(check_fields_compatibility(first_et, et, - first_thf->f3, thf->f3)) - goto type_error; - thf->hook_data = hook_data; - } - return 0; + if(retval->len) + return retval; -type_error: - goto free; -event_error: - g_error("Event type does not exist for event %s", - g_quark_to_string(event)); - goto free; -facility_error: - g_error("No %s facility", g_quark_to_string(facility)); - goto free; -free: - g_array_free(th->fac_index, TRUE); - g_array_free(th->fac_list, TRUE); - th->fac_index = NULL; - th->fac_list = NULL; - return -1; + free_retval: + g_array_free(retval, TRUE); + return NULL; } -void lttv_trace_hook_destroy(LttvTraceHook *th) +void lttv_trace_hook_destroy(GArray *th) { - g_array_free(th->fac_index, TRUE); - g_array_free(th->fac_list, TRUE); + int i; + for(i=0; ilen; i++) { + g_ptr_array_free(g_array_index(th, LttvTraceHook, i).fields, TRUE); + } + + g_array_free(th, TRUE); } @@ -1248,13 +1206,15 @@ gint lttv_traceset_context_pos_pos_compare( const LttvTracesetContextPosition *pos2) { int i, j; - int ret; + int ret = 0; - if(pos1->tfcp->len == 0) { - if(pos2->tfcp->len == 0) return 0; - else return 1; + if(ltt_time_compare(pos1->timestamp, ltt_time_infinite) == 0) { + if(ltt_time_compare(pos2->timestamp, ltt_time_infinite) == 0) + return 0; + else + return 1; } - if(pos2->tfcp->len == 0) + if(ltt_time_compare(pos2->timestamp, ltt_time_infinite) == 0) return -1; for(i=0;itfcp->len;i++) { @@ -1335,7 +1295,13 @@ struct seek_back_data { guint events_found; guint n; /* number of events requested */ GPtrArray *array; /* array of LttvTracesetContextPositions pointers */ - LttvFilter *filter; + LttvFilter *filter1; + LttvFilter *filter2; + LttvFilter *filter3; + gpointer data; + check_handler *check; + gboolean *stop_flag; + guint raw_event_count; }; static gint seek_back_event_hook(void *hook_data, void* call_data) @@ -1345,15 +1311,35 @@ static gint seek_back_event_hook(void *hook_data, void* call_data) LttvTracesetContext *tsc = tfc->t_context->ts_context; LttvTracesetContextPosition *pos; - if(sd->filter != NULL && sd->filter->head != NULL) { - if(!lttv_filter_tree_parse(sd->filter->head, + if(sd->check && sd->check(sd->raw_event_count, sd->stop_flag, sd->data)) + return TRUE; + sd->raw_event_count++; + + if(sd->filter1 != NULL && sd->filter1->head != NULL && + !lttv_filter_tree_parse(sd->filter1->head, ltt_tracefile_get_event(tfc->tf), tfc->tf, tfc->t_context->t, - tfc)) - return FALSE; + tfc,NULL,NULL)) { + return FALSE; } - + if(sd->filter2 != NULL && sd->filter2->head != NULL && + !lttv_filter_tree_parse(sd->filter2->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc,NULL,NULL)) { + return FALSE; + } + if(sd->filter3 != NULL && sd->filter3->head != NULL && + !lttv_filter_tree_parse(sd->filter3->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc,NULL,NULL)) { + return FALSE; + } + pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array, sd->first_event); @@ -1396,7 +1382,12 @@ static gint seek_back_event_hook(void *hook_data, void* call_data) guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, guint n, LttTime first_offset, seek_time_fct time_seeker, - LttvFilter *filter) + check_handler *check, + gboolean *stop_flag, + LttvFilter *filter1, + LttvFilter *filter2, + LttvFilter *filter3, + gpointer data) { if(lttv_traceset_number(self->ts) == 0) return 0; g_assert(ltt_time_compare(first_offset, ltt_time_zero) != 0); @@ -1409,6 +1400,7 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, LttvTracesetContextPosition *saved_pos = lttv_traceset_context_position_new(self); LttTime time; + LttTime asked_time; LttTime time_offset; struct seek_back_data sd; LttvHooks *hooks = lttv_hooks_new(); @@ -1416,8 +1408,14 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, sd.first_event = 0; sd.events_found = 0; sd.array = g_ptr_array_sized_new(n); - sd.filter = filter; + sd.filter1 = filter1; + sd.filter2 = filter2; + sd.filter3 = filter3; + sd.data = data; sd.n = n; + sd.check = check; + sd.stop_flag = stop_flag; + sd.raw_event_count = 0; g_ptr_array_set_size(sd.array, n); for(i=0;itime_span.end_time) > 0) { time = self->time_span.end_time; } + asked_time = time; time_offset = first_offset; lttv_hooks_add(hooks, seek_back_event_hook, &sd, LTTV_PRIO_DEFAULT); @@ -1439,14 +1438,15 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, while(1) { /* stop criteria : - n events found - * - time < beginning of trace */ - if(ltt_time_compare(time, self->time_span.start_time) < 0) break; + * - asked_time < beginning of trace */ + if(ltt_time_compare(asked_time, self->time_span.start_time) < 0) break; lttv_traceset_context_position_copy(end_pos, next_iter_end_pos); /* We must seek the traceset back to time - time_offset */ /* this time becomes the new reference time */ time = ltt_time_sub(time, time_offset); + asked_time = time; time_seeker(self, time); lttv_traceset_context_position_save(self, next_iter_end_pos); @@ -1521,7 +1521,13 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, struct seek_forward_data { guint event_count; /* event counter */ guint n; /* requested number of events to jump over */ - LttvFilter *filter; + LttvFilter *filter1; + LttvFilter *filter2; + LttvFilter *filter3; + gpointer data; + check_handler *check; + gboolean *stop_flag; + guint raw_event_count; /* event counter */ }; static gint seek_forward_event_hook(void *hook_data, void* call_data) @@ -1529,24 +1535,42 @@ static gint seek_forward_event_hook(void *hook_data, void* call_data) struct seek_forward_data *sd = (struct seek_forward_data*)hook_data; LttvTracefileContext *tfc = (LttvTracefileContext*)call_data; - if(sd->filter != NULL) { - if(!lttv_filter_tree_parse(sd->filter->head, + if(sd->check && sd->check(sd->raw_event_count, sd->stop_flag, sd->data)) + return TRUE; + sd->raw_event_count++; + + if(sd->filter1 != NULL && sd->filter1->head != NULL && + !lttv_filter_tree_parse(sd->filter1->head, ltt_tracefile_get_event(tfc->tf), tfc->tf, tfc->t_context->t, - tfc)) - return FALSE; + tfc,NULL,NULL)) { + return FALSE; + } + if(sd->filter2 != NULL && sd->filter2->head != NULL && + !lttv_filter_tree_parse(sd->filter2->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc,NULL,NULL)) { + return FALSE; + } + if(sd->filter3 != NULL && sd->filter3->head != NULL && + !lttv_filter_tree_parse(sd->filter3->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc,NULL,NULL)) { + return FALSE; } - - sd->event_count++; + sd->event_count++; if(sd->event_count >= sd->n) - return TRUE; - else - return FALSE; + return TRUE; } -/* Seek back n events forward from the current position +/* Seek back n events forward from the current position (1 to n) + * 0 is ok too, but it will actually do nothing. * * Parameters : * @self the trace set context @@ -1556,12 +1580,27 @@ static gint seek_forward_event_hook(void *hook_data, void* call_data) * returns : the number of events jumped over (may be less than requested if end * of traceset reached) */ guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self, - guint n, LttvFilter *filter) + guint n, + check_handler *check, + gboolean *stop_flag, + LttvFilter *filter1, + LttvFilter *filter2, + LttvFilter *filter3, + gpointer data) { struct seek_forward_data sd; sd.event_count = 0; sd.n = n; - sd.filter = filter; + sd.filter1 = filter1; + sd.filter2 = filter2; + sd.filter3 = filter3; + sd.data = data; + sd.check = check; + sd.stop_flag = stop_flag; + sd.raw_event_count = 0; + + if(sd.event_count >= sd.n) return sd.event_count; + LttvHooks *hooks = lttv_hooks_new(); lttv_hooks_add(hooks, seek_forward_event_hook, &sd, LTTV_PRIO_DEFAULT); @@ -1575,7 +1614,9 @@ guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self, G_MAXUINT, NULL); /* Here, our position is either the end of traceset, or the exact position - * after n events : leave it like this. */ + * after n events : leave it like this. This might be placed on an event that + * will be filtered out, we don't care : all we know is that the following + * event filtered in will be the right one. */ lttv_process_traceset_end(self, NULL, NULL, NULL, hooks, NULL);