#MINTIA (not vibecoded)

1 messages · Page 11 of 1

warm mural
#

@twilit smelt quick question, https://github.com/xrarch/mintia2/blob/main/OS/Executive/Ke/xr17032/KeException.jkl#L178 shouldn't checks like these (there are multiple occurences of it) also include whether or not IPL < DPC? Because I don't think software ints should be dispatched at IPL_DPC unless I'm misunderstanding the code, I had to add this check in my kernel and was wondering if you also had come into the same issue that made me add it, so I checked if mintia also did it

#

maybe I'm also missing something else

#

this is what I was missing

#

ok that's smart

#

but then wouldnt that result in a negative shift for ipl=0

warm mural
#

what is the defined behavior for those

#

in C they are UB

twilit smelt
#

That never happens

#

The macro is never expanded with ipl 0

warm mural
#

oh yeah right

twilit smelt
#

Software interrupts at ipl 0 aren't a thing

warm mural
#

there are no softints at ipl=0

twilit smelt
#

ipl0 cant have soft ints by definition because ipl is unsigned and all interrupts with ipl >= current ipl are masked off

#

so youd need an ipl below 0 to have any soft ints at ipl0 be delivered

#

which donut exist

warm mural
twilit smelt
#

ive been slacking on mintia

#

ewwww netbsd has a giant mutex around its buffer cache

#

also i learned what the xnu strategy for avoiding priority inversion with shared locks is, since you cant reasonably inherit priority through shared holders

#

they just revert to priority ceiling

#

when you take an rwlock shared, your priority is raised to a maximum

#

@warm pine

warm pine
twilit smelt
#

source: cogolein

warm pine
#

actually i will admit that i secretly harbour a suspicion that it could be that priority inheritance is a cargo culted feature, at the cost of the complexity in implementing it, and reduced ability to reason about the priority at which some work is carried out (since now there are countless ways it can be dynamically influenced), and that simpler strategies could be superior most of the time

twilit smelt
#

VMS only ever did priority ceiling, still does

#

when you take a kernel mutex it raises your thread to max priority until you release it

#

NT was also spec'd to do this and it actually does so in the april 1991 mips build, but by september 1991 theyd replaced it with random boosting

warm pine
#

i am in no way confident about this suspicion and on the contrary i think there is a strong chance i could be wrong, but i do think it's a possibility

raven drift
#

I think the issue with these is that they are not very useful for real time applications

warm pine
#

trivial to reason about

#

random boosting is random so it's out

#

it's also not a technique i know of being used outwith the very particular case of active deadlock breaking by nt

twilit smelt
#

the lowering part of priority ceiling in april 1991 NT

#

if the thread's held mutex list is non-empty v2 + 24 != *(_DWORD *)(v2 + 24), return

#

otherwise it became empty, so the priority is lowered back to a value previously stored in the thread

#

also notice the elusive KeReleaseMutex

#

another thing that was gone by september 1991

#

the mutex object

#

this is a VMS-ism that disappeared by first release of NT

#

there are several others

raven drift
#

the issue with priority ceiling is that you have to know the ceilings of all locks in advance, don't you?

twilit smelt
#

VMS (and ancient pre-release NT) would just raise to max priority

#

max user thread priority at least

#

with the assumption the kernel threads will behave well

#

yeah

#

if the thread's base priority was below 16, its raised to 16

#

which is the largest user priority

#

16-31 are real time priorities

#

actually this is the lowest real time priority

#

not highest user priority

#

so this thread couldnt even be preempted after taking this mutex

raven drift
#

that sounds like it could easily be used to starve the rest of the system

twilit smelt
#

no because kernel codepaths are controlled so you can just Know there arent places where a mutex is held for a veeeery long time without blocking

#

this only applies to kernel mutexes

#

i disagree with real time threads not being preemptible though

#

if they must be nonpreemptible then this really should have been highest user priority rather than lowest real time priority

#

imo

raven drift
#

what's the point of having more than one real time priority if real time tasks are not preemptible (by higher prio tasks)?

twilit smelt
#

it still determines the order the next one will be selected in when the current one blocks

raven drift
#

ah

#

this indeed sounds like a weird choice though

twilit smelt
#

this practically makes huges swathes of the kernel nonpreemptible

#

clearly they had a sit down and decided the entire idea was bunk at some point between april and september 1991 and just replaced it with random boosting

#

@warm pine behold: the VMS balance set mechanisms, in NT

#

im not completely sure what these are doing other than the first is presumably sweeping the ready queues and removing all of the excluded process's ready threads (thereby forcibly suspending them. bad idea, deadlocksville, better to let them run and suspend themselves at a quiescent point e.g. before returning to usermode) and the latter is unblocking them. the former in preparation for a whole-process swapout and the latter upon bringing it back in

#

i just had a very QUAINT idea

#

i could literally look at the VMS sources for this and theyll probably look extremely similar but in VAX assembly and commented

#

relevant code should be in here

#

already a good file

#

a question some of the off topic channel dwellers here should be asking themselves

#

special cases for multithreaded processes

#

fun fact: they didnt add true multithreading to VMS until after the Alpha port, so this is VAX assembly that never even ran on a VAX

dapper mulch
# twilit smelt

Is this decompiling? Interesting, what __fastcall for mips looked like. I only know o32 😁

mortal thunder
#

i think i gave him that one

digital pivot
digital pivot
#

why did they give it up?

#

afaik modern nt doesnt have such thing

twilit smelt
#

yeah it doesnt

#

so i actually experimented with implementing a balance set in old mintia and multithreading really does complicate it

#

the need to suspend all threads of a process

#

this isnt actually hooked up to anything in april 91, its implemented but never called

twilit smelt
digital pivot
twilit smelt
#

it seems VMS forcibly suspends all threads of the process on the spot

#

it does this by removing any ready ones from the run queues

#

and placing them on a list, anchored in the process, of threads that need to be re-readied when the process is brought back into the balance set

#

and any that are unblocked after the process has been selected, are placed on the same list

#

so when you call the routine to remove a process from the balance set, it returns with the process Really Removed

#

the way it avoids certain deadlocks is to special case the holding of various mutexes in the kernel

#

where if any threads of a process are holding one of those mutexes, the process is ineligible for removal

#

NT doesnt seem to have any checks like that implemented in this "stub" implementation of KeExcludeProcess

#

and its possible it was a real pain in the neck and they decided it was the wrong way to go entirely

hybrid condor
twilit smelt
# twilit smelt the way you do this is critical

also if you have each thread suspend itself when it gets scheduled back in and is about to return to usermode, it could take a loooooooong time for that to actually happen and that defeats the purpose of process swap-out which is an attempt to rapidly obtain lots of memory

#

i think this was the main issue with the way i tried to do it that made it suckish and not work well

#

i have a thing now called "lazy APCs" which get dispatched on return to usermode and also whenever the thread does a wait on behalf of usermode (signified by calling the wait function with mode=usermode)

#

