LINUX.ORG.RU

История изменений

Исправление 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.