История изменений
Исправление KivApple, (текущая версия) :
Завершение процесса - очень редкая ситуация для микроконтроллера. Ради такого дела можно и прерывания позапрещать. Подразумевается, что память не освобождается. Могут только создаваться новые элементы очереди и добавляться с помощью schedulerResumeTask, а также добавляться-удаляться в очередь-из очереди существующие.
Я тут исправил ряд косяков. Теперь всё выглядит так:
Thread * volatile threadQueue[TASK_SCHEDULER_MAX_PRIORITY + 1];
volatile int threadMaxRunningPriority = 0;
inline Thread *schedulerFindNextTask(void) {
Thread *nextThread = NULL;
do {
int maxRunningPriority = threadMaxRunningPriority;
while (maxRunningPriority >= 0) {
nextThread = threadQueue[maxRunningPriority];
if (nextThread != NULL) {
break;
}
int newMaxPriority = maxRunningPriority - 1;
__sync_bool_compare_and_swap(&threadMaxRunningPriority, maxRunningPriority, newMaxPriority);
maxRunningPriority = threadMaxRunningPriority;
}
} while (nextThread && (!__sync_bool_compare_and_swap(&threadQueue[nextThread->priority], nextThread, nextThread->nextScheduled)));
return nextThread;
}
void schedulerResumeTask(Thread *thread) {
if (!__sync_bool_compare_and_swap(&(thread->running), false, true)) return;
while (true) {
if (threadQueue[thread->priority] == NULL) {
thread->nextScheduled = thread;
if (__sync_bool_compare_and_swap(&threadQueue[thread->priority], NULL, thread)) {
break;
}
} else {
thread->nextScheduled = threadQueue[thread->priority]->nextScheduled;
if (__sync_bool_compare_and_swap(&(threadQueue[thread->priority]->nextScheduled),
thread->nextScheduled, thread)) {
break;
}
}
}
int maxPriority, newMaxPriority;
do {
maxPriority = threadMaxRunningPriority;
newMaxPriority = (thread->priority > maxPriority) ? thread->priority : maxPriority;
} while (!__sync_bool_compare_and_swap(&threadMaxRunningPriority, maxPriority, newMaxPriority));
}
void schedulerSuspendTask(Thread *thread) {
if (!__sync_bool_compare_and_swap(&(thread->running), true, false)) return;
while (true) {
Thread *prev = threadQueue[thread->priority];
if (prev == NULL) break;
while (prev->nextScheduled != thread) {
prev = prev->nextScheduled;
}
if (__sync_bool_compare_and_swap(&(prev->nextScheduled), thread, thread->nextScheduled)) {
if (__sync_bool_compare_and_swap(&(threadQueue[thread->priority]), thread, thread->nextScheduled)) {
__sync_bool_compare_and_swap(&(threadQueue[thread->priority]), thread, NULL);
}
break;
}
}
}
Спасибо большое за подсказки.
Исходная версия KivApple, :
Завершение процесса - очень редкая ситуация для микроконтроллера. Ради такого дела можно и прерывания позапрещать. Подразумевается, что память не освобождается. Могут только создаваться новые элементы очереди и добавляться с помощью schedulerResumeTask.