if a wait is on behalf of usermode that signifies a few things like that nothing depends on anything on the thread's kernel stack, so it can be swapped out, and also that its not holding any important locks

#

so this would be a safe point to do the suspension

#

i could also temporarily boost their priorities really high to make sure they suspend themselves quickly

#

once the last one suspends itself it kicks off the remainder of the process of immediately yeeting the process out of memory

#

NT actually does do whole process swapout, but it only does it opportunistically when all threads of the process have been in a wait-on-behalf-of-usermode for longer than X seconds or so

#

it doesnt do anything forcible like this

twilit smelt
#

i have three kinds

digital pivot
#

lazy apcs is your invention?

twilit smelt
#

to my knowledge yeah

#

they replace the function of "normal APCs" in NT

#

which are much scarier and more difficult to work with

#

"special kernel APCs" in NT are identical to my "kernel APC"

#

"normal kernel APCs" dont exist for me and are subsumed by the "lazy APC" which is only dispatched at the times noted in the comment

#

normal kernel APCs basically are dispatched whenever an "APC disable count" is zero inside the thread, and IRQL < APC_LEVEL

#

normal kernel APCs can take more locks than special kernel APCs and can initiate IO and stuff

#

so filesystem drivers have to explicitly increment the disable count upon entry and decrement upon exit

#

which imo is very fragile and fraught with terror

#

using KE_USER_MODE waits as a canonical quiescent point within the kernel is much easier to keep track of

#

i think this would be basically perfect for use to implement the balance set exclusion suspension thing

#

this is an example of that count being incremented in a filesystem driver, the FsRtlEnterFileSystem() macro literally just increments the normal apc disable count for the current thread

#

they have to remember to do this and undo it perfectly in like dozens of places

#

if not hundreds

digital pivot
twilit smelt
#

imo at least

digital pivot
twilit smelt
#

priority inversion avoidance probably

digital pivot
#

aaah

#

right

teal trench
#

private internet access

hybrid condor
twilit smelt
#

it only works if the time between such waits is bounded and ideally fairly short

#

and any unbounded wait can be interrupted by LAPC delivery

#

so for example any wait on like file IO needs to be that

dense vigil
#

@twilit smelt i heard u were good at evaluating kernel quality

#

wondering if people might be willing to tip me regular monthly funding to finish it up

#

and

Demand paged

#

they claim to have memory and cpu hotplug but that seems to be bullshit

warm mural
#

also only 32-bit x86 major L

dense vigil
#

Yeah

#

Look at the linker file

#

It looks insane

#

And why is there a Trib suffix everywhere

warm mural
#

idk what trib means

#

it doesnt seem that bad tho, it does seem to have numa stuff

dense vigil
#

Have you looked at how its actually used?

warm mural
#

wheres the linker script tho

dense vigil
#

From a quick glance its kinda not

warm mural
#

I cant find it

dense vigil
#

Uhh lemme see

twilit ingot
dense vigil
dense vigil
twilit ingot
#

?

dense vigil
#

Oh u don't know what aml is?

twilit ingot
teal trench
#

surprise unplug obviosuly doesn't workl

twilit ingot
#

ah XD

dense vigil
#

U get notified of a request to unplug

warm mural
#

isnt there also CPU hotplug that's possible

twilit ingot
dense vigil
#

If you successfully do it then you tell the firmware it can be removed

dense vigil
twilit ingot
#

i might look at implementing that

#

but idk how to even test it

dense vigil
#

Its very simple

dense vigil
twilit ingot
#

oh

dense vigil
#

Device_add ...

twilit ingot
#

and to remove?

dense vigil
#

Ur not gonna believe it

#

Device_del

twilit ingot
#

XD

#

but it deletes it instantly or it will wait till the os says it's ok?

dense vigil
#

Its simple if u have aml support, which this kernel doesnt and the rsdp parsing i see there is crappy also

dense vigil
twilit ingot
#

i have uacpi, so i just need to implement listeners for it?

dense vigil
#

Yep

twilit ingot
#

cool

#

time to add it to my TODO list

warm mural
dense vigil
blissful smelt
#

exactly 15 year old project lol

#

as of today

warm mural
#

but how will it "wait" when you can just yeet the stick out

dense vigil
#

If u do that it just crashes

twilit ingot
#

it will tell you when to remove them i suppose

dense vigil
#

U push a button and wait for LED to get in a certain state

#

Same as PCI unplug

warm mural
#

ahh

dense vigil
#

0 difference there

#

But to unplug u must online it as movable only on linux

twilit ingot
#

that's a very cool feature to have

dense vigil
#

Otherwise it will always deny unplug

#

And nt just always refuses to unplug

twilit ingot
#

lol

dense vigil
#

At least images I've tested

twilit ingot
#

are those features only on server boards?

blissful smelt
#

wait so I'm guessing it's somehow possible to figure out which sticks of RAM have which address ranges?

#

kewl

twilit ingot
dense vigil
dense vigil
blissful smelt
#

i forgot which ones i thinks

dense vigil
#

Those are acpi tables

twilit ingot
#

strange that windows doesn't let you hotplug cpus and memory

dense vigil
#

It lets you hotplug just fine

#

Just doesnt allow removal

twilit ingot
#

but not unplug

#

lol

dense vigil
#

Yeah

blissful smelt
#

they want u to buy more ram and never get rid of it

twilit ingot
#

you could restart the server to unplug

blissful smelt
#

isnt there some strange limitation on RAM for windows home that isnt present on windows server and stuff on many versions

twilit ingot
#

yes

blissful smelt
#

i think windows home had like a 128GB limit at some point

#

odd stuff

twilit ingot
#

64 for home and 256 for pro i think

dense vigil
#

U mean 32 bit PAE

#

Thats a thing of the past anyway

twilit ingot
#

no, i think they still limit you anyway

blissful smelt
#

64-bit

dense vigil
#

Its kinda hard to get more on a consumer board

blissful smelt
dense vigil
#

But yeah

warm mural
#

I wonder why

blissful smelt
#

marketing and money probably, idk i dont see why there would be a physical limitation or whatnot

warm mural
#

no it's likely a software reason

dense vigil
#

Yeah

warm mural
#

I doubt its a marketing thing

twilit ingot
# blissful smelt 🙁

updated to 2TB for pro and 6TB for pro workstation or enterprise, home is still limited to 128

warm mural
#

oh wait yea that could be it

#

if pro supports more ram

dense vigil
#

I doubt they're so bad at programming they won't support more than 512 gb of ram lol

twilit ingot
twilit ingot
#

6TB max

warm mural
#

bruh

twilit ingot
#

they allow 24TB for servers

dense vigil
#

Less max phys bit less wasted metadata or something idk

twilit ingot
#

nah, most likely marketing

blissful smelt
#

windows, the famously space efficient os 💥

twilit ingot
#

firefox on windows: hmm, lets eat 50Gb of ram because of a mem leak...

#

(yes, this happened)

#

and not just 1 time

dapper mulch
twilit ingot
#

It's fixed there

#

Also, when it reaches max mem, it will reset back to normal usage

twilit smelt
#

Difficult to tell what it does at a glance

#

I'll have to look harder later

#

With my glance I didn't see any locking

#

I'm sure it's there but the implication is that it's very coarse

#

big scheduler lock or some such

#

Only lock implementation I can find is a spinlock

#

Which they refer to as "wait lock"

#

Bad sign

#

But I might just not be spotting their beautiful turnstile backed mutex or whatever yet

#

First impression is that it's way higher effort than most hobby kernels but there's a few tell tale signs that the person isn't very well read

#

which has limited their ability to make this good

#

the usage of UDI makes me think their reading was mostly the osdev wiki cuz UDI is a huge boomerism (fadanoid has talked about it before)

twilit smelt
raven drift
mortal thunder
#

like

#

id expect two underscores to be something unimportant

raven drift
#

Also, NUMA support is not a very exciting feature in reality

#

NUMA support mostly consists of splitting your physical memory allocator into multiple nodes

twilit smelt
#

its one of those things that has a fractal complexity the "better" you want to be at it

raven drift
#

The actual NUMA balancing algorithms are usually quite boring

twilit smelt
raven drift
#

Usually it's either "prefer near memory" or striping (for programs that operate on the same memory range with many cpus)

#

for shared memory parallel programs (say openmp) with a good access pattern, it's often very hard to beat striped numa memory

#

and for simple / short lived applications, just allocating from a near node is good enough

raven drift
dense vigil
#

it had that for userspace as well, but they found it was only useful for super long running programs

dense vigil
#

and if you dont have numa balancing code you will eventually have super fragmented numa balance and have shit allocate from random nodes that have memory left

twilit smelt
#

this was done in cellular irix in the 90s and is described in a book about openvms from like 2003

dense vigil
#

lol

#

yet they never did it for some reason

twilit smelt
#

from OpenVMS Alpha Internals and Data Structures (2003)

twilit smelt
#

i guess the later alpha chips had two separate page table roots and the one looked up on a tlb miss depended on whether the VA was above or below the value of that register

#

they did software tlb miss handling but it was still architecturally done "for you" because the tlb miss handler was in firmware

raven drift
dense vigil
#

well its only for .text so i guess not that bad

raven drift
#

As you need to ensure that it's transparent

dense vigil
#

yeah

raven drift
#

in particular, that concurrent cpus cannot see intermediate states even when mapping one code page over another code page

#

Alternatively you could make these cases illegal but that's probably not an option for linux

dense vigil
#

how do u map one code page over another

#

anyway linux already has core mechanisms to transparently remotely replace page tables of a process so i guess that could just be reused

#

like with live data

#

for memory compaction

raven drift
#

But that's different

#

Because there is only one page table involved

dense vigil
raven drift
#

and not one copy of the page table for each cpu

#

it depends on whether you need the mechanism to be fully transparent or not

#

if you want it to be fully transparent, you need to make sure that stuff like this doesn't happen:

  • cpu 1 reads a word W of address P and sends it to cpu 2
  • cpu 2 reads address P and compares it to W
  • cpu 3 remaps address P to another page
  • cpu 2 sees the old contents at P while W is equal to the new contents of P
dense vigil
#

well if cpu3 is still in the mmap syscall cpu2 is racing against it anyway

#

like isnt this the exact same problem as munmap

raven drift
#

well, without per-CPU page tables there are way fewer failure conditions here

dense vigil
#

like I guess u have to "tlb invalidate" when mapping as well

#

so that other cpus refresh their page table as well

raven drift
#

consider the case that P is not initially mapped, cpu 1 successfully reads P but cpu 2 faults

#

this cannot happen without duplication of pts per NUMA domain

dense vigil
#

ngl i dont understand how this isnt a bug in the userspace program

raven drift
#

well it all depends on what guarantees your memory mapping primitive provides

dense vigil
#

like if you dont finish the syscall its not done

#

you cant expect for its result to be visible

raven drift
#

but certainly a naive implementation of this duplication feature is detectable by user space code without kernel interaction

dense vigil
#

yeah i guess

#

u could have the faulting cpu check a bit and retry the fault

#

to easily work around this

raven drift
#

this is probably not an issue for your average userspace program that'll never do something insane like this

twilit smelt
#

i wish i could do that when i woke up

twilit smelt
#

a good bandaid for 5000 different problems

raven drift
#

but it might be for example for virtual machines that rely on race free behavior for correctness

dense vigil
#

linux already does page fault retries if you blow on the handler wrong

twilit smelt
#

everyone does

raven drift
#

or tracers and debuggers inserting breakpoints etc

twilit smelt
#

its the only reasonable way to work around some races

#

bsds, xnu, nt, linux all do it

dense vigil
twilit smelt
#

if you dont have at least one page fault retry path its probably because your vmm is trivial

dense vigil
#

fair

raven drift
#

you need to handle spurious faults even without duplicated pts

#

my point is that it gets more complicated with duplicated pts

#

not that it's impossible

dense vigil
#

i mean yyeah lol of course

raven drift
#

and it requires more heavy synchronization

#

i'm pretty sure that i can construct a case on x86 that detects this unless the kernel does something like break before make

dense vigil
#

thats why they found out it was worse for short lived programs

twilit smelt
#

which retries forever until theres a result other than "there was a weird race condition it would take another 4000 lines of code to work around so just run me again instead"

raven drift
#

yeah you basically need to check if the page is mapped on some archs anyway

#

i'm pretty sure that there are archs that only guarantee eventual consistency for the tlb (rv might be one but i'd have to check the docs to be sure)

#

= you can't be sure that no pf will be triggered even if the page is mapped in the pt

#

of course high quality implementations will usually avoid this but i'm not sure if it's architecturally guaranteed

twilit smelt
#

yeah (you probably know this but just for expository purposes) there are also architectures that cache invalid PTEs in the TLB which can cause spurious page faults like MIPS

raven drift
#

yeah true

twilit smelt
#

and your page fault handler sees the pte's valid bit is set and goes "oh" and flushes the page from the tlb and returns

#

this was common in software refill architectures because it removes a branch from the tlb refill handler

#

namely the branch to check the pte's valid bit and branch off to the page fault handler if its clear

#

cpu does it for you instead so you can just blindly load the pte into the tlb without caring about whether the valid bit is set or not and return

#

unsure if loongarch does this

warm pine
#

if you are then you can do something outrageous like cellular irix

warm pine
#

you can treat NUMA as "let's try and make an SMP kernel run better on it" or as "let's try and make a kernel that looks more like one for running on distinct nodes of a distributed cluster, and carefully introduce mechanisms for explicit sharing/loaning/migration of resources"

#

as for zambezi i've been watching it for some time

#

and last i looked i thought it looked as though there were at least some nice ideas but too young to judge yet and far too eccentric with its naming

#

if you think it's hard to keep track of what's what in Managarm when everything has an arbitrary name like lewis, michael, iain, or gordon, then wait until you see zambezi, it's even worse

twilit smelt
#

it got no blocking mutexes that i could find

#

so much for scaling

warm pine
twilit smelt
#

and it gets unlocked after doing some stuff to make sure there arent missed wakeups

#

right?

#

xv6 has a similar thing, you can pass the address of a spinlock into the context switch function to get it to do the same, for the same reason

dense vigil
twilit smelt
#

NT solves the same problem by having a sticky event flag bit

warm pine
#

only after the move towards good SMP support (mostly by copying what solaris did) did most of the BSDs start moving towards unifying on their sleeping locks

#

prior to that they used a primitive like this which was sufficient to implement various blocking locks of subtly differing behaviours

dense vigil
#

someone should tell them that c++ has static_assert

twilit smelt
#

in illumos the thread structure has a field t_lockp which is a pointer to a spinlock to atomically release after fully switching away from the thread

#

the turnstile chain lock is released this way when a thread blocks on one

twilit smelt
#

something really funny is that if i look up "osdev" in any random coding discord

#

a ton of the results are people going like "osdev discord traumatized my friend :/"

#

all the people who ragequit here go out into the wild and talk about how this discord is traumatic and warning people away from it

twilit smelt
#

picked a random one and found this

dense vigil
#

yes its very hard to explain to a beginner that a proper bootloader that actually works is a multiyear project

twilit smelt
#

i love the popular interpretation of the limine shilling as being like

#

"osdev discord HATES anybody who tries to do anything on their own! theyre jealous of our High Agency!"

#

meanwhile my project is the NIH of NIH and i dont get any shit for it so obviously thats not it buddy

raven drift
#

As a good bootloader looks nothing like a good kernel

dense vigil
#

yeah

dense vigil
#

we just know how those usually end

#

and what bugs it leads to

warm pine
#

it's just boring and tbh if it seems alluring then one has to ask what interest you have in writing an actual kernel

dense vigil
#

yep

raven drift
dense vigil
#

the usual idea is "well since im writing a kernel surely i must write a bootloader lol"

raven drift
#

plus, a beginner's goal is probably not to write a great kernel anyway

#

in many cases

warm pine
dense vigil
#

yeah but dealing with bios quirks and real mode crap is not exactly useful for kernel dev

#

so u gotta figure out what interests u

warm pine
#

but if you just flash your bios then you're missing something else, viz. assembling your own computer

#

but if you put together a single-board computer with, say, an off-the-sheld motorola 68040, you're missing out on the experience of assembling your own integrated circuits

icy bridge
#

NIH always has a cutoff point, for many people that's "to change this you have to flash firmware"

#

for other people that's "this will not be used after boot" (i.e. the bootloader can still be third party)

twilit smelt
#

we all pick a cutoff point yeah

dense vigil
#

u can always just decide to make a working kernel first and them implement a bootloader later if you're still interested in that

#

to at least eliminate these sorts of bugs

raven drift
twilit smelt
#

so people get annoyed when beginner #23932 wants to do his own bootloader because its gonna suck and be broken and teach him almost nothing but dont get annoyed when i have my project where i nih'd a lot more than just the bootloader because it already worked before i showed it off

raven drift
icy bridge
#

like the combination "this is my first os dev related project + I am writing my own bootloader + I am unwilling to do research beyond the first 10 words of the first Google result" is very common and very annoying

twilit smelt
#

yeah you can get away with anything here if youre on a footing of "i did a good chunk of the thing and then talked about it" rather than "im desperately begging for help on how to do the thing"

#

if youre the latter and youre talking about doing something unusual its definitely out of stupidity rather than a well-calculated experiment

icy bridge
twilit smelt
#

i dont relate to people who learned from those tutorials because i feel like i came at it from a completely different angle where i wanted to do my own computer and there were no tutorials for that so i learned how from papers about like risc workstations and their operating systems and architecture manuals

#

and i feel like more people should do that lol

#

way better at honing research skills and engineering sense and stuff than most other routes into osdev i think

icy bridge
#

definitely yeah

twilit smelt
#

reading papers and catching up through the decades really lets you know why things are the way they are and what factors are super important and so on

#

because they discuss motivation

#

from an industry/academia insider perspective

#

which is wayyyy more valuable than whatever discussions are on the osdev forums or wiki or tutorials

icy bridge
#

certainly doesn't help that all the osdev tutorials are made by people who themselves don't really know what they're doing (the people who do are too busy working on their os to make tutorials)

twilit smelt
#

@warm pine random thing: VMS doesnt eagerly reap dead threads, it lets their corpses pile up until memory is low and then it frees them all at once (the swapper does this just whenever its awoken, for any reason. it is never explicitly awoken to free dead threads, so this tends to happen when memory is low)

#

interesting little difference from the norm

#

seems highly intentional too like they decided that was superior to having a worker thread wake up and do it all the time

twilit smelt
#

the hypothetical korona tutorial would probably spawn 30 mini managarms

brittle locust
#

both better than what we have now

warm pine
#

it's not as though they're doing something like ad hoc slab allocation where the dead threads can be recycled into new ones?

twilit smelt
#

nope

#

i say that present tense but that was only true as of 2003

#

could have changed in the 22 years of active development since then

#

reaping dead threads is considered a memory-making activity

#

and therefore the obligation of the swapper

#

i could see it being better if for some reason youre creating and destroying threads at a very high frequency

#

eliminating the excess preemption from a kernel worker thread freeing them constantly and doing it all at once at intervals could be a lot faster

#

so like @mortal thunder 's fireworks test might be accelerated by this lol

icy bridge
cunning mortar
#

10000 paging.asms

#

RE: osdev traumatised blah blah

is it that pervasive? because tbh we're not that mean to anyone? like, other than telling people "hey, this stupid thing you're doing is stupid", that is

twilit smelt
#

i do regularly see people bitching about osdev discord in random places

cunning mortar
#

no one here has ever prevented or bitched to anyone e.g. writing their own bootloader if they know what they are doing

twilit smelt
#

but rest assured its almost always whiny crybabies who dont matter

cunning mortar
#

idk what their idea of what we're supposed to do is? like, use tons of emojis, saying that vibe coding is the future, and encourage them to do anything they want, despite the fact that it will very likely end up in failure and waste of time?

#

lol

earnest zenith
#

Put we don't see that that often anymore

cunning mortar
#

yeah

earnest zenith
#

Ever since it got removed

cunning mortar
#

did it get removed?

#

from where?

earnest zenith
#

One thing I see more of again is cfenollosa

earnest zenith
twilit smelt
cunning mortar
#

i honestly don't even remember where it came from

#

i thought it was brokenthorn

#

and then like

#

spread like some sort of weird mutation gene

twilit smelt
#

mintsuki tutorial

#

five. thousand. mini vinixes.

cunning mortar
#

god no

#

i'd hate myself if that was the end result

#

i don't think i am a good kernel designer, i just do what's fun, and most of the time that doesn't align with what's best

#

plus

#

i think kernel design fundamentally cannot be encoded in a tutorial

twilit smelt
#

i dont think anybody is a good kernel designer

#

i think some industry teams are collectively good kernel designers

