babeltrace_cl.c 9.15 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "babeltrace_cl.h"

/*
 * Prints a line for `message`, if it's an event message, to the
 * standard output.
 */
//static
//void print_event(struct opencl_dispatch *opencl_dispatch, struct opencl_callbacks *opencl_callbacks, const bt_event *event)
//{
//    const bt_event_class *event_class = bt_event_borrow_class_const(event);
//
//    /* Get the number of payload field members */
//    const bt_field *payload_field =
//        bt_event_borrow_payload_field_const(event);
//    uint64_t member_count = bt_field_class_structure_get_member_count(
//        bt_field_borrow_class_const(payload_field));
//
//    /* Write a corresponding line to the standard output */
//    printf("%s (id: %" PRIu64 ") (%" PRIu64 " payload member%s)\n",
//        bt_event_class_get_name(event_class),
//        bt_event_class_get_id(event_class),
//        member_count, member_count == 1 ? "" : "s");
//}

Thomas Applencourt's avatar
Thomas Applencourt committed
25
26
27
28
struct babeltrace_cl_event_callbacks * opencl_create_event_callbacks(const char *name) {
    intptr_t mem = (intptr_t)calloc(1, sizeof(struct babeltrace_cl_event_callbacks) + strlen(name) + 1);
    struct babeltrace_cl_event_callbacks * callbacks = (struct babeltrace_cl_event_callbacks *)mem;
    callbacks->name = (const char *)(mem + sizeof(struct babeltrace_cl_event_callbacks));
29
30
31
32
33
    strcpy((char *)(callbacks->name), name);
    utarray_new(callbacks->callbacks, &ut_ptr_icd);
    return callbacks;
}

Thomas Applencourt's avatar
Thomas Applencourt committed
34
35
void babeltrace_cl_register_dispatcher(struct babeltrace_cl_dispatch *opencl_dispatch, const char *name, babeltrace_cl_dispatcher_t *dispatcher) {
    struct babeltrace_cl_event_callbacks *callbacks = NULL;
36
37
38
39
40
41
42
43
    HASH_FIND_STR(opencl_dispatch->event_callbacks, name, callbacks);
    if (!callbacks) {
        callbacks = opencl_create_event_callbacks(name);
        HASH_ADD_KEYPTR(hh, opencl_dispatch->event_callbacks, callbacks->name, strlen(callbacks->name), callbacks);
    }
    callbacks->dispatcher = dispatcher;
}

Thomas Applencourt's avatar
Thomas Applencourt committed
44
45
void babeltrace_cl_register_callback(struct babeltrace_cl_dispatch *opencl_dispatch, const char *name, void *func) {
    struct babeltrace_cl_event_callbacks *callbacks;
46
47
48
49
50
51
52
53
    HASH_FIND_STR(opencl_dispatch->event_callbacks, name, callbacks);
    if (!callbacks) {
        callbacks = opencl_create_event_callbacks(name);
        HASH_ADD_STR(opencl_dispatch->event_callbacks, name, callbacks);
    }
    if (func)
        utarray_push_back(callbacks->callbacks, &func);
}
54
55
56
57
58

/*
 * Initializes the sink component.
 */
static
59
bt_component_class_initialize_method_status opencl_dispatch_initialize(
60
61
62
63
64
        bt_self_component_sink *self_component_sink,
        bt_self_component_sink_configuration *configuration,
        const bt_value *params, void *initialize_method_data)
{
    /* Allocate a private data structure */
Thomas Applencourt's avatar
Thomas Applencourt committed
65
    struct babeltrace_cl_dispatch *opencl_dispatch = calloc(1, sizeof(struct babeltrace_cl_dispatch));
66
67
68
69

    /* Set the component's user data to our private data structure */
    bt_self_component_set_data(
        bt_self_component_sink_as_self_component(self_component_sink),
70
        opencl_dispatch);
71
72
73
74
75
76
77
78
79
80
81
82

    /*
     * Add an input port named `in` to the sink component.
     *
     * This is needed so that this sink component can be connected to a
     * filter or a source component. With a connected upstream
     * component, this sink component can create a message iterator
     * to consume messages.
     */
    bt_self_component_sink_add_input_port(self_component_sink,
        "in", NULL, NULL);

Thomas Applencourt's avatar
Thomas Applencourt committed
83
    init_babeltrace_cl_dispatcher(opencl_dispatch);
84
85
86
87
88
89
90
    return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
}

/*
 * Finalizes the sink component.
 */
static
91
void opencl_dispatch_finalize(bt_self_component_sink *self_component_sink)
92
93
{
    /* Retrieve our private data from the component's user data */
Thomas Applencourt's avatar
Thomas Applencourt committed
94
    struct babeltrace_cl_dispatch *opencl_dispatch = bt_self_component_get_data(
95
96
        bt_self_component_sink_as_self_component(self_component_sink));

Thomas Applencourt's avatar
Thomas Applencourt committed
97
    struct babeltrace_cl_callbacks *s, *tmp;
98
99
100
101
    HASH_ITER(hh, opencl_dispatch->callbacks, s, tmp) {
      HASH_DEL(opencl_dispatch->callbacks, s);
      free(s);
    }
Thomas Applencourt's avatar
Thomas Applencourt committed
102
    struct babeltrace_cl_event_callbacks *s2, *tmp2;
103
104
105
106
107
    HASH_ITER(hh, opencl_dispatch->event_callbacks, s2, tmp2) {
      HASH_DEL(opencl_dispatch->event_callbacks, s2);
      utarray_free(s2->callbacks);
      free(s2);
    }
108
    /* Free the allocated structure */
109
    free(opencl_dispatch);
110
111
112
113
114
115
116
117
118
119
}

