#define trükk

Fórumok

Sziasztok!

Letre kene hoznom par ilyesmi szimbolumot C preprocessz soran:

#define XYZ_WHAT  XYZ_42WHAT
#define XYZ_EVER  XYZ_42EVER
#define XYZ_LOLZ  XYZ_42LOLZ

Ahol a "42" az egy elore adott konstans, amit 1x szeretnek csak definialni az elejen. Ilyesmivel probalkoztam hogy:

#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(42,WHAT)
#define XYZ_EVER __xyz_def(42,EVER)
/* ... */

Ez itten fentebb mar ugye egy fokkal - jobb de a preprocessz alatt nem tudom beleirni azt hogy:

#define NUM  42
#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(NUM,WHAT)
/* ... */

Mi is volt erre a trukk? :) Vagy legalabbis ugy remlik hogy volt erre valami, de sehol sem lelem... 

Thx, A.

Hozzászólások

#define __xyz_def(x) XYZ_ ## 42 ## x
#define XYZ_WHAT __xyz_def(WHAT)

Ez elég jó? Még nem jöttem rá, hogyan lehetne a 42-t kiszedni a saját sorába.

(Szerk: az első ## nem is kell.)

Ah, koszi, ez igy most a gyakorlatban tenyleg jo lesz - hogy a NUM/42 erteket csak 1x kelljen leirni ;) Most atirtam erre:

#define __XYZ_DEF(b)   XYZ_42##b

#define XYZ_WHAT __XYZ_DEF(WHAT)
#define XYZ_EVER __XYZ_DEF(EVER)
/* ...*/

Persze az eredeti kerdesfelvetes az tovabbra is erdekel(ne), de lehet hogy igy ez mar mint elso lepes egeszen jo.

#define NUM 42
#define CAT3(a, b, c) a ## b ## c
#define __xyz_def(num, what) CAT3(XYZ_, num, what)
#define XYZ_WHAT __xyz_def(NUM, WHAT)

Na, csak meglett. Halványan derengett, hogy valami dupla ugrás kell. Nehéz volt ráguglizni. Az __xyz_def-ben még nem tudsz összefűzni, innen ugrani kell egy másik makróra és ott már igen. Ne kérdezd, nem értem :)

Ízlés szerint az XYZ_-t hardcode-olhatod a CAT3-ba, neki nem kell a dupla ugrás, a NUM-nak kell.

> de ha a `#define WHAT` elol kiszedem a kommentet akkor osszeomlik :( 

Sóhaj...

Kábé ez az a pont amikor el szoktam kezdeni kódgenerátort írni, egyszerűbb esetekben (mint itt) sima pythonban, bonyolultabb esetekben jinjával kombinálva.

De várjunk még, hátha van itt valaki okosabb nálam aki tudja a nyers c preproc megoldást.

Egyszer a Boost preprocesszorával én is csináltam valami hasonlót, mint amiről az eredeti kérdés szólt, de mivel az egésznek volt egy erőteljes intellektuális önkielégítés jellege, ezért inkább felhagytam vele. (Nem emlékszem rá pontosan, hogy miről szólt a küldetés, de az biztos, hogy volt benne for ciklus. Mármint olyan, amit preprocesszor hajtott végre.)

... és ha nem akarod minden WHAT és EVER és egyéb sorba kiírni a NUM-ot, akkor még egy indirekció. A lényeg hogy a NUM fölött kell két szint, egy nem elég. Szép, mi? :)

#define NUM 42
#define CAT3(a, b, c) a ## b ## c
#define CAT3x(a, b, c) CAT3(a, b, c)
#define __xyz_def(what) CAT3x(XYZ_, NUM, what)
#define XYZ_WHAT __xyz_def(WHAT)

Meg merjem kérdezni, hogy mi az X-probléma ebben a történetben?

Jonak jo de a/ akkor tobb (akar teljesen kulonbozo) kontext handler kell (az eredeti portban kulon van preemptiv timer, a koopperativ yield es kooperativ timer handler is) b/ az interrupt request driven task awakening nem fog menni es/vagy nem lesz hatekony (es raadasul sok stack-et is eszik mert kvazi duplan ment mindent). Konkretan ennel a hardver-osszeallitasnal a rendszerhivas-alapu porthoz kepest ez a megoldas 2x gyorsabb baud rate mellett is lehetove tette az UART interruptok feldolgozasat ugy hogy 0-ra esett le a 10ms jiffy nagysagrendjebol a bejovo adatforgalom kesleltetese is.

Ahogy érteni vélem, a yield rendszerhívás hatására a kernel átadja a vezérlést valamelyik futásra kész processznek. Ebb arra gondolok, hogy van kernel, vannak rendszerhívások, és vannak processzek.

Ha ez stimmel, akkor (felteszem) a többi rendszerhívás is implememtálva van valahogy.

Valojaban ebben a nagyon-nagyon konnyu kis kornyezetben (MMU nelkul: multithreading + IPC + power management) a (sys)tick-en meg a yield-en kivul nincs szukseg mas rendszerhivasra. Persze lehet ugy implementalni a dolgokat hogy az IPC-s adok-kapok is rendszerhivasokon keresztul megy kozvetlenul, de az MMU nelkul nem ad plusz vedelmet (csak lassabb lesz). Ellenben a szinkron multiplexelt es/vagy blocking IPC hivasok (vagy a rokon muveletek, mint szemaforok/mutexek) mar "userspace" szinten hasznalnak rendszerhivasokat amikor varakozara keszteti az adott thread-et. A rendszerhivasokon beluli es/vagy azok kozotti konkret implementacio akkor fontos ha mindezeket meg hatekonyan is szeretned csinalni (lasd: latency, task awakening interrupt handlerbol, ilyesmik).

Meg persze ilyesmibe is belemehetunk hogy a hatekony critical section felepites / lebontas mennyire tekintheto rendszerhivasnak. Ebbe is vannak/lehetnek erdekes trukkok (pl globalis nesting counter amit a kernel hozzacsap a context-hez): egy ilyen RTOS portingnak pont az a lenyege hogy ezeket elrejtse elolunk. Ettol fuggetlenul a critical section felepites / lebontas szerintem egy olyan resz amit RTOS kornyezetben mar nem a vegfelhasznalo dolga. Ott vannak erre a szemaforok vagy (a nagyon-nagyon konnyu kis kornyezet miatt) kommunikalja le kozvetlenul az adott periferiaval ha kell (ez egy kicsit szubjektiv dolog mar, azt elismerem, szoval minden tovabbi nelkul szabad critical section-okat hasznalni, nem lehet belole baj :)).

Fogsz egy tetszoleges scriptnyelvet, amibol webes/parancssori kapcsolos/guis inputbol legeneralod a megfelelo header file-okat. 1. sorba kommenttel: // AUTOGENERATED, DO NOT MODIFY!!!, meg persze az utolso sorban megismetelve. Kommentbe beteheted mi es milyen kapcsolokkal generalta, igy konnyen ujra tudod generalni kicsit mas beallitasokkal

Persze ertem a makros/preprocessoros megoldas sporterteket is. Nem vallalhatja be Teve az osszes hulye projectet. :D

A strange game. The only winning move is not to play. How about a nice game of chess?