#

but every individual sucks at it

cunning mortar
#

yeah possibly

twilit smelt
#

too many concerns to juggle

#

you can spend a lifetime becoming an expert at any one of those concerns

#

and still miss some shit

#

our projects are all doomed to have a bunch of stuff that STINKS

brittle locust
twilit smelt
#

well lets not lie to ourselves we also sometimes just say "you are stupid"

#

collective "we"

brittle locust
#

yeah for sure but they take it so personally

twilit smelt
#

mostly JW

#

also me sometimes

#

due to evilness

earnest zenith
#

but most got it from the wiki

twilit smelt
#

thread reaping is batched now, 500ms worth of terminated threads will be reaped at once

#

when mm is more fleshed out itll trigger reaping early during low memory as well

earnest zenith
#

unless I sniff bad faith, then maybe I'll accuse them of lying

twilit smelt
twilit smelt
#

since thats another thing that could cause worker threads to be scheduled at an unduly high frequency

#

so ill probably want to generalize this to a "timed work item"

twilit smelt
warm mural
#

The balanced queue stuff

twilit smelt
#

which system did i steal the idea from?

warm mural
#

Yea

twilit smelt
#

NT

warm mural
#

I was looking at NT but couldn't find that much details in win internals at least

twilit smelt
#

they dont call it a "balanced queue"

#

they call it just a "queue" i think

warm mural
#

Yeah

twilit smelt
#

i called it a balanced queue to contrast with the request queue which is a thing i have that NT doesnt

warm mural
#

But apart from a small paragraph there's nothing on it

twilit smelt
#

and is my analogue to NT's Ke-level "device object"

warm mural
#

They talk briefly about ExQueueWorkItem

earnest zenith
twilit smelt
#

the what

earnest zenith
#

or excessive self-advertising

twilit smelt
#

here

teal trench
twilit smelt
#

but the regulars from then are gone and the new ones are cooler so i havent since i came back in late 2021

earnest zenith
#

are there not regulars from 2020 still around?

twilit smelt
#

the problematic ones arent

twilit smelt
#

but im talking more along the lines of belittling the premise and telling me im wasting my time and shit

#

people would do way back then

earnest zenith
twilit smelt
#

no carver was cool back then

#

i understand he has some crazy politics but that never came up at the time lol (at least not where i could see it)

#

i dont wanna name names in case someone returns and name searches and it causes mysterious beef down the line

twilit smelt
#

and was long overdue

twilit smelt
earnest zenith
twilit smelt
#

mind you the compiler is shit but like i can just write a new one and slide that in at any time, which is infinitely better than the entire language being shit

#

also someone's doing a new jackal compiler already

#

sandwichman

#

he recently reached the milestone of the entire parser of the old jackal compiler (5k lines) parsing and type checking correctly in his compiler's frontend

#

very cool stuff

warm mural
#

Ah yea I haven't from that project in a while

#

Coyote I think it's called

twilit smelt
#

yah

warm mural
#

A C backend would be really cool

twilit smelt
#

for which compiler

warm mural
#

That one, + you'd need fantasy ISA ones

#

So eventually mintia can run on real archs

twilit smelt
#

current jackl compiler already has a c backend (which is how it builds itself for real computer)

warm mural
#

Ah so you could theoretically already port to amd64?

#

Oh wait I think czapek did exactly that lol

twilit smelt
#

someone already got mintia kernel up to the crash screen by doing that yeah lol

#

yep

sterile frost
#

it was fun

twilit smelt
#

kernel guy tries to write userspace tooling:

sterile frost
#

yeah that made me puke when i tried to do an amd64 backend

twilit smelt
#

i wanted to separate it out but when i tried it was so dense with ifdefs it almost felt better to leave it repeated

#

its something i need to give some attention to though lmfao

#

i do feel guilty about it. i have self awareness.

twilit smelt
sterile frost
#

i think i know where this is going

#

but i have absolutely zero idea

twilit smelt
#

for example when it was ported to mips

#

they created a new directory called mips

#

copypasted the entire kernel tree into it

sterile frost
#

oh no.

twilit smelt
#

from one of the other ports

#

and then changed things willy nilly in there

#

until it ran on mips

sterile frost
#

that's painful

twilit smelt
#

so each time it was ported it was basically forked off into a new kernel that evolved independently from the others

#

and theyd rarely sync up except with great effort

sterile frost
#

i hope it didn't take them that long to figure out they can just put all those directories in one kernel and swap out the include path

twilit smelt
#

it was done like this primarily because each new port was done by a new company

#

out of a forked source tree

#

and they didnt have like github to all coordinate with lol

sterile frost
#

yeah that is fair

twilit smelt
#

i realized something that made me feel really stupid

#

which is how to properly add page tables to system space (on 32 bit)

#

people kept saying "oh you just update the process's page directory to add the new page table when it faults on something in the new part of system space" but this didnt sit right with me because there are moments you could fault on it that would just kill you dead

#

like architecturally

mortal thunder
#

right now I just wanna make sure nothing leaks any memory

digital pivot
twilit smelt
twilit smelt
#

@acoustic sparrow you often have interesting insights

#

when a thread dies i now have it enqueue a timer for 500ms in the future, this timer is not re-enqueued for subsequent dead threads

#

when it expires, all dead threads are reaped in a worker thread

#

the effect is that i batch reaping in 500ms intervals rather than having a worker thread wake up every time a thread dies

#

ill also reap it ahead of time when memory is low

#

do you think this is worthwhile and do u think it could have any surprising drawbacks

acoustic sparrow
#

that seems potentially really problematic

twilit smelt
#

why

acoustic sparrow
#

the status code is available in the parent immediately, right?

twilit smelt
#

yeah

#

this is just the final freeing of the kernel stack basically

#

which you cant do in the thread's context so you need a worker thread to do it

#

or i do

acoustic sparrow
#

so why not reap in the parent?

twilit smelt
#

thats essentially the same thing

#

as using a worker thread

#

just with more weird cases

acoustic sparrow
#

except you dont have a 500ms timer

twilit smelt
#

theres the same issue though of excess preemption if theres a time where threads are being terminated at a high frequency

acoustic sparrow
#

one other alternative is to have a per-cpu stack for freeing other stacks

twilit smelt
#

i need a full thread context because i need to take blocking mutexes in order to free the kernel stack

#

all my memory manager locks are blocking mutexes now

acoustic sparrow
twilit smelt
twilit smelt
#

because you have stuff like the timer interrupt doing runtime accounting in it and so on

#

so i also free that at the same time i free the kernel stack

acoustic sparrow
twilit smelt
#

really i remove a refcount from it which is biased to represent an executing context while its running

#

so if a process has a handle to this thread object, it still wont be deleted when the reaper gets to it, and the process can examine its exit status and accounting info and so on until it closes the handle

#

kernel stack is immediately deleted by the reaper tho

#

but the thread object itself it just unbiases the refcount

#

which may or may not delete it on the spot

twilit smelt
#

its not

#

i put that in the deletion routine for the thread object instead

