diff options
author | lexborisov <lex.borisov@gmail.com> | 2017-03-14 17:27:25 +0300 |
---|---|---|
committer | lexborisov <lex.borisov@gmail.com> | 2017-03-14 17:27:25 +0300 |
commit | 2055ee6d008e07b1012e8e0249b60bab6ed0e9e7 (patch) | |
tree | e5707ae2a17f9b1f509bd5d1ae61af45083d05f3 | |
parent | 9fe5924a04ff352c9709d7a6b6e6ce6052db1666 (diff) |
Added perf.c to myport
-rw-r--r-- | Makefile.cfg | 4 | ||||
-rw-r--r-- | include/mycore/perf.h | 49 | ||||
-rw-r--r-- | source/mycore/perf.h | 49 | ||||
-rw-r--r-- | source/myport/posix/mycore/perf.c | 136 | ||||
-rw-r--r-- | source/myport/windows_nt/mycore/perf.c | 92 |
5 files changed, 330 insertions, 0 deletions
diff --git a/Makefile.cfg b/Makefile.cfg index a2ab124..1663cb3 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -91,6 +91,10 @@ ifeq ($(MyCORE_BUILD_WITHOUT_THREADS),YES) MODEST_CFLAGS += -DMyCORE_BUILD_WITHOUT_THREADS endif +ifeq ($(MyCORE_WITH_PERF),YES) + MODEST_CFLAGS += -DMyCORE_WITH_PERF +endif + #******************** # Utils #*************** diff --git a/include/mycore/perf.h b/include/mycore/perf.h new file mode 100644 index 0000000..99e5f7e --- /dev/null +++ b/include/mycore/perf.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2015-2017 Alexander Borisov + + This library 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. + + This library 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 for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MyCORE_PERF_H +#define MyCORE_PERF_H +#pragma once + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <mycore/myosi.h> + +#ifdef MyCORE_WITH_PERF +void * mycore_perf_create(void); +void mycore_perf_clean(void* perf); +void mycore_perf_destroy(void* perf); + +mycore_status_t myhtml_perf_begin(void* perf); +mycore_status_t myhtml_perf_end(void* perf); +double myhtml_perf_in_sec(void* perf); + +unsigned long long mycore_perf_clock(void); +unsigned long long mycore_perf_frequency(void); +#endif /* MyCORE_WITH_PERF */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MyCORE_PERF_H */ diff --git a/source/mycore/perf.h b/source/mycore/perf.h new file mode 100644 index 0000000..0e878a1 --- /dev/null +++ b/source/mycore/perf.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2015-2017 Alexander Borisov + + This library 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. + + This library 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 for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MyCORE_PERF_H +#define MyCORE_PERF_H +#pragma once + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mycore/myosi.h" + +#ifdef MyCORE_WITH_PERF +void * mycore_perf_create(void); +void mycore_perf_clean(void* perf); +void mycore_perf_destroy(void* perf); + +mycore_status_t myhtml_perf_begin(void* perf); +mycore_status_t myhtml_perf_end(void* perf); +double myhtml_perf_in_sec(void* perf); + +unsigned long long mycore_perf_clock(void); +unsigned long long mycore_perf_frequency(void); +#endif /* MyCORE_WITH_PERF */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MyCORE_PERF_H */ diff --git a/source/myport/posix/mycore/perf.c b/source/myport/posix/mycore/perf.c new file mode 100644 index 0000000..8b30508 --- /dev/null +++ b/source/myport/posix/mycore/perf.c @@ -0,0 +1,136 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library 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. + + This library 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 for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Authors: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifdef MyCORE_WITH_PERF + +#if MODEST_BUILD_OS == Darwin || MODEST_BUILD_OS == FreeBSD +#include <sys/sysctl.h> +#elif MODEST_BUILD_OS == Linux +#endif + +#include "mycore/myosi.h" +#include "mycore/perf.h" + +struct mycore_perf { + unsigned long long start; + unsigned long long end; + unsigned long long freq; +} +typedef mycore_perf_t; + +void * mycore_perf_create(void) +{ + mycore_perf_t *perf = mycore_calloc(1, sizeof(mycore_perf_t)); + if(perf == NULL) + return NULL; + + perf->freq = mycore_perf_frequency(); + + return perf; +} + +void mycore_perf_clean(void* perf) +{ + memset(perf, 0, sizeof(mycore_perf_t)); +} + +void mycore_perf_destroy(void* perf) +{ + if(perf) + mycore_free(perf); +} + +mycore_status_t myhtml_perf_begin(void* perf) +{ + ((mycore_perf_t*)(perf))->start = mycore_perf_clock(); + return MyCORE_STATUS_OK; +} + +mycore_status_t myhtml_perf_end(void* perf) +{ + ((mycore_perf_t*)(perf))->end = mycore_perf_clock(); + return MyCORE_STATUS_OK; +} + +double myhtml_perf_in_sec(void* perf) +{ + mycore_perf_t *obj_perf = (mycore_perf_t*)perf; + + if(obj_perf->freq) + return ((double)(obj_perf->end - obj_perf->start) / (double)obj_perf->freq); + + return 0.0f; +} + +unsigned long long mycore_perf_clock(void) +{ + unsigned long long x; + + __asm__ volatile ( + "cpuid\n\t" /* cpuid serializes any out-of-order prefetches before executing rdtsc (clobbers ebx, ecx, edx) */ + "rdtsc\n\t" + "shl $32, %%rdx\n\t" + "or %%rdx, %%rax" + : "=a" (x) + : + : "rdx", "ebx", "ecx"); + + return x; +} + +unsigned long long mycore_perf_frequency(void) +{ + unsigned long long freq = 0; + +#if MODEST_BUILD_OS == Darwin && defined(CTL_HW) && defined(HW_CPU_FREQ) + /* OSX kernel: sysctl(CTL_HW | HW_CPU_FREQ) */ + size_t len = sizeof(freq); + int mib[2] = {CTL_HW, HW_CPU_FREQ}; + + if(sysctl(mib, 2, &freq, &len, NULL, 0)) + return 0; + + return freq; + +#elif MODEST_BUILD_OS == Linux + /* Use procfs on linux */ + FILE* fp = fopen("/proc/cpuinfo", "r"); + if(fp == NULL) + return 0; + + /* Find 'CPU MHz :' */ + char buf[1024] = {0}; + double fval = 0.0; + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (sscanf(buf, "cpu MHz : %lf\n", &fval) == 1) { + freq = (unsigned long long)(fval * 1000000ull); + break; + } + } + + fclose(fp); + return freq; + +#else + return freq; +#endif /* MODEST_BUILD_OS == Darwin || Linux */ +} + +#endif /* MyCORE_WITH_PERF */ diff --git a/source/myport/windows_nt/mycore/perf.c b/source/myport/windows_nt/mycore/perf.c new file mode 100644 index 0000000..f67d604 --- /dev/null +++ b/source/myport/windows_nt/mycore/perf.c @@ -0,0 +1,92 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library 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. + + This library 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 for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Authors: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifdef MyCORE_WITH_PERF +#include <windows.h> + +#include "mycore/myosi.h" +#include "mycore/perf.h" + +struct mycore_perf { + LARGE_INTEGER start; + LARGE_INTEGER end; + LARGE_INTEGER freq; +} +typedef mycore_perf_t; + +void * mycore_perf_create(void) +{ + mycore_perf_t *perf = mycore_calloc(1, sizeof(mycore_perf_t)); + if(perf == NULL) + return NULL; + + QueryPerformanceFrequency(&perf->freq); + + return perf; +} + +void mycore_perf_clean(void* perf) +{ + memset(perf, 0, sizeof(mycore_perf_t)); +} + +void mycore_perf_destroy(void* perf) +{ + if(perf) + mycore_free(perf); +} + +mycore_status_t myhtml_perf_begin(void* perf) +{ + QueryPerformanceCounter(&((mycore_perf_t*)(perf))->start); + return MyCORE_STATUS_OK; +} + +mycore_status_t myhtml_perf_end(void* perf) +{ + QueryPerformanceCounter(&((mycore_perf_t*)(perf))->end); + return MyCORE_STATUS_OK; +} + +double myhtml_perf_in_sec(void* perf) +{ + mycore_perf_t *obj_perf = (mycore_perf_t*)perf; + + if(obj_perf->freq.QuadPart) + return ((double)(obj_perf->end.QuadPart - obj_perf->start.QuadPart) / (double)obj_perf->freq.QuadPart); + + return 0.0f; +} + +unsigned long long mycore_perf_clock(void) +{ + LARGE_INTEGER x; + QueryPerformanceFrequency(&x); + return (unsigned long long)x.QuadPart; +} + +unsigned long long mycore_perf_frequency(void) +{ + LARGE_INTEGER x; + QueryPerformanceFrequency(&x); + return (unsigned long long)x.QuadPart; +} + +#endif /* MyCORE_WITH_PERF */ |