#MINTIA (not vibecoded)
1 messages · Page 8 of 1
this is why it baffles me that trump is turning america in favor of russia
is he?
he was, then he wasn't
tbf trump is hostile to just about everyone
he obviously doesnt like zelensky though
theres more tarrifs and sanctions planned on russia so yeah i think it does
Things are so confusing and changing so quickly I stopped reading the news lately
true
the best thing ive done this month for my health tbh was starting to walk daily
but then also logging off of X with no intention of logging back in
was about time
should've been done a long time ago but yeah
(im reaching 3 weeks)
isnt that because they're all banned in turkey 
i just check r/turkey a few times a week to see whats up
no?
i could've sworn they banned instagram a while back
oh yeah
but that was protested and reverted pretty quickly
we do have discord banned
lmao why discord of all things
i get stuff like signal and telegram because end to end encryption and feds hate that
because of these conversations 
a guy beheaded his gf and threw her head from on top of a castle
but discord will bend over backwards to appease local gov
they were like
hmm this guy is an "incel"
and discord has "incel" groups
most mentally stable discord user
discord is a us company
so they were like "ok clearly discord is the issue" and banned it
im trying to explain why it got banned
dumbo
russia has banned youtube
i was being sarcastic
and discord as well
i wasnt
that is somehow not as dumb a reason to ban it as i had expected tbh
yeah it's not too bad of a reason
but it still destroyed a bunch of programming communities
and jobs too
usually its like somebody on this platform called my mom gay and now i want it banned
for people who did contract work over discord
the closest we have to that is the wikipedia / pastebin bans
just use vpn?
tho wikipedia is no longer banned
banning something that programmers use is the dumbest thing ever
not everyone is going to bother installing one
like me
i just use zapret
makes it pretty hard to file your taxes if you're getting work over a banned platform
kinda screwed if you get audited
russian technology lol
russians / eastern europeans are good as fuck at 2 things
- circumventing censorship
- piracy
you forgot drink driving
mostly
they do weird shit with the packets so that the isp cant detect the website names
like putting whitespace
like it fools DPIs and you connect to servers as normal, directly
or delaying the packets in weird ways / sending them in chunks
still have to use a diff DNS tho
ofc
anyways
im glad i installed zapret
since it unblocked literally every single banned werbsite
which includes PASTEBIN
you have no idea how much i suffered cuz of no pastebin access
i would have a heart attack every time someone was like "oh yeah check out my code!!" and it was a pastebin link
my method of choice has been a free tier ec2 instance running openvpn
its pretty robust since most isps dont want to ban aws ip ranges
thankfully havent needed it too much in canada but when i visit england its useful
what did england block
its the other way around, alot of places have ip banned england
theres some new rules around moderating online content that makes it basically impossible to run a website there if you're not a megacorp
niice
except russia, and they're also banning openvpn by its signature
also england ocassionally goes on a power trip and bans an ip range that actually covers more than they wanted to ban
good jobs guys you banned russia today but you also banned every single other ip address in eastern europe for 2 days
also
turkey recently banned
alcohol brand websites
i didnt even know those existed lmao
we have so much banned internet shit it's incredible
im surprised reddit isnt banned yet
did you know 99% of authoritarian states stop censoring the internet right before civil unrest stops
i knew turkey does it
cuz i fuckin live here
usually when a terrorist attack / huge protests like what's happening rn happen
they bandwidth throttle all the big social media websites
Just lie lol
Ahhh yeah I got caught stealing like 500 twinkies from the grocery store delivery truck
I was gonna resell them at the college campus and undercut the vending machine prices
That's what I'd say
🗣️
oddly specific
tomorrow ill start designing the io system in earnest hopefully
the packet stuff i wrote is already obsolete
why not design everything before implementing a single part of it
?
i implemented io packets thinking id do the io system the same way i did in old mintia
after that i decided to read up on plug n play and stuff and ended up changing my ideas for how i wanted to do it big time
i see
Basically I'm no longer satisfied with doing stuff like 80s-y ways
I want to design stuff really flexibly and extensibly and not make goofy 1989 assumptions like "the set of hardware won't change substantially after boot"
Still doing that aesthetically but what I've written so far is already definitely anachronistic for 1989
Turnstiles, fancy scheduler, pervasive lock free stuff, all of these are pretty out of place
you could also go for an alternate timeline kinda thing, like, "what if these 80s companies continued making new tech and x86 never caught on"
The end goal is to run on amd64 at some point and be genuinely useful (although not uniquely so in any way, obviously) and not just larpy and dumb
dont you think it might lose some of its charm by being more "professional"?
So I want to have an IO system that is designed with awareness of plug n play and power management and stuff so that later I can do that stuff on real people computers
That ship has long sailed
Most of the ppl who were following this project since the goofy lua emulator in like 2018 lost interest bc it got "too professional" and that was still during old mintia
are you going to use the System V ABI in the kernel/userspace or are you going to make up your own calling convention?
and also do you have plans to also port to 32-bit x86 or just x64
why would he do that
apart from like
a posix compat layer
why would he NOT do that
cuz it doesnt fit the project goals?
and porting to amd64 by creating your own call conv does
yup
you got it
you dont have to though
amd64 isn't a platform that doesn't already have a call conv
you can just use that
"amd64" doesnt have a call conv
no, it has several
there's the system v abi call conv, and the ms fastcall call conv
dude i know
afaik
im just saying the calling convention depends on the arch
ok
not the other way around
so why do you think it's against the project goals to use an existing call conv for amd64
because he's inventing all of his own stuff?
one arbitrary limitation something like this would entail would be that you couldn't link jackal and C code together
although meh
that depends on the xrsdk linker supporting elf objects primarily
thats why i said he could do it for a posix compat layer or smth
I mean
I like to invent my own stuff but there's no reason to arbitrarily use a randomized calling convention just to be Different
sysv is great aside from not letting you use the carry or direction flag as an error bit on returns
although you can at least return 128 bit structs in rax:rdi so its not all bad
oh you mean x86 not itanium
4head on my part oops
itanium is ia64
i forget intel calls it that
yeah, the naming is confusing
also making an os in 2025 and targeting 32 bit as anything more than an afterthought is shooting yourself in the foot a little
my os fully supports it, and I had intentions to do it from the beginning
but i started with 64 bit stuff and went to 32 bit later
if only itanium was supported by limine...
at some point im going to have to add sparc support to limine and im not looking forward to getting a changeset that big merged lol
but there's no uefi for it 
openfirmware 
openboot is written entirely in forth so it must be good
i mean if limine gets support for openfirmware, why not add powerpc support as well 
if Limine ever gets PPC OpenFirmware support, I'd port it to the Wii 
Wii is 32 bits?
Yup
I mean I though that Limine boot protocol was 64 bit only...
yeah but limine works on 32 bit machines
linux works on 32 bit machines
multiboot2 supports ppc
(i think)
or it might have been mips... i dont remember
sorry for misinformation
mips
but the first two are still true :^)
Also, does Wii have openfirmware?
Also, I think a more interesting target is Wii U 
It's afaik it's 3 Wiis bolted together
not yet
a port of OpenBIOS is being worked on
but no, not yet
it's actually kinda more interesting
it's more of "We took 3 Wiis, gave them performance enhancing drugs, taped them together, then gave it 2GB of RAM, and a competent GPU"
(the Wii had only 88MB, and a custom, not very good, GPU)
so 1 wiiu = 3 wiis = 3 * 2 gamecubes? 
in terms of CPU horsepower? close enough yeah
nice
although at each step they bumped the clock speed substantially
GC -> Wii was 1.5x (486Mhz -> 729MHz)
Wii -> Wii U was ~1.75x (729MHz -> 1.2GHz)
but... close enough
i am implementing IO enqueue for mintia2 IO system (the real one not the one im throwing away)
there are four important data structures
IoPacket: describes an overall ongoing IO request
IoLocation: an element in a list anchored on an IoPacket which contains context for a member of the target device stack. may or may not allocate one, its not required if you have no context that needs to be looked up after enqueue time (simple filter drivers would not require one of these)
IoTrampoline: contains the parameters for the IO dispatch routines; you modify this in your driver to direct the enqueue routine to the appropriate next device w/ appropriate next parameters after you return. the initial one is stack-allocated but extra ones can be allocated dynamically for fragment packets
IoDevice: a member of a device stack and potentially attached to one or more planes of the device tree
the lifetime of a dynamically allocated IoTrampoline would be really brief, only living until the end of enqueue time, so its probably more than sufficient to have a cache of like 8 of them
and almost never hit the actual heap
along with probably a cache of like 20 and 40 packets and locations respectively
the IoTrampoline isnt the same as the IoPacket bc saving space, it contains request initiation information that a physical device might be able to do a more compact representation for in its per-location context (for instance a disk that only supports 32 bit LBAs can store that rather than the fully-qualified 64 bit byte offset; or a serial port doesnt have to store such a thing at all bc it makes no sense)
both are always stack-allocated for synchronous non-fragmented IOs which will be the most common probably
also i might embed the first IoLocation inside the IoPacket just bc its gonna be exceedingly common to have at least 1
also im gonna try to have the whole thing be procedural rather than ever directly setting stuff inside these system-defined structures
im aware this will have some performance hit but if i want my drivers to be as cute as iokit's and avoid the gnarliness of NT's this is the only option
i can use macros for certain things if they only set/get fields whose offset is guaranteed to never change
frinch toste
you've got zone allocator, the time has perhaps come to extend it with slablike features and magazines
perhaps.
i like the new developments in your io subsystem plans btw
i can't copy them (too much runs at dpc level on my side) so you know it's genuine
btw im allowing completion routines to re-enqueue the same packet, potentially to a completely different device stack, and then return OS_STATUS_MORE_PROCESSING_REQUIRED which causes the higher level completion code to drop what its doing and leave the packet alone and just return
the location for the guy who returned that status code as well as everybody above him stays intact
and next time completion runs through, he'll get called again
so in this way you can move bidirectionally up and down the device stack
bc the locations are dynamically allocated i dont need to allocate a whole new packet if i target it to another device stack
i can just kinda do it and itll work and i'll receive a completion callback later like normal
yes, it's really quite flexible, i like it a lot in that regard
this whole thing will almost certainly require more cycles than the old mintia io system (barring jackal codegen advantages)
but drivers will be wayyyy prettier probably
ideally ill be able to come up with sufficient abstractions for it to be iokit level pretty
in particular the trampoline structure needing to be dynamically allocated for associated packets might end up being a scary bottleneck but its basically necessary due to the absence of a location structure until its actually created, not to mention it should lower memory consumption overall
the alternative is to put the stuff thats in the trampoline into the packet header
and then let that just waste some bytes while the io is ongoing (since its useless after enqueue time)
in any case this is transparent enough that i can switch it up later if i want
with magazines or similar caching allocator it should end up with the limiting factor being the cost of a function call in most cases
I got the early implementation of this new scheme pushed before I went to bed last night
Completely untested and highly intricate so it's probably broken in 10 ways but still representative of how it'll be
im going to some lengths to eliminate tricky rules
one of them was that you cannot associate any IO packets with a parent until after youve ruled out all error cases
because there wasnt necessarily a good way to tear down an associated packet
but i came up with a way
basically i just leave it associated and leave it deferred-enqueued at the time that the parent is failed
the parent packet is left intact by the reference taken out by this child
when the child goes to be enqueued, i notice that the parent's enqueue-time status was something other than PENDING (which means it was early-completed either in success or in failure), and then instead of going thru and enqueuing the child i just complete it immediately
with the same error status
idk if this makes any sense to anybody other than fadanoid who has been like following along closely for the last few yrs of conceptual development on this stuff lol
but tl;dr drivers will be able to look a lot cleaner bc they wont have to be as meticulous about this particular error case
this works specifically because the packets arent actually set going inline with each driver's dispatch routines
a whole packet is processed before any of its children are
so any enqueue-time non-pending statuses are known to all the children before the ultimate caller of IoEnqueuePacket receives them
this is important bc of the lifetime of the parent packet
if you receive anything other than OS_STATUS_PENDING from IoEnqueuePacket, you can assume the packet is fully back in your custody (assuming you set it so that it isnt automatically freed upon completion. if you did then its just gone and obviously you cant touch it again)
in particular, you know there are no child packets that depend upon it still out there asynchronously doing something
so you can free the packet if you want or do whatever with it and its safe
i'll peruse it in due course
Lmk if you notice stupid stuff
the io registry planes in xnu are not trees
they are DAGs
something to note
just as a parent can attach to multiple children, a child can attach to multiple parents
cycles i assume are forbidden although im not seeing any logic that checks for them
one example of this in use is the RAID driver
an AppleRAIDSet device object is a child of multiple parents (aka "providers"), which are its underlying disk devices that form the set
lolz!
this could have just been return super::attach( provider );
how silly...
i bet somewhere in the history of that function there was a debug log on line 124
iokit is difficult to understand bc of oop spaghetti
by that i mean the sources of iokit itself
iokit's drivers seem to benefit more than they suffer
not to mention an almost total lack of comments
i hate people who are like "dont write comments. write self-documenting code." and then it turns out what they mean is something like this where the individual operations are obvious bc of well-named variables and stuff but its much much more difficult to piece together the high level theory of what this is actually accomplishing
which could have been explained in a comment somewhere but wasnt
the version of this method from mac os 10.1 is considerably simpler than the modern one lol
ive found studying older versions of systems can help a lot with understanding the newer stuff
there are fewer details obscuring the overall architecture ig
once u understand that then its easier to go back to the more complicated thing and fill in the details
i agree
Yes
The substantially less brain folds version
Top was the implementation of IOService::_adjustBusy in modern xnu (2024) and bottom was in Mac OS 10.1 (2002)
the year I was born
!
you're stupdi cuz they said // a multiply attached IOService can be visited twice and that explains pretty much the entire function which is already very self explanatory
i love how theres a single comment and it means like nothing
may as well not be there
I'm trying to understand the big picture implications not the little mechanical trivia
i get what it's doing but not why
Its difficult to follow bc there's all these asynchronous notifications and stuff which are all indirections into stuff that's difficult to find
Like im still unsure what this busy count is even for
It's not a reference count because there's already one of those
isnt there more a explanatory documentation
I read like all the iokit docs already lmfao
is there a documentation page for the busyState itself
I see no issue 
well it's a do while loop
so presumably they're just trying to eliminate an extra level of indentation
I still wouldn't have done it like that tho
judging by the code they couldve just done
if(!x) return ...;
and then put the do while after it
great minds think alike
wait why is it recursing here
thats still the adjustBusy function right
I do not know the meaning of that flag
I'll find out another day, for now I must sleep
Also I don't rly wanna understand it toooo hard bc then I'll inevitably just duplicate it while doing my own thing
I have my own ideas for how to do a pnp friendly IO system with an iokit esque driver model
They don't seem to line up much with the actual iokit impl
cool
Which isn't to say they're better but I'll learn more if I try them and fail organically than if I just rip off a robust one that's already real
you can also do else for and else switch
i tried to go straight into compiler dev always trying to do the best possible thing instead of just going with my ideas and iterating until it was good
but i agree they should've just done if (!delta) return result;
you can do a billion combinations of those
it just doesnt help readability
eh occasionally it can
if your coding style is based on occasions, it probably isnt very good
I like the naming in iokit but I dislike every other thing about the code style
It's interesting how it seems to be almost an echo of a new kernel that they would have liked to make if they had time bc it's internally consistent in style and design but totally mismatches the mach and bsd parts
wonder what growing a matching kernel around iokit would look like
would be written in c++ ofc
I do have to sleep tho bye
good night
gn
going to sleep at 1 am be like
i fucking missed an exam today cuz i was like "oh the biology exam tomorrow is at like 14 so i can just sleep late and skip the first half of school"
completely forgot about another exam at 9 am
i had to miss a test yesterday since i had a practical exam in driving
damn
at least you had to miss it
my condolences
i was victim to my own lack of memory
true
no about driving
oh yeah i passed
my condolences were for needing to drive
when the russians invade you're gonna have to floor it to save your family anyways
better to learn it now
That's true
although i think there are going to be checks at the external borders if we get invaded
we only barely entered schengen so the borders can be brought back in full force relatively quickly
just cross the border to bulgaria and it should be smooth sailing from there
yeah that's what i was just on about
well i was thinking of crossing to hungary but same idea
oh but you know what we do have
mountains
the russians will have a hard time conquering us on the other side of the carpathians
block off all the roads once they reach the mountains, fuck em
honestly i wouldnt even worry about it now
yeah kinda
if russia does invade it'll probably in a few decades
when they recover from the ukrainian war
the only thing russia can do at this point to romania specifically is send drones and missiles
not a full ground invasion like in ukraine
poland and the baltics are severely more affected because they border russia and belarus
but romania's got the entirety of ukraine as a shield
same
I do...
people who type very quickly and dont reread their code
last time i checked your code didn't look like that
Something's off with the first screenshot
I'd say you sent two different functions
yeah, the first function is IOService::terminatePhase1 and the second one is IOService::_adjustBusy
I think this is just a progress indicator for the matching process
it's a struggle to find much information on what motivated the design
Email Avi Tevanian 
https://www.geeklair.net/~dluke/PCIdevice_tutorial.txt some old mailing list posts from Godfrey van der Linden who appears to have been the main architect of iokit are found here
I'll be damned
snap
i was just about to link it
it's reassuring that device teardown was just as mind bending for them as for me
I've just spent the last 2 1/2 months struggling through learning IOKit well enough to write an ethernet driver for the popular tulip line of chips. I thought I would share my experiences and make it less painful for future aspiring driver writers to get bootstrapped.I'm going to write a...
oh man that code is rough lol
something about array elements being accessed like that also really irks me
at least the naming isnt too bad
lemme see if i can dig up some symbol names from oracledb, those were really rough
lxhmcnv, sltsmnt, lxgt2u, lemfaf, lxuCpCplrStr, skgpospidstr, and lxsCpkgpospidstrtr from quick glance
10/10 symbol names
holy shit what
oracledb despite being an oracle product and apparently a nightmare to work on is a rare story of long running engineering success in the buisness world
the same 150-ish people have been working on it for nearly 40 years
the core oracledb team has had a single public job opening in the last 3 years
i wonder how much time it would take to rewrite it
its around 20 million lines of C, assembly, and C++ for the core database
they have zero unit tests but achieve nearly 90% test coverage using nothing but end to end and integration tests
plus the mountains of perl, java, shell scripts, and other stuff for the surrounding ecosystem
oracle rac is 500mb of perl and shell scripts that somehow works
it also ships with debug symbols, which is a rarity these days
a couple more good symbolskdstf001010100001000kmP hcsXQryObjCpTrvrDspForXAutoExFnPro
alot of functions are also prefixed with the names of people who work there which is certainly an interesting style
anyway yeah funny symbol names 10/10
ahh that makes sense
ig
damn
i have also read its not a very fun codebase to work in though
yeah macro hellscape that breaks all tooling and has 3 day test runs
yeahhhh
"hey, who the fuck renamed hcsXQryObjCpTrvrDspForXAutoExFnPro to hcsXQryObjCpTrVrDspForXAutoExFnPro? it broke half the assembly files?"
i suspect the first three letters are initials
also they have tests
so so many tests
is it really that huge
why
it does alot of things
postgressql also does a lot of things and isnt 20 million loc
its like 1.3M lines of code
oracledb was written before anything was actually standard so it includes all kinds of stuff that postgres just doesnt need to include now
if it aint broke dont fix it ¯_(ツ)_/¯
also their codebase will contain all kinds of government required auditing support code that stuff like postgres just doesnt need
they generate an insane amount of audit logs that are needed to comply with various government agencies
death by a thousand cuts kind of deal where every client wants one specific feature and eventually the codebase grows alot
Oopsie
I got lost ig
i found a recording of the original wwdc 2003 presentation
uploading it to yt rn
ripped off a dvd the internet archive had
Godfrey van der Linden's presentation on IOKit at WWDC 2003
Ripped from these DVDs: https://archive.org/details/Apple_WWDC_2003_DVDs
He uses the word "mind bending" lol
Woahh
I just realized my packet enqueue scheme lets you go up a device stack as easily as it lets you go down
Gonna be suuuper useful for pnp
how the fuck do people read that code
the second one maybe "hcs X Query Object Copy Traverse Display For X Auto Extra Function Prototype`?! but the first one I cant decipher
Extraordinary synchronicity
and thats probably what he said when they got device teardown working reliably.
things are slowly coming together
in my head
im glad i havent rushed ahead with anything other than the basic packet enqueue stuff bc gears are definitely still turning
wowza
something clicked suddenly
WHICH IS:
you only need to worry about synchronization issues for requests entering the device stack at the top level
in the case of iokit storage drivers, the top level is always IOMediaBSDClient
so i went to that source module and bingo
its the junction between the BSD layer the iokit storage drivers
and is full of synchronization goodies
i also realized my io requests have to be polymorphic
targeted toward either an FCB or a device object
why can't the device object have a single FCB associated with it
basically bc itll be redundant info
i want a device object to only have an FCB if it is being exposed through the namespace
this FCB will be managed by a pseudo filesystem driver (think of it like devfs) that accomplishes basically the same tasks that IOMediaBSDClient does in iokit
basically making sure that the device stack doesnt disappear while the request is inflight
a device stack will actually be able to disappear from underneath a filesystem mounted upon it, just not while an io request is actively ongoing
basically by the filesystem only accessing the device thru the FCB, and the FCB just gets "detached" from the device stack when it goes away
further attempts to communicate with the underlying device will yield IO error statuses
if a device your driver is managing physically disappears then the bus driver will generate a termination packet that travels up the device stack and its your job to cancel any inflight IO requests with an appropriate status code asap (and prevent any new ones with the right error status as well)
so that the memory can get cleaned up promptly
a lot of this explains how iokit was seemingly magically able to call up and down the device stack without ensuring at each level that the next still existed and whatever
basically the guarantees were already made at a higher level
which ofc makes sense, its the only logical explanation for how they were doing that
but its nice to find the component most directly responsible for doing that
cool timeline of the earliest mac osx (rhapsody) development
in 1997
thats actually wild that they ported nextstep to powerpc and got the blue box (classic environment) running on it in literally 3 months
tbf the blue box pre-existed from Copland, it was the only thing of Copland that survived iirc
something i knew but didnt pay much attention to was that the development of OSX was a nearly NT-level undertaking
they werent quite developing a 99% new modern OS from scratch from the ground up as quickly as possible (NT was the last time anybody ever succeeded at that (Copland was the last time anybody ever tried in general)) but they probably wrote just as much code or more
I think Apple had been suffering under similar circumstances (they were stuck with the 68000 while MS was stuck with 16-bit x86)
Have you considered reaching out to them?
i feel like ive bothered enough cool boomers and have used up my boomer bothering budget
if i bother more ill become known among the boomers as a notorious boomer botherer
dont want that to happen
its crazy ive been at this for like 5 yrs and im only just now getting to concepts that are younger than i am
well, almost
they were at least being presented on while i was a baby
rather than 10-30 yrs before my birth
this exact io system design im about to implement at least will be considerably younger than me
but it uses concepts that are quite a bit older than i am, just in a new combination
im writing the quantity of comments that i wish iokit had
the biggest one there is for a thing i thought of in the shower that wont actually be needed for some time
allegedly im committing a cardinal sin of over-designing things before i actually get there but i dont have the skill issues of tech influencers who say stuff like that, so im p sure itll all fit together nicely
I don't think any level of skill saves you from that issue
well this entire kernel is already an exercise in "doing stuff before i need it"
It's fine to design stuff in advance and if you're doing this for your own enjoyment there's also little cost associated with it
but it's still unlikely that the final design after gaining implementation experience will look anything like what you designed initially
well thats the thing, i already did a big fancy kernel that implemented all these features (page swapping, async io, driver stacking, etc), and it took me like 3 yrs and didnt rly look anything at the end like it did at the start
im basically just doing the same thing again but with more brain folds
i feel ive already put in the 90% learning cost which is learning how to structure stuff overall which forms the large majority of the effort bc failing at that causes you to redesign and rewrite big swathes
especially with page swapping lol
but we'll see how this all pans out, im still optimistic although itll take a long time
im already 9 months deep
Yeah, it's true that you'll need to do less redesign in that case but that's not because other ppl have skill issues, it's rather because this is already your v2 or v3 ;D
true!
i was joking about that part tho
i just like saying mean things about tech influencers
also this time im doing tonnns of work to limit kernel stack usage
the IO enqueue mechanisms, object deletion, and other stuff are built around work lists, whereas call-through is used for the same thing in other kernels
the goal is for the maximum call depth to be deterministic and like less than 10-20
so i can use a single page of kernel stack
everything related to computing was invented before 1970 really
its all been remixes of the same concepts and ideas since then
not exaaaactly
That's not really true. Many designs that were reasonable in 1970 are not reasonable anymore
most lock free techniques are newer than that for instance
In 1970 we didn't have SMP, large multi-level caches, asynchronous devices etc
brb furiously googling when the first cpu with cmpxchg was created
nothing even uses cmpxchg
at the hardware level
its all ll/sc since the late 90s at least
created != used
can i adjust my statement to like 1979 or so 
if you want to ask when modern systems designed started, look for the first devices that used command queues in RAM instead of register interfaces
and these probably appeared in the mid 90s
probably earlier in the server and mainframe space
up to that point you'd still drive a device by writing a bunch of registers on the device itself
i was shocked at how modern (in nature) the capabilities of like the early 90s Alpha mainframes were, it was just slower
huh, i always though cmpxchg was picked mostly because it was easy to implement in hardware
the more you know
no, ll/sc is MUCH easier to implement in hardware
yeah
at least in smp systems
ll/sc is literally just: once I have a cacheline in exclusive mode, i can do whatever i want w/o other CPUs seeing it
dont most atomic instructions have to be implemented somewhere in the cache controller rather than the ALU or am i mistaken on that as well
yeah it basically rides on the cache coherency traffic youre already doing
no extra cost ish
well theyre all decomposed to ll/sc sequences on x86
so no
i need to brush up on my hdl quite badly, its a bit of a weak spot for me
i have a fpga dev board i feel i need to use it more
the fpga is to small to synthesize real™️ stuff but too large to ever fill with a personal project
and forward progress can be guaranteed by letting load-link refuse to write back the cacheline until X instructions have been retired
i swear no matter how much i stare at atomic code and write my own it never quite makes sense why it works
my third eye opened when i implemented ll/sc by simulating a MESI cache coherency protocol in software
for my smp emulator for my toy arch
imho acquire/release semantics are quite intuitive
i get the C++ side of things mostly, its just load store reordering relative to an instruction
the c11 memory model is very easy to understand compared to everything that came before it
its the actual atomic algorithms beyond quite basic cas loops that elude me somewhat
but yes, code that needs stronger barriers than acquire/release is not that easy to understand
despite implementing a lock free mpsc queue, rcu, and a whole pile of lockfree stuff i just never quite get why it works
i know enough to be dangerous which is perhaps the worst place to be with this stuff lol
for example, sometimes you want to write code that first publishes data and then checks if it needs to ping consumers
this goes beyond just acquire/release
and may require a full memory barrier depending on how exactly the code is written
the implementation of io registry planes in iokit is strange
when you create a plane called for instance MyDumbPlane it will create the strings:
MyDumbPlaneParentLinks
MyDumbPlaneChildLinks
and then it uses these as keys into a global OSDictionary (hash table) which yields an OSArray
im not quite sure why this isnt just two pointers
what is OSArray
so pointer + size + cap?
anyways if OSArray can be relocated by resizing maybe thats why theyre using those strings?
no the actual OSArray object has a static location, the buffer is what moves
itd break its membership in the dictionary if it itself could move
could the hash table impl be moving it
its not
hmm
i would say "maybe it's so that you dont have hanging pointers and fail when trying to use those keys instead" but like that makes 0 sense in this context
im at a loss
the only thing i can think is that it has some introspection purpose
oh wait
i think i get it
its not global after all. this OSDictionary is per io registry node
its to avoid storing links for all possible IO planes within each registry node, so that you can create an arbitrary number of them at runtime
a plane btw is like a whole node graph
a DAG
used to model relationships between devices
okay this is all making more sense now lol
good lord this is memory-hefty though
i got confused because C++ has the same syntax for accessing globals and class members lol
and i was reading it with C brain
also im reading the mac os x 10.3 and modern iokit sources side by side to see how they changed
terrifyingly, the 10.3 one had a complete rwlock implementation special for the io registry
by nowadays it uses a generic one exported by xnu
i found maybe the most repulsive reddit comment section in history https://old.reddit.com/r/linuxmemes/comments/vq6vtq/xnu_sounds_cool_though_ngl/
it's just copypastas lol
exactly
the repulsive part is that those are somehow real people who spent their time posting inane spam for fun
and not bots
lol
honestly it's like the lowest effort content ever
just CTRL+C CTRL+V
they dont even change the damn thing
is it really though
who cares
there's something to be said about people who argue names
i had a funny idea for dequeuing timers safely
such that like once you dequeue it you can be sure nobody will touch it after the dequeue call returns (and it can be deallocated or whatever)
for context i have per-cpu timer trees and a per-cpu timer expiration dpc
basically when i go to dequeue a timer and the caller specified that he'd like it to be completely quiescent after the dequeue (which has to be specified bc sometimes it doesnt matter so much, like if youre just dequeuing and re-enqueuing to change the timeout and arent about to free the timer or smth)
if it's enqueued to the current processor, i can just remove it from the timer structures safely and return. this is fine bc i know the timer expiration dpc isnt currently running because IM running.
if its enqueued to a remote processor, i can migrate the current thread to that processor and then dequeue it lol
and then just return
i think a similar/identical thing would work for quiescent DPC dequeue
so then i dont need a DPC barrier bc i can just do this
the "i know the DPC isnt running on that processor because IM running on that processor" trick
also i can make it the caller's responsibility to decide whether the timer callback or DPC routine need to be executed
i already return FALSE if the object was not actually enqueued, TRUE if it was and i dequeued it
with these extra guarantees, this can be used to know for sure whether the routine executed or not
if it returns TRUE and you need the routine to execute (maybe it frees up some resources or something) then you can explicitly call it yourself
nvm, does not work
for timers and dpcs both
you need to dequeue them to ensure that a dispatch will not begin on another processor in the future
and then do a full dpc barrier to ensure that a dispatch is not ongoing in the present
this is relevant especially for like driver unloading
i havent been charging full quota for IO packets bc itd make the overhead of allocating the packet locations and stuff even more unbearable
but i should charge at least quota for the packet header
so that Something is accounted even if its not the full thing
its the piece with the longest lifetime as well
i could also completely forego it and just make outstanding async IO requests their own resource accounted separately
kind of annoying playing with an old mintia disk image and going like "man i wonder if ill ever be able to make something like this" and then remembering i DID make something like that and i had to THROW IT AWAY because 15 YEAR OLD ME thought itd be a good idea to design the worst programming language in history
at least im making the most of the opportunity and im not just rewriting the old one 1:1, flaws and all, like the original plan was to do
also iokit is really cool
i love the flow of IO dispatch and the driver matching process
yeah
i like the overall design but i feel like an obsession with quality was missing during the implementation lol
"such drivers and nubs through the device-interface mechanism"
thats just a typo
yes in the sense that youre not supposed to directly use it anymore, driverkit iirc is a userspace driver framework that youre supposed to use instead
but they didnt get rid of it they just privatized it
whats it supposed to be
confusingly the new "driverkit" shares a name with nextstep "driverkit" which was the father of iokit
no relation
so it went driverkit -> iokit -> driverkit (different one)
nextstep driverkit docs
probably they did a new one for OSX instead of reusing driverkit because it wasnt plug-n-play ready
or power management ready
driverkit doesnt seem to have had any concept of the IO registry which is integral to how iokit implements those things
so it wasnt suitable for a consumer OS
if they had some compelling reason to maintain nextstep's existing driver base then they would have had to retrofit those features onto driverkit
like they had to with NT
which would have made a horrific mess (like it did in NT)
luckily they were putting it on apple machines that couldnt make use of any of the existing nextstep drivers anyway so they were able to just do an all-new IO system lol
prob why its so clean compared to the modern NT one
also its apple so they can just tell developers "well fuck you you now have to write your drivers against the new api" :^)
nt uses tons of globals tho
landy famously de-globaled almost the whole memory manager though
partition objects
ah, in xnu all mm state is broken down in globals ?
vm_compressor - memory compression i assume
yeah like it was in old NT
if XNU added NUMA support theyd probably scoop this all up into something similar to partition objects
and itd probably be suicidal-thoughts-inducingly tedious
Remind me, sir, what was that?
essentially just an object that contains all of the formerly global state from the NT VMM
one partition object per NUMA node?
and i mean all of it
yeah
each one has its own page lists with their own locks, they even each have their own pagefile
transferring pages between them is an explicit operation
which i dont believe is done in the numa use case, but theres another use case which is creating an airtight memory sandbox for some group of processes and transferring page frames is meant for that (in theory - im unaware if this is actually done)
I see
Seems like Windows has been aware of NUMA for quite a while
im not doing numa support but i have put my vmm state in a partition object
just because its extremely easy and low-cost to do from the ground up
and would be extremely tedious later
some of it still isnt numa-fied though like the kernel heap is still global
(cuz im not doing numa support)
but thatd be easier to do later
dedicate a big chunk of kernel space for a heap for each numa node and have them allocate preferentially from the closest heap
im just generally poking around xnu lately
especially iokit
memory compression would be cool but its not in the plans rn cuz theres already so much to do
memory compression is very nice
i wanted plugnplay and power management in the mintia2 io system so i studied both modern NT and XNU's strategies and i liked XNU's better so i was gonna model it vaguely on that
Yeah, pretty interesting, recently fixed a bug related to the compressor : an inversion occurs when a low pri thread gets stuck in the compressor while a high pri thread waits for the same page
I meant to reply somewhere else
i like to believe the NT guys would have come up with something less clusterfucked if at all possible
Is it really that bad there
yeah theres like 50000 intricate rules for everything because of the way they had to retrofit it on the old IO system
the "WDF" (windows driver framework) was an attempt that came a bit later to shield people from this by wrapping the nasty native IO system for you
but its still not nearly as clean as iokit
to be clear i dont blame them
iokit was designed from a clean slate with all the features considered from the ground floor, while the NT people had to retrofit them onto a driver model that was already like 10 years old and could not be sacrificed
so they had the harder task by far
they probably did an okay job considering that lol
I might be wrong, but I think they have a more modern framework?
"all" is relative here btw lol
UMDF
i mean the big ones like plugnplay and power management had to be retrofitted such that the old drivers would continue to work perfectly whereas iokit always had them - both have had to add new major features since then im sure
yeah
i havent compared this to driverkit (which iiuc is the macOS usermode driver framework) so i cant comment on the relative "cleanliness"
im just talking about the kernel mode side
I believe it shifts development outside the kernel?
Starting with Catalina Apple moved to a new SDK, yeah
iokit is still very pervasively in use for many drivers though right?
is the intent to phase that out completely one day
have all drivers in usermode
or is it just deprecated as an outward-facing thing but still has a long planned life ahead of it for apple's private use
i really should study these usermode driver models
but its a "later" thing
like i mentioned im already planning like 5000 new (to me) things for this kernel
its getting major second system effect already
if i plan even more stuff like usermode peripheral drivers w/ corresponding fancy framework or memory compression or something else i run the risk of not finishing it until after i graduate uni
and id really like to have it done by then
i can do that and then revisit it later lol
im realizing this is becoming less of a toy kernel and more a pretty substantial research project at least for 1 person
there are published research kernels that were less ambitious
from like the 90s lol
granted the ones im thinking of were all dumb microkernels by masters students who wanted to get it over with asap
but the planned/current feature list includes:
- page swapping, including of most kernel memory
- fundamentally async io system (including the filesystems)
- driver stacking
- name cache (like linux dirent cache) based vfs
- loadable/unloadable drivers
- plug-n-play, power management
- robust resource accounting
- scalable locking (turnstiles) with priority inheritance
- SMP w/ nontrivial scheduler w/ fine-grained locking
- fully preemptible (that is, spinlocks forbidden) outside the scheduler and primary ISRs, fully interruptible scheduler
- fully featured FAT driver & driver for custom journaling filesystem (TBD)
- once ported to amd64, an IP stack and linux compat layer will be written
- stacking window system for the native personality (linux one will use the typical wayland/whatever boringness)
- native userspace, including basic suite of command line utilities and desktop apps
plus lots of other stuff
these are all kinda hard
but i think i can do it in like 2 years
well. i can at least do the native bits in 2 years
the linux compat thing on its own (trying to run a substantial linux userspace, binary-compatible, on my own kernel) could easily take another year or two
question: why journaling fs?
bc if im doing custom everything way overengineered to an extent that literally anybody would advise against and severely doubt i would ever get done then that should include the filesystem too or its lame
and not a b-tree FS or a log structured FS
oh i see the question now
(aka basically btrfs and f2fs respectively)
i do not believe b-trees are on the same axis as the other things you mentioned?
i think you can have a journaled or log structured fs that uses b-trees
i dont think so?
why
dunno about the details
by btree i mean using btrees and copy-on-write for everything
oh i see
which doesnt require journaling
thought you meant like btrees for directories and storing file extents and stuff
nono
New system extensions are designed to be used everywhere possible. Essentially, kexts are deprecated ; you should be using system extensions (dexts)
i like how this dodges answering my question kinda
i designed a "mintyfs" i was gonna start implementing just before i decided to trash the entirety of old mintia
and it was super boring because i was afraid of both journaling and b-trees
so im kinda glad i didnt waste time implementing it
it was kinda an HPFS clone but with all the cool parts gone due to fear
a fancy new filesystem prob will not be part of the base system
ill probably just have a fat driver and an aisixfs driver like old mintia
and then move on
ill come back and do fancy fs later
cuz it deserves to be its own major project taking months
but theres no time for that in the current plan
isnt driverkit a user mode framework for iokit
so its based on iokit
why aisixfs and not ext2?
other than NIH ig
because thats how im currently formatting the test images
ah fair
the disk tool in the sdk can be extended with new filesystems though so i could switch to something like ext2
but yeah the NIH factor was the motivation here
aisixfs ofc is literally just a stupid fat clone but with inodes
why does it have inodes? bc aisix cloned the dumb BeOS vfs design where vnodes need a unique number and i didnt want to figure out how to make that work with a non-inode-based filesystem
so i added inodes
originally there were no inodes and it was just straight up a fat clone
cant you make a better FS
thats an ntfs clone instead
call it
limnfs
mintyfs is already named to rhyme with ntfs
counterpoint you are turkish
counterpoint the majority of your country voted for trump
ouch! i mean your difference between "minty" and "menty" is probably not reflective of that in american english
most americans would pronounce those identically
not all though
the majority of your country voted for trump anyways, get destroyed libbie
im unsure off the top of my head what accents would distinguish those but ik some would
I answered "is the intent to phase that out completely one day have all drivers in usermode"
thats different but now it doesnt rhyme with ntfs
n is read like
ik im messing with you lol
an
and manty is read like man
so you get like
the same an
instead of minty only having nty in common
unless NTFS is read like intyfs or something
it is
why would it be pronounced differently
literally like, eenty fs???
not eeeeee
i thought it was read like "an"
i think we are suffering from not having a standardized way to communicate phonemes
luckily theres a solution to this
wow
put that in here
Read IPA notation
it does a great job of reading it
copy this "ɪn.ti.ɛf.ɛs" exactly
and press read
with [us english] accent selected
in the drop down
hmmm
it's more of an ı
but theres a bit of e in there
turkishly speaking
i see why it doesnt rhyme now
but that doesnt matter, how?
because aisixfs is a dum fat clone, wow.
now i shall leave, ka-chow
inversion here means priority inversion ?
interesting to see a case of it
i think will was afraid of priorit inversions in mm code
and implemented turnstiles , they are used in solaris and macos
I have them too ; in fact, I'm using sleep with an inheritor
When another thread waits for a page it first checks a special hash table for a registered page worker (if one exists) - and if found the thread sleeps using an inheritor mechanism propagating its priority
it's enn-tee-eff-ess btw, with the same e before the n as after the f and s
but i also think mintyfs and ntfs rhyme because of the -n-tee-eff-ess part
i like mine better
interesting , is yours implementation open or not
i just realized the 10 yr anniversary of me trying to make a compuer from scratch is coming up lol
well the 9 yr anniversary is coming up
thats the first attempt, which i still have (no i will not post it because its 14 yr old me code and its terrible)
ill note that it had fixed width 5 byte instructions
and it had an extremely bad language called "X" (which was a placeholder for a better name that i never came up with) which looked like this
glad osdev discord didnt exist back then, i might have embarrassed myself trying to post about this
this was so long ago it predates me regularly using discord at all i think
lol the language literally did not have support for expressions
it only did control flow, everything else required inline asm
i prob couldnt figure out expression parsing when i was 14
jackal would have blown my mind
nextstep driverkit source code
apparently the very earliest source releases of darwin from like early 1999 still had it
it even has references to the unreleased m88k-based "NeXT RISC Workstation" (NRW)
@hybrid condor u might be interested to see the objective C based father of iokit
TOKEN RING!!!
#if defined(hppa)
#import <machdep/machine/pmap.h>
#endif
lol PA-RISC support
almost forgot nextstep ran on that
seems absolutely ancient
much older than the other files
only half as many lines as its then-current version IOLogicalDisk.m
and theyre worse
@warm pine minoca has iterative io enqueue
idk if i knew that and forgot
you might wonder how its checking a bit in the IRP to tell whether the stack level pended it
because that should mean custody has passed to an asynchronous context that could complete it at any moment (leading to the IRP being freed)
afaict its because an IRP is a full object manager object
and has a refcount taken out here
imo this is a mis-abstraction
because thats like the only real use of doing that?
and the extra overhead is quite severe
ofc you need a count of remaining child packets in order to defer completion until the last one has finished
but that's quite different from the full overhead of an Ob header and everything
i agree, why would you do it like that
IRPs don't need object manager machinery as far as I can tell (other than the refcount possibly?)
one cool thing you could do with it is actually allow people to have handles to IRPs
and you could selectively cancel an IRP or whatever, using this handle
but this is a relatively rare thing to want to do
hmm true
if you want to provide that functionality you could create a full object wrapper around a non-ob IRP structure, which you only use when theres an async request
and avoid the extra overhead on synchronous requests
where you just create a normal IRP
that makes sense
they use the ability to wait for an irp object or to signal it with ob api
yeah i just mentioned this
and i still think its weird they do it for every irp
because most of the time you dont care about doing that
vast majority of the time
even if you do, usually completion ports are still lighter weight and the superior option
so it doesnt win on performance and im unsure it even wins on elegance because completion ports are designed to be easy to use with worker thread pools whereas this api would be more difficult
so youd probably just use completion ports anyway and forego this entirely
if both existed
and if only this existed, itd be a worse system for it
its just their name for APCs it seems
which appears to only be what a special kernel APC is in NT
Yeah that's what I immediately was struck by
I return the pended code instead
But what if it's anyway completed? I'm away from home and can't look any closer at their code
In my case if an iop is pended then a return code must be used to prevent reentry to the processing - as completion (rather "continuation") of a pending iop restarts processing in opposite direction
they removed it the same day when added lol
i think i know why
not having them from the beginning, they probably didnt take care to make certain things APC safe by raising irql to block them out
after implementing this they prob quickly realized "oh this just made like 5000 race conditions of a thread with itself which i dont feel like fixing so nvm"
representing a DAG by giving each vertex a distinct set of parents and children is so convenient for locking
makes fine grained locking really easy lol
this is turning out way too clean
im scared
only needing to lock one node to be able to get safe-to-use pointers to any of its relations is pretty cool
this is a good DAG representation. feel embarrassed i didnt know about this before
pretty basic data structure knowledge
if anyone here likes mintia but thinks vaporwave is cringe youll be disappointed to learn my personal soundtrack for mintia is almost entirely vaporwave-adjacent tracks and always has been
the music does give a kind of an 80s vibe
the fact vaporwave is composed of 80s/90s samples and my brain likes to associate that with mintia is def not a coincidence
uhhh i understand it theoretically but ive never dived deep
well do you have any idea why this isnt returning false?
are you sure thats lambda calculus and nothing else
it does let you define variables
as in
not lambda calculus variables
but like
you just name a lambda expression
thats how variables in forth work as well
pair expands to (λx. (λy. (λf. ((f x) y))))
false expands to (λt. (λf. f))
true expands to (λt. (λf. t))
second expands to (λp. (p false))
theoretically bitadd false false should be returning pair false false
which should then be reduced to false by second
but it's not
this is extremely crucial cuz i need binary representations of numbers in order to make this fantasy arch not take 2 seconds per cycle
church numerals are too space and time inefficient
if theres a moment i could have answered this question at all
its not this one
barely know that shit and ive been up like 24+ hours
damn
do you know someone who has expertise in this area
the r/pl discord is full of people who are into that kind of thing
just do haskell
functional programming ppl are all super into lambda calculus
it's lambda calculus but useful