Többszálúság fejtágító

Fórumok

Egyesek fejében hatalmas káosz és sötétség kavarog ennek kapcsán, ezért úgy gondoltam, írok egy mini fejtágítót. Előrebocsátom, hogy az alábbi definíciók NEM teljesek, szándékosan hiányosak és leegyszerűsítettek, csupán azokat az aspetusokat emeltem ki belőlük, melyek a többszálúság kapcsán relevánsak.

Multithreading

A végrehajtás úgy történik, hogy a processzorban van ún. utasításszámláló regiszter, ez tárolja a soronkövetkező gépi kódú utasítás memóriabeli címét.
Ezt a regisztert szokás PC-nek hívni (Program Counter, Motorola, ARM, stb. processzorokon) vagy IP-nek (Instruction Pointer, x86-on).

Ha ennek a regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk.

Multitasking

Ellőbbitől független dolog, de az előfeltétele ennek, többszálúság nélkül nincs multitasking se. Ilyenkor jellemzően az összes többi regiszter is mentődik az utasításszámlálóval együtt, emiatt címtérváltás is bekövetkezhet. Három fajtája létezik:

- Szekvenciális az, ha az új szál lefutása után kerül csak vissza a vezérlés a megszakított szálra.
- Ko-operatív az, ha létezik egy ún. yield hívás, aminek hatására visszaadódik a vezérlés a megszakított szálra (vagy egy bármilyen másik szálra).
- Pre-emptív az, ha egy időzítő segítségével akkor is átatódik a vezérlés egy másik szálra, ha az éppen végrehajtott szál nem hív yield-et és nem is fejeződött még be.

Régi szép időkben egyértelmű volt ez a dolog, mert a processzek közti kapcsolás a kernelben történt és címteret is váltott, a pthread-ek közti kapcsolás pedig egy processzen és egy címtéren belül történt, és a kernel nem is tudott róla.

A mai kernelekben már kicsit összetettebb dolog amióta léteznek a SYS_set_tid_address, SYS_sched_setscheduler stb. rendszerhívások; azóta a kernel nemcsak a különböző címterű processzekről tud, hanem az egy címtéren belüli szálakról is, és azok kapcsolását is ő végzi (ez egyébként a multicore miatt szükséges, lásd alább). Ez a megoldás egyébként a Solaris kernelből eredeztethető, ahol LightWeight Process-nek hívták az ilyen közös címtéren belüli szálakat.

Multicore (hyperthreading, SMP)

Ezt sajnos helytelenül hívják néha multithreading-nek, de ennek semmi köze az első pontban leírthoz. A többmagvas processzor azt jelenti, hogy egyszerre több utasításszámláló regiszterrel is gazdálkodhatunk.
De mégyegyszer, ennek semmi, de semmi köze a fenti kettőhöz, egy egymagvas processzoron is simán megvalósítható a multithreading és a multitasking, ezért jobb ezt multicore-nak, hyperthreading-nek (vagy esetleg SMP-nek, Symmetric Multi Processing-nek hívni).

- Ha a szálak száma meghaladja a processzormagok számát, akkor látszólagos párhuzamosságról beszélünk. Ilyenkor időosztásos (time sharing) módon több szál hajtódik végre és osztozik egy adott processzormag utasításszámláló regiszterén (ehhez mindenképp kell multitasking).
- Valós párhuzamosságról akkor beszélünk, ha a szálak száma kevesebb vagy egyenlő, mint a rendelkezésre álló processzormagok száma. Ilyenkor minden szál saját processzormagot, és azzal saját dedikált utasításszámláló regisztert kap (ekkor nem előfeltétel a multitasking).

Ps: teljesség kevéért van még a nem szimmeltrikus multicore is, de abba most ne menjünk bele, mert a többszálúság elmagyarázáshoz nincs rá szükség.
Ps2.: vegyük észre, mikor előfeltétel a multitasking és mikor nem. Szerevereken, asztali gépeken mindig rengeteg a processz és a szál, több, mint a mag, ezért mindig van multitasking is. Olyan, hogy multitasking nélkül létezik multithreading, jellemzően csak ipari PLC-ken meg néhány embedded IOT eszközön fordul elő, máshol nem.

Blokkoló IO

Ez azt jelenti, hogy az IO hívás blokkolja a hívót, és annak a következő utasítása nem hajtódik végre, amíg az IO művelet be nem fejeződik.

Nem-blokkoló IO

Ez csak annyit jelent, hogy az IO hívás egyből visszatér, azonban SEMMIT, de SEMMIT nem jelent arra nézve, hogy aztán a későbbiekben hogyan értesül a hívó az IO művelet befejeztéről.
Jellemzően két fajtája van: ami többször is hívható és kóddal tér vissza (nem multithreadinges O_NONBLOCK read/write), és a callback alapú (multithreadinges, alacsony szinten csakis a POSIX szignálok ilyenek, semmi más, pl. SIGINT, SIGIO vagy stílusosan SIGHUP :-) ).

Szekvenciális IO

Ez azt jelenti, hogy egyszerre csak egyetlen IO kéréssel foglalkozhat a hívó. FIGYELEM! Nem arról van szó, blokkol-e vagy sem, hanem hogy hány IO kéréssel tud foglalkozni egyszerre.

Aszinkron IO

Aszinkron IO-ról abban az esetben beszélhetünk, ha az IO kérések feldolgozása NEM SZEKVENCIÁLIS, hanem párhuzamos, azaz az egyik IO kérésnek nem kell várnia egy másik IO kérés feldolgozására.
Ismét nem arról van szó, hogy blokkol-e vagy sem, multithreading esetén simán lehet blokkoló is aszinkron, mert csak az adott IO művelethez tartozó szál blokkolódik, a többi vígan futkorászik tovább.

Multiplexing

Multiplexing az, ha több nem-blokkoló IO kontextussal rendelkezünk, és ezeket egyetlen szálon AKTÍVAN pollozuk. Multiplexer nem lehet aszinkron, mert hiába a több IO kontextus, a feldolgozásuk mindenképp szekvenciális, azaz egyszerre csak egy IO kéréssel tud foglalkozni, a többinek várakoznia kell.

Összefoglalva:
- minden multitask egyben kötelezően multithread is, de nem minden multithread multitask
- minden multicore egyben kötelezően multithread is, de nem minden multithread multicore
- minden aszinkron egyben kötelezően multithread is, de nem minden multithread aszinkron
- szekvenciális (és a multiplexing) nem multithreading
- blokkoló IO hívás lehet szekvenciális (POSIX alapeset) és aszinkron is (multithreading esetén, IO-ként egy-egy szál blokkolt vagy sem)
- nem-blokkoló IO hívás lehet szekvenciális (ha nem multithreading, azaz multiplexing) és aszinkron is (ha multithreading)

Hozzászólások

Félre ne érts, nem kötözködni akarok, csak a jobbító szándék vezérel. Szóval a fenti dolgok nagy részével a gyakorlatban találkoztam, de ha nem tudnám mit akarsz elmagyarázni, biztos hogy nem ebből jönnék rá. Megpróbálom kiegészíteni. De igazából aki nem tudja legalább nagyjából, hogy hardver és oprendszer szinten mi történik, annak kár erőlködni a megértéssel.
Az első két fogalom: jobb lenne thread-nek és process-nek nevezni. Mind a kettő egy önállóan futtatott kód. A lényeges különbség, hogy egy process-hez felosztható több thread-ra (mindig van pontosan egy gazda), de a thread-ek a process-ektől eltérően egy címtérben futnak. Kivétel amikor nincs process egyáltalán, mert pl. az adott processzor nem képes címtereket elválasztani (lásd MMU). De ez tényleg régen volt csak.
A multicore/hyperthreading mérőszámok azt mutatják meg, hogy a processzor hány process-t és/vagy thread-et tud natívan egyszerre futtatni. Ha ez kisebb mint a futni kívánók száma, akkor jön az emuláció, ami az általad is leírt multitasking módok szerint valósulhat meg.

Szekvenciális io: itt nem a hívó hanem a végrehajtó tud egyszerre egy kéréssel foglalkozni szerintem. De az oprendszer simán emulálhat neki egy queue-t.

Multiplexing: itt nem tudom mire gondolsz. Normális esetben a multiplexing azt jelenti, hogy egy csatornára összemixelek több adatfolyamot. Lehet hogy más kontextusban másképp használják, de akkor írd oda.

Félre ne érts, nem kötözködni akarok, csak a jobbító szándék vezérel.

Semmi gond, köszönöm a hozzászólásodat!

ha nem tudnám mit akarsz elmagyarázni, biztos hogy nem ebből jönnék rá.

Igen, nem véletlenül tituláltam mini fejtágítónak. Simán meg tudnék tölteni egy könyvet is ezzel, itt csak egy gyors glossary-t akartam, mert a másik topikumban pár dilettáns láma troll össze-vissza beszélt.

aki nem tudja legalább nagyjából, hogy hardver és oprendszer szinten mi történik, annak kár erőlködni a megértéssel.

Való igaz, konkrétan ezt írtam nekik a másik topikban: "Kopipészt huszárok vagytok, csak a magas szintű API hívásokról van némi homályos sejtésetek, de amint az a kérdés, hogy mi is történik a motorháztető alatt alacsony szinten, beadjátok a kulcsot, fingotok sincs semmiről".

Az első két fogalom: jobb lenne thread-nek és process-nek nevezni.

Nem. multithreading != thread és multitask != process.

Például, a megszakításvezérlő multithreading-es, de semmi köze ennek az operációs rendszer által biztosított pthread-hez sem a process-ekhez. A POSIX által biztosított signal-ok ugyancsak multithreading-ek, de megint csak semmi közük a pthread-hez (nem pthread-es processz is használhat signal-okat).

És a mutitask sem azonos a processkapcsolással, mert pthread-ek között is kell kapcsolni, az elv itt is pontosan az, amit leírtam. Azt is leírtam, hogy a threadkapcsolás és a processkapcsolás abban tér el, hogy utóbbi címteret is kapcsol.

A lényeges különbség, hogy egy process-hez felosztható több thread-ra (mindig van pontosan egy gazda), de a thread-ek a process-ektől eltérően egy címtérben futnak.

Így van, ezt külön ki is emeltem. A címtérváltás egyébként x86-on úgy történik, hogy a General Purpose Register-eken kívül a 3-as számú kontrollregiszter is mentődik és beállítódik. Ez a kontrollregiszterváltoztatás egyben vezérli az MMU-ban a TLB flush-t is.

Ha ez kisebb mint a futni kívánók száma, akkor jön az emuláció

Pontosan ezt írtam, itt nem értem, min kéne változtatnom. Annyi csak, hogy "emuláció" helyett a "látszólagos párhuzamosság" szókapcsolatot használtam, mert szerintem az jobban kifejezi a time sharing lényegét.

Szekvenciális io: itt nem a hívó hanem a végrehajtó tud egyszerre egy kéréssel foglalkozni szerintem.

Gözöm sincs, hogy mit értesz ebben a kontextusban "végrehajtó" alatt, de biztos nem. Az IO kérés feldolgozását az végzi, aki az IO műveletet meghívta, azaz a hívó. (Itt most lényegtelen, hogy a read()-re visszaadott adatról vagy a write() esetleges hibakódjáról van-e szó, a lényeg, hogy a műveletet hívónak kell foglalkoznia ezzel.)

De az oprendszer simán emulálhat neki egy queue-t.

Nem számít. Itt nem az a kérdés, hogy honnan kerül a hívó memóriájába az adat, hanem az, hogy amíg molyol rajta, addig történhet-e másik IO feldolgozás vagy sem.

Multiplexing: itt nem tudom mire gondolsz. Normális esetben a multiplexing azt jelenti, hogy egy csatornára összemixelek több adatfolyamot.

Majdnem, nagyjából igen, ezt, de pontosítanék, nincs "összemixelve" egy csatornára, hanem több várakozó csatorna közül az választódik ki, amelyiken végzett már az IO művelet és el lehet kezdeni a feldolgozását. Hogy nagyon nagyon egyértelmű legyek, POSIX man 2 select és man 2 ppoll (persze nem csak ezekkel lehet multiplexelni, de ez az iskolapélda rá).

Figyeld meg, szó sincs arról, hogy egyetlen csatornába mixelnének, hanem hívásonként különböző fd-ket (nfds elemű fds tömb valamelyik elemét) adhatja mindkettő vissza, attól függően, melyik fd-n végzett az IO művelet már és áll rendelkezésre adat (vagy írásnál melyik fd fogad adatot). Nyilván el tudok képzelni persze olyan implementációt is, ahol egy szuper meta file descriptor önmagában multiplexel, és az applikáció magas szinten egyetlen fd-nek látja, na de a motorháztető alatt annak is különböző fd-kkel kell zsonglőrködnie, pont úgy, ahogy a select() és a ppoll() teszi.

Na de a lényeg: multiplexer esetén nem lehetséges a párhuzamos feldolgozás, mivel az mindig pontosan egy fd-t választ ki a tömbből, és amíg annak a feldolgozásával nem végzett, addig nem tud újabb fd-t lekérni egy és ugyanazon szálon. Magyarán a feldolgozás szekvenciális és nem párhuzamos.

Ha meg több szálat használ, akkor visszajutottunk oda, ahonnan a másik topikban indultunk, miszerint azt állítottam, "... minden aszinkron API - a Javascript motorok pedig különösképpen -, erdendően többszálúak. (Akkor is, ha a többszálúság csak a motorháztető alatt található és nincs direktben kivezetve a JavaScript API-jára, még akkor is)". A zárójeles részben arra utaltam, hogy itt most nem a magas szintű JavaScript Thread-ekről van szó, hanem a JS motorbeli pthread-ekről.

Szerkesztve: 2024. 07. 22., h – 19:12

Köszi! Nekem, mint nem programozó, nagyon hasznos!

En is pontositanek egy par aprosagot:

Multithreading: [...] Ha ennek a regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk.

Ez itt nem teljesen pontos. Amit irsz, hogy _csak_ az IP/PC regisztert mented memoriaba, az a klasszikus megszakitas-hivas, nem pedig a multithreading. Multithreading eseten is mentened kell a processzor belso allapotat, es az adott thread folytatashoz azt vissza kell allitanod 1:1-ben. A konnyites tenyleg annyi, ahogy mondod, hogy a cimter az valoban nem fog valtozni, igy a "teljes allapot" mentese egy-ket fokkal egyszerubb, viszont sokkal hatekonyabb (hiszen par tucat regiszter mentese meg visszaallitasa sokkal gyorsabb mint egy cimter-valtas es/vagy TLB cache flush utani feleledes). De ebben az allapotban (avagy context-ben) benne van nemcsak a IP/PC meg az osszes "egyszeru" regiszter, hanem meg a flag-ek is meg a SIMD, FPU, stb, regiszterek is. Szoval egy modern procinak a context az mar egy egesz nagy valami is lehet. Ha csak a register file-t nezzuk mar ugy is.

Ha megnezed a `man 2 clone` leirast, akkor abbol azt lehet latni hogy a "multithreading" es a "multiprocesszing" kozotti atmenet az egeszen folytonos, es uj processzek/threadek letrehozasakor valojaban temagad tudod hangolni hogy mennyire is kezdjen el kulonbozni a ket processz, marami a cimteret (meg a tobbi I/O eroforrast) illeti. Lehet minden teljesen kozos, sot, szelsoseges esetben a stack is lehet kozos. Oke, ezutobbi elegge extrem, nem tudom hogy ki az aki annyira bator es/vagy mi arra az use case ha kozos a stack :) (hiszen akkor mar egy fuggvenyhivast sem tudsz csak ugy vegrehajtani). De pont a stack kulonbozosege implikalja hogy minimalis kulonbnsegek mar thread-ek eseten is megjelenhetnek (gondolj bele hogy pl a kernel "alalapozhat" meg memoriat az egyik thread stack-jenek, ha az tulsagosan elkezdene noni lefele, mig a masiknak nem kell). Persze ettol meg a context switch olcso marad, marad(hat) ugyanaz a cimter, jo ez. 

A szinkron/aszinkron I/O-val kapcsolatban pedig:

  • ezelobbi esetben a processz/thread egyszercsak ugye eljut oda hogy kell neki adat: akkor meghivja a megfelelo rendszerhivast, es az vagy blokkol (blocking I/O), vagy nem (nonblocking), vagy meg tudod nezni hogy tobb forrasbol szarmazo adatok eseten melyikben van valami (azaz melyik blokkolna ha blocking modon hivnad). Ezutobbi az amit a select() es baratai csinalnak, es ezert hivjak ezt "szinkron multiplexing"-nek. Ez mind-mind szinkron.
  • Az aszinkron I/O eseten meg beallit(hat)od hogy egy adott forras (pl file descriptor) eseten, ha az nem blokkolna egy blocking muvelet soran, akkor hivjon meg a kernel egy, az adott processzhez tartozo signal handlert (ld: SIGIO). Lenyegeben olyan mint egy interrupt, csak a kernel "csinalja" es nem-privilegizalt modon is fut (de privilegizalt folyamatok kozbenjarasaval).

Programozasi szempontbol a multithreading meg aszinkron I/O azert erdekes mert ugyanabban a cimterben szakad meg ezert vagy azert (preemption vagy interruption) a program futasa es kerul at egy masik pontra. Igy mindket entitas (ket kulonbozo thread, vagy egy processz/thread es signal handler) eseten nagyon figyelned kell hogy a kozos cimterben levo valtozok kozul mi az ami volatile es mi az ami nem. Ez akkor is igaz ha ket kulonbozo processzed van, latszolag kulonbozo cimterrel, de van egy kozos hasznalato shared memory terulet is es abba pakolgat az ember valtozokat. De persze a ket fenti, "klasszikus szinkron" meg "klasszikus aszinkron" esetek kozott sem annyira eles az atmenet. Peldaul csinalhatsz olyat hogy: a/ egy "A" thread letrehoz egy "B" thread-et, ami csak loop-olva varja hogy valahonnan, egy adott file descriptorrol jojjon adat, es ha jon akkor atir megfelelo modon egy, a kozos cimterben levo volatile valtozot. Vagy b/ ez az "A" thread csinal egy SIGIO handlert, amit majd meghiv a kernel ha tortenik valami akcio egy adott file descriptoron. A handler pedig ekkor atir megfelelo modon egy, a kozos cimterben levo volatile valtozot. Az "A" thread szemszogebol nezve az a/ es b/ esetben ugyanaz tortenik, az a processz nem tudja megkulonboztetni a ket implementaciot. Mindketto hatekony lesz, de hogy melyik lesz hatekonyabb az mar implementacio/kernel/finomhangolas/stb fuggvenye. 

Tanuljatok már meg OLVASNI. Komolyan, botrányos, amit a HUP közössége magyar nyelvű szövegértés címszó alatt előad.

Ez itt nem teljesen pontos.

Vö: "Előrebocsátom, hogy az alábbi definíciók NEM teljesek, szándékosan hiányosak és leegyszerűsítettek, csupán azokat az aspetusokat emeltem ki belőlük, melyek a többszálúság kapcsán relevánsak."

Amit irsz, hogy _csak_ az IP/PC regisztert mented memoriaba

NEM EZ VAN ODAÍRVA. Nincs "csak", nem írtam ilyent sehol. Ne képzelj már oda olyan dolgokat, amik nincsenek is ott. Nincs ott semmilyen "csak", mert soha nem is írtam oda.

Amit irsz, hogy _csak_ az IP/PC regisztert mented memoriaba, az a klasszikus megszakitas-hivas

HIBÁS. Ad egy, nem is ezt írtam, ad kettő a megszakítás hívás során SEM CSAK az utasításszámláló mentődik, de AZ IS. Már ha x86-on beszélünk, akkor mentődnek még a szegmensszelektorok és veremmutató is, ha az ARM-ről, akkor meg egyik se, mert ott egy külön dedikált regiszterbe kerül a mentett utasításszámláló nem is memóriába, de ennyire aztán végképp nem akartam belemenni a részletekbe, mert még a leegyszerűsített leírás is meghaladja az értelmi képességeit egyeseknek.

Multithreading eseten is mentened kell a processzor belso allapotat, es az adott thread folytatashoz azt vissza kell allitanod 1:1-ben.

HIBÁS ez is. Az már a multitasking lenne, amiről itt beszélsz, kevered a dolgokat. Multitaskingnál elvárás ugyanis, hogy az állapot bármikor megszakítható és 1:1-ben helyreállítható legyen, és annál le is van ez írva: "Ilyenkor jellemzően az összes többi regiszter is mentődik az utasításszámlálóval együtt". Multithreadingnél ilyen nincs, ott csak annyi az elvárás, hogy a clobbered registers-ek vissza legyenek állítva, semmi több. Szó sincs a teljes belső processzorállapot mentéséről, még véletlenül se.

De ebben az allapotban (avagy context-ben) benne van nemcsak a IP/PC meg az osszes "egyszeru" regiszter, hanem meg a flag-ek is meg a SIMD, FPU, stb, regiszterek is.

Ez is HIBÁS. Ha éppenséggel tudni akarod, akkor a kernel egy kivételkezelőt helyez minden coprocesszor műveletre, ami bebillent egy flaget a taszk állapotleíróban. Taszkkapcsoláskor csakis abban az esetben mentődnek és állítódnak vissza a nem GPR-ek (mint a SIMD és FPU állapotok), ha ez a flag be volt billentve, egyébként le sem szarja őket. De ismételten, ennyire nem akartam belemenni a részletekbe, mert egyeseknek már ez az egyszerűsített leírás is bőven meghaladja az értelmi képességeit.

Ha megnezed a `man 2 clone` leirast, akkor abbol azt lehet latni...

...akkor pontosan azt látni, mint amit írtam, megint csak kénytelen vagyok ismételni magam, mert nem tudtok olvasni: "A mai kernelekben már kicsit összetettebb dolog amióta léteznek a SYS_set_tid_address, SYS_sched_setscheduler stb. rendszerhívások..."

eseten nagyon figyelned kell hogy a kozos cimterben levo valtozok kozul mi az ami volatile es mi az ami nem.

Ez sem pontos. Erre van a thread_local kulcsszó, aminek hatására egy dedikált regiszter relatív címzési módot fordít a fordító, az ilyen tárolási osztályú változókat pedig egy külön szegmensbe gyűjti a linker (Linux-on és Windows-on is egyaránt).
- Éppenséggel ha tudni akarod, akkor ezt a SysV ABI definiálja, a dedikált regiszter relatív címzéshez tartozó relokációs rekordoknak meg TLS van a nevükben, lásd például Motorola, Sparc, AArch64 vagy épp x86_64 esetén.
- A PE/COFF formátum esetén a működési elv TELJESEN AZONOS, azaz szeparánt szegmens, dedikált regiszter relatív címzés, stb. csak apró implementációs eltérések vannak a SysV-hez képest, ennek a definíciója pedig itt olvasható.
Maga a volatile kulcsszó csak annyit tesz, hogy a fordító nem optimalizálhatja ki a változó kiértékelést, azaz magyarul muszáj mindig memóriacímzésű utasításra (LOAD/STORE/MOV) fordítania a rá történő hivatkozásokat, nem tárolhatja azt pékdául átmenetileg egy regiszterben vagy ilyesmi.

ugyanabban a cimterben szakad meg ezert vagy azert (preemption vagy interruption)

Hogy mekkora baromságot írtál itt össze, azt hadd ne kelljen részleteznem. Minden pontjában hibás, teljes egészében. A megszakítás független a címtértől, a preemtive és az interrupt pedig nem két külön dolog, hanem az interrupt lehet preemptive vagy sem...

De ismételten, ennyire szándékosan nem akartam belemenni a részletekbe, mert egyeseknek már ez az egyszerűsített leírás is bőven meghaladja a szövegértési és értelmi képességeit.

Vállalom, én biza' nem szeretem a semmirekellő trollokat, az olyanokat meg különösen nem, akik még felnőtt létükre sem voltak képesek megtanulni írni-olvasni.

Túl gyakori a HUP-on az, hogy valaki mindenáron ki akar javítani, pedig nincs is mit, csak valójában nem voltak képesek elolvasni vagy értelmezni azt, amit írtam. Egyszer - kétszer előfordul, persze, oké, megesik. Na de állandóan?
Nem hiszem, hogy irreális vagy túlzott elvárás lenne a magyar nyelvű olvasás és szövegértés egy szakmai fórumon.

Semmi köze ennek a türelemhez, egy pillanatig sem húztam fel magam az elmúlt hetekben.

Én bizony büszkén vállalom, hogy elküldöm a picsába azt, aki nem tud olvasni, de mégis kötözködni próbál. Mert valakinek muszáj, és ha más nem vállalja, hát akkor leszek én.

Nézd csak meg, ebben a topikban is kulturáltan válaszoltam mindenkinek, kivéve apai-nak, aki olyant reklamált, amit nem is írtam, és olyant hiányolt, amit viszont leírtam.
Csak magára vessen, magának ásta a vermet, simán elkerülhette volna ezt egy icipici odafigyeléssel (és persze alaposabb olvasással).

Azért ha már "fejtágítást" tűztél ki célul

Nem tűztem ki célul. A sok barom óbégatása közepette jött valaki, aki intelligensen és kulturáltan megkért, hogy írjam ezt össze, ezért boldogan összeírtam. Ennyi.
Miért akarnék én olyan értelmi fogyatékosokat tanítani, akik még olvasni sem tudnak - ráadásul ingyen? Nem akarok. Aki tudja hasznosítani, amit itt összeírtam, annak egészségére és örülök, aki nem, hát az magára vessen.

Már a GUI topikomban is megmondatam, hogy ha valakinek mások az igényei, mint amikre a lib készült, az használjon mást és kész. De nem értették.
Itt is ez van, ha nem tetszik, ne olvasd. Vagy, ha olvasod, akkor olvasd el rendesen, és ne olyanokba köss bele, ami nincs is odaírva, vagy olyant hiányolj, ami viszont oda van írva.

 

HIBÁS ez is. Az már a multitasking lenne, amiről itt beszélsz, kevered a dolgokat. Multitaskingnál elvárás ugyanis, hogy az állapot bármikor megszakítható és 1:1-ben helyreállítható legyen, és annál le is van ez írva: "Ilyenkor jellemzően az összes többi regiszter is mentődik az utasításszámlálóval együtt". Multithreadingnél ilyen nincs, ott csak annyi az elvárás, hogy a clobbered registers-ek vissza legyenek állítva, semmi több. Szó sincs a teljes belső processzorállapot mentéséről, még véletlenül se.

A regisztereket thread-eknél is elmenti, minden egyes alkalommal (linuxon 1000szer másodpercenként per processzormag)... "multi-threading" s a "multi-tasking" között itt csak az a különbség, hogy lesz-e address space change vagy nem... 

 

Ez sem pontos. Erre van a thread_local kulcsszó, aminek hatására egy dedikált regiszter relatív címzési módot fordít a fordító, az ilyen tárolási osztályú változókat pedig egy külön szegmensbe gyűjti a linker (Linux-on és Windows-on is egyaránt).

megint félrebeszélsz: itt az lett elmondva, hogy a globális változóknál már figyelni kell, nem szabad feltételezni, hogy csak ez a thread matathat hozzá.

pl. egy sima increment lehet, hogy nem atomikus, mert nincs mutex/nincs lock prefix. Hogy jön ide a thread local storage?

"multi-threading" s a "multi-tasking" között itt csak az a különbség, hogy lesz-e address space change vagy nem...

Nem, kevered a dolgokat. Az a threadkapcsolás és processzkapcsolás közötti különbség, amiról beszélsz (amit egyébként pontosan le is írtam, pontosan így, hadd ne másoljam le).

A pthread-eket meg ugyanúgy kell multitaskingolni, különben nem futhatna több szál párhuzamosan. És mivel multitasking van a thread-eknél is, ezért nyilván ott is menteni kell a regisztereket (merthogy az állapotmentés a multitasking-nál kell).

megint félrebeszélsz: itt az lett elmondva, hogy a globális változóknál már figyelni kell, nem szabad feltételezni, hogy csak ez a thread matathat hozzá.

Ismételten nem én beszélek félre, az lett mondva, hogy volatile-e. És arra válaszoltam. Neked pedig a válaszom az, hogy threadeknél thread_local változókat használj, amikor csak teheted, globális helyett, úgy jön ide.

Multithreadingnél ilyen nincs, ott csak annyi az elvárás, hogy a clobbered registers-ek vissza legyenek állítva, semmi több. Szó sincs a teljes belső processzorállapot mentéséről, még véletlenül se

ez, konkrétan marhaság, mindig, minden regisztert el kell menteni minden threadben, ha egyszer megszakítottad.

 

Ismételten nem én beszélek félre, az lett mondva, hogy volatile-e. És arra válaszoltam. Neked pedig a válaszom az, hogy threadeknél thread_local változókat használj, amikor csak teheted, globális helyett, úgy jön ide.

nem, nem arra válaszoltál. ismétlem: arról volt szó, hogy jobban kell figyelni a globális változókra. azok mindig vannak, hiába jössz a thread local storage-dzsel.

ez, konkrétan marhaság, mindig, minden regisztert el kell menteni minden threadben, ha egyszer megszakítottad.

Akkor miszter nagyszájú, legyél kedves megmutatni, hol történik ez az állítólagos mindent mentés az alábbi forrásban, amikor a megszakítás konkrétan bekövetkezik:
https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S
Gyerük! Hol található?

Fogd már fel, hogy az állapotmentés csak a MULTITASK-hoz kell, amikor a taszkkapcsolás történik, és igen, a pthread-ek a multitask-oltak, nem is a processzek. Valójában a mai modern kernelek ütemezője nem is lát processzeket, neki minden task szál és kész!

De itt a konkrét kernel forrás, nesze:
https://github.com/torvalds/linux/blob/master/arch/x86/kernel/process_6…

__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
	struct thread_struct *prev = &prev_p->thread;
	struct thread_struct *next = &next_p->thread;

Látod, hogy mi a legeslegelső lépés, hogy mit kér le a struct-ból? És látod azt is, hogy egy valag if feltétel van arra, hogy mikor mit kell menteni és visszatölteni? A "mindig, minden regisztert el kell menteni" a marhaság, te tanulatlan tuskó. A TIF_NEED_FPU_LOAD az szerinted mire van?
És látod azt is, hogy ez a switch_to végzi a taszkkapcsolást, ami NEM MINDIG hívódik meg, amikor szálkapcsolás történik az entry_64.S-ben? (Segítek, nem call, hanem jmp utasítással hívódik a függvény, erre magadtól úgyse lennél képes rájönni.)

ismétlem: arról volt szó, hogy jobban kell figyelni a globális változókra

Ismétlem, NEM TUDSZ OLVASNI. De ide másolom, csak neked, most próbáld meg VÉGIGOLVASNI, és ne add fel a mondat közepén, csak mert hosszú (kiemelés tőlem): "Programozasi szempontbol a multithreading meg aszinkron I/O azert erdekes mert ugyanabban a cimterben szakad meg ezert vagy azert (preemption vagy interruption) a program futasa es kerul at egy masik pontra. Igy mindket entitas (ket kulonbozo thread, vagy egy processz/thread es signal handler) eseten nagyon figyelned kell hogy a kozos cimterben levo valtozok kozul mi az ami volatile es mi az ami nem."
Látod? Vagy most sem voltál képes a mondat végéig eljutni?

Innentől magadra maradtál, vagy tanulsz a hibáidból, vagy hülye maradsz életed végéig. Te döntésed, engem hagy ki a hülyeségeidből. Ja, és TANULJ MEG OLVASNI, mert azt nem tudsz.

Akkor miszter nagyszájú, legyél kedves megmutatni, hol történik ez az állítólagos mindent mentés az alábbi forrásban, amikor a megszakítás konkrétan bekövetkezik:
 

a regiszterekről beszéltem...

csak úgy halkan mondom, hogy pl. az asm_sysvec_apic_timer_interrupt így kezdődik:

push    0FFFFFFFFFFFFFFFFh
call    error_entry
mov     rsp, rax
mov     rdi, rsp
call    sysvec_apic_timer_interrupt
jmp     error_return
 

az error_entry pedig (entry_64.S):

SYM_CODE_START(error_entry)
ANNOTATE_NOENDBR
UNWIND_HINT_FUNC

PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8

push    rsi
mov     rsi, [rsp+8]
mov     [rsp+8], rdi
push    rdx
push    rcx
push    rax
push    r8
push    r9
push    r10
push    r11
push    rbx
push    rbp
push    r12
push    r13
push    r14
push    r15
push    rsi
...

tudod, ezekből lesz a struct pt_regs *regs ...  🤭

DEFINE_IDTENTRY_SYSVEC(sysvec_apic_timer_interrupt)
{
       struct pt_regs *old_regs = set_irq_regs(regs);

        apic_eoi();
        trace_local_timer_entry(LOCAL_TIMER_VECTOR);
        local_apic_timer_interrupt();
        trace_local_timer_exit(LOCAL_TIMER_VECTOR);

        set_irq_regs(old_regs);
}

Pontosan. Mas architekturak is gyk egzaktul ezt csinaljak. Pl RISC-V esten:

SYM_CODE_START(handle_exception)

        csrrw tp, CSR_SCRATCH, tp
        bnez tp, _save_context

_restore_kernel_tpsp:
        csrr tp, CSR_SCRATCH
        REG_S sp, TASK_TI_KERNEL_SP(tp)

_save_context:
        REG_S sp, TASK_TI_USER_SP(tp)
        REG_L sp, TASK_TI_KERNEL_SP(tp)
        addi sp, sp, -(PT_SIZE_ON_STACK)
        REG_S x1,  PT_RA(sp)
        REG_S x3,  PT_GP(sp)
        REG_S x5,  PT_T0(sp)
        save_from_x6_to_x31
/* .... */


Ahol:

.macro save_from_x6_to_x31
        REG_S x6,  PT_T1(sp)
        REG_S x7,  PT_T2(sp)
        REG_S x8,  PT_S0(sp)
        REG_S x9,  PT_S1(sp)
        REG_S x10, PT_A0(sp)
        REG_S x11, PT_A1(sp)
        REG_S x12, PT_A2(sp)
        REG_S x13, PT_A3(sp)
        REG_S x14, PT_A4(sp)
        REG_S x15, PT_A5(sp)
        REG_S x16, PT_A6(sp)
        REG_S x17, PT_A7(sp)
        REG_S x18, PT_S2(sp)
        REG_S x19, PT_S3(sp)
        REG_S x20, PT_S4(sp)
        REG_S x21, PT_S5(sp)
        REG_S x22, PT_S6(sp)
        REG_S x23, PT_S7(sp)
        REG_S x24, PT_S8(sp)
        REG_S x25, PT_S9(sp)
        REG_S x26, PT_S10(sp)
        REG_S x27, PT_S11(sp)
        REG_S x28, PT_T3(sp)
        REG_S x29, PT_T4(sp)
        REG_S x30, PT_T5(sp)
        REG_S x31, PT_T6(sp)
.endm

De irtam mar RISC-V/RV32 BIOS variansokat (pontosabban SBI-t, ahogy ott nevezik azt ami a BIOS/ACPI helyen van), es ott is ez van a belepesi pont helyen, egy ilyen objektumba menti le az allapot:

struct irq_context
{
    uint32_t pc;
    uint32_t status;
    uint32_t cause;
    uint32_t reg[NUM_GP_REG];
};

Ez az SBI lementi a context-et es utana dolgozik vele ha kell (pl hianyzo utasitaskeszlet potlasa, misaligned access implementalasa szoftvberbol, machine-level fault-ok kezelese, machine-level hypervisoring, stb). Szoval azert ez azert sokmindenre jo igy. Es muszaj lementenie mert abban a pillantban nem tudhatja a CPU hogy mit is fog csinalni a tovabbiakban vele barmi ami futni fog azon a gepen (masik szal, masik processz, masik virtualis gep, stbstb).

Ez az egesz interrupt entry ott kezd erdekesse valni a dolog amikor a hardver eleve egy olyan stack frame-t keszit elo privilegium-szint emeles soran, ami a C ABI-val mar kompatibilis. Na, akkor ket reszrol kell osszekanalzni a context-et (lasd: ARM, vagyis bizonyos ARM core-ok). Ott kevesbe feltuno a "mindent mentunk" kodreszlet. 

Ez az egesz interrupt entry ott kezd erdekesse valni a dolog amikor a hardver eleve egy olyan stack frame-t keszit elo privilegium-szint emeles soran, ami a C ABI-val mar kompatibilis.

Mármint úgy érted, az adott platformra úgy definiálták a C ABI-t, hogy egy az egyben a hardvert követték le :)

Mondani mondhatod, de attól még faszság marad. Nem véletlen, hogy a megszakításbelépési pont Assembly-ben van írva, és nem C-ben. Mit gondolsz, miért?
És mutass egy architektúrát, ahol a megszakítás ABI-ja megegyezik a normál függvényhívás ABI-jával. Nem is létezik ilyen architektúra!

És mutass egy architektúrát, ahol a megszakítás ABI-ja megegyezik a normál függvényhívás ABI-jával. Nem is létezik ilyen architektúra!

Itten, ni, peldaul:

/* ... */

uint32_t * RAM_VECTORS[48] __attribute__ ((section(".ramvectors")));

/* ... */

void USART1_IRQHandler(void)
{
 packet_t   *packet;
 packet=(packet_t *)buffer_in_rs485;

 if ( USART1->ISR & USART_ISR_RXNE )
  {   /* ... */
  }
}

int irq_setup(void)
{
 /* ... */
 RAM_VECTORS[16+USART1_IRQn     ]=(uint32_t *)USART1_IRQHandler;
 /* ... */

 SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_1|SYSCFG_CFGR1_MEM_MODE_0;

 return(0);
}

/* ... */

int main(void)
{
 /* ... */
 irq_setup();
 /* ... */

 USART1->CR1 |= USART_CR1_RE|USART_CR1_TE;
 USART1->CR1 |= USART_CR1_UE;
 USART1->CR1 |= USART_CR1_RXNEIE;
 NVIC_EnableIRQ(USART1_IRQn);
 NVIC_SetPriority(USART1_IRQn,0);
 /* ... */
}

Mindezt pedig:

$ make ...
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -masm-syntax-unified -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections # ... 

Szánalmas. ARM alatt nincs is ilyen, azt ott külön független hardware vezérli, de te még azt sem tudod, hogy "NVIC"-t kezelő kód az "NVIC_EnableIRQ" függvényen túl berak még egy ISR kódot is a programodba... Szánalmas vagy, na.

Maga az ARM nem is tud megszakításvektorokat kezelni, csak 4 típust ismer (Sync, IRQ, FIQ, SError, esetleg ezek jogosultság szintes kombinációja a CSel rendszerregiszter beállításától függően), az már az ISR feladata, hogy különböző rendszerregisztereket lekérve eldöntse, melyik is történt (pl. hogy UART IRQ volt-e egyáltalán a megszakítás oka).

Röviden: az ISR az, ami aztán a ramvectors tömbből választ, és nem a CPU.

https://developer.arm.com/documentation/ddi0487/latest/arm-architecture…
https://documentation-service.arm.com/static/5f8fef3af86e16515cdbf816

Elárulom, hogy ez pontosan ugyanígy zajlik akkor is, ha nem NVIC-ed hanem GIC-ed vagy QA-d van, mint a régi Pi-ken.

Ezt mondjuk nem értem, a vektor táblára egy hardver regiszter mutat (VTOR), amúgy mindenféle régi CPU (még a Z80 is) "magától" megtalálja az adatbuszra helyezett bájtból, hogy melyik ISR-t kell hívnia (azon a VTOR az I regiszter).

Mondjuk ahogy most keresgélek, VTOR és igazi vektoros megszakítás csak Cortexeken van?

Igen, VTOR az Cortex-Mx processzorokon biztos van, ahol x az legalabb 3. Legalabbis M3, M4 es M33-on talalkoztam vele, M0-on meg biztos nincs (ott annyit tesz nehany gyarto hogy ugyan fix VTOR=0 ertekkel dolgozik, de a felhasznalo eldontheti hogy melyik memoria-kompomenst is mappel be a 0-s cimre... es ha az a RAM, akkor kis trukkel kb pont meg lehet csinalni ugyanazt mintha lenne VTOR-unk). 

Sajnos az application processor vonalat annyira nem ismerem ilyen szempontbol. De egeszen meg mernem mondani hogy ott is valami hasonlo van. Vagyhat biztos nem olyan elborult mint peldaul a RISC-V eseteben...  :) 

Aha, igen, igy szuroprobaszeruen megneztem a Cortex-A9-et es az is vector table-t hasznal.

RISC-V eseten is lehet majdnem igy csinalni. De az is opcionalis es akkor is csak aszinkron megszakitasokra, es akkor is az egy jump table lesz a gyakorlatban es nem egy ISR vector table. A "de facto ajanlas" az inkabb az hogy egy entry point legyen csak minden privilegizalasi szinthez, es akkor egy belso control & status register (mcause, scause) alapjan dontsd el hogy mit csinalsz. Az ottani BIOS (SBI) is altalaban ezt implementalja meg a Linux is ilyen (ld. linux/arch/riscv/kernel/entry.S: handle_exception).

Én úgy nézem vektor tábla az mindegyiken van, viszont csak a Cortexen lehet az IRQ-t külső forrásból jövő vektorral megetetni, a hagyományos ARM az olyan, mint a 6502 volt, csak ennek 8 bejegyzés van a táblázatában (reset, undefined instruction, software int, prefetch abort, data abort, not used, irq, firq). Ennél valóban neked kell az ISR-ben ellenőrizni, hogy honnan jött a megszakítás. Mikrovezérlős környezetben ez megengedhetetlen, van több tucat periféria, ha az ISR úgy nézne ki, hogy if (SPI_IRQ) spi_isr(); else if (UART_IRQ) usr_isr(); ... az interrupt latency hatalmas lenne.

De azért csodálkozom, hogy az alap ARM az ilyen "buta".

Szerk.:

https://developer.arm.com/documentation/dui0471/m/handling-processor-ex…

Szóval valóban csak Cortexen van ilyen.

https://developer.arm.com/documentation/dui0471/m/handling-processor-ex…

"Exception handlers for microcontroller profiles are not required to save or restore the system state and can be written as ordinary, ABI-compliant C functions. However, it is recommended that you use the __irq keyword to identify the function as an interrupt routine, see the following example."

No comment...

 

Egy projektemben meg én is használok jópár periféria ISR-t, és valahogy nem fedeztem fel ezt a "NVIC_EnableIRQ" függvényen túl berak még egy ISR kódot is a programodba". Ehelyett pl. az UART ISR beállításához meghívom azt, hogy NVIC_SetVector(ID_UART0, (uint32_t) &Usart0IrqHandler); NVIC_EnableIRQ(ID_UART0); és ennyi, innentől igenis a HW kezeli.

 

Ah, igen, es raadasul elegge vegyes is a kep: The use of an NVIC in the microcontroller profiles means that the vector table is very different from other ARM processors, because it consists of addresses not instructions. 

Koszi, ezt nem tudtam.

Ja meg igen, ez a 8-byte alignment is egy erdekes kerdes. The Application Binary Interface (ABI) for the ARM Architecture requires that the stack must be 8-byte aligned on all external interfaces, such as calls between functions in different source filesMondjuk legalabb idoben felkeszultek a 64-bites rendszerekre, igy is nezhetjuk :) Meg hogy ha mar a stack kell parameteratadasra-visszaadasra akkor valoban jobb ez a 8-byte alignment, nem ezen mulik a boldogsag. 

NVIC_SetVector(ID_UART0, (uint32_t) &Usart0IrqHandler); 

No, ezt sem ismertem igy ebben a formaban - de ha jol latom, szorul szora azt csinalta mint ami nalam az a RAM_VECTORS[] tomb:

/**
  \brief   Set Interrupt Vector
  \details Sets an interrupt vector in SRAM based interrupt vector table.
           The interrupt number can be positive to specify a device specific interrupt,
           or negative to specify a processor exception.
           Address 0 must be mapped to SRAM.
  \param [in]   IRQn      Interrupt number
  \param [in]   vector    Address of interrupt handler function
 */
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
  uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2);      /* point to 1st user interrupt */
  *(vectors + (int32_t)IRQn) = vector;                              /* use pointer arithmetic to access vector */
  /* ARM Application Note 321 states that the M0 does not require the architectural barrier */
}

Itt az az "Address 0 must be mapped to SRAM." az erdekes, azert hasznalom azt a __attribute__ (( section(".ramvectors") )); dolgot hogy az tuti ott legyen. De akkor egyszerubb mar eleve a linker scriptben kihagyni azt a regiot, oszt annyi. Ez igy tenyleg elegansabb.

Én úgy nézem vektor tábla az mindegyiken van

Nem az a kérdés, hanem hogy megszakításvektorokat tartalmaz-e az a tábla, vagy pedig megszakítástípusfüggő lekezelőfüggvények címeit.

viszont csak a Cortexen lehet az IRQ-t külső forrásból jövő vektorral megetetni

Minden IRQ külső forrásból érkezik, mert a perifériák generálják és nem a CPU. (Manapság főleg embedded cuccoknál minden egy SoC-ra van integrálva, de akkor sem a CPU generálja ezeket, hanem a perifáriák.)

Exception handlers for microcontroller profiles are not required to save or restore the system state

Valóban, no comment! Ennyit arról, hogy mindig, minden megszakításnál mindent menteni kell!
A kivételkezelő eljárás meg már csak azért sem lehet sima C függvény, mert azokhoz a fordító "RET" utasítást generál, a kivételekezelő eljárásból (exception handler-ből) viszont "ERET" utasítással kell visszatérni.

innentől igenis a HW kezeli.

Persze, hogy a HW kezeli (mégis, mi más kezelhetné?), na de nem a CPU. A CPU már csak a lánc legeslegvégén jön képbe, az interrupt controller UTÁN (ami esetedben az NVIC, de általánosságban sokkal inkább GIC lesz az).

Valóban, no comment! Ennyit arról, hogy mindig, minden megszakításnál mindent menteni kell!

Legalábbis amit használsz az ISR-ben, FIRQ-nak pl. az is a lényege, hogy minimális állapotmentés után már dolgozhat az ISR (ARM-nál nem tudom pontosan, hogy mennyivel "könnyebb" a FIRQ mint az IRQ, 6809-en pl. csak a PC meg flagek mentődnek, míg IRQ-nál minden regiszter).

Persze, hogy a HW kezeli (mégis, mi más kezelhetné?), na de nem a CPU. A CPU már csak a lánc legeslegvégén jön képbe, az interrupt controller UTÁN (ami esetedben az NVIC, de általánosságban sokkal inkább GIC lesz az).

Azt mondjuk érdekes lehet, hogy az extra vektorok kezelése vajon hol történik, az ARM core-ban is kell, hogy legyen némi változtatás, hogy az egy szem IRQ handler helyett lehessen max. 256 (NVIC-nél).

Egy Z80-nál vagy 68000-nél az interrupt controller egyszerűen felrakja az adatbuszra a periféria címét, ez alapján a CPU tudja, hogy melyik ISR-t kell hívnia. De az alap ARM-nál nincs ilyen, az kap egy IRQ-t, és van 1 db ISR, ami intézkedik, míg az NVIC hogy közli az ARM core-ral, hogy honnan vegye a ISR címét?

Egy régi AT91SAM MCU datasheetje (ezen még AIC van, nem NVIC) így írja:

When the instruction loaded at address 0x18 is executed, the program counter is loaded with the value
read in AIC_IVR. Reading the AIC_IVR has the following effects:
– Sets the current interrupt to be the pending and enabled interrupt with the highest priority. The current
level is the priority level of the current interrupt.
– De-asserts the nIRQ line on the processor. Even if vectoring is not used, AIC_IVR must be read in
order to de-assert nIRQ.
– Automatically clears the interrupt, if it has been programmed to be edge-triggered.
– Pushes the current level and the current interrupt number on to the stack.
– Returns the value written in the AIC_SVR corresponding to the current interrupt.

Nekem úgy tűnik,  ha az ARM core elkezdené az ISR-t, az AIC "alányúl", és lecseréli a PC-t arra, ami a saját vektortáblájában van. Arra nem találtam bizonyítékot, hogy az maga az ISR intézkedne a megfelelő vektor kiolvasásáról, és a kívánt periféria ISR hívásáról.

 

GIC egyébként ahogy nézem, a hagyományos CPUk-hoz tartozó interrupt controller, az AIC, NVIC meg a mikrokontrolleresekhez van.

De az alap ARM-nál nincs ilyen, az kap egy IRQ-t, és van 1 db ISR, ami intézkedik

Pontosan. Ezt hívtam alacsony szintű ISR-nek, és erre mondtam, hogy ezt nem lehet C függvényként megírni, mert nem C ABI-t használ. Az általa hívott IRQ-nkénti függvények már lehetnek C-ben természetesen.

Arra nem találtam bizonyítékot, hogy az maga az ISR intézkedne a megfelelő vektor kiolvasásáról

Például Linux kernel esetén itt vannak az alacsony szintű ISR-ek, típusonként és privilégiumszintenként összesen 16 kombináció, a "vectors" nevű címtől kezdve, minden egyes ISR-nek 128 bájtot lefoglalva. A legelső címe töltődik be a VBAR regiszterbe, és mind fixen 128 bájt méretű (tehát nincs is tábla, mint x86-on vagy Z80-on). Megjegyzés: alapból 4 típus van, ez a CSel rendszerregiszter állításával szétbontható privilégiumszintenként 4-4-4-4-re (utolsó a 32 bites).

Az itt megadott "kernel_ventry" makró kifejtve az, ami beállítja a C ABI-hoz a környezetet és meghívja a C függvényt (mivel makróról van szó, elég fifikásan áll össze a C függvény nevének a szimbóluma, de ebben a sorban lévő branch ugrik rá).

Maga az IRQ sorszámának lekérése, hogy melyik IRQ is történt, az IC specifikus, mint említettem, szóval azt nem is fogod így megtalálni a Linux kernel forrásában, mert az egy DTB fájlból jön (pl Raspi esetén innen). Ebben a bináris fájlban leírva, hogy milyen IC van a rendszerben, hogy annak milyen regiszterei vannak, azok milyen MMIO címen érhetők el, és hogy melyik regiszter melyik bitje tárolja, hogy mely IRQ is történt valójában.

Szóval a Linux kernelben az alacsony szintű Assembly ISR (kernel_ventry) hív egy fifikás, makróparaméterekből összelegózott nevű C függvényt, majd aztán az lesz az, ami a DTB alapján kiolvassa az IRQ-t, meghatározza a hozzá tartozó vektort és meghívja az annak megfelelő tényleges lekezelő rutint.

Ezt mondjuk nem értem

Tessék elolvasni a belinkelt dokumentációt.

A modern ARM procikon (konkrétan ARMv7, v7l, 8 és afölött) nincs VTOR, hanem VBAR rendszeregiszter van, aminek a vektortáblája megszakítástípusfüggő ISR-erekre mutat és nem megszakításvektorokra.

Ez megvan, de ahogy fentebb is kiderül, a VTOR az az NVIC-hez tartozik, ami meg a Cortexeken van. Egy ARM Cortex meg simán lehet ARMv7 alapú, úgyhogy a különbség inkább a mikrokontrolleres és a nem mikrokontrolleres ARM-ok közt van.

Ha meg AIC van (az jó régi már), ott AIC_SVR van, ennek inicializálása egy standard startup kódban:

for (i=1;i < 31; i++)
{
   AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ;
}

Na de ennek már nem sok köze van a szálakhoz és processekhez.

Na de ennek már nem sok köze van a szálakhoz és processekhez.

Valóban, de nagyon kellemes felüdülés a sok seggfej dilettáns troll mellett egy értelmes, hozzáértő emberrel is beszélgetni végre.

Nagyon szépen köszönöm, hogy megmutattad a trolloknak, hogy mi is lenne az elvárt viselkedés egy szakmai fórumon.

az error_entry pedig (entry_64.S):

Hazudsz, az entry_64.S-ben NINCS ilyen kódrészlet.

Ad egy, még ha lenne is, te azt hiszed, hogy az error_entry hívódik mindig, minden megszakításnál? LOL

Ad kettő, hol mentené ez a SIMD regisztereket? Merthogy a GPR az nem "mindig, minden", ugye?

Ad három, rákerestem az általad idemásolt kódrészletre, és kurvára NEM IS SZEREPEL a https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S fájlban, lúzerkém.
És egész biztos, hogy a Linux kernel forrásában MÁSHOL SEM, ugyanis amit idemásoltál az Intel syntax, a Linux kernel pedig AT&T syntax-ban íródott, seggarc.

én disassembláltam a kernel lefordított kódját, édes lelkem, a lefordított entry_64.o-t. (ida64 a tool, ha éppenséggel érdekel, ezért nem gnu syntax, ezt igazán ismerhetné egy "önjelölt bootloaderfejlesztő" )

a forrásban  pedig megmutattam neked, hogy hol van:

/arch/x86/kernel/idt.c, line 133:

static const __initconst struct idt_data apic_idts[] = {
....

INTG(LOCAL_TIMER_VECTOR,              asm_sysvec_apic_timer_interrupt),

 

ez van az idt-ben, angyalkám. és, ahogy mondtam, ha megnézed mi van annál a symbolnál, az azzal kezdi, hogy call error_entry. 

csak, hogy a gyengébbek is megértsék:

ott van a:

DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR, sysvec_apic_timer_interrupt);       linux-6.9.10/arch/x86/include/asm/idtentry.h
 

ez így néz ki:

#define DECLARE_IDTENTRY_SYSVEC(vector, func)           \
       DECLARE_IDTENTRY(vector, func)

 

az pedig:

/*
* The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs.
*/
#define DECLARE_IDTENTRY(vector, func)                  \
       idtentry vector asm_##func func has_error_code=0

 

az idtentry az ott van az entry_64.S-ben
 

.macro idtentry vector asmsym cfunc has_error_code:req
SYM_CODE_START(\asmsym)
...

idtentry_body
..
 

az pedig:

.macro idtentry_body cfunc has_error_code:req

       /*
        * Call error_entry() and switch to the task stack if from userspace.
        *
        * When in XENPV, it is already in the task stack, and it can't fault
        * for native_iret() nor native_load_gs_index() since XENPV uses its
         * own pvops for IRET and load_gs_index().  And it doesn't need to
        * switch the CR3.  So it can skip invoking error_entry().
        */
       ALTERNATIVE "call error_entry; movq %rax, %rsp", \
                   "call xen_error_entry", X86_FEATURE_XENPV
        
       ENCODE_FRAME_POINTER
       UNWIND_HINT_REGS

       movq      %rsp, %rdi                              /* pt_regs pointer into 1st argument*/

       .if \has_error_code == 1
               movq   ORIG_RAX(%rsp), %rsi   /* get error code into 2nd argument*/
               movq   $-1, ORIG_RAX(%rsp)     /* no syscall to restart */
       .endif
                
       call    \cfunc
                
       /* For some configurations \cfunc ends up being a noreturn. */
       REACHABLE

       jmp    error_return
.endm
 

megvan? még ki is boldoztam, nehogy ne bírd követni...

igen, továbbra is fenntartom, hogy hülyeségeket beszélsz...

Régi szép időkben egyértelmű volt ez a dolog, mert a processzek közti kapcsolás a kernelben történt és címteret is váltott, a pthread-ek közti kapcsolás pedig egy processzen és egy címtéren belül történt, és a kernel nem is tudott róla.

 

mi az, hogy a kernel nem is tudott róla? mikor volt a linuxban userspace scheduling? a kernel mindig is task-okat ütemezett (amit a struct task_struct leír), ami lehet kernel thread, user thread (egy single-threaded vagy egy multi-threaded processz egyik threadje). Beszélek itt a nptl előtti időkről is (linuxthreads).

Pont az volt a gond linuxthreads-szel, hogy túl "nehéz" volt, nem működött rendesen a signal handling, a ps minden threadet kilistázott, mint processz, stb.

 

de ennél azért jóval többfajta szál van ugye, vannak még ISR-ek, signal thread-ek, a kernel threadekről nem is szólva stb.

az ISR mióta "thread"? mi az, hogy "signal thread", lol.

mi az, hogy a kernel nem is tudott róla? mikor volt a linuxban userspace scheduling?

ROTFL. Na fuss neki mégegyszer, mit is írtál itt valójában.

az ISR mióta "thread"?

Mindig is az volt. Mi más lenne, agyas? Ja, hogy el kéne tudni olvasni a definíciót és meg is kéne tudni érteni, de neked ez nem megy? Így jártál.

mi az, hogy "signal thread"

Tanulatlan tuskó. man 7 signal

bocs, de aki ilyet ír, hogy a kernel nem is tud a váltásról, az félrebeszél 🤭

 

 az ISR az interrupt service routine, igen, az egy függvény, kernel space-ben és semmi köze a threadekhez, azontúl, hogy az aktuális thread contextjében fut le

 

a "signal" az egy inter-processz kommunikáció, by definition... lehet küldeni egy processznek vagy egy threadnek... szerinted a signal az egy thread. ezt írtad... 

 

ps. komolyan ajánlom neked, hogy a szociális képességeidet fejleszd (tudod: emberi interakciók, önbizalomhiány, ilyenek)... 

És itt nagyon fontos megjegyezni, hogy ha signal handlert írsz, akkor abból csak async-signal safe dolgokat hívhatsz, ami a syscall-ok és library-k apró részhalmaza (https://man7.org/linux/man-pages/man7/signal-safety.7.html, az MT-Safe-nél erősebb koncepció). Ha ezt nem veszed figyelembe, akkor a programod látszólag működni fog, de ez egyrészt akár exploitolható biztonsági hiba is lehet (lásd regreSSHion), valamint ritka race condition-k tárháza.

Szerintem elfogadható és tömör válasz ad a ChatGPT:

A multithreading, multitasking, és multicore fogalmak mind a számítógépes rendszerek teljesítményének és hatékonyságának javításával kapcsolatosak, de különböző koncepciókat és technológiákat jelentenek. Íme a különbségek:

Multithreading (többszálú végrehajtás)

  • Definíció: A multithreading egy programon belüli több szál egyidejű futtatására utal. Egy szál a program futási egysége, amely magában foglal egy sor utasítást.
  • Cél: A szálak párhuzamos futtatása a program hatékonyságának növelése érdekében. Ez különösen hasznos, amikor a program több feladatot végezhet párhuzamosan, például adatfeldolgozást és felhasználói interakciókat.
  • Példa: Egy webböngésző, amely külön szálat használ a felhasználói bemenetek kezelésére, egy másikat pedig a weboldalak betöltésére és megjelenítésére.

Multitasking (többfeladatos végrehajtás)

  • Definíció: A multitasking egy operációs rendszer azon képességére utal, hogy több feladatot (folyamatokat) tud egyidejűleg kezelni. Ezek a feladatok párhuzamosan futnak, gyakran időosztásos alapon.
  • Cél: Az operációs rendszer hatékonyabbá tétele azáltal, hogy több programot tud egyidejűleg futtatni, látszólag egyidejűleg, azáltal, hogy gyorsan vált közöttük.
  • Példa: Egy felhasználó egyszerre írhat egy dokumentumot, hallgathat zenét és böngészhet az interneten különböző programokban.

Multicore (többmagos processzor)

  • Definíció: A multicore egy processzorarchitektúrára utal, amely több független végrehajtási egységet (magot) tartalmaz egyetlen chipen belül. Ezek a magok párhuzamosan tudják végrehajtani az utasításokat.
  • Cél: A számítási teljesítmény növelése azáltal, hogy több mag dolgozik együtt párhuzamosan, így több utasítást lehet egyszerre végrehajtani.
  • Példa: Egy négymagos (quad-core) processzor, amely négy különálló magot tartalmaz, amelyek egyidejűleg képesek különböző feladatokat végrehajtani.

Összefoglalás

  • Multithreading: Több szál fut egyetlen programon belül, hogy növelje a program hatékonyságát és teljesítményét.
  • Multitasking: Az operációs rendszer képes több programot egyidejűleg futtatni, gyors váltással a folyamatok között, hogy látszólag párhuzamosan fussanak.
  • Multicore: Több mag egyetlen processzorban, amelyek párhuzamosan végrehajthatják az utasításokat, növelve a számítási teljesítményt.

Ezek a technológiák együttműködve jelentősen növelhetik egy számítógépes rendszer teljesítményét és hatékonyságát.

Szerintem elfogadható és tömör válasz ad a ChatGPT

Igen, bár kicsit slendrián a megfogalmazása: "több programot tud egyidejűleg futtatni", a program önmagában nem is futtatható, csak a szálak képesek futni, ugyebár.
Ezenkívül amit a multithreading-re ír, az csak a felhasználói pthread-re igaz, de ennél azért jóval többfajta szál van ugye, vannak még ISR-ek, signal thread-ek, a kernel threadekről nem is szólva stb.

A chatgpt egy sokkal világosabb első megközelítést adott

Helyes, de semmiképp sem teljes. A kernel thread-ekről cakk-um-pakk megfeledkezett például.
Ezen kívül notóriusan keveri a "szál", "program", "feladat" és "folyamat" kifejezéseket, pedig nem mindegy. Nem szakmai ember nem tudja a különbséget, nekik jó.

Szerkesztve: 2024. 07. 24., sze – 06:34

Fejtágító gyanánt jó lenne inkább arról írni, hogy ne lőjék tökön egymást és magukat a konkurens folyamatok. Osztott erőforrások, szinkronizáció, szemaforok, ilyesmi. Én Java alatt használok pár nekem bevált módszert, de szívesen olvasnék arról, milyen lehetőségek vannak még, akár más nyelvekben és rendszerekben.

A  klasszikus Linux/POSIX C megoldasokon kivul csak a konnyedebb, beagyazott renszerekre, mikrokontrollerekre keszitett multithreading library-kat meg az ahhoz kapcsolodo dolgokat ismerem valamennyire. De ezutobbi dolgokban az az erdekes hogy mar egy par kilobyte-os kernellel meg hozza kapcsolodo API-val kapcsolatosan is megjelennek azok a problemakorok amik a nagy renszerek eseten is. Pl hogy mikor jobb spinlock-ot vagy mikor jobb szemafort/mutexet hasznalni, mennyire fugghet ez attol hogy milyen jellegu a krtikus szakasz amit vedeni kell (azaz csak szamolgatos vagy van-e benne potencialis I/O, vagy I/O tranzakcio), miket erdemes hasznalni privilegizalt illetve user-mode esetekben, mar itt elojonnek a kulonbsegek szemaforok meg mutexek kozott, mikor lehet megsporolni az atomi muveteket, mifele problemak jonnek be ha multi-core rendszerek is vannak, stb.

Szoval tenyleg erdekes lehet hogy mas nyelvek hogyan es/vagy milyen nyelvi elemekkel operalniak, mert a megoldando alapproblemak viszont kb hasonlo jelleguek :) Pl pont a Java-nal ezeket alig ismerem.

Szerk: pl C-ben jo lenne egy ilyen nyelvi elem:

int some_lock(int x)
{
 printf("Enter lock %d\n",x);
 /* do_lock(x); */
 return(0);
}

int some_unlock(int x)
{
 /* do_unlock(x); */
 printf("Leave lock %d\n",x);
 return(0);
}


#define some_critical(x) for ( int __i=({ some_lock(x);0; }); __i==1 ? ({ some_unlock(x); 0; }) : 1; __i++ )

int main(int argc,char *argv[])
{
 int    x;

 x=7;

 some_critical(x)
  {     int     __i;
        __i=3;
        (void)__i;
        printf("something interesting.\n");
  }

 return(0);
}

Es akkor a do_lock/do_unlock lehetne minden a cli/sei-tol kezdve a spinlock-on keresztul a mutexekig barmi... ahol persze x az valami some_lock_t; 

Szoval tenyleg erdekes lehet hogy mas nyelvek hogyan es/vagy milyen nyelvi elemekkel operalniak, mert a megoldando alapproblemak viszont kb hasonlo jelleguek :) Pl pont a Java-nal ezeket alig ismerem.

Ha valakit érdekel, akkor szerintem ezt a Scala alatti ZIO library oldja meg a legjobban.

Itt egy jó bemutatása, miként működik: John A De Goes - ZIO: Next-Generation Effects in Scala

Tudom, hogy nem "igazi" többszálú megoldás, mert a Go runtime eltakarja az OS/HW megoldásait a konkurens feladatvégrehajtásra, de annyira elegáns és hatékony a Go nyelv megoldása, talán megér itt egy kommentet.

Itt szálak helyett gorutinok vannak, amelyek csatornákon keresztül tudnak kommunikálni, és elég egyszerű lekódolni egy pub/sub, vagy queue feldolgozó megoldást, és persze egy szerveralkalmazást. 

"Share memory by communicating; don't communicate by sharing memory"

https://go.dev/tour/concurrency/1

https://go.dev/doc/effective_go#concurrency

Ez igazából a Hoare-féle CSP megvalósítása, ott is csatornákkal működik a szálat közötti adatmegosztás.

Viszont az általad linkelt oldalon: 

Goroutines run in the same address space, so access to shared memory must be synchronized. 

Szóval mégis van szálak közötti közvetlen adatmegosztás, mert ugyanaz a címtér. Az, hogy a csatorna egy eleve szálbiztos adatstruktúra, és használd azt, az egy dolog, ilyet más nyelvben is tudsz csinálni (vannak szálbiztosra megírt adattípusok, amiket bármikor megoszthatsz a szálak között), ez nem nagy truváj.

Számomra "utoljára" elegáns és hatékony az Erlang (postafiók-üzenet és "processzek" kezelése) megoldása volt, mert - kis túlzással? - aköré építették a nyelvet.

Ilyen szinten még "szemnyitogató" :) lehet a continuations és coroutines terület - ehhez én a Scheme-t ajánlom.

annyira elegáns és hatékony a Go nyelv megoldása

Már meg ne haragudj, de az már megint egy magas szintű absztrakció. Ez a topik pont azért született, mert a HUP-os közönség csak a magas szintet ismeri, és halvány lila fogalma sincs, alacsony szinten miként történnek a dolgok.

De ha már programozási nyelv, nekem egyébként az Ada95 szálkezelése tetszik nagyon, eddig még sehol nem láttam annyira szép és teljeskörű nyelvi implementációt, mint ott (a Pascal szerű szintaxist leszámítva, szemantikailag értem, hogy szép).

Szerkesztve: 2024. 07. 25., cs – 12:09

Na jó, a sok okoskodó balfasznak, akik még olvasni sem tudnak, idemásolom mégegyszer:

Aki tudja hasznosítani, amit itt összeírtam, annak egészségére és örülök, aki nem, hát az magára vessen.

Már a GUI topikomban is megmondtam, hogy ha valakinek mások az igényei, mint amikre a lib készült, az használjon mást és kész. De nem értették.
Itt is ez van, ha nem tetszik, ne olvasd.

A továbbiakban nem érdekel, ha hülyék maradtok, ágyő! :-D

? Én tök nyugodt vagyok. Ha a stílusom miatt hiszed, hogy nem, hát azt csak azért használom, mert ezek a trollok nem értenek a szép szóból.

Nekik kéne mondani, hogy nyugi, mert jól láthatóan idegesek és elvesztették az eszüket. Annyira, hogy már nemcsak össze-vissza hazudoznak, hanem konkrétan bizonyítékot próbáltak hamisítani. Erre nincs semmilyen mentség. Ráadásul annyira dilettánsok és balfaszok, hogy összekeverték az Assembly dialektusokat, így egyből lebuktak a hamisítási kísérletükkel.

Mármint itt nem arról van szó, hogy tévedtek. Megpróbáltak bizonyítékot hamisítani, na az már egy egész más alja szint, nem igaz?

te bzt... egy paripafütyit vagy nyugodt. nekem tényleg nincs veled semmi bajom, de ez elsősorban egy szakmai fórum. És szerintem ebben a fórumban (velem szemben at least) még egy épképzláb érvelésed nem volt, csak az anyázás s a hiszti, hogy olvassuk el és hogy mindenki hülye, rajtad kívül, természetesen.

Se viselkedni, se érdemben érvelni nem tudtál, már meg ne haragudj. Kernel-buzzwordöket villogtatva még nem győztél meg, bocs.

Én úgy érzem, hogy minden állításomat érdemben megérveltem, alátámasztottam, de ez szerinted trollkodás. Természetesen, ha az egodat simogattam volna, gondolom még meg is köszönted volna.

most komolyan:

"Ha ennek a regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk."

ez a multithreading, hogy megváltozik a  "normál programfolyam"? Ha egy program setjmp/longjmp-t használ, akkor is megváltozik a normál programfolyamat, mégsem multi-threaded. A multi-threaded konkrétan azt jelenti, hogy több szálon fut (wikipedia: "Multithreading is a widespread programming and execution model that allows multiple threads to exist within the context of one process.")

 

Akkor meséled a multitaszkingnál, hogy lehet kooperatív, szekvenciális meg preemtív. Ez mondjuk igaz, de miért, a threadek nem preemtíven vannak általában megszakítva?

 

"A többmagvas processzor azt jelenti, hogy egyszerre több utasításszámláló regiszterrel is gazdálkodhatunk."

A többmagos processzor azt jelenti, hogy konkrétan több magja van. Hyperthreadingnél is több utasításszámláló van, a kernel konkrétan több processzort lát, mégsem több magos a processzor.

 

Mondhatsz, amit akarsz, de ezeket nem gondoltad át. De megsértődsz, ha valaki nem szarja össze magát tőled.

 

1. Nekem semmi bajom a szakmai tudásoddal, de még mindig fenntartom, hogy helyenként hülyeségeket írtál.

2. Ha ez a stílusod, ám legyen, (nekem nincs szükségem arra, hogy lehülyézzelek) és ez nem engem minősít. De szerintem itt még vannak olyanok, akik egyetértenek velem abban, hogy egy szakmai fórumon ez a viselkedés nem helytálló, nem etikus, bántó, egyenesen neveletlenség és ahogy fennebb írtam: szerintem neked komoly problémáid vannak a szociális készségeiddel. Ezt ne trollkodásnak vedd, hanem gondolkozz el rajta.

egy paripafütyit vagy nyugodt

Talán nemcsak Napóleonnak hanem telepatának is képzeljünk magunkat? Mégis honnan tudhatnád ezt, elmeroggyantkám?

nekem tényleg nincs veled semmi bajom

Nekem viszont nagyon is van bajom veled, ugyanis egy szar alak vagy, hazudsz, és még hamisítani is megpróbáltál. Pont az olyan senkiházi hazudozó alakok miatt szenved ez az egész gyönyörű ország, mint amilyen TE vagy.
Elképzelni se tudom, mi járhatott abban a beteg fejedben, hiszen bárki egyetlen kattintással meggyőzödhet róla, hogy a kódrészleted semmiképp sem származhat az entry_64.S-ből.

Erre mondják, hogy dilettáns idióta, és azon nincs is mit csodálkozni, hogy most meg felkaptad a vizet és besértődtél, hogy lebuktál és senki nem kajálta be a faszságod.

Egy ilyen alja senkiházi hazudozó trollal nincs mit beszélnem a továbbiakban. Viszlát!

a hamisítást te találtad ki. fent szépen el van magyarázva: ida-val disassembláltam, ott van az eredmény. intel assembly, nem at&t. csak nem olvastad el, ugye... mert minek...

 

ott van, entry_64.o: https://ibb.co/KK4V3pH

 

 

Erre mondják, hogy dilettáns idióta, és azon nincs is mit csodálkozni, hogy most meg felkaptad a vizet és besértődtél, hogy lebuktál és senki nem kajálta be a faszságod.

bocs, de itt te vagy az is aki vádol és az is, aki megsértődött 🤭

// Happy debugging, suckers
#define true (rand() > 10)

Ez nekem disassembly nélkül is ott van

Ne csinálj már te is komplett hülyét magadból... Neked az alábbi két kódrészlet netán azonosnak tűnik?

Az igazi tartalom:

SYM_CODE_START(error_entry)
	ANNOTATE_NOENDBR
	UNWIND_HINT_FUNC

	PUSH_AND_CLEAR_REGS save_ret=1
	ENCODE_FRAME_POINTER 8

	testb	$3, CS+8(%rsp)
	jz	.Lerror_kernelspace

és micsa troll kódja:

SYM_CODE_START(error_entry)
	ANNOTATE_NOENDBR
	UNWIND_HINT_FUNC

	PUSH_AND_CLEAR_REGS save_ret=1
	ENCODE_FRAME_POINTER 8

	push    rsi
	mov     rsi, [rsp+8]

Segítek, testb != push.

Micsa troll már csak azért is nyilvánvalóan hazudik, mert egy valódi disassembly-ben nem is lehetnének ott az előfordító makrók. Persze ha nem lenne egy dielttáns idióta, mint minden troll, akkor tudná ezt, és meg sem próbálta volna azt hazudni, hogy ez egy disasembly...

Igen, nem csak azonosnak tűnik, de azonos is:

https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S…

SYM_CODE_START(error_entry)
    ANNOTATE_NOENDBR
    UNWIND_HINT_FUNC

    PUSH_AND_CLEAR_REGS save_ret=1

Ahol a "PUSH_AND_CLEAR_REGS" jön az entry_64.S -be itt: https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S…

#include "calling.h"

Ami aztán itt van definiálva: https://github.com/torvalds/linux/blob/master/arch/x86/entry/calling.h#…

Amit persze tovább kell követni egészen idáig: https://github.com/torvalds/linux/blob/master/arch/x86/entry/calling.h#… ahol ezek születnek:

    .if \save_ret
    pushq    %rsi        /* pt_regs->si */
    movq    8(%rsp), %rsi    /* temporarily store the return address in %rsi */
    movq    %rdi, 8(%rsp)    /* pt_regs->di (overwriting original return address) */
    .else
    pushq   %rdi        /* pt_regs->di */
    pushq   %rsi        /* pt_regs->si */
    .endif
    pushq    \rdx        /* pt_regs->dx */
    pushq   \rcx        /* pt_regs->cx */
    pushq   \rax        /* pt_regs->ax */
    pushq   %r8        /* pt_regs->r8 */
    pushq   %r9        /* pt_regs->r9 */
    pushq   %r10        /* pt_regs->r10 */
    pushq   %r11        /* pt_regs->r11 */
    pushq    %rbx        /* pt_regs->rbx */
    pushq    %rbp        /* pt_regs->rbp */
    pushq    %r12        /* pt_regs->r12 */
    pushq    %r13        /* pt_regs->r13 */
    pushq    %r14        /* pt_regs->r14 */
    pushq    %r15        /* pt_regs->r15 */

Szóval de, ott van az, igaz végig kell követni a makrókat, de nem gondoltam volna hogy ez problémát okoz neked. Az egész pedig nem lesz kevésbé igaz azért, mert ő mixelte a disassembly-ből kapott kódot az eredetivel azért, hogy egyszerűbben kifejthető legyen egy hsz-ben mint a mostani blob-om, ahol lépésről lépésre végigmegyek neked. Az egész dolog tényén pedig végképp nem változtat semmit

// Happy debugging, suckers
#define true (rand() > 10)

Nekem viszont nagyon is van bajom veled, ugyanis egy szar alak vagyhazudsz, és még hamisítani is megpróbáltál. Pont az olyan senkiházi hazudozó alakok miatt szenved ez az egész gyönyörű ország, mint amilyen TE vagy.
 

ezen már csak azért is sírva kell felröhögnöm, mert még nem is abban az országban élek 🤭

Szerkesztve: 2024. 07. 25., cs – 23:48

En ugy latom nem igazan sikerult megtalalni kinek is szol ez a fejtagito. Egyreszrol egyszerusitett masreszrol tele van olyan reszletekkel ami nem oda valo. Nem igazan vilagos, hogy OS szinten vagy programnyelv szinten taglalod a dolgokat. Gondolom jobb cim lett volna "Többszálúság fejtágító hardcode C fejlesztoknek OS nezopontbol". Az egesz tema nagyon bonyolult lehetetlen egyszeruen roviden elmagyarazni. Nem csodalkozom hogy sok kritikat kaptal lehetetlenre valalkoztal. Nem lehet 2-3 konyv tartalmat fel oldalban elmagyarazni. Szerintem eleg lett volna tisztazni a fogalmakat elmeleti sikon kihagyva az OS-t. Kb hasonlot mint amit a ChatGpt csinalt.

Lassan gépelem, hogy biztos el tudjátok olvasni: TANULJATOK MÁR MEG MAGYARUL OLVASNI.

Nem igazan vilagos, hogy OS szinten vagy programnyelv szinten taglalod a dolgokat.

Itt egy újabb kötekedő, akinek (minő meglepetés) valójában az a baja, hogy nem képes magyar nyelvű szöveget olvasni és értelmezni. Minden kérdésedre lett már adva válasz, csak hát olvasni luxus ugye...

Idemásolom mégegyszer: "Ez a topik pont azért született, mert a HUP-os közönség csak a magas szintet ismeri, és halvány lila fogalma sincs, alacsony szinten miként történnek a dolgok."

Az egesz tema nagyon bonyolult lehetetlen egyszeruen roviden elmagyarazni.

FACEPALM. Sosem volt cél a teljes körű magyarázat, ez mindig is egy glossary-nak volt szánva, és ez még a topiknyitóban is ott áll kerek-perec, csak hát olvasni is kéne tudni: "Előrebocsátom, hogy az alábbi definíciók NEM teljesek, szándékosan hiányosak és leegyszerűsítettek, csupán azokat az aspetusokat emeltem ki belőlük, melyek a többszálúság kapcsán relevánsak."

De mi több, ezt külön le is írtam már, de ezt is idemásolom mégegyszer: "Igen, nem véletlenül tituláltam mini fejtágítónak. Simán meg tudnék tölteni egy könyvet is ezzel, itt csak egy gyors glossary-t akartam"

Nem csodalkozom hogy sok kritikat kaptal lehetetlenre valalkoztal.

Nem kaptam egyetlen kritikát se, az nem kritika, ha valaki picsog, hazudozik meg hamisítani próbál.
És nem szabadna, hogy egy szakmai fórumon ennek megértését bárki "lehetetlen"-nek titulálja. Ha menne nektek a magyar nyelvű szövegértés, akkor talán még tanulhatnátok is abból, ami le lett írva.

Nyilvánvaló, hogy még véletlenül sem velem és a segítő szándékommal van a baj, hanem veletek trollokkal, akik még olvasni se tudnak, csak jártatjátok a szátokat, mint egy Rogán propagandista. Mit nektek tények, ugye?

Szerintem eleg lett volna tisztazni a fogalmakat elmeleti sikon kihagyva az OS-t.

Oszt annak mégis mi értelme lett volna, arra ott a ChatGPT, az pont a ti értelmi színvonalatokon áll és csak a magas szintről hadovál.

Pont az volt a lényeg, hogy alacsony szintről is legyen valami írás, mert ahhoz vagytok igazán hülyék, ahhoz van szükségetek fejtágítóra. Magas szintre úgyis a ChatGPT-t használjátok, ugye...

"Ez a topik pont azért született, mert a HUP-os közönség csak a magas szintet ismeri, és halvány lila fogalma sincs, alacsony szinten miként történnek a dolgok."

azért nem kis pofa kell egy ilyet leírni egy olyan helyen, ahol vannak olyanok, akik ~20 éve HUP tagok. Tudod: akik már akkor assemblyben programoztak, amikor neked még szerintem nem is szőrösödött...

 

Pont az volt a lényeg, hogy alacsony szintről is legyen valami írás, mert ahhoz vagytok igazán hülyék, ahhoz van szükségetek fejtágítóra. Magas szintre úgyis a ChatGPT-t használjátok, ugye...

szerintem meg pont az volt a lényeg, hogy egy kicsit villoghass és megmondd a tutit. 

 

Nyilvánvaló, hogy még véletlenül sem velem és a segítő szándékommal van a baj, hanem veletek trollokkal, akik még olvasni se tudnak, csak jártatjátok a szátokat, mint egy Rogán propagandista. Mit nektek tények, ugye?

mondjuk a "meg nem értett zseni" nem ártana, ha el is tudná mondani, hogy mit akar

azért nem kis pofa kell egy ilyet leírni egy olyan helyen, ahol vannak olyanok, akik ~20 éve HUP tagok.

És annak, hogy mióta tagok, mégis mi köze a tudásszintjükhöz?

szerintem meg pont az volt a lényeg, hogy egy kicsit villoghass és megmondd a tutit.

LOL.

mondjuk a "meg nem értett zseni" nem ártana, ha el is tudná mondani, hogy mit akar

Megtettem, de nem ártana, HA EL IS TUDNÁD OLVASNI. Ja, persze, magyar nyelvű szövegértés az neked nem megy.

azért nem kis pofa kell egy ilyet leírni egy olyan helyen, ahol vannak olyanok, akik ~20 éve HUP tagok. Tudod: akik már akkor assemblyben programoztak, amikor neked még szerintem nem is szőrösödött...

Valójában ő sem mostanában kezdte itt a vitatkozást, anno ki is érdemelt egy hangzatos címet PaXTeam-től:

ez kesz, te megnyerted 10 evre elore a balfasz@hup cimet ;). lentebb mindjart atnezzuk, mit sikerult eddig 'bizonyitanod' ;).

Ez csak az összefoglaló, érdemes elolvasni az egész szálat az elejétől.

Azóta eltelt 12 év, de a kommunikációs stílus és az ego nem változott, csak a nick…

Ha valaki felül tud emelkedni ezen a többek által is kifogásolt stíluson, az találhat hasznos infókat ezekben az eszmecserékben is, szóval ne hagyjátok abba, csak azt ne várjátok közben, hogy bármilyen érv hatására megváltozik a kommunikációja vagy nyilvánosan belátja a tévedéseit! ;-)

Szabi

Attol meg hogy valaki magas szinten programoz nem biztos hogy hulye, es ez igaz a forditotjara is. En semmilyen allitast nem tettem a te viselkedesedre vagy szellemi szinvonaladra, es nem is fogok.
Azt irod hogy "lényeg, hogy alacsony szintről is legyen valami írás", de ezt nem tunteted fel sem a cimben sem a szovegben. Ez ami nagyon felreertheto es felrevezetol lehet annak aki nem teljesen szakertoje a temanak. Ami nem is elvarhato hiszen ez a HUP es nem egy programozo szakportal. Altalaban ritkan szoktam ide irogatni, de mivel 20+ ev szoftverfejlesztes utan talan van valami fogalmam ezektol a fogalmakrol, ugy ereztem talan tudok segiteni a fogalmak tisztazasaban. Valaszodbol azt szurtem le nem igazan erdekel masok velemenye es mindent szemelyes vagy szakmai tamadasnak ertekelsz. Eppen ezert ne vedd sertesnek ha nem valaszolok a reakciodra, vagy ha sertesnek veszed az a te dolgod.    

Ebben a topikodban megvártam, hogy másoknak a szakmai hozzászólásaira jöjjön elő a lealacsonyító sértegetésekkel válaszoló istenkomplexusod.

Nálad az a definíciója a multithreading-nek, hogy a PC/IP "regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk."

Tehát ha MS-DOS-ban, vagy ha manapság is használt közismertebb alternatívát nézünk, mondjuk Arduino/AVR esetén, amikor hardver interrupt kiszolgálás kezdődik: a régi PC/IP érték elmentődik a memóriába, konkrétan a stack-be, és a processzor állapotában az a változás következik be, hogy a PC/IP regiszter egy normál programfolyamtól eltérő értéket vesz fel. Már ne haragudj, de az interrupt kiszolgálást és az MS-DOS / Arduino rendszerek ezzel kapcsolatos működését rajtad kívül senki nem nevezi multithreading-nek.

Messiásnak képzeled magad és kinyilatkoztatásokat teszel, ami alapból csak furcsa lenne. Baj ott lesz belőle, hogy a személyiséged nagyjából Eric Cartman legrosszabb énjét idézi, ha valaki nem nyalja a segged, akkor egyből trollnak nevezed és sértegetni kezded, miközben a kinyilatkoztatásaid legalábbis nagyon erősen véleményesek. A troll te magad vagy.

Azért egy troll szájából ez rohadtul röhejes, azzal tisztában vagy ugye? LOL

Egyébként is, soha sem rejtettem véka alá (de még direkt meg is írtam, többször is), hogy az olyan seggfej trollok, mint te ne számítsanak tőlem semmi másra, mint viszonttrollkodásra. Hát nem tűnt fel, hogy csak a hozzád hasonló balfaszokat oltom, mindenki mással normálisan kommunikálok? Persze, hogy nem tűnt fel.

Te kezdted a trollkodást, de felsültél, alaposan le lettél oltva és viszonttrollkodást kaptál az arcodba, most meg itt rinyálsz emiatt. Mégis, mire számítottál, mikor eleve megmondtam, hogy ez lesz?

Továbbra sem tűnt fel, hogy kontraproduktív, amit csinálsz? Hiába seggfejezel, egészséges pszichéjű, felnőtt emberekkel állsz szemben, akiket ez nem riaszt el.

És hogy ki sült fel végül? Nyugodtan vesd össze azzal, amit itt művelsz, mivel ugyanaz a sztori:

Itt kinyilatkoztatod, hogy te aztán mindenkinél jobban ismered a multithreadinget. Ott kinyilatkoztatod, hogy te mindent megoldottál a többszálú UI toolkitek kapcsán.

Itt jöttek többen is szakmai észrevételekkel. Ott én úgy csatlakoztam be, hogy hoztam linkekkel egy példát, hogy az AWT-nél ezen már kb. 30 éve átestek, hogy mennyire lehetséges egy multithread UI, és belátták a saját tévedésüket. Ebben amúgy továbbra sem világos, hogy mi volt a trollkodás.

Itt jöttél a szokásos sértegetésekkel, meg hozzá a témát viszonylagosan érintő, de a konkrét kérdéshez nem teljesen releváns kódrészletekkel. Ott is ugyanez történt, kicsit hosszassabban eszkalálódott. Ezútom is elismerésem micsa-nak, hogy ő itt hamarabb tudta zárni a témát.

(Ami itt nem volt, csak a másik topikban, valaki beidézett egy AI által generált választ, ami engem cáfolt, és ott el is ismertem tévedésem. Aztán kiderült, hogy az AI által generált válasz faszság)

Itt végül nem tudtál a helyesen idézett kódrészletekre semmi érdemlegest válaszolni, legfeljebb a disassembly kódról a hamisításról vádaskodást. És aztán a másik topikban is kiderült a végére az igazság: 1., 2. 

En ehhez (sem) ertek, de a kommentszekcioban eloadott handras-puzser improv, az valami csucs. :)

Szerkesztve: 2024. 07. 26., p – 13:14

szóval... az egyik "konfúzió", amiről bzt beszél, csak nem tudja leírni... az a pthread library... ami, ha jól tudom, Solaris-on user-level threadekkel (is) volt megimplementálva, de linuxon mindig is csak kernel-threadekkel működott... először linuxthreads, majd NPTL (2.6-os kerneltől).

 

de a solaris-os implementációban is volt preemtív megszakítás, ahol nyilvánvalóan elmentette az adott task állapotát, regisztereket, stack pointert, mindent (a TCB-be)... aztán ott is áttértek a csak-kernel thread-es modellre.

csak 2024-ben már senkit nem érdeklenek a user-level threadek...

az a pthread library... ami, ha jól tudom, ... linuxon mindig is csak kernel-threadekkel működott.

Jól van, hulla felesleges tovább bizonygatnod, hogy segghülye vagy a témához, már mindenki tökéletesen tisztában van vele. Miután megpróbáltál bizonyítékot hamisítani, már mindenki csak röhög rajtad, akkor is, ha nem írsz ekkora ökörségeket.

Nem, a pthread-nek és a kernel-threadnek SEMMI közük egymáshoz. Ha ezt nem vagy képes felfogni, akkor menj el kertésznek vagy építőmunkásnak, mert a PROGRAMOZÁS NEM NEKED VALÓ.

csak 2024-ben már senkit nem érdeklenek a user-level threadek...

FACEPALM.

Itt szerintem két külön dolgot értetek kernel thread alatt, és ez okozza a félreértést. bzt itt azt mondja kernel thread-nek, ami a kernelben fut, kernel privilégiumokkal. micsa azt érti alatta, ami normál user módú thread, de a kernel hozza létre és a kernel intézi a scheduling-ot. És egy harmadik dolog amit micsa user-level thread-nek hív, az olyan dolog, amiről a kernel nem is tud, a processz saját magán belül teljesen user módban oldja meg a schedulingot. A pthread legtöbb implementációja a 2. eshetőséget csinálja, de a 3. is létezhet, bár ott általában kihívásokra fel kell készülni. És itt a 2. és 3. közti különbségre gondolt micsa.

de a 3. is létezhet, bár ott általában kihívásokra fel kell készülni.

Igen, ez egy erdekes kihivas lehet. Pl timer_create(), setitimer(), alarm() segitsegevel...? Valami rendszerhivas biztos kell hozza mert privilegizalas nelkul nem ferhet hozza az egy szalon futo user-mode processz semmi olyasmihez ami preemtiv jellegu. 

Erdekes ez a kernel <-> user thread, mindkettonek vannak elonyei es hatranyai.

A Java most tert vissza az egyfajta user thread-re a virtual threadekkel ami kombinacioja a kettonek otvozve mindket oldal jo tulajdonsagait. Az implementacio jol peldazza hogy a multithreading mennyire osszefugg a szinkron aszinkron vegrehajtassal. Hasonlo "user thread", lightweight thread/concurrency koncepcio van mas nyelvekben is lasd Go. Ez azert van mert rajottek hogy jol skalazhato massziv parhuzamos mukodest hatekonyan nem lehet kernel thread-ekkel megvalositani, lasd a nem mai "C10K problem" es modern tarsai. 

nézd, én itt ezt befejeztem, nekem erre több energiám nincs

én nem hamisítottam semmit, ezzel velem mások is egyetértenek, ha még mindig itt tartunk, akkor azt gondolom, hogy neked tényleg súlyos problémáid vannak... én a helyedben tényleg felkeresnék egy szakembert...  a legnagyobb jóindulattal mondom... segítséget kérni nem szégyen... sok szerencsét az életben...

Jellemző troll viselkedés, de hiába, rólam lepattan.

én nem hamisítottam semmit,

Valóban, csak szerettél volna hamisítani meg hazudozni, de rohadt gyorsan LEBUKTÁL, mert nem értesz hozzá. Hazug embert könnyebb utolérni, mint a sánta kutyát!

ezzel velem mások is egyetértenek

Csakis a 4 spanod, márha nem alteregók eleve, ugye. Egyébként meg tök mindegy, Föld nem sem lesz lapos, akárhány idióta is állítja róla, akkor sem lapul ki.

És hogy tisztázzuk, egyértelműen hamisítottad a kódot ebben a posztodban:
1. azt állítottad, hogy a kódrészlet az entry_64.S-ből való. Nem írtál semmiféle disassembly-ről még csak véletlenül sem.
2. mikor rámutattam, hogy hazudsz, mert még a dialektusa is más, mint a valódi kernelé, azután - de csakis azután, nem előtte - kitaláltad az újabb ida-s disassembly-s hazugságot
3. csakhogy egy disassembly nem tartalmazhatna előfordító makrókat, amik viszont nagyon is ott virítanak az eredeti posztodban, tehát ez is egyértelműen hazugság.

Ez már nem mosod le magadról, bárki láthatja mennyire gerinctelen féreg vagy, aki még azután sem kér bocsánatot, hogy lebukott, hanem inkább még tovább ront a helyzetén azzal, hogy hárítani meg kétségbeesetten pocskondiázni próbál.

sok szerencsét az életben...

Tökéletes, meg ne lássalak Téged vagy a spanjaidat bármelyik eljövendő topikomban! Ha mégis odapofátlankodnátok, előre szólok, hogy csak alázásra és oltásra számíthattok, mert még olvasni sem tudtok!

Itt vered a melled, hogy téged bizony nem ért meg senki, de ahol ki van fejtve a történet, oda már nem böfögsz vissza.

Egyébként pedig ha már hazugság, akkor te hazudsz: 1. azt állítottad, hogy a kódrészlet az entry_64.S-ből való. Nem írtál semmiféle disassembly-ről még csak véletlenül sem.

Ezzel szemben a valóság az, hogy ő ennyit írt:

a regiszterekről beszéltem... csak úgy halkan mondom, hogy pl. az asm_sysvec_apic_timer_interrupt így kezdődik:

Illetve:

az error_entry pedig (entry_64.S):

Egyrészt nem írta, hogy ez a részlet innen való (még azt sem írta, hogy egy forráskódot másol direktben, így lehet az bármi, pl.: disassembly output), csupán hivatkozott rá, hogy valami így kezdődik és megjelölte, hogy egyébként merre található (entry_64.S). Ebből egy valódi programozó összerakja a dolgokat, ha pedig megnézi a konkrét hivatkozást, akkor látja a makrókat amit aztán végigkövethet.

Ha mégis odapofátlankodnátok, előre szólok, hogy csak alázásra és oltásra számíthattok, mert még olvasni sem tudtok!

Jelen pillanatban az egyetlen, akit megaláztál, az saját magad volt

// Happy debugging, suckers
#define true (rand() > 10)

Egyrészt nem írta, hogy ez a részlet innen való

Kódrészlet elé kiírta a fájl nevét kettősponttal, ez egyértelműen azt jelzi, hogy a kódrészlet (állítása szerint) abból a fájlból való, már bocs.

csupán hivatkozott rá, hogy valami így kezdődik és megjelölte, hogy egyébként merre található (entry_64.S)

Na hát ez, arra nem található, és nem is úgy kezdődik, pontosan ezért hazugság, amit állított.

Tisztázzuk, még ha el is hinnénk azt a hazugságot, hogy valóban ida-zott, az általa bemásolt kódrészlet akkor sem felel meg a valóságnak, mert a függvény "testb" utasítással kezdődik, és nem "push" utasítással. PONT.

>>a függvény "testb" utasítással kezdődik, és nem "push" utasítással. PONT.

illetve hát pont nem

$ objdump --disassemble=error_entry entry_64.o

entry_64.o:     file format elf64-x86-64


Disassembly of section .text:

Disassembly of section .entry.text:

00000000000018a0 <error_entry>:
    18a0:       56                      push   %rsi
    18a1:       48 8b 74 24 08          mov    0x8(%rsp),%rsi
    18a6:       48 89 7c 24 08          mov    %rdi,0x8(%rsp)
    18ab:       52                      push   %rdx
    18ac:       51                      push   %rcx
    18ad:       50                      push   %rax
    18ae:       41 50                   push   %r8
    18b0:       41 51                   push   %r9
    18b2:       41 52                   push   %r10
    18b4:       41 53                   push   %r11
    18b6:       53                      push   %rbx
    18b7:       55                      push   %rbp
    18b8:       41 54                   push   %r12
    18ba:       41 55                   push   %r13
    18bc:       41 56                   push   %r14
    18be:       41 57                   push   %r15
    18c0:       56                      push   %rsi
    18c1:       31 f6                   xor    %esi,%esi
    18c3:       31 d2                   xor    %edx,%edx
    18c5:       31 c9                   xor    %ecx,%ecx
    18c7:       45 31 c0                xor    %r8d,%r8d
    18ca:       45 31 c9                xor    %r9d,%r9d
    18cd:       45 31 d2                xor    %r10d,%r10d
    18d0:       45 31 db                xor    %r11d,%r11d
    18d3:       31 db                   xor    %ebx,%ebx
    18d5:       31 ed                   xor    %ebp,%ebp
    18d7:       45 31 e4                xor    %r12d,%r12d
    18da:       45 31 ed                xor    %r13d,%r13d
    18dd:       45 31 f6                xor    %r14d,%r14d
    18e0:       45 31 ff                xor    %r15d,%r15d
    18e3:       f6 84 24 90 00 00 00    testb  $0x3,0x90(%rsp)
    ...
    ...

- Ad egy: a kérés kifejezetten az volt, hogy az entry_64.S-ből idézzen!
- Ad kettő: na így néz ki egy disassembly, de ő NEM is ezt a kódot másolta be, még véletlenül sem! De mégha ezt is másolta volna be, a kérés kifejzetten az volt, hogy az entry_64.S-ből idézzen!
- Ad három: ez a kód rohadtul nem ment MINDIG, MINDEN regisztert minden megszakításnál, mint ahogy állította. Már megmondtam ezt is, hogy az error_entry nem mindig hívódik, és ráadásul SIMD/FPU mentés sincs benne, és azt még apai is tudja, hogy az része lenne a MINDEN-nek.
- Ad négy: hát nem azt picsogtátok, hogy a megszakítás nem is multithreading, akkor meg miért is lenne érdekes, hogy egy megszakításnál mi mentődik, "az a klasszikus megszakitas-hivas, nem pedig a multithreading"? Itt már megint öngólt rúgtatok, gratulálok!

De snq- lenni baromarcú troll, nem tudni magyarul olvasni és szövegérteni, ezért olyanba kötözködni, ami egyértelműen le lenni már írva! LOL

Csak úgy kérdezem, nem unjátok még, hogy minden trollkodási próbálkozásotok besül, csúnyán beégtek, és csak le lesztek (tök jogosan) oltva? Egyesik szerint a hülye az, aki ugyanazt ismétli és más kimenetelt vár...
Nem lesz más kimenetel: ha továbbra is hazudozni próbáltok, csak felsültők és alázásban lesz részetek, ahogy megérdemlitek.

"mert a függvény "testb" utasítással kezdődik, és nem "push" utasítással. PONT."

Nem kellene hazudozni, a függvény négy makróval indít, nem testb -vel

Nem kellene hazudozni, a makró az még csak véletlenül sem Assembly nyelvű utasítás. Sőt, még csak nem is az assembler dolgozza fel...

"a makró az még csak véletlenül sem Assembly nyelvű utasítás."

Szóval nem lényeges, hogy ott van, nem számít, hogy a függvényhez tartozik és nem tartalmazhat semmit, ami hozzátesz a végleges kimenethez, a függvény kizárólag a testb utasítással kezdődhet a makrók ellenére. Ezt állítod?

// Happy debugging, suckers
#define true (rand() > 10)

Tökéletes, meg ne lássalak Téged vagy a spanjaidat bármelyik eljövendő topikomban!

Azért erre van egyszerűbb megoldás is: ne írj egy fórumban hülyeségeket. Mégis mit vártál, konkrétan ebben a topikodban már a legelső definíciód is egy óriási tévedés, ami főleg úgy visszatetsző, hogy úgy kezded, hogy te aztán majd jól helyreteszel mindenkit.

annyira kellemetlen olvasni a stílusát

Mondja a troll. Mégis, idejöttél, ideböfögted ezt, szerinted mennyi szakmai komolyságot sikerült ezáltal felmutatnod?

Annak meg kifejezetten örülnék, ha valóban kerülnének a hozzád hasonló seggfejek, ha nem tűnt volna fel, eleve ez volt a cél a viszont trollkodással ;-)

részemről ezentúl azt ír, amit akar

De aztán álld is a szavad, kerüld el jó messze a topikjaimat a spanjaiddal együtt! Eleve ezt posztot sem kellett volna megírnod!

Azért erre van egyszerűbb megoldás is: ne írj egy fórumban hülyeségeket.

Te voltál az, aki az SMGUI topikomba off-topik hülyeségeket kezdett irogatni, még véletlenül sem én mentem utánnad. És most is, Te vagy az, aki idejött egy pofonért!

Trollkodni próbáltál, aztán meg itt sírsz, hogy felsültél, és viszont lettél trollkodva.

Bizonyára nem emlékszel, hogy mi volt az SMGUI topikodban: egyrészt többször is leírtam, hogy én elismerem, hogy csinálod a toolkit-edet. De: kijelentetted, hogy te kisujjból megoldottad a multithread UI-k problémáját, amire én a legelső hozzászólásomban nem is saját, hanem a Java AWT fejlesztők véleményét linkeltem be, akik ezen már évtizedekkel ezelőtt túl voltak, hogy lehetséges-e egyáltalán normálisan multithread UI-t csinálni. Ebben mi a trollkodás? Talán az, hogy nem a seggedet nyaltam?

És hogy ki sült fel? Gondolom már nem emlékszel, mi lett a vége: 1., 2.

Azt mondtad, nem irogatsz többet!

leírtam, hogy én elismerem, hogy csinálod a toolkit-edet.

Konkrétan azt hitted, JS motort írok, erről ennyit...

kijelentetted, hogy te kisujjból megoldottad a multithread UI-k problémáját

Hol is állítottam állítólag ezt? SEHOL. Konkrétan azt állítottam (próbáld meg értelmezni és felfogni), hogy kemény munkával és körültekintő odafigyeléssel megoldottam azt, hogy ne okozzon problémát, ha a view réteg és a controller réteg különböző szálakon fut! (Szemben az immediate-mode GUI-val, ahol a view és controller szétválasztása külön szálra NEM lehetséges.) És ezt nemcsak állítottam, hanem a GYAKORLATBAN IS BIZONYÍTOTTAM.

Csak hát nem te nem tudni magyarul olvasni meg nem menni magyar szövegértés, ugyebár!

És hogy ki sült fel?

Egyértelműen TI. Megígértétek, hogy nem irogattok többet, de még erre sem vagytok képesek, mert az internetes pöcegödör legalja trollok vagytok.

Hol is állítottam állítólag ezt? SEHOL.

Ahaha, hadd segítsek: erre "Az összes általam ismert UI toolkit egyszálú" ezt válaszoltad: "És jó szar is mind. Itt semmi akadálya, hogy az egyik szálon futó GUI által beállított változó értékét egy másik szálon kérd le, vagy hogy az egyik szálon beállított érték alapján a másik szálon futó GUI megfelelően jelenítse meg a check box-ot vagy akármit."

És erre "Mire és hogyan kell a multithreadinget használni?" ezt válaszoltad: "Bármilyen művelet esetén."

És a legszebb, hogy ezeken a pontokon én még nem is vettem részt a párbeszédben. Na erre varrjál gombot.

 

Konkrétan azt hitted, JS motort írok, erről ennyit...

Senki nem hitte ezt, ezt főleg úgy furcsa leírnod itt most, hogy konkrétan a rákövetkező hozzászólásban egyből felvilágosítottalak, hogy mire gondoltam szarkasztikusan, de hát ugye az a szövegértés... amit te oly sokat emlegetsz.

 

Azt mondtad, nem irogatsz többet!

Megígértétek, hogy nem irogattok többet,

Egyrészről most mi ez? Visszavonulót akarsz fújni? Mennyire átlátszó vagy. De hiszen egész eddig a győzelem kapujában érezted magad, vagy nem?

Másrészről biztos összekeversz valakivel, én sosem mondtam ilyet, sőt, explicit kijelentettem, hogy a szakmai párbeszéd amúgy engem szórakoztatna, de hát veled csak ez maradt, úgyhogy ez szórakoztat :D 

Te kezdtél off-topik hülyeségeket összehordani, te próbáltál meg trollkodni, de hülye vagy hozzá, ezért felsültél, most meg rinyálsz, hogy helyette téged trollkodtak meg.
Szánalmas.

Már a másik topikban is idéztem ezt a szép ősi magyar mondást: "aki elmegy kurvának, az ne sírjon, ha basszák", de gondolom most sem leszel képes felfogni az értelmét.

Szerintem ez az egész "fejtágító" teljesen gyakorlatiatlan, mai átlagos programozó feladataihoz képest irreleváns nüanszokon való lovagolás és faszméregetés.

Gábriel Ákos

Ebben tökéletesen egyetértünk, az egész onnan indult, pár seggarc troll mégis erről kezdett hadoválni az SMGUI-s topikomban, ékesen prezentálva, mennyire nem értenek hozzá, mert még átlagos programozónak is kevesek.

Emiatt (egy kulturált HUP-társ, még véletlenül sem troll) megkért, hogy írjam össze külön topikban, én meg szívesen összeírtam, és pont, történet vége.
Én sem értem, mi a francnak próbálnak ezek trollok még mindig itt görcsölni. Annyi értelme van itt kötözködni próbálni, mint Orbán "békemissziójának" az eredménye! :-)

Kedves seggarc trollok! Hát nem arról volt szó, hogy megfogadtátok, többet nem irogattok a topikjaimba? Akkor mégis mire véljem ezeket a további posztokat?

(Szarkazmus. Tisztában vagyok vele, hogy egy alja hazug bagázs vagytok, így nem meglepő, hogy akkor is hazudtatok, amikor azt állítottátok, nem posztoltok többet. De most legalább mindenki láthatja, mennyire nem szabad elhinni semmit nektek!)

Szerkesztve: 2024. 07. 27., szo – 13:13

A megszakítások kapcsán lenne egy javaslatom. A továbbiakban csak azokkal folytatom a diskurzust, akik helyesen válaszolnak az alábbi kérdésekre és képesek helyes példát hozni rájuk.

Aki a Halának Hídján át kíván kelni, e három kérdésre megfeleljen, vagy át nem eresztem!

- mi a különbség az exception, a soft int, hard int és IRQ között?
- mi a különbség az interrupt és a trap között?
- mi a különbség a "RET" és az "IRET" (x86) illetve "ERET" (ARM) utasítások működési mechanizmusa között?

Könnyítésként elfogadok példákat i386 (32-bit), x86_64 (64-bit), ARM7 (AArch32) valamint ARM8 (AArch64) alatt is, és az olyan nüanszokba, mint az IST bele sem kérdezek.
Aki nem ad helyes választ, annak a megszakításokkal kapcsolatos posztjaira a továbbiakban nem válaszolok, akármekkora hülyeséget is ír. Ez így fair, nem?

A helyes válaszokat egy hét múlva (aug. 3) közzé teszem, és előre leszögezem, hogy az arra érkező rinyálást leszarom, nem érdekel senkit a dilettáns kötözködésetek. Tetszik, nem tetszik, ez van!

na ide figyelj, te kis mitugrálsz...

engem nevezel te hazugnak, aki két sor disassembly-t nem tud értelmezni, csak picsogni?

engem nevezel te tanulatlannak, aki már akkor vm86 módú virtuális környezetet írt full assemblyben, amikor ez a portál még csak nem is létezett?

amikor neked a tojáshéj a seggeden volt, akkor én nulláról 32-bites full featured oprendszert írtam, ami tudott threadeket :P...  swappinget, filerendszert, networkingot, és distributed módban tudott több gépen futva problémákat megoldani (t.i. ez volt az államvizsgám). Tudod: tudott lekezelte a trapeket, exceptionöket, hardware interruptokat... És elmentette azt a kibaszott contextet, mert azt el kell menteni... Akkor is, ha Mr. Mitrugrálsz szerint nem kell...

Abban az időben, amikor még nem így volt internet és nem volt qemu... hanem rendes vason ment a fejlesztés...

 

itt TE akarod elmagyarázni, hogy mi az IRET meg a trap? te tényleg azt hiszed, hogy te találtad fel a spanyolviaszt, más ezen a portálon nem olvasott dokumentációt?

a szaros hobbi projektjeidre vagy olyan kibaszottul büszke, hogy a pofád nagyobb, mint az ajtó? Valami real-world projektről beszélj. Amikor elfogadnak egy patched tőled a linux kernelbe...  vagy kifejlesztettél egy hardvert és írtál hozzá drivert.

 

tényleg te akarsz itt "fejtágítót" tartani? ez a kabát neked egy kicsit nagy, angyalom...

ülj le ügyesen a seggedre és örülj, hogy van rajta egy lyuk, amin tudsz szarni és fingani... én a helyedben elsősorban ilyeneket tanulnék meg mint  önreflexió és reality-check... mert az neked nincs... a nagy pofádon kívül...

 

te csótány, ami vagy.... 

Igen, téged nevezlek HAZUGNAK, minden joggal. És nem vagyok az angyalod, súlyos téveszmékben szenvedsz, ha meg nem sértelek, talán neked van szükséged arra a bizonyos reality-checkre, mert láthatóan lecsatlakoztál a valóságról.

És külön felhívnám a figyelmet arra, hogy ez a posztod is
- tagadhatatlanul PICSOGÁS csak, egyetlen választ sem voltál képes adni egyik kérdésre sem,
- de még csak nem is a témában szóltál hozzá, csak pocskondiázni próbáltál tök eredménytelenül, mert még ehhez is kevés vagy.

Szóval igen, minden alapom megvan rá, hogy egy dilettáns faszkalap TROLLNAK tituláljalak, erről Te magad gondoskodsz a viselkedéseddel (most is, ez a legutóbbi posztod is ékes példája, mekkora seggfej vagy valójában).

Ja, és a spanjaid sem különbek, akik rabszolgamód, Rogán propagandistákat megszégyenítve nyomogatják a posztodra a szavazataikat; azt hiszem teljesen felesleges magyarázni, hogy egy értelmes, intelligens ember sosem like-olna egy ilyen alpári stílusú trágár posztot, mint a tied, erre csakis egy másik TROLL lehet képes, homo sapiens nem. :-D :-D :-D

Nem jön be, nálam a telemetriát tartalmazó JS le van tiltva, annélkül meg összefossa magát az oldal... :-D
De másoktól hallottam, hogy a youtube-on semmi más nem megy az utóbbi időben, csak Orbán fizetett hazugságai meg orosz propaganda.

Szerkesztve: 2024. 08. 03., szo – 12:16

Ahogy az előre tudható volt, a nagypofájú trollok közül egyetlen egy sem volt képes válaszolni.
És most a várható időjárás: kellemes napos, de szórványosan habzó szájú trollpanaszeső fordulhat elő.

Minden más fórumtársnak ellenben nagyon szívesen, remélem hasznotokra válik ez az alacsony szintű leírás.

A helyes válaszok:

- exception

Ezt a CPU generálja, valamilyen rendszerregiszterbeállítás vagy utasítás hatására (értsd: NEM egy dedikált utasítás hatására), például DIV előidézhet division by zero-t, vagy az STR utasítás translation fault-ot.
Ezek akkor is kiváltódnak, ha a megszakítások egyébként le vannak tiltva a CPU-ban (x86-on CPU interrupt flag, ARM-on a DAIF regiszter).

- soft int

Ezt is a CPU generálja, azonban egy dedikált utasítás hatására (x86-on INT, ARM-on BRK utasítás, vagy ha privilégiumszintváltást is akarunk, SVC, HVC stb.). Mivel ez a forráskódban is megjelenik, ezért hívják ezt szoftveres, azaz "soft int"-nek.

- hard int

Ezt NEM a CPU generálja, hanem valamilyen, CPU-tól független áramkör, amit jellemzően interrupt controllernek hívnak (IC). Régen PC-ken ez a PIC volt, manapság az APIC, x2APIC vagy épp az IOAPIC. ARM-on ugyanez a helyzet, ott is független, például régi Pi-ken BroadcomIC volt, Pi4-n QA, Pi5-ön meg már GIC. Szóval NEM a CPU, hanem attól független a forrása. Mivel nem szoftver, hanem hardver generálja, ezért "hard int" a neve.

Ezeknek annyira nincs közük a CPU-hoz, hogy például x86-on a RESET-et követően a hard int-ek átfedésben leledzenek a CPU exception-jeivel, és a rendszerprogramozó dolga, hogy átprogramozza az IC-t és az ütközést megszüntesse.
A fogadásukat a CPU egységesen (értsd: nem egyenként) tilthatja vagy engedélyezheti (x86-on CPU interrupt flag, ARM-on a DAIF regiszter).

- IRQ

Valamilyen külső periféria generálja az IC felé, ami hard int-et idéz elő ennek hatására a CPU-ban. Ezt nyilván a csak magas szintet ismerő trollok úgysem lesznek képesek felfogni, nekik csak "IRQ" minden, de valójában áramkörileg ez a periféria-IC és az IC-CPU jel tök "más dróton megy", és külön is kell ezeket konfigurálni.

Hiába vannak a megszakítások engedélyezve a CPU-ban, mégsem jön létre csak úgy egy hard int se, mivel az IRQ-kat még külön-külön is engedélyezni kell az IC-ben. Valamint vice versa, hiába vannak az IRQ-k engedélyezve, ha a hard int egységesen le van tiltva a CPU-ban.

Az IC-ben konfigurálható, hogy adott IRQ-hoz milyen hard int jöjjön létre (x86-on IRQ-nként állítható ez, ARM-on meg az, normál vagy a fast hard int ISR-je hívódjon-e meg).

- interrupt vs. trap

A kétféle megszakítás között az a különbség, hogy az utasításszámláló a következő utasításra (interrupt) vagy a megszakítást kiváltó utasításra (trap) mutat-e. Ez azért lényeges, mert előbbi nem újrajátszható, míg az utóbbi igen.

Például x86-on an INT 3 utasítás kiváltja a megszakítást, ami interrupt típusú, tehát az INT 3 utasítás UTÁNNI cím mentődik le, és az utasítás maga nem újrajátszható. Ezzel szemben mondjuk egy érvénytelen címre hivatkozó MOV utasítás trap-et vált ki, mondjuk page fault-ot, aminél az azt kiváltó utasítás utasításszámlálója mentődik, így tehát az az ISR lefutása után a MOV újra végrehajtásra kerül.

- RET vs. IRET/ERET

A sima RET utasítás, amit alapesetben a C fordító generál csak visszatér a hívóhoz, de nem idézhet elő privilégiumszintváltást (x86-on kiveszi a veremből a CALL által lerakott címet (csakis egyetlen címet, semmi mást!) és odaugrik, ARM-on a visszatérési címet egy GPR tárolja (hangsúlyozom, egy GPR), amit a BL utasítás helyez oda).

Ezzel szemben az IRET/ERET úgy tér vissza a hívóhoz, hogy közben privilégiumszintváltás történhet (ehhez x86-on több mindent kell kivenni a veremből, ún. interrupt stack frame-t, míg ARM-on a a visszatérési címet NEM egy GPR-ből, hanem egy rendszerregiszterből, az egyik ELR valamelyikéből veszi és más rendszerregiszterek is közrejátszanak, tehát hangsúlyozom, NEM egy GPR-ből).

Magyarán a kettő működési mechanizmusa nagyon nem azonos, ezért nem lehetséges szabvány C függvénnyel megszakításkezelőt írni (abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI). Amikor egyesek az NVIC_SetVector()-t hívták, az valójában NEM az alacsony szintű megszakításvezérlőt állította, hanem a megszakításvezérlő által hívott lekezelő függvény címét (ami már lehet szabvány C függvény, hiszen az ERET-et nem az adja ki, hanem az alacsony szintű ISR).

ARM8 esetén nincs is megszakításivektortábla, de még csak semmilyen tábla se, hanem fix méretű megszakítástípusfüggvények vannak. Azaz megszakítástípusokra van egy-egy fix méretű ISR a VBAR rendszerregiszter által mutatott kódterületen. Ha például exception történik, akkor mindegy, hogy milyen exception, ugyanaz az ISR kód fut le, ami aztán konzultál az Exception Syndrome Register nevű rendszerregiszterrel, és az alapján dönti el, mi is történt és melyik lekezelő függvényt is kell meghívnia.
Ha IRQ történik, ugyanez, akkor is egységesen ugyanaz az ISR fut le, csak ilyenkor ennek az ISR-nek IC típus-specifikus (értsd: CPU-tól független) módon kell kiderítenie, hogy melyik IRQ is történt valójában, és az annak megfelelő lekezelő függvényt hívnia. Hangsúlyozom, hogy ARM8-on ez szoftveresen történik egy alacsony szintű ISR által, aminek MUSZÁJ az ERET utasítással visszatérnie.

Ezzel szemben x86-on van megszakításvektortábla, viszont az itt beállított minden egyes funkciónak MUSZÁJ az IRET utasítással visszatérnie, tehát ezek sem lehetnek szabványos C függvények (továbbá attól függően, hogy exception trap/abort vagy interrupt történt-e, eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges).

Mégegyszer hangsúlyozom, bár már előre megírtam, hogy a trollok picsogására nem fogok válaszolni.

Amikor egyesek az NVIC_SetVector()-t hívták, az valójában NEM az alacsony szintű megszakításvezérlőt állította, hanem a megszakításvezérlő által hívott lekezelő függvény címét (ami már lehet szabvány C függvény, hiszen az ERET-et nem az adja ki, hanem az alacsony szintű ISR).

Azt hittem, ezen túl vagyunk :D

De, az NVIC_SetVector() az egy olyan címet állít be, amit a hardver for hívni, NVIC-es ARM (Cortex M)-nél _nincs_ ilyen "alacsony szintű" megszakításvezérlő a lehető legalacsonyabb latency érdekében, GIC-esnél van. NVIC-nél máshogy néz ki a vektor tábla is, ott VTOR-nak hívják, az első 15 eleme előre definiált megszakítástípusok handlereire mutat (első a reset, utolsó a systick handler), ezek után jönnek az NVIC-re kötött perifériáktól jövő irq handlerek címei.

NVIC_SetVector() az így néz ki:

 uint32_t vectors = (uint32_t )SCB->VTOR;
 (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector;

 

ahol NVIC_USER_IRQ_OFFSET 16, tehát a VTOR hw reg által meghatározott táblában a periféria megszakítások vektorai a fix funkciójú megszakítások vektorai után jönnek.

Ha ezek szoftveresen lennének lekezelve, akkor mi a tosznak kell, hogy egy HW regiszter mutasson rájuk?

Te írtad:
"De az alap ARM-nál nincs ilyen, az kap egy IRQ-t, és van 1 db ISR"
"a hagyományos ARM az olyan, mint a 6502 volt [...] Ennél valóban neked kell az ISR-ben ellenőrizni, hogy honnan jött a megszakítás."

Én írtam:
"Pontosan. Ezt hívtam alacsony szintű ISR-nek, és erre mondtam, hogy ezt nem lehet C függvényként megírni"

Te írtad:
"Nekem úgy tűnik, ha az ARM core elkezdené az ISR-t, az AIC "alányúl", és lecseréli a PC-t arra, ami a saját vektortáblájában van."
"innentől igenis a HW kezeli."

Erre írtam:
"Persze, hogy a HW kezeli (mégis, mi más kezelhetné?), na de nem a CPU."
(itt CPU alatt az ARM core-t kell érteni, ha esetleg nem lenne tiszta, a HW pedig az, ami CPU-nak "alányúl")

Te írtad, hogy nem tudod, hogy "az extra vektorok kezelése vajon hol történik, az ARM core-ban is kell, hogy legyen némi változtatás, hogy az egy szem IRQ handler helyett lehessen max. 256 (NVIC-nél)."
Na, az alacsony szintű megszakítás kezelő pont az, ami ezt végzi, ez normál ARM-nél egyetlen ISR, és ami NVIC esetében (állításod szerint nem ROM kód vagy built-in lib vagy mittoménmi, hanem) állítólag hardveres hákolás (nem tudom, pontosan mire gondoltál az "alányúl" alatt, de hardveres hákolásnak hangzik).

Egyik esetben sem lehet ezt az alacsony szintű kezelőt C-ben megírni, első esetben speciális utasítás kell, második esetben meg nem is ARM kódról van szó (az általuk kiválasztott, IRQ-nak megfelelő lekezelő ARM-os függvény már mindkét esetben lehet C-ben természetesen).

mi a tosznak kell, hogy egy HW regiszter mutasson rájuk?

Pontosan. Nem ARM CPU-os rendszerregiszter mutat rá, hanem egy, CPU-tól tök független periféria regisztere, ami periféria nem része a "normál" ARM-nek, nem szerepel a DDI0487 specifikációban sem, csak bizonyos mikrokontrollerek esetében található meg, (a Te szavaiddal) alap ARM-nál nincs ilyen. Én így fogalmaztam: "Ezt NEM a CPU generálja, hanem valamilyen, CPU-tól független áramkör, amit jellemzően interrupt controllernek hívnak (IC)."

A teljesség kedvéért, ez x86-on is ugyanúgy történik, ott is egy, a CPU-tól független áramkör kezeli az IRQ-kat. Az eredeti IBM PC-ken ez a 8259-es PIC volt és fizikailag is külön chip volt, manapság pedig az ugyanabba a SoC-ba integrált local APIC. Akárcsak az ARM esetében, ezeket sem CPU regiszterekkel programozod, hanem a CPU-tól független perifária regisztereken keresztül (hogy egész pontos legyek, ezek a perifária regiszterek eredetileg IO porton keresztül voltak elérhetők, aztán MMIO-n keresztül, legújabban meg model specifikus regisztereken keresztül).

Na, az alacsony szintű megszakítás kezelő pont az, ami ezt végzi, ez normál ARM-nél egyetlen ISR, és ami NVIC esetében (állításod szerint nem ROM kód vagy built-in lib vagy mittoménmi, hanem) állítólag hardveres hákolás (nem tudom, pontosan mire gondoltál az "alányúl" alatt, de hardveres hákolásnak hangzik).

Igen, valami hardveres hákolás, nincs semmi kód, amit a CPU futtat (max. mikrokód, haha).

Már eleve a "normál" handler tábla is tök más (alap ARM-on nincs systick pl., meg nem is 15 elemből áll, ráadásul nem is ISR-k címei vannak benne).

A PIC-et ismerem, ezek a CPU-k ugye tudták fogadni az IRQ vektort az adatbuszon (amit a megszakítást kérő periféria tesz oda, vagy pl. a PIC), így ezeken sem kell külön "master" handler.

ezeken sem kell külön "master" handler.

Így van, x86-on minden IRQ-hoz eleve külön handler rendelhető (ráadásul programozható, hogy melyik legyen az, szóval nemcsak a függvény címét állíthatod, hanem azt is, hogy tábla melyik rekeszéből vegye a függvénycímet).

Viszont mégsem úszod meg az Assembly-t, mert RET helyett IRET utasítással kell visszatérni a handlerből, ráadásul az exception típusú handlerek hívásakor olyan a verem, mint az ökörhugyozás (egyszer van hibakód, máskor nincs), szóval ezt is rendbe kell tenni. A veremmutató direkt manupilálása pl olyan dolog, amit nem lehet C-ből (sem semmilyen más, magas szintű nyelvből) megcsinálni.

(És ezzel még nincs is vége, 64 bites módban ott van még az IST is, ami képes vermeket kapcsolni megszakítás meg IRET híváskor, hasonlóan az ARM-es SP_ELx regiszterekhez. Ott meg különösen észnél kell lenni, hogy melyik verem is az aktív éppen, cserébe a megszakítás nem piszkálja a felhasználói módú vermet, így stack overflow támadás sem lehetséges a handlerben.)

alap ARM-on nincs systick

Á ne is mondd, heteket szívtam miatta. RPi-n például legalább 5 féle időzítőd van, és persze a saját doksija mindent nemes egyszerűséggel "ARM TImer"-nek hívja csak, aztán igazodj ki, melyik melyik... Végül is arra jutottam, hogy egyetlen van csak alap ARM-on, de az meg nem tud IRQ-t generálni, csak pollozni lehet (logikus, hisz az alap ARM-ben nincs IC).

A BCM féle ARM Timer tudtommal még mindig nincs implementálva qemu-n (legalábbis mikor legutóbb néztem, még nem volt), a QA-as ARM Timer is csak azért működik, mert én megírtam (a BCM-es patchemet nem olvasztották be, azt mondták, implementáljam le az összes többi BCM2837-es eszközt is, majd akkor meggondolják. Erre azt mondtam, fenéket, nem tollas a hátam. A QA-s patchem egy másik reviewer-hez került, ott nem volt semmi gond).

Viszont mégsem úszod meg az Assembly-t, mert RET helyett IRET utasítással kell visszatérni a handlerből,

Ez Z80-on is így volt már, bár igazából a RETI csak azért kellett, hogy a külső interrupt vezérlő tudja, hogy vége a megszakításnak (prioritásoknál fontos ez). Viszont az NVIC handlerei az tényleg sima C ABI, pedig annak is kéne tudni, hogy mikor ér véget a handler (prioritások miatt szintén, NVIC-ben az N az Nestedet jelent). Nem tudom, ezt pontosan hogy csinálja, csak ennyit találtam róla:

A microcode present in the Cortex®-M4 automatically
pushes the context to the current stack and restores it
upon interrupt return.

Lehet, hogy valahogy megjelöli a stacken, hogy ez egy handlerhez tartózó return address, és így el tudja végezni a context visszaállítást/prioritások kezelését?

Lehet, hogy valahogy megjelöli a stacken, hogy ez egy handlerhez tartózó return address, és így el tudja végezni a context visszaállítást/prioritások kezelését?

Valahogy igy, igen, A sima C ABI eseten a return address a link registererbe (lr, r14) kerul. A "ret" utasitas meg igazabol egy indirekt ugras a link regiszterre (bx lr). 

Megszakitas eseten meg a kovetkezo van:

  • A CPU lementi a C ABI inverzet, azaz a caller-saved regisztereket (r0, r1, r2, r3, r12, lr) illetve a CPU aktualis program counteret es statuszat (pc, xpsr) a stack-re. 
  • Beallit egy specialis lr erteket (amit megtehet mert a megszakitas pillanataban levo link register a stack-re kerult), ami egy "soha nem hasznalt" teruletre mutat - ez konkretan 0xfffffffz, szoval konnyen megjegyezheto. Az uccso nibble par metaadatot letarol ami a megszakitasbol valo visszatereshez kell (pl hogy sima user/thread modbol jott-e a megszakiras vagy az NVIC "nested" uzemmodja miatt egy alacsonyabb prioritasu megszakitasbol, stb), de a lenyeg hogy az lr erteke egy ilyen unmapped region-ba mutat
  • A CPU raugrik a megfelelo vektortabla megfelelo elemen talalhato cimre: pc <= mem[VTOR+offset], ahol az offset az a trap/softint/hardint/irq alapjan szamolodik (ahol a "szamolodik"-ban benne van az NVIC osszes finomsaga, prioritasok, late arrival, stb... ezt az adottt NVIC egyertelmuen definialja)
  • A C ABI koteles menteni maganak az r4 ... r11 es lr regisztereket es csak az r0 ... r3, r12-t "baromlhatja el". Szoval amikor a handler visszater `bx lr` utasitassal akkor egyreszt minden nonvolatile regiszter helyreallt, masreszt meg a CPU az link register ertekebol tudja hogy "nem csak ugy siman egy `pc <= lr` beiras kell, hanem interruptbol terunk vissza
  • A CPU ekkor szepen kiszedi a stackrol az r0, r1, r2, r3, r12, lr, xpsr ertekeit a memoriabol, plusz ugye a pc is visszaall oda ahol megszakadt a folyamat, azaz: pc <= mem[msp + frame_pc_offset].
  • es minden megy tova.

Szoval igy csinalja a Cortex-Mx rendszer (M0, M3, M4, M7, M33 biztosan). 

Meg annyi finomitas van hogy mar Cortex-M0-tol kezdve is "ket stack" van, azaz az van egy main stack pointer (msp) meg egy program stack pointer (psp). Itt az a gondolat hogy a megszakitasba valo belepeskor mindig az msp-t hasznalja r13 == sp regiszterkent, normal uzemben (thread mode) pedig kitalalhatjuk hogy ezt vagy azt hasznaljuk. Hogy melyik is az aktiv az egyreszt szoftverbol allithato masreszt a megszakitasba valo belepeskor ez is lementodik (legjobb emlekeim szerint a link register also nibble-jebe, lasd: z, fentebb). Ennek akkor van jelentosege ha a handlert egy olyan trap valtja ki ami pont a stack tulcsordulasa miatt kovetkezett be - ekkor a handlerbe valo belepeskor mindig erre biztonsagos(abbnak gondolt), msp-vel jelol stackre menti le a CPU ezt a 32 byteot. A psp pedig normal (thread) modban mutathat valami kevesbe kordaban tartott memoriateruletre es a handler le tudja kezelni a mezei thread altal kivaltott/bekovetkezett stack tulcsordulast... vagy egyszeruen azt hogy a thread stack-je egyszeruen tul kicsi a teljes 32 byetos menteshez. 

azért kellett, hogy a külső interrupt vezérlő tudja, hogy vége a megszakításnak

Az független az ERET/IRET utasítástól. Ez utóbbi csak a CPU-n belül teszi helyre a privilégiumszinteket és a vermeket (handler mindig kernel space, de lehet, hogy user space-re kell visszatérni belőle, ráadásul ez utóbbiból szálanként van egy-egy), a külső interrupt vezérlőt ettől függetlenül kell nyugtázni. Ez utóbbira jellemzően van egy külön periféra regiszter az IC-ben (tehát nem ARM core regiszter, hanem HW perifária regiszter), pl. GIC_EOIR, vagy LAPIC_EOI.

Gondolom mivel "alányúl" az NVIC az egész mechanizmusnak, ott ez is automatikusan történik a hatékonyság érdekében, de attól még megtörténik mind az ARM rendszerregiszterállítás, mind az EOI nyugtázás az IC-ben.

pedig annak is kéne tudni, hogy mikor ér véget a handler

Nemcsak kéne, kell is tudnia. Ez része kell, hogy legyen az "alányúlásnak", biztos vagyok benne, hogy az megfelelően állítja az ARM rendszerregisztereit is.

Lehet, hogy valahogy megjelöli a stacken, hogy ez egy handlerhez tartózó return address, és így el tudja végezni a context visszaállítást/prioritások kezelését?

ARM-on a visszatérési érték nem a verembe kerül, hanem (normál függvényhívás esetén) egy GPR regiszterbe, handler hívás esetén pedig egy rendszerregiszterbe. Előbbiből csak egy van, utóbbiből privilégiumszintenként egy-egy (azért, hogy az ERET kiadásakor privilégiumszintet lehessen váltani, ARM-es szóhasználattal exception level-t). Egész biztos vagyok, hogy a NVIC-es alacsony szintű ISR ugyanezt szimulálja (vagy direktben beállítja az ARM regisztereit, vagy olyan lépéseket tartalmaz, amiknek technikailag ugyanez a hatásuk)

A microcode present in the Cortex®-M4

Ezek szerint az alacsony szintű ISR, amiről egész eddig beszéltem, NVIC esetében mikrokódban van implementálva. Hogy ez akkor most végül is hardveres vagy szoftveres-e, abban inkább nem foglalnék állást, mivel mindkét esetre tudok érveket és ellenérveket is. Maradjunk annyiban, hogy hardverbe vasalt szoftver :-) A lényeg, hogy itt található az alacsony szintű ISR.

Nem ismerem az NVIC pontos mikrokódját, de lefogadom, hogy valami ilyesmi lehet a benne írt alacsony szintű ISR:
1. aktuális ARM verem és PC mentése
2. átkapcsolás az ISR vermére
3. az NVIC regiszterei alapján meghatározza a lekezelőfüggvény címét
4. regiszterek és verem beállítása C függvény híváshoz
5. lekezelő függvény hívása az ARM processzoron
6. NVIC EOI nyugtázás
7. visszakapcsolás az ARM eredetileg megszakított vermére és PC visszaállítás (ERET-nek megfelelő lépések, csak NVIC módra)

Amit apai írt, az biztos nem úgy van, már csak azért sem, mert abban igaza van, hogy két független veremről van szó, a handler nem használja a megszakított program vermét.

handler nem használja a megszakított program vermét.

Inkabb ugy mondanam, hogy nem illik hasznalia, de hasznalhatja. Egyreszt valtogathatja hogy mi is kegyen az aktiv sp (msp v psp) masreszt meg kulon-kulon is hozzafer (mrs, msr utasitasokon keresztul). Valojaban ez mar OS design kerdese: ha kulon TCB-ket definialgat maganak a kernel sajat memoriajan akkor igenis ne nyuljon hozza. Ha pedit a normal preemption/cooperation-t ugy implementalja hogy a context az minden thread sajat veremen legyen lementve akkor meg hozzafer. Mindegyik megkozelitesnek van elonye meg hatranya, de abszolute igaz hogy a "nem turkalunk" az elegansabb. 

Inkabb ugy mondanam, hogy nem illik hasznalia, de hasznalhatja.

ARMv8 (tehát alap ARM, NVIC hákolás nélkül) nem. Ott ha a megszakításkezelő magasabb privilégiumszintű, mint a megszakított, akkor a veremváltás MINDIG bekövetkezik, nem opcionális. (Azonos privilégiumszint esetén nem vagyok biztos, mert olyannal még sosem volt dolgom a gyakorlatban, de azt hiszem olyankor is beállítódik a verem az SP_ELx-ben tárolt értékre)

Jaja, igen, ezt nem tudtam. M33-mal en is meg csak 1x dolgoztam alaposabban, es ott pont ez az aspektus nem szamitott igazan mert elegge bare metal volt a projekt :) A legtobbet/leginkabb meg M0-n szoktam ugykodni, ott meg ugye a "privilegiumszint" is inakbb csak valamifele "feny az alagut vegen hogy 1x majd ilyesmi is lehet ebbol". Es pont ez az msp/psp valtas az eloszele ennek. Konkret privlegiumot meg memoriavedelmet nem ad, de legalabb valami kezdet hogy a program onmagatol meg tudja vedeni mar egy kicsit magat.

OFF
Szeretném megköszönni, hogy az utóbbi posztjaid kulturáltak, és kifejezném abbéli örömömet, hogy sikerült szakmai szintű értelmes társalgást kialakítanunk.
Ha esetleg gúnyosnak éreznéd az előbbi mondatom, kérlek ne tedd, tényleg őszintén mondtam, hogy örülök neki és a jövőben is szeretném így folytatni!
/OFF

Ezzel szemben x86-on van megszakításvektortábla, viszont az itt beállított minden egyes funkciónak MUSZÁJ az IRET utasítással visszatérnie, tehát ezek sem lehetnek szabványos C függvények (továbbá attól függően, hogy exception trap/abort vagy interrupt történt-e, eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges).

 

bzt, megint hülyeségeket beszélsz... 🤣

void handler(void *p)  __attribute__((interrupt));

 

semmi assembly és szépen belegenerálja az iretq-t

micsa, te már megint hülyét csináltál magadból mivel olvasni sem tudsz, de ami a legnagyobb baj, hogy csak hőbörögsz tanulás helyett, ezért hülye is maradsz életed végéig.

Egyrészről: "abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI"
De főként: "eltérő a stack frame, szóval még gatyába is kell rázni a vermet" és "A veremmutató direkt manupilálása pl olyan dolog, amit nem lehet C-ből (sem semmilyen más, magas szintű nyelvből) megcsinálni."

Ja "olvasni kellett volna a könyveket, nem égetni" (bár gondolom fogalmad sincs, honnan származik ez az idézet, mert jól láthatóan analfabéta vagy, így alapfokú műveletséged sincs.)

Majd ha Ti kimostátok, és ideidézel egy csúnya szót, amit írtam és nem csak micsától idéztem! ROTFL.
Te is jobban tennéd, ha ELOVASNÁD, amit írtam, és akkor számodra is nyilvánvaló lenne, miért ostobaság, amit micsa írt (megszakítás nemcsak interrupt lehet, hanem exception is).

ps: az meg már tényleg csak hab a tortán, hogy még az az egysoros C kód, amit idemásolt, mindjárt KÉT HIBÁT is tartalmaz, LOL.

Majd ha Ti kimostátok, és ideidézel egy csúnya szót, amit írtam és nem csak micsától idéztem! ROTFL.

Mind a személyeskedést, mind az első "hülye" jelző személyre aggatva tőled származik. Ezt követően csak lentebb csúsztál, mikor hazugsággal vádoltál valakit (ráadásként abban a szálban továbbra is kérdések várnak rád).

ps: az meg már tényleg csak hab a tortán, hogy még az az egysoros C kód, amit idemásolt, mindjárt KÉT HIBÁT is tartalmaz, LOL.

Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val, így kérlek jelöld meg, melyik az a két hiba amire utalsz. Az említett egy sor fordítása után, a kapott binárison végrehajtott disassembly eredménye (szánalmas, hogy kénytelen vagyok ennyire specifikus lenni az irányodba):

0000000000001143 <handler>:
    1143:       f3 0f 1e fa             endbr64
    1147:       55                      push   %rbp
    1148:       48 89 e5                mov    %rsp,%rbp
    114b:       50                      push   %rax
    114c:       48 83 ec 08             sub    $0x8,%rsp
    1150:       48 8d 45 08             lea    0x8(%rbp),%rax
    1154:       48 89 45 f0             mov    %rax,-0x10(%rbp)
    1158:       90                      nop
    1159:       48 8b 45 f8             mov    -0x8(%rbp),%rax
    115d:       c9                      leave
    115e:       48 cf                   iretq

// Happy debugging, suckers
#define true (rand() > 10)

Miért nem akkor volt ilyen nagy a pofád, amikor választ kellett volna adni? Akkor bezzeg kussoltál, pedig egy egész hetet adtam, hogy biztos legyen időd átolvasni a doksikat. Így utólag feleslegesen puffogsz.

Mind a személyeskedést, mind az első "hülye" jelző személyre aggatva tőled származik.

Szánalmas vagy. Az eredeti posztomban nem is szerepel ez a szó, ellenben micsa rá adott válaszában viszont szerepel. Bárki megnézheti, és látni fogja, hogy HAZUDSZ.

Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val

Megint HAZUDSZ. Micsa kódjában nincs is implementáció, az egész biztos nem hozhatta azt az eredményt, amit idemásoltál (sem semmilyen más eredményt, ugyanis az csak egy prototípus, tanulatlan nagyszájú troll, az nem fordul semmilyen kódra).

De jó, javítsuk ki micsa kódját implementációra, cseréljük le a ";"-t "{}"-re. Eredmény:

$ gcc aaa.c -o aaa 
aaa.c:1:1: error: attributes should be specified before the declarator in a function definition
    1 | void handler(void *p) __attribute__((interrupt)) {}

Szóval újfent, ebben is HAZUDTÁL.

A másik hibát (ami szemantikai), rád bízom, hogy megtaláld, pláne úgy, hogy már le is írtam korábban pontosan (kétszer is), miért hibás az az Assembly kód, amit bemásoltál. Tessék megtanulni olvasni és magyar nyelvű szöveget értelmezni, és ki fog derülni, akkor is, ha magadtól képtelen vagy rájönni. Még annyit is segítek, hogy a paraméterhez és az exception hibakódokhoz van köze. Ha ezek után sem tudod, hát, magadra vess!

A továbbiakban sem engem (és valószínűleg semelyik másik értelmes fórumozót sem) érdekel, hogy miket hazudozol itt, csúnyán leszerepeltél a spanjaiddal együtt.
Olvasni kellett volna a könyveket, nem égetni!

Szóval amikor nyitottad ezt a posztot, ekkor: 2024. 07. 22., h – 12:29, te belinkelsz egy olyan hsz-t bizonyíték okán, ami ekkor született: 2024. 08. 03., szo – 23:37

A két időpont között pedig itt használtad a hülye szót másokra, annak ellenére, hogy ez volt az állításod: "Majd ha Ti kimostátok, és ideidézel egy csúnya szót, amit írtam és nem csak micsától idéztem! ROTFL.". A többi hsz nem tűnik el, nem lesznek irrelevánsak, csak mert éppen másik szálban vannak. Így hát parancsolj:

 2024. 07. 23., k – 20:57 (hülye) | https://hup.hu/comment/3088782#comment-3088782
 2024. 07. 25., cs – 12:09 (hülye) | https://hup.hu/comment/3089632#comment-3089632
 2024. 07. 25., cs – 20:53 (szar alak vagy, hazudsz, hamisítasz) | https://hup.hu/comment/3089891#comment-3089891
 2024. 07. 26., p – 11:00 (hülyék) | https://hup.hu/comment/3090049#comment-3090049
 2024. 07. 26., p – 11:12 (hülye) | https://hup.hu/comment/3090057#comment-3090057
 2024. 07. 26., p – 15:56 (segghülye) | https://hup.hu/comment/3090200#comment-3090200
 

De jó, javítsuk ki micsa kódját implementációra, cseréljük le a ";"-t "{}"-re. Eredmény:

Miért kellene lecserélni? Kizárólag egy üres implementációt kell neki adni. Nem rakétatudomány az idézett egy sorhoz még egy darab sort hozzáadni, hogy fordítható kódot kapj. Gondoltam ez még neked is sikerül, tévedtem! Elnézést, hogy ezt mertem feltételezni rólad.

// Happy debugging, suckers
#define true (rand() > 10)

te belinkelsz egy olyan hsz-t bizonyíték okán

...pontosan azt linkeltem, amire micsa válaszolt. Egyébként meg, ha azt hiszed, hogy például ez egy kulturált hozzászólás, akkor a Te fejedben is irtó nagy baj van.

A többi hsz nem tűnik el, nem lesznek irrelevánsak, csak mert éppen másik szálban vannak.

Az ott elhangzottakat továbbra is fenntartom, egy tanulatlan, hazug csürhe vagytok, akik nem csak buták, de ami nagyobb baj, hogy nem is akartok tanulni.

Miért kellene lecserélni? Kizárólag egy üres implementációt kell neki adni.

FACEPALM. És az a csere mégis mit csinál szerinted, ha nem pont ezt, te nagyokos? (Ne válaszolj, költői kérdés.)

Nem rakétatudomány az idézett egy sorhoz még egy darab sort hozzáadni, hogy fordítható kódot kapj.

DE ÚGYSE FORDUL LE! Lásd a bemásolt hibaüzenetet, ami bizonyítja, hogy HAZUDTÁL. De még ha kijavítod a szintaktikai hibát és megadsz egy rakat kapcsolót a gcc-nek, és úgy valahogy lefordítod, MÉG AKKOR IS HIBÁS az eredmény.

Tényleg nem tudom, minek válaszolok egy olyannak, aki HAZUDOZIK össze-vissza, KÉPTELEN OLVASNI, és jól láthatóan meghaladja a magyar nyelvű szövegértés az értelmi képességeit.
Ágyő!

...pontosan azt linkeltem, amire micsa válaszolt. Egyébként meg, ha azt hiszed, hogy például ez egy kulturált hozzászólás, akkor a Te fejedben is irtó nagy baj van.

Ilyet aztán végképp nem állítottam

Az ott elhangzottakat továbbra is fenntartom, egy tanulatlan, hazug csürhe vagytok, akik nem csak buták, de ami nagyobb baj, hogy nem is akartok tanulni.

de szemben veled, ez a tanulatlan hazug csürhe mégsem annyira buta mint te, hogy érvelés helyett kizárólag rágalmaz és személyeskedik :)

FACEPALM. És az a csere mégis mit csinál szerinted, ha nem pont ezt, te nagyokos? (Ne válaszolj, költői kérdés.)

DE ÚGYSE FORDUL LE! Lásd a bemásolt hibaüzenetet, ami bizonyítja, hogy HAZUDTÁL. De még ha kijavítod a szintaktikai hibát és megadsz egy rakat kapcsolót a gcc-nek, és úgy valahogy lefordítod, MÉG AKKOR IS HIBÁS az eredmény.

Tényleg nem tudom, minek válaszolok egy olyannak, aki HAZUDOZIK össze-vissza, KÉPTELEN OLVASNI, és jól láthatóan meghaladja a magyar nyelvű szövegértés az értelmi képességeit.
Ágyő!

Várjá várjá, haladjunk lépésről lépésre a kedvedért. Fogjuk elsőnek a micsa által adott megfejtést, módosítás nélkül:

$ echo 'void handler(void *p)  __attribute__((interrupt));' > bzt.c

aztán fogunk még !egy! sort, az előző forward declaration / function prototype mellé. Semmi dirt magic, csak szép lazán:

$ echo 'void handler(void *p) {}' >> bzt.c

Majd leszünk olyan gonoszak, hogy lefordítjuk ezt a kódot a következő módon:

$ gcc -mgeneral-regs-only -c -Wall bzt.c

Se hiba, se warning, se error, semmi :) pontosabban majdnem semmi, lett egy szép "bzt.o". Elviekben idáig már nem kellett volna eljutnunk, de ha már valahogy létrejött, akkor megnézzük, ott leledzik az a fránya iretq vagy sem :

$ objdump -d bzt.o | grep -c iretq
1

Mielőtt valamilyen csavaros módon kiderülne, hogy hazudok, meg mindenki hazudik és az ettől független "-mgeneral-regs-only" rakja oda az iretq -t ami nem is létezik, mert ez a kód le sem fordulhat, megnézzük mi történik ha nincs ott micsa csicsa sora, megcsináljuk újra az egészet nélküle:

$ echo 'void handler(void *p) {}' > bzt2.c
$ gcc -mgeneral-regs-only -c -Wall bzt2.c
$ objdump -d bzt2.o | grep -c iretq
0

Lááám, az iretq eltűnt, de azért lessük meg, mi lett helyette:

$ objdump -d bzt2.o | tail -1
   e:   c3                      ret

Szóval, mit látunk? Micsa csicsa sora iretq-t generál, amit a te állításod szerint csak és kizárólag assembly nyelven lehetséges megoldani, c -ben nem. Erre tessék az eredeti cáfolathoz

// Happy debugging, suckers
#define true (rand() > 10)

Micsa csicsa sora iretq-t generál

Továbbra sem micsa sora generálta azt a kódot, de látom, képtelen vagy felfogni mi az a prototípus és inkább HAZUDSZ.

Se hiba, se warning, se error, semmi :)

Szívesen várom a magyarázotod, miért raktad oda a "-mgeneral-regs-only" kapcsolót és miért próbáltál meg HAZUDNI - még erről is.
Csak nem egy "sorry, not implemented" gcc hibaüzenet miatt, amit megpróbáltál eltussolni?

Szóval, mit látunk?

Hát azt, hogy nem értesz hozzá, HAZUDOZOL és KÉPTELEN VAGY magyar nyelvű szöveget OLVASNI és megérteni...

Segítek, idemásolom mégegyszer, ezt kellett volna tudnod értelmezni, de neked láthatóan nem sikerült: megadsz egy rakat kapcsolót a gcc-nek, és úgy valahogy lefordítod, MÉG AKKOR IS HIBÁS az eredmény.
És hogy mi is a hiba? Görgess fel és OLVASS, többször is leírtam.

- Miért történt az, hogy micsa sorával ott van az iretq, a sora nélkül pedig sima ret van?

- Mi olyan történik az egyetlen (és nem "rakat kapcsoló") "-mgeneral-regs-only" hatására, ami bármiben is megváltoztatná az előbbi eredményt? (clang -al még ez sem kell btw.)

// Happy debugging, suckers
#define true (rand() > 10)

Ahogy vártam, továbbra is képtelen vagy válaszolni. Nem meglepő, hiszen egy tudatlan TROLL vagy, aki csak picsogni képes.

Ja, és ha már személyeskedést akarsz, az aláírásod tökéletesen tükrözi a gennyes jellemed, Te magad kürtölöd világgá vele, milyen ember vagy valójában:

// Happy debugging, suckers
#define true (rand() > 10)

Ez egy normális programozónak még csak eszébe sem jutna soha, ilyesmi csakis egy megkeseredett, szánalmas, ártó szándékú TROLL fejében fordulhat meg.

Te vagy az, aki jelen pillanatban hazugsággal vádolsz mindenkit, de érvelni nem tudsz, hogy miért. Mindkét kérdésem releváns a vádaddal kapcsolatban és ebben a helyzetben a bizonyítási kényszer a tied, szóval:

- Miért történt az, hogy micsa sorával ott van az iretq, a sora nélkül pedig sima ret van?

- Mi olyan történik az egyetlen (és nem "rakat kapcsoló") "-mgeneral-regs-only" hatására, ami bármiben is megváltoztatná az előbbi eredményt? (clang -al még ez sem kell btw.)

// Happy debugging, suckers
#define true (rand() > 10)

hazugsággal vádolsz mindenkit, de érvelni nem tudsz, hogy miért

...vagy csak TE nem tudsz olvasni, erre gondoltál már?

Ezeket nem tudtad elolvasni és értelmezni, mégegyszer idemásolom őket, hogy ÖBALFASZSÁGODNAK még csak keresgélni se kelljen, LOL:

- "Miért nem akkor volt ilyen nagy a pofád, amikor választ kellett volna adni? Akkor bezzeg kussoltál, pedig egy egész hetet adtam, hogy biztos legyen időd átolvasni a doksikat."
- "Micsa kódjában nincs is implementáció, az egész biztos nem hozhatta azt az eredményt, amit idemásoltál"
- "megadsz egy rakat kapcsolót a gcc-nek, és úgy valahogy lefordítod, MÉG AKKOR IS HIBÁS az eredmény."
- "már le is írtam korábban pontosan (kétszer is), miért hibás az az Assembly kód, amit bemásoltál"
- "eltérő a stack frame, szóval még gatyába is kell rázni a vermet"
- "Még annyit is segítek, hogy a paraméterhez és az exception hibakódokhoz van köze."
- "abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI"
- továbbra sem árultad el, minek raktad oda azt a kapcsolót, "Csak nem egy "sorry, not implemented" gcc hibaüzenet miatt, amit megpróbálsz eltussolni?"

Persze mi mást is várhatnánk egy olyan HAZUG TROLL-tól, mint Te, aki válaszokat képtelen adni, magyarul SEM TUD OLVASNI, csak szánalmasan terleni meg hergelni próbál és semmi más.
A legnagyobb vicc az, hogy hát még a hergelés sem megy neked, mert ahhoz is túl hülye vagy. Kevés vagy, mint macisajtban a brummogás...

ps: Vígasztaljon a tudat, hogy most már mindenki tudja rólad, milyen semmirekellő és rosszindulatú ember is vagy valójában. Mit mondjak, aktívan tettél róla, hogy ez kiderüljön, gratulálok! :-D

- Miért történt az, hogy micsa sorával ott van az iretq, a sora nélkül pedig sima ret van?

- Mi olyan történik az egyetlen (és nem "rakat kapcsoló") "-mgeneral-regs-only" hatására, ami bármiben is megváltoztatná az előbbi eredményt? (clang -al még ez sem kell btw.)

// Happy debugging, suckers
#define true (rand() > 10)

Még most sem voltál képes válaszolni... Várható volt. De azért kapsz mégegy utolsó esélyt, hogy tisztára mosd a neved!

Miért történt az, hogy micsa sorával ott van az iretq, a sora nélkül pedig sima ret van?

Mert az ABI felülbíráló attribútumot törölted ki, nyilvánvalóan!

Mi olyan történik az egyetlen (és nem "rakat kapcsoló") "-mgeneral-regs-only" hatására, ami bármiben is megváltoztatná az előbbi eredményt?

Le se fordul nélküle, hibát dob, amit megpróbáltál LETAGADNI. (GYK: a többes számot meg azért használtam, mert nem az "-mgeneral-regs-only" az egyetlen, amivel fordításra lehet bírni, például használhattál volna "-mno-sse -mno-mmx -mno-80387" kapcsolókat is, ugye.)

$ gcc aaa.c -o aaa 
aaa.c: In function ‘handler’:
aaa.c:1:1: sorry, unimplemented: SSE instructions aren’t allowed in an interrupt service routine
    1 | void __attribute__((interrupt)) handler(void *p) {}
      | ^~~~

Tehát egyértelműen HAZUDTÁL, mikor azt mondtad, "Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val".

És most rajtad a sor, barátocskám, VÁLASZOLJ!
- miért most utólag akarsz kötekedni, miért voltál végig csöndben, amikor egy hét időt adtam a válaszokra?
- miért hiszed, hogy az ABI-t felülbírálva az a függvény még mindig szabvány C ABI-t használ? (Nyilván nem.)
- miért hiszed, hogy a lefordított program "az elvárt eredmény" és hogy egyáltalán működőképes? (Nem az, megírtam nem is egyszer, hogy mi a baj vele.)
- miért hazudtad, hogy csak az egy darab prototípus sorral generáltál kódot? (Nyilván nem.)
- miért hazudtad, hogy lefordul és próbáltad meg letagadni, hogy hibát dob a gcc kapcsolók nélkül?

Ha tisztázni akarod a neved, akkor csak simán válaszolj a feltett kérdésekre!

"Mert az ABI felülbíráló attribútumot törölted ki, nyilvánvalóan!"

Egyetlen egy dolgot töröltem ki, micsa sorát. Ezt itt végigkövetheted újra, ha elkerülte volna a figyelmedet. Ez elvileg nem lehet ABI felülbíráló attribútum, meg úgy egyébként se semmi, mert állításod szerint a sor két hibát is tartalmaz, illetve másik állításod szerint a kérdésem (amire most válaszoltál), egyébként sem lehetséges. Itt azért lehet el kellene döntened végre, lehetséges-e vagy sem, hibás vagy sem. Mert vagy itt beszélsz sületlenséget, vagy ott.

"Le se fordul nélküle, hibát dob, amit megpróbáltál LETAGADNI."

Az egésznek az első említése általam történt, és most azt mondod, hogy azt tagadom, amit én írtam le elsőnek? Elég nyakatekert mutatvány, de ha beidéznéd azt a részletet, ahol ilyen irányba tagadást tettem, azt megköszönöm.

"Tehát egyértelműen HAZUDTÁL, mikor azt mondtad, "Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val"."

Az említett egy darab sor továbbra is hiba és warning nélkül fordul -Wall opcióval. De igazad van, kihagytam még az üres function body-t (lásd lentebb) és a következő kettő kapcsolót: -c bzt.c (ezeket azért belátod, hogy kénytelen voltam megadni a fordításhoz). Szóval bár nagyon nagyon háttal és csukott szemmel kell nézni ezt, de ha szerinted hazugság, ám legyen :D

- miért most utólag akarsz kötekedni, miért voltál végig csöndben, amikor egy hét időt adtam a válaszokra?

Az, hogy hup.hu kiadásban egy origo bulvárrovat "Többszálúság fejtágító" értelmezését olvassam tőled, ahol úgy próbálsz te lenni a legokosabb, hogy végtelen butának tetteted magad (gondolok itt arra, ahogy a makrók létezését próbálod minden irányból elkerülni és letagadni, de még van rá ezer példa itt is), bár végtelenül szórakoztató, rövidtávon unalmas. Sokkal szórakoztatóbb lenne még az is, ha ráfognád a napszélre az iretq odakerülését és levezetnéd, ahogy a töltött részecskék átbillentik a biteket (ha megpróbálod, akkor légyszi ne hagyd ki azt a részt ahol a jelenség folyamatosan reprodukálható, baromira érdekelne).

- miért hiszed, hogy az ABI-t felülbírálva az a függvény még mindig szabvány C ABI-t használ? (Nyilván nem.) / - miért hiszed, hogy a lefordított program "az elvárt eredmény" és hogy egyáltalán működőképes? (Nem az, megírtam nem is egyszer, hogy mi a baj vele.)

nem hiszem, de nem is volt kérdés sose. Az egész oda vezethető vissza, ahol az állításod alapján csak assembly-ben lehet iret

- miért hazudtad, hogy csak az egy darab prototípus sorral generáltál kódot? (Nyilván nem.)

Senki nem állított ilyet. Számomra értelemszerű (számodra ezekszerint nem? programozóként azért ez vicces), hogy egy prototípust ki kell egészíteni. Azt se felejtsük ki, hogy az egészet még bele kell írni egy file-ba, majd a megfelelő fordítóval lefordítani. (azért írom oda a megfelelő fordítót, mert 5 perc múlva megpróbálsz rámutatni arra, hogy láááám, tcc-vel fordítva valóban hibás. Ekkor jön megint az előbb említett úgy hiszed magad okosnak, hogy csak szimplán butának tetteted magad).

- miért hazudtad, hogy lefordul és próbáltad meg letagadni, hogy hibát dob a gcc kapcsolók nélkül?

Ha egy picit több eszed lett volna, akkor ezt a szálat még megpróbálhattad volna meglovagolni azzal, hogy "nem említettem mivel fordítottam elsőnek (clang) és ezzel is hazudtam!". Kár, hogy ezt már nem tudod megpróbálni, bár annyi mindennel próbálkoztál, jöhet ez kövinek :\

(next round)

// Happy debugging, suckers
#define true (rand() > 10)

Ahogy előre megmondtam, válaszokat most sem kaptunk, csak ködösítési és hárítási kíséreltet, meg újabb HAZUGSÁGOKAT. És még csak meg sem próbáltad cáfolni, hogy rosszindulatú vagy.

Az, hogy hup.hu kiadásban egy ... baromira érdekelne).

Ebben az ömlengésben csak sértegetni próbálsz, de egyáltalán NEM ADSZ VÁLASZT arra a kérdésre, hogy miért most utólag pampogsz csak.
Az ok nyilvánvaló, és most már az is látja, akiben esetleg volt némi kétely TROLLságodat illetően.

- miért hiszed, hogy a lefordított program "az elvárt eredmény" és hogy egyáltalán működőképes?

nem hiszem, de nem is volt kérdés sose.

HAZUDSZ, mindigvégig csakis erről volt szó, nem másról. És ha még Te sem hiszed, hogy működőképes, akkor meg minek irogatsz egyáltalán a topikomba?

az állításod alapján csak assembly-ben lehet iret

Megint HAZUDSZ. Sosem állítottam ilyent, de hogy tisztázzuk, HAZUDSZ-e, idemásolom, hogy pontosan miket állítottam:
"eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges"
"A veremmutató direkt manupilálása pl olyan dolog, amit nem lehet C-ből (sem semmilyen más, magas szintű nyelvből) megcsinálni."

Arról nem tehetek, hogy a magyar nyelvű szövegértés meghaladja az értelmi képességeidet.

- miért hazudtad, hogy csak az egy darab prototípus sorral generáltál kódot? (Nyilván nem.)

Senki nem állított ilyet.

Akkor ezek mik?
"Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val"
"Az említett egy darab sor továbbra is hiba és warning nélkül fordul -Wall opcióval"

Hazug embert könnyebb utolérni, mint a sánta kutyát!

Ha egy picit több eszed lett volna...

Ez megint NEM VÁLASZ, csak sértegetési kísérlet. Továbbra sem árultad el, miért is raktad oda azt a kapcsolót (ne is fáradj, bárki leellenőrizheti saját maga, hogy HAZUDTÁL, mikor azt mondtad, lefordul nélküle.)

Tessék, gabrielakos, kell még ennél több bizonyíték, hogy Mcsiv egy TROLL?

"Ebben az ömlengésben csak sértegetni próbálsz, de egyáltalán NEM ADSZ VÁLASZT arra a kérdésre, hogy miért most utólag pampogsz csak."

Az, hogy nem tetszik a válasz, az más téma, pedig benne van. De akkor röviden, mert látszólag nem sikerült értelmezned: nem tekintelek szakértőnek és végképp nem tekintelek annyira relevánsnak, hogy érdemben foglalkozzak veled, volt jobb dolgom :)

"Hazug embert könnyebb utolérni, mint a sánta kutyát!" / "Ha egy picit több eszed lett volna..."

Az, hogy szűkítve "..."-al megpróbáltad eltűntetni azt ahol leírtam, clang volt az első fordító egy ügyes próbálkozás, ez továbbra is áll, a kérdésedet pedig teljesen invalidálja is :)

A "senki nem állított ilyet" is megpróbálhatnád tovább olvasni, "Senki nem állított ilyet. Számomra értelemszerű (számodra ezekszerint nem? programozóként azért ez vicces), hogy egy prototípust ki kell egészíteni."

ne is fáradj, bárki leellenőrizheti saját maga, hogy HAZUDTÁL, mikor azt mondtad, lefordul nélküle

Bár minden második hozzászólásodban felhívod a figyelmet arra, hogy az emberek mennyire nem tudnak értelmezni, valahogy neked sem akar összejönni, pedig ebben a hozzászólásomban is, meg a korábbiakban is már ott van a válasz :)

Tessék, gabrielakos, kell még ennél több bizonyíték, hogy Mcsiv egy TROLL?

Sajnálom, ha trollkodásnak veszed azt, hogy olyan összetett mondatokban válaszolok neked aminek a második felét nem érted. Az első felét pedig hiába idézgeted újra és újra, majd kérdezel rá, a második fele tartalmazza a válaszodat. Gondoltál már rá, hogy megpróbálod elolvasni?

// Happy debugging, suckers
#define true (rand() > 10)

Számomra értelemszerű (számodra ezekszerint nem? programozóként azért ez vicces), hogy egy prototípust ki kell egészíteni.

"Az említett egy darab sor nálam hiba és warning nélkül fordul -Wall opcióval, ráadásként az elvárt eredményt hozza iretq -val"
Ha kiegészítetted, akkor miért HAZUDTAD, hogy "az említett egy darab sor fodrul"? Akkor már nemcsak arról az egy darab sorról van szó, nyilvánvalóan.

Én válaszoltam, most rajtad a sor, VÁLASZOLJ!
- miért most utólag akarsz kötekedni, miért voltál végig csöndben, amikor egy hét időt adtam a válaszokra?
- miért hiszed, hogy az ABI-t felülbírálva az a függvény még mindig szabvány C ABI-t használ? (Nyilván nem.)
- miért hiszed, hogy a lefordított program "az elvárt eredmény" és hogy egyáltalán működőképes? (Nem az, megírtam nem is egyszer, hogy mi a baj vele.)
- miért hazudtad, hogy csak az egy darab prototípus sorral generáltál kódot? (Nyilván nem.)
- miért hazudtad, hogy lefordul és próbáltad meg letagadni, hogy hibát dob a gcc kapcsolók nélkül?

Legfőképpen erre: miért hiszed, hogy a lefordított program "az elvárt eredmény" és hogy egyáltalán működőképes?
Csak járatod itt a szád, miközben a lefordított programod nem is működik, elszáll a francba az iretq hívásnál, ha például page fault hívja.

Részemről adtam egy lehetőséget, hogy tisztára mosd a neved, de egyértelműen NEM IS AKARTÁL élni vele, csak SÉRTEGETNI PRÓBÁLTÁL helyette, ezzel beismerted, hogy csak egy hozzá nem értő TROLL vagy. Ennyi.

a kérdéseidre már fentebb válaszoltam, próbáld meg újra :)

"Részemről adtam egy lehetőséget, hogy tisztára mosd a neved, de egyértelműen NEM IS AKARTÁL élni vele, csak SÉRTEGETNI PRÓBÁLTÁL helyette, ezzel beismerted, hogy csak egy hozzá nem értő TROLL vagy. Ennyi."

Hamár az én hozzászólásaimat nem sikerült értelmezni, legalább a sajátjaidat megpróbálhatnád, akkor legalább nem hisztiznél, hogy elvileg "sértegetni próbáltalak" miközben te ezt a határt már több alkalommal átlépted :)

"Csak járatod itt a szád, miközben a lefordított programod nem is működik, elszáll a francba az iretq hívásnál, ha például page fault hívja."

gondolom a típus meghatározása sokat segíthet ezen a helyzeten, javaslom csapd fel a dokumentációt az edge case esetekért :) Bár egyébként azt állítod, hogy az a sor egyébként is hibás, nem értem hogy hívhatja page fault ebben az esetben. vagyis HAZUDTÁL? :D

// Happy debugging, suckers
#define true (rand() > 10)

gondolom a típus meghatározása sokat segíthet ezen a helyzeten

Természetesen rosszul gondolod, mert nem értesz hozzá. Újfent bizonyítottad, hogy csak egy szánalmas hazug TROLL vagy, aki még a betonba is belekötne.

De tessék, cáfolj meg, mutass be egy működő C kódot, ha tudsz!
A feladat: C-ben írt x86_64-es megszakításkezelő, Assembly nélkül, ami helyesen fut le page fault esetén és képes visszatérni a megszakított utasításhoz (nem baj, ha semmi mást nem csinál, csak térjen vissza hiba nélkül).

még arra sem sikerült választ találnod, miért vagyok hazug troll.

Még mindig nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

teljesen felesleges újra és újra bemásolnod

Csak nem ideges vagy? Megismétlem: működő C-ben írt PoC hiányában csak egy szánalmas hazug TROLL vagy. Meg akarsz cáfolni? Mutass egy működő PoC-t!

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Másodszor szólok, vegyél vissza, idézz ide egy csúnya szót, amint nem csak az előttem szólótól idéztem!

Micsára miért nem szóltál rá, például ezért, meg ezért meg ezért de pláne ezért a hozzászólásáért? Várom a válaszod!
Nem vet rád valami túl jó fényt, hogy kettős mércét alkalmazol és még fenyegetőzni is próbálsz, csak szólok.

miután "seggarcnak", "tanulatlan tuskónak", "okoskodó balfasznak", "szar alaknak", "senkiházi hazudozó alaknak", "dilettáns idiótának"  neveztél, hazugnak tituláltál,  azt mondtad, hogy "meghamisítottam" az outputot...  miközben nem vetted a fáradtságot, hogy egy disassemblyt megnézz... 

tisztára logikus...

 

de nem csak rólam van szó, te ilyen vagy, nálad ez az alap, te vagy az isten (bár nem tudom, mire) és rajtad kívül mindenki hülye... itt arról beszélnek, hogy nem csak velem, hanem mással is: 1, 2, 3, 4 ... és próbálják felhívni a figyelmedet, hogy kellene pótolni az elmaradt otthoni 7 évet... amikor is az ember megtanul szocializálódni

 

idézz ide egy csúnya szót, amint nem csak az előttem szólótól idéztem!

én neked ilyeneket NEM mondtam, babám, csak miután felcseszted az agyam... 

Tessék, gabrielakos, kell még ennél több bizonyíték, hogy micsa egy TROLL?

hanem mással is: 1, 2, 3, 4 ...

Köszönöm a példákat, ezek ékesen bizonyítják, hogy minden alkalommal TI kezdtétek a kötözködést, én ártatlan vagyok. Mindjárt a legelső tökéletes példája, hogy egy mocskos szájú hozzászólásra illedelmesen válaszoltam, és a benne lévő csúnya szó CSAK IDÉZET az előttem szólótól.

Kedves gabrielakos, bizonyára elkerülte a figyelmed, hogy adós vagy a válasszal, ezért megismétlem a kérdést: ezekre a trollokra miért nem szóltál rá?

egész pontosan melyik volt az "illedelmes" válasz? a "seggarc", a "tanulatlan tuskó", az "okoskodó balfasz", a "szar alaknak", a "senkiházi hazudozó alak",  esetleg a "dilettáns idióta"? Netalán a "sötét agymosott egyedek", a "baromarc" vagy az "idióta, dilettáns banda"?

 

Tessék, gabrielakos, kell még ennél több bizonyíték, hogy micsa egy TROLL?

az a gond, hogy neked azt jelenti a "troll", hogy nem ért veled egyet és esetleg (alátámasztva) megmondja, hogy nincs igazad... mert azt az egod már nem bírja elviselni

 

csak felhívom a figyelmed, hogy azzal, hogy nyilvánosság előtt hazugnak neveztél, még törvényt is sértettél (btk. 2012. C. törvény).

Keress már rá a szálban, hogy ki kötözködött először. Ebben a szálban, az SMGUI-s szálban, bármelyikben!
Keress már rá a szálban, ki próbált bizonyítékot HAMISÍTANI? Ki állított egyértelmű hazugságokat, például hogy a prototípus kódra fordul?

Szerkesztve: 2024. 08. 03., szo – 16:30

Vajon a JavaScript async API -ja még mindig többszálú ;)
 

"És most a várható időjárás: kellemes napos, de szórványosan habzó szájú trollpanaszeső fordulhat elő."
"Minden más fórumtársnak ellenben nagyon szívesen, remélem hasznotokra válik ez az alacsony szintű leírás."

Aki nem képes tanulni belőle, az csakis magára vessen, részemről a téma lezárva.

Átfutottam ezt a topikot, és bennem egy kérdés merült fel:

Mi a fasz?

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

FIgyú már bzt! Ez maradhatott volna egy tisztán szakmai thread is.

Tök ügyes gyerek vagy technikailag.

Ha pl úgy zársz egy technikailag vitás helyzetet (ez már kommunikáció), hogy "a legjobb tudásom szerint ez-és-ez van, értem, hogy Te mást hiszel, de akkor maradjunk ennyiben" - ebben sehol egy anyázás, stb...  Nem is mindig kell válaszolni. Ha igazad van, sincs igazad, ha nem megfelelően jelzed... És okosabb emberek mindig vannak (úgy értem, hogy igazából is), akár igaza is lehet a másiknak.

Csinálj valami jót, a következő thread-ben oszd meg, és legyen olyan ami simán szakmai, személyeskedés/visszaszemélyeskedés/leoltás nélkül, sokkal lazábban.

Bocs, a beledumálásért.  Ez csak az én véleményem, és a legjobb szándékkal írtam.

Kedves Micsa, Mcsiv és többi troll!

Tegyünk pontot az ügy végére, bizonyítsátok, hogy nem csak hazudoztatok össze-vissza. Ehhez mindössze egy nyúlfarnyi PoC-t kell prezentálnotok.

A feladat: C-ben írt x86_64-es megszakításkezelő, Assembly nélkül, ami helyesen fut le page fault esetén és képes visszatérni a megszakított utasításhoz (nem baj, ha semmi mást nem csinál, csak térjen vissza hiba nélkül).

Amíg nem vagytok képesek egy ilyen forrást prezentálni, amit lefordítva qemu-ban bárki kipróbálhat és ott hiba nélkül fut, addig maradtok siralmas, hazug TROLLok ;-D Csak rajtatok múlik, hogy tisztára tudjátok-e mosni a neveteket (eddig nem sikerült).

(Ja és azért qemu, mert az könnyen single step debuggolható és képes logolni a megszakítások bekövetkeztét is.)

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Nem, csak egyszerűen jobban hiszek a gcc/clang fejlesztőknek mint neked, hogy az " __attribute__((interrupt))" nem véletlen interrupt névvel van ellátva, és nem véletlen iretq amit generál.

Azon felül, hogy 10 másodpercnyi kutatást végeztem a témában (lásd fentebb) abban is biztos vagyok, hogy a "hazudsz" és "szánalmas troll" jelzőid mellett az új, eddig nem létező kitételeket megfelelően választottad meg (bár el sem olvastam, de beleillene a képbe)

Az eredeti felvetésed előbbivel cáfolva, a random generált szabályrendszernek való megfelelést pedig szimplán dobom az előbbi oknál fogva. További jó tengelykörülipörgést számodra 🍿 ;)

// Happy debugging, suckers
#define true (rand() > 10)

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Azon felül, hogy 10 másodpercnyi kutatást végeztem a témában

...és máris azt képzeled, hogy szakértő vagy a témában? LOL, magadat buktatod le, ráadásul egyfolytában.

"...és máris azt képzeled, hogy szakértő vagy a témában? LOL, magadat buktatod le, ráadásul egyfolytában."

Nem, még csak le sem buktattam magam, mert soha nem vallottam magam szakértőnek :) A 10 másodperces kutatás és az, hogy nem okoz gondot egy prototype kiegészítése, úgy tűnik tökéletesen elegendő skill veled szemben, még csak szakértőnek sem kell lenni :D

// Happy debugging, suckers
#define true (rand() > 10)

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

soha nem vallottam magam szakértőnek

Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt? LOL, ismét magadat buktattad le, TROLL.

"Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?"

elegendő a tények megfelelő kezelése, és látni hogy mi történik. Ha ott van az iret, akkor hiába mondod a másikra, hogy hazudik, az bizony ott marad :\

// Happy debugging, suckers
#define true (rand() > 10)

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

elegendő a tények megfelelő kezelése, és látni hogy mi történik

HAZUDSZ. Ha valóban látod, mi történik, akkor ismertesd a verem tartalmát a handler-beli iret kiadása előtti pillanatban, amikor az page fault hatására hívódott! Nyilván nem leszel rá képes, mert nem is értesz hozzá, csak a szád nagy. Nem, 10 másodpercnyi kutatás nem elegendő az alacsonyszintű programozás összes tényének megismeréséhez.

Ha ott van az iret, akkor hiába mondod a másikra, hogy hazudik

HAZUDSZ. Sosem állítottam, hogy csak az iret-re lenne szükség. Sőt, egyértelműen megmondtam, hogy önmagában az iret nem elégséges, még a vermet is gatyába kell rázni. Persze olvasni nem tudsz, inkább HAZUDOZOL össze-vissza.

Mégegyszer megkérdezem, ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?

Most bezzeg lapítasz, mint az a bizonyos a fűben, ahogy várható volt. Választ még mindig nem adtál, de még csak cáfolni sem próbáltad, hogy TROLL vagy, a szolgamód +1-ező cimboráiddal egyetemben.

Ezekre az egyszerű kérdésekre nem adtál még mindig választ, csak HAZUDSZ folyton-folyvást:
- Miért hazudtad, hogy az egysoros hiba nélkül lefordul, mikor nem is?
- Hol van az a PoC, ami bizonyítja, hogy egyáltalán működőképes a lefordított program?
- Hogy néz ki a verem az iretq hívásának pillanatában, ha page fault-ra hívódott a handler függvény?
- Beismerted, Te is tisztában voltál vele, hogy fingod sincs a témáról, és csak 10 mp-t foglalkoztál vele, akkor minek keztél el egyáltalán kötözködni itt a topikomban?

Az első három kérdésre sosem leszel képes válaszolni, mert láthatóan neked még az olvasással is gondod akad.

Viszont az utolsó kérdésre nagyon is kíváncsi lennék, ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért tetted?

Jaj, dehogy lapítok, fentebb már kifejtettem a veled való pontos hozzáállásomat, ez nem változott, sőt :)

A kérdéseidre a korábbi hsz-ekben találsz pontos és releváns információt. Mivel sose kérdeztél vissza semmire, csak ismételgetted magad, gondolom értelmezni nem sikerült őket, de ebben sajnos nem tudok segíteni :\

"Viszont az utolsó kérdésre nagyon is kíváncsi lennék, ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért tetted?"

A korábban említett 10 másodperc elegendő volt ahhoz, hogy elolvassam a gcc dokumentáció első 4 sorát amiben minden benne van, amit kerestem. Nem hiszem hogy aljas rosszundulat és ártó szándék lenne az, hogy elsőre megtaláltam, bár lehet ezt te fenyegetésnek éled meg :)

Felesleges energiáid levezetéséhez egyébként dobj hibajegyet a clang/gcc fejlesztőknek, hogy teljesen hülyék

// Happy debugging, suckers
#define true (rand() > 10)

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Nem hiszem hogy aljas rosszundulat és ártó szándék lenne az

Hanem mi? Egyáltalán nem adtál választ, ha nem ártó szándék, akkor mi más. Helyette megint sétregetni próbáltál csak, ami csak azt támasztja alá, hogy egy szánalmas TROLL vagy csupán.

Mégegyszer megkérdezem, ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?

Én itt már kezdem elveszteni a fonalat úgyhogy kérlek világítsátok meg egy kicsit.

Ugye arról van szó, hogy

1. bzt szerint C-ben nem lehet IRETQ-t generálni.

2. Erre Mcsiv összerakott valamit C-ben ami valahogy kiizzadt magából egy IRETQ utasítást.

3. De ez bzt-nek nem tetszik, mert csak egy laboratóriumi eset aminek gyakorlati haszna nincs.

?

majdnem :) Az eredeti megoldást micsa szállította, bzt lehazugozta. Én csak elolvastam a vonatkozó clang/gcc doksit, kipróbáltam, működik és én egy hazug troll lettem. A gyakorlatban is működik, haszna is van, se dirty magic, se tömjén nem kell hozzá, de bzt talált egy szegletet amire gondolom nem igaz (ezt nem teszteltem, de nem is állítottam), azóta pedig ez a fixációja :)

// Happy debugging, suckers
#define true (rand() > 10)

1. bzt szerint C-ben nem lehet IRETQ-t generálni.

Azt csak a TROLLok hazudták. Én sosem állítottam ilyent.

Azt állítottam, hogy szabvány C függvénnyel nem lehet megszakításkezelőt írni x86-on. Valamint azt, hogy ABI felülbíráló attribútumot (mint amilyen pl. az "__attribute__((interrupt))") használva már nem szabvány C függvényről beszélünk, és ráadásul önmagában az IRETQ sem elég, a vermet is gatyába kell rázni, mielőtt azt az IRETQ utasítást kiadhatná a processzor (hívott általi paramétereltávolítás nem C szabvány).

Mindezt össze is foglaltam micsa szánalmas posztjára válaszként.

2. Erre Mcsiv összerakott valamit C-ben ami valahogy kiizzadt magából egy IRETQ utasítást.

Nem, amit micsa összerakott, az nem is generált IRETQ-t (mert csak egy prototípus, implementáció nélkül). Annak is hibás (gcc mondja: "error: attributes should be specified before the declarator in a function definition").
Mcsiv hazudott, megpróbálta a) ezt a hibát letagadni és azt hazudta, lefordul, és b) suttyomban implementációra kijavítva és extra "-mgeneral-regs-only" kapcsolót megadva végül hibás kódra fordította le.

3. De ez bzt-nek nem tetszik, mert csak egy laboratóriumi eset aminek gyakorlati haszna nincs.

Nem, az a baj vele, hogy HIBÁS. Még ha kijavítjuk implementációra, akkor is hibás, le sem fordul (gcc mondja: "sorry, unimplemented: SSE instructions aren’t allowed in an interrupt service routine").
Ha megadunk speciális gcc kapcsolókat, akkor lefordulni már le fog ugyan, de úgysem működő kód az eredmény, elszáll a francba például page fault megszakítás esetén. Ezt is érthetően leírtam MCsiv-nek, csak hát nem tud olvasni.

Félreértés ne essék, mükődő C kódot ezidáig egyetlen nagyszájú sem volt képes bemutatni, helyette MCsiv beismerte, hogy csak 10 mp-t foglalkozott a témával és nem is ért hozzá, úgy próbált meg rosszindulatóan okoskodni, meg ártó szándékkal kötözködni.

Zanzásítva ez a tényállás.

ps: a teljesség kedvéért leírom, hogy létezik gcc specifikus workaround a problémára de az
a) nem része a C nyelvnek,
b) fordító függő hákolás,
c) azt a workaround-ot egyik TROLL sem említette ezidáig még.
Csak pofáznak meg hazudoznak itt össze-vissza, de hetek alatt sem voltak képesek elolvasni a gcc doksiját, ezért mondtam, hogy "nemcsak buták, de tanulni sem akarnak".

az eredeti kijelentés így hangzott: 

eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges

amiben Első Utolsó Nagy BZT kijelentette, hogy IRET-et csak assembly nyelven lehet...

erre írtam én be, hogy pl. a gcc tud ilyet, olyan kódot generálni, ami használható megszakítás kiszolgálásra (kijavítom: ez egy gcc specifikus extenzió a C-hez, de pl. a clang is tudja... bár ezt sem tudtad felfogni, ugye), nem KELL föltétlenül assemblyben írni. 

A stack-kel sem kell csinálni semmit, mert általában user módban szakad meg a task, a processzor megcsinálja a privilege level váltást, kiszedi a TSS-ből a kernel stack pointert (amit az OS beállított), abba ügyesen elmenti a visszatérési címet, flageket, aztán lefut az ISR és vissza lehet térni. Hardver interruptból általában nincs szükség a stack frame-et matatni és ha nem lesz pl. taszkváltás, akkor NEM KELL CSINÁLNI semmit, simán vissza lehet térni... az iretq meg fogja csinálni a privilege level váltást, ha kell (na jó, van 1-2 dolog, interrupt vezérlő meg babámfüle). Csak szemléltetni akartam, hogy Mr. BZT-nek ez a kijelentése sem állja a helyét: nem kell a "gatyába zárni a vermet".

Ha interrupt handler közben page fault lesz, akkor azt nagy valószínűséggel elcseszted... ez egyszerűen nem történhet meg, gyakorlatilag lekezelhetetlen: nem fogsz tudni egy IO műveletet végrehajtani, amikor egy ISR handlerben vagy. Csak ehhez át kellene látni az egészet, ugye.

 

Nem, amit micsa összerakott, az nem is generált IRETQ-t (mert csak egy prototípus, implementáció nélkül). Annak is hibás (gcc mondja: "error: attributes should be specified before the declarator in a function definition").

Ha megadod a gcc-nek a "-mgeneral-regs-only", akkor szépen lefordítja. Ha beleteszel a függvénybe egy "alma++;"-t akkor kb. ilyen kódot generál:

        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register %rbp
        pushq   %rax
        .cfi_offset %rax, -24
        cld
        leaq    8(%rbp), %rax
        movq    %rax, -16(%rbp)
        movl    alma(%rip), %eax
        incl    %eax
        movl    %eax, alma(%rip)
        popq    %rax
        popq    %rbp
        .cfi_def_cfa %rsp, 8
        iretq

 

szépen látszik az iretq és, hogy az összes regiszter, amit használt (rbp, rax), azokat szépen elmenti... ami elég is lenne, elvileg, gyakorlatilag nem, már mondtam, hogy kell matatni az apic-ot...

 

@pentike: bzt-nek egész konkrétan az a baja, hogy mi itt, páran, nem tetszettünk összeszarni magunkat őfelsége arroganciájától és ego-jától, esetleg meg mertünk kérdőjelezni pár kijelentését, emiatt meg lettünk büntetve, "seggarcnak", "tanulatlan tuskónak", "okoskodó balfasznak", "szar alaknak", "senkiházi hazudozó alaknak", "dilettáns idiótának" lettünk kinevezve, tudniillik ő fedezte fel a spanyolviaszt. Ja nem. Bár, az alátámasztott felvetéseinkre sosem tudott érdemszerűen válaszolni (sőt, szerintem maga a topiknyitás is rengeteg hülyeséget tartalmaz), mi mégis kiűzettünk a birodalomból az ő topikjából. Ja nem, ez egy közösségé, nem bzt-é, bocsánat.

Szóval, mi mind hazudunk és nem értünk hozzá... nincs hozzáfűznivalóm...

eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges

amiben Első Utolsó Nagy BZT kijelentette, hogy IRET-et csak assembly nyelven lehet...

Nem, a fenti mondtatom még véletlenül sem ezt jelenti, hanem azt, hogy a verem gatyába rázása (direkt veremmutatómanipuláció) az, ami csak Assmebly nyelven lehetséges. Megint visszakanyarodtunk oda, hogy NEM TUDSZ OLVASNI, és a magyar nyelvű szövegértés meghaladja az értelmi képességeidet.

És csak az sem mentség, hogy mellékmondatot tartalmaz, mert egyértelműen is leírtam, mellékmondat nélkül:
Egyrészről: "abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI"
De főként: "eltérő a stack frame, szóval még gatyába is kell rázni a vermet" és "A veremmutató direkt manupilálása pl olyan dolog, amit nem lehet C-ből (sem semmilyen más, magas szintű nyelvből) megcsinálni."
De ezt sem voltál képes ELOLVASNI, sem MEGÉRTENI.

Ha megadod a gcc-nek a "-mgeneral-regs-only", akkor szépen lefordítja.

Megint HAZUGSÁG, még ezek után is a lefordított kód HIBÁS, nem is működik page fault handlerként. Ezt is leírtam számtalanszor már, de NEM OLVASTAD el. Vagy csak nem akarod beismerni, hogy HAZUDSZ.

már mondtam, hogy kell matatni az apic-ot...

Ez is HAZUGSÁG, részletesen leírtam, mi a különbség a megszakításfajták között, csak NEM TUDSZ OLVASNI. Nem minden megszakítás IRQ, ráadásul nem is biztos, hogy van apic (ezt is részletesen kifejtettem, de NEM OLVASTAD EL).

bzt-nek egész konkrétan az a baja, hogy mi itt, páran, nem tetszettünk összeszarni magunkat őfelsége arroganciájától és ego-jától

Ismét HAZUGSÁG, egyértelműen megmondtam, mi a bajom. Konrtéan az a bajom, hogy úgy próbáltok rosszindulatból kötözködni, hogy bevallottan nem is értetek hozzá és ráadásul MÉG OLVASNI sem tudtok.

Bizonyíték, hogy megint HAZUDSZ, és megmondtam kerek-perec, mi bajom:
- "Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?"
- "Beismerted, Te is tisztában voltál vele, hogy fingod sincs a témáról, és csak 10 mp-t foglalkoztál vele, akkor minek keztél el egyáltalán kötözködni itt a topikomban?".

mi mind hazudunk és nem értünk hozzá

Igen. Bizonyíthatóan hazudtok, bizonyíthatóan (és bevalottan) nem is értetek hozzá, Te és a spanjaid, egy maximum 5 fős tanulatlan TROLL csürhe. Érdekes, mindenki mással értelmesen diskurálunk ezen a fórumon, mindössze veletek van baj csak. És nemcsak nekem, trey-nél is kihúztad már a gyufát.

Szóval:

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

a nagy pofádra, oda... 

tessék: 

itt van ez a projekt: https://github.com/mckev/bootstrap

kicheckoutolod, ráteszed a patchemet, lásd lennebb... felsetupolja a 77-es idt entry-t, semmi assembly...

úgy kell indítani, hogy: qemu-system-i386 -cdrom myos.iso

 

minden kbhitre szépen meghívja a megszakítást, a "terminál" pedig megy tovább... a megszakítás handler meg sima C-ben van írva, és minden billentyűre kiírja, hogy "nagypofaju bztnek..." a handlerből...

szerk: nincs ott semmiféle "verem gatyába rázása"... assemblyből... a C függvény meg van adva magában az idt-ben...

 

screencast itt

 

lehet tippelni, hogy mi lesz erre bzt reakciója... hogy HAZUG vagyok-e vagy TANULATLAN TUSKÓ... SEGGARC, maybe... esetleg mindhárom?

 

 

patch:

diff --git a/src/compile.sh b/src/compile.sh
old mode 100644
new mode 100755
index 2f20d7d..ae62d30
--- a/src/compile.sh
+++ b/src/compile.sh
@@ -3,8 +3,8 @@
set -e
 
 
-AS=~/opt/cross/bin/i686-elf-as
-GCC=~/opt/cross/bin/i686-elf-gcc
+AS=i686-elf-as
+GCC=i686-elf-gcc
GCC_OPTIONS="-std=gnu99 -ffreestanding -O2 -Wall -Wextra -masm=intel"
OBJ_FILES=""
 
@@ -54,7 +54,7 @@ rm -f timer.o
$GCC $GCC_OPTIONS -c timer.c -o timer.o
OBJ_FILES="$OBJ_FILES timer.o"
rm -f trap.o
-$GCC $GCC_OPTIONS -c trap.c -o trap.o
+$GCC $GCC_OPTIONS -c trap.c -o trap.o -mgeneral-regs-only
OBJ_FILES="$OBJ_FILES trap.o"
rm -f util.o
$GCC $GCC_OPTIONS -c util.c -o util.o
diff --git a/src/kernel.c b/src/kernel.c
index 3aa19db..633ada1 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -28,6 +28,6 @@ void kernel_main() {
       STI();
 
       // Call main
-       main_starfield();
-       // main_terminal();
+       //main_starfield();
+       main_terminal();
}
diff --git a/src/main_terminal.c b/src/main_terminal.c
index eb4ef36..db89500 100644
--- a/src/main_terminal.c
+++ b/src/main_terminal.c
@@ -17,6 +17,7 @@ int main_terminal() {
               if (kbhit()) {
                       char ch = getch();
                       terminal_writechar(ch);
+                       asm volatile("int 77");
               }
       }
 
diff --git a/src/trap.c b/src/trap.c
index 09500af..fa07d15 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -83,10 +83,34 @@ extern uint32_t trap_vectors[];     // in trap_vectors.s
       (gate).off_31_16 = (uint32_t)(off) >> 16;                       \
}
 
+#define VGA_BUFFER (uint16_t*)0xb8000
+#define VGA_WIDTH 80
+
+void print_string(int line, int offset, const char* str, uint8_t color)
+{
+       uint16_t*       vga = VGA_BUFFER;
+       int             i = 0;
+
+       while (str[i] != '\0') {
+               vga[i + line * VGA_WIDTH + offset] = (color << 8) | str[i];
+               i++;
+       }
+}
+
+void __attribute__((interrupt)) my_isr(void *)
+{
+       static int line = 0;
+       const char *str = "nagypofaju bztnek...";
+
+       print_string(line, 40, str, 0x0f);
+       line++;
+}
+
void trap_vectors_init() {
       for (int i = 0; i < 256; i++) {
               SETGATE(idt[i], 0, SEG_KCODE << 3, trap_vectors[i], 0);
       }
+       SETGATE(idt[77], 1, SEG_KCODE << 3, my_isr, 0);
}
 

a generált kód pedig (objdump, at&t assembly syntax, a gyengébbek kedvéert):

00000000 <my_isr>:
  0:   55                      push   %ebp
  1:   89 e5                   mov    %esp,%ebp
  3:   53                      push   %ebx
  4:   8b 1d 00 08 00 00       mov    0x800,%ebx
  a:   51                      push   %ecx
  b:   52                      push   %edx
  c:   ba 01 00 00 00          mov    $0x1,%edx
 11:   50                      push   %eax
 12:   8d 04 9b                lea    (%ebx,%ebx,4),%eax
 15:   c1 e0 04                shl    $0x4,%eax
 18:   8d 8c 00 50 80 0b 00    lea    0xb8050(%eax,%eax,1),%ecx
 1f:   b8 6e 00 00 00          mov    $0x6e,%eax
 24:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi
 2b:   8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi
 2f:   90                      nop
 30:   80 cc 0f                or     $0xf,%ah
 33:   83 c1 02                add    $0x2,%ecx
 36:   83 c2 01                add    $0x1,%edx
 39:   66 89 41 fe             mov    %ax,-0x2(%ecx)
 3d:   66 0f be 42 ff          movsbw -0x1(%edx),%ax
 42:   84 c0                   test   %al,%al
 44:   75 ea                   jne    30 <my_isr+0x30>
 46:   83 c3 01                add    $0x1,%ebx
 49:   58                      pop    %eax
 4a:   5a                      pop    %edx
 4b:   89 1d 00 08 00 00       mov    %ebx,0x800
 51:   59                      pop    %ecx
 52:   5b                      pop    %ebx
 53:   5d                      pop    %ebp
 54:   cf                      iret

 

mivel szerintem alszik, segítek neki, hogy addig is haladjon a szál, a deadlock-ot amibe került nem nehéz reprodukálni: hazudsz te tanulatlan tuskó, mert ez nem is page fault (bár ezt csak később tettem feltétellé), csak sima interrupt! A kód pedig egyébként is hibás mert tele van + jelekkel, az nem fordulhat le!

// Happy debugging, suckers
#define true (rand() > 10)

a következő patch exception handlereket is kezel:

lekezeli a 0-st (division by 0) és lekezeli a 13-ast (generic protection fault)... (csak azért nincs page fault, mert nincs paging ebben a projektben)...

 

A 0-st egy "div ebx" triggereli (ahol ebx 0) ("x" betű), a 13-ast egy "mov es, ax" (ahol ax egy hibás szelektor lesz) ("p" betű)...

Az elsőnek nincs error kódja, a másodiknak van... mindkét esetben az opcode két byte-os, ezért megnöveli a stack-en lévő eip-t kettővel... az utasítást gyakorlatilag kihagyja és megy szépen tovább...

Mindkét handler teljesen C-ben van írva, semmi assembly... az error kódot is szépen kiszedi a stackből az iret előtt...

érdekes: semmi stacket nem kellett "gatyába rázni" assemblyben, sem az iret utasítást... de én vagyok a tanulatlan tuskó, ugye... sőt, még olvasni se tudok

 

 

diff --git a/src/compile.sh b/src/compile.sh
old mode 100644
new mode 100755
index 2f20d7d..ae62d30
--- a/src/compile.sh
+++ b/src/compile.sh
@@ -3,8 +3,8 @@
set -e
 
 
-AS=~/opt/cross/bin/i686-elf-as
-GCC=~/opt/cross/bin/i686-elf-gcc
+AS=i686-elf-as
+GCC=i686-elf-gcc
GCC_OPTIONS="-std=gnu99 -ffreestanding -O2 -Wall -Wextra -masm=intel"
OBJ_FILES=""
 
@@ -54,7 +54,7 @@ rm -f timer.o
$GCC $GCC_OPTIONS -c timer.c -o timer.o
OBJ_FILES="$OBJ_FILES timer.o"
rm -f trap.o
-$GCC $GCC_OPTIONS -c trap.c -o trap.o
+$GCC $GCC_OPTIONS -c trap.c -o trap.o -mgeneral-regs-only
OBJ_FILES="$OBJ_FILES trap.o"
rm -f util.o
$GCC $GCC_OPTIONS -c util.c -o util.o
diff --git a/src/kernel.c b/src/kernel.c
index 3aa19db..633ada1 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -28,6 +28,6 @@ void kernel_main() {
       STI();
 
       // Call main
-       main_starfield();
-       // main_terminal();
+       //main_starfield();
+       main_terminal();
}
diff --git a/src/main_terminal.c b/src/main_terminal.c
index eb4ef36..e2d1ef8 100644
--- a/src/main_terminal.c
+++ b/src/main_terminal.c
@@ -5,6 +5,27 @@
#include "terminal.h"
 
 
+extern void dummy_func(unsigned);
+
+void do_division_by_0()
+{
+       __asm__ __volatile__ (
+               "mov eax, 42;"
+               "mov ebx, 0;"
+               "div ebx;"      // két byte
+       );
+}
+
+void do_generic_prot_fault()
+{
+       __asm__ __volatile__ (
+               "push eax;"
+               "mov ax, 3243;" // invalid, 2 bytes
+               "mov es, ax;"
+               "pop eax;"
+       );
+}
+
int main_terminal() {
       terminal_init();
       terminal_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLUE));
@@ -17,6 +38,12 @@ int main_terminal() {
               if (kbhit()) {
                       char ch = getch();
                       terminal_writechar(ch);
+                       asm volatile("int 77");
+                       if (ch == 'x') {
+                               do_division_by_0();
+                       } else if (ch == 'p') {
+                               do_generic_prot_fault();
+                       }
               }
       }
 
diff --git a/src/trap.c b/src/trap.c
index 09500af..4ece430 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -31,6 +31,7 @@ typedef struct {
       uint16_t ss, padding6;
} trapframe;
 
+void print_int_hex(const char *pre, int line, int col, unsigned d);
void trap(trapframe* tf) {
       /*
               Referenced from trap_vectors.s and trap_asm.s
@@ -83,10 +84,74 @@ extern uint32_t trap_vectors[];     // in trap_vectors.s
       (gate).off_31_16 = (uint32_t)(off) >> 16;                       \
}
 
+#define VGA_BUFFER (uint16_t*)0xb8000
+#define VGA_WIDTH 80
+
+void print_string(int line, int offset, const char* str, uint8_t color)
+{
+       uint16_t*       vga = VGA_BUFFER;
+       int             i = 0;
+
+       while (str[i] != '\0') {
+               vga[i + line * VGA_WIDTH + offset] = (color << 8) | str[i];
+               i++;
+       }
+}
+
+void print_int_hex(const char *pre, int line, int col, unsigned d)
+{
+       const char *hextab = "0123456789ABCDEF";
+       char buf[64];
+       int j, k;
+
+       k = 0;
+       while (pre[k] != '\0') {
+               buf[k] = pre[k];
+               k++;
+       }
+       buf[k] = 0;
+
+       for (j = 7; j >= 0; j--) {
+               buf[k + 7 - j] = hextab[(d >> (4*j)) & 0xf];
+       }
+       buf[k + 8] = 0;
+       print_string(line, col, buf, 0x0f);
+}
+
+void __attribute__((interrupt)) my_isr(void *)
+{
+       static int line = 0;
+       const char *str = "nagypofaju bztnek...";
+
+       print_string(line, 40, str, 0x0f);
+       line++;
+}
+
+void __attribute__((interrupt)) my_division_by_0(unsigned int* regs)
+{
+       static int line = 0;
+
+       print_int_hex("division_by_0: eip=", line, 5, regs[0]);
+       regs[0] += 2;
+       line++;
+}
+
+void __attribute__((interrupt)) my_generic_fault(unsigned int* regs, unsigned error_code)
+{
+       static int line = 0;
+
+       print_int_hex("generic fault: eip=", line, 15, regs[0]);
+       regs[0] += 2;
+       line++;
+}
+
void trap_vectors_init() {
       for (int i = 0; i < 256; i++) {
               SETGATE(idt[i], 0, SEG_KCODE << 3, trap_vectors[i], 0);
       }
+       SETGATE(idt[0], 0, SEG_KCODE << 3, my_division_by_0, 3);
+       SETGATE(idt[13], 0, SEG_KCODE << 3, my_generic_fault, 3);
+       SETGATE(idt[77], 1, SEG_KCODE << 3, my_isr, 0);
}

 

na... bzt... hát mi történt? semmi hozzáfűznivaló a patchemhez? pedig én dolgoztam vele, még a nevedet is beleírtam... 

na, de hogy semmi komment... ez igazán tiszteletlenség... én még abban is reménykedtem, hogy valami bugot fogsz felfedezni benne... (csak sima C, csak kevés assembly van benne 🤭 )

Szerkesztve: 2024. 08. 19., h – 20:09

Fantasztikus, hogy léteznek ennyire sötét emberek, mint Micsa és Mcsiv. A gcc doksit még mindig nem sikerült végigolvasniuk, ROTFL.

Mindkét handler teljesen C-ben van írva, semmi assembly...

__asm__ __volatile__

No comment. Még a hülye is látja, hogy HAZUDSZ.

az error kódot is szépen kiszedi a stackből az iret előtt...

semmi stacket nem kellett "gatyába rázni"

No comment.

itt van ez a projekt

Na, pontosan erről beszélek, csak egy szánalmas kopipaszta huszár vagy, akinek fogalma sincs arról, mit is csinál igazából.

Köszönöm, hogy újfent igazoltátok, helyesen ítéltelek meg titeket, TROLLok!

Az egész ott kezdődik, hogy még az architektúrát sem sikerült eltalálniuk. Az a projekt, amiből idemásoltak egy részletet, még csak nem is x86_64-re íródott... Tényleg ROTFL :~D

Mivel nyilvánvalóan nem szakértők, marad az, hogy pusztán rosszindulatból és ártó szándékkal próbálnak itt kötözködni, tehát TROLLok. Q.E.D.

Értem, köszi. A gcc gondolom le tudja generálni a megfelelő opkódot. De ez gcc specifikus? __attribute__((interrupt)) - tehát ha más fordító van, akkor kellhet az assembly?

Szerk: nekem ez csak azért volt kérdés, mert szerintem mást jelent, ha valamit GCC-vel meg lehet oldani, és mást, ha C-ben (tehát valamelyik standardban benne van, és implementálják a fordítók).

Egyébként ügyes a patch amit csatoltál, jó példa, és a projekt+a kapcsolódó blog is jó, amit linkeltél, fogom nézegetni,  köszi szépen!

Itt a válasz, már megírtam.

ps: a teljesség kedvéért leírom, hogy létezik gcc specifikus workaround a problémára de az
a) nem része a C nyelvnek,
b) fordító függő hákolás,
c) azt a workaround-ot egyik TROLL sem említette ezidáig még.
Csak pofáznak meg hazudoznak itt össze-vissza, de hetek alatt sem voltak képesek elolvasni a gcc doksiját, ezért mondtam, hogy "nemcsak buták, de tanulni sem akarnak".

persze, hogy nem standard C... könyörgöm, kernelről beszélünk...gcc tudja, clang tudja... (ugyanez a syntax) ez már elég nagy szelet...

msvc és icc nem tudja, de ott is lehet matatni ilyenekkel, mint __declspec(naked)

de ne hasonlítsuk a msvc-t a 3 platformjával a gcc 30+ platformjával...

Oké, értem, ahogy én látom a kérdést: Hivatalosan, ha azt mondod, hogy "C-ben lehet ilyet", azt egyféle dolgot jelent nekem. De itt a GCC tudja ezt. - szerintem itt beszéltetek el egymás mellett bzt-vel. Tehát C-ben ilyet nem lehet. - De szerintem tök jó a GCC megoldása erre, és én is ezt használnám, ha kellene.

C-be nem is lenne értelme ilyet berakni a standard-ba szerintem, ha mögé gondolunk a dolgoknak. Ezért nincs benne, nincs mindenhol értelme, a C pedig megpróbál általános lenni.

Bocsi, hogy ebbe beledumálok: Ezt bzt, (a stílustól függetlenül) írta is. (Szerintem kár így reagálnia, ahogy korábban írtam, akár beszélgetni is lehetne. Mi ezen a filmen szoktunk röhögni, ha valaki felhúzza magát: "Goosfraba!" tök jó film: https://www.youtube.com/watch?v=TUvvYUVbbl4 - kár felkapni a vizet. :) )

Mi is eljutottunk a megoldásig kb 3 üzenetváltáson keresztül.

Ezt bzt, (a stílustól függetlenül) írta is.

Valamint azt is írtam már a legeslegelején, hogy: Én bizony büszkén vállalom, hogy elküldöm a picsába azt, aki nem tud olvasni, de mégis kötözködni próbál. Itt most pontosan ez történt, nem tudnak olvasni, mégis kötözködni próbáltak.

Szerintem kár így reagálnia

Ne felejtsük el,
- ők jöttek ide az én topikomba,
- ők próbáltak bizonyítékot hamisítani,
- ők próbáltak meg kötözködni annélkül, hogy értenének hozzá,
- ők nem voltak képesek rendesen elvolasni, amit írtam,
- ők nem voltak képesek elolvasni a gcc doksit,
- és ők próbáltak meg sértegetni engem.

Én csakis azon gúnyolódtam teljesen jogosan (idézetekkel és linkkel), amikor magukból csináltak hülyét. Előre megmondtam, hogy a TROLLokkal ez lesz, nem kell meglepődni.

És azt se felejtsük el, hogy ez messze nem az első eset, amikor ezek a TROLLok összeszemetelik a topikjaimat. A stílust ők maguk érdemelték ki, senki mással nem beszélek így, csakis velük, és nem is én kezdtem ezt a stílust, hanem ők.

akár beszélgetni is lehetne

Látogass el az SMGUI topikomba, ott megpróbáltam szép szóval beszélni velük, de nem értették, továbbra is csak fröcsögtek. ÉN MEGPRÓBÁLTAM, a lelkiismeretem tiszta.

Ebben a topikban is megpróbáltam, de itt is csak fröcsögnek, nézd csak meg a saját szemeddel, kinek a stílusával is van baj!

Bzt, engedd el.

A stílust azért írtam, mert az ilyen stílusú válaszokkal, mint a HAZUDSZ vagy TROLL nagy betűkkel írva, meg "adok egy feladatot a nagyarcúaknak", nem biztos, hogy támogatást fogsz kapni, még akkor sem, ha igazad van.

Nekem pl az a taktikám hasonló helyzetben, hogy elengedem... Nem érdekel igazán, hogy ki mit gondol, ha egyszer nem értünk egyet valakivel, akkor elfogadom, hogy más véleményen van, és megyünk tovább.

Például: Én személy szerint úgy gondolom, hogy a standard C az, ami az ISO szabványban le van írva, és abban nincs megszakításkezelés. Ezt leírtam ide. Elkezdhet velem valaki vitatkozni, ha értelmesen leírja, hogy miért gondol mást, akkor meg fogom érteni, ha nem, akkor megyünk tovább.

A stílust azért írtam, mert az ilyen stílusú válaszokkal, mint a HAZUDSZ vagy TROLL nagy betűkkel írva, meg "adok egy feladatot a nagyarcúaknak", nem biztos, hogy támogatást fogsz kapni, még akkor sem, ha igazad van.

Sosem érdekelt, hogy kinek van igaza, csak az, hogy mi az igazság. És az sem érdekel már, ha nem vagyok népszerű, sőt, kifejezetten hízelgő és bóknak veszem, ha ez az agymosott csürhe utál ;-)

Nekem pl az a taktikám hasonló helyzetben, hogy elengedem

Előre megmondtam, hogy ezt fogom csinálni, ha egy hozzá nem értő kötekedni próbál, szóval csupán tartom magam ahhoz, amit ígértem. De bevallom, piszkosul szórakoztat is, ahogy besétálnak a csapdáimba és folyamatosan hülyét csinálnak magukból.

Azért az lássuk, hogy ők annak ellenére, hogy bevallották, tudatában voltak a hozzá nem értésüknek, mégsem kérdeztek, nem intelligensen társalogtak, hanem mégis egyből támadni és sértegetni próbáltak, ezért nincs lelkiismeret furdalásom, ha lejáratom őket.

Nem érdekel igazán, hogy ki mit gondol, ha egyszer nem értünk egyet valakivel, akkor elfogadom, hogy más véleményen van, és megyünk tovább.

Ez rendben is volna, na de ők nem véleményt formának, hanem bizonyíthatóan HAZUDOZNAK. Tudod, az nem vélemény és ki mit gondol kérdése, hogy valami benne van-e egy szabványban, vagy hogy egy adott sorra hibát dob-e a fordító.

És itt átkanyarodtunk korunk legégetőbb problémájára, ami minden más bajnak a gyökere, ami az orosz álhírek és rogáni propaganda csimborasszója, hogy megpróbálják összemosni a tényeket a véleményekkel. Ha ezt hagyjuk, akkor vége az emberiségnek (nem túlzok, ez tényleg egyenesen oda vezet, ez az információs kút megmérgezése). Ez már más lapra tartozik, itt ne menjünk bele a részletekbe, itt legyen elég annyi, hogy a tényeket véleményekkel keverni a legsúlyosabb veszély az emberiség jövőjére nézve.

C-be nem is lenne értelme ilyet berakni a standard-ba szerintem, ha mögé gondolunk a dolgoknak. Ezért nincs benne, nincs mindenhol értelme, a C pedig megpróbál általános lenni.

Igen, a C az elegge altalanos, de minden ami a protected/privileged/escalated/interrupted/trapped/etc temakorrel kapcsolatos az nagyon specifikussa teszi. Nem is a nyelvet magat, hanem a "koritest". Igazabol igy "okolszabalynak" azt mondam hogy a C forditok (pl GCC) adnak egy relative egyszeru metodust arra hogy a "tankonyvi pelda" jellegu megszakitasokat kenyelmesen irj. Ezekben az esetekben altalaban valami #define-olt makrot, __attribute__-ot, stb kell ele-moge irni a megfelelo handlernek, es akkor a fordito megcsinalja azt amit kell (a regiszterek/allapotok kapcsan menti amit menteni kell majd visszaallitja, megfelelo interrupt return utasitassal ter vissza a sima return helyett, beleteszi a megfelelo vektorokat/jmp-ket a a vektortablaba/jmp tablaba ha kell, stb). Ha van hardveres/beepitett/mikrokodolt segitseg (mint pl az ARM Cortex-Mx kontrollereknel) akkor ez annyira ki tud egyszerusodni hogy semmit nem kell a handler ele-moge irnod :) Ld. fentebb, valahol. Ezekben az esetekben tehat egyreszt semmi asm-tudas nem szukseges, masreszt viszont nem art tisztaba lenni a megfelelo function attribute-k kimerithetetlen hosszu listazasval hogy tkp mi mit csinal (avagy a makrokat ezek egyszerusitesere meg kismeretkben valo hordozhatosagara keszitettek fel).

Viszont olyan esetekben amikor a tankonyvi peldaknal komplexebb valamit kell megoldanunk, akkor mar igen jo esellyel nem usszuk meg sem az assembly-t, sem a fenti function attribute-k meg kimeritobb tanulmanyozasat. Persze ez az allitas is erosen ketseges lehet, pl az is erosen rendszer-fuggo meg kicsit szubjektiv is hogy mi szamit "tankonyvi peldaknal komplexebb valami"-nek, de egy context switch vagy illegal instruction fault handler mar joesellyel ide tartozik. 

Es hogy a kivetel gyengitse a szabalyt, meg ilyesmikkel is lehet talalkozni mint struct interrupt_frame *. Ezt abszolute nem ismerem a gyakorlatban, de nem kizart hogy ezzel pont a "tankonyvi peldaknal komplexebb valami"-k egy reszeben is ki tudunk szabadulni az assembly-zes kenyszerebol. Legalabbis hasonlo elgondolasokat lattam mar RISC-V BIOS-ok (SBI-k) eseteben, ahol ugyan kezzel, de egy teljesen egyseges interrupt handlert allitanak be ami utana minden esetben a szabvany C ABI szerint adja at a teljes kontextet barmilyen okbol kifolyolag is hivtak meg a handlert (azaz ugyanaz hw interruptra, sw interruptra es trap-ek eseten is, sot, exception/interrupt delegation eseten is). Raadsul RISC-V eseten az eggyel kisebb privilegizalasi szinten futo op rendszer (pl. linux kernel) is ezt csinalja. Azaz siman el tudom kepzelni azt hogy egy megfelelo __attribute__ legeneralja ezt a kodreszletet egy masik/adott architektura eseten es onnantol kezdve szabvany C ABI szerint mennek tovabb a dolgok a maguk utjan. Kicsit hasonloan mint a Cortex-M eseten, csak egyreszt nem prociba vasalt mikrokoddal hanem sajat koddal, masreszt meg az ABI ott nem void handler (void) lesz hanem void handler (context_t *) lesz.

tldr: elegge vegyes az osszkep, igen. 

meg ilyesmikkel is lehet talalkozni mint struct interrupt_frame *. Ezt abszolute nem ismerem a gyakorlatban, de nem kizart hogy ezzel pont a "tankonyvi peldaknal komplexebb valami"-k egy reszeben is ki tudunk szabadulni az assembly-zes kenyszerebol.

Majdnem. Az struct interrupt_frame * mutató nem oldja meg, és nem is paraméter valójában, hanem a visszatérési értékre (a struktúra legalsó eleme a visszatérési érték) mutat a veremben.

Ami ténylegesen megoldja a dolgot (és amit mind a mai napig nem voltak képesek elolvasni a doksiban a TROLLok), az az, ha a mutató után megadunk egy MÁSODIK skalár argumentumot a prototípusban, na akkor a gcc specifikus attribute miatt valójában azt sem paraméterként, hanem lokális változóként kezeli a gcc által generált kód (azaz a visszatérési érték alatti verembejegyzésre hivatkozik). Továbbá, normál szabvány C függvény esetében x86_64-on a veremben található egy red zone nevű terület, a gcc hákolás miatt ez is hiányzik, mert az felülcsapná a struct interrupt_frame-t. A Micsa TROLL által idekopipasztázott i386-os kódnak ezzel sem kell törődnie, mert i386-on nincs is red zone.

Mindezt persze érthetően le is írtam, nem is egyszer, csak hát nem tudnak olvasni:
- "ABI felülbíráló attribútumot (mint amilyen pl. az "__attribute__((interrupt))") használva már nem szabvány C függvényről beszélünk" és
- abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI.

utana minden esetben a szabvany C ABI szerint adja at a teljes kontextet

siman el tudom kepzelni azt hogy egy megfelelo __attribute__ legeneralja ezt a kodreszletet

A helyzet az, hogy ilyen kódot a gcc nem képes generálni x86_64-en. A konkrét gcc hibaüzenet, ahogy már többször is leírtam, "Sorry, unimpimplemented". Amikor Mcsiv azt hazudta, hogy lefordul kapcsolók nélkül, akkor valójában azért volt szükség a "-mgeneral-regs-only" kapcsolóra, mert a teljes kontextet mentő kódot nem, csak az általános célú regisztereket mentő kódot képes generálni (és azok közül is csakis azokat a regisztereket menti, amiket a megszakításfüggvény használ, és nem az összeset).

elegge vegyes az osszkep, igen.

Valóban, ennek ellenére "MCsiv beismerte, hogy csak 10 mp-t foglalkozott a témával és nem is ért hozzá, úgy próbált meg rosszindulatóan okoskodni, meg ártó szándékkal kötözködni."
10 másodperc nyilván nem elégséges egy ennyire összetett dolog megértéséhez.

"Amikor Mcsiv azt hazudta, hogy lefordul kapcsolók nélkül, akkor valójában azért volt szükség a "-mgeneral-regs-only" kapcsolóra"

Te papolsz a szövegértésről, bár 20x leírtam már, leírom mégegyszer: clang

"10 másodperc nyilván nem elégséges egy ennyire összetett dolog megértéséhez."

Annak megállapításához, ami az eredeti állítás volt: "semmi assembly és szépen belegenerálja az iretq-t" tökéletesen elegendő volt, én ezt állítottam végig. Erre a 10 másodperc bőven elégséges, de itt megint a szövegértés az, ami úgy tűnik csak neked nem megy :)

// Happy debugging, suckers
#define true (rand() > 10)

Annak megállapításához, ami az eredeti állítás volt: "semmi assembly és szépen belegenerálja az iretq-t"

FACEPALM. Az eredeti állítás véletlenül sem ez volt, hanem ez:
nem lehetséges szabvány C függvénnyel megszakításkezelőt írni (abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI)
Fuss neki mégegyszer, próbáld meg ELOLVASNI és MEG is ÉRTENI, ami ide van írva. A Te értelmi képességeidhez mérten ez nehéz feladat, ezt már demonstráltad, de azért csak próbáld meg!

Továbbá SOSEM állítottam, hogy ne lehetne iretq-t generáltatni, csak az azt, hogy SZABVÁNY C függvényben nem, és hogy önmagában az iret még nem elég, de ezt is tisztáztuk már, csak hát nem tudtad SEM ELOLVASNI, SEM MEGÉRTENI ezt sem.

Na, kinek is van baja a magyar nyelvű szövegértéssel, Mcsiv? Egy tanulatlan és ostoba, szánalmas TROLL vagy csupán. És mivel nem is akarsz tanulni, az is maradsz!

"FACEPALM. Az eredeti állítás véletlenül sem ez volt, hanem ez:"

Az a facepalm, hogy az eredeti állítás amire reagáltam, pont az volt, amire hivatkoztam. Az, hogy te a világ közepének gondolod magad, csak megmosolyogtató. Az, hogy a legokosabbnak képzeled magad úgy, hogy 20x kell leírni a clang-ot, mire megérted, már nevetséges. Az, hogy belekötsz a prototype-ba, hogy két hibát is tartalmaz, miközben nem, majd hibásan egészíted ki, csak hogy hibásnak tűnjön, szánalmas.

"Na, kinek is van baja a magyar nyelvű szövegértéssel, Mcsiv? Egy tanulatlan és ostoba, szánalmas TROLL vagy csupán"

Neked. "Tanulatlan és ostoba trollként" nekem valahogy mégis sikerült kiegészíteni a prototype-ot és pont azt kaptam, amit állítottak róla. Ezen pedig az állandó tagadásod, értetlenkedésed, az eredeti "szabályrendszer" kiegészítéseid sem tudnak változtatni és eddig a percig sem sikerült megcáfolnod. Korábban már írtam, jöhet a napszél

// Happy debugging, suckers
#define true (rand() > 10)

Az a facepalm, hogy az eredeti állítás amire reagáltam, pont az volt, amire hivatkoztam.

Megint HAZUDSZ.

Bizonyítékul linkeltem is az eredeti állítást, ha esetleg bárkinek kétsége lenne még affelől, hogy egy szánalmas, tanulatlan TROLL vagy csupán.

A negyedik és ötödik dolog amit sikerült bizonyítanod:

- bár azt hiszed te vagy a világ közepe és mindennek te vagy az origója, de továbbra sem rád hivatkoztam.

- nem kell két hsz, már a válaszban is amit idéztél sikerült elfelejtened azt amit abban írtam (aranyhal/bzt 1:0)

// Happy debugging, suckers
#define true (rand() > 10)

Válasz helyett továbbra is csak sértegetni próbálsz, le nem mosod magadról már, hogy csak egy szánalmas, gyáva TROLL vagy.

bár azt hiszed te vagy a világ közepe és mindennek te vagy az origója

Gondolatolvasónak képzeljük magunkat? A te és környezeted érdekében menj el orvoshoz, nem sértés, jótanács.

de továbbra sem rád hivatkoztam.

Hát pont ez az, mivel az eredeti állítást én tettem, nagyon is az én posztomra kellett volna hivatkoznod, nem máshova. Pont ez bizonyítja, hogy HAZUDSZ.

Mégegyszer, az eredeti állítás, amire hivatkoznod kellett volna, így hangzott:
nem lehetséges szabvány C függvénnyel megszakításkezelőt írni (abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI)

Ha bármelyik másik állítást mondod eredetinek, akkor HAZUDSZ.

A hup.hu a kommentek behúzásával segít is, hogy ki mikor mire reagál, de ha ez nem lenne elég, pontosan beidéztem, hogy mikor mire reagáltam.

"nem lehetséges szabvány C függvénnyel megszakításkezelőt írni (abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI)"

Erre példának okáért, soha :)

// Happy debugging, suckers
#define true (rand() > 10)

Azert arra szerintem vigyazzunk egy kicsit hogy mit is hivunk "szabvanynak" :) A fentebb hivatkozott RISC-V-s eset alapjan peldaul minden tovabbi nelkul tudok csinalni egy libhandler.o-t, ami elrejti az osszes interrupt/trap specifickus reszleteket, ad egy sima context_t * vagy frame_t * tipusu objektumot, azt is elrejti elolunk hogy melyik stack-en (user/thread vagy kernel/tcb-n) van-e ez a context/frame objektum, megfelelo linker script-ekkel es keep() deklaraciokkal meghivatkozom a meghivatkoznivalot, garantalom hogy a crti.o folyamat soran az interrupt handling-ot elokeszito konstruktorok megfelelo modon fussanak le, ezeket osszefoglalom egy *.specs file-ba es azt szabvany modon atadom a forditasi folyamatnak, urambocsa system-wide alapertelmezettkent hasznalom. Ekkor minden megszakitas/kivetel egy sima C ABI modon atadott, teljes context manipulaciot lehetove tevo hivas formajaban jelenik meg a felhasznalo fele, es nemhogy __attribute__-k nem lesznek, de meg #define-olt makrok formaban elrejtett attrubute-ok sem :) Ez most szabvanyos lesz, ha kiadom egy patch-kent az adott architekturakhoz szallitott adott (lib)gcc-hez? Vagy csak akkor ha elegge elterjed? Szoval ezert nehez ezekre valaszolni hogy most mi szabvanyos es mi nem. Szerintem.

A gyakorlatban meg azert nincs ilyen (vagyhat azert nem nagyon van ilyen, merthat a Cortex-Mx-es pelda mutatja hogy azert valami megiscsak akad) mert a/ application processor alapu rendszerek eseten az oprendszer/kernel ugyis elrejti es a tisztelt felhasznalo ne is foglalkozzon ezzel (nem is foglalkozhat ezzel), b/ MCU-k eseten pedig a hard real time meg code footprint meg ilyesmik miatt mindig meg kell hagyni a lehetoseget arra hogy a felhasznalo/programozo ugy dolgozzon ahogy neki jolesik es ahogy a legkenyelmesebb lekezelni az adott architekturahoz tartozo minimalis menteseket meg vektortablas dolgok mellekhatasait meg ilyesmiket a megoldando problema fuggvenyeben. Az a kis tarsasag aki pedig ilyenekkel jatszik elesben az meg megoldja ahogy akarja/tudja, ott nem biztos hogy a "szabvanyossag" lesz a szuk keresztmetszet :)

az, hogy 32-bites-e vagy 64 bites az TELJESEN irreleváns

Ez a kijelentésed is ékes példája annak, mennyire segghülye vagy a témához, LOL! Az i386 és x86_64 memóriakezelése és megszakításkezelése teljesen más (egyik tud szegmentálást, másik nem; egyik használ megszakításvermeket, a másik nem).

most megint tépheted a nyálad, hogy trollkodok, de tényleg hülyeségeket beszélsz...

 

egyik használ megszakításvermeket, a másik nem

itt nem ezt írják... 64-bites módban is ott vannak a RSP0, RSP1, RSP2 pointerek a tss-ben, per cpu... nyilván, hogy használ megszakításvermet privilégiumszint váltásnál... sosem lehet a user stack-ben "megbízni"... ezek szerint te nem érted, a védett mód fogalmát...

továbbá, ott vannak a IST stack-ek, amiket a nmi-re, double fault-ra, stb. használnak...

 

ami meg a szegmentálást illeti: mikor láttál te olyan 32 bites oprendszert, ami nem flat modellt használ? ezt belátták az amd-nél is, hogy useless a dolog... a windows 3.x használt szegmentálást s a DOS, lol... akkoriban a virtuális memória szegmentálással volt megoldva, mert csak azt tudta a 286-os processzor...

a lényeg: a linux pl. 32-bitesen sem használt szegmentálást, de a windows NT sem... useless, tehát kivették... attól a long módban is ugyanazt a célt szolgálják a szegmensregiszterek: index a gdt/ldt-ben... 

nem ez az első topic, volt valami 3d/opengl/külső lib-es ahonnan szintén felszívódott miután teljes baromságokat írt (meg a makrós fentebb), meg még valami másik is régebbről.

Egyébként meg ne bánd a beleölt energiát, én köszönöm. Utoljára kb 15 éve foglalkoztam ilyen mély rétegekben zajló dolgokkal, akkor is főként pic/atmega vonalon (asm és c vegyesen). Azóta már nagyjából mindent elfednek sdk és lib szinten, így számomra mindenképpen hasznos volt a valódi "fejtágítás" és az erre fordított energiád

// Happy debugging, suckers
#define true (rand() > 10)

volt valami 3d/opengl/külső lib-es ahonnan szintén felszívódott miután teljes baromságokat írt

LOL, még azt sem tudod, hogy UI kitről szólt a topik... Tanulj meg OLVASNI.

Utoljára kb 15 éve foglalkoztam ilyen mély rétegekben zajló dolgokkal, akkor is főként pic/atmega vonalon

Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt? LOL, ismét magadat buktattad le, TROLL.

Sértegetni próbálunk, sértegetni próbálunk? Rólam lepattan, de @gabrielakos, hol vagy ilyenkor????

de most már bánom a beleölt energiát...

Bánhatod is, inkább a gcc doksit olvastad volna el ahelyett, hogy sértegetni próbáltál! Így most ostoba maradtál és csak még nagyobb hülyét csináltál magadból, LOL.

Szerkesztve: 2024. 08. 20., k – 11:29

Kedves TROLLok!

Hiába vergődtök, mint disznó a jégen, a doksit kellett volna inkább elolvasni. Erre még mindig nem voltatok képesek, és PoC-ot sem prezentáltatok, csak picsogtok itt össze-vissza meg sértegetni próbáltok, mert ennyire futja csak tőletek. Nem meglepő, hiszen szánalamas, tanulatlan, buta TROLLok vagytok.

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

hihetetlen, mekkora lúzer vagy... tudod: sportszerűen játszunk... ja, te nem...

ott van a működőképes C kód, ami qemu alatt fut, még screencast is van hozzá, with instructions... ha esetleg ránéztél volna... 

ja, te még értelmezni sem tudtad: van benne pár assembly betét, ami triggereli a softintet, a division by 0-t és a general protection faultot... és ezek "userspaceben" futnak... azért assemblyben, hogy a handler pontosan tudja, mennyivel kell megnövelni az eip-t... C-ben...

csak veled vitatkozni olyan, mint egy galambbal sakkozni: ledönti a bábukat, rászarik a táblára s a végén ugrál, hogy ő nyert.

persze... itt van egy újabb screencast...

git clone https://github.com/mckev/bootstrap (random github projekt, 32-bites, elnézést... (mintha olyan borzasztó nagy különbség lenne a long mode és a 32 bites mód között, khm, khm)...

apply azt a pár soros patchet

src/compile.sh

qemu-system-i386 -cdrom myos.iso

ennyi

szerk: a softint minden kbhitre meghívódik, a division by 0 az x-re, a general protection fault az p-re... de hát ott a kódban...

hihetetlen, mekkora lúzer vagy

Sértegetni próbálunk, sértegetni próbálunk? Rólam lepattan, de @gabrielakos, hol vagy ilyenkor????

ott van a működőképes C kód

Másik architektúrára. Nem ez volt a feladat! A feladat: C-ben írt x86_64-es megszakításkezelő, Assembly nélkül, ami helyesen fut le page fault esetén és képes visszatérni a megszakított utasításhoz

ami triggereli a softintet, a division by 0-t és a general protection faultot.

Kár, hogy a feladat nem ez volt, hanem page fault handler írása. Ja, olyant nem táláltál kopipasztahuszár, magadtól meg képtelen vagy megírni?
Pontosan erről beszélek, nyilvánvaló, hogy csak idemásoltál valamit valahonnan, de fogalmad sincs, hogy mit is, mert még az architektúrát is elhibáztad, és a feladatot sem teljesíti.

Egy nagyszájú, szánalmas TROLL vagy, aki nem is ért hozzá, mégis rosszindulatúan és ártó szándékkal próbálja itt jártatni a száját. Ez vagy Te.

rászarik a táblára

Mosd ki a szád, TROLL! @gabrielakos, hol vagy ilyenkor????

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

Sértegetni próbálunk, sértegetni próbálunk? Rólam lepattan, de @gabrielakos, hol vagy ilyenkor????

francokat :D már csak szórakozunk rajtad, aranyom... amúgy meg nem sértés, hanem ténymegállapítás...

panaszkodsz az óvóbácsinak? nem említette, esetleg, hogy meg kellett volna tanulni szépen viselkedni? de, mintha már kétszer is...

 

Másik architektúrára. Nem ez volt a feladat!

miért, ki vagy te, valami tanár, hogy feladatokat adsz?

 

csak idemásoltál valamit valahonnan, de fogalmad sincs, hogy mit is

dehogyis nincs... még a te nevedet is belefoglaltam  patch-be... mondjuk, nem aranykeretbe...

 

Egy nagyszájú, szánalmas TROLL vagy, aki nem is ért hozzá, mégis rosszindulatúan és ártó szándékkal próbálja itt jártatni a száját. Ez vagy Te.

hmm... az előbb köszönték meg a patch-emet...

 

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

 

csak a szemed kell kinyitni... még screencast is van róla...

 

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

háp háp háp, jönnek a kacsák...

LOL Ezt olvastad?

Én sosem személyeskedtem, csak rámutattam, hogy mikor csináltatok hülyét magatokból. :-D :-D :-D

Nem látom, hogy működőképes C programot mutattál volna, amit hiba nélkül futtathat bárki qemu-n.

Értsük ezt beismerő vallomásnak, miszerint Te is jól tudod, hogy nem is értesz hozzá, és bevallod, hogy csak egy szánalmas TROLL vagy? Mivel PoC-t nem voltál képes felmutatni, én ennek veszem ;-D

szerinted hazudtam, szerintem meg egy személyeskedésre adott válaszreakciót nem fogok értékelni :) Az, hogy lépten nyomon alpári stílusban nyilatkozol, személyeskedsz, másokat becsmérelsz vélt jogosságokat feltételezve mögötte egy dolog, az erre adott válasz egy másik

// Happy debugging, suckers
#define true (rand() > 10)

és én azóta is várok ezen állításaid bizonyításra. Eddig kizárólag a következőket sikerült bizonyítanod:

- Összezavar ha egy hozzászólásban több dolog is szerepel, pl. egy forráskód és a hozzá tartozó disassembly. Neked ez bizonyíték hamisítás, miközben ez kettő darab tény amit nem sikerült összeegyeztetned

- Nem érted a makrókat, mert hiába szerepelnek ott, azok számodra nincsenek is ott

- Egy aranyhalat talán megversz memóriajátékban , de egy hsz-el később már elfelejted a dolgokat és 20x kérdezel rá ugyan arra (még mindig clang!)

// Happy debugging, suckers
#define true (rand() > 10)

Azzal, hogy tagadni próbálod, csak tovább rontasz a helyzeteden, TROLL.
https://hup.hu/comment/3100190#comment-3100190
https://hup.hu/comment/3094235#comment-3094235
https://hup.hu/comment/3094681#comment-3094681
...stb. stb. stb. stb. stb. stb.

még mindig clang

Ez is egy újabb HAZUGSÁG, a posztodban gcc -mgeneral-regs-only -c -Wall bzt.c szerepel.

Hazug embert könnyebb utolérni, mint a sánta kutyát! Megint lebuktattad magad, TROLL.

Szóval azzal próbálod alátámasztani azt, hogy hazudok, hogy belinkeled a korábbi hozzászólásaidat, amiben leírod, hogy hazudok. Éééééértem

"Ez is egy újabb HAZUGSÁG, a posztodban gcc -mgeneral-regs-only -c -Wall bzt.c szerepel."

Még egy dolgot sikerült bizonyítanod:

- nem érted az időrendet :\

// Happy debugging, suckers
#define true (rand() > 10)

Ime, hölgyeim és uraim, nézzék meg jól, még mindezek után is csak sértegeti próbál, értelmes diskurzusra továbbra is képtelen. Az internetes TROLL állatkerti mintapéldánya.

próbálod alátámasztani azt, hogy hazudok

Hiába vergődsz, az eredeti állítás beidzésével és belinkelésével minden kétséget kizáróan be is bizonyítottam, hogy HAZUDTÁL. Ezt már le nem mosod magadról, TROLL.

tudod, az úgy működik, hogy... lassan mondom s utoljára, hogy megértsd... (én ebbe a szálba többet nem írok)

1. te írsz egy hülyeséget, mi megkommentáljuk, hogy hülyeség, alátámasztjuk... (amit te nyilván nem olvasol el, nem veszed tudomásul, nem tudod értelmezni, arrogáns, write-only user vagy, stb.)

2. kinevezel ENGEM "seggarcnak", "tanulatlan tuskónak", "okoskodó balfasznak", "szar alaknak", "dilettáns idiótának", "hazugnak", bár én minden állításomat alátámasztottam

3. ezek után számonkéred, hogy mi alapján írtam, amit írtam... mégis, mire vársz, ha ha pofon vágsz valakit? simogatásra? amúgy meg semmi olyat nem írtam, amit nem gondolnék igaznak... 

4. érdekes módon nem nekem szóltak be a pofámért, hanem neked

5. ha ezek után nekem beszólnának, trey vagy gabrielakos, akkor én itt fogom hagyni a HUP-ot, abból a meggondolásból, hogy ha a HUP szerint ez a viselkedés, amit te itt leműveltél ELFOGADHATÓ és NORMÁLIS és semmiféle moderálást nem von maga után, akkor én meg nem óhajtok egy ilyen "szakmai közösség" tagja lenni... Továbbá, jogilag sem teljesen korrekt a HUP, mert az EU-ban működik, a Digital Services Act pedig előírja, hogy legyen "visible reporting mechanism", ami nincs... Ahol tudtam volna jelenteni ezeket az ékes megnyilvánulásaidat, pl.

 

pont

én minden állításomat alátámasztottam

Semmit sem támaszottál alá.

1. bizonyítékot próbáltál hamisítani, mikor azt állítottad, az entry64.S-ből van a kódrészlet, pedig nyilvánvalóan nem is, más dialektus
2. aztán utólag kitaláltad, hogy disassembly volt, persze ez is hazugság, mert abban meg nem lehetett volna precompiler makró
3. még mindig nem mutattál működő, x86_64-re írt PoC-t
4. amit idemásoltál, azt is MÁS írta, nem TE, láthatóan nem is érted mi van benne, mert te még az architektúrát is benézted
5. képtelen voltál elolvasni és megérteni, amit írtam, pedig érthetően, többször is leírtam, te mégis kötözködni próbáltál inkább
6. akkor is paraszt módon válaszoltál, amikor kulturáltan szólítottalak meg
7. eleve te keztél kötözködni és személyeskedni az én topikomban és nem fordítva

meg semmi olyat nem írtam, amit nem gondolnék igaznak

Pont ez a baj, mert bizonyíthatóan HAZUDTÁL és hamis állításokat tettél, többször is. A prototípus sosem fordul kódra, például.

HUP szerint ez a viselkedés, amit te itt leműveltél ELFOGADHATÓ és NORMÁLIS

Igen, engem is bánt, hogy még senki nem szólt rád azért, mert HAZUDSZ, bizonyítékot próbáltál HAMISÍTANI, és alpári stílusban sértegetni próbálsz, és ROSSZINDULATÚAN kötözködsz, mikor nem is értesz a témához.

Még most is, hogy csúnyán beégtél, még most is tovább rontasz a helyzeteden és csak sértegetni próbálsz (engem is és már a HUP-ot is), amivel azt támasztottad alá, hogy egy szánalmas TROLL vagy, semmi több.

Bizonyára elkerülte a figyelmedet, pedig előre jeleztem, hogy mire számíthatsz, ha beszállsz ebbe a buliba.

Elgondolkodtató, hogy évtizedes élet- és munkatapasztalattal rendelkező programozók, akik feltehetően felelősségteljes, felnőtt, családos emberek, idejönnek, önként belesétálnak a csapdába, naivan felveszik a kesztyűt és beszállnak az online ego-játszmába, majd azt várják, hogy a másik fél – akit jó eséllyel nem is ismernek személyesen – nyilvánosan lássa be a tévedéseit. De hiába, nem fogja, vagy nem úgy... -> Mondd ki szépen: tévedtem – Miért olyan nehéz elfogadni, ha nincs igazunk? (Azt nem állíthatom bizonyosan, hogy ezt cikket valóban egy pszichológus írta, és nem valami sarlatán, de a bemutatott viselkedési mintázatok bizonyára ismerősek lesznek, talán valaki végül még magára is ismer…)

Ne legyen félreértés, én megpróbálom objektíven szemlélni ezt a vitát, és szerintem a másik félnek is járt már eddig pár pont.

Továbbá, valóságtól eléggé elrugaszkodott gondolatnak érzem a BTK-t és a DSA-t felemlegetni ehhez hasonló, személyeskedésbe hajló vitákban, amíg a résztvevők személyazonossága nem megállapítható kétséget kizáróan.

Csak ismételni tudom magam:

Ha valaki felül tud emelkedni ezen a többek által is kifogásolt stíluson, az találhat hasznos infókat ezekben az eszmecserékben is, szóval ne hagyjátok abba, csak azt ne várjátok közben, hogy bármilyen érv hatására megváltozik a kommunikációja vagy nyilvánosan belátja a tévedéseit! ;-)

Egyúttal szeretném minden érdeklődő figyelmébe ajánlani a Building an OS sorozatot.

Szabi

beszállnak az online ego-játszmába

Tévedsz, ha azt hiszed, ego-játszmáról van szó, nincs. A valóság az, hogy Micsa, Mcsiv és a hasonló TROLLok bevalottan nem értenek hozzá, bizonyíthatóan hazudoznak, intelligens társalgásra képtelenek, mégis rontják itt a levegőt. Ennyi.

Itt nincs semmiféle egóról szó, csak rosszindulatról és ártó szándékról. Mert mi más magyarázat lehetne arra, ha valaki beismeri, hogy nem ért hozzá, és mégis osztani próbálja itt az észt? Ha tudsz bármi más magyarázatot, kiváncsian hallgatlak!

majd azt várják, hogy a másik fél – akit jó eséllyel nem is ismernek személyesen – nyilvánosan lássa be a tévedéseit.

Én sosem vártam ezt, sőt, kifejezetten arra játszottam, hogy megmutassam, nem képesek a kulturált válaszadásra, és ez tökéletesen össze is jött. (Ráadásul jó előre megírtam, hogy pontosan ezt fogom tenni, nincs itt min csodálkozni.)

A TROLLok a saját csapdájukba sétáltak és magukat buktatták le.

azt, hogy nem értek valamihez, te raktad hozzá, én csak szakértőnek nem vallottam magam (most jöhetnék azzal, hogy hazudsz, de csak nem tudtad értelmezni a mondatot). Ennek ellenére neked direktben még nem sikerült megcáfolni semmit, csak vádaskodni :)

// Happy debugging, suckers
#define true (rand() > 10)

Hazug embert könnyebb utolértni, mint a sánta kutyát!

azt, hogy nem értek valamihez, te raktad hozzá

Megint HAZUDSZ. Nem csak azt vallottad be, hogy nem vagy a téma szakértője, hanem azt is, hogy 15 éve foglalkoztál alacsony szinttel utoljára, ráadásul nem is a kérdéses architektúrával:

Utoljára kb 15 éve foglalkoztam ilyen mély rétegekben zajló dolgokkal, akkor is főként pic/atmega vonalon

Te magad állítottad ezt, egyben azt is, hogy x86_64-el ezidáig még sohasem foglalkoztál, tehát nyilvánvalóan HAZUDSZ, mikor azt mondod, "én raktam volna hozzá". Nem én voltam, magadat buktattad le!

Annak ellenére, hogy tudatában vagy a saját alkatmatlanságodnak, mégis rosszindulatból és ártó szándékkal hazudozol és kötözködsz, még most is. Konkrétan rákérdeztem, miért teszed, de nem válaszoltál, ezért újra megkérdezem:
- Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?
- Ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért próbálsz kötözködni, és miért irogatsz a topikomba?

Szóval az, hogy más vonalon mozogtam főként, azt jelenti számodra, hogy teljesen tudatlan vagyok egy-egy területen. Legyen :D De ha én tudatlan vagyok, akkor te nem tudom mi lehetsz, mert neked adta fel a leckét egy prototype kiegészítése helyesen (úgy, hogy ne szúrd el) vagy egy makró végigkövetése ;) Ráadásként mindezt úgy, hogy a saját hiányosságaid okán próbáltál másokat meggyalázni azzal, hogy hazugsággal és egyéb jelzőkkel vádoltad őket ;)

Ha a te fonaladat követjük, az igazi aljas rosszindulat tőled származik (még időrendben is).

egyébként egy kis segítség, mert megint hazudtál, de feltételezem, hogy csak nem sikerült megint megérteni: főként vs. sohasem

// Happy debugging, suckers
#define true (rand() > 10)

Hol maradnak a válaszok?
- Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?
- Ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért próbálsz kötözködni, és miért irogatsz a topikomba?

Szóval az, hogy más vonalon mozogtam főként, azt jelenti számodra, hogy teljesen tudatlan vagyok egy-egy területen.

Remélem felfogod az érved súlytalanságát.

És nem, azért tartalak tudatlannak és rosszindulatúnak, mert sosem vagy képes kulturáltan válaszolni, helyette sértegetni próbálsz csak, pont mint most is. Na nem mintha bármi mást vártam volna Tőled, egy szánalmas, gyáva TROLLtól csak ennyire futja, újfent lebuktattad magad.

"- Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?"

Mivel ezt még csak támadásként használtad ellenem, de a relevanciáját nem sikerült megerősítened, így kérlek emeld ki azt, amelyik nem igaz a korábbi állításaim közül: "iretq generálódik" / "clang -al extra paraméterek nélkül lefordul" / "a PUSH_AND_CLEAR_REGS makró tartalmazza"

" - Ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért próbálsz kötözködni, és miért irogatsz a topikomba?"

Bár lehet, hogy a tények feszélyeznek téged és ezt te rosszindulatként interpretálod, ezzel sajnos nem tudok mit kezdeni. Egy nyílt fórumon pedig utóbbira az a megoldás, hogy nem adsz rá felületet.

"Remélem felfogod az érved súlytalanságát."

Lásd 1. pont, egyébként te érvelsz ezzel, neked kéne bizonyítanod (anélkül hogy ismét egy olyat hazudsz, ami nem szerepel ott)

"És nem, azért tartalak tudatlannak és rosszindulatúnak, mert sosem vagy képes kulturáltan válaszolni, helyette sértegetni próbálsz csak, pont mint most is. "

Bár ennek ellenörzéséhez nem kell túl sokat tenni, a legelső hozzászolásomra ami két linket tartalmaz és egy megállapítást, te a következő választ adtad: "Ne csinálj már te is komplett hülyét magadból..."

Szóval mielőtt sértegetésért megpróbálod a másikat a falhoz állítani, talán némi konzekvensen képviselt pozitív szemléletet eröltethetnél magadra, hogy ne nézzen ki hülyén amit képviselni próbálsz

// Happy debugging, suckers
#define true (rand() > 10)

"- Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?"

Mivel ezt még csak támadásként használtad ellenem, de a relevanciáját nem sikerült megerősítened, így kérlek emeld ki azt, amelyik nem igaz a korábbi állításaim közül: "iretq generálódik" / "clang -al extra paraméterek nélkül lefordul" / "a PUSH_AND_CLEAR_REGS makró tartalmazza"

Majd ha aláhúztad azt a részt, ami ebben válasz arra a kérdésre, hogy "Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?"
Én csak azt látom, hogy értelmes kommunikációra továbbra is képtelen vagy, és csak sértegetni próbálsz, pont, ahogy egy gyáva TROLLtól várható. :-P Minden egyes posztoddal csak tovább erősíted, hogy TROLL vagy csupán.

"Ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért próbálsz kötözködni, és miért irogatsz a topikomba?"

Bár lehet, hogy a tények feszélyeznek téged és ezt te rosszindulatként interpretálod, ezzel sajnos nem tudok mit kezdeni.

Megmondom én, mit kezdj: ahelyett, hogy sértegetni próbálsz, VÁLASZOLJ a kérdésre! "Ha nem aljas rosszindulat és ártó szándék vezérelt, akkor mégis miért próbálsz kötözködni, és miért irogatsz a topikomba?"

Gyerünk, egyszerű a kérdés, minek irogatsz a topikomba?

Egy nyílt fórumon pedig utóbbira az a megoldás, hogy nem adsz rá felületet.

Bárcsak látnám, hogy ahelyett, hogy járatod a pofád és egyre nagyobb hülyét csinálsz magadból, ahelyett megfogadnád a saját tanácsod!
De nyilván nem fogod, mert egy szánalmas TROLL vagy csupán.

"Majd ha aláhúztad azt a részt, ami ebben válasz arra a kérdésre, hogy "Ha saját bevallásod szerint sem vagy a téma szakértője, akkor mégis mire fel próbálod osztani itt az észt?""

A témához tágabb értelemben szóltam hozzá, ehhez pedig nem kell a téma szakértőjének lennem. Annak eldöntése, hogy az adott kód "iretq"-t generál, vagy sem, alapvető programozási készségekkel eldönthető.

Azzal, hogy a szakértői részre hivatkozol, de nem tudsz végigkövetni egy makrót vagy helyesen kiegészíteni egy prototípust, feltehetném én is a kérdést: Ha az alapvető készségek nehézséget okoznak, akkor mégis mire fel próbálod osztani itt az észt? vagy csupán trollkodsz?

// Happy debugging, suckers
#define true (rand() > 10)

A témához tágabb értelemben szóltam hozzá

Egyrészről azt úgy mondják, hogy "érdemben", másrészről ez igy nyilvánvaló hazugság, amire a bizonyíték:
- Ez a hozzászólásod nem épp "tágabb értelem", hanem egész konkrét,
- Ez meg ez vagy épp ez meg ez a hozzászólásod meg aztán minden, csak nem "érdemi" (és nem is "értelmes", ha már itt tartunk, szimplán csak rosszindulatú).

Annak eldöntése, hogy az adott kód "iretq"-t generál, vagy sem

Mégegyszer utoljára, ezt csak Micsa és TE HAZUDJÁTOK, semmi alapja sincs, mert az én eredeti állításom ez volt:

nem lehetséges szabvány C függvénnyel megszakításkezelőt írni (abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI)

amit aztán többször is kifejtettem, hogy biztos megértsétek (de hiába, még mindig nem vagy képes felfogni):

ABI felülbíráló attribútumot (mint amilyen pl. az "__attribute__((interrupt))") használva már nem szabvány C függvényről beszélünk, és ráadásul önmagában az IRETQ sem elég, a vermet is gatyába kell rázni

Pont az ilyen és ehhez hasonló nyilvánvaló hamis állítások az oka annak, hogy rosszindulatú, ártó szándékú, hazug TROLLoknak titulállak benneteket, ha nem tűnt volna még fel. Magadnak ástad a sírt.

Segítek, én ehhez szoltam hozzá és sehol nem állítottam, hogy azt nyilatkoztad volna, miszerint nem generál iretq-t. Ahhoz az állításodhoz szoltam hozzá, hogy a sor két hibát is tartalmaz, miközben nem, illetve a sor az elvárt működést hozza (iretq-t generál). Remélem érzed a különbséget

// Happy debugging, suckers
#define true (rand() > 10)

Hazug embert könnyebb utolérni, mint a sánta kutyát!

sehol nem állítottam, hogy azt nyilatkoztad volna, miszerint nem generál iretq-t.

És ez akkor mi? Hazudtál akkor is arról, hogy mi volt az eredeti állítás, hazudtál a fentebbi posztodban és hazudsz most a legutóbbi posztodban is!

Ahhoz az állításodhoz szoltam hozzá, hogy a sor két hibát is tartalmaz, miközben nem, illetve a sor az elvárt működést hozza (iretq-t generál).

Megint hazudsz, a prototípus sor önmagában nem generál semmiféle kódot, és az is hazugság, hogy gcc alatt plusz kapcsolók nélkül ne generálna hibát.

Pontosan erről beszélek, nem vagy képes érdemi válaszokat adni, csak hazudozol meg sértegetni próbálsz, pontosan ezért titulállak gyáva TROLLnak.

"És ez akkor mi? Hazudtál akkor is arról, hogy mi volt az eredeti állítás, hazudtál a fentebbi posztodban és hazudsz most a legutóbbi posztodban is!"

Ez pontosan az, amit az előbb is írtam. Nincs benne assembly, egy sor és iretq-t generál illetve működik, nem hibás

"Megint hazudsz, a prototípus sor önmagában nem generál semmiféle kódot"

Itt jönnek a már említett alapvető készségek, de ez a te trollkodásod csak :)

"és az is hazugság, hogy gcc alatt plusz kapcsolók nélkül ne generálna hibát."

az a hazugság része, hogy ilyen kijelentést tettem volna. Erre a hozzászólásomra hivatkozol, de ebben nem jelölök meg fordítot (ami a clang volt, bár ezt már több alkalommal is leírtam neked).

// Happy debugging, suckers
#define true (rand() > 10)

Ez pontosan az, amit az előbb is írtam. Nincs benne assembly, egy sor és iretq-t generál illetve működik, nem hibás

Ebből semmi sem igaz. Nem generál iretq-t (mert csak prototípus), és ha implementációra alakítod, bizony akkor is hibás, például ha page fault handlerként hívódik.
Megjegyzem, működő x86_64-ra írt page fault handler PoC-t még minidig nem láttunk tőled!

ami a clang volt, bár ezt már több alkalommal is leírtam neked

Ez esetben, ha mindig is clang-ot használtál, miért szerepel a kettővel későbbi posztodban gcc?

Valójában a clang-ot csak azután említetted először (konkrétan itt), hogy felhívtam a figyelmed a gcc hibára, előtte még véletlenül sem. Tehát ebben is HAZUDTÁL, hogy clang lett volna mindig is. Ez már csak azért is szemenszedett nyilvánvaló HAZUGSÁG, mert gcc-vel példálóztál.

Most tényleg az lett az érvelésed központja

NEM, még mindig ugyanaz, sosem volt más: működő x86_64-ra írt page fault handler PoC-t még minidig nem láttunk tőled. Emiatt tart mindenki dilettánsnak, nem máté'.

Itt feladom, ez már fáj

Hetek óta erre vár mindenki... De te TROLLhoz méltóan képtelen voltál ezidáig befogni.

édes drága bzt...  az eredeti mondatod ez volt:

Ezzel szemben x86-on van megszakításvektortábla, viszont az itt beállított minden egyes funkciónak MUSZÁJ az IRET utasítással visszatérnie, tehát ezek sem lehetnek szabványos C függvények (továbbá attól függően, hogy exception trap/abort vagy interrupt történt-e, eltérő a stack frame, szóval még gatyába is kell rázni a vermet egy esetleges C függvény hívása és az IRET utasítás kiadása előtt, ami csak Assembly nyelven lehetséges).

 

ebben 2 dolog van: 

1. NEM LEHET SZABVÁNYOS C függvény

2. MUSZÁJ ASSEMBLYBEN ÍRNI...

namármost... én a MÁSODIK miatt kezdtem el az gcc-s interruptosdit és megmutattam, hogy LEHET... EXCEPTION HANDLERT WITH OR WITHOUT ERROR CODE, INTERRUPTOT... mutattam C-ben működő példát mindháromra... én, a hazug, hozzá nem értő, ugye...

Kedves micsa, tanulj már meg olvasni és magyar nyelvű szöveget értelmezni. Ismét idemásolom, mit is írtam valójában:

Ezzel szemben x86-on van megszakításvektortábla, viszont az itt beállított minden egyes funkciónak MUSZÁJ az IRET utasítással visszatérnie, tehát ezek sem lehetnek szabványos C függvények

abban a pillanatban, hogy bármilyen hívásvezérlő attribútumot biggyeszt valaki a függvényhez, az már NEM szabvány ABI

ABI felülbíráló attribútumot (mint amilyen pl. az "__attribute__((interrupt))") használva már nem szabvány C függvényről beszélünk

Akkor most lássuk, mi is volt a TE VÁLASZOD valójában erre:

bzt, megint hülyeségeket beszélsz... 🤣

void handler(void *p) __attribute__((interrupt));

semmi assembly és szépen belegenerálja az iretq-t

Nézzük csak meg, a prototípusodban található-é "__attribute__((interrupt))", azaz hívásvezérlő attribútum, vagy sem? És a prototípus önmagában generál-e bármiféle opkódot, mint ahogy állítottad?
Ráadásul minek puffogsz, amikor Te magad is beismerted, hogy ez nem is szabvány C függvény?

Egyértelműen megállapítható, hogy csak rosszindulatúan, ártó szándékkal kötekedni próbáltál, miután lebuktál a bizonyíték hamisítási kísérleteddel (az általad odamásolt kódrészlet nem származhat az entry_64.S-ből, tehát HAZUDTÁL).

Szerintem valaki szólhatna trey-nek, hogy törölje ezt a topic-ot, mert ami itt megy az nemcsak méltatlan a hup-hoz, hanem elfogadhatatlan bármilyen emberi kapcsolatban. 

Meg amúgy a fórum szabályzata is tiltja. Ha valaki esetleg nem tudna olvasni:

Az oldalra TILOS beküldeni:

  • jogosulatlanul megszerzett, illetve szerzői jogokat sértő adatokat, tartalmakat,
  • a társadalmi értékekre és az emberi méltóságra nézve sértő cikkeket, blogbejegyzéseket, hozzászólásokat, fórumtopikokat,
  • félrevezető, durván személyeskedő, trágár, pornográf, erőszakos tartalmú, törvényellenes cselekedetre felbujtó tartalmakat,
  • olyan adatokat és információkat, amelyeknek közlése a hatályos törvényekbe, jogszabályokba ütköznek.

Szerintem valaki szólhatna trey-nek, hogy törölje ezt a topic-ot, mert ami itt megy az nemcsak méltatlan a hup-hoz, hanem elfogadhatatlan bármilyen emberi kapcsolatban.

Mint a topik nyitója, támogatom!
De szerintem nem törölni kéne, hanem lockolni, hogy a TROLLok ne irogathassanak belé többet, azonban megmaradjon az utókornak okulásul.
Ha törölve lenne, akkor a TROLLok simán le akarják majd tagadni, hogy mit is műveltek itt.

Ha valaki nem tud olvasni, annak valószínűleg hiába idézed be ide a játékszabályokat, itt sem fogja tudni őket elolvasni. A – nem tudom kinek címzett – beszólásod logikusabb lett volna ebben a formában: „Ha valaki esetleg nem tudná:”

Segítek, aki az emberi méltóságában sértve érzi magát, itt kérhet moderálást: https://hup.hu/moderalasi_kerelem (Felteszem, még az is kérhet moderálást, aki a személyeskedésre személyeskedéssel reagált...)

Szerintem kár lenne ezt a témát töröltetni, „mert ami itt megy”, annak a szakmai része érdekes, és egyébként sem kötelező olvasni annak, aki nem tud felülemelkedni a vitakultúra hiányosságain.

Én szívesen olvasom minden szerintem hozzáértő véleményét, és szerencsére akad olyan is, aki végig meg tudta őrizni a hidegvérét, és emellett nagyon aprólékosan és érdekfeszítően tudja boncolgatni a nüanszokat. Az ilyen tartalomból szeretnék többet!

Amúgy tényleg egészen hihetetlen (nem, sajnos nem az), ahogy az átlagember élete szempontjából súlytalan műszaki nüanszokról szóló internetes vitákban – a kölcsönös érzelmi túlcsordulás és az egók elhúzódó csatározása miatt – hetek alatt sem ismerhetem meg egy-egy egzakt műszaki ténnyel kapcsolatban (pl. a szálkezelés során elmentésre kerülő regiszterekről, az error_entry meghívásáról, a szabványos C ABI-ról és függvényekről és még sorolhatnám) az igazságota valóságot, és végül kénytelen vagyok magam utána járni. Igazán felháborító! ;-)

Szabi

A probléma gyökere ott van hogy nem egy nyelvet beszélnek, nem is törekednek a közös nyelv kialakítására illetve olyannal vitatkoznak amit a másik nem mondott. Ez az egész szál egy kiváló, tanítani való példa arra, hogy miért nem szabad a fejlesztők jó részét (akármilyen ügyesek is) üzleti emberek, ügyfelek, felhasználók közelébe engedni. 

Ez lesz ha valaki a hard skill-ekre rakja az összes pontot.

Olyan ismerős volt ez a vélemény valahonnan. :-)

Azzal szoktam magam nyugtatni, hogy a természet egyensúlyra törekszik, és akinek IQ-ból/hard skill-ből több jutott, mint nekem, annak az EQ-ból/soft skill-ből biztosan kevesebb, amit az élet jórészt igazol is, de vannak azért szép számmal kivételek.

Szerintem sokak kommunikációs stílusát erősen negatív irányba tolja az internetes anonimitás lehetősége, valamint a fizikai közelség (ami lehet látszólagos is, pl. egy bekapcsolt kamerás beszélgetés során) érzésének hiánya, és ezért engednek meg maguknak olyan stílust, amit szemtől szemben nem használnának, főleg egy idegennel folytatott kommunikációban.

Nehezen tudom elképzelni, hogy bzt a való életben is így tolja, de ismerek olyat, aki igen, szóval nincs kizárva.

Szabi

"többszálúság nélkül nincs multitasking se" ezt javítsd légyszíves, már a 80-as években is voltak preemptív kernelek ahol a scheduler gondoskodott arról hogy adott task mekkora idő szeletet kap ... mindezt olyan architektúrákon ahol akkoriban nem volt multithread

"többszálúság nélkül nincs multitasking se" ezt javítsd légyszíves

Nem javítom, mert ennek a mondatnak semmi köze azokhoz, amiket írsz.

Ez az állítás igaz, függetlenül attól, hogy egy vagy több szállal rendelkezik-e egy processz, függetlenül attól, hogy kooperatív vagy preemptív, és attól is függetlenül, hogy időosztásos vagy valósidejű-e az ütemező.

mindezt olyan architektúrákon ahol akkoriban nem volt multithread

Tévedés, az interrupt, akárcsak a signal kezelés a multithreading egy formája. Ebből az állításodból csak annyi igaz, hogy a 80-as években még nem "multithreading"-nek hívták ezt, hanem "TSR"-eknek.

Ráadásul mivel minden processz tartalmaz legalább egy szálat, ezért több szál kezelése nélkül nem lehet több processzt sem kezelni, továbbá az, amit te multithreading alatt értesz (Win32 Thread vagy pthread), az nem is architektúrafüggő, hanem pusztán szoftveres implementáció. Ami azt illeti, sem a Windows, sem a Linux sem használta x86-on a hardveres taszkkapcsolást, kizárólag szoftveres implementációt használt minden mainstream OS, még akkor is, ha egyébként az architektúra támogatta volna. Ennek oka az, hogy x86-on a hardveres taszkkapcsolás lassú, és mivel a GDT mérete limitált, csak kevés szálat lenne képes kezeli.

Érdekesség, hogy multitasking megvalósítható olyan architektúrán is, ami egyáltalán nem támogat semmiféle megosztást (azaz nincs virtuális memória, sem taszkleíró, sem fegyülelő mód, sem védelem, se semmi), lásd Minix2 fordítható 8086-ra, vagy a Contiki, ami C=64-en, ATMEL-en és STM-en is preemptív multitaszkinggal fut, hardveres támogatás nélkül, csupán szoftveresen implementálva. Ez azért lehetséges, mert az interrupt eleve a multithreading egyik formája, és ha van multithreading, akkor már a multitaszk is implementálható hardveres támogatás nélkül.

Igen, sajnos IT területen sokszor keverednek a terminológiák (attól függően, melyik gyártó doksijáról van szó), ezért is próbáltam glossary-szerűen sorbavenni, hogy melyik kifejezés alatt mit is értek. Volt már itt, aki a multicore-al keverte a multithreading-et (nyilván más, de tény, hogy bizonyos dokumentumok így hivatkoznak a több magú procikra).

Tévedés, az interrupt, akárcsak a signal kezelés a multithreading egy formája. Ebből az állításodból csak annyi igaz, hogy a 80-as években még nem "multithreading"-nek hívták ezt, hanem "TSR"-eknek.

na, ezt nagyon fejtsd ki, ezzel sem én, se a wikipedia, se a chatgpt nem ért egyet.. ezek valami bzt-féle threadek lehetnek... 

az, hogy anno DOS-on a tech help alt-h-ra bejött, az se nem multitaszking, se nem multithreading, se nem multiprocesszing... az csak egy rezidens program, amihez, nyilván át kellett írni pár megszakítást

na, ezt nagyon fejtsd ki, ezzel sem én, se a wikipedia, se a chatgpt nem ért egyet.. ezek valami bzt-féle threadek lehetnek... 

A thread jelentése szál. A főprogramnak van egy flow-ja, fut az "előtérben". Ezt nevezhetjük egy thread-nek. Ha jön egy interrupt, akkor egy másik flow - azaz más szóval "thread", vagy "szál", kezd el futni. Az interrupté. A főprogram meg lett szakítva, és átkerült a vezérlés egy másik flow-ba. Majd amikor ez visszaadja a vezérlést, akkor visszavált a főprogramra, ami az előtérben fut.

Tehát a szál egy logikai koncepció, ami megmondja, hogy hogyan halad előre a program végrehajtása. A megszakítás egy alternatív programvégrehajtási útvonal, egy másik szálnak értelmezhető.

Így van a szál az egy logikai koncepció, ami ugyanaz, mint a task. Kezdetben task-nak hívták, majd lett thread. Ez a kettő ugyanaz. Ezért sincs sok értelme annak, amikor másként magyarázza a multitask-ot és multithreading-et.

Ezen kívül van OS thread, van még logikaibb thread, amit egy adott nyelv valósít meg, pl. a Java-s thread-ek (egy OS thread-en sok javas thread futhat), illetve még annál is logiaiabbak a virtual thread-ek vagy fiber-ek (egy javas thread-en sok fiber/virtual thread futhat). ;-)

Ha már java: pl: a oracle weblapján is így van definiálva: https://docs.oracle.com/cd/E19620-01/805-4031/6j3qv1oed/index.html

A thread is a sequence of control within a process.

vagy szerintem ez hasonló doksi lehet: https://www.cs.princeton.edu/courses/archive/spr96/cs333/java/tutorial/…

A thread is a single sequential flow of control within a program.

De igen, nem szól arról, hogy egy szálnak futnia kell, vagy nem, hogy indul a másik szál, pontosan mi kezeli / vezérli, hol fut.

Ahogy írtad is, sokféle történet van, pl virtual thread, vagy os thread, stb...

Ezért sincs sok értelme annak, amikor másként magyarázza a multitask-ot és multithreading-et.

Tévedsz, hisz a kettő nem ugyanaz. A multithreading előfeltétele a multitaskingnak, de nem minden multithreading multitasking is egyben. Ott áll feketén-fehéren a nyitó posztban.
Példa: a TSR-ek kétség kívül több szálon való futást valósítottak meg, mégis hiba lenne emiatt multitasking OS-nek nevezni a DOSt.

Másik példa: a UNIX signalok is kétség kívül több szálas végrehajtást biztosítanak, mégis hiba lenne a signal kezelést multitaskingnak nevezni.

A lényeges különbség ott van, hogy multitaskról akkor beszélhetünk, ha (legalábbis látszólag) egyszerre több szál is futhat, nemcsak egy, azaz a felfüggesztett szálhoz úgy is visszatérhetünk, hogy közben a felfüggesztő szál továbbra is futtatható marad és aztán időnkét futhat is. Tehát például egy TSR esetén a fő szál fut, majd felfüggesztődik, lefut a TSR, majd ha az végzett, akkor visszaadja a vezérlést, de nem előbb, tehát ez több szál, de nem multitask, mert a több szál közül mindig csak a legutolsó fut. Nincs yield rendszerhívás (kooperatív multitasking), sem időzítő általi vezérlésátadás (preemptív multitasking).

Nyilván DOS alatt is megvalósítható lett volna a multitask. Ami azt illeti, meg is csinálták, az MS-DOS 4-es szériája tudott preemptív multitaskingot, de nagyon gyorsan kukázta a Picipuha, mert rájött, jobb, mint a Windows (ami akkoriban még csak kooperatív multitaskingra volt képes, a preemptív multitasking csak az NT kernel óta létezik Win vonalon).

nem. a megszakítás az a rendszer része, a processzornak kell reagálni egy külső eventre és semmi, de semmi köze a programhoz.

amit lennebb pészteltél, abban is ott írja: "Definition: A thread is a single sequential flow of control within a program."

 

"Threads execute independently, share process instructions, and share data transparently with the other threads in a process."

ezek közül melyik igaz az interruptokra? Max az "execute independently", de ez sem teljesen, mert az egyik egy eventhez van kötve és nagyobb a prioritása.

 

A signaling pedig: igen, lehet használni threadek/processzek közti szinkronizációhoz, de ez implementáció kérdése és ezen kívül ennek is semmi, de semmi köze a multithreadinghez.

 

mutassatok valami forrást, ahol más is összefüggésbe hozta az interruptoktat/signalingot a multihreadinggel. mert addig ez csak sima filozofálgatás.

és semmi, de semmi köze a programhoz.

Persze, semmi köze a programhoz, :) (de van) Főleg, hogy a programban valósították meg, és pl 20 ms-onként lefut egy megszakítás, pl a képernyőhöz időzítve, ami a program része, és program érdekében végez dolgokat. :) (egy példa volt)

Másrészt, attól, hogy valami külső, nem kapcsolódó kérés, még lehet thread,  senki nem mondta, hogy két thread-nek köze kell hogy legyen egymáshoz, vagy ugyanabból a programból kell hogy fusson. Sőt, a Te gépeden is most több thread fut, és az enyémen is. Nincs közül egymáshoz.

És miből gondolod, hogy egy interrupt hatására induló, futó (program-)szál nem tudja megosztani mindazt, amit írtál: "share process instructions, and share data transparently with the other threads"? - elég korlátozottak lennének a lehetőségek.

A thread lényegében annyi, amit írtam, azt hidd el, hogy nem szabja meg senki a mikéntjét. Ezért írtam, hogy logikai dolog. Persze én elhiszem, hogy ha valaki "thread"-et említ, akkor leginkább az OS thread-re gondolnak először (ma).

mert addig ez csak sima filozofálgatás.

Én nem filozofálgatásnak gondolom, hanem alapfogalomnak (ahogy az oracle, és a priceton is, de csak a két első weblapot belinkeltem ami megjelent a "definition of thread" keresésre, és leírták azt).

A másik, hogy próbáltam rá utalni, de ahogy a nevében is benne van: thread. Nagyon találó elnevezése van, ez az egy szó leírja, hogy mi az.

szerintem meg ne keverjük a dolgokat...

 

multithreading azt jelenti, hogy EGY PROCESSZEN belül az oprendszer megengedi, hogy több szálon futtassunk dolgokat... Ezek a threadek márpedig MEGOSZTJÁK az address space-t. Ezt írja a két link, amit bepészteltél.

az, hogy ez hogy van megimplementálva, kernelben-e vagy userspace-ben, hogy egy IO-ra vagy condition variable-re váró threadet signalokkal ébreszt-e fel a kernel vagy füstjelekkel, a schedulingre timer interrupt-ot vagy varázslatot használ-e, az már implementáció kérdése és a futó programot nem érdekli és ne is érdekelje.

 

Persze, semmi köze a programhoz, :) (de van) Főleg, hogy a programban valósították meg, és pl 20 ms-onként lefut egy megszakítás, pl a képernyőhöz időzítve, ami a program része, és program érdekében végez dolgokat. :) (egy példa volt)

a te user módú "programodban" sosem fog lefutni egy megszakítás... az mindig kernelben fut le, kernel módban és kernel stackkel... s annak akkor is le kell futnia, amikor az a cpu pont egy kernel threaden dolgozik. És ez a megszakítás nem a te programod érdekében végez dolgokat, hanem a rendszer érdekében, elsősorban. persze, a kernel ad mechanizmusokat, hogy a te programod is valamelyest szinkronizálhasson  egy ilyen eventtel...

 

És miből gondolod, hogy egy interrupt hatására induló, futó (program-)szál nem tudja megosztani mindazt, amit írtál: "share process instructions, and share data transparently with the other threads"? - elég korlátozottak lennének a lehetőségek.

ezt nem értem. mi az, hogy "interrupt hatására induló, futó szál"?  te el is olvastad, amit kérdeztél? ez az angol mondat egész pontosan azt mondja, hogy a threadek megosztják az address space-t: a kódot és az adatokat... WITHIN THE PROCESS (amit levágtál a mondat végéről).

De a te programod SOSEM fogja elérni a kernel adatait (ahol a megszakítás fut) és az interrupt handlerből sem nagyon lehet matatni az éppen futó user módú taszk memóriájában (mert lehet, hogy az a page pont ki van swappelve... linuxon van copy_from_user(), de azt nem lehet ISR-ből használni, hanem ehhez kell kérni egy tasklet, workqueue, bottom-half, stb. és majd abban).

 

A thread lényegében annyi, amit írtam, azt hidd el, hogy nem szabja meg senki a mikéntjét. Ezért írtam, hogy logikai dolog. Persze én elhiszem, hogy ha valaki "thread"-et említ, akkor leginkább az OS thread-re gondolnak először (ma).

nem értem, mit akarsz ezzel mondani.

 

Én nem filozofálgatásnak gondolom, hanem alapfogalomnak (ahogy az oracle, és a priceton is, de csak a két első weblapot belinkeltem ami megjelent a "definition of thread" keresésre, és leírták azt).

én is ezt mondom...  szerintem meg ti filozófálgattok az interruptokról és a signalokról, amikor multithreadingről beszélünk... bzt szerint az a "multithreadingnek" egy formája...  lol (én erre kértem forrást)

szóval, thread=szál, interrupt=system related mechanism, sometimes used for sheduling threads, signaling = limited form of inter process communication

multithreading azt jelenti, hogy EGY PROCESSZEN belül az oprendszer megengedi, hogy több szálon futtassunk dolgokat... Ezek a threadek márpedig MEGOSZTJÁK az address space-t. Ezt írja a két link, amit bepészteltél.
az, hogy ez hogy van megimplementálva, kernelben-e vagy userspace-ben, hogy egy IO-ra vagy condition variable-re váró threadet signalokkal ébreszt-e fel a kernel vagy füstjelekkel, a schedulingre timer interrupt-ot vagy varázslatot használ-e, az már implementáció kérdése és a futó programot nem érdekli és ne is érdekelje.

Szerintem nem teljesen érted a dolgot. Thread azóta létezik, hogy programflow van, és program counter van a számítógépben, és halad előre a végrehajtás. Vegyél egy C64-et alapul. Ha semmilyen megszakítás nem fut, mert letiltasz mindent, akkor is van egy thread-ed, a főprogramod fut benne!

a te user módú "programodban" sosem fog lefutni egy megszakítás... az mindig kernelben fut le, kernel módban és kernel stackkel... s annak akkor is le kell futnia, amikor az a cpu pont egy kernel threaden dolgozik. És ez a megszakítás nem a te programod érdekében végez dolgokat, hanem a rendszer érdekében, elsősorban. persze, a kernel ad mechanizmusokat, hogy a te programod is valamelyest szinkronizálhasson  egy ilyen eventtel...

A "user mód", meg "kernel mód" egy operációs rendszer függő dolog, a thread fogalma meg általános. Ahogy azt írtam korábban.

ezt nem értem. mi az, hogy "interrupt hatására induló, futó szál"?  te el is olvastad, amit kérdeztél? ez az angol mondat egész pontosan azt mondja, hogy a threadek megosztják az address space-t: a kódot és az adatokat... WITHIN THE PROCESS (amit levágtál a mondat végéről).
De a te programod SOSEM fogja elérni a kernel adatait (ahol a megszakítás fut) és az interrupt handlerből sem nagyon lehet matatni az éppen futó user módú taszk memóriájában (mert lehet, hogy az a page pont ki van swappelve... linuxon van copy_from_user(), de azt nem lehet ISR-ből használni, hanem ehhez kell kérni egy tasklet, workqueue, bottom-half, stb. és majd abban).

Kevered az absztrakciós szinteket. Nincs kernel, felejtsd el. Még egyszer leírom: a thread egy logikai koncepció, ami megmondja, hogy hogyan halad előre a program végrehajtása.

Gondolom láttál már igazi, kicsit nagyobb programot, amiben nem csak egy iskolai példája van az interruptnak. Ha van egy interruptod, az nem csak ott lóg a levegőben, és önmagában csinál dolgokat, hanem általában adatokat kell feldolgoznia. Vegyünk egy hőmérőt. Ha mérés van, akkor például triggerel egy interruptot, és ki lehet olvasni az adatokkat a hőmérőből a triggerelt interrupt kódjában. Adatmegosztás: Szerinted ha ez az interrupt nem tudna adatokat megosztani mással, akkor hogy oldaná meg, hogy például a programban máshol felhasználd a hőmérsékletet? Programkód megosztás: Szerinted az interrupt nem hívhat meg olyan programkódot, amit más is hív? Az interrupt egy másik szál? Nyilvánvaló, az eredeti szál megszakadt, és az interrupt kezdett el futni, ami egy teljesen másik programkód, mint ami futott éppen (aminek a végrehajtása megállt).

ezt nem értem. mi az, hogy "interrupt hatására induló, futó szál"?  te el is olvastad, amit kérdeztél? ez az angol mondat egész pontosan azt mondja, hogy a threadek megosztják az address space-t: a kódot és az adatokat... WITHIN THE PROCESS (amit levágtál a mondat végéről). De a te programod SOSEM fogja elérni a kernel adatait (ahol a megszakítás fut) és az interrupt handlerből sem nagyon lehet matatni az éppen futó user módú taszk memóriájában (mert lehet, hogy az a page pont ki van swappelve... linuxon van copy_from_user(), de azt nem lehet ISR-ből használni, hanem ehhez kell kérni egy tasklet, workqueue, bottom-half, stb. és majd abban).

A válaszod alapján azért nem érted, mert hasonlóan tekinthetsz a kérdésre, mint amikor valaki azt mondja, hogy "az internet az a Google". Nem értesz szerintem egy mélyebb fogalmat, ami a "thread", ami egy program logikai végrehajtási szála, és összekevered egy adott implementációval, mint például a "kernel thread". Különböző szinteken beszélünk ugyanarról a fogalomról. Bzt a "thread"-et említette, ami pontosan ezt jelenti, amit én leírtam.

Ez szerintem olyan, amiket írsz, mint amikor valaki a paprikás krumpli főzéséről beszél, de nem ismeri a hő fogalmát. Az előbbi egy konkrét tevékenység, amihez kell a hő, a hő pedig egy alapvető pedig egy alapvető fizikai jelenség, amely nélkül a főzés fogalma értelmezhetetlen.

Korábban írtam: "Persze én elhiszem, hogy ha valaki "thread"-et említ, akkor leginkább az OS thread-re gondolnak először (ma)." -   Ezt válaszoltad: "nem értem, mit akarsz ezzel mondani."

Azért mert pontosan ezt teszed, amit én írtam. Teljes egészében csak a kernel által kezelt, és OS által indított thread-ben gondolkozol, nem pedig az általános fogalomban, hogy mit jelent egy thread. Meg tudnád azt fogalmazni ezek után, hogy neked mit jelent egy thread, miért ezt a nevet kaphatta? Szerinted mi a definiciója?

szerintem meg ti filozófálgattok az interruptokról és a signalokról, amikor multithreadingről beszélünk... bzt szerint az a "multithreadingnek" egy formája...  lol (én erre kértem forrást)

Továbbra sem gondolom filozofálgatásnak, egyrészt én kizárólag csak a thread fogalmáról beszéltem, ami bele tartozik az is, amit Bzt írt (hogy külön threadnek tekinthető, ha egy különálló programkód futás indul el egy interrupt hatására (az interrupt kódja), remélem ez így már érthető), másrészt, ha egy alapfogalom érhető, akkor nem kell rá példákat keresni, meg külön megemlíteni forrásokban, csak értelmezni kell az alapfogalmat. A gravitáció például: nem szükséges egy tanulmányt belinkelnem neked arra, hogy ha egy almát elengedek a föld felett, az le fog esni. Gondolom elhiszed, ha érted, hogy mi az a gravitáció.

Amikor egy programról beszélünk, fontos, hogy nem csupán konkrét implementációról van szó, hanem olyan elgondolásokról és absztrakciókról is, amelyek a program működését irányítják.

Bízom benne, hogy így már sikerült tisztázni, hogy hol beszélünk másról, és most már érthetőbb, hogy ki mire gondol.

Szerintem nem teljesen érted a dolgot. Thread azóta létezik, hogy programflow van, és program counter van a számítógépben, és halad előre a végrehajtás. Vegyél egy C64-et alapul. Ha semmilyen megszakítás nem fut, mert letiltasz mindent, akkor is van egy thread-ed, a főprogramod fut benne!

én nem értem, az a lényeg, hogy te érted...

 

 

bár, ezeket ajánlom figyelmedbe, udvariasan, nem bzt stílusban:

- ez a wikipédiás cikk a threadekről: https://en.wikipedia.org/wiki/Thread_(computing) 

- ez egy másik cikk, arról szól, hogy mikor jelent meg a thread, mint fogalom... 70-es években: http://www.serpentine.com/blog/threads-faq/the-history-of-threads/

- ez egy harmadik cikk, hogy mikor jelentek meg a megszakítás, mint fogalom 1954-ben: https://en.wikipedia.org/wiki/Interrupt

(érdekes, akkoriban senkinek nem jutott eszébe threadeknek nevezni a dolgokat... na, de te ezt biztos jobban tudod, mert utánanéztél...)

- esetleg eltraccsolhatsz a chatgpt-vel is a dologról... 

 

de a legfontosabb: javítsd ki a wikipédiás cikket... esetleg Bryan O'Sullivan-nek is szólj, hogy te jobban tudod, hogy hogy alakult ki a thread fogalma...

Az általad belinkelt wiki és a "thread mind fogalom" blog, mindkettő azzal kezdi, hogy a szál, az olyan szekvenciális vezérlő egység, amelynek a végrehajtása folyamatosan halad előre.

Wiki: In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system.

Blog: The notion of a thread, as a sequential flow of control, dates back to 1965, at least, with the Berkeley Timesharing System.

Ez nagyszerű, mert azon felül, hogy ahogy a wiki, én nem részleteztem, hogy hogyan történik az ütemezésük, ugyanezt írtam.

 

Nézzünk meg a Thread osztály javadocját, ami a Java-ban reprezentál egy szálat: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html

A thread is a thread of execution in a program.

Ez az első mondat a Thread dokumentációjában, összhangban amit a cikkek írnak, amit belinkeltél, hogy olvassam el, vagy összhangban azzal, amit én írtam.

Amit az interrupthoz belinkeltél cikket:

In digital computers, an interrupt (sometimes referred to as a trap)[1] is a request for the processor to interrupt currently executing code (when permitted), so that the event can be processed in a timely manner.

Tehát azt írja, hogy megszakítja az éppen futó kódot (sequential flow of control), hogy az eseményt fel tudja dolgozni. (ami nyilván egy másik kód (másik sequential flow of control).

Ha ezt összerakod, akkor mi jön ki?

Szeretnék rávilágítani, hogy az interrupt megszakítja az egyik vezérlési szálat, és az interrupt mehanizmusa, hogy átkerül a vezérlés egy másik vezérlési szálra.

Tehát szerintem tök jók az oldalak, amiket belinkeltél.

 

én nem értem, az a lényeg, hogy te érted...

Nézd, nekem teljesen mindegy, de Te kevertél bele kernelt, user módot, kernel módot, még swappelés is volt, amiről itt nincs szó (mert azok implementációs kérdések egy operációs rendszerben, és semmiben nem befolyásolják azt, hogy mi az a thread). Ezért gondoltam, hogy esetleg nem érted, amit én mondani akartam, hogy miről beszélek (amit én pontosan értek, hogy én mit szeretnék neked mondani).

 

a megszakítás megszakítja az éppen futó thread-et és lefuttatja az megszakítás handlert... nem egy másik threadet...

 

Wiki: In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system.

az ISR-re igaz ez? "can be managed independently by a scheduler"

nem

 

a java doksidból:

Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.

igaz valami ezekből egy ISR-re? "Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon."

nem

 

tehát Mr. dlaszlo keveri a fogalmakat?

igen

 

tehát az ISR nem thread, te pedig pont olyan vagy, mint bzt: nem bírod beismerni, ha tévedsz

az ISR-re igaz ez? "can be managed independently by a scheduler"

Nekem annyira nem fontos, hogy Te megértsd, hogy az ISR mechanizmus egy eszköz lehet arra, sőt az, hogy átadd a vezérlést egy másik végrehajtási szálnak.

Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.

A Java implementációban (aminek a doksijából van ez a szöveg).

tehát az ISR nem thread, te pedig pont olyan vagy, mint bzt: nem bírod beismerni, ha tévedsz

Egyszerűen nem értek veled egyet abban, amiről vitáztunk (szerintem nem sikerült megértened a kérdést, ha ezt így vezeted fel: tehát az ISR nem thread), sőt nem is írtad le, hogy szerinted mi a thread. Belinkelték két oldalt (az általam belinkelt másik három mellé), amikben az első mondat az volt, amit én is írtam.

Oké, tudod mit Micsa, nem tudom, hogy szerinted mi a thread definiciója, mert azt nem írtad, de akkor biztos, hogy én tévedek. :D

Mondjuk nem követtem végig ezt a szálat, csak szomorúan olvastam 1-1 hozzászólást, de így kezdem érteni hogy tudott ez a thread 300+ kommentre duzzadni. Itt lehet, hogy nem csak annyi probléma volt, hogy bzt személyeskedik, ugye? (ha már megemlítetted Őt is) ;)

tehát Mr. dlaszlo keveri a fogalmakat? igen

Oké. :)

Itt találtam egy számomra relevánsnak tűnő hivatkozást a fentebb említett – és filozofikusnak is nevezhető – „a szál egy logikai koncepció” megközelítésre az MIT Press által kiadott Introduction to Embedded Systems című könyvből, aminek így kezdődik a 11.2 Threads című fejezete:

Threads are imperative programs that run concurrently and share a memory space. They can access each others’ variables. Many practitioners in the field use the term “threads” more narrowly to refer to particular ways of constructing programs that share memory, but here we will use the term broadly to refer to any mechanism where imperative programs run concurrently and share memory. In this broad sense, threads exist in the form of interrupts on almost all microprocessors, even without any operating system at all (bare iron).

Ez visszahivatkozik a 10.2.1 Interrupts and Exceptions című fejezetre, ami így kezdődik:

An interrupt is a mechanism for pausing execution of whatever a processor is currently doing and executing a pre-defined code sequence called an interrupt service routine (ISR) or interrupt handler.

Szabi

+1, köszi.

A szálakat a legtöbb leírás hasonlóan határozza meg: sequential flow of control.

Nincsenek kötelező attribútumai, ami kőbe lenne vésve, vagy nincs kötelezően meghatározva, hogy mennyi ideig kell futniuk, nem kell egymás mellett futniuk (futhatnak csak látszólag egymás mellett akár). Akár elvehetik egymástól a futás lehetőségét percekre is.

Meg lehet közelíteni a kérdést úgy, hogy egy adott környezetben mit jelent a szálkezelés. Például egy adott környezetben vannak kötelező attribútumai, prioritása a szálaknak, - ha ezt megvalósítják / megvalósították - implemetáció kérdése.  - A szál alapvető fogalma ezek felett áll.

Egy adott platformon vannak eszközök/lehetőségek is, amivel megoldható a szálak kezelése (de nincs megkötés, hogy mit használhatsz): memória hozzáférési szabályok, taszk állapotleíró, akármi... és a megszakítások is ezek közé tartozik.
A szál továbbra is egy vezérlést végző utasítás sorozat, ami fut.

Ezért gondolom, hogy nincs semmi baj szerintem azzal, amit bzt írt:

Érdekesség, hogy multitasking megvalósítható olyan architektúrán is, ami egyáltalán nem támogat semmiféle megosztást (azaz nincs virtuális memória, sem taszkleíró, sem fegyülelő mód, sem védelem, se semmi), lásd Minix2 fordítható 8086-ra, vagy a Contiki, ami C=64-en, ATMEL-en és STM-en is preemptív multitaszkinggal fut, hardveres támogatás nélkül, csupán szoftveresen implementálva. Ez azért lehetséges, mert az interrupt eleve a multithreading egyik formája, és ha van multithreading, akkor már a multitaszk is implementálható hardveres támogatás nélkül.

Egyébként ezt is érdemes kiemelni, amit a thread nyitóban írt (erről beszélünk):

Multithreading

A végrehajtás úgy történik, hogy a processzorban van ún. utasításszámláló regiszter, ez tárolja a soronkövetkező gépi kódú utasítás memóriabeli címét.
Ezt a regisztert szokás PC-nek hívni (Program Counter, Motorola, ARM, stb. processzorokon) vagy IP-nek (Instruction Pointer, x86-on).

Ha ennek a regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk.

 

Köszi a doksit, érdekesnek tűnik, megnézem. :)

Közismert szabály, hogy elég hosszú idő után bármely vita szavak jelentésének boncolgatásába megy át, de azért ismerjük el, a 'szál' avagy 'thread' szó az ipar általános használatában a 'lightweight process'-et jelenti, és sokkal később jelent meg, mint a 'megszakítás', 'kontextus-váltás', 'korutin', 'multi-processor', 'multi-task', 'ütemezés', 'virtuális memória' stb. fogalma.

Természetesen ettől még ki-ki olyan egyéni szóhasználatot szóhasznál, amilyet akar, de nem udvariatlanság ezt az elején határozottan bejelenteni.

Oké, senki nem vitatja, ez így van, valószínűleg az interruptot előbb ismerte mindenki, mint hogy thread-eken gondolkodott volna. De ettől még megvan, hogy most mit jelent a thread (a leírások szerint is), és ez értelmet ad nézőpontoknak, gondolatoknak.

Én azért rugóznam ezen, mert bzt most default (szerintem gondolkodás nélkül) le lett hurrogva egy olyan hozzászólásban (az ezzel kapcsolatos hozzászólásában), amit teljesen másnak írt, értelmes a hozzászólása, egyébként meg amikbe beleolvastam abban szerintem igaza van. (Itt kezdődött ez a kérdés: https://hup.hu/comment/3100873#comment-3100873 ) Mindezt miután már sikerült túllépni azon, standard C-ben tisztán lehet-e interrup handlert írni (ott is, ugye kinek volt igaza? a standard C nem támogatja, ahogy azt le is írta, az egyéb kiegészítések a gcc-ben, clang-ban igen).

De a végtelenségig el lehet húzni egy vitát, ha meg sem akarjuk érteni, amit a másik mond - ez történthetett ebben a szálban is. Főleg ha valaki vevő rá, nem tudja kezelni, és személyeskedésbe megy át emiatt egy thread.

Már nem bzt-t akarom én megvédeni, csak amit mondott, a szakmai része, az szerintem is úgy van. - csak a kommunikáció kinek hogy megy.

Na mindegy is. :)

nem udvariatlanság ezt az elején határozottan bejelenteni.

Pontosan ezt tettem, azért írtam a nyitót glossary stílusban, hogy mindenki számára tiszta legyen, melyik kifejezés alatt mit értek pontosan. Persze a TROLLok még csak el sem olvasták, mert csak rosszindulatúan kötekedni akarnak.

Az sosem volt kérdés, hogy én mit is értek egy-egy kifejezés alatt, hisz mindet egyértelműen sorra vettem a topiknyitóban.

Tényleg fájdalmas tud lenni, amikor valaki energiát fektet abba, hogy részletesen leírjon valamit, és utána a leírtakat elkezdi valaki kiforgatni, a válaszokat szelektíven olvassa, és beáll egy viselkedés minta, hogy bármit is mondasz, mindig ellentétes reakciót kapsz. Már azt is nehéz követni egy idő után, hogy valójában min megy a vita. Az, aki később kapcsolódik be, pedig attól függően alakítja ki a véleményét, hogy éppen honnan kezdi olvasni a thread-et, A-t vagy B-t fog igaznak gondolni.

Én szívesen olvasnék több szakmai tartalmat a HUP-on, személyeskedés nélkül. Ahelyett, hogy valaki kitartóan torpedózna egy thread-et, amelyben valaki szakmai tartalmat osztott meg, nem csak flame-et, érdemesebb lenne új thread-et nyitni, és abban kifejteni a saját gondolatait - nem csak azt, hogy mi nem úgy van, hanem azt is, hogy szerintük hogyan van. Tehát szívesen olvasnék egy átfogó leírást, ha valaki máshogy látja a thread kezelést, vagy hogy mi az az interrupt. - de ugye azt meg kell írni.

Ahelyett, hogy valaki kitartóan torpedózna egy thread-et, amelyben valaki szakmai tartalmat osztott meg, nem csak flame-et, érdemesebb lenne új thread-et nyitni, és abban kifejteni a saját gondolatait - nem csak azt, hogy mi nem úgy van, hanem azt is, hogy szerintük hogyan van.

Sajnos nem működik. Ez az egész onnan indult, hogy elkezdték torpedózni az SMGUI topikomat, pont ezért indítottam ezt az új threadet. Jól láthatóan sem az eredeti threadben, sem itt, az új threadben nem képesek az értelmes társalgásra, hisz ezek csak szánalmas, rosszindulatú TROLLok, ezt akárki meglássa'.

Mármint úgy értem, hogy akik torpedóznak, azok nyugodtan nyithatnak egy thread-et, és én szívesen tanulnék tőlük is, ha valami szakmai dolgot nagyon tudnak, és el akarják mondani. Nem csak azt, hogy mi nem úgy van, hanem azt is, hogy mi hogyan van. Egy leírásba szépen struktúráltan összegyűjtve, felépítve a mondandót. - ami részükről is hozzáadott érték lenne a hup-on, amivel persze dolgozni kellene (trollkodni könnyebb).

mutassatok valami forrást, ahol más is összefüggésbe hozta az interruptoktat/signalingot a multihreadinggel. 

FreeRTOS alatt, de mas hasonlo lightweight mulithreading library vagy kernel eseteben is egy interrupt handler tipikus feladata szokott lenni alvo (adatra varo) thread-ek felelesztese. Lasd peldaul ez itt, ezen belul is a taskwoken allapothoz kapcsolodo yield.

Ez a fent linkelt pelda teljesen analog azzal amikor pl linux/pthread eseten az egyik szal az epp alszik mert abban egy read() varja az adatot egy pipe-bol. Es ezzel parhuzamosan egy signal handler eteti meg valamikor ugyanazt a pipe-ot, felelesztven ezzel ezt az adott szalat. 

ne keverjük a mikrokontrollerekre írt freertos-t egy modern os-sel...

"FreeRTOS can be thought of as a thread library rather than an operating system" (wikipedia)

 

 

Ez a fent linkelt pelda teljesen analog azzal amikor pl linux/pthread eseten az egyik szal az epp alszik mert abban egy read() varja az adatot egy pipe-bol. Es ezzel parhuzamosan egy signal handler eteti meg valamikor ugyanazt a pipe-ot, felelesztven ezzel ezt az adott szalat. 

csak, hogy tisztázzuk: a read()-re váró thread magától is felébred, ha az a pipe olvashatóvá válik (ott vannak a kernelben a wait queue-k... wait_event_interruptible... wake_up_interruptible...)... a signal is felébreszti, csak azt mondom, hogy ehhez nem kell signal

 

persze, hogy felébreszthet egy megszakítás egy threadet... nem ez a probléma...

hanem, hogy az az állítás, hogy ha megszakításokat használunk, akkor az már multithreading... 

 

az volt a kérés, hogy forrást bzt kijelentésére, miszerint "az interrupt, akárcsak a signal kezelés a multithreading egy formája".

ne keverjük a mikrokontrollerekre írt freertos-t egy modern os-sel...

Pont erről van szó, hogy senki nem keveri. A modern os-sel Te jössz. Te veszed azt valamiért természetesnek, hogy amikor valaki megemlíti a multithreading-et, és a thread-eket, akkor egy modern os-ről beszélünk, nem pedig általánosan.

Szerkesztve: 2024. 08. 23., p – 15:11

@dlaszlo: szerintem hagyd, Micsa ékesen bebizonyította, hogy egy TROLL, senkire nem hajlandó hallgatni, semmilyen észérvre sem kíváncsi, csak kötekedni próbál - és most már - Téged is csak sértegetni akar.

Hibát követsz el, ha azt hiszed, értelmes, intelligens társalgást lehet vele folytatni, mert nem lehet. Vele és a hozzá hasonló ostoba TROLLokkal úgy kell beszélni, ahogy én tettem, mert csak azt értik, semmi mást.
Például hiába beszélsz magyarul egy angolhoz, nem fogja érteni, hasonlóan hiába beszélsz értelmesen egy TROLLhoz, nem fogja érteni. Egy TROLLhoz TROLLul kell szólni, ha azt akarod, hogy az üzeneted átmenjen.

Én másodfokú bírósági itélettel tudom bizonyítani, hogy ellenem Fideszes lejárató hadjárat folyik évek óta, szóval én már megszoktam a TROLLokat és engem hidegen hagy, hogy folyton belém akarnak kötni. Köszönöm mindazt, amit írtál, de aggódom kicsit, hogy mi lesz, ha Te is célponttá válsz.

most lattam meg ezt a threadet, de aztan a sok low level C huszar aki 50+ es nem latott meg eleteben mas nyelvet, nem hogy modern cuccokat, szettrollkodta a faszba. kar erte.

Összefoglalom magamnak, hogy mit értettem meg az itt tanultakból:

Nem mindegy, hogy simán hardver szinten nézzük a dolgokat OS nélkül, vagy OS-el.

OS nélkül a szál egy olyan utasítássorozat ami valamilyen külső hatásra fel tud függesztődni é
s utána folytatódni tud onnan ahol felfüggesztődött.  
Eszerint a megszakításkezelő rutin is egy szál mert a végrehajtása közben jöhet másik megszakí
tás aminek a végeztével folytatódhat.

Ha viszont van operációs rendszer akkor a szál definiciója kiegészül azzal a fontos dologgal,
hogy az egy folyamaton (process) belüli szálak közös címteret használnak ami megegyezik az őket tartalmazó folyamat címterével.
Ez a kitétel viszont nem teljesül? az megszakításkezelő rutinokra mert azok a kernel címterében futnak, nem a process címterében.
Vagy mégis?
https://www.sciencedirect.com/topics/engineering/interrupt-service-rout…
Itt azt írja, hogy

"Although an ISR might move data from a CPU register or a hardware port into a memory buffer, in general it relies on a dedicated interrupt thread, called the interrupt service thread (IST), to do most of the required processing."

tehát az ISR csak szól a kernelnek, hogy izé van, rúgd be az IST-t - ami ugyanolyan ütemező által ütemezett szál mint a többi - és a kernel szépen megfelelő prioval beütemezi az IST-t. Viszont mivel az IST a kernel része, ezért a kernel címterében fut, a process címteréhez nem fér hozzá. DE ettől még az ISR hozzáférHETNE?
 

Csak tényleg egy utolsó gondolat:

Talán szerencsésebb lenne azt mondani ahelyett, hogy ha van OS a szál definíciója kiegészül, inkább azt hogy az OS biztosít egy struktúrált környezetet a processek révén a szálak számára (aminek a definíciója nem változik). Az OS gondoskodik a szálak ütemezéséről, lehetővé teszi, hogy a szálak közös címtereket használjanak, erőforrásokat osszanak meg, hatékonyan működjenek együtt. - de bocsi, ha ez már csak nyelvészkedésnek tűnik.

OS nélkül a szál egy olyan utasítássorozat ami valamilyen külső hatásra fel tud függesztődni és utána folytatódni tud onnan ahol felfüggesztődött.

Semmi köze az OS-hez. A szálat így definiáltam:
Ha ennek a regiszternek [PC] az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk.

Ha viszont van operációs rendszer akkor a szál definiciója kiegészül

Nem hiszem. A szál egy absztrakt fogalom, nem függ attól, hogy van-e OS, max. egy OS-ben többféleképp is bekövetkezhet a szálváltás. A hangsúly azon van, hogy az új PC érték a normál programfolyamtól független-e, nem azon, hogy honnan jön az új érték.

tehát az ISR csak szól a kernelnek, hogy izé van, rúgd be az IST-t

Nem, az ISR a kernel része, mindig (akár monolitikus pl Linux, akár mikrokernel pl Minix). Egyébként ne használjuk ebben a kontextusban az "IST"-t, mert piszkosul zavaró, ugyanis x86_64-on ugyanígy hívják az ISR veremváltó mechanizmust is (vissza oda, hogy már megint keverednek az IT terminológiák).

Egész konkrétan x86_64 alatt így zajlik a dolog:
- meghívódik egy megszakítás (hogy mi váltja ki, az most lényegtelen, lehet soft int vagy hard int is)
- a CPU kiolvassa az Interrupt Descriptor Table megfelelő bejegyzéséből a típusát és az Interrupt Service Routine címét
- a CPU kiolvassa a Task State Segment shadow másolatából az IST mezőket (már ha az IDT bejegyzés megfelelő bitjei be vannak állítva)
- attól függően, hogy történt-e privilégiumszintváltás, a CPU más-más adatokat ment a (IST-től függően pontenciálisan új) verembe
- attól függően, hogy mi volt a megszakítás típusa, a CPU további adatokat rakhat a verembe
- a CPU az IP regiszterbe az ISR címét helyezi, így a továbbiakban az fog futni (típustól és privilégiumszinttől függően más rendszerregiszterek is változhatnak, nemcsak az IP)

Aztán hogy ez az ISR tulajdonképpen mit is csinál, az már a kernel dolga, szoftveres implementáció csak, nem hardveres, mint a fentiek. Egy egyszerű kernel lekezelheti egyből a dolgokat, míg egy mikrokernel jellemzően csak üzenetet küld egy eszközvezérlő processznek (amiben a megszakításkezelő thread található) stb., ez már a kernel belügye.

Viszont mivel az IST a kernel része, ezért a kernel címterében fut

Ez egyáltalán nem biztos. Ez csak a monolitikus kernelekre jellemző (de ott sem mindig), mikrokernelek esetében meg kifejezetten nem igaz ez az állítás. Mondom, ez már a kernel belügye.

Összefoglalva:
- az ISR lekezelheti egyből a dolgot (tipikusan Linux 0.0.1)
- az ISR felébreszthet egy kernel thread-et (tipikusan Linux, amióta van kthread)
- az ISR üzenetet küldhet egy felhasználó módú processzben futó szálnak (pl. Minix)

Köszi, így már kezd összeállni a dolog!

Akkor ebben a részben IST alatt az "x86_64-on ugyanígy hívják az ISR veremváltó mechanizmust" érted

- a CPU kiolvassa a Task State Segment shadow másolatából az IST mezőket (már ha az IDT bejegyzés megfelelő bitjei be vannak állítva)
- attól függően, hogy történt-e privilégiumszintváltás, a CPU más-más adatokat ment a (IST-től függően pontenciálisan új) verembe

 és az általam linkelt doksiban lévő IST (Interrupt Service Thread) meg a

- az ISR felébreszthet egy kernel thread-et (tipikusan Linux, amióta van kthread)
- az ISR üzenetet küldhet egy felhasználó módú processzben futó szálnak (pl. Minix)

thread-eknek felel meg?

Akkor ebben a részben IST alatt az "x86_64-on ugyanígy hívják az ISR veremváltó mechanizmust" érted

Igen. Hogy egész pontos legyek, Intel® 64 and IA-32 Architectures Software Developer's Manual Combined Volumes 3A, 3B, 3C, and 3D: System Programming Guide doksi 8.7 TASK MANAGEMENT IN 64-BIT MODE c. fejezetében a 276. oldalon, a Figure 8-11. 64-Bit TSS Format ábrán jelzett Interrupt Stack Table-re gondolok itt IST alatt.

Egyébként a Linux kernel doksija is a hardveres kernel vermeket érti IST alatt, és nem a kthread-eket (őszintén szólva most először látom az Interrupt Service Thread kifejezést rá, eddig sehol, egyetlen más doksiban sem láttam így hívva ezt).
x86_64 also has a feature which is not available on i386, the ability to automatically switch to a new stack for designated events such as double fault or NMI, which makes it easier to handle these unusual events on x86_64. This feature is called the Interrupt Stack Table (IST).

és az általam linkelt doksiban lévő IST (Interrupt Service Thread) meg a ... thread-eknek felel meg?

Nem egészen, mondjuk félig. Az általad linkelt doksi kifejezetten a monolitikus kernelekről (mint a Linux) és a kthread-ekről szól, és nem úgy általánosságban és nem is a POSIX értelemben vett pthread-ekről.

Például Minix esetén nincs kthread szál, az csak egy üzenetet küld egy mezei felhasználói processznek. A mikrokerneleknek pont ez az ismérve, hogy a felügyeleti szinten csak üzeneteket küldözgetnek jobbra-balra, minden feladatot nem privilegizált, felhasználói szintű programok végeznek, amik így nem férnek hozzá a kernel (vagy egymás) erőforrásaihoz. (De mégegyszer, a szálat itt most konkrétan kthread értelemben véve, és nem általánosságban.)

Köszi, így már érthető.

 

Azt jól értem, hogy a Te szál definíciódat fenntartva amennyiben van kernel, a szálakat be lehet sorolni két nagy csoportba:

1. kernel által priorizált és ütemezett szálak

* kernel szálak - ha vannak és ha vannak akkor ezek a kernel memóriáján osztoznak

* userspace szálak - ezek az őket tartalmazó process memóriáján osztoznak

2. nem kernel által ütemezett szálak

* Interrupt Service Routine - ez nyilván a kernel kódja lesz, de az ütemezőnek nincs ráhatása, hogy fusson-e vagy sem mert hardver szinten a proci indítja. Bár nem tudom a softirq-t meg tudja-e fogni az ütemező, ha megvan a megfelelő privilégiumszintje, hogy kiváltódjon, sanszos, hogy azt sem.

Remélem nem hagytam ki semmit.

> Ha [a PC] regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor [bzt értelemben] többszálú programvégrehajtásról beszélünk.

Ki tudja ebből megmondani, hogy a GOSUB 100 vagy CALL 5 vagy INT 21h vagy SVC 0x80 végrehajtása bzt értelemben többszálú programvégrehajtásnak számít-e?

A választ nem tudom, de még mindig próbálom követni a témát, ezért teszek ide a kérdést érintően egy kis magyarázatot a ChatGPT-től, a – hozzám hasonló – nem programozó egyedek jobb megértésének elősegítésére:

The codes you've provided are associated with different programming languages and environments. Here’s a breakdown of each one:

  1. GOSUB 100:

    • This is typically found in BASIC programming languages. The GOSUB statement is used to call a subroutine located at line number 100. A subroutine is a block of code that performs a specific task. After the subroutine execution, control returns to the line after the GOSUB statement.
  2. CALL 5:

    • In some programming contexts, particularly in assembly language or lower-level languages, CALL is used to call a procedure or function. The number 5 often represents a procedure that has been defined elsewhere in the code. When CALL 5 is executed, the control transfers to the procedure numbered 5.
  3. INT 21h:

    • This is an interrupt used in DOS (Disk Operating System) programmable environments, particularly in x86 assembly language. The INT instruction is used to invoke an interrupt, and 21h refers to DOS interrupt 21, which is a common interrupt used for various functions (file handling, console input/output, etc.) in DOS applications. The specific operation performed is determined by the values stored in the registers (like AH).
  4. SVC 0x80:

    • This is used in Unix-like operating systems, particularly in assembly language or system-level programming. SVC stands for Service Call, and 0x80 is the instruction number for the Linux syscall interface. This particular call is used to request a system service from the kernel, such as file operations, process management, and so on. The specific service requested is determined by the values in other registers (like EAX for the syscall number, and arguments passed via other registers).

In summary, these codes invoke subroutines or system services in their respective environments: BASIC for GOSUB, assembly/C for CALL, DOS assembly for INT 21h, and Unix system calls for SVC 0x80.

Szabi

Nem rossz, CALL 5 ügyben még tegyük hozzá ezt:
https://en.m.wikipedia.org/wiki/CP/M 
https://en.m.wikipedia.org/wiki/Zero_page_(CP/M)#CALL_5 
https://en.m.wikipedia.org/wiki/Program_Segment_Prefix
a CALL 5 CP/M-ben a rendszerhívás megfelelője.

Az én értelmezésemben: Itt a normál programfolyamból hívsz meg egy rutint, tehát ez a "normál programfolyam" része. Nem az történik amit bzt írt: "a normál programfolyamtól eltérő érték kerül helyette bele" (a PC-be vagy IP-be).

> > > Az én értelmezésemben: Itt a normál programfolyamból hívsz meg egy rutint, tehát ez a "normál programfolyam" része. Nem az történik amit bzt írt: "a normál programfolyamtól eltérő érték kerül helyette bele" (a PC-be vagy IP-be).

> > Ugye-ugye, a definíció kulcseleme egy másik definiálatlan fogalom.

> Mire gondolsz, melyik a definiálatlan fogalom?

A 'normál programfolyamtól eltérő érték' fogalma problémás ebben a mondatban:

Ha ennek a regiszternek az értéke elmentődik a memóriába, és egy, a normál programfolyamtól eltérő érték kerül helyette bele, akkor többszálú programvégrehajtásról beszélünk.

Szerintem is nagyon nehéz precízen fogalmazni, és úgy, hogy mindenkinek minden ugyanazt jelentsen.

Elágazások vannak a programban, és a szubrutin hívást én a normál programfolyam részének gondolom.

Ráadásul még nagyobb kavart okozhat, ha idevesszük a kooperatív multitaszkingot, ahol a szálak egymásnak adják át a futás lehetőségét, például úgy, hogy explicit módon meghívnak egy szubrutint, ami elrendezi a vezérlés átadást a "normál programfolyamtól eltérő, másik programfolyam" egy pontjára. - Nem tudom, hogy ezt használják-e még, lehet hogy pl mikrokontrollereken, vagy kisebb rendszerekben lehet értelme.

Ráadásul még nagyobb kavart okozhat, ha idevesszük a kooperatív multitaszkingot, ahol a szálak egymásnak adják át a futás lehetőségét,

Szerintem nem okoz kavart, mivel a vezérlés átadás a "normál programfolyamtól eltérő, másik programfolyam" egy pontjára itt is megtörténik (szvsz ebből a szempontból lényegtelen, hogy szubrutint kell-e hívni ehhez, vagy időzítő kényszeríti-e ki).

Nem tudom, hogy ezt használják-e még

Igen, használják, lásd pthread_yield. Ezen kívül akkor is implicit bekövetkezik, ha egy szinkron rendszerhívás (pl. read) nem teljesíthető, mondjuk mert IO eszközre vár; az összes modern kernel ilyenkor nem adja vissza a vezérlést, hanem másik szálra kapcsol, aztán majd ha befejeződött az IO és az adat rendelkezésre áll a memóriában, akkor felébreszti a blokkolt szálat.

Bár első ránézésre nem nyilvánvaló, de a sleep is valójában kooperatív multitaszk a háztető alatt (hisz hívást követően a vezérlés egy másik szálra kerül).

A 'normál programfolyamtól eltérő érték' fogalma problémás ebben a mondatban

Nyilván. Ahhoz, hogy pontosan definiáljuk, mely állapotok tartoznak egy adott program normál programfolyamához, formálisan kellene bizonyítani az adott program működését. Ez lehetséges, de irtó nehéz feladat, ezért egy-két konkrét esettől eltekintve nincs is egyik program sem bizonyítva. Így mi is kénytelenek vagyunk a pontatlan definíciót használni, a józan észre hagyatkozni, hogy mi számít "normál programfolyamnak".

Nehéznek nehéz, de azért lehet rá kísérletet tenni: a hagyományos terminológiában a multithreading a multiprocessing fokozása/fejlesztése: egyes processek közös címtartományban vannak, és osztoznak egyes erőforrásokon (file handle, shared memory, etc), ezek a threadek.

Namostan a process (avagy folyamat), az egy olyan programfutás, ami alá van vetve az ütemezésnek, azaz megkaphatja és elvesztheti/elengedheti a CPU-t, prioritása lehet, input-ra várhat, stb.

Még sok más dolgot is csinálhat, de talán ez is elég ahhoz, hogy megállapítsuk, hogy pl. a hw-interrupt az nem process/thread, mivel nincs alávetnek az ütemezésnek, és nem is engedheti el a CPU-t. Persze az lehetséges, hogy a hw-interrupt csak betesz egy feladatot egy que-ba, ahonnan majd kiolvassa egy kernel-thread/process, és az végrehajtja.

egyes processek közös címtartományban vannak, és osztoznak egyes erőforrásokon

Ez éppen úgy igaz az ISR-ekre is, a kernel "processz" részei, közösen a higher-half címtartományban, egymástól függetlenek és osztoznak bizonyos erőforrásokon.

talán ez is elég ahhoz, hogy megállapítsuk, hogy pl. a hw-interrupt az nem process/thread, mivel nincs alávetnek az ütemezésnek

A pthread sincs POSIX szabvány szerint. Simán elfogadott, hogy pusztán felhasználói módban váltogatnak a szálak, saját ütemezővel, a kernel ütemezője még csak nem is tud róluk.

Nagyon sokáig a Linux sem tudott kapcsolni pthread szálak között, az viszonylag új fejlesztés (valahol 2.4 körül került be, előtte nem volt), valamint az első musl implementációknál is a pthread_create nem hívott syscall-t, hanem maga kezelte a szálak altatását/felébresztését/ütemezését, így a kernel ütemező nem is tudott a pthread szálakról ott sem. Mégis multithreading-nek nevezzük a pthread-et ezeknél az implementációknál is.

(ps1.: a legújabb musl már a SYS_sched_setscheduler rendszerhívást használja, akárcsak a glibc, és a saját _wake, _wait stb. funkciója opcionális.)

(ps2: ugye a lényeges különbség csak multicore esetén jön elő; ha a kernel nem tud a thread-ekről, akkor csak az adott processzhez tartozó összes thread-et egyszerre tudja átköltöztetni egyik magról a másikra, míg ha a kernel ütemező tud róluk, akkor optimálisabb a kihasználtság, hisz minden thread-et külön magon képes futtatni. Amíg egymagos processzorok voltak a jellemzőek, addig nem is volt fontos, hogy a Linux kernel maga ütemezze a szálakat, addig bőven elég volt, hogy a libc kapcsolgatta őket pusztán felhasználói módban, hiszen egyszerre úgyis csak egy utasítást tudott végrehajtani a CPU.)

megint totális hülyeségeket beszélsz...

 

Nagyon sokáig a Linux sem tudott kapcsolni pthread szálak között, az viszonylag új fejlesztés (valahol 2.4 körül került be, előtte nem volt), valamint az első musl implementációknál is a pthread_create nem hívott syscall-t, hanem maga kezelte a szálak altatását/felébresztését/ütemezését, így a kernel ütemező nem is tudott a pthread szálakról ott sem. Mégis multithreading-nek nevezzük a pthread-et ezeknél az implementációknál is.

 

A 2.0-ás linux kernelben már volt clone és CLONE_VM. 1996-ban... a glibc pedig 1997-ben kapott linuxthreads supportot... nem volt full posix compliant, de egészen a 2.6-os kernelig szépen működött (a signalokkal meg a thread id-kkel volt egy kis gond..), aztán jött a NPTL

Ennek mindjárt 30 éve. Miért kell jönni itt a userspace-ben gányolt threadekkel?

 

DE

 

 bepésztelsz egy linket, ahol azt mondod, hogy a musl libc userspace-ben implementálta meg a threadeket és nem hívott syscall-t...

akkor ez mégis mi a túró?

 

    a_inc(&rs.blocks);
    while (rs.lock) __wait(&rs.lock, 0, 1, 1);

    a_inc(&libc.threads_minus_1);
    ret = __uniclone(stack, start, new);

    a_dec(&rs.blocks);

 

ott van a pthread_create-ben, te pésztelted be...

 

 az __uniclone pedig x86_64-en:

.global __uniclone
.type   __uniclone,%function
/* rdi = child_stack, rsi = start, rdx = pthread_struct */
__uniclone:
       subq    $8,%rsp         /* pad parent stack to prevent branch later */
       subq    $16,%rdi        /* grow child_stack */
       mov     %rsi,8(%rdi)    /* push start onto child_stack as return ptr */
       mov     %rdx,0(%rdi)    /* push pthread_struct onto child_stack */
       mov     %rdx,%r8        /* r8 = tls */
       mov     %rdi,%rsi       /* rsi = child_stack */
       leaq    40(%rdx),%r10   /* r10 = child_id */
       movl    $56,%eax        /* clone syscall number */
       movl    $0x7d0f00,%edi  /* rdi = flags */
       mov     %r10,%rdx       /* rdx = parent_id */
       syscall                 /* clone(flags, child_stack, parent_id,
                                *       child_id, tls) */
       pop     %rdi            /* child stack: restore pthread_struct
                                * parent stack: undo rsp displacement */
       ret
 

 

i386-on:

.global __uniclone
.type   __uniclone,%function
__uniclone:
       movl    4(%esp),%ecx
       subl    $24,%ecx
       movl    8(%esp),%eax
       movl    %eax,16(%ecx)
       movl    12(%esp),%eax
       movl    %eax,24(%ecx)
       pushl   %ebx
       pushl   %esi
       pushl   %edi
       pushl   %ebp
       movl    %eax,8(%eax)
       leal    20(%eax),%edx
       leal    4(%eax),%esi
       movl    %edx,%edi
       movl    $0x7d0f00,%ebx
       movl    $120,%eax
       int     $128
       popl    %ebp
       popl    %edi
       popl    %esi
       popl    %ebx
       ret

 

sőt, a musl libc SOHA nem használt userspace threadeket... már az első commitnál is __clone volt a pthread_create-ben

most megint szidhatsz, hogy széttrollkodtam a becses írásodat...  s ezzel megint megsérült az egod... bocsánat :)

Ezt most tényleg csak azért boncolgatom (nem kötözködésnek szánom), hogy milyen nehéz jól leírni egy ilyet:

egyes processek közös címtartományban vannak, és osztoznak egyes erőforrásokon (file handle, shared memory, etc), ezek a threadek.

Ez a mondat amit írtál, szó szerint azt jelenti, hogy

  • "egyes processek közös címtartományban vannak",  - Ez szerintem hamis: A processek mindig külön címtartományban vannak.
  • "és osztoznak egyes erőforrásokon (file handle, shared memory, etc)," - Igaz: Ez lehet igaz, az operációs rendszer segítségével elérhetnek közös erőforrásokat
  • "ezek a threadek." - Hamis: A processek biztosan nem thread-ek.

Megpróbálom én is, hogy hogyan gondolok erre, bár ez is félreérthető, pongyola lehet. Majd kijavítotok, ha hülyeséget írok szerintetek.

Szerintem:

  • Egy futó program az egy vagy több processből áll, amikor az operációs rendszer elindít egy programot, akkor létrehoz egy vagy több processt. - A processek között az operációs rendszer biztosítja, hogy szeparálva legyenek egymástól. (De léteznek módszerek pl a processzek közötti komunikácóra (inter process communication), ezek lehetnek például queue-k, amit Te is említettél.  Az egyes processek hierarchikus szerkezetben vannak, ahol az indító process a parent processz, a létrehozott processz pedig a child processz.)
  • Egy process egy vagy több "vezérlési szekvenciából" áll, azaz egy vagy több thread-ből áll. Az operációs rendszer biztosítja, hogy az egy processen belül futó thread-ek megosztják a processz címtartományát, a külön processben futó thread-ek viszont elkülönült címtartományban futnak.
  • A thread egy vezérlési szekvencia, amik egy adott végrehajtási irányt követnek.

De ez már arról szól, hogy hogyan működik egy operációs rendszer, ezek az operációs rendszer lehetőségei, a thread ez egy ettől függetlenül létező logikai fogalom, amit az operációs rendszernek is használnia kell a program futtatásának érdekében. De szerintem nem értelmezhető az, hogy bizonyos esetekben a számítógépen nem vezérlési szekvencia (azaz thread) fut.

Valóban nagyon nem egyszerű, meg merem kockáztatni, hogy az IT egyik legszövevényesebb és legkomplexebb része az alacsony szintű és kernel programozás.

A processek mindig külön címtartományban vannak

Nem feltétlen. Olyan architektúrán is fut több processzes (és több szálas) OS, aminek nincs virtuális memóriakezelése (azaz az egész gép egyetlen címtér), például 8086-ra fordított Minix, vagy az eredeti M68K-n futó AmigaOS, vagy a Commodore64-en futó Contiki.
Érdekesség, a Microsoftnak van egy olyan kutatási céllal írt OS-e, ahol minden processz egyetlen közös címtérben fut, itt a szálakat SIP-nek (Software Isolated Process) hívják.

amikor az operációs rendszer elindít egy programot, akkor létrehoz egy vagy több processt

Pontosan egyet. Több processz valóban tartozhat hozzá, de ahhoz a programnak fork() rendszerhívást kell explicit használnia.

Egy process egy vagy több "vezérlési szekvenciából" áll, azaz egy vagy több thread-ből áll.

Így van.

Az operációs rendszer biztosítja, hogy az egy processen belül futó thread-ek megosztják a processz címtartományát

Kicsit sántít. Ez nem feltétel, ám való igaz, hogy a mai modern (címtérszeparációt támogató) gépeken és a legújabb (szálakat ütemezni képes) kernel-nél így van. A kernelnek nem szükséges tudnia a processzen belüli thread-ekről, azokat a libc is kapcsolgathatja saját hatáskörben (de ez csak régen volt így, manapság már nem, ma már tényleg úgy megy, ahogy írod).

De ez már arról szól, hogy hogyan működik egy operációs rendszer, ezek az operációs rendszer lehetőségei, a thread ez egy ettől függetlenül létező logikai fogalom

Igen, ez már a kernel implementáció belügye, a szál valóban egy ettől független fogalom.

Igen, köszi az észrevételt. Nehéz leírni úgy, hogy általános legyen, és ne keverjen bele konkrét megoldásokat az, aki megpróbál erről írni.

például:

> amikor az operációs rendszer elindít egy programot, akkor létrehoz egy vagy több processt

Pontosan egyet. Több processz valóban tartozhat hozzá, de ahhoz a programnak fork() rendszerhívást kell explicit használnia.

Az is kérdés, hogy "egy program" alatt mit is értünk, ki mire gondol. Vagy hogy hogyan történik az elindítása. - Minden kapcsolódó processt az oprendszer indít el, ez biztos - valahogy, valamikor. :)

Egy program még az sem biztos, hogy egy gépen fut, lehet hogy van 25 különálló modulja, külön gépeken fut, vagy több gépen több példányban fut ugyanaz a kód. - Bár ezt nevezzük inkább akkor "rendszernek". :)

Amit tényleg nem írtam, hogy milyen lépésekből áll ez az indítás, amire hivatkoztam, de ezekre ezekre akartam hivatkozni. Igazad van, egy program indításához nem kell új folyamatot indítani, a meglévő "hívó" folyamatban indul execve-vel.

  • "egyes processek közös címtartományban vannak",  - Ez szerintem hamis: A processek mindig külön címtartományban vannak.

Volt olyan is a történelemben, hogy SVS (Single Virtual Storage), az előtt meg olyan, hogy nem is volt virtuális memória, csak fizikai. Ettől még igazad van, nem írtam le világosan, hogy a korszerű rendszerekben a processek külön-külön címtartományban vannak, ettől az általános szabálytól térnek el a Light Weight Processek (avagy threadek).

  • "ezek a threadek." - Hamis: A processek biztosan nem thread-ek.

Fordítva gondoltam, lásd fentebb.

Szóval a javított verzió:

a hagyományos terminológiában a multithreading a multiprocessing fokozása/fejlesztése: egyes processek -- az általános szabálytól eltérően -- közös címtartományban vannak, és osztoznak egyes erőforrásokon (file handle, shared memory, etc), ezek a threadek, avagy Light Weight Processek.

a hagyományos terminológiában a multithreading a multiprocessing fokozása/fejlesztése: egyes processek -- az általános szabálytól eltérően -- közös címtartományban vannak, és osztoznak egyes erőforrásokon

Egy kicsit gondolj bele, ez a definíció éppúgy érvényes a signalkezelőkre is (nem véletlen mondtam, hogy azok is valójában szálak).

Amit írtál, az szerintem a pthread (klasszikus POSIX szabvány szerinti szál) definíciója akart lenni. A multithreading azért ennél jóval bővebb fogalom, amibe természetesen a pthread is beletartozik, de csak egy része annak.

ezek a threadek, avagy Light Weight Processek.

Ha egész pontosak akarunk lenni, akkor az LWP kifejezetten egy olyan szálat takar, amiről a kernel ütemezője tud. Érdekesség: ezt először a Solaris kernelben implementálták, onnan került át a többi POSIX rendszerbe, persze más néven, hogy elkerüljék a patent trollkodást.

Mivel egyértelműen létezhetnek olyan thread-ek is, amikről a kernel nem is tud, illetve a signalkezelők is tekinthetők független szálaknak, ezért nem rakhatunk egyenlőségjelet a thread és az LWP közé.
Az igaz, hogy minden LWP egyben biztosan thread is, de nem minden thread LWP.

> Egy kicsit gondolj bele, ez a definíció éppúgy érvényes a signalkezelőkre is (nem véletlen mondtam, hogy azok is valójában szálak).

Elhiszem, hogy 'bzt értelemben' szálak, de hagyományos értelemben nem: nincsenek alávetve az ütemezésnek és nem mondhatnak le a CPU-ról (yield).

A második rész jogos, valóban lehetséges a többszálúságnak egyfajta emulációja userspace-ben, amelyben mondjuk egy blokkoló read(2)-et nemblokkoló read-re cserélre re az emulációs réteg, hogy addig más szál futhasson.

Elhiszem, hogy 'bzt értelemben' szálak, de hagyományos értelemben nem

A TE definíciódról beszéltem, ami így hangzott: "egyes processek -- az általános szabálytól eltérően -- közös címtartományban vannak, és osztoznak egyes erőforrásokon". Ebből mi nem igaz a signal handlerekre?
A főprogrammal közös címtérben vannak, azzal erőforrásokat osztanak meg, és attól függetlenül futnak ugyanabban a processzben.

nincsenek alávetve az ütemezésnek és nem mondhatnak le a CPU-ról (yield).

Ezeknek a fogalmaknak semmi köze a többszálúsághoz, ezek a multitasking hatáskörébe tartoznak. Hogy blokkolódik-e a fő szál vagy sem, míg a signal handler végez, attól függetlenül a fő szál és a signal handler szála két, egymástól független szál.

Pont, ahogy írtam: "többszálúság nélkül nincs multitasking se.", és "minden multitask egyben kötelezően multithread is, de nem minden multithread multitask". A signal handler tökéletes példája ez utóbbinak.

Visszacsavarnék az eredeti hsz-hez:

az első bekezdésben a 'thread'-et speciális 'process'-ként definiálom, a másodikban a 'process'-t próbálom definiálni.

Beidézném az egészet, de az első bekezdést kijavítva (ld. a dlaszlo olvtárs által feltárt hibás fogalmazást).

1. A hagyományos terminológiában a multithreading a multiprocessing fokozása/fejlesztése: egyes processek -- az általános szabálytól eltérően -- közös címtartományban vannak, és osztoznak egyes erőforrásokon (file handle, shared memory, etc), ezek a threadek, avagy Light Weight Processek.

2. Namostan a process (avagy folyamat), az egy olyan programfutás, ami alá van vetve az ütemezésnek, azaz megkaphatja és elvesztheti/elengedheti a CPU-t, prioritása lehet, input-ra várhat, stb.

1. A hagyományos terminológiában a multithreading a multiprocessing fokozása/fejlesztése: egyes processek -- az általános szabálytól eltérően -- közös címtartományban vannak, és osztoznak egyes erőforrásokon (file handle, shared memory, etc), ezek a threadek, avagy Light Weight Processek.

Megismétlem, nem létezik olyan, hogy "hagyományos terminológia", Te itt konkrétan a POSIX terminológiára utalsz, azaz a pthread-re, ami csak egy kis szelete az egésznek.
A kettőspont utánni definíciód meg éppúgy érvényes a signal handlerekre is, mint a pthread-es szálakra.

Namostan a process (avagy folyamat), az egy olyan programfutás, ami alá van vetve az ütemezésnek, azaz megkaphatja és elvesztheti/elengedheti a CPU-t, prioritása lehet, input-ra várhat, stb.

Megismétlem, multitaskingról beszélsz itt, nem többszálúságról, tehát alapjaiban hibás ez a definíció a processzre, mert nemcsak multitasking rendszerek léteznek.

Konkrét ellenpéldával cáfolva, lásd például a FreeDOS-t vagy MS-DOS-t (vagy bármelyik másik monotasking operációs rendszert), aminek se ütemezője, se yield hívása, se prioritási listája sincs, tehát semmi multitask, mégis egyértelműen rendelkeznek processzekkel (a linkelt forráskódból ez egyértelmű és tagadhatatlan).

TL;DR: annak, hogy van-e ütemező egyáltalán, semmi köze a processzekhez és a szálakhoz, monotasking rendszerben is van processz és (processzenként egy) szál.

> Megismétlem, nem létezik olyan, hogy "hagyományos terminológia",

https://en.wikipedia.org/wiki/Thread_(computing)

> Te itt konkrétan a POSIX terminológiára utalsz, azaz a pthread-re, ami csak egy kis szelete az egésznek.

Például Win32-ben is van multithread, szemben a Win16-tal, ahol csak multiprocess van. (Valamint Win16-ban még Single Virtual Storage van (286-tól felfelé), Win32-ben Multiple Virtual Storage).

https://en.wikipedia.org/wiki/Thread_(computing)

Nem csoda, hogy összekevered a multitasking-al ha a wikipédiáról tájékozódsz. Láthatóan olyan fiatal Z generációs vérpistikék írták ezt a konkrurens futtatásról hablatyoló wiki oldalt, akik már csak Windows-t láttak életükben, és el sem tudják képzelni, hogy létezik nem-multitask is, pl. CP/M-ről meg DOS-ról még csak nem is hallottak.

Javaslom inkább a fentebb linkelt Intel System Developer's Manual elolvasását, vagy Tannenbaum Operációs rendszerek könyvét, na ezek sokkal, de sokkal megbízhatóbb források, mint a wikipédia.

Mégegyszer:
- multithread: több szálat tárolsz és ennyi (nincs köze párhuzamossághoz, ütemezéshez, se semmi)
- multitask: több szálat futtatsz egyszerre (na ez a konkurens futás, amiről a wiki beszél; ez lehet akár látszólagos, akár tényleges, akár kooperatív, akár preemptív)
E kettő NEM ugyanaz, ahogy írtam: "minden multitask egyben kötelezően multithread is, de nem minden multithread multitask".

Például Win32-ben is van multithread, szemben a Win16-tal, ahol csak multiprocess van.

Hoppá, most öngólt rúgtál!
1. Win16 alatt sem volt ütemező, sem prioritás, csak yield, tehát a definíciód szerint processzei sem lehetnének!
2. minden processznek tartalmaznia kell legalább egy végrehajtási szálat, tehát ha multiprocess, akkor egyben multithread is.

Jó, hát így nem nagyon megyünk előre, talán egyezzünk meg abban, hogy a világ többi része hibásan használja thread fogalmát, te viszont helyesen.

Bár még mindig nincs meg a bzt értelemeben vett multithreading precíz definíciója, aminek alapján bárki meg tudja állapítani, hogy az exception, a hw-interrupt, a rendszerhívás, a szubrutinhívás stb. bzt thread-e vagy sem.

A Win16 valóban nevezhető többszálúnak, olyan értelemben, ahogy 8080-as nevezhető többmagos CPU-nak: egymagos, az egy több mint nulla, tehát többmagos. De természetesen kiegészíthetjük a definíciót (mármint a hibás, tehát nem bzt értelmű, hanem a világ többi része által használt fogalmakét):

1. Multhithreading rendszerben a felhasználói program tud szálakat (thread) indítani.

2. A thread (avagy LWP) olyan speciális process, ami -- az általános szabálytól eltérően -- a szülőjével közös címtartományban fut, és osztoznak egyes erőforrásokon (file handle, shared memory, etc).

3. A process (avagy folyamat) egy olyan programfutás, ami alá van vetve az ütemezésnek, azaz megkaphatja és elvesztheti/elengedheti a CPU-t, prioritása lehet, input-ra várhat, stb.

Jó, hát így nem nagyon megyünk előre, talán egyezzünk meg abban, hogy a világ többi része hibásan használja thread fogalmát, te viszont helyesen.

Bár még mindig nincs meg a bzt értelemeben vett multithreading precíz definíciója, aminek alapján bárki meg tudja állapítani, hogy az exception, a hw-interrupt, a rendszerhívás, a szubrutinhívás stb. bzt thread-e vagy sem.

Ezt Te így látod, én meg nem értek veled egyet. Amire "bzt féle thread"-ként hivatkozol - ami a thread valójában is, nem csak bzt szerint - az alapja az olyan leírásoknak, amiket Te  is találsz, amik általában az operációs rendszer szempontjából tárgyalják a thread-et. Mindegyikben ott van az, ami például ebben az IBM által írt AIX-os oldalon: https://www.ibm.com/docs/en/aix/7.2?topic=programming-understanding-thr…
Azaz "A thread is an independent flow of control" - és pont. A folytatás már az operációs rendszer szempontjából tárgyalja tovább, mert ez az oldal az operációs rendszer leírása.

Pont hogy azért jó az a definició, mert a thread-et mint fogalmat nem sajátíthatja ki egyetlen megoldás, thread-ek léteztek a Commodore 64 idején is, és később is léteznek majd, amikor egy kernel esetleg máshogy csinál valamit.

Szerintem érthető amit Bzt írt (bár nekem elsőre egy kicsit technikai volt), és a véleménye széles körben elfogadott. Az IBM-nek, Oracle-nek, Princeton-nak, vagy más releváns forrásoknak én jobban hiszek, egy hup-os forumon felmerült kérdés esetén, hogy bzt jól írta-e a thread-et, vagy sem. Mivel az Ő véleményük egybehangzik bzt véleményével (érteni kell, hogy miről szól amit írnak), én ezért sem nevezném "bzt féle thread"-nek.

jól értem, hogy fogtad az AIX-ról szóló doksit, kiemeltél egy mondatot, arra azt mondod, hogy általánosságban igaz a threadekre, minden más pedig az operációs rendszer szempontjából tárgyalja?

// Happy debugging, suckers
#define true (rand() > 10)

Pontosabban mondva, az olvtárs kivett egy mondatot a szövegből, de annak is csak az egyik felét:

Volt: A thread is an independent flow of control that operates within the same address space as other independent flows of controls within a process.

Lett: A thread is an independent flow of control.

Igen, Te meg az én commentemből emelted ki ezt a részt, és kihagytad, hogy írtam is, hogy ez egy operációs rendszer leírása, ami a Thread-et a saját szempontjából tárgyalja, és a többi már erről szól.

De ahogy írtam, nem értünk egyet (ebben a kérdésben), és szerintem ugyanazokat a köröket futjuk, úgyhogy maradjunk annyiban, hogy megígérem, hogy itt biztos hogy írni/jelezni fogom, ha megváltozik a véleményem a threadről.

Meg ha megnézed az egész fórum thread-et, két-három oracle doksit, egyetemnek a doksiját, Micsa segített, és hozott egy wiki cikket, meg egyéb Berkeley-es blogot. Ugyanaz van bele leírva, csak érteni kellene.

Szóval jól érted, és a többi doksit is kiemeltem. És mellesleg az AIX-ról szóló doksi is bőven elég, mert jól leírja a thread általános fogalmát.

Mindegyik leírás a thread-ről szól az adott területen, és ez a közös a thread-ekben amit kiemeltem.

Nem fogok rugózni a thread definicióján, mert pontosan érthető, hogy mi az, sajnálom, ha valaki nem tudja megkülönböztetni, ha operációs rendszer, vagy csak egy számítógép szempontjából van tárgyalva. Szóval amit kiemeltem pontosan az a thread, és ennek értelmében ha egy számítógépen fut valami, akkor olyan nincsen, hogy az nem egy thread, ha független folyamat utasításai egymás után futnak. Ennek a fogalmát egészíti ki az összes leírás, ami ebbe a fórum szálba be lett linkelve, a saját szemszögéből.

Egyébként ez a viccess videó jutott eszembe, hogy kb ilyen gyönyörűen beszélünk el egymás mellett: https://www.youtube.com/watch?v=Dv8l8TKKVkU

Igen. Vannak cpu thread-ek, os szinten értelmezett thread-ek, vm (pl java vm) szinten értelmezett tread-ek meg a program utasítások lefutásának szála vagy szálai (ami logikai szint). Aztán akkor lehet keverni ezeket meg más fogalmakat és hosszú flame-ben szórakoztatni egymást. Egy vicc volt ez már a legelején is.

+1 Igen, és logikailag egy közös bennük, amit kiemeltem.

Ugye az egész fórum szál így néz ki. Ami nekem nagyon szúrta a szemem, hogy Bzt, vagy aki ugyanazon a véleményen van leír valamit, és a kezdeti befeszülés miatt, vagy eleve egó kérdések miatt olyan, mint ha ez szándékosan nem lenne megérthető. Pedig egy egyszerű fogalomról van szó, kb józan paraszti ésszel érthető, hogy a másik miről beszél, és mi a kontextus (nem a linux kernel).

Mindegy szerintem érdemes elengedni, aki úgy érzi, hogy igaza van, annak igaza van. Micsával ezt már meg is beszéltük korábban.

Még egy kiegészítés: én úgy láttam, hogy egyedül NevemTeve volt az, aki azt mondta, hogy szerinte nem ez a thread, *hanem ez*, és leírta, hogy mit gondol. Ugye más, pedig csak annyit írt, hogy *nem*. Tehát +1 neki.

Az a gond, hogy el kell olvasni pár ezer oldal irodalmat hozzá hogy valaki igazán képbe kerüljön meg meg kell nézni pár példát a hardverig "leásva". Egy ekkora témában a fórum keretei közt szerintem működőképes "fejtágítót" a témában nem is igazán lehet csinálni. K*rva óvatosan fogalmazva, egy-egy "szintet" megcélozva lehetne talán csinálni - mindig egy témára koncentrálva és felülről kezdve, egyszerű dolgokkal -, hogy ne legyen kavar fejekben. De ez is inkább cikk/blog-sorozatot kíván mint egy "észosztást" egy másik flame kapcsán.

Na meg rengeteg türelmet és melót. Ezek közül egyik sincs itt. :(

+1 Igen.

Egyébként én nagyon értékelem a szándékot, hogy leült valaki, és elkezdett egy szakmai témát leírni a hup-on. Függetlenül attól, hogy az egy kezdő, vagy egy haladó szintű leírás. Egy ilyet mindig nehezebb elkészíteni, mint utána belekötni.

Sajnos ez nagyon félrement, legközelebb remélem, hogy jobban sikerül, és nem csap át személyeskedésbe, értelmetlen egymás mellett elbeszélésbe. Tök jó lenne ilyeneket olvasni, persze a megfelelő stílusú hozzászólásokkal. :)

Az a gond, hogy el kell olvasni pár ezer oldal irodalmat hozzá hogy valaki igazán képbe kerüljön meg meg kell nézni pár példát a hardverig "leásva".

Igen, alulrol epitkezve erdemes megneznunk ezt - azaz milyen minimalis hardver szupport kell ahhoz hogy egy egyszeru preemptiv multithreading megvalosithato legyen. Annyira azert nem kell sok ehhez halistennek :) Ha par ezer oldalt nem is kell atnezni, de kb ~100 oldalbol leirhato mar egy olyan rendszer amin mar Linuxot is tudunk futtatni. 

Elfelejted hogy ha alulról akarnál indulni, akkor kell tudni hozzá "kicsit" programozni is ugye (asm, c) ill. legalább a hagyományos Neumann-féle szgép működésének ismerete (cpu, memória, perifériák) és talán nem lehet megúszni egy konkrét cpu és köré épített architektúra ismeretét sem (esetleg kis elektronikával fűszerezve :)).

A legtöbb (felső szintű) iskola ezeket az ismereteket párhuzamosan mélyíti, és "felülről" indul szerintem.

1. Multhithreading rendszerben a felhasználói program tud szálakat (thread) indítani.

2. A thread (avagy LWP) olyan speciális process, ami -- az általános szabálytól eltérően -- a szülőjével közös címtartományban fut, és osztoznak egyes erőforrásokon (file handle, shared memory, etc).

Ez a definíció továbbra is igaz a signal handlerekre (is). Nem írtad még mindig le, hogy a fenti definícióból mi az, ami szerinted ne lenne érvényes a signal handlerekre és hogy azok szerinted miért nem szálak.

A thread (avagy LWP)

Ezen kívül azt is tisztáztuk már, hogy a thread egy bővebb fogalom, mint az LWP. Nem rakhatsz egyenlőségjelet e kettő közé, mert nem minden thread LWP (utóbbi kifejezetten olyan szál, amiről a kernel ütemezője tud). Konkrét ellenpélda a Lua baselib coroutine-jai: ezek is a szülőjével közös címtérben futnak, osztoznak az erőforrásokon, a főprogramtól függetlenül futnak; de a kernel semmit sem tud róluk és senki sem nevezne egy Lua coroutine-t LWP-nek, csak thread-nek.

3. A process (avagy folyamat) egy olyan programfutás, ami alá van vetve az ütemezésnek

Nyilvánvalóan hibás még mindig, hiszen processzek léteznek DOS alatt is, ahol nincs is ütemező. Ezt feleslegesen erőlteted, ha egyszer ellenpélda cáfolja.

Mégegyszer, kevered a többszálúságot a multitasking-al. Multitask alatt azt értjük, hogy egynél több szál képes futni egyszerre (akár látszólagosan, akár ténylegesen).
Nyilván, hogy egyszerre több szál futhasson, ahhoz előfeltétel a több szál és az ütemező megléte, ugyanakkor fordítva ez nem igaz. Csak azért, mert egyszerre egy szál képes futni, még nem jelenti azt, hogy ne lehetne több szál.

Megpróbálom egy példával szemléltetni: van egy netes játék, mondjuk tétova tevéket kell noszogatni. Az, hogy hány regisztrált felhasználója van a szolgáltatásnak (szálak száma), és hogy egyszerre, egy adott pillanatban hány felhasználó képes bejelentkezi (konkurensen futó szálak száma), tök független egymástól. Ha egyszerre csak egy játékos tud bejelentkezni, az nem jelenti azt, hogy összesen csak egyetlen játékosnak lehet tevéje, attól még simán lehet több regisztrált játékos.

Ezt a definíciót nem én találtam ki, helytelen tehát a "bzt-féle" jelző használata.
Bármelyik operációs rendszerek fejlesztésével foglalkozó szakkönyvben (pl. Tanenbaum-könyv) vagy bármelyik gyártó által kiadott alacsony szintű dokumentációban (pl. Intel Manual, AIX, MSDN, Linux doksi, stb.) ezt találod.

Ki tudja ebből megmondani, hogy a GOSUB 100 vagy CALL 5 vagy INT 21h vagy SVC 0x80 végrehajtása bzt értelemben többszálú programvégrehajtásnak számít-e?

Attól függ, hogy normál programfolyamra kerül-e a vezérlés, vagy attól függetlenre. Ha független, akkor egész biztos több szálról van szó.

GOSUB 100 - határozottan a programon belül kerül át a vezérlés, tehát ez nem több szál
CALL 5 - szintén, még akkor is, ha az 5-ös címen egy máshonnan betöltött program található, ettől nem lesz többszálú
INT 21h - a normál programfolyamtól nem független a vezérlésátadás (de lásd alább)
SVC 0x80 - szintén (de lásd alább)

Az utolsó kettő soft int, ugyanazt a mechanizmust használja a CPU a vezérlésátadásra, mint a hard int esetén. Nyilván mondhatjuk azt is, hogy a soft int nem minősül több szálnak, azonban a hard int mindenképp több szálat jelent, mivel nyoma sincs a szoftverben, mégis meghívódhat a normál proramfolyamtól függetlenül. Mivel a soft int azonos vezérlésátadási mechanizmust használ, mint a hard int, ezért (megállapodás kérdése) független szálnak is tekinthetjük, vagy (mivel szerepel a kódban) csak egy más privilégiumszinten futó szubrutinnak (szvsz ez utóbbi).

Korábban megjegyezte valaki a setjmp/longjmp-ot, nyilván az is normál programfolyamon belül adja át a vezérlést (sőt, csak olyan PC-t képes beállítani, ami korábban a normál folyam során már egyszer szerepelt a PC-ben, mást nem is).