Commit 35f524b4 authored by Dorel Coman's avatar Dorel Coman Committed by Oliver Horst
Browse files

memguard: improved comments of functions and cleaned code

parent 5482c1d3
/**
* Created by Dorel Coman on 30.04.18.
*
* This benchmarks are meant to be used for testing the MemGuard framework built on top of FreeRTOS
* This functions are meant to be used for testing and profiling the MemGuard framework which can be foundb inside
* memguard.h and which is built on top of FreeRTOS.
*/
#include "freertos/FreeRTOS.h"
......@@ -25,35 +26,37 @@
#define MB_IN_BYTE (1024 * 1024)
#define SIZE_MEM_READ 16
/* Definitions of the timer used for profiling */
#define TTC_TIMER_CORE_0_DEVICE_ID XPAR_XTTCPS_2_DEVICE_ID
#define TTC_TIMER_CORE_0_INTR_ID XPAR_XTTCPS_2_INTR
/* Priority of the ICI for the XScuGic_SetPriorityTriggerType() */
/* Priority of the inter core software interrupts used for synchronizing
the cores while profiling */
#define ICI_INT_PRIORITY 232
#define BENCHMARK_ICI_INT_ID 2
#define SECONDS_OF_BENCHMARKING 10
#define TIMER_HZ 4
#define TIMES_TO_COUNT (SECONDS_OF_BENCHMARKING * TIMER_HZ)
/* Frequency of the timer used for profiling. Each tick of the timer is equivalent to
(1 / TIMER_FREQ) time. We use the variable "ticks" for counting the time and run each
benchmark for the selected time */
#define TIMER_FREQ 4
#define TICKS_TO_COUNT (SECONDS_OF_BENCHMARKING * TIMER_FREQ)
#define NUMBER_OF_BENCHMARKS 17
/* Definitions used for initializing the arrays used in the profiling */
#define ARRAY_TYPE double
#define ARRAY_SIZE 12000000 // 12 Million elements = 96 MB space * 3 arrays = 288 MB total
#define ARRAY_SIZE 12000000 // 12 Million elements = 96 MB space -> 3 arrays = 288 MB total space
#define CONST 5
/* Arrays used for profiling */
ARRAY_TYPE a[ARRAY_SIZE];
ARRAY_TYPE b[ARRAY_SIZE];
ARRAY_TYPE c[ARRAY_SIZE];
/* Array used for tracing the usage of bandwidth in each window*/
#define TIME_FRAMES_IN_ARRAY 80000
uint32_t trace_arr[TIME_FRAMES_IN_ARRAY];
uint64_t bw_used;
/* Used for stopping the while loop when the timer has counted 10 seconds */
/* Used for halting the running benchmark when the timer has reached "SECONDS_OF_BENCHMARKING" seconds */
static volatile uint32_t not_stop_timer;
/* Used for synchronizing the start of the slave benchmark together with the master core benchmark */
static volatile uint32_t start_slave_bench;
/* Used for counting how many fractions of time have occurred already and to stop the timer when it reaches 10 seconds*/
......@@ -62,6 +65,9 @@ volatile uint32_t ticks;
/* It counts the cycles occured during a MemGuard time window */
volatile uint64_t cycle_count;
/* It counts the BUS_ACCESS events */
uint64_t bw_used_by_task;
/* It counts the number of accesses to the main memory during 10 seconds */
volatile uint64_t bus_accesses;
......@@ -105,16 +111,10 @@ static XScuGic *interrupt_controller;
/* Instance of the Timer */
static XTtcPs benchmark_timer;
static XTtcPs benchmark_timer_2;
void handler_timer_interrupt(void *callback_ref);
void benchmark_timer_setup();
void benchmark_slave_setup();
void benchmark_timer_setu_2();
/**
*
*/
void _1_3_bench();
void _2_63_bench();
void _3_122_bench();
......@@ -133,7 +133,7 @@ void _15_1648_bench();
void _16_1866_bench();
void _17_2029_bench();
/* array of function used for accessing in sequence all the benchmark functions */
/* Array of function used for accessing in sequence all the benchmark functions */
void (*bench_arr[])() = { _1_3_bench, _2_63_bench, _3_122_bench, _4_234_bench, _5_326_bench, _6_415_bench, _7_446_bench, _8_531_bench,
_9_618_bench, _10_700_bench, _11_886_bench, _12_1101_bench, _13_1206_bench, _14_1550_bench, _15_1648_bench,
_16_1866_bench, _17_2029_bench };
......@@ -161,7 +161,7 @@ void init_benchmark()
void start_benchmarks() {
uint64_t data[17][11] = {0};
/* setting the random function, used for getting random indexes in array */
/* Setting the random function, used for getting random indexes in array */
srand(pmu_read_cyclecount());
printf("\n\rstart benchmark\n\r");
......@@ -170,12 +170,16 @@ void start_benchmarks() {
XScuGic_SoftwareIntr(interrupt_controller, BENCHMARK_ICI_INT_ID, XSCUGIC_SPI_CPU1_MASK);
} else {
start_slave_bench = 0;
/* Variable used for synchronizing the start of the slave core in the same moment with
the master core. The variable is set to 1, when the master core calls the slave core
with the SGI, */
start_slave_bench = 0;
while(!start_slave_bench){
}
}
/* Iterating over all benchmarks and measuring each of them for 10s */
/* Iterating over all benchmarks and measuring each of them for a set amount of time */
for (int i = 0; i < NUMBER_OF_BENCHMARKS; i++) {
for (int j = 0; j < ARRAY_SIZE; ++j) {
......@@ -184,18 +188,16 @@ void start_benchmarks() {
c[j] = CONST;
}
for (int j = 0; j < TIME_FRAMES_IN_ARRAY; j++)
trace_arr[j] = 0;
/* variable used for stopping the loop when the timer has counted 10 seconds */
/* Variable used for stopping the loop when the timer has counted 10 seconds */
not_stop_timer = 1;
/* resetting all the variables which keep count of the occurring events */
/* Resetting all the variables which keep count of the occurring events */
ticks = 0;
cycle_count = bus_accesses = instr_exec = reclaim_val = 0;
memguard_cycle_count = windows_count = bw_used = reclaim_exec = 0;
memguard_cycle_count = windows_count = bw_used_by_task = reclaim_exec = 0;
overflow_calls = reclaim_tries = suspend_exec = bw_used_before_susp = 0;
/* Resetting the clock counter */
pmu_write_counter(BENCH_3_CNTR_ID_CLOCK_CYCLES, 0);
printf("id: %u bench: %d\n\r", core_id, i);
......@@ -208,17 +210,19 @@ void start_benchmarks() {
(*bench_arr[i])();
}
} else {
/* Running the heavy benchmark on the slave core */
while (not_stop_timer) {
(* bench_arr[16])();
}
}
/* Saving the results of current benchmark to be printed later alltogether */
data[i][0] = instr_exec;
data[i][1] = cycle_count;
data[i][2] = bus_accesses;
data[i][3] = memguard_cycle_count;
data[i][4] = windows_count;
data[i][5] = bw_used;
data[i][5] = bw_used_by_task;
data[i][6] = overflow_calls;
data[i][7] = reclaim_tries;
data[i][8] = suspend_exec;
......@@ -226,7 +230,7 @@ void start_benchmarks() {
data[i][10] = reclaim_val;
}
/* trick used for delaying the printf of the core 1*/
/* Trick used for delaying the printf of the core 1*/
if(core_id != MASTER_CORE_ID){
int val = 0;
for (int j = 0; j < 50000000; j++)
......@@ -239,7 +243,7 @@ void start_benchmarks() {
bus_accesses = data[i][2];
memguard_cycle_count = data[i][3];
windows_count = data[i][4];
bw_used = data[i][5] / windows_count;
bw_used_by_task = data[i][5] / windows_count;
overflow_calls = data[i][6];
reclaim_tries = data[i][7];
suspend_exec = data[i][8];
......@@ -261,14 +265,17 @@ void start_benchmarks() {
printf("cycl: %llu memg_cycl: %llu over: %u.%03u windows: %llu tot_bw %llu inst: %llu ",
cycle_count, memguard_cycle_count, overhead_whole, overhead_decimal,
windows_count, bw_used, instr_exec);
windows_count, bw_used_by_task, instr_exec);
reclaim_val /= windows_count;
printf("overf: %llu reclaim_tries: %llu reclaim_exec %llu reclaim_val %llu susp_exec: %llu bw_before_susp %llu\n\r",
overflow_calls, reclaim_tries, reclaim_exec, reclaim_val, suspend_exec, bw_used_before_susp);
printf("overf: %llu reclaim_tries: %llu reclaim_exec %llu reclaim_val %llu ",
overflow_calls, reclaim_tries, reclaim_exec, reclaim_val);
printf("susp_exec: %llu bw_before_susp %llu\n\r", suspend_exec, bw_used_before_susp);
}
/* Printing the IPC for all the benchmarks in sequence in order to allow its collection */
printf("\n\rIPC:\n\r");
for (int i = 0; i < NUMBER_OF_BENCHMARKS; i++) {
instr_exec = data[i][0];
......@@ -281,13 +288,14 @@ void start_benchmarks() {
printf("%u.%03u\n\r", ipc_whole, ipc_decimal);
}
}
/****************************
* Tracing functions
****************************/
void memguard_trace_bw_per_tick(uint32_t bandwidth_used)
{
bw_used += bandwidth_used;
bw_used_by_task += bandwidth_used;
windows_count++;
}
......@@ -312,9 +320,9 @@ void trace_reclaim_exec(uint32_t reclaim)
reclaim_exec++;
reclaim_val += reclaim;
}
void trace_suspend_routine()
{
uint64_t local = suspend_exec;
suspend_exec++;
}
......@@ -347,6 +355,10 @@ void stop_memguard_trace()
* Benchmark setup functions
**********************************/
/**
* This function sets up the benchmark timer used for timing the tracing functions. It is executed on the Master core
* and uses the third TTC timer assigned to the core.
*/
void benchmark_timer_setup()
{
int status;
......@@ -371,7 +383,7 @@ void benchmark_timer_setup()
XTtcPs_SetOptions(&benchmark_timer, TIMER_OPTIONS_BENCH);
// The following call will map the frequency to the interval and prescaler values.
XTtcPs_CalcIntervalFromFreq(&benchmark_timer, TIMER_HZ, &INTERVAL_BENCH, &PRESCALER_benchmark);
XTtcPs_CalcIntervalFromFreq(&benchmark_timer, TIMER_FREQ, &INTERVAL_BENCH, &PRESCALER_benchmark);
// Set the interval and pre-scale
XTtcPs_SetInterval(&benchmark_timer, INTERVAL_BENCH);
......@@ -389,13 +401,16 @@ void benchmark_timer_setup()
XTtcPs_EnableInterrupts(&benchmark_timer, XTTCPS_IXR_INTERVAL_MASK);
}
/**
* This function sets up the interrupt handler on the slave core, in order to allow it to be called by the Master core
* through a Software Generate Interrupt
*/
void benchmark_slave_setup()
{
int status;
status = XScuGic_Connect(interrupt_controller, BENCHMARK_ICI_INT_ID,
(Xil_ExceptionHandler)handler_timer_interrupt, (void *)interrupt_controller);
configASSERT(status == XST_SUCCESS);
XScuGic_SetPriorityTriggerType(interrupt_controller, BENCHMARK_ICI_INT_ID, ICI_INT_PRIORITY, 0b01);
......@@ -403,8 +418,12 @@ void benchmark_slave_setup()
}
/**
* This interrupt handler is used by the benchmark timer for incrementing the tick and counting the total time the
* benchmark functions are needed to run. When the time is reached the handler sets the not_stop_timer variable to 0
* causing the benchmark executing to stop and exit the loops, allowing to start the next benchmark function and,
* before that, storing the profiling variables into an array.
*
* @param callback_ref
* @param callback_ref: not used
*/
void handler_timer_interrupt(void *callback_ref)
{
......@@ -413,23 +432,24 @@ void handler_timer_interrupt(void *callback_ref)
if(core_id == MASTER_CORE_ID)
{
// read the interrupt status, then write it back to clear the interrupt.
/* Read the interrupt status, then write it back to clear the interrupt. */
u32 status_event = XTtcPs_GetInterruptStatus((XTtcPs *)callback_ref);
// we clear the interrupt status if it was triggered by a timer
/* We clear the interrupt status if it was triggered by a timer */
if ((XTTCPS_IXR_INTERVAL_MASK & status_event) != 0)
XTtcPs_ClearInterruptStatus((XTtcPs *)callback_ref, status_event);
} else {
/* Variable used for synchronizing the start of the slave core in the same moment with the master core */
if(start_slave_bench == 0){
start_slave_bench = 1;
return;
}
}
/* We are counting 40 times 0.25 seconds because the counters would overflow in case
of monitoring for more than 0.25 second */
/* In the standard setting we are counting 40 times 0.25 seconds. We do this to avoid the overflow of the
profiling PMU counters. Under 0.25 seconds the risk of overflow is reduced. */
ticks++;
if(ticks == TIMES_TO_COUNT){
if(ticks == TICKS_TO_COUNT){
not_stop_timer = 0;
if(core_id == MASTER_CORE_ID)
......@@ -449,6 +469,9 @@ void handler_timer_interrupt(void *callback_ref)
*
* where N is the ID of the benchmark
* where X is the bandwidth it uses
*
* Each bench function has the "not_stop_timer" variable in the loop in order to be able
* to stop the function when the timer has reached the stop time.
*/
void _1_3_bench()
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment