[OSy] Nestihajici zapsani CP0 compare registru

Michal Klempa michal.klempa at gmail.com
Wed Nov 3 13:22:30 CET 2010


Podarilo sa mi najst po dlhom citani archivov tento mail
https://d3s.mff.cuni.cz/pipermail/osy/2007-October/000767.html
Ktory ciastocne odpoveda. Pise sa tam
"Timer muze bezet jak v kontextu vlakna, ktere jej zaregistrovalo (a na ukor
jeho planovaciho casu), tak v samostatnem vlakne, ktere je dedikovano pro
obsluhu timeru"

A tak daleko som sa (ako vidno z prveho mailu) este nedostal, aby som
dokazal ten handler pustit v kontexte toho vlakna, ktoreho si spravilo
timer_start. Ako take nieco spravit? Ved vlaknu sa nastavi panensky kontext
a potom sa prepne na neho prvy krat a uz zacne vykonavat 'user supplied'
funkciu.
Mal by som mu nejak zmenit program counter na obsluznu rutinu a preplanovat?
Pricom na konci obsluhy timera by som mal vzdy jump naspat na program
counter, kde vlakno bolo predtym, nez som mu zacal vnucovat timer?

Pri zpracovavi v samostatnom vlakne som stale lamer v tom, ze kto na neho
potom preplanuje, ked aj planovac pouziva timer framework.
Zatim
Michal Klempa

2010/11/3 Michal Klempa <michal.klempa at gmail.com>

