#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages ยท Page 47 of 1
who's everyone?
idk I have seen multiple oses in the past days
im only aware of mr pmos
i am planning on doing la64 but
it's far from being anything serious
the fact that uACPI initialized means that I have full userspace working
Lol cool
(I mean I think everything pagefaults after that)
Broken timer
Update uacpi and it won't show time
why does everyone think faster than me
Apparently they have a proper TSC-like timer, and I've missed it
So I think I'll fix that, and then I'll try to implement the QEMU ACPI GED thing
now do it in real hardware
work
ah
i also have ppc64le hw
that is actually cool tbh
i have a 3A6000 la64
what do you even do at suse?
But there's no limine 
all sorts of things
Though does it have EDK?
I've seen a port on GitHub
But I think it was not accepted to mainline
Wait a second
PPC
Why did I think about MIPS
let me check our system
painkillers
several kinds of drugs
to numb the pain of working at suse
its a cool company
idk
something something device trees
loongarch64 is the coolest risc
they are actually on board with proper standards like UEFI and ACPI
there is actual hardware that works and is cheaper and powerful, unlike riscv
Now somebody just needs to add SMP support to Limine
There is a tiny issue
Lack of documentation
(like for vector extensions)
i mean it still has some documentation, it's not completely undocumented
linux 
i bet if you look for stuff in Chinese you'll find way more
And the documentation that's there is translated from Chinese, with errors
no the chinese one is also TBD
https://elixir.bootlin.com/linux/v6.13.6/source/arch/loongarch/include/asm/asmmacro.h#L242 this looks like it's broken to me
And Linux is insane
vector instructions and virtualization manuals are TBD in both chinese and english
and i guess from what mishakov says they are translated from chinese
I've gotten vector extensions to work
nice :^)
(like the clang issued code does not crash)
It's a matter of saving and restoring registers from the kernel's point of view, so like not complicated
i guess i just didn't pay attention
The only thing that was pagefaulting was Rust
Because it was linking against libc with brainrot bug in it
I think its ACPI looks more interesting than that of RISC-V
that's really cool
I guess now the only arch where uacpi hasn't been confirmed to work is itanium
I see ged
MIPS?
no acpi there
pushed an update to zuacpi to update to zig 0.14
nice
yes, i think it seems quite promising
i'll probably buy a loongarch board if/when i come across one

