#Nyaux
1 messages Β· Page 25 of 1
might not be that bad of an idea...
now do the same thing
this represents @finite summit:
- Write a VMM
- Work on the rest of the ker-
- Rewrite the VMM - if it fails 4
- Rewrite the kernel
with 60 threads
kk
will stress test after finishing writing sched
this rewrite, it's more like
- write vmm
- rewrite vmm
- do other kernel shit
- rewrite vmm
- do toher kernle shit
what I do is
in my thread ready function
Cpu cache starts crying
how
^^^
I find the cpu with the least amount threads in it's queue
If you keep moving between cpus youre gonna have to read everything into the cache in the new cpu
and choose that cpu
okay so what if it only trickles down if the queue reachs a max thread count
say 3
what abt that
yea im imagining it in my brain
i think that works well
My scheduler is gonna do something like this to figure out what cpu to run on (inspired by ule):
Cpu it has a hard target for, always picks it
Last cpu it ran on if it can run immediately
Going up from the last cpu to see if any can run it immediatelly
Go to the least loaded cpu in the system
With load being nr of threads in the queue
nevermind. I updated discord and it's still fucking UI message passing somehow
or whatever
I literally cannot see the threads
#[no_mangle]
pub fn schedule_task(regs: Registers) -> Option<Registers> {
let addr_to_info = rdmsr(0xC0000101);
if addr_to_info == 0 {
return None;
}
let info = core::ptr::with_exposed_provenance_mut(addr_to_info as usize) as *mut perthreadcpu;
unsafe {
if (*info).run_queue.len() == 0 {
return None;
}
if let Some(mut r) = (*info).next.take() {
let thr = (*info).run_queue.pop_front().unwrap();
(*r).run_queue.push_back(thr);
}
if (*info).run_queue.len() == 0 {
return None;
}
let mut thr = (*info).run_queue.pop_front().unwrap();
if let Some(mut cur_thr) = (*info).cur_thread.take() {
(*cur_thr).content.frame = regs;
(*info).cur_thread = Some(Box::from(thr));
(*info).run_queue.push_back(*cur_thr);
}
if (*info).run_queue.len() == 0 {
todo!()
}
todo!()
}
}
what ive got so far
actually
nvm this wont work
fuck
hmmm
@finite summit the problem is
the gs_base is stored in thread
and is making things difficut
idk what to do
wat
it shouldnt be im guessing?
if you are switching to a thread currently in kernel mode then you ignore gsbase when switching to its context
otherwise
you want to swapgs then set gsbase to whatever the thread's context says it is
no thats not what im talking abt
ugh
struct process {}
#[repr(C, packed(8))]
pub struct perthreadcpu {
kernal_stack_ptr: *mut u8,
user_stack_ptr: Option<*mut u8>,
run_queue: VecDeque<Thread>,
next: Option<Box<perthreadcpu>>,
cur_thread: Option<Box<Thread>>,
}
struct Thread {
name: String,
tid: usize,
gs_base: *mut perthreadcpu,
fs: usize,
content: cpu_ctx,
process: Option<Arc<Mutex<process>>>,
}
this is how i define everything atm
#[repr(C, packed(8))]
pub struct perthreadcpu {
kernal_stack_ptr: *mut u8,
user_stack_ptr: Option<*mut u8>,
run_queue: VecDeque<Thread>,
next: Option<Box<perthreadcpu>>,
cur_thread: Option<Box<Thread>>,
}
yes
wrmsr(GS_BASE, foo)
.next exists
bru
also doing this in a linked list
seems useless
when you can do it in a linear array
#[no_mangle]
pub fn schedule_task(regs: Registers) -> Option<Registers> {
let addr_to_info = rdmsr(0xC0000101);
if addr_to_info == 0 {
return None;
}
let info = core::ptr::with_exposed_provenance_mut(addr_to_info as usize) as *mut perthreadcpu;
unsafe {
if (*info).run_queue.len() == 0 {
return None;
}
if let Some(mut r) = (*info).next.take() {
let mut thr = (*info).run_queue.pop_front().unwrap();
thr.gs_base = (*info).next.take().unwrap().as_mut();
(*r).run_queue.push_back(thr);
}
if (*info).run_queue.len() == 0 {
return None;
}
let thr = (*info).run_queue.pop_front().unwrap();
if let Some(mut cur_thr) = (*info).cur_thread.take() {
(*cur_thr).content.frame = regs;
let fs = rdmsr(0xC0000100);
(*cur_thr).fs = fs as usize;
(*cur_thr).gs_base = info;
(*info).cur_thread = Some(Box::new(thr));
(*info).run_queue.push_back(*cur_thr);
} else {
(*info).cur_thread = Some(Box::new(thr));
}
let thr = (*info).cur_thread.take().unwrap();
wrmsr(0xC0000100, thr.fs as u64);
wrmsr(0xC0000102, thr.gs_base as u64);
return Some(thr.content.frame);
}
}
this function
is the most
disgusting code ive ever wrote
but lets hope it works π€
ima gonna hook this up to the lapic
try this on 1 core
2
or 18
im gonna try to add a thread
fun
fault
and of course attaching gdb makes @molten grotto 's uacpi crate say i have no kernel api
oh wait
i just realized
okay it works now
yep ticks now
okay something very cursed is happening
like its able to get the registers
but then it stops
and its stuck
the lapic is firing
strange
oh
okay
this is dumb
im afraid
im going sleep and after that im gonna read some things on scheduler design
im awake
but
idfk
i dont think its a good idea to store the cpu queue in gs base
this complicates things
it'd be better to have a static variable the cpu index's with its lapic id
why?
it just gets difficult for me to manage cause like the thread stores its gs_base but i have to save and load the gs base and like the actual cpu queue is INSIDE the gs_base and i dont know how to setup the cpu queues when there are no threads
unless you have a better approach to this
cause im rlly confused tbh
there is always a thread
and a thread always has a pointer to the cpu it runs on
the first thing you do before you do anything is set up threading primitives
aka per cpu data
you can just statically allocate it for obvious reasons
like for example no memory manager or allocator being available
I store the current thread in gs
And get the cpu using a pointer inside the thread
what
this is confusing

