mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 16:25:31 +03:00
Added test to check filling up and emptying queue.
This commit is contained in:
parent
3fa0163713
commit
cd3b584879
2 changed files with 45 additions and 11 deletions
|
@ -82,30 +82,32 @@ STATIC_UNIT_TESTED bool queueContains(cfTask_t *task)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_UNIT_TESTED void queueAdd(cfTask_t *task)
|
STATIC_UNIT_TESTED bool queueAdd(cfTask_t *task)
|
||||||
{
|
{
|
||||||
if ((taskQueueSize >= TASK_COUNT) || queueContains(task)) {
|
if ((taskQueueSize >= TASK_COUNT) || queueContains(task)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
for (int ii = 0; ii <= taskQueueSize; ++ii) {
|
for (int ii = 0; ii <= taskQueueSize; ++ii) {
|
||||||
if (taskQueueArray[ii] == NULL || taskQueueArray[ii]->staticPriority < task->staticPriority) {
|
if (taskQueueArray[ii] == NULL || taskQueueArray[ii]->staticPriority < task->staticPriority) {
|
||||||
memmove(&taskQueueArray[ii+1], &taskQueueArray[ii], sizeof(task) * (taskQueueSize - ii));
|
memmove(&taskQueueArray[ii+1], &taskQueueArray[ii], sizeof(task) * (taskQueueSize - ii));
|
||||||
taskQueueArray[ii] = task;
|
taskQueueArray[ii] = task;
|
||||||
++taskQueueSize;
|
++taskQueueSize;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_UNIT_TESTED void queueRemove(cfTask_t *task)
|
STATIC_UNIT_TESTED bool queueRemove(cfTask_t *task)
|
||||||
{
|
{
|
||||||
for (int ii = 0; ii < taskQueueSize; ++ii) {
|
for (int ii = 0; ii < taskQueueSize; ++ii) {
|
||||||
if (taskQueueArray[ii] == task) {
|
if (taskQueueArray[ii] == task) {
|
||||||
memmove(&taskQueueArray[ii], &taskQueueArray[ii+1], sizeof(task) * (taskQueueSize - ii));
|
memmove(&taskQueueArray[ii], &taskQueueArray[ii+1], sizeof(task) * (taskQueueSize - ii));
|
||||||
--taskQueueSize;
|
--taskQueueSize;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -216,8 +218,8 @@ void scheduler(void)
|
||||||
const bool outsideRealtimeGuardInterval = (timeToNextRealtimeTask > realtimeGuardInterval);
|
const bool outsideRealtimeGuardInterval = (timeToNextRealtimeTask > realtimeGuardInterval);
|
||||||
|
|
||||||
// The task to be invoked
|
// The task to be invoked
|
||||||
uint32_t selectedTaskDynPrio = 0;
|
|
||||||
cfTask_t *selectedTask = NULL;
|
cfTask_t *selectedTask = NULL;
|
||||||
|
uint16_t selectedTaskDynamicPriority = 0;
|
||||||
|
|
||||||
// Update task dynamic priorities
|
// Update task dynamic priorities
|
||||||
uint16_t waitingTasks = 0;
|
uint16_t waitingTasks = 0;
|
||||||
|
@ -247,13 +249,13 @@ void scheduler(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->dynamicPriority > selectedTaskDynPrio) {
|
if (task->dynamicPriority > selectedTaskDynamicPriority) {
|
||||||
const bool taskCanBeChosenForScheduling =
|
const bool taskCanBeChosenForScheduling =
|
||||||
(outsideRealtimeGuardInterval) ||
|
(outsideRealtimeGuardInterval) ||
|
||||||
(task->taskAgeCycles > 1) ||
|
(task->taskAgeCycles > 1) ||
|
||||||
(task->staticPriority == TASK_PRIORITY_REALTIME);
|
(task->staticPriority == TASK_PRIORITY_REALTIME);
|
||||||
if (taskCanBeChosenForScheduling) {
|
if (taskCanBeChosenForScheduling) {
|
||||||
selectedTaskDynPrio = task->dynamicPriority;
|
selectedTaskDynamicPriority = task->dynamicPriority;
|
||||||
selectedTask = task;
|
selectedTask = task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,8 +266,8 @@ void scheduler(void)
|
||||||
|
|
||||||
currentTask = selectedTask;
|
currentTask = selectedTask;
|
||||||
|
|
||||||
// Found a task that should be run
|
|
||||||
if (selectedTask != NULL) {
|
if (selectedTask != NULL) {
|
||||||
|
// Found a task that should be run
|
||||||
selectedTask->taskLatestDeltaTime = currentTime - selectedTask->lastExecutedAt;
|
selectedTask->taskLatestDeltaTime = currentTime - selectedTask->lastExecutedAt;
|
||||||
selectedTask->lastExecutedAt = currentTime;
|
selectedTask->lastExecutedAt = currentTime;
|
||||||
selectedTask->dynamicPriority = 0;
|
selectedTask->dynamicPriority = 0;
|
||||||
|
|
|
@ -77,8 +77,8 @@ extern "C" {
|
||||||
extern void queueClear(void);
|
extern void queueClear(void);
|
||||||
extern int queueSize();
|
extern int queueSize();
|
||||||
extern bool queueContains(cfTask_t *task);
|
extern bool queueContains(cfTask_t *task);
|
||||||
extern void queueAdd(cfTask_t *task);
|
extern bool queueAdd(cfTask_t *task);
|
||||||
extern void queueRemove(cfTask_t *task);
|
extern bool queueRemove(cfTask_t *task);
|
||||||
extern cfTask_t *queueFirst(void);
|
extern cfTask_t *queueFirst(void);
|
||||||
extern cfTask_t *queueNext(void);
|
extern cfTask_t *queueNext(void);
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,38 @@ TEST(SchedulerUnittest, TestQueue)
|
||||||
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
|
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SchedulerUnittest, TestQueueAddAndRemove)
|
||||||
|
{
|
||||||
|
queueClear();
|
||||||
|
taskQueueArray[TASK_COUNT + 1] = deadBeefPtr;
|
||||||
|
|
||||||
|
// fill up the queue
|
||||||
|
for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
|
||||||
|
const bool added = queueAdd(&cfTasks[taskId]);
|
||||||
|
EXPECT_EQ(true, added);
|
||||||
|
EXPECT_EQ(taskId + 1, queueSize());
|
||||||
|
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
|
||||||
|
}
|
||||||
|
// double check end of queue
|
||||||
|
EXPECT_EQ(TASK_COUNT, queueSize());
|
||||||
|
EXPECT_NE(static_cast<cfTask_t*>(0), taskQueueArray[TASK_COUNT - 1]); // last item was indeed added to queue
|
||||||
|
EXPECT_EQ(NULL, taskQueueArray[TASK_COUNT]); // null pointer at end of queue is preserved
|
||||||
|
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]); // there hasn't been an out by one error
|
||||||
|
|
||||||
|
// and empty it again
|
||||||
|
for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
|
||||||
|
const bool removed = queueRemove(&cfTasks[taskId]);
|
||||||
|
EXPECT_EQ(true, removed);
|
||||||
|
EXPECT_EQ(TASK_COUNT - taskId - 1, queueSize());
|
||||||
|
EXPECT_EQ(NULL, taskQueueArray[TASK_COUNT - taskId]);
|
||||||
|
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
|
||||||
|
}
|
||||||
|
// double check size and end of queue
|
||||||
|
EXPECT_EQ(0, queueSize()); // queue is indeed empty
|
||||||
|
EXPECT_EQ(NULL, taskQueueArray[0]); // there is a null pointer at the end of the queueu
|
||||||
|
EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]); // no accidental overwrites past end of queue
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SchedulerUnittest, TestQueueArray)
|
TEST(SchedulerUnittest, TestQueueArray)
|
||||||
{
|
{
|
||||||
// test there are no "out by one" errors or buffer overruns when items are added and removed
|
// test there are no "out by one" errors or buffer overruns when items are added and removed
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue