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