blob: 0cc0c33aac4a3c11d02460bc890d5499ea893006 [file] [log] [blame]
/*
*Licensed to the Apache Software Foundation (ASF) under one
*or more contributor license agreements. See the NOTICE file
*distributed with this work for additional information
*regarding copyright ownership. The ASF licenses this file
*to you under the Apache License, Version 2.0 (the
*"License"); you may not use this file except in compliance
*with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing,
*software distributed under the License is distributed on an
*"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
*specific language governing permissions and limitations
*under the License.
*/
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include "benchmark.h"
static const char * const BENCHMARK_NAME = "REFERENCE";
static const double SAMPLE_FACTOR = 100;
typedef struct thread_info {
benchmark_pt benchmark;
int nrOfSamples;
unsigned int result;
struct timeval begin;
struct timeval end;
int skips;
} thread_info_t;
static void benchmark_thread(thread_info_t *info);
static int benchmark_calc(int arg1, int arg2);
celix_status_t benchmark_create(benchmark_pt *benchmark) {
//do nothing
return CELIX_SUCCESS;
}
celix_status_t benchmark_destroy(benchmark_pt benchmark) {
//do nothing
return CELIX_SUCCESS;
}
benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
int i;
pthread_t threads[nrOfThreads];
thread_info_t infos[nrOfThreads];
benchmark_result_t result;
unsigned long elapsedTime = 0;
result.skips =0;
for (i = 0 ; i < nrOfThreads ; i += 1) {
infos[i].benchmark = benchmark;
infos[i].nrOfSamples = nrOfSamples;
infos[i].skips = 0;
infos[i].result = rand();
pthread_create(&threads[i], NULL, (void *)benchmark_thread, &infos[i]);
}
for (i = 0; i < nrOfThreads ; i += 1) {
pthread_join(threads[i], NULL);
elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
result.skips += infos[i].skips;
}
result.averageCallTimeInNanoseconds = elapsedTime;
result.averageCallTimeInNanoseconds *= 1000;
result.averageCallTimeInNanoseconds /= nrOfSamples;
result.averageCallTimeInNanoseconds /= nrOfThreads;
result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
result.nrOfThreads = nrOfThreads;
result.nrOfsamples = nrOfSamples;
return result;
}
static void benchmark_thread(thread_info_t *info) {
int i;
int result = info->result;
struct timeval *begin = &info->begin;
struct timeval *end = &info->end;
int nrOFSamples = info->nrOfSamples;
gettimeofday(begin, NULL);
for (i = 0; i < nrOFSamples; i += 1) {
result = benchmark_calc(result, i);
}
gettimeofday(end, NULL);
info->result = result;
}
char * benchmark_getName(benchmark_pt benchmark) {
return (char *)BENCHMARK_NAME;
}
celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
//ignore service is not used
return CELIX_SUCCESS;
}
celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
//ignore service is not used
return CELIX_SUCCESS;
}
/*
* Same implementation as the math_service. This function is used a reference.
*/
static int benchmark_calc(int arg1, int arg2) {
return arg1 * arg2 + arg2;
}
double benchmark_getSampleFactor(benchmark_pt benchmark) {
return SAMPLE_FACTOR;
}