<neiluj>
I'm interested about real time os, but it is too ambitious for a toy project.
<neiluj>
interested in*
freakazoid343 has joined #riscv
<muurkha>
for me, assembly is a welcome relief from the messy tar-pit of dependencies, versions, buggy libraries, etc. it's very, very simple, like a zen rock garden
<kehvo>
A simple virtual machine could be an idea
<muurkha>
it doesn't have to be practical to be enjoyable
<muurkha>
I also wrote a web server in assembly
freakazoid12345 has quit [Ping timeout: 265 seconds]
Sofia has quit [Remote host closed the connection]
<neiluj>
muurkha: impressive, you must know very well how sockets and the like work
<neiluj>
or maybe you've implemented a UDP server?
<neiluj>
do you have the code of it somewhere?
Sofia has joined #riscv
<muurkha>
I wouldn't say I know very well how sockets work. I mean I've never implemented the sockets API
<neiluj>
Nice thing you added the comments section at the top ;)
<muurkha>
clients have to choke down whatever garbage servers spew at them
<muurkha>
HTTP/1 servers hardly have to implement anything
compscipunk has joined #riscv
<muurkha>
a real-time OS can be very simple indeed if it doesn't have to do much. if you squint hard enough, an implementaton of SysV's makecontext() and swapcontext() functions is "a real-time OS"
<jrtc27>
well, "We assume that the request path is 5 bytes into the buffer and that the request is a GET." kinda simplifies things a lot
<jrtc27>
string parsing is the hard part
<muurkha>
jrtc27: yeah, but the great thing is that that's an acceptable assumption in the case of HTTP :)
<muurkha>
not a GET? not supported!
<muurkha>
makecontext() and swapcontext() is barely more than a procedure prologue and epilogue with a bug in it
<muurkha>
normally people don't start calling it a "real-time OS" until you at least write a scheduler though
<neiluj>
muurkha: thanks for the pointers!
<jrtc27>
"HTTP/1.0 servers must: [...] understand any valid request in the format of HTTP/0.9 or HTTP/1.0;"
<neiluj>
how long was it to write your server muurkha?
<neiluj>
and most importantly, how did you debug it? I guess the process is different than debugging C code?
<jrtc27>
in many ways assembly is easier to debug, since what you write is exactly what's run, and the disassembly in gdb is what you wrote
<muurkha>
sure!
<muurkha>
jrtc27: well, it generates a valid response (though HTTP/1.0, not HTTP/0.9) to any valid request. whether it understands it sounds like a question that hinges on the nature of consciousness, which I don't pretend to understand
<jrtc27>
it may be a valid response in isolation but not in the context of requests
<muurkha>
hmm, actually, is that true?
<muurkha>
maybe it doesn't handle HTTP/0.9
<jrtc27>
the wording is less tight than later RFCs but it's still pretty clear that you can't just assume everything's a GET
<jrtc27>
HEAD is clearly defined
<jrtc27>
you treat it like a GET
<muurkha>
well, if it's a HEAD, you'll get an error
<jrtc27>
because the path starts with a space?
<jrtc27>
that's not a valid interpretation of the request, hence not a valid response for it
<jrtc27>
and it also still includes a body for the error message
<jrtc27>
which is not valid for HEAD
<muurkha>
hmm, you're right about that
<muurkha>
so it's depending on tolerant clients
<muurkha>
of course if a client sends an HTTP/1.0 request to an HTTP/0.9 server, similar things will happen
<muurkha>
but there aren't a whole lot of those around anymore for peole to worry about compatibility with
<muurkha>
*people
gbrlwck has quit [Quit: Client closed]
<muurkha>
neiluj: I don't really know. I wrote it in 02013
freakazoid343 has quit [Read error: Connection reset by peer]
<muurkha>
which contains a section entitled "Are you insane?"
<muurkha>
I think I probably wrote the original program one evening (02013 December 6) but I didn't check it into Git until I had it running
<muurkha>
but "running" here means that it was accepting connections in a loop and sending "hello, world\n" to them before closing them
<neiluj>
"(Take note
<muurkha>
10 hours later I had it serving web pages, but I probably slept most of that
<neiluj>
that I’ve spent many hours achieving its current size.)"
<neiluj>
Such dedication
<muurkha>
I kept working on it Saturday and Sunday, at which point it was down to 3312 bytes
<muurkha>
then the next weekend I worked on it all weekend and eliminated the dependencies on libc, which might be a worse idea on RISC-V
<muurkha>
also I made it fork off child processes to handle the requests up to a limit
shicz has quit [Ping timeout: 265 seconds]
<muurkha>
I thought this would make it slow but surprisingly it didn't
<muurkha>
I guess fork() is less expensive when you only have five pages mapped. also Linux in 02013 on multi-GHz hardware could fork() a lot faster than SunOS 4.1 on a 20MHz SPARC :)
shicz has joined #riscv
<muurkha>
anyway, then I worked on it a few more days that month
<muurkha>
so maybe "a week" is a good ballpark answer to your question about how long it took to write, neiluj
<muurkha>
mostly I debugged it with strace
<muurkha>
occasionally gdb
<muurkha>
I should write an httpdito-riscv
vagrantc has joined #riscv
Jmabsd has quit [Ping timeout: 265 seconds]
Jmabsd has joined #riscv
Jmabsd has quit [Remote host closed the connection]
aportnoy has joined #riscv
aportnoy has joined #riscv
aportnoy has quit [Changing host]
<leah2>
oh, muurkha on irc. hi :)
___nick___ has joined #riscv
___nick___ has quit [Client Quit]
___nick___ has joined #riscv
<muurkha>
hello admirable neukirchen!
<sorear>
is one of you new here
<muurkha>
no, I just changed my name from xentrac
Koobrick has joined #riscv
amazigh has joined #riscv
<amazigh>
hello, what riscv emulator do you recommend to build a toy compiler?
aportnoy has quit [Read error: Connection reset by peer]
aportnoy has joined #riscv
<muurkha>
qemu-user-riscv on Linux, but I'm just a muurkha; maybe someone else has a better suggestion
<jrtc27>
qemu is normally the right answer, yes
<jrtc27>
if you're on linux and targeting linux riscv then you can use qemu-user
<jrtc27>
otherwise you'll want qemu-system
<jrtc27>
(qemu-user also exists for freebsd riscv, but I doubt you're developing on and for freebsd)
<muurkha>
I guess the correct executable name is qemu-riscv32 or qemu-riscv64, from the package at least Debian calls qemu-user
<muurkha>
nothing is called qemu-user-riscv in real life, just in my head
<jrtc27>
IMO it probably should be, maybe also with a linux in there because what user means varies between OSes..
<muurkha>
presumably qemu-user on freebsd lets your program make freebsd system calls?
<jrtc27>
yes
<muurkha>
the nice thing about qemu-user for a toy compiler is that you can get something working very quickly, because you don't have to deal with initializing a computer
<muurkha>
or writing I/O device drivers
<muurkha>
extra bonus if your intended end use is actually building binaries to run under Linux rather than standalone
<muurkha>
because RISC-V binaries that run under qemu-user will also usually run under regular RISC-V Linux without qemu (on real hardware or in an emulated virtual machine)
<muurkha>
but even if you're really targeting a GD32FV103 or something, amazigh, using qemu-user is an easier way to get started
<amazigh>
what about unicorn engine ?
<sorear>
do you have a platform in mind
<sorear>
do you want to invent a whole platform or use an existing OS
<amazigh>
I am just toying with a silly idea, I will just use qemu, i guess with linux as os (and not try to target bare-metal)
<amazigh>
are you familiar with nanopass incremental approach to compiler construction?
<amazigh>
nanopass will describe the steps required to implement an object language, with several nanostep into the meta-language
<amazigh>
I would like to make the reverse operation, that is bootstrap an object language from many meta-languag, until the object language
<amazigh>
and learn about somekind of assembly language.
shicz has quit [Ping timeout: 260 seconds]
<amazigh>
honestly, it would have been easier (I think) to have just a CPU emulator, that display registers, and can input code store in memory inside the similator
<muurkha>
amazigh: I haven't tried Unicorn
<muurkha>
I think the nanopass approach is great
<amazigh>
yes, but it is not bootstrappable, you can only describe the nanostep language in the object language
<muurkha>
I think starting from the business end of the compiler i a good way to do things
<muurkha>
*is
shicz has joined #riscv
<amazigh>
you still need to know the target, also it does not solve the bootstraping of the origin compiler
<muurkha>
qemu-system does have a console monitor to display registers and input code to store in memory. not sure if you can do that with qemu-user
<jrtc27>
qemu-user can provide a gdbserver just like qemu-system
<muurkha>
yeah, gdb is definitely a way to do that
<muurkha>
but qemu-system also has its own minimal monitor on its own console
<muurkha>
gdb is probably more convenient :)
<muurkha>
amazigh: I wonder if there's a RISC-V monitor that does what you're describing without an emulator (or on top of an existing emulator)
<muurkha>
I never used ITS but I've read about a practice its users had sometimes called "programming in the debugger"
Koobrick has quit [Ping timeout: 260 seconds]
<muurkha>
the ITS shell was called HACTRN and was actually a gdb-like debugger, so you could interactively program in assembly language in the shell
<muurkha>
but initially it had no program, so if you tried to run, the program would halt and return control to the debugger (invalid instruction exception for uninitialized memory? not sure)
<muurkha>
so then you could use the interactive assembler to poke some instructions into your process's memory and continue
<muurkha>
and if it at some point ran off the end of what you'd written so far, it would halt in the same way, and you could inspect its registers and memory and maybe add a little more code
<muurkha>
is that the kind of experience you're looking for, amazigh?
<muurkha>
(you could of course also load an existing program, and you could save your memory image as a program if you got it doing what you wanted)
aportnoy has quit [Remote host closed the connection]
aportnoy has joined #riscv
neiluj has quit [Ping timeout: 260 seconds]
<amazigh>
my goal is still fuzzy, I will think about it
Raito_Bezarius has quit [Ping timeout: 240 seconds]
aportnoy has quit [Ping timeout: 265 seconds]
rlittl01_ has quit [Quit: -a- Connection Timed Out]
rlittl01 has joined #riscv
mahmutov has joined #riscv
BOKALDO has quit [Quit: Leaving]
Koobrick has joined #riscv
yeirr has quit [Remote host closed the connection]
<leah2>
calling it a gdb-like debugger is offense to gdb tho ;)
<muurkha>
what, did you use HACTRN?
<muurkha>
I thought you were German and born about the time the last ITS system was shut down
winterflaw has quit [Remote host closed the connection]
winterflaw has joined #riscv
winterflaw has quit [Remote host closed the connection]
<leah2>
yes
<leah2>
that's not fair tho
<leah2>
i was three when it was shut down at MIT :p
<leah2>
that doesnt stop me from running it in simh however :)
<muurkha>
haha!
<leah2>
and lurking enough in #pdp-10 helped too
<muurkha>
which image do you use, and how do I get started?
<leah2>
there's a big github repo
<muurkha>
and what are the pros and cons of HACTRN vs. GDB?
<leah2>
hactrn feels more like debug.com than gdb ;) has basic symbol resolution tho
<muurkha>
yeah, I think amazigh might be super happy with debug.com
<muurkha>
leah2: on your essay, I think DEC TECO also has prefix arguments
<muurkha>
which suggests that maybe original TECO did too, and maybe QED
<muurkha>
so maybe they originated before E
<leah2>
yes, teco had prefix too
<leah2>
but not on ctrl-u
<muurkha>
no, not on ^U
<muurkha>
I thought you were saying that prefix arguments themselves were a thing Emacs took from E
freakazoid333 has joined #riscv
<muurkha>
it's interesting that in this DDT session the string "hello" is a prefix argument to the altmode-j command. I haven't used a lot of noun;verb CLIs; they're almost all verb;noun for some reason
<leah2>
i guess conceptually they existed before
<leah2>
yeah
<muurkha>
except, like, FORTH
<muurkha>
in my own computing life it was PARC-inspired GUIs via Macintosh that brought the noun;verb ordering to the fore
<muurkha>
and even then there are lacunae: to type "I really like it" with "really" in bold, the easy way is to type "I <verb: ^B>really(noun)<verb: ^B> like it" rather than selecting the "really" after you type it
<muurkha>
I wrote an experimental thing for Markdown editing that works the other way around: I `really` like it is typed "I really<M-`> like it"
<muurkha>
if there's no active region M-` will `` the previous word, or extend an existing `` region back by another word. I feel like this is how M-u, M-c, and M-l should work, too, not to mention Macintosh-style ^B and ^I
<muurkha>
or I guess ⌘B and ⌘I
<muurkha>
because this makes the feedback more immediate and reduces the amount of invisible or only-subtly-visible state, plus also it's less keystrokes
<muurkha>
John Cowan tells me that indeed DEC TECO had numeric prefix arguments
freakazoid333 has quit [Read error: Connection reset by peer]
freakazoid333 has joined #riscv
shicz has quit [Ping timeout: 245 seconds]
shicz has joined #riscv
aportnoy has quit [Ping timeout: 260 seconds]
pecastro has quit [Ping timeout: 260 seconds]
<muurkha>
leah2: do you know how the 200-word records related to the pages?
<muurkha>
was it a one-to-many kind of thing or many-to-many?
<leah2>
good question
<leah2>
i dont know
<leah2>
most text files used longer pages, but perhaps mail archives didnt
JSharp has quit [*.net *.split]
mrkajetanp has quit [*.net *.split]
sm2n has quit [*.net *.split]
cengiz_io has quit [*.net *.split]
Forty-Bot has quit [*.net *.split]
awordnot has quit [*.net *.split]
kehvo has quit [*.net *.split]
oaken-so1rce has quit [*.net *.split]
Xark has quit [*.net *.split]
kehvo has joined #riscv
awordnot has joined #riscv
<muurkha>
how did E insert records in place? was there a UUO for that?
cengiz_io has joined #riscv
<leah2>
it cant insert, just overwrite. but there's a syscall or something yeah
JSharp has joined #riscv
winterflaw has joined #riscv
mrkajetanp has joined #riscv
Forty-Bot has joined #riscv
sm2n has joined #riscv
Xark has joined #riscv
<muurkha>
you said "Of course, if you inserted so much you actually needed to insert a new record, the file needed to be rewritten. This was called “bubbling”, and E also did it in-place"
<leah2>
by in-place i meant it wrote to the same file
<muurkha>
oh, I see
<muurkha>
so you didn't need 2 megabytes of quota to edit a one-megabyte file
<leah2>
but you write the new content to the end of the file and then swap it around
<leah2>
yes
<leah2>
but still rewrite 0.5mb if you change something in the middle
<muurkha>
it can't just swap the records?
<leah2>
i dont think so, they have linear order
oaken-source has joined #riscv
<muurkha>
i see
<muurkha>
clearly on dectape that would be the case
<leah2>
:)
<muurkha>
i've been thinking it would be nice to have a filesystem that supported efficient space sharing for multiversioned files, immutable file snapshots, and insertion and deletion in the middle of the file
<muurkha>
immutable file snapshots in particular are desirable for a lot of reasons. like, on Unix if you mmap() a file you are forever after at risk of segfaults if someone else ftruncates it out from under you
<muurkha>
while if you could trust the filesystem to efficiently COW the file if someone modified it, you could read it in lazily. super helpful for opening those hundred-gigabyte log files in your editor
<leah2>
doesnt reflink do this these days?
smartin has quit [Quit: smartin]
<muurkha>
hmm, maybe so! I hadn't heard of it
<leah2>
but i think zfs doesnt support it yet
<muurkha>
also I think a file that is a reflinked copy of another file can still be modified
<muurkha>
just not by modifications to the original file
<leah2>
yes, but only the changed blocks are allocated
<leah2>
oh you mean a reflinking mmap, misread
<muurkha>
right, but I mean another process can still ftruncate the copy and core-dump your editor or whatever
<muurkha>
maybe every editor buffer should be a separate process anyway
<leah2>
well that's a case where you are allowed to write a segv handler ;)
<muurkha>
maybe it would be better to prevent the segv!
<leah2>
a segv isnt a problem in itself :p
<muurkha>
no, but the fact that the data you wanted to see in your editor is gone is a problem
<muurkha>
a segv is extra complexity and complexity is a problem, but "suck it up" is a reasonable answer
<leah2>
> btrfs supports a new reflink() operation which is essentially a copy-on-write filesystem copy. You could reflink() your file to a temporary on start-up, mmap() the temporary, then msync() and reflink() the temporary back to the original to checkpoint.
<muurkha>
yaeh
<leah2>
aha, it could be used like this :D
<muurkha>
and you could unlink() the temporary
<leah2>
or even use the new swap syscall
<muurkha>
not familiar
<muurkha>
unlink() would make it unusual for the problem to arise
<muurkha>
Oberon took a different approach to anonymous tempfiles: IIRC opening the file was one operation, while adding a name to it was a second, optional operation
<leah2>
linux has O_TMPFILE nowadays too
<muurkha>
so if you never "added it to the directory" you were guaranteed nobody else could open it
<leah2>
yes
<muurkha>
hmm, I don't think you can use O_TMPFILE with reflink(), can you?
<leah2>
no, reflinkat needs names, but copy_file_range(2) uses fd
<leah2>
and is supposed to use reflinks below
<leah2>
could be a nice experiment :)
<muurkha>
oh interesting! that's even better!
<leah2>
then you also can only page in what your editor looks at :)
<muurkha>
exactly!
<muurkha>
as long as you're not on RV32 :(
<muurkha>
Subversion's approach to tagging and branching was similar to reflink(), though at file granularity instead of block granularity
<muurkha>
and I think ZFS snapshots are too?
<leah2>
well zfs reflink isnt merged
<leah2>
but it's cow is on block level pretty sure
<muurkha>
I mean the ZFS filesystem snapshot feature
<muurkha>
creates modifiable snapshots, not immutable ones
<muurkha>
of the entire filesystem
<muurkha>
so, here's another thing that ought to be implementable on btrfs/zfs-like filesystems, and maybe you know a way: a reliable and efficient way to find what files have changed since you last processed them
<muurkha>
for example, for a filesystem search engine
<muurkha>
maybe you want to build a full-text index over a lot of documents that are just sitting around in your filesystem
<leah2>
this is ironically easier on windows
<muurkha>
and later you want to update it incrementally
<leah2>
afaiu there are no official userspace tools to quickly do find(1)
<muurkha>
find(1) is only half the problem
<muurkha>
the other half is detecting whether a file has changed without reading all of it
<muurkha>
reliably
<leah2>
yeah
<leah2>
i dunno a proper way to do it
<muurkha>
(if there's a way to do that, ideally you could make the filesystem traversal fast too by checking for unchanged subdirectories etc.)
<leah2>
but in ssd times directory iteration is pretty quick :)
<leah2>
you can write a daemon that uses the fatrace interface to learn about changes, but it's online
<muurkha>
true! but only if your data is so small it fits on an ssd
<muurkha>
yeah, or inotify
<leah2>
there are bg ssd
<leah2>
inotify only works if you have few directories
<muurkha>
but it seems like this is a problem btrfs, zfs, and other LFS-like firesystems ought to be able to solve, since they don't mutate file blocks in place (which also means they have no obstacle to inserting efficiently into the middle of the file)
<leah2>
yeah they have the data
<leah2>
but it's not exposed
<muurkha>
:'(
<muurkha>
zfs makes baby muurkha cry!
<leah2>
perhaps you can use snapshots and zfs send and look what changed there
<leah2>
but that still keeps the old data around
<leah2>
there is a zfs diff tool
<leah2>
aha there are zfs bookmarks
<leah2>
and they can be used for incremental sends