what what?
can u explain further what you meant cause i dont understand
explain what?
now i am confused lol
you just put them in .data/.rodata
aka statically allocate
"allocate"
struct thread
{
// ...
cpu_local* master;
// ...
};```
a global variable
but i thought we were gonna store it in gs base that data
my brain has exploded
yeah so what
you said you stored the cpu being ran on
you can still take a pointer to it
in the thread struct
and stash it in gs base
ooohhh
you can store the current thread in gs base, then you can have a pointer to a static cpu struct
i seee
or wait that might be stupid
i might be stupid
You don't actually store it in gs base
PAGE??? 4096 byte PAGE???? GET IT π
You store a pointer
you set up per cpu data (cpu info + current thread pointer) as soon as possible
and to avoid having an allocator up to do that
you can just have it as static variables for the bootstrap cpu
and properly heap allocate it for other cpus
Yea
idk what's so hard to understand about
struct cpu_local
{
thread* curr;
// other shit
};
struct cpu_local bsp_cpu;
// ...
// setup cpu struct
bsp_cpu.curr = ...;
// write to gs base
wrmsr(GS_BASE, &bsp_cpu);```
then when setting up other cpus
you do the same but you use a heap allocator to allocate the cpu_local struct
cant i just do something like this
struct cpu_local {
lapic_id: usize,
cur_thread: // ptr to thread,
}
static blah: Once<Vec<cpu_local>> = Once::new();
// in smp.rs
fn init() {
...
blah.run_once(|| // setup cpu structs
return vec
);
...
}
fn schedule_task() {
...
let id = get_lapic_id();
let cpu_struct = blah.get()[id]
}
is this bad or
what abt the run queue, where does that go
NO
oh lol
for the most part it is fine
BUT you store a pointer
to the current CPU's
CPU LOCAL STRUCT IN GS_BASE
AHHHHHHHHHH]
cpu_local struct
if it's per-cpu run queues
otherwise it's a global variable protected by a global lock
ok
but
if you plan on modifying this queue
from other cpus
you would probably want to lock it
otherwise just having interrupts disabled while modifying it should be fine
so gs_base points to per cpu data -> per cpu data has the run queue, the current cpu and kernel stack ptr and if usermode user stack ptr
yeah sure
whatever you need to put in there
you put in there
it's your kernel, not mine
magic
bru
I mean if you're just doing round robin
you simply
curr = curr->next;
if (!curr) curr = queue.head```
on schedule
then switch to the new thread
whenever you want
Don't care about load balancing or work stealing
For now
Just assign CPUs in a round robin fashion
okay
what about if gs_base points to a cpu_local struct and that cpu_local struct points to the run queue, and gs_base is stored in the thread itself and the msr is written to from the thread itself, and your still in that same run queue
wont you be stuck on the same cpu_local struct
You setup a different gs_base for every cpu
no but, if its in the cpus "run queue" it can only point to that cpu
otherwise it doesnt make sense
how to explode brain 101 !!
you don't ever write to gs_base in kernel mode
except when swapgsing
when coming from/returning to
userspace
and returning to includes a context switch to a user thread
you swapgs then write the user thread's stored gsbase
but in kernel mode you ignore the thread's gsbase field in its context
and why do u only write to gs base when going / coming out of a user thread now im even more confused π
swapgs
you know how in your ISR handlers
you swapgs on teh condition that you were interrupted in user mode
*the
yea
in your thread context switch function
if you are going to a user thread
you do the same
swapgs
then you write gsbase to whatever the user thread had it at before
test qword [rdi+16+0xB8], 0x3 ; cs & 0x3 (is user mode?)
je .restore_fs_base
swapgs
mov eax, [rdi]
mov edx, [rdi+4]
mov ecx, 0xC0000101
wrmsr```
okay but like
why do we even store the current cpu struct in gs base in the first place
if we swapgs
or whatev
because it is convinient
and sometimes necessary
and on sched init when u setup the cpus
do u write the gs_base?
to set the cpu_local struct?
im sorry bro π my brain dies
OK forget everything
you have a CPU local struct
you initialize it
you store a pointer to it inside of gs_base
in the thread struct right
no
oh
you store a pointer to the cpu local struct
in gsbase
and for each CPU the value of gsbase differs
when u setup the cpus -> do you create the cpu_local_struct, wrmsr to gs base a ptr to the cpu_local struct on whatever cpu
am i understanding this correctly or do i have severe brain rot
you do do that
GS_BASE
okay
KERNEL_GS_BASE is for swapgs stuff
now the reason we swapgs is because usermode likes to store stuff in gs right?
yup
makes sense, and for getting the cpu_local struct on schedule_task() we read the GS_BASE msr correct?
@junior solstice who dis?
yes
and you can use gs-relative accesses in assembly
if we are returning/coming to usermode we write to kernel_msr_base whatever is in gs_base the usermode thread struct
mov eax, gs:0x8```
i see, yea for syscalls
nope
oh
mhm
when you are going to usermode
that puts the user's GS base value in GS_BASE and the kernel's GS base inside of KERNEL_GS_BASE
and when you are coming from user mode it does the opposite
the user's gs base value goes in KERNEL_GS_BASE
and the kernel's goes in GS_BASE
because what swapgs does is swap the values of the KERNEL_GS_BASE and GS_BASE msrs
and im guessing the kernels gs base (not talking abt the msr)
is the one that stores the cpu local struct
yes
and the user's stores whatever
the user's GS base can really have anything it wants
the kernel doesn't give a shit about what is in it
it only gives a shit about making sure both user code and kernel code have the GS base they expect
okay so
if cs was coming from usermode:
get cpu local from gs_base
do run queue stuff
and if going to usermode:
write to msr kernel_gs_base value of gs_base from thread
going to kernel mode:
do not write anything
if cs was coming from kernel mode:
get cpu local from gs_base
do run queue stuff
and if going to usermode:
write to msr kernel_gs_base value of gs_base from thread
or if going to kernel_mode
no writing
do i understand?
oh
if cs was coming from usermode
swapgs
do shit
swapgs (on return)
if cs is coming from kernel mode
do shit
okay and
for getting the cpu local struct
what do u do
if ur coming from usermode or coming from kernel mode
and for writing the value of gs_base if ur going to usermode
what msr do u write to
like make it like an if statement ill probs understand lmao
π
rdmsr(GS_BASE)
mhm
swapgs
if (frame->cs & 0x3)
swapgs
// do IRQ shit
if (frame->cs & 0x3)
swapgs
iretq```
oaky but what about this^
i understand the swapgs part
well depends
are you going to usermode from an irq handler
if so then swapgs handled it for you
if it's in a thread context switch
then you can write to KERNEL_GS_BASE then swapgs
yea im talking about this
not the irq handler
π
or you can swapgs then write to GS_BASE
so
if coming from usermode:
swapgs
rdmsr gs_base to get cpu local struct
do shit
if going to usermode
writemsr kernel_gs_base value of thread gs_base
swapgs
iretq
else
do nothing and dont swapgs then iretq
if comfing from kernel mode:
no swapgs
rdmsr gs_base to get cpu_local struct
if going to usermode
writemsr kernel_gs_base value of thread gs_base
swapgs
iretq
else
do nothing and dont swapgs then iretq
yea that actually
sounds rlly
easy
π
why didnt i understand it first try
π
its lit the same shit
@finite summit thank you for making me understand
:D
now is funny scheduling time muheheheh
np
also rust community told me to use an AtomicPTR for the cur thread or whatever
yeah it's simple af
im just gonna verify with them the reason why?
I assume that's a pointer for which every access is atomic
yea most likely
A raw pointer type which can be safely shared between threads.
This type has the same size and bit validity as a *mut T.
Note: This type is only available on platforms that support atomic loads and stores of pointers. Its size depends on the target pointerβs size.
okay i see
sorry not cur thread
the
stacks themselves
ask him why
idk why you would need atomic accesses for stack bases
for syscalls
considering the syscall handler is in assembly
idek what difference that makes
in my syscall handlers, scheduler preemption is disabled
but you can still be preempted by other IRQs
aka IRQL is at IRQL_DISPATCH
time to open vscode
https://github.com/OBOS-dev/obos/blob/userspace-work/src/oboskrnl/arch/x86_64/syscall.asm#L49
this is my syscall dispatcher
it simply swapgss first thing then switches to a kernel stack stored in the per-cpu struct
What if the syscall sleeps
it doesn't
shit it does
*it can
they can
!!!
you just saved me the many debugging time
Smh oberrow
smh mathew
SYSCALLS CAN MEOW
GRRR
@finite summit how big of a kernel stack should i alloc
256k?
note that it will be allocated for each user thread
@spice yarrow spotted
jason spotted
ik
memory usage be like:
my user stacks are like 2mib
oh ok
i will do the same then
you allocate user stack whenever a thread is created
and optionally increase its size (?)
what
no
good to know
the stack is just an anon mapping like any other
they're allocated lazily
i.e. on page fault
mmap
demand paging is very easy
^
CoW is where it gets a bit trickier and requires a bit of thinking
on page fault:
if cr2 was mmap-ed && fault == non_present:
map_page(faulted_page, alloc())
When you map, you don't actually map but store that information somewhere
whenever a process tries to access an unmapped page, it page faults and you map it
what
wdym what
store that information where
you implement that
i dont know how to implement this im dead inside 
which is per process
start with like
64kib user stacks
that's the shitty but works way
ok
maybe have a vector of structs per process that say what is mapped to where
Yeah linux has a pretty big user stack
im not implementing this
im just gonna
64kib user stack

