Commit 25382da1 authored by Dorel Coman's avatar Dorel Coman Committed by Oliver Horst
Browse files

memguard: improved code structure and fixed small bugs

parent fa15ab45
......@@ -86,13 +86,6 @@ memguard */
/* Frequency of the TTC timer of memguard */
#define TIMER_FREQ_MEMGUARD ((u32) (1 / WINDOW_TIME))
/* Number of cores used */
#define NUMBER_CORES 2U
/* Core ID of the Master core, it is the core which creates the timer and
synchronize all the MemGuard instances */
#define MASTER_CORE_ID 0U
#define MB_IN_BYTE (1024*1024)
/* Bytes accessed in one BUS_ACCESS event */
......@@ -130,7 +123,7 @@ typedef struct memguard_task_info {
/* It represents the budget statically assigned to the task by the user.
The budget is assigned after a task is created through
memguard_notify_new_task_created(). It represents the Q variable in
memguard_setup_task(). It represents the Q variable in
the MemGuard paper. It represents the number of BUS_ACCESS events the
task is allowed during each window. */
uint32_t ass_budget;
......@@ -233,7 +226,7 @@ static TaskHandle_t memguard_task_handle;
/*******************************************************************************
* Function definitions
******************************************************************************/
static void memguard_setup_task(void *arg);
static void memguard_init_task(void *arg);
int setup_inter_core_interrupts();
int setup_pmu_overflow_interrupt();
......@@ -251,6 +244,18 @@ BaseType_t find_new_budget(memguard_task_info *task_info);
void suspend_task_routine(void *pvParameter1, uint32_t ulParameter2);
void memguard_vTaskSuspend(TaskHandle_t task_handle, memguard_task_info *task_info);
/* Functions defined in runtimes/memguard/benchmark.c */
void memguard_trace_bw_per_tick(uint32_t bandwidth_used);
void trace_entrance_overflow_handler();
void trace_bw_before_suspend(uint32_t bw_used);
void trace_reclaim_tries();
void trace_reclaim_exec(uint32_t reclaim);
void trace_suspend_routine();
void start_benchmark_trace();
void stop_benchmark_trace();
void start_memguard_trace();
void stop_memguard_trace();
/**
* This function is meant to print the file name and line number when an
* assert fails to ease the finding of the error.
......@@ -317,18 +322,18 @@ void memguard_init()
/* The task activated at the beginning of scheduling to setup the timer and
then deleted */
xTaskCreate(memguard_setup_task, "Memguard", configMINIMAL_STACK_SIZE, NULL,
xTaskCreate(memguard_init_task, "Memguard", configMINIMAL_STACK_SIZE, NULL,
MEMGUARD_SETUP_TASK_PRIORITY, &memguard_task_handle);
/* The budget size of the setup task is not important because this task
will be deleted after memguard is setup */
memguard_notify_new_task_created(memguard_task_handle,
BANDWIDTH_ASS_MEMGUARD_TASK_IN_MB_PER_S,
pdTRUE);
memguard_setup_task(memguard_task_handle,
BANDWIDTH_ASS_MEMGUARD_TASK_IN_MB_PER_S,
pdTRUE);
}
void memguard_notify_new_task_created(TaskHandle_t task_handle, uint32_t bandwidth,
BaseType_t prediction_allowed)
void memguard_setup_task(TaskHandle_t task_handle, uint32_t bandwidth,
BaseType_t prediction_allowed)
{
if(task_handle != NULL){
memguard_task_info *new_task_info = malloc(sizeof(memguard_task_info));
......@@ -436,6 +441,9 @@ BaseType_t memguard_can_task_resume(TaskHandle_t xTask)
} else if(xTask == xTimerGetTimerDaemonTaskHandle()){
can_task_resume = pdTRUE;
} else {
can_task_resume = pdFALSE;
}
#if (INCLUDE_memguard_benchmark)
......@@ -454,39 +462,45 @@ void memguard_task_reset_window(TaskHandle_t task_handle)
if(task_handle == memguard_task_handle)
return;
TaskStatus_t status;
vTaskGetInfo(task_handle, &status, pdFALSE, eInvalid);
memguard_task_info *task_info = (memguard_task_info *)
pvTaskGetMemguardTaskInfo(task_handle);
/* Checking if the task was unable to use all the statically assigned
memory in the last window - in this case we compensate the difference
for the next window */
if(task_info->budget_finished == 1){
task_info->curr_used_budget += task_info->counter_val;
/* The substraction represents how much quota the task wasn't able
to use in the last time window */
if(task_info->ass_budget > task_info->curr_used_budget)
new_quota = task_info->ass_budget +
(task_info->ass_budget - task_info->curr_used_budget);
else
new_quota = task_info->ass_budget;
if(task_info->prediction_allowed == pdFALSE) {
/* In this case the task is set as hard real-time type and therefore
we always assign to it its statically assigned quota to guarantee
the WCET */
new_quota = task_info->ass_budget;
} else if(task_info->prediction_allowed == pdTRUE){
} else {
/* Assigning the bandwidth used since the last dynamically assigned
quota, but checking first if there wasn't an overflow meanwhile,
in order to don't add the wrong value to curr_used_budget */
if(task_info->counter_val > mask_value(task_info->cur_ass_budget))
task_info->curr_used_budget +=
task_info->counter_val - mask_value(task_info->cur_ass_budget);
else
task_info->curr_used_budget += task_info->cur_ass_budget;
/* Checking if the task was unable to use all the statically assigned
memory in the last window - in this case we compensate the difference
for the next window */
if(task_info->budget_finished == 1){
task_info->curr_used_budget += task_info->counter_val;
/* The substraction represents how much quota the task wasn't able
to use in the last time window. We do it in order to "compensate"
and improve the average computation */
if(task_info->ass_budget > task_info->curr_used_budget){
task_info->curr_used_budget = task_info->ass_budget +
(task_info->ass_budget - task_info->curr_used_budget);
}
} else {
/* Assigning the bandwidth used since the last dynamically assigned
quota, but checking first if there wasn't an overflow meanwhile,
in order to don't add the wrong value to curr_used_budget */
if(task_info->counter_val > mask_value(task_info->cur_ass_budget))
task_info->curr_used_budget +=
task_info->counter_val - mask_value(task_info->cur_ass_budget);
else
task_info->curr_used_budget += task_info->cur_ass_budget;
}
/* Computing the average of bandwidth usage in order to reduce the
allocated quota if not used */
allocated quota if not used */
task_info->average_used_budget = ema(task_info->curr_used_budget,
task_info->average_used_budget, ALPHA_EMA);
......@@ -498,13 +512,6 @@ void memguard_task_reset_window(TaskHandle_t task_handle)
atomic_fetch_add(&(memguard_info.global_budget),
(task_info->ass_budget - new_quota));
}
} else {
/* In this case the task is set as hard real-time type and therefore
we always assign to it its statically assigned quota to guarantee
the WCET */
new_quota = task_info->ass_budget;
}
#if (INCLUDE_memguard_benchmark)
......@@ -522,23 +529,17 @@ void memguard_task_reset_window(TaskHandle_t task_handle)
vTaskResume will think the user is resuming and don't let it happen */
task_info->tsk_susp_by_memguard = pdFALSE;
/* If the task was suspended by memguard we */
/* If the task was suspended by memguard we resume it */
if(task_info->tsk_susp_by_user == pdFALSE){
vTaskResume(task_handle);
}
task_info->tsk_susp_by_memguard = pdFALSE;
}
void memguard_switch_in()
{
#if (INCLUDE_memguard_benchmark)
{
/* When we are resetting the window, the reset routine is already
tracing the memguard, therefore we don't want to overlap the
tracing of memguard overhead */
if(xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED){
start_memguard_trace();
}
start_memguard_trace();
}
#endif
......@@ -552,12 +553,16 @@ void memguard_switch_in()
pmu_start_counter(MEMGUARD_CNTR_ID, task_info->counter_val);
#if(INCLUDE_memguard_benchmark)
{
start_benchmark_trace();
}
#endif
}
#if (INCLUDE_memguard_benchmark)
if(xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED)
stop_memguard_trace();
{
stop_memguard_trace();
}
#endif
}
......@@ -569,7 +574,7 @@ void memguard_switch_out()
}
#endif
/* The PMU overflow interrupt is disabled because it is now wanted that
/* The PMU overflow interrupt is disabled because it is not wanted that
it triggers when the OS routines are running */
pmu_disable_intr(MEMGUARD_CNTR_ID);
......@@ -585,12 +590,16 @@ void memguard_switch_out()
pmu_write_counter(MEMGUARD_CNTR_ID, 0);
#if(INCLUDE_memguard_benchmark)
{
stop_benchmark_trace();
}
#endif
}
#if (INCLUDE_memguard_benchmark)
{
stop_memguard_trace();
}
#endif
}
......@@ -603,7 +612,7 @@ void memguard_switch_out()
* FreeRTOS instances to start together and make the MemGuard framework
* function correctly.
*/
static void memguard_setup_task(void *arg)
static void memguard_init_task(void *arg)
{
int status;
int_controller_ptr = &xInterruptController;
......
......@@ -82,6 +82,12 @@ static struct ipi_info chn_ipi_info[] = {
{NULL, NULL, NULL, NULL, IPI_BASE_ADDR, IPI_CHN_BITMASK, 0, 0},
};
#ifdef MASTER_CORE_TRUE
#define MASTER_CORE 1
#else
#define MASTER_CORE 0
#endif
#if (MASTER_CORE == 1)
const struct firmware_info fw_table[] =
{
......@@ -127,7 +133,7 @@ struct hil_proc *platform_create_proc(int proc_index)
* shared memory and notification info required for inter processor
* communication. */
struct hil_proc *proc;
proc = hil_create_proc(&zynqmp_a53_a53_proc_ops, proc_index, NULL);
proc = hil_create_proc(&zynqmp_a53_a53_proc_ops, (unsigned long) proc_index, NULL);
if (!proc)
return NULL;
......
......@@ -8,6 +8,10 @@
#define RPMSG_CHAN_NAME "rpmsg-openamp-demo-channel"
#ifdef MASTER_CORE_TRUE
#define MASTER_CORE 1
#endif
#if(MASTER_CORE == 1)
/* Firmware table and binary remoteproc firmware symbols. */
extern unsigned char _binary_amp_remote_elf_start;
......
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