Несмотря на то, что вам уже ответили с хорошим ответом
Ваш обработчик сигнала вызывает sched (), который никогда не возвращается (но заканчивается в любом из for (;;)...
проблема с вашей многозадачной реализацией заключается в том, что для работы переключателя задач необходимо выполнить переключение контекста. Переключатель контекста - это процедура, которая не возвращается, пока не выполнит весь контекстпереключается на другие процессы, и следующая задача, которая должна быть запланирована, должна быть возвращена.Это некий король вызова
yield();
, но фактическое переключение контекста происходит внутри yield.switch - это то, что не может быть реализовано в виде простой подпрограммы (некоторый фрагмент кода, который вы вызываете и возвращаете), потому что он должен возвращать в другом контексте . Для этого вам нужно вызвать yield()
и кодyield должен изменить все регистры процессора на значения, которые они имели в контексте other (включая указатель стека, так что это назначение, которое выВам потребуется два стека), а затем продолжить выполнение этого кода (что заставит программу вернуть в другом контексте )
Так что вам нужно найти местохранить контексты всех задач, которые вы собираетесь разрешить выполнять параллельно.Это включает в себя состояние процессора и стек задачи.Затем вам нужна подпрограмма (это то, что фактически переключает контекст), которая хранит старый контекст (тот, который использует процессор) в хранилище сохранения и вызывает (и устанавливает) контексты новой задачи, которая должна быть запланирована.Что-то вроде:
void task_switch(struct context *old_ctx, struct context *new_ctx);
и эта подпрограмма должна быть написана на ассемблере .... как она должна делать переключение контекста, которое включает в себя переключение стеков каждой задачи.
Как вы видитеэто сейчас?