klange changed the topic of #osdev to: Operating System Development || Don't ask to ask---just ask! || For 3+ LoC, use a pastebin (for example https://gist.github.com/) || Stats + Old logs: http://osdev-logs.qzx.com New Logs: https://libera.irclog.whitequark.org/osdev || Visit https://wiki.osdev.org and https://forum.osdev.org || Books: https://wiki.osdev.org/Books
hmmmm has quit [Quit: Leaving]
hmmmm has joined #osdev
nyah has quit [Quit: leaving]
bauen1 has joined #osdev
spikeheron has quit [Quit: WeeChat 3.7.1]
dutch has joined #osdev
vdamewood has quit [Read error: Connection reset by peer]
vdamewood has joined #osdev
<Jari--> good morning
<klange> hello
gog has quit [Ping timeout: 252 seconds]
tacco has quit [Remote host closed the connection]
gildasio has quit [Remote host closed the connection]
gildasio has joined #osdev
catern has joined #osdev
vdamewood has quit [Read error: Connection reset by peer]
<Jari--> klange: yo
vdamewood has joined #osdev
<Jari--> when I think about programming, I get a slight pain in the dentals
_xor has quit [Quit: brb]
_xor has joined #osdev
<klange> You should see a dentist.
<klange> I just got a root canal on Wednesday.
dutch has quit [Quit: WeeChat 3.7]
dutch has joined #osdev
<Jari--> Any idea guys how many TPM keys does Windows 10 or Ubuntu etc. require ?
<Jari--> My brother had four TPM keys, so I reinstalled, suspected it was rooted.
<Jari--> One suspecting looking key too, etc.
<zid> why? it isn't 2:30 for 14 more minutes!
[itchyjunk] has joined #osdev
CompanionCube has quit [Read error: Software caused connection abort]
CompanionCube has joined #osdev
<mjg> dude what
<mjg> check yo0ur clock
<mjg> it was already 3:16 when you wrote that
carbonfiber has quit [Quit: Connection closed for inactivity]
<heat> mjg, go to bed
<heat> you're not supposed to wake up for 1 more hour
<mjg> STAY HARD
<mjg> CAN'T BREAK BOAT CREW TWO!
<mjg> you would know what it means if you listened to the audiobook
<heat> stay erect
epony has quit [Ping timeout: 246 seconds]
[itchyjunk] has quit [Remote host closed the connection]
<heat> for "random sockets you can actually mmap", you can mmap TCP sockets in linux
<mjg> what are the semantics of that
epony has joined #osdev
xenos1984 has quit [Read error: Connection reset by peer]
vdamewood has quit [Read error: Connection reset by peer]
vdamewood has joined #osdev
epony has quit [Remote host closed the connection]
ZombieChicken has joined #osdev
xenos1984 has joined #osdev
epony has joined #osdev
<heat> mjg, zero copy rcv
<heat> mmap(tcp_socket) gives you a region it then inserts pages into when doing zerocopy recvmsg
<heat> lol, rejecting out of order ELF program headers breaks video games
<clever> what was bioshock doing, that it violated that ordering rule? lol
<heat> they have a weird tool that breaks it
<heat> and because linux never enforced the order, oopsie
ZombieChicken has quit [Remote host closed the connection]
ZombieChicken has joined #osdev
srjek|home has quit [Ping timeout: 260 seconds]
bradd has joined #osdev
Celelibi has quit [Quit: Quitte]
Burgundy has joined #osdev
heat has quit [Ping timeout: 252 seconds]
Celelibi has joined #osdev
ZombieChicken has quit [Quit: WeeChat 3.6]
zaquest has joined #osdev
gog has joined #osdev
vdamewood has quit [Read error: Connection reset by peer]
vdamewood has joined #osdev
gog has quit [Ping timeout: 268 seconds]
bgs has joined #osdev
zaquest has quit [Remote host closed the connection]
zaquest has joined #osdev
Burgundy has quit [Ping timeout: 252 seconds]
bradd has quit [Remote host closed the connection]
bradd has joined #osdev
PapaFrog has quit [Read error: Connection reset by peer]
LostFrog has joined #osdev
<geist> mmm! Andor season 1
<geist> sooo good
<geist> just finished ep 10
Burgundy has joined #osdev
<mrvn> no spoilers
<mrvn> heat: If something can be done then it will be done.
<kazinsal> currently, erm, acquiring beta 3 of Project 4K80
<kazinsal> usually I like to wait for the full release for the LightDNR version they do but I've been itching to rewatch the whole unaltered original trilogy on my nice shiny 4K TV
<kazinsal> maybe I'll grab 4Ks of the prequels as well and do a machete order watch for the long weekend
xvmt has quit [Remote host closed the connection]
<mrvn> I'm just waiting for "Machete Kills Again... In Space!"
GeDaMo has joined #osdev
xvmt has joined #osdev
mrvn has quit [Ping timeout: 276 seconds]
gog has joined #osdev
gog has quit [Client Quit]
heat has joined #osdev
potash has quit [Ping timeout: 252 seconds]
potash has joined #osdev
bradd has quit [Ping timeout: 268 seconds]
y0m0n has joined #osdev
Burgundy has quit [Ping timeout: 268 seconds]
Burgundy has joined #osdev
y0m0n has quit [Ping timeout: 252 seconds]
bauen1 has quit [Ping timeout: 260 seconds]
[itchyjunk] has joined #osdev
Burgundy has quit [Ping timeout: 268 seconds]
epony has quit [Remote host closed the connection]
nj0rd has quit [Quit: WeeChat 3.7]
nj0rd has joined #osdev
epony has joined #osdev
Matt|home has joined #osdev
gildasio has quit [Remote host closed the connection]
nyah has joined #osdev
gildasio has joined #osdev
srjek|home has joined #osdev
gildasio has quit [Ping timeout: 255 seconds]
gildasio has joined #osdev
heat has quit [Remote host closed the connection]
isaacwoods has joined #osdev
heat has joined #osdev
dude12312414 has joined #osdev
srjek|home has quit [Ping timeout: 268 seconds]
Burgundy has joined #osdev
mrvn has joined #osdev
jjuran_ has joined #osdev
jjuran has quit [Ping timeout: 246 seconds]
jjuran_ is now known as jjuran
gildasio has quit [Ping timeout: 255 seconds]
gildasio has joined #osdev
xenos1984 has quit [Ping timeout: 252 seconds]
xenos1984 has joined #osdev
elastic_dog has quit [Remote host closed the connection]
elastic_dog has joined #osdev
jjuran has quit [Quit: Killing Colloquy first, before it kills me…]
jjuran has joined #osdev
xenos1984 has quit [Ping timeout: 252 seconds]
scoobydoo has quit [Ping timeout: 260 seconds]
xenos1984 has joined #osdev
scoobydoo has joined #osdev
tacco has joined #osdev
gog has joined #osdev
<gog> hi
<bslsk05> ​'l9wqk2eia2z91' by [idk] (--:--:--)
<zid> disregard GeDaMo, carcinize.
<gog> that's exactly how i look when using the computer
nyah has quit [Quit: leaving]
<geist> mrvn: yeah but you better watch it soon, it's harder to keep from getting spoiled on the internet
dude12312414 has quit [Ping timeout: 255 seconds]
dude12312414 has joined #osdev
jafarlihi has joined #osdev
<jafarlihi> Does anyone know if construction of LR0 automaton (aka canonical collection) an intermediate step of LALR1? Also, is "canonical collection" term only refers to LR0 automator and not LR1?
<jafarlihi> s/is/does
<jafarlihi> s/automator/automaton
terrorjack has quit [Ping timeout: 248 seconds]
<heat> have you looked in the intel SDM?
terrorjack has joined #osdev
<bslsk05> ​www.theregister.com: NSA urges orgs to use memory-safe programming languages • The Register
<heat> "The NSA has released guidance encouraging organizations to shift programming languages from the likes of C and C++ to memory-safe alternatives – namely C#, Rust, Go, Java, Ruby or Swift."
<heat> geist: JAVJAVAJVAJJAVAJVJAJVAJVAJJVAJVAJJAVAJAVJAVAJVAJJAVAVAJVJAJAVAJAVA
<geist> RUUUUUUUUU ST
<heat> why iz kernel not write in java???
<geist> RUSTUSRUSTURSUTSUT CARGO
<geist> oh that was a thing in the 90s
<gog> python
<gog> kuroko
<geist> actually spent some time digging through an open source rust kernel, seemed like a pretty good solution
<geist> or at least ahigh quality one. but alas it skips the hard problems i havne't seen solved well
<geist> ie, how to really deal with interrupts efficiently, and how to deal with SMP
<zid> is kernel modules a thing yet
<geist> this one just puts a wake up token in some queue at interrupt time, and then expects some looper thread to pick it up later
<heat> i wanna modprobe a cargo module
<geist> i'm really not seeing a lot of good rust kernel solutions yet. though a few folks here were working on one
<zid> I bet an allmodconfig of linux if it were rust would be about 8GB :D
<geist> I forget who, Mutabah ?
<heat> redox
<geist> yeah last i looked at it it had the same 'basically works but is highly inefficient the closer you get to hardware' problem
<geist> basically like before. ie it works as a demo, but if you dig too deep it gets hackier as you get closer to harder
<heat> sgtm
<heat> ok heat@
<geist> that's wher ei usually start: trying to see if the rust model works at that level
<gog> wrap everything in unsafe {}
<heat> Reviewed-by: heat <heat@irc.libera.chat>
<geist> no worse, like 'dont really handle preemption' or 'dont actually run substantial code in IRQ context' etc
<geist> good for a demo, as long as you dont look that closely at how it works
<heat> real kernels use SOFTIRQSSSSSSSSSSSSSSSSs
<gog> don't run code?
<gog> sounds good to me
<heat> safe by default
<geist> heat: well an efficient implementation would probably be tolerable
<geist> but you have all of this issues with object ownership at that level, since it's totally asynchronous
<geist> so you then have to be extremely careful.et cetc and that's where i see all existing implementations *that I've looked at* totally fail
<geist> because you have to start really inventing your own mechanisms there and trying to defeat the whole locking and borrow stuff
<geist> you can avoid some of it on UP, but then SMP comes along and you're back to square one
<heat> linux has some nasty hacks for stuff you can trivially do in C
<heat> I don't know what exactly, tho
<heat> but it actually works pretty well in lonix
<geist> anyway, a compromise could be you write very low level stuff in C/C++ then the bulk of the kernel in rust
wootehfoot has joined #osdev
<geist> ie, have a low level arch/exception/interrupt layer that does what it does, on its particular objects that are owned by that layer
<heat> i vote for "all in K&R C"
<geist> so you can keep them separate
<heat> oh yeah kees isn't taking my patch
<geist> and yeah will be interesting to see what lunix does there
<heat> cuz he's afraid of a refactor at all due to having literally no unit tests
<heat> so the fix is just a hacky fix that technically solves it
gildasio has quit [Remote host closed the connection]
<heat> nt kernel in rust when
<geist> anyway it's pretty clear i can put off learning rust no longer
<heat> learn go and switch products
<geist> and as i said before it's hard for me to learn a new language because i'm not content just learning how to write hello world. i must *deeply* learn exactly what the compiler does
<geist> which is a different level
<geist> in fact i'd rather just not know what the std libraries do, but learn rust core
<zid> yea that's what I don't like about.. most languages
<zid> there's no spec
<geist> and then learn fundamentally how the language works to build up its own set of libs, as is appropriate for bare metal
<heat> since most of my code is kernel code I frequently struggle with using the standard library by memory
<geist> then i really really need to grok what the borrow checker does, what the defacto memory model is, etc
gildasio has joined #osdev
<zid> and I don't have 20 years of playing with cc1 to figure out what it's likely to do
<geist> ie, for exmaple, when rust thinks it 'owns' an object how far does that allow it to relax its memory model
<zid> python is basically witchcraft, by comparison
<geist> hypothetically it can be far more relaxed than even C because it knows it owns the object, nothing else can reference it, etc
<geist> all things that might bite you in the ass in a kernel environment
<geist> alas none of that seems to be really specced
<geist> even ifyou call out to random other libs, if you have the one mutable handle to a thing it should be able to relax memory references even across external cals
<geist> since by definition nothing external can modify it because they dont have the handle
<geist> if i press rust folks for detals here they usually start to admit it's not really well defined
jafarlihi has quit [Quit: WeeChat 3.7.1]
<geist> so okay, then the question is if you defeat that by making sure rust knows you're not the ony owner of a thing then does it tank performance? if so how much? does it get stricter than C?
<geist> etc
<sbalmos> geist: Ironically I'm not so much having a problem understanding Rust, it's more like the black magic of Cargo when it comes to LLVM settings, controlling linker stuff, etc
<heat> see fuchsia's build files
<heat> they pass all those things manually, they don't use cargo
<sbalmos> that build system is uniquely weird in its own right ;)
GeDaMo has quit [Quit: I'm going to show these people something you don't want them to see. I'm going to show them a world without you.]
gorgonical has joined #osdev
<gorgonical> This is unrelated to actual osdev but I just wanted to say I'm reading snow crash and it makes me feel like when I first read neuromancer
carbonfiber has joined #osdev
<geist> yeah if/when i start to fiddle with rust in earnest i'll immediatelys tart by figuring out what cargo is doing and drive it manually from my makefiles
<FireFly> I read snow crash at some point, later tried to read neuromancer but gave up on it halfway through
<geist> aww i love neuromancer
<gorgonical> the first exposure to real cyberpunk I had
<geist> though snow crash is great too, though it's a bit more silly iirc
<geist> but fun
<gorgonical> way more hilarious than neuromancer, but in a good way
<gorgonical> feels on brand with the "high tech, low life" concept
<geist> neuromancer is more srs bsns, but i love the imagery it invokes in my mind. glad a movie has never been made to ruin that
<gorgonical> it's ironic. like the matrix, reading neuromancer now almost feels trite or dated, because it originated so much of the culture that it feels itself like it's playing into the tropes
<geist> yah also its clear that william gibson isn't a computer person, which is i thnk why it ages as well as it does
<geist> it was like he was dscribed what a computer is and then went and wrote a whole book with it (which is actually pretty much exactly what he said happened in interview)
<geist> but somehow that dates it less to a certain extent
<chibill> Lol element pinged me for that
<gorgonical> I do appreciate that stephenson seems to have at one point dabbled with computers, though
<gorgonical> The jargon feels a little more relevant or authentic, somehow
<geist> whereas things written by say Verner Vinge (who is a CS professor i think) can't resist dropping in some computer tech that is instantly out of date
<gorgonical> But retains a good deal of that cyberpunk imaginativeness
<geist> yah i've read a lot of stephenson books. on a good day they're very fun and enjoyable
<geist> 100% of the time they spiral out of control at the end, so you're generally better off stopping about 2/3 of the way in
<gorgonical> oh boy
<gorgonical> I'm at about 1/2 through snow crash. Excited to see how the trainwreck materializes
<geist> yeah i forget how that trainwreck happens. i haven't read it in 20 years, i think it was the first of his that i read
<geist> hmm, what's the stephenson book with the AI primer book
<FireFly> geist: huh funny, I felt kinda the opposite, neuromancer was a bit too... fast-and-loose with the made-up things and didn't really feel as coherent a setting to me
<geist> ah the diamond age
<zid> old sci-fi is kinda bad now ngl
<geist> FireFly: fair. it goes all over the place for sure. actually thats my main complaint WGs other sprawl book
<geist> books i should say
<zid> Lots of telling stories with no point, just sci-fi scectacle
<gorgonical> FireFly: yeah I agree with you. While I love neuromancer it's clear that in the 80s gibson was totally unfamiliar with computers and was really just leaning on the aesthetic of them
<geist> he has a tendency to introduce like 5 subplots that are totally independent of each other and tie them together at the end
<FireFly> geist: fair point about spiraling out of control though
<zid> star trek sort of codified that sci-fi should be childrens' cartoons writ large, a moral lesson in a tech environment
<FireFly> in both cases (snow crash and diamond age) I felt the biggest takeaway was the setting and the worldbuilding
<FireFly> esp for diamond age I think
<geist> that being said i think sci fi got a lot more interesting and sophisticated in about 1980, maybe 75
<FireFly> "I love being in this world and want to know more about it"
<geist> to me 'old sci fi' is more of the heinlein 50s stuff
<gorgonical> ever read starship troopers?
<geist> and R is for rocket, etc
<geist> fr example one of my favorite book series of all times is mid 80s: Hyperion
<geist> still to this day that series is amazing
<zid> I'm a sucker for a good moral lesson in a tech environment, rather than an epic saga where ultimate nothing happens
<zid> ultimately*
<zid> I tried twice to read hyperion, failed badly
<sbalmos> zid: Ender's Game
<zid> exactly sbalmos
<geist> yah funny i started rewatching the movie the other day. all in all not a bad implementation
<zid> I refused to watch it
<geist> EG was one of my favorite books too when i was a kid
<geist> read it when i was like 14
<sbalmos> I wish they had made the follow-up
<geist> oh the movie is actually pretty good
<zid> There's no way hollywood gives a book about introspection which has action scenes, anything but action scenes, imo
<FireFly> gorgonical: only wathed the starship troopers film, but I read bill, the galactic hero
<geist> tat's the problem: it can't really do the introspection. you dont really get a feel for what ender is thinking
<geist> which is i think most of the fun of the book, watching him outmaneuver everyone
<geist> but, it's actually not half bad otherwise
<geist> also they cut out almost all of the peter/valentine stuff which frankly works. that's the most cringey part of the book now
<zid> which part's that?
<gorgonical> firefly: read the book. it's actually pretty awful, but very interesting as the start of the "space marine" trope
<sbalmos> now one movie I wish I had not seen, total waste of time back in the day, was Eragon
<zid> starship troopers is my go-to example of "wtf is the point of this?" He joints the army, serves in it, the end
<geist> zid: oh where they're using the net to take over the world, etc
<zid> shrug, that's all used in later books
<zid> his brother becomes hegemon of earth
<geist> which is so dated now. it was some notion that OSC had at the time that a (then future) internet would somehow make everyone equal and amazing discussions
<geist> right and it's well known that he wrote EG after speaker for the dead basically
<geist> he needed a prequel to the thing he really wanted to publish
<geist> it's kinda a hobbit to LOTR
<zid> his brother is basically trump but less handicapped, blew up on twitter and became jesus
<zid> it's the least sci-fi part of the novel
<FireFly> *eyes twitter* yes, everyone equal and amazing discussions
<geist> yep (trying not to spoil it as much for folks that havne't read it)
<zid> twitter's hilarious rn, glad I don't give a shit about twitter
<zid> but I'm loving all the parody spam in the technical politics channel
<kof123> yes, the internet will dissolve all shallowness, everyone will gain the vision of gods, penetrating into deep truths.....btw, a/s/l ?
jafarlihi has joined #osdev
<jafarlihi> Hey, anyone knows compiler theory here?
<jafarlihi> What's the point of making LR1 automaton if the parser only uses GOTO and ACTION tables? Is the automaton required for constructing GOTO or ACTION tables?
<geist> hmm think i understand what freebsd is doing re: x86 PCIDs
<geist> but it seems really expensive. basically per pmap it stores an array of struct { pcid, generation } per cpu
<geist> and each cpu independently rolls it's own PCID per aspace as it context switches
<geist> by allocating a new one (last + 1) if the pmap's gen counter is != the last gen counter for that cpu
<geist> when it wraps around i think it globally invalidates everything and starts over
<geist> seems a reasonable, simply algorithm but it *does* mean it has a `struct { u32 pcid, u32 generation }[MAXCPUS]` per pmap
<geist> and since MAXCPUS is like 256 that's 8 * 256 *per process*
gorgonical has quit [Ping timeout: 268 seconds]
bgs has quit [Remote host closed the connection]
<mrvn> jafarlihi: without lookahead how would you know which table entry to jump to? And the 1 in LR1 means you only need 1 char lookahead
<mrvn> jafarlihi: The table is your automaton
<jafarlihi> So does GOTO table model the automaton or are they seperate things?
<mrvn> the former
<jafarlihi> Ok thanks
bauen1 has joined #osdev
<jafarlihi> Is dragon book hard to read or am I just dumb?
<mrvn> yes
<geist> very hard to read IMO
<zid> compiler theory is black magic
<zid> academic theory re compiler is a whole branch of nonsense mathematics
<sbalmos> there's non-nonsense mathematics somewhere?
<zid> sure, discrete digital mathematics
<zid> (counting on your fingers)
<mrvn> geist: you can half that by reducing the bit counts
<geist> yeah but the gen could should be 32 in this case, since it could reasonably roll in specific situations if it was just 16
<geist> etc. but yes could probably pack it in tighter
<geist> anyway now i know. it's at least easier to follow, it being freebsd
<mrvn> 12/20 seems like a good split and then you do a global invalidation every million pmap changes.
<geist> and there's anice wall of text describing it in pmap
<mrvn> global as in all threads with that address space
jafarlihi has quit [Quit: WeeChat 3.7.1]
sortie has quit [Ping timeout: 252 seconds]
sortie has joined #osdev
<mrvn> geist: Overall 8 * 256 is just 2k. If you are like me and try to put any kernel obejct in it's on physical page then that is nothing. It's left over space in the page for struct Task.
* geist nods
<geist> it's a compromise for sure
<mrvn> what is a lot of memory is rather relative. :)
<geist> plus that's assuming you have MAXCPUS set to 256
<geist> i think that's just the default/upper limit
<mrvn> I think anyone with more than 256 core doesn't worry about a little bit of memory.
srjek|home has joined #osdev
<mrvn> I do hate fixed sized arrays though. Having an upper limit for 256 cores at compile time feels just wrong to me.
<gog> 256 cores should be enough for anybody
<mrvn> and then you buy a GPU
<gog> oh that's right
<gog> they have cores that can be scheduled with actual things now
<zid> 256 is like, 16 E5-2698s and that's a $3200 cpu
<geist> yah i'm not a fan of the fixed size array
<geist> it's one thing ti have a fixed size CPUMAX *bitmap* sicne it's fairly space efficient
<zid> only supporting computers with $50000 of cpus seems sane
<geist> and will still be fairly reasonable for say 256 or so
<geist> but an array of anything larger start to get big
<geist> but also in general yes like to avoid CPUMAX anyway
<mrvn> geist: but it's still big enough that you want a "num_cpus" variable that says how much of that bitmap you use. And if you have that then why not size the bitmap to fit?
<geist> deopends on the use case.
<geist> static vs dynamic basically
<mrvn> All you really save with a CPUMAX is the dynamic allocation of the bitmap.
<geist> correct. so depends on the use case
<geist> lots of times when bitmaps are involved it's some sort of local thing where you're sending IPIs to other cores, etc
<geist> so in those cases you're usually far too low to dynamically allocate, and frequently you're doing it on the stack
<mrvn> FDSET for select is a pain
<geist> anyway
<geist> back to grinding on this. coming up with my own solution
<mrvn> geist: oh yeah, alloca() of the bitmap might be a problem. Needs lots more stack and if you have per process stacks...
<mrvn> geist: I would go with a {uint64_t pcid_generation; unit64_t pmap_generation; uint16_t pcid; } to maximize the remote shootdowns you can do.
<mrvn> That assumes you have less cores than PCIDs, or at least less processes running in parallel.
<mrvn> safe to assume for a few more years I think.
<mrvn> Do you have a "BitSet<CPUMAX> running_on;"
<mrvn> ?
<geist> yes
<mrvn> Another approach is to have a last_pcid in every task and a global "pid_t last_task[MAX_PCID]; pcid_t next_pcid;". If "last_task[task->pcid] == task->pid" then you can reuse the pcid.
<mrvn> carefull with pid rollover though.
<mrvn> Anyone using 64bit pid_t?
<geist> there is no pid in zircno
<geist> but there's an object id for zircon processe objects, and they're 64bit yes
gog` has joined #osdev
<sortie> mrvn, yep, 64-bit pid_t, that's me yessir
gog has quit [Killed (NickServ (GHOST command used by gog`))]
gog` is now known as gog
dutch has quit [Quit: WeeChat 3.7]
dutch has joined #osdev
bauen1 has quit [Ping timeout: 260 seconds]
bauen1 has joined #osdev
ptrc has quit [Remote host closed the connection]
ptrc has joined #osdev
MiningMarsh has quit [Quit: ZNC 1.8.2 - https://znc.in]
Emil has quit [*.net *.split]
particleflux has quit [*.net *.split]
bombuzal has quit [*.net *.split]
qookie has quit [*.net *.split]
energizer has quit [*.net *.split]
pieguy128 has quit [*.net *.split]
Emil has joined #osdev
DanielNechtan has joined #osdev
particleflux has joined #osdev
pieguy128 has joined #osdev
energizer has joined #osdev
qookie has joined #osdev
MiningMarsh has joined #osdev
<Mutabah> geist: Re rust kernel - Yep, I have one.
<geist> woot
<Mutabah> IMO, you don't need to get too far from the hardware before you can start really avoiding `unsafe`