1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15#include <autoconf.h>
16#include <sel4camkes/gen_config.h>
17#ifdef CONFIG_CAMKES_CONNECTOR_TIMING
18
19#include <assert.h>
20#include <sel4bench/sel4bench.h>
21#include <stdbool.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25#include <utils/util.h>
26
27
28/* This size is arbitrary. */
29#define TIMING_ENTRIES 4096
30
31#define TIMING_DEFS(pref, pts...) \
32    static int libsel4camkes_timing_buffer_iteration = -1; \
33    static ccnt_t libsel4camkes_timing_buffer[TIMING_ENTRIES]; \
34    static char *libsel4camkes_timing_points[] = { \
35        pts \
36    }; \
37    void pref##_timing_get_points(char ***points, size_t *size) { \
38        *points = libsel4camkes_timing_points; \
39        *size = ARRAY_SIZE(libsel4camkes_timing_points); \
40    } \
41    uint64_t pref##_timing_get_entry(unsigned iteration, char *point) { \
42        assert(iteration * ARRAY_SIZE(libsel4camkes_timing_points) < TIMING_ENTRIES); \
43        for (unsigned offset = 0; offset < ARRAY_SIZE(libsel4camkes_timing_points); offset++) { \
44            if (!strcmp(libsel4camkes_timing_points[offset], point)) { \
45                return (uint64_t)libsel4camkes_timing_buffer[iteration * ARRAY_SIZE(libsel4camkes_timing_points) + offset]; \
46            } \
47        } \
48        /* Named point not found. */ \
49        return 0; \
50    } \
51    void pref##_timing_reset(void) { \
52        libsel4camkes_timing_buffer_iteration = -1; \
53        memset(libsel4camkes_timing_buffer, 0, sizeof(ccnt_t) * TIMING_ENTRIES); \
54    }
55
56#define TIMESTAMP(point) \
57    do { \
58        static bool noted = false; \
59        static int index; \
60        if (!noted) { \
61            for (index = 0; index < ARRAY_SIZE(libsel4camkes_timing_points); index++) { \
62                if (!strcmp(libsel4camkes_timing_points[index], point)) { \
63                    break; \
64                } \
65            } \
66            assert(index < ARRAY_SIZE(libsel4camkes_timing_points)); \
67            noted = true; \
68        } \
69        if (index == 0) { \
70            sel4bench_init(); \
71            libsel4camkes_timing_buffer_iteration++; \
72        } \
73        if (libsel4camkes_timing_buffer_iteration * ARRAY_SIZE(libsel4camkes_timing_points) + index < TIMING_ENTRIES) { \
74            libsel4camkes_timing_buffer[libsel4camkes_timing_buffer_iteration * ARRAY_SIZE(libsel4camkes_timing_points) + index] = sel4bench_get_cycle_count(); \
75        } \
76    } while (0)
77
78#else
79
80#define TIMING_DEFS(pref, pts...) \
81    void pref##timing_get_points(char ***points, size_t *size) { \
82        *points = NULL; \
83        *size = 0; \
84    } \
85    uint64_t pref##timing_get_entry(unsigned iteration, char *point) { \
86        return 0; \
87    } \
88    void pref##timing_reset(void) { \
89    }
90
91#define TIMESTAMP(point) /* nothing */
92
93#endif
94