/*
 * Called when the trace processing graph containing the sink component
 * is configured.
 *
 * This is where we can create our upstream message iterator.
 */
static
bt_component_class_sink_graph_is_configured_method_status
120
opencl_dispatch_graph_is_configured(bt_self_component_sink *self_component_sink)
121
122
{
    /* Retrieve our private data from the component's user data */
Thomas Applencourt's avatar
Thomas Applencourt committed
123
    struct babeltrace_cl_dispatch *opencl_dispatch = bt_self_component_get_data(
124
125
126
127
128
129
130
131
132
        bt_self_component_sink_as_self_component(self_component_sink));

    /* Borrow our unique port */
    bt_self_component_port_input *in_port =
        bt_self_component_sink_borrow_input_port_by_index(
            self_component_sink, 0);

    /* Create the uptream message iterator */
    bt_message_iterator_create_from_sink_component(self_component_sink,
133
        in_port, &opencl_dispatch->message_iterator);
134
135
136
137
138
139
140
141
142

    return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
}

/*
 * Consumes a batch of messages and writes the corresponding lines to
 * the standard output.
 */
static
143
bt_component_class_sink_consume_method_status opencl_dispatch_consume(
144
145
146
147
148
149
        bt_self_component_sink *self_component_sink)
{
    bt_component_class_sink_consume_method_status status =
        BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;

    /* Retrieve our private data from the component's user data */
Thomas Applencourt's avatar
Thomas Applencourt committed
150
    struct babeltrace_cl_dispatch *opencl_dispatch = bt_self_component_get_data(
151
152
153
154
155
156
        bt_self_component_sink_as_self_component(self_component_sink));

    /* Consume a batch of messages from the upstream message iterator */
    bt_message_array_const messages;
    uint64_t message_count;
    bt_message_iterator_next_status next_status =
157
        bt_message_iterator_next(opencl_dispatch->message_iterator, &messages,
158
159
160
161
162
            &message_count);

    switch (next_status) {
    case BT_MESSAGE_ITERATOR_NEXT_STATUS_END:
        /* End of iteration: put the message iterator's reference */
163
        bt_message_iterator_put_ref(opencl_dispatch->message_iterator);
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
        goto end;
    case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
        status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
        goto end;
    case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
        status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
        goto end;
    case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
        status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
        goto end;
    default:
        break;
    }

    /* For each consumed message */
    for (uint64_t i = 0; i < message_count; i++) {
        /* Current message */
        const bt_message *message = messages[i];
183
184
185
        if (bt_message_get_type(message) == BT_MESSAGE_TYPE_EVENT) {
            const bt_event *event = bt_message_event_borrow_event_const(message);
            const bt_event_class *event_class = bt_event_borrow_class_const(event);
Thomas Applencourt's avatar
Thomas Applencourt committed
186
            struct babeltrace_cl_callbacks *callbacks = NULL;
Brice Videau's avatar
Fixed?    
Brice Videau committed
187
            const char * class_name = bt_event_class_get_name(event_class);
188

Brice Videau's avatar
Fixed?    
Brice Videau committed
189
            HASH_FIND_STR(opencl_dispatch->callbacks, class_name, callbacks);
190
            if (!callbacks) {
Brice Videau's avatar
Fixed?    
Brice Videau committed
191
                const size_t class_name_sz = strlen(class_name);
Thomas Applencourt's avatar
Thomas Applencourt committed
192
                callbacks = (struct babeltrace_cl_callbacks *)calloc(1, sizeof(struct babeltrace_cl_callbacks) + class_name_sz + 1);
Brice Videau's avatar
Fixed?    
Brice Videau committed
193
194
195
                callbacks->name = (const char *)callbacks + class_name_sz;
                strncpy((char *)(callbacks->name), class_name, class_name_sz + 1);
                HASH_ADD_KEYPTR(hh, opencl_dispatch->callbacks, class_name, class_name_sz, callbacks);
Thomas Applencourt's avatar
Thomas Applencourt committed
196
                struct babeltrace_cl_event_callbacks *event_callbacks = NULL;
Brice Videau's avatar
Fixed?    
Brice Videau committed
197
                HASH_FIND_STR(opencl_dispatch->event_callbacks, class_name, event_callbacks);
198
199
200
201
202
203
204
                if (event_callbacks) {
                    callbacks->dispatcher = event_callbacks->dispatcher;
                    callbacks->callbacks = event_callbacks->callbacks;
                }
            }
            /* Print line for current message if it's an event message */
            if (callbacks->dispatcher)
Brice Videau's avatar
Brice Videau committed
205
                callbacks->dispatcher(opencl_dispatch, callbacks, event, bt_message_event_borrow_default_clock_snapshot_const(message));
206
207
208

            /* Put this message's reference */
	}
209
210
211
212
213
214
215
216
217
218
219
        bt_message_put_ref(message);
    }

end:
    return status;
}


/* Mandatory */
BT_PLUGIN_MODULE();

220
/* Define the `opencl` plugin */
221
222
223
BT_PLUGIN(opencl);

/* Define the `text` sink component class */
224
BT_PLUGIN_SINK_COMPONENT_CLASS(dispatch, opencl_dispatch_consume);
225
226
227

/* Set some of the `text` sink component class's optional methods */

228
229
230
BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(dispatch, opencl_dispatch_initialize);
BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(dispatch, opencl_dispatch_finalize);
BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(dispatch, opencl_dispatch_graph_is_configured);