Commit cdbc9e8e authored by Oliver Horst's avatar Oliver Horst
Browse files

[merge] Integrated 'feature/memguard' branch

parents 304b50cc 71f61863
/*******************************************************************************
* Created by Dorel Coman on 23.10.17.
*
* This is the implementation of the Memguard framework for ARM64 on FreeRTOS.
* MemGuard is meant to manage the access to the Main Memory, allowing the user
* to set defined limit to the bandwidth available to each task. The current
* implementation allows to run an instance of FreeRTOS on each core and it
* monitors each task running on the different instances.
*
* Yun, H., Yao, G., Pellizzoni, R., Caccamo, M., & Sha, L. (2016). Memory
* bandwidth management for efficient performance isolation in multi-core
* platforms. IEEE Transactions on Computers, 65(2), 562-576.
* https://doi.org/10.1109/TC.2015.2425889
******************************************************************************/
#ifndef FREERTOS_EXTRA_MEMGUARD_H
#define FREERTOS_EXTRA_MEMGUARD_H
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
/* Remove any unused trace macros. */
#ifndef traceMEMGUARD_START
/* */
#define traceMEMGUARD_START()
#endif
#ifndef traceMEMGUARD_STOP
/* */
#define traceMEMGUARD_STOP()
#endif
#ifndef traceMEMGUARD_RECLAIM_TRIAL
/* */
#define traceMEMGUARD_RECLAIM_TRIAL()
#endif
#ifndef traceMEMGUARD_RECLAIM_SUCCESSFULL
/* */
#define traceMEMGUARD_RECLAIM_SUCCESSFULL( x )
#endif
#ifndef traceMEMGUARD_SUSPEND_TASK
/* */
#define traceMEMGUARD_SUSPEND_TASK( x )
#endif
#ifndef traceMEMGUARD_OVERFLOW_HANDLER
/* */
#define traceMEMGUARD_OVERFLOW_HANDLER()
#endif
#ifndef traceMEMGUARD_GLOBAL_BUDGET
/* */
#define traceMEMGUARD_GLOBAL_BUDGET( x )
#endif
#ifndef traceMEMGUARD_TASK_BUDGET
/* */
#define traceMEMGUARD_TASK_BUDGET( a, b )
#endif
/**
* This function sets up the MemGuard framework and it should be called at
* the beginning of the main() function, before any task is created. It
* initializes the variables used by MemGuard and creates the task which will
* set up the interrupts and the timer used by the framework.
*/
void memguard_init();
/**
* This function communicates to MemGuard the creation of a new task and
* informs the framework of which is the bandwidth allowed to the respective
* task. If this function is not called for the created task, the
* latter will not be scheduled (i.e., added to the ready list) and it will
* stay blocked until its creation is notified to memguard which will unlock it.
*
* @param task_handle of the task which was created
*
* @param bandwidth : expressed in MB/s - it is the statically assigned
* bandwidth. More details, about what the statically assigned bandwidth, is
* can be found at the memguard_task_info struct definition inside memguard.c
*
* @oaram prediction_allowed : boolean - if set to pdTRUE allows the
* bandwidth of the task to be dynamically predicted. At the beginning of
* each MemGuard window the bandwidth assigned is recomputed as follows: if
* the task is predicted not to use the full amount of assigned bandwidth,
* the surplus of bandwidth is donated to the global budget. During the time
* window, any task which finishes its bandwidth can reclaim some from the
* global budget. This choice will not guarantee to have always the needed
* bandwidth as the prediction may not be totally correct.
* If the parameter is set to pdFALSE it is guaranteed that the task will have
* always allocated its assigned bandwidth, without donating anything. This
* allows to have a predictable memory bandwidth and should always be set to
* pdFALSE in case of hard real-time tasks.
* For a better description of the mechanism please read the chapter "4.3
* Memory Bandwidth Reclaiming" in the paper linked at the beginning of the
* page.
*/
void vMemguardMonitorTask(TaskHandle_t pxTaskToBind,
uint32_t ulBandwidth,
BaseType_t xPredictionAllowed );
/**
* This function notifies MemGuard that a task was resumed through the
* vTaskSuspend() function. It should not be used anywhere except inside
* vTaskSuspend().
* @param xTask task handle which was suspended
*/
void vMemguardNotifyTaskSuspended( TaskHandle_t pxHandle ) PRIVILEGED_FUNCTION;
/**
* This function notifies MemGuard that a task was resumed through the taks
* management APIs. It should be used only inside the functions vTaskResume()
* and xTaskResumeFromISR().
* @param task_handle of the task which was resumed
*/
void vMemguardNotifyTaskResumed( TaskHandle_t pxHandle ) PRIVILEGED_FUNCTION;
/**
* This function notifies MemGuard that a task was deleted. MemGuard will,
* therefore, free the memory occupied by the related memguard_task_info
* structure. This function should be called only inside vTaskDelete().
*
* @param task_handle of the task which is being deleted.
*/
void vMemguardNotifyTaskDeleted( TaskHandle_t pxHandle ) PRIVILEGED_FUNCTION;
/**
* This function returns pdTRUE if the task was suspended by MemGuard and
* pdFALSE otherwise. It is supposed to be used only inside the functions
* vTaskResume() and xTaskResumeFromISR. It is used in order to know if a
* task can be programmatically resumed or it has to be kept suspended until
* MemGuard starts a new time window.
*
* @param xTask which it is wanted to resume
* @return pdFALSE if it should not be rusmed, pdTRUE if it can be resumed
*/
BaseType_t xMemguardIsTaskBlocked(TaskHandle_t pxHandle ) PRIVILEGED_FUNCTION;
/**
* This function notifies MemGuard that a task has to be reset meaning that its
* assigned budget has to be re-computed has to be recomputed and assigned to
* the task. This function is called for each task when the time window is
* being reset, and it is called only inside the function:
* vTaskResetMemguardWindowForTaskList()
*
* @param task_handle of the task which has to be resetted.
*/
void vMemguardResetWindowForTask(TaskHandle_t task_handle) PRIVILEGED_FUNCTION;
/**
* This function is called during a context switch, before a task is scheduled.
* It restores the value of the BUS_ACCESS event counter, previously saved in
* the variable curr_budget of the struct memguard_task_info. The struct is
* referenced by the TCB of the task with the name memguardTaskInfo.
*/
void vMemguardTaskSwitchIn();
/**
* This function is called during a context switch before a task is descheduled.
* It saves the value of the BUS_ACCESS event counter in a task's variable
* keeping track of the bandwidth usage. The value is saved inside the variable
* curr_budget of the struct memguard_task_info which is referenced by the
* TCB of the task with the name memguardTaskInfo
*/
void vMemguardTaskSwitchOut();
/**
*
* @param task_handle
* @param task_info
*/
void vMemguardSuspendTask( TaskHandle_t pxHandle, void *pvTaskInfo );
/**
* This function is called by the MemGuard timer tick or by a slave in order
* to start a new window. It uses a Software Generated Interrupt for
* communicating to each core to execute their relative
* vMemguardSlaveTickHandler() function.
*
* @param callback_ref not used
*/
void vMemguardMasterPeriodTickHandler( void *callback_ref );
/**
* This function calls the reset_window_routine() which is executed inside a
* task context, the task being the Timer task of FreeRTOS. It executes the
* proper window reset for the respective core. It is called by the master
* core on each slave core.
*
* @param callback_ref not used
*/
void vMemguardSlavePeriodTickHandler( void *callback_ref );
/**
* This functions handles the PMU overflow interrupt and it's called by the
* GIC interrupt when a counter overflows.
*
* The case have to be excuted in their current order, never re-arrange them.
* @param callback_ref not used
*/
void vMemguardOverflowHandler( void *callback_ref );
#endif /* FREERTOS_EXTRA_MEMGUARD_H */
cmake_minimum_required(VERSION 3.7 FATAL_ERROR)
add_subdirectory(malloc)
add_subdirectory(memguard)
cmake_minimum_required(VERSION 3.7 FATAL_ERROR)
target_sources(
freertos-plus
#
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/memguard.c"
)
BSD with Attribution License
Copyright (c) 2015-2020 fortiss GmbH - Research Institute of the
Free State of Bavaria, Guerickestr. 25, 80805 Munich, Germany
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
4. Redistributions of any form whatsoever must retain the following
acknowledgment: 'This product includes software developed by the
fortiss GmbH -- Research Institute of the Free State of Bavaria,
Munich, Germany (https://www.fortiss.org/).'
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SPDX-License-Identifier: BSD-3-Clause-Attribution
The documentation of MemGuard can be found in the folder freertos/doc
under the name: MemGuard.pdf
TODO:
The function metal_start_slaves() from extra/multi_core needs the files
platform_info.c/.h and rsc_table.c/.h which can be found in runtimes/memguard
and runtimes/memguard/slave. There should be found a solution for the doubled
files and they should be moved inside open-amp submodule. also the
extra/multi_core folder and files should probably be moved inside the
open-amp submodule.
\ No newline at end of file
This diff is collapsed.
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