| 
					
				 | 
			
			
				@@ -0,0 +1,519 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* StarPU --- Runtime system for heterogeneous multicore architectures. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright (C) 2019                                     Inria 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * StarPU is free software; you can redistribute it and/or modify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * it under the terms of the GNU Lesser General Public License as published by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the Free Software Foundation; either version 2.1 of the License, or (at 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * your option) any later version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * StarPU 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 Lesser General Public License in COPYING.LGPL for more details. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Performance counters and configurable knobs */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <stdlib.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <stdint.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <starpu.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <common/config.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <common/starpu_spinlock.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <core/workers.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <common/knobs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct perf_counter_array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct starpu_perf_counter *array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int updater_array_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	void (**updater_array)(struct starpu_perf_counter_sample *sample, void *context); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct perf_counter_array global_counters	= { .size = 0, .array = NULL, .updater_array_size = 0, .updater_array = NULL }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct perf_counter_array per_worker_counters	= { .size = 0, .array = NULL, .updater_array_size = 0, .updater_array = NULL }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct perf_counter_array per_codelet_counters	= { .size = 0, .array = NULL, .updater_array_size = 0, .updater_array = NULL }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct starpu_perf_counter_sample global_sample	= { .scope = starpu_perf_counter_scope_global, .listener = NULL, .value_array = NULL }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_sample_init(struct starpu_perf_counter_sample *sample, enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT_PERF_COUNTER_SCOPE_DEFINED(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->scope = scope; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->listener = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->value_array = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_init(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_sample_exit(struct starpu_perf_counter_sample *sample) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(sample->listener == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->listener = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (sample->value_array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		free(sample->value_array); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->value_array = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->scope = starpu_perf_counter_scope_undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_destroy(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_perf_counter_sample_init(&global_sample, starpu_perf_counter_scope_global); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* call counter registration routines in each modules */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu__task_c__register_counters(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_perf_counter_unregister_all_scopes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_perf_counter_sample_exit(&global_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_scope_name_to_id(const char * const name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "global") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_scope_global; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "per_worker") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_scope_per_worker; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "per_codelet") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_scope_per_codelet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char *starpu_perf_counter_scope_id_to_name(const enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_global: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "global"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_per_worker: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "per_worker"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_per_codelet: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "per_codelet"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_type_name_to_id(const char * const name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "int32") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_type_int32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "int64") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_type_int64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "float") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_type_float; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(name, "double") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return starpu_perf_counter_type_double; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char *starpu_perf_counter_type_id_to_name(const enum starpu_perf_counter_type type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_type_int32: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "int32"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_type_int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "int64"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_type_float: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "float"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_type_double: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "double"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct perf_counter_array *_get_counters(const enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT_PERF_COUNTER_SCOPE_DEFINED(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_global: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return &global_counters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_per_worker: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return &per_worker_counters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case starpu_perf_counter_scope_per_codelet: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return &per_codelet_counters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			STARPU_ABORT(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int _starpu_perf_counter_register(enum starpu_perf_counter_scope scope, const char *name, enum starpu_perf_counter_type type, const char *help) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT_PERF_COUNTER_TYPE_DEFINED(type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = counters->size++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_REALLOC(counters->array, counters->size * sizeof(*counters->array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct starpu_perf_counter * const new_counter = &counters->array[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int id = _starpu_perf_counter_id_build(scope, index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	new_counter->id = id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	new_counter->name = name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	new_counter->help = help; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	new_counter->type = type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void _unregister_scope(enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(counters->array); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	counters->array = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	counters->size  = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_unregister_all_scopes(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_unregister_scope(starpu_perf_counter_scope_global); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_unregister_scope(starpu_perf_counter_scope_per_worker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_unregister_scope(starpu_perf_counter_scope_per_codelet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_nb(enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return counters->size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_nth_to_id(enum starpu_perf_counter_scope scope, int nth) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return _starpu_perf_counter_id_build(scope, nth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_name_to_id(enum starpu_perf_counter_scope scope, const char *name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (index = 0; index < counters->size; index++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (strcmp(name, counters->array[index].name) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return _starpu_perf_counter_id_build(scope, index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char *starpu_perf_counter_id_to_name(int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int scope = _starpu_perf_counter_id_get_scope(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = _starpu_perf_counter_id_get_index(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (index < 0 || index >= counters->size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return counters->array[index].name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char *starpu_perf_counter_get_help_string(int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int scope = _starpu_perf_counter_id_get_scope(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = _starpu_perf_counter_id_get_index(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(index >= 0 && index < counters->size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return counters->array[index].help; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_perf_counter_get_type_id(int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int scope = _starpu_perf_counter_id_get_scope(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = _starpu_perf_counter_id_get_index(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(index >= 0 && index < counters->size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return counters->array[index].type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_list_avail(enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct perf_counter_array * const counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (index = 0; index < counters->size; index++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const struct starpu_perf_counter * const counter = &counters->array[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		printf("0x%08x:%s [%s] - %s\n", _starpu_perf_counter_id_build(scope, index), counter->name, starpu_perf_counter_type_id_to_name(counter->type), counter->help); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_list_all_avail(enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	printf("scope: global\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	starpu_perf_counter_list_avail(starpu_perf_counter_scope_global); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	printf("scope: per_worker\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	starpu_perf_counter_list_avail(starpu_perf_counter_scope_per_worker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	printf("scope: per_codelet\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	starpu_perf_counter_list_avail(starpu_perf_counter_scope_per_codelet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct starpu_perf_counter_set *starpu_perf_counter_set_alloc(enum starpu_perf_counter_scope scope) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct perf_counter_array *counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct starpu_perf_counter_set *set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_MALLOC(set, sizeof(*set)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set->scope = scope; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set->size  = counters->size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_CALLOC(set->index_array, set->size, sizeof(*set->index_array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_free(struct starpu_perf_counter_set *set) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	memset(set->index_array, 0, set->size*sizeof(*set->index_array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(set->index_array); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	memset(set, 0, sizeof(*set)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(set); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_enable_id(struct starpu_perf_counter_set *set, int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = _starpu_perf_counter_id_get_index(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(index >= 0 && index < set->size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set->index_array[index] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_disable_id(struct starpu_perf_counter_set *set, int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index = _starpu_perf_counter_id_get_index(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(index >= 0 && index < set->size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set->index_array[index] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct starpu_perf_counter_listener *starpu_perf_counter_listener_init(struct starpu_perf_counter_set *set, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		void (*callback)(struct starpu_perf_counter_listener *listener, struct starpu_perf_counter_sample *sample, void *context), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		void *user_arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct starpu_perf_counter_listener *listener; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_MALLOC(listener, sizeof(*listener)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	listener->set = set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	listener->callback = callback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	listener->user_arg = user_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return listener; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_listener_exit(struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	memset(listener, 0, sizeof(*listener)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(listener); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void set_listener(struct starpu_perf_counter_sample *sample, struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_lock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(sample->listener == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(listener->set != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(listener->set->scope == sample->scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->listener = listener; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Assume a single listener, for now, which sets the set of counters to monitor */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(sample->value_array == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_CALLOC(sample->value_array, sample->listener->set->size, sizeof(*sample->value_array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_unlock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_global_listener(struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set_listener(&global_sample, listener); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_per_worker_listener(unsigned workerid, struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct _starpu_worker *worker = _starpu_get_worker_struct(workerid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set_listener(&worker->perf_counter_sample, listener); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_all_per_worker_listeners(struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned nworkers = _starpu_worker_get_count(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned workerid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (workerid = 0; workerid < nworkers; workerid++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		starpu_perf_counter_set_per_worker_listener(workerid, listener); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_set_per_codelet_listener(struct starpu_codelet *cl, struct starpu_perf_counter_listener *listener) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(cl->perf_counter_values == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_CALLOC(cl->perf_counter_values, 1, sizeof(*cl->perf_counter_values)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(cl->perf_counter_sample == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_MALLOC(cl->perf_counter_sample, sizeof(*cl->perf_counter_sample)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_perf_counter_sample_init(cl->perf_counter_sample, starpu_perf_counter_scope_per_codelet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set_listener(cl->perf_counter_sample, listener); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void unset_listener(struct starpu_perf_counter_sample *sample) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_lock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(sample->listener != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	memset(sample->value_array, 0, sample->listener->set->size * sizeof(*sample->value_array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(sample->value_array); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->value_array = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sample->listener = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_unlock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_unset_global_listener() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unset_listener(&global_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_unset_per_worker_listener(unsigned workerid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct _starpu_worker *worker = _starpu_get_worker_struct(workerid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unset_listener(&worker->perf_counter_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_unset_all_per_worker_listeners(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned nworkers = _starpu_worker_get_count(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned workerid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (workerid = 0; workerid < nworkers; workerid++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		starpu_perf_counter_unset_per_worker_listener(workerid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_perf_counter_unset_per_codelet_listener(struct starpu_codelet *cl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(cl->perf_counter_sample != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unset_listener(cl->perf_counter_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_perf_counter_sample_exit(cl->perf_counter_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(cl->perf_counter_sample); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cl->perf_counter_sample = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	free(cl->perf_counter_values); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cl->perf_counter_values = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_register_updater(enum starpu_perf_counter_scope scope, void (*updater)(struct starpu_perf_counter_sample *sample, void *context)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(!_starpu_machine_is_running()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct perf_counter_array *counters = _get_counters(scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int upd_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	upd_id = counters->updater_array_size++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_STARPU_REALLOC(counters->updater_array, counters->updater_array_size * sizeof(*counters->updater_array)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	counters->updater_array[upd_id] = updater; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* - */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void update_sample(struct starpu_perf_counter_sample *sample, void *context) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_lock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct perf_counter_array *counters = _get_counters(sample->scope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* for now, we assume that a sample will only be updated if it has a listener plugged, with a non-empty set */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (sample->listener != NULL && sample->listener->set != NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (counters->updater_array_size > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			int upd_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for (upd_id = 0; upd_id < counters->updater_array_size; upd_id++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				counters->updater_array[upd_id](sample, context); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (sample->listener != NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				sample->listener->callback(sample->listener, sample, context); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_spin_unlock(&sample->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_update_global_sample(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	update_sample(&global_sample, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_update_per_worker_sample(unsigned workerid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct _starpu_worker *worker = _starpu_get_worker_struct(workerid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	update_sample(&worker->perf_counter_sample, worker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_perf_counter_update_per_codelet_sample(struct starpu_codelet *cl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	update_sample(cl->perf_counter_sample, cl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE(STRING, TYPE) \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+TYPE starpu_perf_counter_sample_get_##STRING##_value(struct starpu_perf_counter_sample *sample, const int counter_id) \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(starpu_perf_counter_get_type_id(counter_id) == starpu_perf_counter_type_##STRING); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(sample->listener != NULL && sample->listener->set != NULL); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(_starpu_perf_counter_id_get_scope(counter_id) == sample->listener->set->scope); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const struct starpu_perf_counter_set * const set = sample->listener->set; \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const int index =  _starpu_perf_counter_id_get_index(counter_id); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(index < set->size); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	STARPU_ASSERT(set->index_array[index] > 0); \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return sample->value_array[index].STRING##_val; \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE(int32, int32_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE(int64, int64_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE(float, float); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE(double, double); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#undef STARPU_PERF_COUNTER_SAMPLE_GET_TYPED_VALUE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 |