#

thats not where that should be

#

i can just move that to the reaper rq

acoustic sparrow
#

i have a mildly cursed solution to the stack freeing problem

#
RaiseIRQL();
while (true) {
    if (g_prevStack) {
        LowerIRQL();
        free(atomic_swap(&g_prevStack, null));
        RaiseIRQL();
    } else break;
}
g_prevStack = current_stack;
#

pretend you do the atomic swap before lowering irql

#

and its percpu

twilit smelt
acoustic sparrow
#

while you are on the thread stack

twilit smelt
#

Oh I see

#

Yes I get it

#

So you just always have a kernel stack sitting around lol

#

Goofy

acoustic sparrow
twilit smelt
#

That's not cursed at all though it's smart

#

Yeah even on my 2-4mb target that's nothing

acoustic sparrow
#

plus, when you need a new one, you can use a defer-freed one

#

so its really just an alloc cache

twilit smelt
acoustic sparrow
twilit smelt
#

if another thread is exiting on another cpu it could free your stack

#

before you switched off it

acoustic sparrow
twilit smelt
#

right you did say that

#

you have to make sure to keep preemption disabled between setting your stack as the prev stack and switching off it though

acoustic sparrow
#

they cant free your stack, because you are with a raised irql

acoustic sparrow
#

freeing the thread object requires some other thread

twilit smelt
#

well this is interesting to keep in mind, the thread object thing necessitates another thread anyway though

#

yeah

#

so i may as well just reap the stack there too

acoustic sparrow
#

if there is at least one other ref then you can just unref and its fine, you aren"t freeing

twilit smelt
acoustic sparrow
#

otherwise, you can transfer ownership to a worker thread

#

which is rare anyway

#

because almost all processes have someone who wants to get the status

#

unix solves this by offloading it to pid 1

twilit smelt
#

ik the unix solution

acoustic sparrow
#

yea

twilit smelt
#

i think it makes less sense when everything is a refcounted object

acoustic sparrow
#

yea maybe

twilit smelt
#

and the lifetime of a thread is determined by you having its handle rather than you not having wait()ed it yet

#

er process

#

or whatever

acoustic sparrow
#

but i think the ownership transfer approach is pretty reasonable

#

plus, you can also do the same deferred free trick with it

#

but with a short timer to make sure that threads always get freed at some point

twilit smelt
#

also mintia has no process tree

acoustic sparrow
twilit smelt
#

the posix subsystem will keep track of one but native mintia has no use for one

acoustic sparrow
#

if only for introspection

twilit smelt
#

for introspection i keep the parent process's pid as a hint

#

in the child

#

that can be invalidated later but hopefully not too quickly

acoustic sparrow
#

not a weak ref?

twilit smelt
#

nop

acoustic sparrow
#

but your pids can roll over?

twilit smelt
acoustic sparrow
#

yea its not common

twilit smelt
#

there are ways to tell also

#

that it was invalidated

#

namely if the "parent" was created later than the child

#

then you know its not the real parent

acoustic sparrow
#

oh yea

twilit smelt
#

this is what like task manager does in windows to draw the process tree

#

the timestamp of creation is stashed in the process object and can be queried

#

and is used for this

#

among other things probably

acoustic sparrow
#

assuming your timestamp doesnt roll over

twilit smelt
#

well mine are 64 bit count of milliseconds

#

EWWW MILLISECONDS CRINGE WHY NOT NANOSECONDS

#

shut up

#

anyway they wont roll over for billion year

acoustic sparrow
twilit smelt
#

i mean i could change it to a smaller unit

acoustic sparrow
#

but yea

#

you could also just make pids 64 bit

#

which gets rid of rollover as a concern entirely

twilit smelt
#

i dont do pids as an incrementing count

acoustic sparrow
#

ah i see

twilit smelt
#

i do it as a free list threaded through the entries of a resizable array indexed by pid

acoustic sparrow
#

ahh

twilit smelt
#

theres a sequence number on each entry which forms the low like 12 bits of the pid

#

so that reused table entries dont cycle over too quickly

acoustic sparrow
#

ah i see

twilit smelt
#

its in paged pool of course

#

wouldnt be me if i didnt make it swappable

twilit smelt
#

threads also have ids and go in the same table

#

one posix thing i allowed to encroach directly into Ps is PGIDs

#

theres a process group object which implements posix group and sesssion semantics

#

it even does the thing where a PGID cant be reused as a PID (which would accidentally or maliciously make a new process a retroactive group/session leader) until all of the group members die

#

when a group leader dies, it atomically exchanges its pointer in the pid table with a pointer to the group object

#

rather than freeing the entry

#

the group object removes itself from the pid table when its refcount drops to zero (there are no processes with its pgid anymore)

twilit smelt
#

to me its obvious that its not that difficult to implement the group/session semantics in terms of objects, so its fairly natural

#

it also would have added an additional layer of fake posix pids in the posix subsystem that just doesnt need to be there

#

so this bit of contamination seemed fine

#

im not obsessed with "purity"

#

ill do whatevers necessary to get posix implemented as quickly and painlessly as possible, ill isolate whats easy to isolate in a Psx- component of the kernel but whats not, i wont worry too much about

#

the logic of maintaining a process tree will go in Psx but ill allow the structures for it to just be part of the process object, inline; maybe isolated in a PsxProcess struct

#

posix subsystem will also be kernel mode

#

which is obvious from what i already said

mortal thunder
#

so why not use the object manager machinery to destroy the thread stack

#

are you afraid of unresponsive processes not actually closing the exited thread handle?

mortal thunder
#

why not?

twilit smelt
#

The process can close the handle before the thread terminates

mortal thunder
#

yes

twilit smelt
#

So that's why

mortal thunder
#

in my OS, the thread holds a reference to itself while it's running

twilit smelt
#

Then the only reference to the thread object is the one implied by the fact the thread is running

#

Yes

#

Now where do you remove this reference?

mortal thunder
#

i remove it in a DPC that executes after a thread switch, which slams the thread into a queue of objects to remove and wakes up the object reaper thread

#

my point is that you could have only one such queue instead of two

twilit smelt
#

Okay so what was the point of what you said originally cuz that's basically what I do

#

Wdym two

#

I only have one reaper queue

mortal thunder
#

one for freeing objects from high IPL and one for freeing thread stacks

#

or did I misunderstand

twilit smelt
mortal thunder
#

i see

twilit smelt
#

I mean you could probably find a way to make them the same thing I just think it'd be unergonomic and weird

dense vigil
acoustic sparrow
digital pivot
#

will mintia have something like io uring ?

dense vigil
#

as far as thread reaping i think linux doesnt refcount it and does the waitpid thing

icy bridge
#

how does it handle SA_NOCLDWAIT then?

twilit smelt
#

It'll be one with the Linux compat layer

#

it'll even have cow fork implemented the uvm way

#

The constraint of needing to have good fork and support Linux mount semantics (including bind mounts and so on) has dictated a lot of the planned design for the vmm and "vfs" respectively

#