i just want a working os anyway like 
This iteration of astral only had demand allocation at first but then I expanded it to copy on write and proper file mappings with page cache etc
You'll still need mmap and it's better to use on demand paging for that
nooo
that sucks
no its fine
yes but it's simple
use rbtree!!!! (/s kinda)
I have never actually used rbtree
or any datastructure that allows for better searching
if kernel explodes due to stack size being too small just increase stack size
memory usage?
pfft
whats that

hash map 
yes
I say that but I use a linked list lmao
does rust have a built in hash map
like Vec
anyways @finite summit ive created the cpu local structs written them to gs base, now how do i decide which thread do i give to which cpu for the kernel entry thread or whatevs
in the standard library yea
so not with no_std
dunno
I will use a rbtree once I implement one
Linked list can go a long way
yeah
I still use it in astral
realistically a process wont mmap 1000 times
vector is probably better than that, no?
you could binary search
oh yeah
just insert sorted :D
why not use freebsd's tree.h
not using C?
or just don't wanna
because ew C!!
anyone know :(
I want to minimize external dependencies
I'm currently in the process of phasing out frigg
do i just give it to the buttstrap cpu
whichever has the lowest amount of low priority threads
GET IT BUTTSTRAP π
someone pin this
best joke ever
anon map
yes
basically you have one entry per page
im just gonna give it to the buttstrap cpu

netbsd uses some kind of dynamic multi-level array
guys whats ur opinion on the buttstrap cpu
best cpu or what
am i right or am i right
audience claps and laughs
(sarcasm)
π‘
this is openbsd but whatever
https://github.com/NetBSD/src/blob/trunk/sys/uvm/uvm_amap.h#L169 netbsd comments are better nvm
no
looks like openbsd uses an older version of uvm or something (?)
they took it from netbsd on 2001/02/18 21:19:08
stop aruging in my thread and let me code π‘
I think I might just use a tree
faster than linked list and might use less space than an array (?)
pub fn create_kentry() {
// on the buttstrap cpu
let him = rdmsr(0xC0000101);
let bro = core::ptr::with_exposed_provenance_mut(him as usize) as *mut perthreadcpu;
let new_ctx = cpu_ctx::new(lol as usize, false, unsafe { (*bro).kernal_stack_ptr });
let new_man = Thread::new("MY MAN", 0, 0, 0, new_ctx);
unsafe {
(*bro).run_queue = Some(Box::into_raw(Box::new(new_man)));
}
}
so easy
Bro can't take it seriously
buttstrap
serious
mint would agree
thats how you call the buttstrap cpu
right mint
yes nyauxmaster
that is how you call the buttstrap cpu
see they agree!!!
its not working 
its stuck here
and even tho it is returning the registers
and stuff
its not
running my entry function

so not fair
and i do
move rax into rsp
rahhhhh
cpu hates me chat
π
excuse me what the fuck
why don't you just
have an asm file
π
nuh uh !
Inline assembly is evil.
cant you just pass that address to addr2line
i did
you grep
lol thats the result
accident
i made a mistake
i would use gdb but
this happens when i attach gdb
not my fault 1000%
i think its a bug with uacpi-rs
idk
qwinci pls fix
like this is so obvious
why does attaching gdb cause it to shit itself
clealy does
works fine in tcg and kvm
not when attaching gdb server tho
so im kinda screwed
idfk how im gonna debug my scheduler and why its shitting itself
Wtf is the KTUACPI... trait
idk man
shouting
lmao
ima wait for qwinci to come online cause this should NOT happen
and i dont think i will be able to debug my scheduler without gdb
or some kind of debugging tool
lmao
bro i cant printf fucking assmebly
i need to see the stack
whats going on
if the stack is getting fucked or whatever
i'd imagine its something with the assembly
thats what i think
make a function that prints something and extern C it
thats why i need gdb
and call it from asm
bru
@molten grotto do u know whats going on, this shouldnt happen like. at all. with the uacpi-rs crate u have
try reading the uacpi source where the panic is thrown
debug the issue without the debugger
i read the source
and what did it tell you
where does it panic
line 183
show me the line 183
Where is it called from
I lost them
called when uacpi::init
and where is it called from?
can you show it to me
common rust L
its not a rust L
idk man
i rlly dont know
maybe rust is optizming the struct out?
cause theres no data in it
idk why it'd do that tho
does it work in debug mode?
yep on both modes
so when does it not work
gdb L then
it's always a rust L
bru
further debugging shows invalid opcode
i dunno but it is what is says before it triple faults
Does it say 7c0
in the RIP, yea
Then why are u looking at something else
it says that address^
7c0
which is
my print function
x/10i 0xffffffff000007c0
attaching a debugger makes this even weirder
but ill try again
Run that in qemu, not gdb then
alr
idfk
wait no
nvm
ffffffff800007c0 <NyauxKT::term::_print>:
ffffffff800007c0: 55 push rbp
ffffffff800007c1: 48 89 e5 mov rbp,rsp
ffffffff800007c4: 48 83 ec 10 sub rsp,0x10
ffffffff800007c8: 48 89 fa mov rdx,rdi
ffffffff800007cb: b1 01 mov cl,0x1
ffffffff800007cd: 0f 1f 00 nop DWORD PTR [rax]
ffffffff800007d0: 31 c0 xor eax,eax
ffffffff800007d2: f0 0f b0 0d 6e 11 04 lock cmpxchg BYTE PTR [rip+0x4116e],
found it
looks fine ummm
this is weird, flanterm doesnt even use my allocator so
hmm
push rbp is not an invalid instruction

i even have a double fault handler so
this is very weird
Dump memory contents at the time of crash
difficult, this thing hates attaching gdb but ill try
Dump using the qemu monitor
k will do
It's not as good as gdb, but it's still useful
Well you should definitely fix that sometime
the registers
memory map
thats what im trying to fix
this is the same problem
anything else i could dump?
info tlb
k
That's weird, I thought it combined sequential entries
Question, what if you report your kernel entry point with loop { asm!("out 0xe9, {}", in("al")b'!') }
try to see if you can get gdb to connect to that
at the start of my kernel entry point or where
yeah
how did you find outβ½
magic
gdb connected
whats next
btw im NOT running a mac swear
π π
what next
try this launch.json https://github.com/jasondyoungberg/MycrOS/blob/main/.vscode/launch.json
Install gdb
Oh wait you need the extension, just a sec
Also the executable path should be NyuaxKT for you
okay
ok done
What I find gdb super useful for is getting backtraces
okay got gdb now @spice yarrow
do i remove the uh
asm thing or what
and how do i run commands to gdb via the debug console in vscode
yeah, remove it and see if you can step through everything
I don't think you can? Just use the command line version if you need that
wha
thats all there is
bru
If you want to manually run gdb commands then launch gdb in your bash shell
if you want a nice gui use vscode
okay you might be able to do -exec command in the debug console
What's the line that panicked?
279
in uacpi-rs
and it has invalid opcode otherwise
No like open the file and ss it
this
okay so it's returning an error, fix however your calling uacpi
you aren't getting invalid opcodes anymore
wait so it still does different stuff with gdb attached?
yep
wtf
I KNOW!!!
π
qwinci says its my allocator so clearly somethings wrong idfk
difficult to debug without gdb
im screwed maybe

im just gonna ask the rust gods @spice yarrow in their os-dev channel
maybe they might know
idfk
cause i lit have no option
Why are you using a remote desktop thing
im not
its showing wsl as that icon for some reason
what
There's a remote desktop title on the top left
idfk but its wsl
Is that heavily customized windows or what
im not using "rdp"
no its lit a dock
And a top bar thing
part of the dock
And that's because wsl is just Linux running in a vm
So the GUI apps are remote
yea ik
chat
we have more information
!!!
commenting out
everything
related to writing to the limine terminal
it page faults here
CR2=0xffffffffffffff84
error code is 0
hmm
in here
yep
cr2 is actually this
interesting
it is most likely a rust skill issue im afraid
asking rust peopel for help
The what?
Please do not tell me you used the feature request
Probably meant flanterm?
no i didnt
flanterm
also i have been sleeping all day
π
might not get any work done today
i have a lot of homework
maybe tmerw
still going back and forth with the
rust community rn
cause my page table just always never works

chat im going to cry
its UB
always ub
fucking ub
i hate ub
with a venginence
aaaa
nyaux try not get stuck with rust skill issue #5012616 @finite summit am i right or am i right
if i started with C
we could have signals by now
im genuinely like
im so tired
writing a rust kernel
has been an absolute nightmare for me
I hate rust
do you think i should
think about switching
cause im actually
so annoyed
with rust now
drives me insane
nice now I'm cold
C++ is basically a huge toolkit for you to make your own language 
speaking of cold, my room rn is the nice cold
like not the too cold
the cozy cold
thanks to canada, I get ~0 degree weather in the middle of autumn
not canadian, but have lived in canada my entire (short) life
ontario
ah so probs warmer than here
I've heard you're in quebec?
yea
from misc sources
cool
my friend once went to quebec and the first thing he said was "hon hon oui oui baguette"
yea
montreal is pretty much all english speaking
well not rlly
but like
as soon as you enter the airport you'll hear english

as in live in canada
and idk who that is lol
bro
some old guy it seems
the K in K&R
ohhhhh
designed go?
that guy
the k in AWK too
it's a language
btw he literally coined hello, world
so idk I think he had atleast a little impact 
nah not that much /j
literally did nothing but invent C
like why didn't he invent rust instead
same thing
idk if he helped design GO tho, he did write the book
I need to read up on programming history tbh
also designed m4
m4 carbine?
kinda crazy we still use 1970s scripting languages
I wouldn't say it's a bad idea. rust unsafe is a lot more dangerous than c (though safe rust is much safer than c)
no the script configuration thing
macro processing language
I've never used it but it's used in e.g autotools
autotools is delusional
ah it's kinda like a preprocessor
I'd sudo apt remove it if I didn't need it for building gcc n' stuff
autotools is nice for some stuff
And you seem to really be struggling with rust's rules, so if you decide to switch I wouldn't hold it against you
since you're the rust compiler, should nyauxmaster rewrite in C++
how is it more dangerous than C tho
C has no restrictions
didn't you used to be clang
clang I am no more
I 3> implicitly casting void* to int*
when I allocated a short
(never happened)
I am sorry, why is there a pregnant man emoji on discord
unless I'm missing something that is impossible
unless it's like, trans man pregnant
yeah maybe
Breaking rust's invariants create instant ub, while c doesn't really have many invariants to uphold
I have no idea what that means
maybe has something to do
with
invariant stuff
stuff that do not vary
wtf
rust my behated
now it's too cold
I get blanket and be back
back
let mut x = 10;
let ptr: *mut i32 = &mut x;
unsafe {
let r = &mut *ptr;
let _ = &mut *ptr; // this should be a nop, but it causes ub
dbg!(r);
}
how
Rust should just define every single possible behaviour and become the first language without ub
You can never have two &mut at the same time
It already does
oh right you're borrowing two times
i want to cry
There's also the fact that thread::spawn can never capture non-static lifetimes, even if the thread is killed when it's dropped
tbh it would probs suck even if i did switch to c++
because im such a shitty programmer
do you even know C++
you wouldn't have to worry about rust's crazy invariants
I've been using C++ for a while and I still get confused over stuff like std::forward
which is what seems to be your main struggle
i would use it if it had iterators and hashmaps
hashmaps are so useful
it does tho