Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 28 мар 2024, 14:47

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
СообщениеДобавлено: 16 ноя 2017, 03:16 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Мы с Лёшей Большаковым спроектировали и реализовали модуль для кооперативной многозадачности. Вот пример с летающими шариками, тут никакой синхронизации, всё дёргается. Но фишка не в этом. Все шарики двигаются внутри вот этой одной процедуры, выполняемой параллельно 8 раз:

Код: "OBERON"
  1. PROCEDURE MoveBall;
  2. VAR
  3. x, y: INTEGER; sx, sy: SHORTINT;
  4. BEGIN
  5. x := b.RND(20, 240); y := b.RND(20, 160);
  6. sx := SHORT( b.RND(0, 1) ); IF sx = 0 THEN sx := -1 END;
  7. sy := SHORT( b.RND(0, 1) ); IF sy = 0 THEN sy := -1 END;
  8. g.PUTSPR(x, y, 1, 8, SYSTEM.ADR(Ball), g.XORSPR);
  9. LOOP
  10. g.PUTSPR(x, y, 1, 8, SYSTEM.ADR(Ball), g.XORSPR);
  11. IF (x < 1) OR (x > 247) THEN sx := -sx END;
  12. x := x + sx;
  13. IF (y < 8) OR (y > 190) THEN sy := -sy END;
  14. y := y + sy;
  15. g.PUTSPR(x, y, 1, 8, SYSTEM.ADR(Ball), g.XORSPR);
  16. t.Yield;
  17. END;
  18. END MoveBall;

PUTSPR - процедура Сержа Колотова для вывода спрайта с пиксельной точностью. Я её не модифицировал для работы с буфером. И критики по поводу дёрганья шариков не жду. Именно для шариков лучше было бы делать всё в цикле. Это я так, для теста. Модуль Tasks и примеры его использования залиты в репозиторий.

Переключение контекста задач очень легковесное, буквально несколько машинных команд.

Вот документация на модуль:

Код: "OBERON"
  1. MODULE Tasks; (* non-portable *)
  2.  
  3. (*
  4.   Модуль обрабатывает следующие нештатные ситуации:
  5.   22 "Statement lost" - Run запущен не из "главной" задачи
  6.   25 "Parameter error" - эта задача уже есть в списке
  7. *)

Каждая задача обладает своим собственным стеком и может иметь локальные переменные. Поэтому ей требуется своя память для работы. Для этого статически или динамически создаётся переменная, которая хранит память для задачи. Представлены следующие модели задач, отличающиеся размером стека:

Код: "OBERON"
  1. TYPE
  2. Low = RECORD (Context) stack: ARRAY 20 OF BYTE END;
  3. Tiny = RECORD (Context) stack: ARRAY 40 OF BYTE END;
  4. Small = RECORD (Context) stack: ARRAY 60 OF BYTE END;
  5. Medium = RECORD (Context) stack: ARRAY 80 OF BYTE END;
  6. Large = RECORD (Context) stack: ARRAY 100 OF BYTE END;
  7. Huge = RECORD (Context) stack: ARRAY 120 OF BYTE END;

Модель Tiny имеет размер стека 40 байтов, и этого достаточно для обработки прерывания IM 1. Модель Low гарантированно упадёт при обработке прерывания IM 1 и нужна для особых случаев (работа в режиме DI).

Код: "OBERON"
  1. PROCEDURE Count (): SHORTINT;
Возвращает количество запущенных задач. В коде есть ограничение на предел количества задач - 255. Ограничение видится разумным, т.к. при большом количестве задач тратится всё больше ресурсов на переключение их контекста. Плюс ещё и память. Модель Tiny берёт 50 байт на задачу. 50x255 = 12750 байт.

Код: "OBERON"
  1. PROCEDURE Spawn ((*VAR*) ctx: Context; proc: PROCEDURE);
Ставит задачу proc в очередь выполнения. Выполнение начнётся по кольцу при вызове процедуры Run.

Код: "OBERON"
  1. PROCEDURE Id (ctx: Context): INTEGER;
Возвращает id (идентификационный уникальный номер) контекста - двухбайтовое целое число.

Код: "OBERON"
  1. PROCEDURE MyId (): INTEGER;
Возвращает свой id, т.е. текущей выполняемой задачи. В случае основной задачи он равен 0.

Код: "OBERON"
Выполняет атом одной из задач в кольце. Нормальное использование Run - вызывать в цикле, пока есть активные задачи: REPEAT Tasks.Run UNTIL Tasks.Count() = 0
Run спроектирован таким образом, чтобы после каждого атома (Yield) отдавать управление основной задаче. Это может понадобиться для выполнения в основной задаче каких-то действий с более высоким приоритетом.

Код: "OBERON"
Своеобразный "разрыв". Вызывается внутри задачи для передачи управления другим задачам.

Смотрите примеры работы с модулем Tasks: TestTasks и MoveBalls.


Вложения:
MoveBalls.zip [1.06 КБ]
Скачиваний: 448
Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 23 янв 2018, 08:29 
Не в сети
Администратор
Аватара пользователя

Сообщения: 86
Цитата:
Возвращает количество запущенных задач.

Как-то сразу вспоминаю недавний срач за углом)) Поводом послужило:
На одном процессоре может быть несколько задач и один процесс.
На нескольких процессоров может процессов по числу процессоров несколько задач на каждом процессоре))

_________________
Действия профессионала предсказуемы. Но в мире полно любителей!


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club