Callbacky vs. korutiny v C

knuths_daemon

Callbacky vs. korutiny v C
« kdy: 17. 05. 2017, 09:37:46 »
Zdravím, mám prototyp aplikace v C využívající polling, kterýžto podle události volá callbacky. Kód je ale vzhledem k těm callbackům dost špagetový, proto bych rád využil spíše ve všech ohledech lepší korutiny. Problém ale je, že ucontext už je zlikvidovaný  a aplikace je pro MCU, nejspíš tam bude FreeRTOS nebo něco podobného, takže běžné knihovny pro Linux použít nejde. Nějaké typy, jak přepínat mezi fibry? Předpokládám, že v pollingu prostě stačí místo callbacků volat příslušnou čekající korutinu, jen se trochu bojím přepínání kontextu. Stačí prostě uložit registry a přehodit zásobník?


Qeek

Re:Callbacky vs. korutiny v C
« Odpověď #1 kdy: 17. 05. 2017, 10:16:27 »
Jestliže tam poběží nějaký RTOS, není lepší použít přímo jeho korutiny, které přepínání kontextu vesměs řeší za tebe?

dustin

Re:Callbacky vs. korutiny v C
« Odpověď #2 kdy: 17. 05. 2017, 11:23:19 »
Nejsem žádný embedded odborník, ale teď potřebuji vyřešit trochu složitější úkol pro STM32 a docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.

Re:Callbacky vs. korutiny v C
« Odpověď #3 kdy: 17. 05. 2017, 11:40:18 »
docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.
Souhlas, s Chibiosem jsem si taky trochu hrál a moc se mi líbil.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Callbacky vs. korutiny v C
« Odpověď #4 kdy: 17. 05. 2017, 11:41:38 »
docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.
Souhlas, s Chibiosem jsem si taky trochu hrál a moc se mi líbil.
Preemptivní přepínání kontextů ale neřeší dotaz.


dustin

Re:Callbacky vs. korutiny v C
« Odpověď #5 kdy: 17. 05. 2017, 11:53:56 »
Preemptivní přepínání kontextů to přímo neřeší, ale třeba probouzení vláken událostmi, čekání vlákna na signál, mailboxy/fronty mezi vlákny atd. - možná by ten polling vůbec nebyl potřeba, kdyby se využily možnosti embedded OS. Samozřejmě ve finále to na tom jednojádře poběží stejně, ale vývoj může být trochu méně bolestný a bližší programování v normálním OS. Leč nechť každý koná dle svých potřeb.


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Callbacky vs. korutiny v C
« Odpověď #7 kdy: 17. 05. 2017, 12:02:07 »
Preemptivní přepínání kontextů to přímo neřeší, ale třeba probouzení vláken událostmi, čekání vlákna na signál, mailboxy/fronty mezi vlákny atd. - možná by ten polling vůbec nebyl potřeba, kdyby se využily možnosti embedded OS. Samozřejmě ve finále to na tom jednojádře poběží stejně, ale vývoj může být trochu méně bolestný a bližší programování v normálním OS. Leč nechť každý koná dle svých potřeb.
On ten polling (vlastní smyčka) je alternativou, to ano, ovšem využití služeb OS zní jako overkill, když můžu přepínat kontexty v userspacu. Třeba na Arduinu je vlastní implementace jediná možnost.

dustin

Re:Callbacky vs. korutiny v C
« Odpověď #8 kdy: 17. 05. 2017, 12:22:14 »
Ten chibiOS je odladěná docela rozsáhlá (volitelně přikompilovatelná) implementace "vlastní smyčky", samozřejmě nerozlišuje mezi user-space a kernel-space. Mimochodem funguje i pro AVR arduino, ale samozřejmě to má krutě málo RAM. Naposledy jsem pro arduino řešil přesně takovou smyčku ručně + matlal se s prioritami obsluh (např. příjem zprávy přes sériák větší priorita, aby nic nezmeškal, zatímco výpis na grafický TFT počká). V dalším projektu jsem si už připlatil a místo Arduino mini pro za 35 Kč používám STM32 maple mini za 75Kč + vývoj  v chibios v eclipse. Jde to i HW krokovat, ale tam jsem se zatím ještě nedostal.

lopata

Re:Callbacky vs. korutiny v C
« Odpověď #9 kdy: 17. 05. 2017, 12:32:38 »
setjmp a longjmp je možné použít k userspace implementaci korutin.

Sten

Re:Callbacky vs. korutiny v C
« Odpověď #10 kdy: 17. 05. 2017, 12:35:06 »
setjmp a longjmp je možné použít k userspace implementaci korutin.

To už radši getcontext/setcontext, tam nedochází k problémům se sdíleným stackem

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Callbacky vs. korutiny v C
« Odpověď #11 kdy: 17. 05. 2017, 12:38:30 »
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
Kód: [Vybrat]
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.

lopata

Re:Callbacky vs. korutiny v C
« Odpověď #12 kdy: 17. 05. 2017, 12:45:30 »
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
Kód: [Vybrat]
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.

Stack jde hacknout nějak takhle: http://fanf.livejournal.com/105413.html
Hezké to není, ale fungovat by to mělo, pro mikrokontrolér myslím dobré, relativně nenáročné na zdroje a všechno je pod kontrolou v userspace.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Callbacky vs. korutiny v C
« Odpověď #13 kdy: 17. 05. 2017, 13:03:39 »
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
Kód: [Vybrat]
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.

Stack jde hacknout nějak takhle: http://fanf.livejournal.com/105413.html
Hezké to není, ale fungovat by to mělo, pro mikrokontrolér myslím dobré, relativně nenáročné na zdroje a všechno je pod kontrolou v userspace.
Tady akorát záleží, na čem to poběží, aby to zbytečně nebrzdily syscally. Jinak ano, osobně sice preferuju čistší switch zásobníku, ale pokud se někomu ten kód líbí...

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Callbacky vs. korutiny v C
« Odpověď #14 kdy: 18. 05. 2017, 11:11:53 »
Jestliže tam poběží nějaký RTOS, není lepší použít přímo jeho korutiny, které přepínání kontextu vesměs řeší za tebe?
Kooperativní konkurentní běh se vesměs řeší v userspacu (je to levnější) a ani OS nepotřebuje (minimalistické MPU). Obecně vyjma inicializace stačí pro přepnutí sekvence 1. push registrů, 2. přehození zásobníku, 3. pop registrů. Některé jazyky ani s registry nic nedělají, protože mají jiné vhodnější ABI, ale i tak je to operace velmi levná. Vlákna jsou zbytečně drahá, když je stejně k dispozici jen jedno vlákno a veškeré operace jen čekají (buď na senzor nebo data z jiné korutiny). Preemptivní přepínání je ve většinu případů kontraproduktivní (navíc vyžaduje přerušení, čímž se to celé ještě zhorší).