#include "tracercore.h"
#include "tracer.h"
-extern struct marker __start___markers[];
-extern struct marker __stop___markers[];
+extern struct marker __start___markers[] __attribute__((visibility("hidden")));
+extern struct marker __stop___markers[] __attribute__((visibility("hidden")));
/* Set to 1 to enable marker debug output */
static const int marker_debug;
/*
* ignore error, continue
*/
+
+ /* This is added for UST. We emit a core_marker_id event
+ * for markers that are already registered to a probe
+ * upon library load. Otherwise, no core_marker_id will
+ * be generated for these markers. Is this the right thing
+ * to do?
+ */
+ trace_mark(metadata, core_marker_id,
+ "channel %s name %s event_id %hu "
+ "int #1u%zu long #1u%zu pointer #1u%zu "
+ "size_t #1u%zu alignment #1u%u",
+ iter->channel, iter->name, mark_entry->event_id,
+ sizeof(int), sizeof(long), sizeof(void *),
+ sizeof(size_t), ltt_get_alignment());
} else {
disable_marker(iter);
}
static void marker_update_probes(void)
{
/* Core kernel markers */
- marker_update_probe_range(__start___markers, __stop___markers);
+//ust// marker_update_probe_range(__start___markers, __stop___markers);
/* Markers in modules. */
//ust// module_update_markers();
+ lib_update_markers();
//ust// tracepoint_probe_update_all();
/* Update immediate values */
core_imv_update();
-//ust// module_imv_update();
+//ust// module_imv_update(); /* FIXME: need to port for libs? */
marker_update_processes();
}
/* write rcu_pending before calling the RCU callback */
smp_wmb();
call_rcu_sched(&entry->rcu, free_old_closure);
+ /*synchronize_rcu(); free_old_closure();*/
goto end;
error_unregister_channel:
/* Core kernel markers */
if (!iter->lib) {
+ /* ust FIXME: how come we cannot disable the following line? we shouldn't need core stuff */
found = marker_get_iter_range(&iter->marker,
__start___markers, __stop___markers);
if (found)
return found;
}
+void lib_update_markers(void)
+{
+ struct lib *lib;
+
+//ust// mutex_lock(&module_mutex);
+ list_for_each_entry(lib, &libs, list)
+ marker_update_probe_range(lib->markers_start,
+ lib->markers_start + lib->markers_count);
+//ust// mutex_unlock(&module_mutex);
+}
+
+static void (*new_marker_cb)(struct marker *) = NULL;
+
+void marker_set_new_marker_cb(void (*cb)(struct marker *))
+{
+ new_marker_cb = cb;
+}
+
+static void new_markers(struct marker *start, struct marker *end)
+{
+ if(new_marker_cb) {
+ struct marker *m;
+ for(m=start; m < end; m++) {
+ new_marker_cb(m);
+ }
+ }
+}
+
int marker_register_lib(struct marker *markers_start, int markers_count)
{
struct lib *pl;
pl->markers_start = markers_start;
pl->markers_count = markers_count;
+ /* FIXME: maybe protect this with its own mutex? */
+ lock_markers();
list_add(&pl->list, &libs);
+ unlock_markers();
+
+ new_markers(markers_start, markers_start + markers_count);
+
+ /* FIXME: update just the loaded lib */
+ lib_update_markers();
- printf("just registered a markers section from %p and having %d markers\n", markers_start, markers_count);
+ DBG("just registered a markers section from %p and having %d markers", markers_start, markers_count);
return 0;
}
+
+int marker_unregister_lib(struct marker *markers_start, int markers_count)
+{
+ /*FIXME: implement; but before implementing, marker_register_lib must
+ have appropriate locking. */
+
+ return 0;
+}
+
+static int initialized = 0;
+
+void __attribute__((constructor)) init_markers(void)
+{
+ if(!initialized) {
+ marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));
+ printf("markers_start: %p, markers_stop: %p\n", __start___markers, __stop___markers);
+ initialized = 1;
+ }
+}