Live data from Hacker News

Memory Allocation

samwho.dev

151–160 of 182 posts

Re: Memory Allocation

#151
post #68

Oh, if only I had this in college! This is a fantastic explanation.

[1] is not very far from that. IMHO, [1] it is better. [1] https://pages.cs.wisc.edu/~remzi/OSTEP/vm-freespace.pdf

OSTEP is what made it _finally_ click for me, but I think the online demo is great because of the interactivity. Both have their place!

Re: Memory Allocation

#152

Earlier quoted context omitted.

In Hyper-V it's fairly easy. You make a virtual serial port ("COMPort"), set the bootloader to enable kernel debugging over serial, then connect to the virtual serial port from the host via a named pipe. https://learn.microsoft.com/en-us/windows-hardware/drivers/d... I haven't tried it with vSphere but I suspect it'd be similar.

Delphi 7 was 2002. Was hyper-v around back then? Or is this just a legacy app still running?

Hyper-V wasn't until Windows Server 2008. I know you could do virtual serial ports w/ VMware GSX and ESX (and later ESXi) forwarded to real hardware serial ports on the host.

Re: Memory Allocation

#153

Earlier quoted context omitted.

Yes and no, it took me from 8am to 3am once we decided it needed to get fixed but really it sat on the app for years, it only happened on a background process that sent print jobs on a timer, since it used Windows GDI to compose the image we sent to the printer it was affected (our "frontend" should've been affected too but never was, I guess because it had a different memory usage pattern). We just had it restart it…

Owch, I’m guessing that wasn’t -5 hours of debugging.

It was actually 250 hours

Re: Memory Allocation

#154
post #106
post #94

Earlier quoted context omitted.

I think the far weirder part of this was the kernel-side handling of scrollbars

Until Windows 95, Windows was essentially just a DOS application that grabbed the framebuffer and ran an event loop where it drew "controls" (which includes windows, buttons, text views, and yes, scrollbars.) That was the whole point of it. It wasn't an "OS" per se; DOS was the OS. Windows was what a Linux-head would think of as a combination of an X server and window manager. And Windows loaded your "application" as…

> That was the whole point of it. It wasn't an "OS" per se; DOS was the OS. Windows was what a Linux-head would think of as a combination of an X server and window manager.

This seems like a very post-3.0 (i.e. 386-only) view of things—the 8086 and 286 versions of Windows were also fairly advanced memory allocator/overlay manager hybrids.

They parcelled out memory, compacted it to avoid external fragmentation (take that, dlmalloc!), expelled pieces that could be read back from executables, and discarded segments that the application programmer said could be recovered, as necessary. (Yet they couldn’t actually swap mutable memory, as far as I can tell. Why?) For data, they required your cooperation by only revealing addresses between *Lock and *Unlock calls and requiring you to store handle+offset pairs otherwise; for code, the 8086 kernel would reach into your stack and walk the frame pointer chains in order to redirect return addresses to swap-in thunks. (Maintaining LRU lists along the way in either case.) Things became better on the 286 when it could just hand out segment selectors and arrange for accesses to fault as required, but this is the problem statement that Windows 1.0, running on the 8086, set out for itself.

Now, none of this is impossibly difficult (although I shudder at the thought of doing it without good debugging tools), but it feels pretty damn OS-like to me. You might argue there isn’t much virtualization of hardware going on—except for RAM, CPU, display, keyboard, and mouse—but I’d say there is at least as much of it in Win16 as there is in DOS.

One would hope things would get easier on the 386. And then one gets to DPMI and VDMs and still wants to support 16-bit drivers that hooked BIOS calls as though that would help and now the system cannot interact with the user while it’s formatting a floppy[1].

> [T]he concurrency primitive wasn’t the “task” [but instead] the window. Until Windows 95, Windows was a multi-windowing OS. [... E]ach window participated separately in the global Windows event loop, up-to-and-including things like having its own set of loaded fonts, its own clipboard state, and its own interned strings table. In OOP terms†, your application was just a dead "class object", running no logic of its own save for one-time load and unload hooks.

That... doesn’t sound correct on the implementation level. If you’re an instance of a Win16 executable module, you own a copy of your executable image’s mutable data, you own your memory allocations (that are not marked GMEM_SHARE), you own a stack, you get all (“posted”, i.e. asynchronous) messages for all windows you (or your library dependencies) created and you ask the system to munge and route them to the message dispatch routines of the windows you created—or not, if you don’t want to.

Now, the overall effect is very much like what you described, and often it may feel that you could as well throw out all those tedious GetMessage-TranslateMessage-DispatchMessage loops and replace them with a standard implementation of a vat[2]. Then a puny message handler decides to hijack the whole thing and go into a modal dialog loop. And damned if I could describe what that means in terms of an object model.

(What would you say about Symbian? Now there’s a system that throws out processes and only runs objects. Except it doesn’t run inside of a DOS or anything; there’s a kernel and on top of that there are objects. Boom. ... I think?)

> The actual more interesting analogy is that Windows was essentially a (single-threaded, cooperatively-scheduled) actor system, where windows were the actors.

Yeah, that I’ll wholeheartedly agree with. Nevermind the drawing part, it even has separate synchronous sends (SendMessage) and asynchronous ones (PostMessage)! Of course, unlike E’s[3], these have completely insane interactions with the concurrency parts, especially once you get to Win32.

[1] http://bytepointer.com/resources/old_new_thing/20090102_002_...

[2] http://www.erights.org/elib/concurrency/vat.html

[3] http://www.erights.org/elib/concurrency/msg-passing.html

Re: Memory Allocation

#155
post #119

Earlier quoted context omitted.

How do you attach kd to VM? While I was at MS, it was such a big PITA - we just had a bunch of IT managed machines with KVM console access and KDNET for debugging.

In Hyper-V it's fairly easy. You make a virtual serial port ("COMPort"), set the bootloader to enable kernel debugging over serial, then connect to the virtual serial port from the host via a named pipe. https://learn.microsoft.com/en-us/windows-hardware/drivers/d... I haven't tried it with vSphere but I suspect it'd be similar.

Kernel debugging over serial should be possible in vSphere, but Ethernet is easier to set up:

1. Make sure at least one virtual NIC on the target VM (with IP connectivity to the debug host machine/VM) is on Microsoft's NIC whitelist[1]. I use e1000e; note that vmxnet3 is not on the list.

2. Follow Microsoft's directions[2] to connect.

I can confirm this works on vSphere[3] and there's no reason it shouldn't also work on VMware Workstation, Player, and Fusion.

[1] https://learn.microsoft.com/en-us/windows-hardware/drivers/d...

[2] https://learn.microsoft.com/en-us/windows-hardware/drivers/d...

[3] Tested last week with a Windows Server 2022 target (e1000e virtual NIC) and Windows 10 debug host (vmxnet3 virtual NIC), both running on ESXi 8.0 Update 1 VM hosts.

Re: Memory Allocation

#156
post #147
post #9

Earlier quoted context omitted.

This feedback has made my day. Thank you. I'm inspired by Bartosz Ciechanowski and Julia Evans. The web is such a powerful toolbox. So many concepts are more complex than text alone can hope to explain. Those two are so creative and full of energy. And you're right, it's incredibly time intensive to put these together. Thousands of lines of code, plus the text content, plus reaching out to domain experts for reviews…

I think it's a nice little example for "Explorable Explanations", a term coined by Bret Victor in his eponymous essay[1] from 2011. [1]: http://worrydream.com/ExplorableExplanations/

I've been admiring this trend since I started seeing these kinds of essays posted here, and felt motivated to start collecting them in a curated list[0]. Happy to accept new entries or volunteers to help maintain it!

[0] https://github.com/BHSPitMonkey/awesome-explanations

Re: Memory Allocation

#157
post #145

Earlier quoted context omitted.

> This might make you realize why MDI (or Multiple Document Interface, where there are multiple small per-document "windows" inside one big window) was so popular back then. The MDI "windows" weren't actually windows — they didn't have their own WndProc. They were just controls, like a tab view is a control. Only the big container window was a real window, and so all the resources within that big window were shared b…

Interesting; through the fog of time, I may have misremembered some "tip" I was given for Windows 3.1 programming efficiency, as being a more definitive statement about the internal structure of Windows than it really was. That tip, as I recall it, was that the developer should minimize the number of top-level windows they create, because each top-level window in the system gets opted automatically into various thing…

Thanks for the interesting discussion. Yes, the fog of time affects us all.

Funny you mention caption buttons (min/max/close/etc.) and menus and such. I meant to add a "Fun fact #2" in my first comment. So here we go...

In traditional Windows applications, none of those are child windows (or child controls, same thing). They are all part of the "non-client area". You may recall there being a whole series of WM_NC... messages like WM_NCMOUSEMOVE and WM_NCPAINT, with the same names as your usual messages except for the NC prefix. Your WndProc would receive all of these messages, but generally would just pass them along to DefWindowProc which handled this "non-client" activity.

Now here is the fun fact. OS/2 Presentation Manager took a different and cleaner approach. It removed the "non-client area" concept entirely, along with all those messages. Instead, all of those window doo-dads were child windows. The minimize button was a child window. Your "client area" was a child window. And so on. It was all child windows.

On this point:

> implementing behaviors that seem like their own child controls, but which are actually parts of the MDI child's own geometry, to reduce the number of event loops that need to be pumped.

To be clear, a typical application had only one event loop. It was your classic GetMessage/TranslateMessage/DispatchMessage loop. DispatchMessage would pass the message off to whatever WndProc it should be directed to.

Re: Memory Allocation

#158
post #39
post #38

This is really, really well done. Also, the allocator playground[0] is really cool. Will be my go-to when teaching this topic moving forward :) [0] https://samwho.dev/allocator-playground/

Thanks so much, I really appreciate it. I'm glad you like the playground. If you don't mind me asking, what/where/how do you teach? I was actually hoping to get the attention of educators with this tool to see if it would make sense in, e.g., undergrad CS courses.

The commentary along with the first milestones achieved by Elon M's SpaceX and Starlink speak of a global scitech education initiative, perhaps even includes Khan Academy, you could see there among those communities if they have a slot for your talent. Look for contact points on their webpage closest to that initiative?

Re: Memory Allocation

#159
Love the visualizations. It would be great to have `realloc` covered too but I'm not sure how much that varies by system, potentially making it too complicated for this sort of post.
Post reply on HN