/*push(stack *, int): запись элемента в стек */
/********************************************************************/
void push(stack *a_stack, int item) {
fprintf(outputfile, "\n\nBefore push - stack pointer: %d",
a_stack->stack_top);
if (!(stack_full(*a_stack))) /*проверка заполнения стека*/
/* перед записью элемента*/
{
a_stack->stack_item[a_stack->stack_top] = item;
fprintf(outputfile, "\nstack item after push: %d",
a_stack->stack_item[a_stack->stack_top]);
a_stack->stack_top = a_stack->stack_top + 1;
fprintf(outputfile, "\nstacktop after push: %d",
a_stack->stack_top);
} else fprintf(outputfile, "\nCannot push - stack is full!");
}
/********************************************************************/
/*pull(stack *): извлечение элемента из стека */
/********************************************************************/
int pull(stack *a_stack) {
int item;
fprintf(outputfile,"\n\nBefore pull - stack pointer: %d",
a_stack->stack_top);
if (!(stack_empty(*a_stack))) /*проверка не пуст ли стек */
/*перед извлечением элемента*/
{
item = a_stack->stack_item[a_stack->stack_top-1];
fprintf(outputfile, "\nstack item pulled: %d", item);
a_stack->stack_top = a_stack->stack_top - 1;
fprintf(outputfile,"\nstacktop after pull: %d",
a_stack->stack_top); return item;
} else fprintf(outputfile, "\nCannot pull - stack is empty!");
}
/********************************************************************/
Мы показали работу этого примера на рис. 8.12. После выполнения этой программы будет выдан следующий код:
Рис. 8.12.Запись в стек и извлечение из стека
Stack top: 0
Stack Empty!
Stack is not full.
Stack top: 0
Stack Empty!
Cannot print - stack is empty!
Before push - stack pointer: 0
Stack is not full.
stack item after push: 11
stacktop after push: 1
Before push - stack pointer: 1
Stack is not full.
stack item after push: 12
stacktop after push: 2
Before push - stack pointer: 2
Stack is not full.
stack item after push: 13
stacktop after push: 3
Before push - stack pointer: 3
Stack is not full.
stack item after push: 14
stacktop after push: 4
Stack top: 4
Stack is not empty.
Stack item: 0
Stack item: 14
Stack item: 13
Stack item: 12
Stack item: 11
Before pull - stack pointer: 4
Stack top: 4
Stack is not empty
stack item pulled: 14
stacktop after pull: 3
Before pull - stack pointer: 3
Stack top: 3
Stack is not empty.
stack item pulled: 13
stacktop after pull: 2
Before pull - stack pointer: 2
Stack top: 2
Stack is not empty,
stack item pulled: 12
stacktop after pull: 1
Before pull - stack pointer: 1
Stack top: 1
Stack is not empty.
stack item pulled: 11
stacktop after pull: 0
Before pull - stack pointer: 0
Stack top: 0
Stack Empty!
Cannot pull - stack is empty!
Несколько стеков.Обычно система микропроцессора содержит один стек. Этот стек объявляется внутри RAM, и процессор имеет несколько функций для объявления положения стека (LDS), записи данных (PUSH), извлечение данных из стека (PULL) и т.д. Кроме того, как мы уже рассказывали в главе 4, в процессор встроен целый ряд аппаратных функций, связанных стеком, таких, как сохранение данных программного счетчика и ключевых регистров. В операционной системе реального времени нам нужен будет стек для каждой задачи, в котором мы будем сохранять контекст. Следовательно, мы должны иметь несколько стеков для работы с системами ОСРВ. В этих случаях, мы используем понятия о стеке, рассмотренные в этом разделе. Мы могли бы легко объявлять дополнительные стеки, использовав приведенный выше код. Кроме того, таким же образом может работать любой из стеков, которые мы объявим.
На этом мы завершаем обзор основных конструкций, которые используются для реализации операционной системы в режиме реального времени. Мы теперь собираемся сместить акценты и обсудить дополнительные концепции ОСРВ в следующем разделе. Мы расстаемся с конструкциями и концепциями, чтобы описать, как программировать различные ОСРВ.
Ранее в этой главе мы сказали, что ОСРВ — компьютерная операционная система, которая должна своевременно обрабатывать несколько событий при ограниченных ресурсах процессора. Наше исследование ОСРВ начинается с определения понятия задачи. Это потребует радикального изменения нашего понимания программ (сдвига парадигмы). При наличии в системе только одного последовательного процессора, мы можем рассматривать программу как последовательность шагов, которые процессор выполняет один за другим по определенному алгоритму. В ОСРВ, наша программа состоит из независимых, асинхронных (могущих появиться в любое время) взаимодействующих задач. И все они будут конкурировать за драгоценное (и ограниченное) время обработки. Наша программа состоит из механизмов, позволяющих следить за состоянием каждой задачи, планировать задачи для выполнения, и удостовериться, что каждая задача получает необходимую долю процессорного времени.
Читать дальше