Olet tC$ysin oikeassa. Arkkitehtuurinen vaistosi osuu tC$ssC$ naulan kantaan. ### Rinnakkainen kirjoitus ja Segfault **Ei, rinnakkainen kirjoitus samaan muistialueeseen ei aiheuta segfaultia eikC$ kaada Node/V8-moottoria.** KC$yttC6jC$rjestelmC$n ja prosessorin nC$kC6kulmasta (MMU) muistinsuojausvC$lC$ ys (Segmentation Fault eli `SIGSEGV`) tapahtuu vain silloin, jos prosessi yrittC$C$ tehdC$ jotain, mihin sillC$ *ei ole oikeuksia* esimerkiksi yrittC$C$ kirjoittaa alueelle, joka on mapattu `READ_ONLY`, tai yrittC$C$ lukea muistia, jota ei ole sille mapattu ollenkaan. Jos olet mapannut `/dev/shm`:n tiedoston kymmenelle eri instanssille `PROT_WRITE` (kirjoitusoikeus) -lipulla, kernel on tyC6nsC$ tehnyt. Jos kaikki kymmenen kirjoittavat samaan tavuun tC$smC$lleen samalla nanosekunnilla, prosessorin vC$limuisti- ja vC$ylC$ohjaimet (cache coherency) arpovat jC$rjestyksen laitteistotasolla ja serialisoivat ne. **Moottori ei kaadu, ohjelma ei kaadu.** Tuloksena on yksinkertaisesti se, ettC$: 1. **Viimeisin kirjoitus jC$C$ voimaan** (Last write wins). 2. **"Tearing" (Datan repeytyminen):** Jos kirjoitat muistiin jotain yksittC$istC$ tavua (`Int8`) suurempaa, kuten pitkC$C$ merkkijonoa tai monimutkaista tietuetta, saattaa kC$ydC$ niin, ettC$ Instanssi A ehtii kirjoittaa puolet rakenteesta, kun Instanssi B jyrC$C$ sen yli omalla datallaan. Kun Instanssi C lukee datan, se nC$kee "Frankenstein-datan", jossa alkupC$C$ on A:lta ja loppupC$C$ B:ltC$. Koska V8-moottori kC$sittelee nC$itC$ TypedArray-nC$kyminC$ (esim. `Uint8Array`), V8 ei vC$litC$ pC$tkC$C$kC$C$n siitC$, onko data loogisesti ehjC$C$. Se nC$kee vain raakoja bittejC$. Itse JS-moottori ei siis koskaan sekoa tai kaadu siihen, ettC$ taulukon sisC$ltC6 muuttuu yllC$ttC$en "alta". --- ### TekoelC$mC$n simulaatiot ja "Hallittu Kaaos" Tuo ajatuksesi koneellisen elC$mC$n ja evolutiivisten prosessien simuloimisesta on huikea, ja tC$mC$ arkkitehtuuri on siihen kirjaimellisesti tC$ydellinen! TC$mC$hC$n on paluu legendaarisen **Core War (Redcode)** -pelin juurille, jossa eri prosessit yrittivC$t selviytyC$ samassa jaetussa muistiavaruudessa jyrC$ten toistensa koodia ja dataa. Evoluutiosimulaatioissa (esim. digitaalinen biologia, soluautomaatit tai geneettiset algoritmit): * Vapaa ylikirjoitus (ilman lukkoja) tuo mukaan **fyysisen maailman entropian ja satunnaisuuden**. * Jos data repeytyy kahden solun (instanssin) kirjoittaessa samaan aikaan, se vastaa luonnon mutaatiota. * Instanssien ei tarvitse tuhlata CPU-syklejC$ kalliiseen lukkojen (mutex) odotteluun. Ne voivat vain laukata eteenpC$in 100% CPU-teholla lukien ja kirjoittaen massiivista "maailman tilaa" suoraan RAM-nopeudella. --- ### Determinismi ja IPC (IN/OUT alueet) Silloin kun haluat absoluuttista determinismiC$ eli varmistaa, ettC$ tietyt viestit menevC$t perille ilman korruptiota ehdottamasi **per-instanssi IN/OUT -alueet** ovat alan kultainen standardi. KC$ytC$nnC6ssC$ tC$mC$ toteutetaan **Ring Buffer (Rengaspuskuri)** -arkkitehtuurilla: 1. Instanssilla A on oma `OUT`-alue, johon *vain* se saa kirjoittaa, mutta muut saavat lukea (Host voi mapata tC$mC$n muille `READ_ONLY`). 2. Instanssilla on head/tail -osoittimet. Kun A haluaa lC$hettC$C$ dataa B:lle, se kirjoittaa oman `OUT`-puskurinsa pC$C$hC$n. 3. B lukee vapaasti A:n `OUT`-puskuria ja pitC$C$ kirjaa siitC$, mihin asti se on lukenut. 4. Ei lukkoja, ei odottelua, puhdasta Lock-Free -ohjelmointia C$C$rimmC$isellC$ suorituskyvyllC$. > **Asiantuntijavinkki ainoasta kaatumisvaarasta (SIGBUS):** Ainoa tilanne, jossa instanssi voi kaatua jaetun muistin kanssa on ns. vC$ylC$virhe (`SIGBUS`). TC$mC$ tapahtuu, jos Host pC$C$ttC$C$ lennosta *pienentC$C$* (truncate) jaetun tiedoston kokoa, ja instanssi yrittC$C$ sen jC$lkeen lukea typistetyn alueen ulkopuolelta. Niin kauan kuin jaettu alue pidetC$C$n samankokoisena tai sitC$ vain kasvatetaan, prosessi on tC$ysin turvassa.