I like how trying to design something well, informed by lots of different kernels, is antithetical to unix

#

It has to suck ass to count as unix

mortal thunder
warm mural
#

I think he's talking from the viewpoint of some people here

twilit smelt
#

I was thinking of doing an r/osdev post when I got to userspace

#

But people are so idiotic on there that I can definitely do it earlier with little to show and still get attention

#

So I might do that today

warm mural
#

put emphasis on the "I made everything from scratch" part

#

take this from the reddit bait master (master baiter?)

warm mural
twilit smelt
#

@warm root prepare the drano

#

I way failed

mortal thunder
#

slacked off or what?

twilit smelt
mortal thunder
#

i see

#

hopefully now that the summer is here you don't have the former problem (temporarily)

twilit smelt
#

no i do

#

i decided to take a summer semester

mortal thunder
#

oh, ok

twilit smelt
#

mintia2 is a year old now and its much further than old mintia was 12 months in

#

but not nearly as far as i would have liked

#

lol nvm

mortal thunder
#

i think old mintia was slightly ahead

twilit smelt
#

old mintia was at userspace, demand paging, etc

#

this was 1 year deep in old mintia

mortal thunder
#

yeah because you had OSDLL already

twilit smelt
#

the screenshot is wrong

#

this was the screenshot

mortal thunder
#

oh you already had a shell going

twilit smelt
#

interestingly its way fewer lines of code than mintia2 is now

mortal thunder
#

around one year from when boron started i barely had a small IO system going, the nvme driver was working but not much more, and i was barely figuring out the memory manager

#

i'm 2 months short of being 2 years in my project (I started it on Aug 20, 2023) and right now i'm supposed to be working on libboron.so loading executables

twilit smelt
#

old mintia 12 months in: 43772 lines
new mintia 12 months in: 45720 lines

#

despite this, old mintia had userspace, demand paging, swapping, and a simple shell

#

mintia2 doesnt even have an IO system and the vmm is a stub

#

goes to show how much more enormous the mintia2 design is

#

second system effect...

mortal thunder
#

1 yr in boron was

iprogramincpp@IPROGRAMINCPP2:/mnt/w/boron$ find -name *.c -or -name *.h | xargs wc -l
...
  28902 total
iprogramincpp@IPROGRAMINCPP2:/mnt/w/boron$ gl
commit 392c8a9f2aa6473970e51e62cb47ac88e58288f7 (HEAD)
Author: iProgramInCpp <[email protected]>
Date:   Sun Aug 18 23:01:50 2024 +0300

and now it's ```
iprogramincpp@IPROGRAMINCPP2:/mnt/w/boron$ find -name *.c -or -name *.h | xargs wc -l
...
38640 total
iprogramincpp@IPROGRAMINCPP2:/mnt/w/boron$ gl
commit 3adc4b0ba5392c07be96f0786ad321dd1328c479 (HEAD -> master, origin/master, origin/HEAD)
Author: iProgramInCpp [email protected]
Date: Sat Jun 28 23:35:57 2025 +0300

twilit smelt
#

old mintia 60k, new mintia 100k+

#

ppl always included the holyc compiler in line counts of templeos so i should start doing the same lol

mortal thunder
#

sure

#

that puts me at a disadvantage because i can't bundle gcc and make with the loc count lmao

hybrid condor
twilit smelt
#

but the next major thing is the IO system

#

the IO system was totally static before but now its gonna be fully plug n play and power management aware

#

next immediate thing is to initialize the boot time IO catalog (iokit-y)

twilit smelt
dense vigil
#

u can just pretend like u did

#

no one is going to check/be able to check anyway

twilit smelt
#

I don't wanna PRETEND

#

According to the roadmap I'll be p much at userspace when I have filesystem drivers

#

I can't do them until the vmm is like done

#

because of dependence on the file view cache which uses demand paged file mapping

twilit smelt
#

its so crazy that a tradition honoring generals in a particular italian city state in like 200 BC led to North Korea having a triumphal arch

#

that just shouldnt be there man

#

the north korean one looks WAY cooler than any of the roman ones did too

#

much larger

green pelican
#

tbf giant monuments tend to go pretty hard

#

thats like half the point of being a military dictator

earnest zenith
#

the other half is doing purges live on TV :^)

sterile frost
#

i was reading a bit through mintia code and i don't really understand what's the point of user- vs kernel-mode waits? does it have any significance? or is it simply the initiator of the wait? there's also alertable vs non-alertable waits but i imagine this is about the possibility of waking up due to signals/apcs

twilit smelt
#

I should really do a table of the effects of alertability and wait mode

sterile frost
#

i think i've seen one for the windows kernel but i couldn't find it

#

but yes that would be very nice

twilit smelt
#

It's not quite the same as the windows one

#

I yoinked the idea in 2021 but it has evolved independently since then

sterile frost
#

i just kinda assumed since the names looked similar

#
  • i don't think windows does signals so that's one significant difference
mortal thunder
sterile frost
#

that would make sense

twilit smelt
#

And if you wait as usermode you're also making a promise to Ke that you're not holding certain locks

#

so that it can dispatch LAPCs in your context which can take said locks

#

(if you were holding them then you would deadlock)

mortal thunder
# sterile frost that would make sense

forgot to post this

Note

SIGINT is not supported for any Win32 application. When a CTRL+C interrupt occurs, Win32 operating systems generate a new thread to specifically handle that interrupt. This can cause a single-thread application, such as one in UNIX, to become multithreaded and cause unexpected behavior.

sterile frost
#

lazy APCs

mortal thunder
#

ah

twilit smelt
# mortal thunder LAPCs?

kernel mode apcs that arent dispatched unless

  1. youre in a usermode wait
  2. youre currently executing in usermode
  3. youre about to return to usermode
#

not to be confused with usermode APCs

#

these run in the kernel and are invisible to userspace

#

it just uses usermode as a quiescent point to know that certain locks arent held so that LAPCs are safe to grab them

twilit smelt
#

@sterile frost

#

this only applies if IPL < KI_IPL_APC at wait time

#

if IPL >= KI_IPL_APC then all events are masked off always

sterile frost
#

interesting

twilit smelt
#

with better color coding and a key

#

@warm pine you might also find this interesting

#

meaning of wait mode & alertability combinations in mintia2

#

theres also a third alertability option which is KE_CANCEL_ON_KAPC which is only valid when supplied with KE_KERNEL_MODE and waiting at IPL >= KI_IPL_APC

#

it causes KAPCs to interrupt the wait, without being delivered

#

this is used by the turnstiles impl to defer KAPC delivery while waiting on a turnstile

#
// Wait on the turnstile event.
// This wait can be cancelled if a kernel APC arrives, but the kernel APC
// will not be delivered since we're at KI_IPL_APC. This allows us to
// clean up our usage of our turnstile, which lets the APC grab turnstile-
// -backed locks once it is actually delivered when we lower IPL.

alertable := KE_UNALERTABLE

