Search logs:

channel logs for 2004 - 2010 are archived at ·· can't be searched

#osdev2 = #osdev @ Libera from 23may2021 to present

#osdev @ OPN/FreeNode from 3apr2001 to 23may2021

all other channels are on OPN/FreeNode from 2004 to present

Monday, 9 May 2022

01:14:00 <heat> mjg, i know i'm late, but page folios exist as a pending patchset
01:14:00 <heat> mostly to make hugepages in the page cache doable
01:16:00 <heat> but basically if you have a hugepage of n pages, those n pages will all point to the same folio
01:16:00 <heat> it's supposed to be super transparent
01:16:00 <heat> I think some filesystems already support hugepages pre-folios, but they're few
01:20:00 <heat> I don't know if they collapse a single radix tree level as a hugepage
01:21:00 <heat> the radix tree API in linux morphed into xarray some years ago, it's basically a fancy array interface with a radix tree behind it
01:38:00 <mrvn> Is there a realloc equivalent in c++?
01:46:00 <geist> Not that i know of. It’d be pretty hard to deal with with constructors of arrays of things i think
01:46:00 <geist> Since that’d probably be the only real use case of it
01:47:00 <geist> I guess it’d have to run constructors on the newly appended objects and vice-versa for destructors
01:47:00 <geist> Otherwise i guess it’d invoke the move operator between them. Sort of an interesting idea at least
01:47:00 <mrvn> Would only work with types that have a trivial copy/move constructor.
01:47:00 <geist> Or even non trivial, as long as it had them
01:48:00 <mrvn> if they are non-trivial you have to allocate a new block and move them all. I don't think you could call the move constructor if the libc realloc moved the object already.
01:48:00 <geist> It is an interesting proposition though, could build something like that on top of C’s realloc i suppose, but you’d have to have fully custom new/delete implementations too, i guess
01:49:00 <geist> Oh that’s true. You’d really need some sort of heap level integration
01:49:00 <mrvn> A realloc_dont_move()
01:49:00 <geist> Like, some sort of try-realloc implementation: try to resize this allocation but if you can’t then dont actually do it
01:49:00 <geist> Yah
01:49:00 <geist> Or really extend, because shrink you can up front run the destructors
01:50:00 <mrvn> But I would assume that realloc basically always moves. The likelyhood there is space after an array is small.
01:50:00 <geist> Yah
01:50:00 <geist> But if you had your own arena style allocator and you were rolling your own thing that uses placement news…. You could build something like this
01:50:00 <geist> Which isn’t really that whacky, folks dothat sort of stuff all the time
01:51:00 <mrvn> I just hate code like this: T* newArray = new T[returnSize()+1]; for(int i = 0; i<returnSize(); i++){ newArray[i] = array[i]; }
01:51:00 <geist> Or forcing a move in that case
01:52:00 <geist> Yah
01:52:00 <geist> OTOH probably all wrapper friendly things would basically do the same thing in the new block case
01:52:00 <geist> Which as you say is probably pretty frequent
01:52:00 <geist> Unless it’s some sort of custom arena
01:53:00 <geist> Resizing down is maybe more realistic, since that’s probably doable in pretty much all cases
01:53:00 <geist> Like an array of ref pointers that you then decide doesn’t need to be as big maybe
01:54:00 <geist> But then i guess this is precisely what std::vectors are for basically
01:55:00 <mrvn> but I believe they will copy on shrink
01:55:00 * geist nods
01:56:00 <geist> And certainly have no mechanism to return the unused portion of the backing store
01:57:00 <mrvn> Now that we have constraints for trivially movable and such one could define a newgrow and newshrink operator
01:57:00 <mrvn> well, newshrink would always work.
02:01:00 <geist> And finally an new array size that takes floating point values!
02:02:00 <mrvn> 3.5 strings?
02:02:00 <geist> Oh what amazing things we could build with that
02:02:00 <geist> Partial constructors would be the bomb
02:03:00 <mrvn> How about a std::vector<bool> with 2^33 entries on 32bit systems? size_t is just too small.
02:03:00 <geist> Like it passes to you in the constructor the fractional part so you can try to allocate as much as you can
02:03:00 <geist> S/allocate/initialize
02:05:00 <heat> upgrade size_t to a uint128_t
02:05:00 <heat> or a long double
02:05:00 <mrvn> I want uint128_t for ARM
02:06:00 <heat> either clang or gcc just broke the ABI for uint128_t
02:06:00 <heat> turns out they were following the sysv spec slightly wrong
02:06:00 <mrvn> for what arch?
02:07:00 <heat> x86
02:07:00 <mrvn> isn't that just the same as two uint64_t?
02:07:00 <heat> alignment
02:07:00 <mrvn> hmm, wait. what if there is only on register left? half in register, half on stack?
02:08:00 <mrvn> heat: what is alignof(uint128_t)?
02:10:00 <moon-child> mrvn: for the argument passing? I think they do all in memory if the entire struct doesn't fit in registers
02:10:00 <moon-child> but might be wrong about that
02:10:00 <heat> mrvn, 16
02:11:00 <mrvn> heat: so where does it break?
02:11:00 <heat> idk but it broke
02:12:00 <mrvn> was it 8 before?
02:12:00 <heat> ah yeah it was LLVM
02:13:00 <heat> LLVM reported 8
02:13:00 <heat>
02:13:00 <bslsk05> ​ make the alignment of >= 128 bit integer types 16 bytes to prevent failure to properly align u128 when using 16-bit cmpchxg · Issue #2987 · ziglang/zig · GitHub
02:13:00 <heat> clang didn't break because they hardcoded it apparently
02:13:00 <mrvn> clang 6.0.0 has align 16 and no __int128 before that.
02:13:00 <psykose> i think that broke rust 128-bit ffi too
02:14:00 <psykose> same llvm reason
02:14:00 <mrvn> Same with gcc 6.1 onwards.
02:14:00 <heat> 20<heat>30 clang didn't break because they hardcoded it apparently
02:15:00 <heat> psykose, yeah, because they got it from LLVM
02:15:00 <mrvn> Seems to llvm is the odd one out and violates the hardware requirements.
02:15:00 <heat> clang, zig, rust build on top of LLVM
02:16:00 <heat> if LLVM is buggy, those 3 are buggy :)
02:16:00 <mrvn> Can't check msvcc, no __int128 there.
02:32:00 <mrvn> "You want to get into some trouble?" "How much trouble?"
03:04:00 <gog> one trouble please
03:05:00 <gog> is it my code that's broken or is it me
03:06:00 <psykose> both
03:07:00 <gog> the code's brokenness is a manifestation of my own brokkenness?
03:07:00 <gog> deep
03:10:00 <mrvn> the codes brokeness is a misjudgement by your own brokeness
03:11:00 <gog> no, it's actually broken, i broke it and i'm still digging up how :p
03:12:00 <gog> the answer is probably pointers
03:14:00 <heat> why
03:15:00 <mrvn> pointers are evil, you have to hide them in wrapper classes
03:17:00 * vdamewood hand mrvn a shared-ptr
03:17:00 * vdamewood hands gog a fish
03:17:00 * heat hands mrvn a range
03:17:00 * heat hands mrvn a span
03:18:00 * heat hands mrvn a string_view
03:18:00 * gog takes a reference of the fsh
03:18:00 <heat> huh, many ways to do the same thing huh
03:19:00 <vdamewood> gog: Don't take a reference, Take ownership and properly consume the API.
03:21:00 <mrvn> but the c++ guidelines say you should take ownership of pointers. But then you have to check them for nullptr. They should really advocate retruning owned references.
03:22:00 <mrvn> why does new even return a pointer? It's never ever returning nullptr, that's what bad_alloc is for.
03:23:00 <vdamewood> mrvn: as opposed to what?
03:24:00 <mrvn> references
03:24:00 <mrvn> T & new<T>
03:25:00 <Mutabah> `T&` isn't a pointer
03:25:00 <Mutabah> Well, last I checked it wasn't
03:25:00 <mrvn> exactly, can't be nullptr
03:25:00 <heat> it can also return a nullptr
03:25:00 <mrvn> (sort of)
03:25:00 <Mutabah> (References may act like pointers, but they aren't)
03:25:00 <mrvn> heat: only the nothrow version
03:25:00 <heat> mrvn, any nonstandard operator new can afaik
03:26:00 <mrvn> heat: that's your problem them. don't break the standard
03:26:00 <heat> you can define a new operator new
03:26:00 <heat> that's not nonstandard
03:26:00 <vdamewood> Well, pointers can be deleted, references can't.
03:26:00 <mrvn> vdamewood: make delete take a reference to match the new new
03:26:00 <vdamewood> Also, pointers can be passed around as values themselves, references can't.
03:27:00 <Mutabah> pointers can be reassigned
03:27:00 <mrvn> Mutabah: cows can be brown. so?
03:28:00 <mrvn> references can be taken the address of
03:28:00 <vdamewood> pointers can be passed to C functions.
03:28:00 <vdamewood> Pointers can do arithmetic.
03:29:00 <mrvn> vdamewood: which would be wrong on an object returned by new
03:29:00 <vdamewood> mrvn: new, sure, but not new[]
03:29:00 <mrvn> no argument there
03:29:00 <Mutabah> All really moot points, since C++ can't change the behaviour of `new` without breaking a LOT of code
03:30:00 <Mutabah> And really, you shouldn't be using it directly in modern code
03:30:00 <mrvn> new? you need it lots of places
03:30:00 <vdamewood> Not really. make_unique and make_shared cover its usecases these days.
03:31:00 <Mutabah> and if you explicitly need `new`, you should wrap it in a custom container type
03:31:00 <mrvn> right, not quite used to them yet
03:32:00 <mrvn> you are probably right. returning a raw pointer should be only in legacy interfaces that you can't fix.
03:32:00 <Mutabah> `std::unique_ptr` is a managed pointer based around `new`/`delete`
03:33:00 <mrvn> lets make new return a unique_ptr :)
03:33:00 <vdamewood> mrvn: Can't without changing backwards compatability. make_unique does that anyway.
03:33:00 <mrvn> except you have to check that for validity again.
03:34:00 <mrvn> I want an unique_ref to show in the API that it will always return an object.
03:34:00 <vdamewood> throw new fit();
03:34:00 <Mutabah> That's more a problem of C++ allowing/requiring null states for everything
03:34:00 <mrvn> yes
03:35:00 <mrvn> You kind of need a linear type system for this.
03:35:00 <Mutabah> If you want that level of changes... I have a language for you
03:35:00 <mrvn> Like when you pass a unique_ptr to a function the compiler should warn about it being used after.
03:35:00 <vdamewood> Mutabah: The crab language?
03:35:00 <mrvn> rust?
03:35:00 <vdamewood> The crab language!
03:35:00 <Mutabah> The crab language!
03:36:00 <mrvn> doesn't seem relevant
03:36:00 <bslsk05> ​ The Language of Crabs by Jamie Kirkpatrick
03:37:00 <vdamewood> mrvn: You didn't get the reference?
03:37:00 <mrvn> google does
03:38:00 <Mutabah> Yes, rust.
03:38:00 <mrvn> Second hit for "crab programming language" is rust
03:38:00 <heat> crap language bad
03:38:00 <heat> embrace C
03:38:00 <heat> that was a typo but a perfect typo
03:38:00 <vdamewood> Rust programmerws call themselves 'rustacens'
03:38:00 <vdamewood> rustaceans*
03:39:00 <Mutabah> mrvn: I honestly see rust as a redesign of C++ with modern principles.
03:39:00 <vdamewood> C is for coding. That's good enough for me.
03:40:00 <heat> based
03:40:00 <vdamewood> The only reason I'm not very deep in rust, myself, is that when I tried to write some boot code with it, the boot code didn't work because I was missing some implementations for required functions and I didn't really want to reimplement them.
03:42:00 <mrvn> The reason I don't write rust is that I don't know any rust
03:42:00 <heat> i'm not deep in rust because the standard library was broken and kept unmapping my user processes's stacks
03:42:00 <heat> i tried fixing it but it didn't work so fuck it
03:43:00 <heat> it would also make llvm a dependency on my gcc builds
03:44:00 <heat> and that's a bit awkward
03:44:00 <Mutabah> a gcc-backed compiler is in the works
03:44:00 <Mutabah> (well, two are :])
03:44:00 <vdamewood> Personally, I would just switch to LLVM if they had a decent 16-bit compiler.
03:44:00 <vdamewood> maybe s/compiler/backend/
03:45:00 <heat> my OS compiles with both
03:45:00 <vdamewood> Oh, don't get me wrong. I use (Apple) clang to build my 32-bits.
03:45:00 <heat> Apple clang is the cursediest clang :)
03:46:00 <vdamewood> Yeah, but it actually works out of the box for cross compiling.
03:46:00 <heat> all of them do
03:46:00 <heat> but clang won't ever support 16-bit
03:46:00 <heat> they focus on modern CPUs
03:46:00 <vdamewood> Yeah, but I still need 16-bit code for my BIOS-based boot loader.
03:47:00 <mrvn> do you really write a hugely complex compiler backend for the 100 lines aof asm you need to switch to 32bit?
03:47:00 <mrvn> or do you want to support avr?
03:48:00 <vdamewood> I think I switched to 32-bit mode in fewer lines than that.
03:50:00 <vdamewood> Though, once I figure out how to boot properly with UEFI, I'm going to drop BIOS support.
03:51:00 <vdamewood> And once that happens, I won't need 16-bit support, anymore anyway.
03:51:00 <heat> well, it's ez
03:52:00 <mrvn> vdamewood: that's what grub-efi is for
03:52:00 <heat> open filesystem, read file, load kernel, close file
03:52:00 <heat> get acpi tables, get memory map, exitbootservices
03:52:00 <heat> /maybe/ set the video mode, /maybe/ load an initrd
03:52:00 <vdamewood> mrvn: That's rather unhelpful.
03:52:00 <mrvn> heat: install grub, don't change any code, boot with uefi out of the box
03:53:00 <heat> write a UEFI bootloader, have fun
03:53:00 <mrvn> vdamewood: why?
03:53:00 <vdamewood> I mean, I'm doing OS dev. You might as well tell me not to write an OS and use Linux instead.
03:53:00 <mrvn> vdamewood: you already support booting bios and uefi through grub. why change anything?
03:53:00 <vdamewood> "Don't write a tool, Use one that exists already."
03:54:00 <Mutabah> IMO, the fun of OSDev is setting up the post-boot stuff.
03:54:00 <Mutabah> Dealing with the boot-time firmware is a distraction from doing the runtime stuff
03:54:00 <psykose> some people are really attracted to the boot though
03:55:00 <vdamewood> Yep. Like me.
03:55:00 <heat> vdamewood, here mine for reference:
03:55:00 <bslsk05> ​ Carbon/efibootldr at master · heatd/Carbon · GitHub
03:56:00 <vdamewood> heat: I'd share mine too, but I don't think I've pushed it anywhere.
03:58:00 <heat> i haven't found the need to do much more than that
03:58:00 <heat> of course, you can give yourself a fancy UI if you want
03:59:00 <heat> you also optimise your file IO because UEFI supports (optional) asynchronous IO
03:59:00 <heat> s/you/you can/
04:06:00 <mrvn> not sure you really care about async IO during boot
04:28:00 <vdamewood> Well, might be time for me to go home.
05:22:00 * mrvn takes a big axt and makes 2 channels.
05:41:00 <bradd> hi. what do you folks recommend for arm development hardware?
05:41:00 <mrvn> an arm soc
05:41:00 <clever> stockholm makes me say rpi :P
05:42:00 <bradd> would a cheap rpi 3 work ok?
05:42:00 <mrvn> sure
05:43:00 <bradd> ok, off to find one online now :)
05:43:00 <bradd> thanks
06:50:00 <geist> would recommend a rpi4 over a 3
06:51:00 <geist> depends on what you're trying to do though. do you want to bare metal osdev, or just want an ARM machine to run say linux on?
06:51:00 <bradd> bare metal osdev
06:52:00 <mrvn> are the RPIs still out of stock?
06:52:00 <geist> yah might be hard to get ahold of
06:52:00 <geist> but, yeah rpi4 is miles ahead of rpi3 in terms of bare metal
06:53:00 <geist> if nothing else because it's much more modern (cortex-a72 vs -a53) and a bit more standard (uses a GIC interrupt controller, has a real hard ethernet block etc)
06:53:00 <geist> lots of the rpi3 is hanging off usb
06:54:00 <bradd> yeah, i've been looking. best i've found so far is a rpi 3 model B for $53.95 cad
06:55:00 <geist> yah a but hard t come by right now
06:55:00 <bradd> I'm gonna look around a bit over the next few days. maybe I'll find something
07:16:00 <nur> just think how awesome the RPI5 will be
07:17:00 <nur> (because I have RPI's 1 and 2 and did nothing much with them so I won't be getting any more till I have something to boot on them :) )
10:26:00 <FatAlbert> GeDaMo: how's my hero doing
10:26:00 <zid> when are you two going on a date
11:05:00 <psykose> yesterday
11:07:00 <mrvn> all my troubles seem so far away
11:08:00 <kazinsal> idea: a weezer-style song called "beatles stoned" about being so high you just jam out to the beatles
18:36:00 <sonny> Am I crazy to think a personal computer should be an rtos?
18:36:00 <zid> Yes
18:36:00 <sonny> but latency/responsiveness is most important
18:36:00 <heat> the opposite of no
18:37:00 <Griwes> rtoses are about deadline accuracy that you, a human, are unlikely to be able to perceive
18:37:00 <sonny> I imagine also the OS just hands over to the process instead of focusing on multiprogramming
18:37:00 <zid> They're great if what you want is to DDoS yourself
18:37:00 <zid> instead of having a general purpose computer
18:37:00 <sonny> lol
18:37:00 <Griwes> (ignore my comment if you are not, in fact, a human)
18:38:00 <sonny> zid: already happens on mobile, one app at a time
18:38:00 <j`ey> sonny: its still doing stuff in the background
18:39:00 <sonny> networking, power control, what else?
18:39:00 <heat> your OS already has pretty decent real time guarantees
18:39:00 <sonny> oh really?
18:39:00 <sonny> ok
18:39:00 <heat> yes, that's how audio works fine
18:39:00 <heat> even under load
18:39:00 <heat> it's not just a stupid round robin :)
18:39:00 <sonny> ah
18:39:00 <zid> rtos basically just means "will stop you running programs if it thinks the audio will skip"
18:40:00 <zid> instead of "The audio might skip if you manage to load so much shit the machine freezes"
18:40:00 <heat> the regular scheduler is already pretty decent, and things like POSIX let you add schedulers that are more realtime if you so choose
18:40:00 <zid> and 'thinks' will be "any chance greater than 0"
18:40:00 <heat> yeah
18:40:00 <heat> nobody dies if your audio skips a millisecond
18:41:00 <zid> on a heavily loaded machine
18:41:00 <zid> and tbh, you can still get audio skips on rtos it just tries its absolte best to stop it happening
18:41:00 <zid> a naughty device still might interrupt storm it or whatever
18:41:00 <sonny> oh rip
18:42:00 <sonny> a personal system also should be distributed obviously, but it seems that's ok to do by a protocol?
18:43:00 <sonny> is there anything else that makes an OS distributed?
18:43:00 <sonny> I mean, you can kiss driver problems goodbye :-)
18:46:00 <sonny> maybe it's that kernel services itself can be shared?
18:46:00 <sonny> directly
19:12:00 * geist yawns
19:12:00 <geist> good afternoon folks
19:13:00 * zid throws peanuts
19:17:00 <geist> oooh i love peanuts
19:34:00 <sbalmos> just as long as we don't end up being a peanut gallery
20:47:00 <heat> helllllllllllllo
20:48:00 <heat> i have returned
20:48:00 <zid> oh what did we do wrong
20:48:00 <heat> you're not making a unix clone
20:48:00 <heat> the gods wake me up when there's people not making unix clones
20:49:00 <zid> I could make one if I wanted!
20:49:00 <heat> do it pussy
20:49:00 <heat> bet you can't
20:49:00 <klange> language
20:50:00 <heat> sorry
20:52:00 <zid> heat: I could if I had any focus, time, capacity or depth
20:52:00 <zid> I just don't want to
21:02:00 <zid> heat: What should my first syscall be?
21:02:00 <heat> exit, per svr4
21:02:00 <zid> okay done
21:03:00 <zid> what's second?
21:03:00 <heat> oh god what a blunder
21:03:00 <heat> read is the first one of course
21:03:00 <heat> then it's write
21:03:00 <heat> open, close
21:03:00 <zid> I don't have anything to read though
21:03:00 <zid> I have no open
21:04:00 <heat> you won't exit(2) until the 60th syscall
21:04:00 <heat> it's the UNIX(tm) way
21:04:00 <heat> yes you do, STDIN
21:04:00 <zid> should I just include a lorem ipsum generator
21:04:00 <zid> so that I have something to read from stdin
21:05:00 <heat> actually i'm very much stupid, I got confused because I started reading from the x86_64 system calls(of course they're different, why wouldn't they be)
21:05:00 <heat> exit is indeed the first syscall per SVR4
21:05:00 <heat> then fork
21:05:00 <zid> okay exit is easy, if(rax == 0) shutdown();
21:05:00 <heat> then it's the basic read/write/open/close
21:11:00 <klange> When I was getting things set up early on, I started with a 'print' syscall ;)
21:11:00 <zid> yea my real first syscall just did a kprintf that a syscall happened
21:12:00 <kazinsal> I think mine was yield
21:13:00 <heat> mine was write
21:14:00 <heat> the first user programs were just write(STDOUT_FILENO, "Hello World!\n", strlen("Hello World!\n"));, without the strlen part because I had no libc
21:23:00 <mjg> you can sizeof on it
21:24:00 <mjg> zid: implement exit() which can fail
21:25:00 <heat> you can sizeof a string?
21:25:00 <klange> yes, a string constant can be sizeof'd
21:25:00 <klange> I have a macro somewhere in one of my things that does this
21:26:00 <klange> #define S(c) (krk_copyString(c,sizeof(c)-1))
21:26:00 <klange> sizeof on a string literal will include the nil byte, of course
21:27:00 <heat> i always depended on strlen getting constexpr'd by the compiler
21:28:00 <heat> TIL
21:28:00 <heat> Is that because "hello" is actually a char[6]?
21:28:00 <heat> probably right?
21:28:00 <klange> yes
21:33:00 <zid> string literal just decays to const char * really easily, same as an array
21:34:00 <moon-child> char*, not const char*
21:34:00 <moon-child> (unless you use c++ i guess)
21:34:00 <sbalmos> let's not talk about UTF-8 multibyte either. how about hello world in Cyrillic?
21:35:00 <zid> neither if you're talking about C moon-child :P
21:35:00 <zid> char* is a C++ thing to 'prove' that the whitespace doesn't matter, it's universally char * in C
21:35:00 <moon-child> zid: ? I'm talking about const, not spaces
21:36:00 <zid> I am talking about type names
21:36:00 <zid> you said "If you're talking about C, you mean char*" I said "if you're talking about C, you mean char *"
21:37:00 <heat> char * str
21:37:00 <heat> checkmate
21:37:00 <moon-child> zid: k
21:37:00 <heat> fwiw I still use int *p in C++
21:37:00 <moon-child> when I include the identifier, I put the * next to it, cf char *s. But when there's no identifier, I leave off the spaces cf char*
21:38:00 <moon-child> if you write char* x, then you should be forced to initialise with = malloc(sizeof* x)
21:39:00 <zid> Just skip all the silly intermediate steps and shoot them
21:39:00 <zid> no need to boobtrap their codebases first
21:40:00 <heat> rust
23:09:00 <geist> boobtrap eheheehehe
23:11:00 <kazinsal> hehehe
23:12:00 <zid> It's like a beartrap
23:13:00 <geist> and yeah the * thing is so dumb
23:13:00 <geist> i lost that battle at work, because style guide is dumb
23:14:00 <zid> Did you at least get tabs
23:14:00 <geist> of course not
23:14:00 <geist> and 2 space indents too!
23:14:00 <zid> okay I want geist on the other team
23:14:00 <zid> he's bound to get me what I want taht way
23:14:00 <geist> but so it goes. work is for the young, with still okay vision
23:14:00 <zid> He's basically a double agent
23:14:00 <zid> presumably you could fix it with a fancy editor but that's work
23:15:00 <geist> yah to be fair i stopped generally using tabs about 10 years ago, since any decent editor can do the right thing with tab expansion
23:15:00 <kazinsal> for some reason my brain really likes type* foo more than type *foo
23:15:00 <geist> and then folks will always screw it up and put both
23:16:00 <geist> i had no problem with tabs, except people would constantly bitch about it and screw it up, so then okay fine. now you get spaces and now you dont get to set your indents locally. have fun.
23:16:00 <geist> kazinsal: oh totally it really *should* be left associative, except it's not
23:17:00 <zid> and the file is bigger for no reason, and you can't test if someone has fucked up and mixed alignment and indentation, and other fun trivialities
23:17:00 <geist> zid: yeah what i did years ago is get vim to display a marker for tabs, so at least i can personally see it when its mixed
23:17:00 <kazinsal> right? it mentally maps like (type pointer) (foo), not (type) (pointer foo)
23:17:00 <zid> the type just has a space in it
23:18:00 <zid> and it's wrong on EVERY level
23:18:00 <geist> i read some justification for why it's right associative, and it kinda makes sense from a regularity point of view, and simplifies the initial parser
23:18:00 <zid> It's `char *`a, b; which is wrong on both fronts so it cancels out ;)
23:18:00 <geist> iirc its mostly beacuse * is already right associative for other ops, and then its 'regular' with & operator
23:18:00 <geist> the real silly point is using the * in a declaration in the first place, instead of something like 'ptr'
23:19:00 <geist> but since it was recycled, it acts like how its used in other parts of the language
23:19:00 <zid> I assume it mattered what was easy to type on a selextric typewriter or something :P
23:20:00 <geist> nah i think it's simply when you see * the parser can group it with the next thing
23:20:00 <geist> in * for mul and * for deref, etc
23:20:00 <zid> I mean, in regardes to making the grammar sensical
23:20:00 <zid> these days we could just say you put an emoji snake
23:20:00 <geist> and of course initial language parsers were written in like 4K of ram
23:20:00 <geist> so they chose to make it simple
23:20:00 <kazinsal> yeah
23:21:00 <zid> as in, there are archaic practicalities they had to consider that we don't
23:21:00 <geist> but yeah it's worth reading it, somewhere there's a doc by one of the C authors that basically talks about initial development of the language and the design choices they made
23:21:00 <geist> it's a good read
23:21:00 <geist> probably about 20 years old, but floating around somewhere
23:21:00 <heat> tab-spaces are fine
23:22:00 <heat> 2 space tabs are not
23:22:00 <zid> what's a tab subtract spaces
23:22:00 <heat> ask javascript
23:22:00 <heat> they can probably give you a random answer
23:22:00 <zid> NaNaNaN Batman
23:33:00 <geist> heat: re: ia64 you should look into the itanium syscall mechanism. it's totally whacky and pretty neat
23:33:00 <geist> and has some of these 'branch into the middle' things to think about
23:33:00 <geist> it's a brain teaser how you can actually make it work securely
23:34:00 <zid> to be fair, so is amd64 :P
23:34:00 <geist> har har. though kinda true for different reasons
23:34:00 <zid> I'm not sure you'd figure out the whole swapgs mess if you just read the instruction listing
23:34:00 <zid> and not any code or system guide or whatever
23:34:00 <geist> or you'd stumble upon the gs problem and then wonder how you solve it
23:34:00 <geist> and suddenly swapgs makes sense
23:35:00 <mjg> mismatched swapgs == $$
23:35:00 <geist> i think i came into it that way. originally i had read swapgs and was like huh okay this is odd
23:35:00 <mjg> which os did not have one
23:35:00 <geist> then later on when implementing it for reals.... oh i get it
23:35:00 <heat> mjg, those bugs are the worst to debug
23:35:00 <zid> irq_entry: /* Erm.. what the fuck reg can I destroy here for a new rsp?.. shit, where's the book */
23:35:00 <geist> yah really anything that is modal like that is intrinsically a bad idea
23:35:00 <geist> SMAP has kinda a similar problem
23:36:00 <geist> wher eyou have to keep toggling a bit back and forth and there are paths where you can end up with it not set right
23:36:00 <zid> do any chips have FRED yet
23:36:00 <geist> also a thing that arm solved much cleaner by having the same thing but requiring no toggles
23:36:00 <mjg> now that you mention it i never checked what happens if you disable or enable it twice in a row
23:36:00 <mjg> i presume nothing changes?
23:36:00 <geist> mjg: which one smap?
23:36:00 <mjg> smap
23:36:00 <mjg> clac or stac, twice
23:36:00 <geist> it's the EFLAGs.AC but i'm thinking about. yeah no problem
23:37:00 <geist> in fac tyou should generally just clac (or stack i forget the polarity) on entry into the kernel basically alaways because of this
23:37:00 <geist> at least you're not toggling it, you're hard setting it to one way or another
23:37:00 <mjg> you have to flip it for user access here and there and -- surprise -- there were bugs in page fault handlng
23:38:00 <mjg> and i don't mean my code :->
23:38:00 <geist> arm solves it (PAN - priviledged access never) by simply having a second set of load/store instructions that access memory as if they were user code
23:38:00 <geist> and thus you enable pan and then use those instructions for your user copy
23:38:00 <geist> pretty solid way to do it
23:38:00 <mjg> interesting
23:38:00 <mjg> but how much of thei nstruction set do the duplicate to do it?
23:38:00 <geist> (though there's a design flag in it they have fixed in newer v8.6)
23:39:00 <geist> mjg: you mean the load/store user instructions?
23:39:00 <mjg> yea
23:39:00 <geist> that's the rub, they're not as powerful instructions, so it's hard to implement really efficiency
23:39:00 <mjg> i'm guessing you may try to get fancy depending on transfer sizes
23:39:00 <geist> ie, only a single register sized load, no writeback update
23:39:00 <geist> vs the usual mechanism where you'd use a load/store pair instruction
23:39:00 <mjg> ye, i expected it comes with a huge drawback
23:40:00 <geist> i htink there may be some microarchitectural reason for that, like the cpu is using some temporary different context when accessing it and maybe a single load/store is doable without any complex uop decoding
23:40:00 <geist> (ie, pair of loads, or writeback to the base register)
23:41:00 <mjg> so imo the thing to do would be to roll with an instruction which takes adress range
23:42:00 <mjg> that still lets you use the regular instruction set
23:42:00 <mjg> i meant instruction address range -- from foo+0x$whatever to foo+0x$whatever_end
23:42:00 <mjg> which would encompass all legal user access
23:43:00 <mjg> but i have no idea how (not)problematic would that be to implement in hw
23:44:00 <mjg> it may reven require that the end of the segment is the closing instruction, so you can't fuck up on this front
23:45:00 <geist> for a single copy you mean?
23:46:00 <mjg> copyin/out: ... ; stac [address of paired clac] ; /* copying happens here */ ; clac
23:47:00 <mjg> if you stac with a lolo addr you get an exeption, which presumably be sorted out during development and wont reach production
23:48:00 <heat> but if you get an exception and stac you need a stack of stac's
23:49:00 <mjg> now that you mention it, someone may want to stac upfront in the routine and then have multiple exit points, each of which requires its own clac
23:49:00 <mjg> so the above does not help in said case
23:50:00 <heat> out: clac; ret
23:50:00 <heat> that's not a problem
23:50:00 <mjg> :sadpanda:
23:50:00 <mjg> the point was to prevent footshoting. the one exit point with clac is something the pgorammer can do on their own as it is
23:50:00 <mjg> the proposal does not help with the other case
23:51:00 <mjg> i mean finding problems with it
23:51:00 <heat> i don't think that's really an issue cuz stac and clac happens on self contained assembly routines/inline asm
23:52:00 <heat> you don't /really/ have complicated flow control there
23:53:00 <mjg> freebsd copyin/copyout have multiple exit points, each of which requires clac to be slapped in there
23:53:00 <heat> geist, were you talking about this (
23:53:00 <bslsk05> ​ Light-weight System Calls for IA-64 — The Linux Kernel documentation
23:53:00 <geist> yeah
23:53:00 <mjg> it happens to be sorted out with a macro, but short of that it would be error prone
23:54:00 <geist> that doesn't really describe the mechanism as some detals of how to use it in kernel
23:54:00 <geist> mjg: since AC is part of eflags the cpu will put it back when you iret at least
23:54:00 <geist> so usually you only have to clac at entry to the kernel
23:54:00 <geist> or stac
23:55:00 <geist> heat: is also a good read
23:55:00 <heat> I actually never explicitly clac on entry
23:56:00 <geist> annoying thing with clac/stac is they're relatively new instructions
23:56:00 <heat> maybe I should...
23:56:00 <geist> so if you just toss them in then stuff pre-haswell wont work, etc
23:56:00 <heat> yeah, lots of alternative instructions
23:56:00 <geist> for zircon we actually do a stilly pet trick where we push the IDT entries forward over the instruction if they're not supported
23:56:00 <geist> though really should just nop em out, so the entry point is aligned
23:57:00 <geist> either of which are probably immeasurable
23:59:00 <heat> i was about the say "I don't clac on ISRs because they never write to userspace", but they do
23:59:00 <heat> when handling a signal