X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fnotification%2Fevent.c;h=d8178eca6fea9e62a4c1f5813704513a7667aea3;hb=56e18c4ce186892c36d7f2cb5078087425e60134;hp=d205e66df95d323a1a10407638104ccd3e9064cf;hpb=d4629a98ce942eb7bb40b2de558e532e61f450b1;p=babeltrace.git diff --git a/lib/graph/notification/event.c b/lib/graph/notification/event.c index d205e66d..d8178eca 100644 --- a/lib/graph/notification/event.c +++ b/lib/graph/notification/event.c @@ -28,292 +28,174 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include #include #include -static -void bt_notification_event_destroy(struct bt_object *obj) +BT_ASSERT_PRE_FUNC +static inline bool event_class_has_trace(struct bt_event_class *event_class) { - struct bt_notification_event *notification = - (struct bt_notification_event *) obj; + struct bt_stream_class *stream_class; - BT_LOGD("Destroying event notification: addr=%p", notification); - BT_LOGD_STR("Putting event."); - BT_PUT(notification->event); - BT_LOGD_STR("Putting clock class priority map."); - BT_PUT(notification->cc_prio_map); - g_free(notification); + stream_class = bt_event_class_borrow_stream_class(event_class); + BT_ASSERT(stream_class); + return bt_stream_class_borrow_trace(stream_class) != NULL; } -static -bt_bool validate_clock_classes(struct bt_notification_event *notif) +BT_HIDDEN +struct bt_notification *bt_notification_event_new( + struct bt_graph *graph) { - /* - * For each clock class found in the notification's clock class - * priority map, make sure the event has a clock value set for - * this clock class. Also make sure that those clock classes - * are part of the trace to which the event belongs. - */ - bt_bool is_valid = BT_TRUE; - - int trace_cc_count; - int cc_prio_map_cc_count; - size_t cc_prio_map_cc_i, trace_cc_i; - struct bt_ctf_clock_value *clock_value = NULL; - struct bt_ctf_clock_class *clock_class = NULL; - struct bt_ctf_event_class *event_class = NULL; - struct bt_ctf_stream_class *stream_class = NULL; - struct bt_ctf_trace *trace = NULL; - - event_class = bt_ctf_event_borrow_event_class(notif->event); - assert(event_class); - stream_class = bt_ctf_event_class_borrow_stream_class(event_class); - assert(stream_class); - trace = bt_ctf_stream_class_borrow_trace(stream_class); - assert(trace); - trace_cc_count = bt_ctf_trace_get_clock_class_count(trace); - assert(trace_cc_count >= 0); - cc_prio_map_cc_count = - bt_clock_class_priority_map_get_clock_class_count( - notif->cc_prio_map); - assert(cc_prio_map_cc_count >= 0); - - for (cc_prio_map_cc_i = 0; cc_prio_map_cc_i < cc_prio_map_cc_count; - cc_prio_map_cc_i++) { - bt_bool found_in_trace = BT_FALSE; - - clock_class = - bt_clock_class_priority_map_get_clock_class_by_index( - notif->cc_prio_map, cc_prio_map_cc_i); - assert(clock_class); - clock_value = bt_ctf_event_get_clock_value(notif->event, - clock_class); - if (!clock_value) { - BT_LOGW("Event has no clock value for a clock class which exists in the notification's clock class priority map: " - "notif-addr=%p, event-addr=%p, " - "event-class-addr=%p, event-class-name=\"%s\", " - "event-class-id=%" PRId64 ", " - "cc-prio-map-addr=%p, " - "clock-class-addr=%p, clock-class-name=\"%s\"", - notif, notif->event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class), - notif->cc_prio_map, clock_class, - bt_ctf_clock_class_get_name(clock_class)); - is_valid = BT_FALSE; - goto end; - } - - for (trace_cc_i = 0; trace_cc_i < trace_cc_count; - trace_cc_i++) { - struct bt_ctf_clock_class *trace_clock_class = - bt_ctf_trace_get_clock_class_by_index(trace, - trace_cc_i); - - assert(trace_clock_class); - bt_put(trace_clock_class); - - if (trace_clock_class == clock_class) { - found_in_trace = BT_TRUE; - break; - } - } - - if (!found_in_trace) { - BT_LOGW("A clock class found in the event notification's clock class priority map does not exist in the notification's event's trace: " - "notif-addr=%p, trace-addr=%p, " - "trace-name=\"%s\", cc-prio-map-addr=%p, " - "clock-class-addr=%p, clock-class-name=\"%s\"", - notif, trace, bt_ctf_trace_get_name(trace), - notif->cc_prio_map, clock_class, - bt_ctf_clock_class_get_name(clock_class)); - is_valid = BT_FALSE; - goto end; - } + struct bt_notification_event *notification = NULL; - BT_PUT(clock_value); - BT_PUT(clock_class); + notification = g_new0(struct bt_notification_event, 1); + if (!notification) { + BT_LOGE_STR("Failed to allocate one event notification."); + goto error; } -end: - bt_put(clock_value); - bt_put(clock_class); - return is_valid; -} + bt_notification_init(¬ification->parent, BT_NOTIFICATION_TYPE_EVENT, + (bt_object_release_func) bt_notification_event_recycle, graph); + goto end; -static -bool event_has_trace(struct bt_ctf_event *event) -{ - struct bt_ctf_event_class *event_class; - struct bt_ctf_stream_class *stream_class; +error: + BT_PUT(notification); - event_class = bt_ctf_event_borrow_event_class(event); - assert(event_class); - stream_class = bt_ctf_event_class_borrow_stream_class(event_class); - assert(stream_class); - return bt_ctf_stream_class_borrow_trace(stream_class) != NULL; +end: + return (void *) notification; } -struct bt_notification *bt_notification_event_create(struct bt_ctf_event *event, - struct bt_clock_class_priority_map *cc_prio_map) +struct bt_notification *bt_notification_event_create( + struct bt_private_connection_private_notification_iterator *notif_iter, + struct bt_event_class *event_class, + struct bt_packet *packet) { struct bt_notification_event *notification = NULL; - struct bt_ctf_event_class *event_class; - - if (!event) { - BT_LOGW_STR("Invalid parameter: event is NULL."); - goto error; - } - - if (cc_prio_map) { - /* Function's reference, released at the end */ - bt_get(cc_prio_map); - } else { - cc_prio_map = bt_clock_class_priority_map_create(); - if (!cc_prio_map) { - BT_LOGE_STR("Cannot create empty clock class priority map."); - goto error; - } - } + struct bt_event *event; + struct bt_graph *graph; - assert(cc_prio_map); - event_class = bt_ctf_event_borrow_event_class(event); - assert(event_class); + BT_ASSERT_PRE_NON_NULL(notif_iter, "Notification iterator"); + BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); + BT_ASSERT_PRE_NON_NULL(packet, "Packet"); BT_LOGD("Creating event notification object: " - "event-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", event-class-id=%" PRId64 ", " - "cc-prio-map-addr=%p", - event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class), cc_prio_map); - - if (!bt_ctf_event_borrow_packet(event)) { - BT_LOGW("Invalid parameter: event has no packet: " - "event-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", " - "event-class-id=%" PRId64, - event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class)); - goto error; - } - - if (!event_has_trace(event)) { - BT_LOGW("Invalid parameter: event has no trace: " - "event-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", " - "event-class-id=%" PRId64, - event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class)); - goto error; - } - - notification = g_new0(struct bt_notification_event, 1); - if (!notification) { - BT_LOGE_STR("Failed to allocate one event notification."); + "event-class-addr=%p, " + "event-class-name=\"%s\", event-class-id=%" PRId64, + event_class, + bt_event_class_get_name(event_class), + bt_event_class_get_id(event_class)); + BT_ASSERT_PRE(event_class_has_trace(event_class), + "Event class is not part of a trace: %!+E", event_class); + event = bt_event_create(event_class, packet); + if (unlikely(!event)) { + BT_LIB_LOGE("Cannot create event from event class: " + "%![event-class-]+E", event_class); goto error; } - bt_notification_init(¬ification->parent, BT_NOTIFICATION_TYPE_EVENT, - bt_notification_event_destroy); - notification->event = bt_get(event); - notification->cc_prio_map = bt_get(cc_prio_map); - if (!validate_clock_classes(notification)) { - BT_LOGW("Invalid event: invalid clock class: " - "event-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", " - "event-class-id=%" PRId64, - event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class)); + /* + * Create notification from pool _after_ we have everything + * (in this case, a valid event object) so that we never have an + * error condition with a non-NULL notification object. + * Otherwise: + * + * * We cannot recycle the notification on error because + * bt_notification_event_recycle() expects a complete + * notification (and the event or clock class priority map + * object could be unset). + * + * * We cannot destroy the notification because we would need + * to notify the graph (pool owner) so that it removes the + * notification from its notification array. + */ + graph = bt_private_connection_private_notification_iterator_borrow_graph( + notif_iter); + notification = (void *) bt_notification_create_from_pool( + &graph->event_notif_pool, graph); + if (unlikely(!notification)) { + /* bt_notification_create_from_pool() logs errors */ goto error; } - BT_LOGD_STR("Freezing event notification's event."); - bt_ctf_event_freeze(notification->event); - BT_LOGD_STR("Freezing event notification's clock class priority map."); - bt_clock_class_priority_map_freeze(notification->cc_prio_map); + BT_ASSERT(!notification->event); + notification->event = event; + bt_packet_set_is_frozen(packet, true); + bt_event_class_freeze(event_class); BT_LOGD("Created event notification object: " "event-addr=%p, event-class-addr=%p, " "event-class-name=\"%s\", event-class-id=%" PRId64 ", " - "cc-prio-map-addr=%p, notif-addr=%p", - event, event_class, - bt_ctf_event_class_get_name(event_class), - bt_ctf_event_class_get_id(event_class), cc_prio_map, + "notif-addr=%p", + notification->event, event_class, + bt_event_class_get_name(event_class), + bt_event_class_get_id(event_class), notification); goto end; error: - BT_PUT(notification); + BT_ASSERT(!notification); + bt_event_destroy(event); end: - bt_put(cc_prio_map); - return ¬ification->parent; + return (void *) notification; } -struct bt_ctf_event *bt_notification_event_get_event( - struct bt_notification *notification) +BT_HIDDEN +void bt_notification_event_destroy(struct bt_notification *notif) { - struct bt_ctf_event *event = NULL; - struct bt_notification_event *event_notification; + struct bt_notification_event *event_notif = (void *) notif; - if (!notification) { - BT_LOGW_STR("Invalid parameter: notification is NULL."); - goto end; - } + BT_LOGD("Destroying event notification: addr=%p", notif); - if (bt_notification_get_type(notification) != - BT_NOTIFICATION_TYPE_EVENT) { - BT_LOGW("Invalid parameter: notification is not an event notification: " - "addr%p, notif-type=%s", - notification, bt_notification_type_string( - bt_notification_get_type(notification))); - goto end; + if (event_notif->event) { + BT_LOGD_STR("Recycling event."); + bt_event_recycle(event_notif->event); } - event_notification = container_of(notification, - struct bt_notification_event, parent); - event = bt_get(event_notification->event); - -end: - return event; + g_free(notif); } -extern struct bt_clock_class_priority_map * -bt_notification_event_get_clock_class_priority_map( - struct bt_notification *notification) +BT_HIDDEN +void bt_notification_event_recycle(struct bt_notification *notif) { - struct bt_clock_class_priority_map *cc_prio_map = NULL; - struct bt_notification_event *event_notification; + struct bt_notification_event *event_notif = (void *) notif; + struct bt_graph *graph; - if (!notification) { - BT_LOGW_STR("Invalid parameter: notification is NULL."); - goto end; - } + BT_ASSERT(event_notif); - if (bt_notification_get_type(notification) != - BT_NOTIFICATION_TYPE_EVENT) { - BT_LOGW("Invalid parameter: notification is not an event notification: " - "addr%p, notif-type=%s", - notification, bt_notification_type_string( - bt_notification_get_type(notification))); - goto end; + if (unlikely(!notif->graph)) { + bt_notification_event_destroy(notif); + return; } + BT_LOGD("Recycling event notification: addr=%p", notif); + bt_notification_reset(notif); + BT_ASSERT(event_notif->event); + BT_LOGD_STR("Recycling event."); + bt_event_recycle(event_notif->event); + event_notif->event = NULL; + graph = notif->graph; + notif->graph = NULL; + bt_object_pool_recycle_object(&graph->event_notif_pool, notif); +} + +struct bt_event *bt_notification_event_borrow_event( + struct bt_notification *notification) +{ + struct bt_notification_event *event_notification; + + BT_ASSERT_PRE_NON_NULL(notification, "Notification"); + BT_ASSERT_PRE_NOTIF_IS_TYPE(notification, BT_NOTIFICATION_TYPE_EVENT); event_notification = container_of(notification, struct bt_notification_event, parent); - cc_prio_map = bt_get(event_notification->cc_prio_map); - -end: - return cc_prio_map; + return event_notification->event; }