does looongarch have HPET? or is this something else
It looks like an x86 hpet
when are we getting shoortarch
MIPS
after averagearch
everyone wants it loong. 
btw, doesn't anyone have MIPS Creator CI20? I won't ask to test anything on it, ๐ I just remembered, I had this tiny cute purple SBC. Good memories. My lowest level coding experience. sigh. I could take it with myself, but we hoped we return.
Honestly I'm not sure it's still around anymore ๐
Was probably destroyed in the war
You mean of mine? My town is completely destroyed. Everything actually. In 1000s km2 around. Below is photo of my house, yet in the summer 2023.
https://ant-upptech.sourceforge.io/res/NashDim-02-2023.jpg
And the 2nd pic is how it looks now. Totally "liberated from nazism".
๐
hopefully your family is OK
thank you. Are alive, already ok. As ok as it can be under almost everydays moped (drones) attacks and a bit rarer ballistic missiles attacks. Kyiv is targeted pretty often.
Man that sucks, they will pay one day, if not in this life, the next one
I speak Turkish and English, I technically studied German for 11 years but I can barely say Kartoffelsalad, I used to be intermediate in toki pona but forgot, I know enough polish to understand some basic song lyrics, I know a couple words of Zazaki - my heritage language
marvin showed cool upcoming risc-v stuff and while I can't comment on price and power (I have no risc-v or loongarch hardware) risc-v is much more accessible
I've at least encountered risc-v boards
loongarch is pretty much still a china-only thing IMO
I'd love to see that (being china only) changed ofc
at least in my mind risc-v comes before loongarch in the list of possible targets
I'd like to see them as equals one day
@gentle peak in old hydrogen u have event callbacks that run from a timer irq right
one of them is a scheduler thing
that can call into do_yield
wouldnt that yield from current irq handler, so u dont run lapic_eoi or other event handlers?
timer event handlers are run with preemption disabled, so the actual yield is only done after it's enabled again
which is done after eoi
ohh
but next time u reschedule this task, would it then be basically on the enable_preempt(); line in the timer handler?
that's where the actual yield happens yea
think so yeah
i didn't really look into how other kernels did it when i made it
i know this is basically equivalent to a two-level softipl thing
but i don't really know anything beyond that
im gonna take a look at how keyronex does it
WHY NOT MINTIA?!?!?!?!?!?!??!??!?!?
we do it identically so it doesnt matter
u hate jackal?
if you would explain how you do it id appreciate it
more mental effort to read for me personally
its just a C reskin
basically rescheduling is a software interrupt but not in the int 0x80 type way
there are interrupt priority levels (IPLs)
the lowest 3 are reserved for software interrupts
0 is everything enabled, 2 is preemption (among other things) masked off
ignore 1 thats out of scope
when a new thread should be scheduled in, a software interrupt is set pending at IPL 2
by software interrupt u mean dpcs?
next time IPL drops below 2, the pending bit is seen and the software interrupt handler is called which performs the actual reschedule
that is one software interrupt at IPL 2
i dont do preemption as a DPC because itd be bad to preempt in the middle of dispatching the DPC queue
i dispatch all the DPCs and then i check for preemption and switch to a new thread if necessary
ok i see that keyronex basically sends an ipi to itself in the timer irq
which then runs the dispatch dpc thing
which then calls reschedule
yeah we diverge there, he does it with a self-hardware-interrupt and uses cr8 to implement ipl, i do it completely in software
isnt doing in hw kinda overkill just to do a context switch
i think my way is better
and slow
thats my opinion
especially bc software raise and lower ipl you can make like 1 and 3 instructions respectively in the fast path
on x86
so its not like that much more than setting cr8. actually its much faster if youre running under a hypervisor
this thing you run in your enable_preempt type of function?
yeah KiLowerIpl
basically, when do u check pending software irqs
oh ok
so basically u do the same thing as proxima
it sets the new ipl and then checks if there are soft ints pending and if so it calls KiDispatchSoftwareInterrupts
otherwise branches around the call
QuantumEnd is what triggers a preempt?
it like does quantum end processing like priority boost decay (if necessary) and selecting the next thread yeah
but doesnt actually switch to it yet
its just one source of thread preemption among others so thats not rolled together
when does it actually switch?
what's this i hear about UltraOS returning
currently just accumulating knowledge lol
where is this?
in any domain in particular?
mostly around scheduling i guess
literally is in that function i linked
i see you invited hyena as visiting lecturer
ah lol
i invited myself bc im annoying
he's automatically present if you start discussing anything about virtual memory or scheduling
lmao
i appreciate it tho
ohhhh i introduced a bug
recently
and only just noticed
thx for making me stare at that
ah ok, so basically:
- Timer irq sets quantum end
- Does a RaiseIpl
- RaiseIpl checks pending software irqs
- If current thread's quantum is over, call into KiQuantumEnd, which picks the next thread to run
- That thread is switchd to at the end of RaiseIpl
not EXACTLY
btw, dpcs are just a linked list of function pointers? what sort of dpcs are there usually, who queues them?
although i liked it for the fact that it collapses the abstraction altogether and is simple, i'll certainly adopt your new approach at some point
and distinguishing raise/lower to/from software levels was a nice trick which i think should be no great difficulty to adapt to and enables those common cases to be written much more optimally
- timer irq decrements current thread timeslice and if it reached zero ticks left, it sets
curcpu->QuantumEnd=TRUEand sets a soft int at IPL 2 - return is about to occur from the outermost interrupt handler (they can nest if higher priority interrupts are taken). if there are now pending soft ints at the last IPL before the interrupt was taken, then the interrupt handler calls
KiDispatchSoftwareInterruptsdirectly before returning. it turns out to be weird and fucked up to callKiRaiseIplandKiLowerIplfor these things. if the last IPL before the interrupt was taken was too high to dispatch the new soft ints, they will be dispatched at the nextKiLowerIplto a lower IPL, and not at this moment - interrupt handler for IPL 2 (aka
KI_IPL_DPC) callsKiQuantumEndwhich determines what thread should run next (if any); it gets set intocurcpu->NextThreadif so - if
curcpu->NextThreadis set before returning from the IPL 2 handler, a switch directly into this new thread is conducted
my used to do the former too but a while ago i changed it to do the latter
do you have any concrete plans or concepts at present? other than linux abi compatibility
nah, nothing concrete like that atm, mostly in the deciding phase
good to see work on boron again btw
hmm
point 2 is a bit too big brained
note that NextThread is checked locklessly there (bc its safe to do so just to check for for transition from null->set) but actually setting it or using it is guarded by the per-processor ready queue spinlock
any ideas you like particularly?
excuse my cross-examination
im definitely more interested in the hw side, so it wont be sophisticated algorithm-wise probably
just the bare minimum to not be embarassing
indeed, well i kinda finished what i needed to do for anon memory for now, now i need to implement memory mapped files, after that i can implement dll mapping and finally some kind of userspace
whats confusing about it
but i need to build an idea of how things are structured first
"if there are now pending soft ints at the last IPL before the interrupt was taken"
what does this mean
last IPL?
ok so like if you were at IPL 0 when you took the interrupt, and the timer interrupt set the pending bit for IPL 2, then it will be dispatched before returning from the interrupt
if there are any pending DPCs or quantum end, is what i understood it to be
however if you were at IPL 2 when the interrupt was taken, this soft int will not be dispatched yet
because it is masked off by the IPL you are returning to from the interrupt
it will be dispatched next time the interrupted code lowers its IPL
like its probably a simple idea but i cant parse it because of these terms i dont understand that well
i need an x86-ified explanation

