aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/benchmark.c102
1 files changed, 101 insertions, 1 deletions
diff --git a/modules/benchmark.c b/modules/benchmark.c
index ed23243b..62720530 100644
--- a/modules/benchmark.c
+++ b/modules/benchmark.c
@@ -91,8 +91,94 @@ struct _ParallelBenchTask {
gint thread_number;
guint start, end;
gpointer data, callback;
+ int *stop;
};
+static gpointer benchmark_crunch_for_dispatcher(gpointer data)
+{
+ ParallelBenchTask *pbt = (ParallelBenchTask *)data;
+ gpointer (*callback)(void *data, gint thread_number);
+ gpointer return_value = g_malloc(sizeof(int));
+ int count = 0;
+
+ if ((callback = pbt->callback)) {
+ while(!*pbt->stop) {
+ callback(pbt->data, pbt->thread_number);
+ /* don't count if didn't finish in time */
+ if (!*pbt->stop)
+ count++;
+ }
+ } else {
+ DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self());
+ }
+
+ g_free(pbt);
+
+ *(double*)return_value = (double)count;
+ return return_value;
+}
+
+bench_value benchmark_crunch_for(float seconds, gint n_threads,
+ gpointer callback, gpointer callback_data) {
+ int cpu_procs, cpu_cores, cpu_threads, thread_number, stop = 0;
+ GSList *threads = NULL, *t;
+ GTimer *timer;
+ bench_value ret = EMPTY_BENCH_VALUE;
+
+ timer = g_timer_new();
+
+ cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ if (n_threads > 0)
+ ret.threads_used = n_threads;
+ else if (n_threads < 0)
+ ret.threads_used = cpu_cores;
+ else
+ ret.threads_used = cpu_threads;
+
+ g_timer_start(timer);
+ for (thread_number = 0; thread_number < ret.threads_used; thread_number++) {
+ ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1);
+ GThread *thread;
+
+ DEBUG("launching thread %d", thread_number);
+
+ pbt->thread_number = thread_number;
+ pbt->data = callback_data;
+ pbt->callback = callback;
+ pbt->stop = &stop;
+
+ thread = g_thread_new("dispatcher",
+ (GThreadFunc)benchmark_crunch_for_dispatcher, pbt);
+ threads = g_slist_prepend(threads, thread);
+
+ DEBUG("thread %d launched as context %p", thread_number, thread);
+ }
+
+ /* wait for time */
+ //while ( g_timer_elapsed(timer, NULL) < seconds ) { }
+ g_usleep(seconds * 1000000);
+
+ /* signal all threads to stop */
+ stop = 1;
+ g_timer_stop(timer);
+
+ ret.result = 0;
+ DEBUG("waiting for all threads to finish");
+ for (t = threads; t; t = t->next) {
+ DEBUG("waiting for thread with context %p", t->data);
+ gpointer *rv = g_thread_join((GThread *)t->data);
+ ret.result += *(double*)rv;
+ g_free(rv);
+ }
+
+ ret.elapsed_time = g_timer_elapsed(timer, NULL);
+
+ g_slist_free(threads);
+ g_timer_destroy(timer);
+
+ return ret;
+}
+
static gpointer benchmark_parallel_for_dispatcher(gpointer data)
{
ParallelBenchTask *pbt = (ParallelBenchTask *)data;
@@ -113,6 +199,15 @@ static gpointer benchmark_parallel_for_dispatcher(gpointer data)
return return_value;
}
+/* one call for each thread to be used */
+bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data) {
+ int cpu_procs, cpu_cores, cpu_threads;
+ cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ if (n_threads == 0) n_threads = cpu_threads;
+ else if (n_threads == -1) n_threads = cpu_cores;
+ return benchmark_parallel_for(n_threads, 0, n_threads, callback, callback_data);
+}
+
bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,
gpointer callback, gpointer callback_data) {
gchar *temp;
@@ -174,7 +269,12 @@ bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,
DEBUG("waiting for all threads to finish");
for (t = threads; t; t = t->next) {
DEBUG("waiting for thread with context %p", t->data);
- g_thread_join((GThread *)t->data);
+ gpointer *rv = g_thread_join((GThread *)t->data);
+ if (rv) {
+ if (ret.result == -1.0) ret.result = 0;
+ ret.result += *(double*)rv;
+ }
+ g_free(rv);
}
g_timer_stop(timer);