ОС2/Пројекат 2022 — разлика између измена

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу
(priča o timeslice)
Ред 18: Ред 18:


== Имплементирање преотимања по временском квантуму ==
== Имплементирање преотимања по временском квантуму ==
 
Концепт временског квантума (''timeslice'') из овог пројекта је исти као онај из школског језгра на ОС1. ''xv6'' мења контекст (преотима) процесе на сваки тајмерски прекид. Ово се може лако променити да подржава преотимање након истека квантума или непостојање преотимања (''nonpreemptive scheduling''). Места од значаја:
# Позив <code>yield()</code> у <code>[[github:/mit-pdos/xv6-riscv/blob/riscv/kernel/trap.c#L80|usertrap()]]</code> се треба догодити само ако је истекао квантум, или никад ако нема преотимања. Овде би се одузимала тренутна вредност све док квантум не истекне.
# Исто и за <code>[[github:/mit-pdos/xv6-riscv/blob/riscv/kernel/trap.c#L154|kerneltrap()]]</code>, који је само случај тајмерског прекида у кернел режиму.
# Праћење временског квантума неког процеса се може имплементирати на разне начине, али најчешћи је памтити га у <code>struct proc</code>, где би онда требало постављати његову вредност у <code>userinit()</code> и <code>fork()</code>.
== Окружење ==
== Окружење ==
=== Makefile ===
=== Makefile ===



Верзија на датум 4. фебруар 2022. у 14:41

Пројекат 2022. године је први пројекат из Оперативних система 1 и 2 у ком се користи xv6 оперативни систем на RISC-V архитектури. У овом водичу се налазе корисни савети при изради пројекта.

Додавање интерфејса распоређивача

Интерфејс дефинисан поставком за распоређивач је исти онај из школског језгра:

struct proc *get(); // Дохватање спремног процеса из реда чекања
void put(struct proc *); // Убацивање спремног процеса у ред чекања

xv6 у себи садржи Round-robin распоређивач директно имплементиран у функцији scheduler(). Неопходно је заменити овај алгоритам са траженим интерфејсом. Места од значаја су она где процес мења стање.

  1. get() у scheduler() након укључивања прекида - прелаз из RUNNABLE у RUNNING.
  2. put() у yield() - кад процес предаје контекст неком другом процесу.
  3. put() у userinit() - кад се креира први кориснички процес.
  4. put() у fork() - кад се форкује нов процес.
  5. put() у wakeup() - прелаз из SLEEPING у RUNNABLE.
  6. put() у kill() - кад процес треба да се заврши треба да га пробудимо.

Имплементирање преотимања по временском квантуму

Концепт временског квантума (timeslice) из овог пројекта је исти као онај из школског језгра на ОС1. xv6 мења контекст (преотима) процесе на сваки тајмерски прекид. Ово се може лако променити да подржава преотимање након истека квантума или непостојање преотимања (nonpreemptive scheduling). Места од значаја:

  1. Позив yield() у usertrap() се треба догодити само ако је истекао квантум, или никад ако нема преотимања. Овде би се одузимала тренутна вредност све док квантум не истекне.
  2. Исто и за kerneltrap(), који је само случај тајмерског прекида у кернел режиму.
  3. Праћење временског квантума неког процеса се може имплементирати на разне начине, али најчешћи је памтити га у struct proc, где би онда требало постављати његову вредност у userinit() и fork().

Окружење

Makefile

Дебаговање корисничких програма

Да би дебаговали корисничке програме, морате у конфигурацији за дебаговање у окружењу променити бинарни фајл који ће gdb-multiarch да дебагује (подразумевано сам кернел).

  • Мени RunEdit ConfigurationsRemote DebugDebug (или ваш назив конфигурације) → Symbol file промените на бинарни фајл корисничког програма (налазе се у директоријуму /user/ и сви почињу са доњом цртом).
  • Поставите breakpoint, покрените ОС са qemu-gdb и у њему покрените изабрани програм.

Промена учестаности тајмерског прекида

У сврху тестирања на одбрани је понекад тражено да се повећа учестаност прекида ради прецизнијих мерења перформанси (помоћу системског позива uptime()) и видљивијег ефекта распоређивања. Интервал тајмера се може променити у фајлу start.c у функцији timerinit().

Тумачење scause и sepc

Прескочене су резервисане вредности.

scause вредност Значење Потенцијални проблем
0 Адреса у PC није поравната Кернел је променио контекст у невалидан процес (вероватно је распоређивач вратио невалидан процес).
1 Грешка у приступу инструкцији
2 Илегална инструкција Уколико користите floating-point типове, они нису подржани на овој имплементацији RISC-V.
3 Breakpoint Не би требало да се појави као разлог за панику.
4 Адреса са које се чита није поравната Лош показивач.
5 Грешка у приступу при читању
6
  • Адреса у коју се пише није поравната
  • Атомична инструкција приступа адреси која није поравната
7 Грешка у приступу при писању/атомичној инструкцији.
8 ecall из корисничког режима Не би требало да се појави као разлог за панику.
9 ecall из супервизорског (кернел) режима Не би требало да се дешава уопште у xv6.
c Странична грешка при учитавању инструкције Кернел је променио контекст у невалидан процес (вероватно је распоређивач вратио невалидан процес).
d Странична грешка при читању
  • Кернел је променио контекст у невалидан процес (вероватно је распоређивач вратио невалидан процес).
  • Лош показивач.
f Странична грешка при писању/атомичној инструкцији
  • Кернел је променио контекст у невалидан процес (вероватно је распоређивач вратио невалидан процес).
  • Лош показивач.

Вредност sepc регистра означава вредност PC у тренутку кад је настала грешка. Може се тачно пронаћи место у коду претраживњем ове адресе у фајлу kernel.asm који садржи и C код кернела и генерисани RISC-V асембли са тачном адресом инструкција.