the current IPL masks off any interrupt with an associated IPL that is <= the current one
right
on x86_64 that can be directly represented with the cr8 register
no like i understand cr8
i dont understand what problem this is solving or working around tho
so basically if you were at IPL 2, masking off preemption, and then the timer interrupt was taken and decided to do a quantum end, you probably dont want to get preempted
so you dont get preempted, it just returns without dispatching that soft int
it gets dispatched when you lower IPL
however if you were at a lower IPL then you do want to get preempted asap
so in that case it is dispatched in the interrupt handler before returning
this allows the scheduler to be interrupted by hardware interrupts and also allows DPC/quantum end dispatch to be done in software
what IPL is timer interrupt?
ideally one of the highest
in mintia2 its the second highest after the IPI which is the highest
so higher than 2?
so what you're saying is, you only dispatch context switches when you lower ipl to some small number?
just define IPL = %cr8, raising a soft interrupt as sending yourself an IPI on a vector that's within that priority class, and every interrupt handler starts by raising %cr8 to the appropriate value for that priority class, and ends by lowering %cr8 to its previous value. that's the kind of concrete processor that the abstract processor that the IPL concept prescribes, and which an IPL mechanism emulates in software to a greater or lesser degree (and it's useful for efficiency to do more emulation than necessary)
but then how do you preempt if you were at ipl 0 and got a timer irq? u cant context switch because current ipl is very high
you can
A hardware interrupt can interrupt a few circumstances:
- User mode / normal IPL kernel mode code
- Code running in IPL 2 (DISPATCH_LEVEL) in NT
- Another hardware interrupt at a lower level
right before you return from the interrupt handler
in short everything is conceptualised as interrupts existing in a hierarchy of priority classes, with the ability to raise IPL to a level such that some priority class of interrupts is blocked (this includes the level 2, that level which does DPC dispatch and does context switch if one is pending)
before return u loweripl to previous, and if it was smaller then 2 than u context switch?
Think about it like this. You basically "morph" the interrupt into a lower level interrupt
otherwise u defer to the interrupted code?
i do lower IPL to the previous one yeah
but i dont use KiLowerIpl to do it
The timer interrupt essentially "becomes" the dispatch interrupt
Without bearing the cost of a return from interrupt and another hardware interrupt
what do you use?
but only if the interrupted code was running at a low ipl right
essentially bc KiRaiseIpl and KiLowerIpl are hyper optimized for the case of moving between software ipls which is the vastly most common case and does not require touching hardware interrupt masking
This can only be done if you interrupted an IPL lower than dispatch level yes
so i can just forego that entirely and pretend ipls that affect hardware interrupts dont exist in those routines
which makes them inappropriate for raising and lowering ipl in hardware interrupt handling
and if it wasnt, then u just set a bit somewhere that a preemption is pending and then it preempts later on in loweripl?
If you interrupted dispatch level then you have to return from that interrupt back into dispatch level
now i'm not sure if the timer interrupt or something else is supposed to determine if a quantum is over
but u can only context switch if < 2?
yes since >=2 masks it off
in boron the timer interrupt does
it does
ok i think i understand
when it detects that a quantum is over it sets a flag "PENDING_QUANTUM_END"
why does it need to interrupt self in this case, if loweripl checks for quantumend anyway?
because it wont call KiDispatchSoftwareInterrupts (which calls the IPL 2 interrupt handler if necessary) unless that bit is set
this basically enables a fast path where you just go like
KiLowerIpl(new):
curcpu->Ipl = new
if curcpu->Pending >> new != 0:
KiDispatchSoftwareInterrupts()
return
where Pending is a bit set
https://github.com/iProgramMC/Boron/blob/master/boron/source/ke/sched.c#L635 is my somewhat more complicated for little reason version
KiSoftInterruptSelf sets a bit in that bit set
if this looks racey bc interrupts can come in and fiddle with it and whatever while youre in KiLowerIpl, youre right. and i noticed that and would take time to disable interrupts for that routine and stuff. however one day i realized that all of the races are harmless and instantly self-correcting and that i dont need to do that
it do?
yeah thats explicitly coded in a few places, the actual KiLowerIpl implementation is this though (the fox32 version for somewhat increased readability for x86 ppl)
i see u also have a similar function for Apcs
the magic number 0xFFFFF000 is where i map the per-cpu structure on fox32 (where there is only ever one cpu)
dont ask why i did that i forgot
i think it micro optimizes some stuff
btw what sort of dpcs does this run usually
one of them is the ULE global work balancer
runs each second on the boot processor and moves threads from the most loaded processor to the least loaded processor until theres balance
it's just a list of function pointers right?
(or until it has moved a lot of threads and needs to take a breather bc its currently holding up literally all threads from executing on that core)
DPCs
essentially yes
whats the difference vs apcs?
DPCs are targeted to a processor and run with preemption disabled
APCs are targeted to a thread and are next executed when the thread is next scheduled in and is at < KI_IPL_APC (which is IPL 1)
they are preemptible
they can also access the userspace of the thread's process
and take faults on it
hmm interesting
so an APC is used to asynchronously write out the IO status block after an async IO request finishes for instance
what apcs does mintia have
new mintia has none yet, old mintia used them extensively for async IO completion and so will new mintia
basically targeting an APC at the originally requesting thread to cause some completion work to be done in its context
i actually implemented them early on in old mintia and then like a year later i hadnt found a use for them so i removed them
and then a year after that i implemented async io and was like "oh. thats what theyre for." and had to dig thru the repo history to resurrect them
damn yours is very nice
clean and abstracted away
makes sense
will, do you mind answering some of the questions in my boron thread
im again kinda lost. i have an inkling of an idea what to do but im not totally sure and would appreciate some feedback
does dispatch refer to DPC in this case? since u cant actually dispatch at dispatch level lol
DPCs run at dispatch level yes
its the level the dispatch interrupt runs at
where dispatch is a VMSy way to say scheduling
aka preemption
so raising to that level masks off the dispatch interrupt ie masks off preemption
so the scheduler doesnt preempt itself basically?
yes
ah
my scheduler never disables interrupts (except at architecturally necessary moments where itd explode if it didnt)
yeah it seems unnecessary if u have ipls
architecturally necessary moments being like where youve only partially switched context and if an interrupt came in at that moment youd blow up for whatever reason dependent upon the architecture's interrupt dispatch details
unavoidable stuff like that
you can do raise ipl lazily, basically store the new ipl in a per-cpu struct and when an interrupt arrives that should be masked out by the new ipl you can just write to cr8 and return from the irq handler
ik you can but thats still slower than software dispatch
and i was trying not to completely overwhelm infy with information lol
infymation
nah i know about lazy ipl
and then lowering is either the same or slower
u still have to run the handler later right
so u must save that info somewhere
This sounds overly complicated for no reason
and dispatch is definitely slower
its not
its pretty simple
its just complicated to explain
interrupt priority levels are a very nice thing
nah its very simple once u understand
i dont understand them fully yet but 
pmOS solution is to just gtfo as soon as possible/dispatch to lower level if the kernel preempted itself
Not tied to priority levels
for lazy ipls im not sure when ur supposed to run the hardware handler properly
maybe u queue it as dpc to run later or something
(I mean in theory, I haven't implemented timer preemption yet)
also again dispatch is taking a whole ass interrupt exception in your way
in mine its a branch
in vms, writing cr8 is much more expensive
because it's a vmexit
on real hw, probably
(though the fact that I don't switch kernel contexts drastically changes everything I guess...)
But is it actually a better solution?
Like how often do you get preempted by timers, compared to extra branches stuff
because an exception is like 100 cycles?
Every time you enter the kernel
in mintia2 i do not really use ipl outside of the innermost parts of my kernel that are called relatively infrequently and briefly
so ive probably mostly removed whatever 0.1% loss from that branch from most of the hot paths
noncontended locks dont raise ipl for instance
also its a forward branch so in the absence of any history or hints its predicted taken (ie no softints pending, the common case) on most uarches :)
jackal allows u to do FN (<typedef>)?
nvm
thats interesting
i got that backward. forward branches are predicted NOT taken on most uarches. :(
backward branches are what are predicted taken bc they are Probably A Loop
which Probably Loops At Least Once
yeah
and then it screams at you violently if you even name a parameter differently than the typedef
[[unlikely]]
ik
in the absence of hints the branch prediction is primed using the sign bit of the branch offset is the common trick i think
cool
actually you have to do that
before you can assign a field of that type with a function pointer
it should
damn new microcode
boo
i havent slept 
@rustic compass @fiery turtle could i work on uacpi-rs?
i dont have a say in this lol, but i dont mind
well, you control the orga don't you?
yes but uacpi-rs is shinribo's code
yes, let me just push my changes
which is basicly 99% of types.h
except handlers, i will figure out how to do them once i encounter them and see how they are used by uacpi
also as of now i copy all strings used by uacpi which are exported to the user into rust code so that i can guarantee that only the reference to the string is passed to the user instead of the entire string (maybe i can cast a reference to a c string to a &str then we can just use uacpi string stuff)
also sorry for taking so long 
i assume you want the table api for now so maybe we could just get barebones mode first
i would say those standard table names which are also defined by uacpi should go into a enum
i guess
how would that look like
you would call the table find method with a member of that enum as a parameter and internally it would use match to turn it into a string and call the string variant
pushed everything
barebones mode included
but no cfg! added to the functions yet
k
yes
im actually not aware of any other user of uacpi-rs atm (besides shinribos os)
also i didnt pass the use buildin mem functions so aparently that works out of the box with rust (core exports mem stuff with c abi)
me neither
sent
accepted
the way i do it for zuacpi is to have a u32-backed enum and each member's value is the four-byte string treated as a u32
idk how youd do that in rust
but its very nice to use in my experience
You can select the ordinals for your enums
enum MyType {
OptionA = 0xdeadbeef,
OptionB = 0xcafebabe,
};
But I think you probably mean this
match packed_name {
0x54445352 => Thing::Rsdt,
_ => Thing::Invalid,
}
more like
enum table {
fadt
hpet
}
match var {
table::fadt => "FADT"
table::hpet => "HPET"
...
}
uacpi_table_find takes a struct with uacpi_object_name which can technically work on a u32 signature
i usually use find_by_signature
can just @bitCast the u32 back to a [4]u8
and it just works
make it inline and the compiler will do it eagerly too
cant do this safely in rust
rip
when an interruption occurs, for example, from the power button, what will happen if cr3 is not a kernel ? (my scheduling changes cr3 for each task)
it's an interrupt like any other interrupt
how you handle it is up to you
how do you handle other interrupts if your kernel isn't mapped lol
it's always mapped
well then where's the problem?
i mean suddenly uacpi will use some addresses which are not mapped
then that's your problem
why aren't they mapped?
kernel stuff should probably always be mapped
or just defer that work instead of doing it in an isr
really up to you
but i don't see why uacpi should be concerned by that, literally nothing about handling interrupts is specific to uacpi
do what you need to do in the isr to either a) defer that work to a worker thread b) allow uacpi to run properly
sounds like a skill issue language, what is there unsafe about this
invalid state
rust enums can only be converted into an integery not the other way around
because of the pattern matching rules
if you suddenly have an unhandled enum representation you'd fall through and get ub
Default case?
not a thing

enums in rust are not layers upon ints
Breakign news assembly is more flexible than rust
Are the CT?
ct?
what's that
It would be sufficient to turn a enum into a int and define each enum element with the value corresponding to a table
Like defining it as a [c_char;4]
And then casting it into a u32
And put that into the enum
Compile time
You mean more memory-unsafe than even C
"are the compile time"?
not sure what you're trying to say
Whether enums are compile time. No. They're not macros but like any other value, expressions with them can be evaluated at compile time.
Safety = Limits
The language doesnโt have to be safe
The code should be safe
โข๏ธ
I used to think this way you know
I considered myself an expert C programmer and still do
And then I tried Rust and immediately fell in love with it
It's very nice not to have to worry about:
- Heap corruption
- Garbage pointers
- Use after free
- Double free
And as a bonus, while not impossible, it's much less common to leak memory.
Rust doesn't really help with memory leaks over C++ though
it does in specific cases
all the stuff that prevents memory leaks in Rust also exists in c++
like refcounting pointers, containers, box/unique_ptr
yeah but Rust makes them mandatory
yeah but that's on purpose
just like calling raw new in C++
Rust protects against memory safety issues and that's very valuable, but it doesn't really improve memory leakage over C++
but memory leaks aren't inherently unsafe
rust doesn't solve logic issues 
i know. i'm not claiming that they are
exactly
ah you edited your msg
just never free 
When I tried it I immediately hated it, it felt like it was limiting me while offering no advantage
Which is different to languages that provide abstraction like C++ which donโt limit you and only allow you to make your code look nicer
But Rust isn't trying to replace C++
If it's "replacing" anything it'd be C
Personally I'm not a big fan of C++
I am comparing C and rust
I just mentioned C++ as something that doesnโt do explicit safety and it works well
this is exactly what zuacpi does fwiw, though zig enums are always int-backed and can be defined as non-exhaustive or have an error for an unexpected value depending on what i want it to do
its just that zig also lets me safely convert that back into a 4-char-array-with-compile-time-length so i can pass it to uacpi
rust is meant to help you write "correct" code
taking shortcuts everywhere is bound to cause some footguns
there is a place for safe rust but i think it's rather smaller than people imagine
you canโt have good code without footguns
Strange to hear that coming from you lol
real
I mean yes
in particular the fearless concurrency and memory safety are not compatible with big shared state machines like kernels (yes, i know we try to localise the state per cpu or per thread or w/e, but we still have it)
Yeah it works best for cli tools or like data processors like compilers
wdym?
Youre like the biggest rust guy here
Yes
the simpler truth is that an efficient kernel needs Frightful Concurrency and Memory Chill
the problem with rust is that i dont see where it makes sense
i dont think it makes sense in app stuff
because in that case you have plenty of GClangs to choose from
I trust your opinion because u know it well
gclangs are slow
lolnope
Go is pretty fast
they're not, they're roaring fast
go is pretty shit lol
And safe af
L opinion
dotnet, HotSpot, JavaScriptCore, V8, LuaJIT...
i mean in terms of performance
in fact they tend to outperform all but the most sophisticated techniques of manual memory management or automated-but-simplistic
dotnet is also very slow in comparison
they are objectively really really bad
Just needs a better gc impl
The lang itself allows for better optimizations
yeah
what a good JIT can do is absolutely incredible
v8 can make even something like JS run like lightning
really?
JavaScriptCore is a bit faster afaik?
but yeah they all do an incredible job of making code run really fast
i mean how much money has been invested in optimizing it
and manhours
its crazy to think about
it is
benchmarks?
you can optimize a jit and gc all you want, but it's still bound by the language design. a lot of the dotnet abstractions are not zero cost
by now a lot, but the dirty secret of JITs is that most of the technology was invented for Smalltalk in the 80s (and then elevated to a high art with Animorphic Smalltalk/Strongtalk in the 90s)
what's cool is that JITs have inherently a better overview of program runtime so they can optimize accordingly
this is really ideas without any evidence to back it up
the cool thing about dot net is struct vs class etc
rust fan L + cope + seethe + mald
allows for some extra optimizations
HotSpot was written by the Animorphic Smalltalk team, and google later hired all of them to write V8. so it has a remarkable degree of overlap
I am a big fan of D
didnt know that
HotSpot is very cool
I think tsoding even made a video on it
in fact even terminology as fundamental as the Oop (ordinary object pointer) can be found in common between Strongtalk, HotSpot, and V8
but yeah the problem with rust is that it really doesnt make sense imo
good because i kinda hate it lmfao
I think it can fit somewhere as a C++ replacement for some user apps
GClangs are way better for apps stuff
Says the person whose nickname is rustc 
for high performance things yeah idk maybe?
also the next ubuntu will ship with rust tools instead of gnu stuff right
well who wouldn't want to write high performance apps
and the Smi as well (SmallInteger, a smalltalk class of integers below (system word size) >> a few tag bits. V8 iirc rejects NaN boxing as an unwanted innovation and retains traditional Smi-tagging
that will be fun
v8 doesn't have nan boxing yeah
actually i think they dont have unboxed pointers in general?
but go, c#, java etc all provide similar levels of performance
without objectively hard to work with borrow checking issues
the cowards, they didn't even use js or lua coreutils
similar compared to rust?
yes i think
if you exclude autovectorization yeah
i suspect that dotnet and hotspot can autovectorize your code too
yeah but they're not very good at it compared to LLVM
almost every comparison i see is them being worse than rust/c/c++
david chisnall actually argues for a lot more use of high-level languages in the core userland of operating systems, he thinks a service manager/"init system" would actually be better off as a small C++ core and lua on top to provide more complex semantics. and he may have a point
worse yes, but the question isnt "is it worse" but "is it significantly worse"
i would argue yes
isnt that basically the "entirely managed os" idea
2-4x worse is not significantly worse for large apps where the ease of developement benefits justify it 10 fold
oh yea sure
in those, the kernel too is usually in the managed language
isnt v8/javascriptcore something like 2x lol
ohh ok
like, for mid-high performance userspace stuff like some web servers Go and Rust are head to head
lmao
random article i found
except that go is like 10 times easier to write code in
that's memory usage
no
oh i read only the beginning, the issue is that GC memory usage is really hard to measure
^
the cpu usage is nowhere close to 100%
imo its less important than performance
the truth in the end is that a lot of apps and core userland as well don't even remotely need to be fast, and this isn't a case of getting drunk on the overabundance of processing power and memory at your disposal today, it's a case of "a service manager running on a 40 year old computer could happily be mostly in Lua without any detectable impact)
u can call into the gc after every statement to bring it down 
emacs is almost mostly written in a shoddy intepreted lisp, and that was plenty fast even 40 years ago
go hits a better p99 in those benchmarks as well
gcs can be faster than manual allocation too
duh? that's under no load
yeah you cant really benchmark fairly like that
so i am very sympathetic to chisnall's position now, that writing a service manager in C or C++ or Rust is giving yourself a lot of pain and adding some risk in the case of the former two, for nothing. it simply doesn't cost much to maintain and operate on a graph of what's probably going to be at most a few hundred services
Modern CPUs are crazy overpowered for what we actually use them for most of the time
C# and go use more memory because there is no memory pressure
so theres no point collecting and wasting cpu time
c# stays under 3%
i'd say no, modern cpus are fast at a lot of things but for others they're hardly faster than 90s stuff (relatively speaking)
unused memory = wasted memory
like memory latency
emacs with libgccjit is now pretty fast
which is cool
literally yes
i keep seeing people mald over windows memory usage
But they're still completely overpowered for the average office job
lmfao
yeah because peope are stupid
Wasn't that a case of caches reported as in-use memory?
microsofts fault for choosing the algo for displaying free memory in task manager
text rendering is a fucking mess
like, doing it faster will break some unicode edge caes
that too
when openFont
hw accel for typeface rendering
I know but I mean you don't need a high-end CPU to render text
And if you're editing documents a lot of it doesn't need to be re-rendered because it's just scrolled around
Be that literal scrolling or inserting lines
but yeah the problem with rust is that its lacking good use cases:
- for web server stuff, go is about as fast at runtime and way faster to write code in (async rust is a mess)
- for kernel stuff, it kinda works? but it's not oom safe so you need lots of ugly hacks if you want to be a real kernel etc
- for embedded, its cool ig? but how much of that is there
- for tools, go works better too imo
have you seen redox code
Why is it cool for embedded
very much embedded actually
like, look at redox futexes
i mean it works well enough
it has a nice ecosystem
embedded != osdev
rustsbi, oreboot
not this kind of embedded lol
Because embedded has always been an environment where robustness is imperative
You mean like toolchain support?
i meant more the "microcontroller shit" kind of embedded
no like libraries
Oh
rustsbi works on microcontrollers afaik
ah yes my 4mb binaries on my microcontroller
but why the fuck would you use it
idk
no_std rust is quite small tbh
most embedded people don't seem to be very good at what they do so rust can only help them really
optimized rust isnt that big if you are careful about using libraries
its not as great as C
but yeah no rust is cool there
the embedded people are getting away with murder
Lol
Well actually modern microcontrollers have legit become that large
Maybe firmware devs should take note
also this
yeah I know
river was fairly small
at least with c you can pop their code into ida and see what kind of crap they did
firmware devs when they have to produce working software:
Lol
How did your bios update go btw
but yeah the problem is like. you either are on a platform which is desktopy enough that a gclang is fine
terrible
or you are in embedded which isnt that big
A friend of mine is a professional embedded dev and he describes his coworkers as incompetent
Lol why
And when I hear the things he says they're incapable of I agree
now my mobo never wakes up again once it hits s3
Also cryptobros like rust a lot iirc
Bruh
they are all about hype lol
do they? that's news to me
and rust is also like 90% about hype
True
they love to use it for smart contrats
most crypto bros dont know shit about coding
Have you tried rust?
yes lol
lol
Because this is what I thought before I tried it
rust is very much overhyped
yeah
it's a good language though
its a cool langauge
I would rather see it with a GC
wouldnt want to write an app in it
100% this
i'm not surprised, it is an area people imagine is full of carmacks, knuths, and other greats, but in reality most of it is not important work and treated as such
am i stupid
rust with gc instead of borrowck crap would be so good
the ocaml stuff is nice, the C/++ stuff is nice, the borrow checker sucks and is annoying to work with
rust gives you the benefit of gclangs without requiring a gc. how is this a bad thing?
the most of the job is probably knowing how to mix freertos and lwip and other things made by the talented ones
because it doesn't give you the benefit of gclangs
lol
Scala?
it fails pretty miserably at it
type Foo struct { Thingy *Bar }
type Bar struct { Items []*Foo }```
please write this go type in rust
the main benefit of gclangs is that you don't have to worry about memory management
this
yeah 100% this
as someone i can't remember put it
in rust you do, you just experience the issues at compile time instead of runtime like with c
the main point of a gclang is that there is 0 thinking required
low level languages is when you have to think about things you don't need to care about
i badly butchered this quote but it went something like that
eh, the compiler is good enough that i can mindlessly write code
when compile fails i just do what it says
and the truth of the matter is most apps do not need to care about memory management
also: without using a lock, refcell, unsafe, a weak pointer, or an enum
struct Foo {
pub bar: Box<Thingy>
}
struct Bar {
pub foo: Vec<Foo>
}
you got the type for foo.thingy the wrong way around
foo has a pointer back to bar
It's something like "when you have to care about the irrelevant"
Oh
the point is that this type is cyclic
or an arena
thanks, now i've been able to find it with google
it's alan perlis
"8. A programming language is low level when its programs require attention to the irrelevant."
that is 100% rust tbh
like rust with GC and good async or goroutines would be very nice to have
The MLisms in it are cool
i fucking hate having opinions
when i didnt like rust everyone was praising it
now i like it and everyone says how trash it is
???
especially as soon as you need unsafe
the second you touch rust unsafe rust begins to suck even harder
tbh
I think it's this then:
struct<'a> Foo {
pub thingy: &'a Bar<'a>
}
struct<'a> Bar {
pub items: Vec<Box<Foo<'a>>>
}
this type is not constructible
you cannot construct <cycle>: Bar { items: vec![Foo { thingy: <cycle> }] }
the only way to do it requires a Cell
just put an option around it 
still unconstructible
IIRC the idiomatic way to do this was to use weak refcounting pointers
which is slower than what go does
is less ergonmic
Oom handling is being worked on and the allocator api handles oom
and is also STILL unconstructible without a refcell
okay cool but i evaluate current results, not theoretical future results
In Rust you sacrifice some of the memory-safe programs and in return you get a type system that guarantees* your code is memory-safe.
also, rust unsafe semantics are insanely hard
no proper oom handling in rust is truly hilarious
in gclangs you get that as well without the sacrificing
*except in the case of LLVM bugs, rustc bugs, or type system soundness holes
yeah, that's pretty much the point
this is also a common compiler patterns
what lol
Not directly
from JITs you have DotNet, HotSpot, JavaScriptCore, V8
They all have an intermediate representation
nativeaot is actually pretty bad though
they all do in the end, and you can haply use C or C++ with a tracing GC if you want
wdym?
i dont have a lot of knowledge about that tbh
yeah whats the problem?
startup is faster, but overall perf is lower than regular c#
huh
and you lose all runtime reflection
unity's il2cpp has reflection
yea but nativeaot is not il2cpp
aot is almost always gonna be slower than a decent jit for the same language, because decent jits utilize info that's only available at runtime
you have PGO though
go has PGO for example
you have some form of reflection, but only the things that are statically determinable
wdym
cant comment on that as i haven't used it
dart has AOT as well i think
basically every good language has an IR :^)
when os in llvm ir
but yeah static PGO kills most of the gains from JIT PGO i think
What about this though: Are there other "well-supported" languages with the same kind of traits system that Rust has? Another one I really like is how Rust deals with generics compared to C++. C++ templates are a good idea executed poorly and IMO Rust does that same thing better.
AFAIK, no
it is a cool think in rust
i like rust error handling
Definitely
yeah its cool
its also stolen straight from other languages
? operator my beloved
but thats besides the point
oh god i looked away for 90 minutes and this place has gone nuts now
traits are an old idea, here they are being put in smalltalk in 2003 https://rmod-files.lille.inria.fr/Team/Texts/Papers/Blac03a-OOSPLA03-TraitsHierarchy.pdf
rusts error handling is cool
rusts error handling just reminds me of haskell tbh
that isnt a bad thing per se but it does
traits are cool too, but they don't outweigh the pain of the borrow checker to me
TBH I don't really like Rust's error handling
why?
every library has their own error types and converting between them is a pain
yeah true
i dont think theres a good way to solve it without a gclang though
speaking of which go has a single error type, which works everywhere!
but no try operator
what i like about rust error handling is that they added a way to catch a panic! and now they've got exceptions
this is basically my feelings on rust tbh. going oh thats a neat idea while never being able to write anything because it turns out everything i want to write has a natural in-memory model that the borrow checker hates
you shouldnt catch panics tho
That's unfortunately inherent to how Rust deals with inheritance
they did?
yup
well because go's ideology is to be simple af
the fate of every programming language that boldly declares "We have something better than exceptions" is to eventually add them in, with some limitation or other
i believe gleam doesnt have exceptions
(but for real)
i do like zig's error handling tbh. no exception type stuff there either but its a fairly early lang
no idea how that plays with BEAM and JS though
yeah true
you can "catch" a panic insofar as you can control what panic calls
exceptions
you cant make that OOM safe
also exceptions arent a good solution /j
honestly ive never found it that limiting. if you need more you can declare that infrastructure yourself and do getlasterror type stuff
go's solution is way better than exceptions
what becomes clear from the history of programming languages is that new ideas come up, they're a fad for a while, then they fade away, and old ideas that were despised for a few years have a habit of coming back
getlasteror is ugly imo
and has kinda the same issue as rust
it doesnt compose particularly well
This is why I think C will still be around in another 70 years
i do think rust is here to stay though
noooooo
okay so now that we have complained at length about rust language
okay i think i have formed a well-thought out opinion
i want a language that gives me the profile of c++ without looking like c++
lets discuss rust libs
liberals ๐ก
aka the ecosystem shitshow
My hot take on Rust's viability is that most (but not all) situations in which people reach for Rust would better be solved by a GC lang
very true
i agree tbh
oh probably
same could be said about c++, no?
Also probably
the second you need more than C, you're doomed anyways
that is true for basically every non gc lang
tbh
except maybe ada
fair point actually
because you may use ada for their theorem proving magic
if you're writing a webserver that needs to process 500 requests / sec, you probably do not want to use Rust
500 per second is nothing
*need
it's not so hot, i think many of us are all aligned on this opinion
You mean 5000 per second if not more?
yep
imagine gc-based autopilot
or a c based autopilot
one hangs the other segfaults
they can hang for quite a while without it being a problem tbh
so long as its not like a critical phase of flight
we can say this: rust is unsuitable for any app which isn't extremely sensitive to performance to such an extent as it can't handle a tracing GC, because rust would require the programmer to invest completely unnecessary effort by virtue of using a too-low-level language;
rust is of limited suitability for complicated shared state monsters like a kernel, because those rely exactly on Frightful Concurrency and Memory Chill techniques for efficiency, and Fearless Concurrency/Memory Safety are pure poison here;
rust may be useful for those apps which don't fall into either category
AFAIK airplane software is written in C and they have (like embedded actually) strict requirements about acceptable programming and memory management patterns
and most apps are in the first category
do go and c# have something like typed enums and/or options
c# does not yet though i think theyre looking into discriminated unions now
which i assume is what you mean by typed enums
I believe that's actually called a fat union
go doesnt have anything like that
tagged, fat, or discriminated union
terms used fairly interchangeably
tagged union yea
More languages should do tagged,fat,discriminated,etc unions
100%
Also why doesn't stuff like Java support having just a plain ol' struct in an array? why does it need to be full on class instances?
when
java doesnt have plain ol structs lol
c# has structs
default init
I know and I'm mad
Also java is way too verbose for my liking
c# structs are great. you can even set explicit field offsets on them
yeah java's type system is very limited
kinda ironic
That's why I pointed out Scala
AFAIK still doesn't the struct
But at least it's got better types than java
yup
if anyone wants to hear more shit about rust: the lack of TLS and async in the standard library is kinda ludicrous
literally every other good language has it
nope!
god c#'s async is so good. legit the biggest reason i use c# for general high level stuff still
well global variables are a crime in rust anyway
My opinion on language to use:
- Kernel -> C and maybe Rust
- Command-line -> Python
- GUI application -> It's a mess either way
- Embedded -> C
for embedded rust is definitely better
I guess there's also:
- Website -> You're fucked
for gui u really want inheritance
website -> typescript
which rust doesnt have

i mean what other options do you have lol
web assembly
website is typescript or js5 preferrably with as few libraries as possible and plain handwritten html
good options i meant lol
speaking as a hobbyist web dev lmao
lol
over the years ive migrated to modern js over typescript but both i still like to use on occasion
I think the JS ecosystem is fucked but react is pretty cool
why not typescript?
Actually that's something I don't find myself missing when programming in Rust. Say about the borrow checker what you want but the way Rust simply prevents thread-safety bugs is very nice.
btw for the typescript thing they chose go over c#
and that was microsoft themselves
soo
this is why i said as few libraries as possible lmao, though i say also fuck react personally, give me jquery or give me nothing
idk why
build system woes mostly
preact is pretty good for small stuff
yes but what if its a thread local variable
Declare a new thread local storage key of type std::thread::LocalKey.
Rust does support thread-local storage but no matter the programming language I don't really find myself ever using actual thread-local globals and just pass around a context instead.
so thats a thing
gotta use jjquery 
tbh i cant remember the last time i needed a thread local outside of kernel dev, where language threadlocal support isnt applicable anyway
@loud ice did u mean something else by tls