IF ipl == KI_IPL_LOW THEN
  // The lock was acquired at LOW IPL, so we should cancel the wait and
  // clean up if KAPCs arrive.

  alertable = KE_CANCEL_ON_KAPC
END

KeWaitForSingleObject (
  KE_KERNEL_MODE, // waitmode
  alertable, // alertable
  NULLPTR, // timeout
  &turnstile^.Event.Header, // object
)
#

added that

marble socket
#

thats really smart will

#

to be fair ipls in nyaux would be cool but that'd be too complicated and introduce a lot of problems nooo

marble socket
#

have hug

#

🫂

twilit smelt
twilit smelt
#

the bad boyfriend is real though

#

or was, i dumped his ass

marble socket
marble socket
twilit smelt
#

im changing a really gigantic macro at the start of the wait functions into a real function to see how many bytes of code that saves, which should be a little easier on icache at the expense of the extra function call

#

before:

text:
  Size     64756 bytes
#

after:

text:
  Size     63892 bytes
#

saved 864 bytes

#

i think thats worth it probably

#

thats 216 instructions

#

on fox32 it goes from 67456 bytes to 66556 bytes which is a 900 byte reduction

#

(no certain instruction count bc fox32 has var length encoding)

#

it cut the size of the wait routines in half

#

expense is an extra like 30 instructions

#

also i think i know a way to skip the check for interrupting events

#

if none are pending

#

(common case)

#

basically just have a little bitmap in the thread structure that has a bit flag for each pending event (one bit each for non-empty kapc, lapc, uapc queue, one bit for non-empty signal set, and so on)

#

check the whole bitmap at once and if its zero skip the check

#

should get me back the 30 instructions i lost by splitting out this function, and then some

#

yeah thatll save about 80 instructions on the hot path lol

#

80-30 = net improvement of 50

#

not very high tech to measure performance by instruction count but its a 1989 RISC so its probably good enough

twilit smelt
#

cuz everyone does like 5 rewrites and each one is better than the last

#

(me included, im doing my fifth one rn)

twilit smelt
#

that should excite u

#

youll learn so much and later itll be even better

marble socket
#

well im not you will id rather reimplement like half of the codebase then rewrite the entire project from scratch plants_troll

twilit smelt
#

well ya u can keep what u can

marble socket
#

yea cause with this rewrite i am on currently im aiming for wayland and xorg

#

if i get there

#

idk

#

id probs rewrite like most of the code related to the VMM especially

#

and probs abstract cpu archiectures better

#

but yk yk

#

i also kinda want swap and shit so a VMM rewrite is on the cards

mortal thunder
digital pivot
#

how is your project doing

twilit smelt
mortal thunder
#

"nanoshell minus one" (2019-2020), "nanoshell zero" (2021), nanoshell (2021-2023), nanoshell64 (2022), and boron (2023-2025)

#

(the first three were all called nanoshell but i added those names retroactively cuz they're not the real deal)

marble socket
mortal thunder
#

i made a simple read-only ext2 implementation a week or so ago

twilit smelt
marble socket
mortal thunder
#

after implementing the ELF loader I'm probably going to work on a pseudo-terminal device

#

or driver

#

i haven't decided if it'll be part of the kernel or not

#

i lean towards it not being part of the kernel and instead being a driver

digital pivot
mortal thunder
#

then i'll have to work on, like, everything. handle inheritance, fork, and then write support for basically everything in the MM/IO stack

twilit smelt
#

and get the best of both worlds

twilit smelt
hybrid condor
#

Work is done and I'm happy

twilit smelt
#

"any more than whats required" is too much but it also depends on other factors

#

like if saving a few instructions is possible but would make the code unreadable and its a fairly uncommon codepath or one thats inherently slow anyway (like if it usually does an IO wait)

#

ill probably just not

#

also my one-man compiler sucks and does dumb codegen all the time anyway

#

i only obsess over it if its a really hot codepath

#

i can get it to contort into generating good code and stuff

#

or give up and use asm

twilit smelt
twilit smelt
#

i was considering against it because i thought id have to update the little bit set with atomics but every place i need to update it, im already holding the thread spinlock

#

same with the place i check it

#

so i should just bea ble to access it normally

#

u might think "but will shouldnt you be implementing your io system instead of micro-optimizing stuff"

#

its part of my normal cycle i tend to oscillate between implementing new functionality and going over the old stuff with a fine toothed comb its just whatever i want to do at any given moment

#

i also think with a project this large and robustness being a goal

#

if i didnt do that it would collapse under its own weight

#

continually revisiting and improving old stuff is def necessary i think, and thats something i realized yrs ago while doing old mintia

digital pivot
twilit smelt
#

event bits are needed for:

  1. non-empty KAPC queue
  2. non-empty LAPC queue
  3. non-empty UAPC queue
  4. SignalMask & SignalAcceptMask is non-zero
#

if any of those are set then the full check will be performed otherwise itll be skipped

#

those bits will also be used to accelerate the check

twilit smelt
#

stuff i cant do tonight or probably tmrw but should finish asap:

  1. thread event bits to avoid calling KiWaitCheck
  2. compiler support for simple inline asm for use for memory barriers and pause rather than the goofy little subroutines i use rn
twilit smelt
#

my favorite thing about my project is when i have to add a compiler feature to make something about the kernel suck less

#

makes me feel like a multics programmer in 1966

twilit smelt
#

managed to fully inline the following (name, codepath savings for each usage):

KeMemoryBarrier, 2 instructions
KeWriteMemoryBarrier, 2 instructions
KeSpinPause, 2 instructions
KiReleaseSpinlock, 3 instructions

managed to partly inline the following:

KiReleaseSpinlockLower, 1 instruction
#

partly inlining KiReleaseSpinlockLower had the additional benefit of reducing cache footprint by reusing the cache line for KiLowerIpl, which was previously inlined specially in a handwritten asm routine

#

well, all of them removed a cache line of footprint each

#

idk how much of an impact this truly had on performance but it sure feels good

#

"why dont you benchmark!!!!" i think the results for this would be mostly lost in the noise of the emulator's performance inaccuracy

#

also while looking at the resulting asm

#

i noticed excess memory barriers

#

this appears twice in KeDispatch.jkl:

    KiReleaseReadyQueueElevated ( prb )
    KiReleaseThreadElevated ( current )

in each case it results in this:

    wmb
    mov long [s0 + 16], 0
    wmb
    mov long [s1 + 48], 0
#

which could just be

#
    wmb
    mov long [s0 + 16], 0
    mov long [s1 + 48], 0
#

so im gonna add a KiReleaseTwoSpinlocks macro which does that

#

there are several other places where this happens

#

two spinlocks being released immediately adjacent which results in an unnecessary memory barrier

#

im not missing anything due to 3am brain right @dense vigil

#

ive designated you to tell me whether this is subtly broken

#

wmb is a store barrier so here its making sure that whatever you did in the critical section while holding the spinlocks is committed before you release them (if it got reordered after that or vice versa thatd be bad)

#

but it doesnt matter what order the spinlocks are released in or whatever so there doesnt need to be a second one