1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-22 07:37:38 +01:00

benching: add benching facilities

This commit is contained in:
Théophile Bastian 2018-06-15 01:15:16 +02:00
parent a77b0cd7bd
commit 4024d5c269
3 changed files with 87 additions and 0 deletions

View file

@ -255,3 +255,10 @@ extern const char *unw_strerror (int);
extern int unw_backtrace (void **, int);
extern unw_addr_space_t unw_local_addr_space;
#include <time.h>
struct timespec chrono_report(void);
struct timespec chrono_start(void);
void chrono_end(struct timespec);
void chrono_report_disp(void);

View file

@ -95,6 +95,11 @@ noinst_HEADERS += setjmp/setjmp_i.h
### libunwind:
libunwind_la_LIBADD =
### libunwind-benchmarking
libunwind_benchmarking_la_SOURCES = benchmarking.c
noinst_LTLIBRARIES += libunwind-benchmarking.la
libunwind_la_LIBADD += libunwind-benchmarking.la
# List of arch-independent files needed by both local-only and generic
# libraries:
libunwind_la_SOURCES_common = \

75
src/benchmarking.c Normal file
View file

@ -0,0 +1,75 @@
/********** Libunwind -- eh_elf flavour **********
* This is the eh_elf version of libunwind, made for academic purposes.
*
* Théophile Bastian <theophile.bastian@ens.fr> <contact+github@tobast.fr>
*************************************************
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
************************************************/
#include <time.h>
#include <stdint.h>
#include <stdio.h>
typedef struct timespec chrono_t;
static const long NSEC_MAX = 1000 * 1000 * 1000;
static chrono_t _timer_accu = {
.tv_sec = 0,
.tv_nsec = 0
};
static size_t _call_count = 0;
static void normalize_timer(chrono_t* timer) {
if(timer->tv_nsec >= NSEC_MAX) {
timer->tv_sec++;
timer->tv_nsec -= NSEC_MAX;
}
else if(timer->tv_nsec < 0) {
timer->tv_sec--;
timer->tv_nsec += NSEC_MAX;
}
}
static void timer_add(chrono_t* out, chrono_t t1, chrono_t t2) {
out->tv_sec = t1.tv_sec + t2.tv_sec;
out->tv_nsec = t1.tv_nsec + t2.tv_nsec;
normalize_timer(out);
}
static void timer_diff(chrono_t* out, chrono_t t1, chrono_t t2) {
out->tv_sec = t2.tv_sec - t1.tv_sec;
out->tv_nsec = t2.tv_nsec - t1.tv_nsec;
normalize_timer(out);
}
chrono_t chrono_start() {
chrono_t out;
clock_gettime(CLOCK_REALTIME, &out);
return out;
}
void chrono_end(chrono_t start) {
chrono_t diff;
++_call_count;
timer_diff(&diff, start, chrono_start());
timer_add(&_timer_accu, _timer_accu, diff);
}
chrono_t chrono_report() {
return _timer_accu;
}
void chrono_report_disp() {
fprintf(stderr,
"=============== BENCH ===============\n"
"Total unwind time: %ld s %ld ns, %lu calls\n",
_timer_accu.tv_sec,
_timer_accu.tv_nsec,
_call_count);
}