> Zdravim,
>
> On Tue, 02 Nov 2010 14:00:17 +0100
> Martin Decky <decky at d3s.mff.cuni.cz> wrote:
>
> > Hezky den,
> >
> > priste bych prosil psat podobne dotazy prednostne do konference ..
> >
> > > Takze sa mi stane, ze nastavim compare na 43907 ale count uz je
> > > 44010 napriklad. Tento delay v mojom kode som metodou try&fail
> > > odhadol na 200 tickov a jednoduchy patch je samozrejme nastavit ten
> > > compare o 200 tickov dalej v adekvatnych pripadoch.
> >
> > Asi nezbyva nez cely ten algoritmus udelat robustne. Stejne se musite
> > probouzet periodicky z duvodu planovani, takze v planovaci muzete
> > otestovat, zda od posledniho pruchodu timery nejake nahodou
> > nevyprsely, aniz by se provedly, a primo je provest nebo oznacit k
> > provedeni (podle toho, v jakem kontextu obsluzne rutiny casovacu
> > provadite).
> Mam timer, ktory si pusta priamo scheduler, takze raz cas sa aktivuje
> funkcia 'schedule' volana ako handler nejakej struct timer:
> schedule_init () {
>
>        timer_init(&tmr[cpuid()], 2000, &schedule_on_timer, ...)
>        timer_start(&tmr[cpuid()]);
> }
>
> schedule () {
> ....
> timer_start(&tmr[cpuid()]);
> // namisto write_cp0_count(read_cp0_count() + QUANTUM);
>
> Ked handlujem timer interrupt, vytiahnem
> vsetky timery, ktore uz vyprsali z listu (so zakazanymi interruptmi) a
> nahadzem si ich do lokalnej premennej (povedzme ze pole). Teda si ich
> nahadzem na stack threadu, na ktoreho ucet bezi obsluha timer
> interruptu.Nasledne povolim interrupty a zacnem postupne vykonavat
> vsetky vyprsane timery:
>
> timer_handle_int() {
>        array to_procces;
>        query_and_disable_ints()
>        while ((x= pending_timers_get_nearest()).time < real_time) {
>                pending_timers_extract(x);
>                t.append(x);
>        }
>        conditionally_enable_ints();
>
>        foreach (tmr in to_process) {
>                tmr.handler(tmr, tmr.data);
>        }
> }
>
> Este napisem ako radovo vyzera timer_start:
> timer_start(tmr) {
>        query_and_disable_ints()
>        tmr.scheduled_ticks= read_cp0_count() + tmr.usec * 4;
>        pending_timers_insert(tmr);
>        new_timer= pending_timers_get_nearest();
>        write_cp0_compare(
>                max(read_cp0_count() + 200, new_timer.scheduled_ticks)
>        );
>        conditionally_enable_ints();
> }
>
> Lenze ked pride niekto a napise program:
> void* thread_run (void*) {
> putc('1');
> timer_start(&tmr)
> }
>
> kde usec = velmi malo...
>
> Stane sa toto, nastavi sa timer -> nastavi sa compare (urcite vacsie
> ako count). Vyvola sa interrupt hned ako to je mozne, pusti sa
> timer_handle_int(), vytiahne si timer a povoli interrupty. Hned ako
> spusti znovu tento kod
> putc('1');
> timer_start(&tmr)
>
> Znova sa zaradi do pending_timers, ak je tam prvy, znova sa nastavi
> compare. A znova dostanem interrupt, zavola sa timer_handle_int() a
> vytiahne sa timer z fronty, zacne sa spracovavat. A znova a znova...
> teoreticky stale na ucet toho isteho threadu, az dokym nepride timer
> schedulera na rad. A takto mu mozem vycerpat stack, na to ze stale robi
> rekurziu do timer_handle_int() v podstate.
>
> Otazka je, maju sa spracovavat handlery timerov so zakazanym
> interruptom?
>
> Rozmyslal som, ze by timery mohol spracovavat samostatny thread, okrem
> toho, ze by to bolo pomale (bud kym sa preplanuje  - cely interval
> schedulera, alebo natvrdo context switch- trva cely context switch) to
> ani neviem naprogramovat lebo som strasny lamer:-) Napriklad nahadzem
> na queue timery ktore ma specialny thread spracovat a zrazu nema na
> neho kto preplanovat lebo aj scheduler je riadeny timerom:-) Takze by
> som musel robit 'switch_to_thread' vzdy ked tam nejaky timer prihodim
> na tu queue, a to je uz to iste ako ho spracovat rovno.
>
> >
> > > Otazka moja je (ktoru neviem z manualov vycitat), je moznost (a ako)
> > > priamo nastavit IP7 bit v kode (pri zakazanych interruptoch), takze
> > > by sa hned ako povolim interrupty vyvolal interrupt 7 a handlovanie
> > > timerov?
> >
> > Ne, bit IP7 programove nastavit nelze, muze to udelat pouze procesor
> > sam pri rovnosti Count a Compare registru. Uvedomte si ale, ze muzete
> > nastavovat nejen hodnotu registru Compare, ale take hodnotu registru
> > Count, takze vzdy, kdyz potrebujete naplanovat dalsi probuzeni, tak
> > muzete zajistit, ze Count < Compare.
> Myslim ze som to dokazal kodom vyssie, nejaka rozumna konstanta tam asi
> vzdy bude musiet byt, lebo samotne write_cp0_compare a read_cp0_count
> nieco trvaju, tak aby som tam zapisal nieco urcite vacsie, ako pocet
> tickov ktore trva kym sa vykonaju tieto instrukcie.
>
> >
> > > Minimalne by som sa zbavil nejakeho 200 tick delayu, samozrejme
> > > timery by tam pretekali aj tak: ked raz niekto zavola timer_start(1
> > > usec) tak sa moze aj na kolomaz rozliat a nestihnem ho zobudit za
> > > jednu mikrosekundu. Ale bolo by to aspon pekne.
> >
> > Probuzeni presne za 1 usec neni rozhodne nutne, zadani to nepozaduje
> > a pochopitelne to v non-RT systemu ani nemuzete nijak garantovat.
> > Obsluzna rutina timeru by se nemela zavolat drive nez po vyprseni
> > timeoutu, ale pokud se zavola v rozumne dobe po vyprseni, vse je OK.
> >
> > Planovaci kvantum urcite odpovida definici "rozumne doby".
> >
> >
> > M.D.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://d3s.mff.cuni.cz/pipermail/nswi004/attachments/20101103/c08152ca/attachment.html>


More information about the NSWI004 mailing list