|
|
|
|
|
by AshamedCaptain
1116 days ago
|
|
> Until Windows 95, everything was just happening in one shared address space, in real mode. In fact, it was only in Windows 3.1 where user applications stopped running in ring 0! Windows 3.0 and predecessors runs in processor which had no concept of "ring 0", so that should not be surprising at all... > Your application wasn't even a "process" per se I think this is a bit of a "modernistic", "win32y" view of the definition of a process. Surely there are processes/tasks in 3.x -- you can launch multiple instances of a module, each of them can allocate memory separately, each of them have different resources/handles, and the OS will cleanup for you once each instance terminates (cleanly). Obviously, without any type of virtual address space or memory protection, any such process can write to and destroy the memory of any other process, but they are still processes. The existence of Yield/DirectedYield , which do not take/need a window, is also a hint of that. (Note there are no threads in 3.x). Many platforms (that either predate VM or decide not to use VM for e.g. power usage concerns) worked like this. MacOS, Windows CE, PalmOS, etc. |
|
I don't think this is true, though? You're not getting separate processes; you're just getting separate hInstances. Which don't map cleanly to a process-like abstraction.
Consider: while you can (in theory) spawn multiple copies of a Win16 executable, with each spawn getting its own hInstance and therefore its own locals heap, this isn't an inherent part of Win16's architecture, but rather is something specific to its handling of spawning executables. DLLs weren't included in this handling, and so only get one hInstance+heap each. This means that if you load and call into the same DLL from two separate actively-running Win16 programs, then that DLL must juggle any state it wants to keep for its N active callers on its own single heap. A function call crossing semantically-distinct memory protection domains, without any kind of IPC serialization, is not very "process"-y. It's more of an object system, like the JVM.
(In both Windows and the JVM: each "object" has its own private heap, and a module wrapping access to that heap; and some "objects" additionally have their own concurrent execution thread. But a given execution thread isn't "bottled up in" a particular heap; it just has a "home" heap. If an execution thread calls another object's API, then that execution thread, through that API, manipulates that other object's heap. There's no concept of IPC — of manipulations of other objects' heaps requiring you to ask the other object whose execution thread owns that heap to do the manipulation for you.)
> The existence of Yield/DirectedYield , which do not take/need a window, is also a hint of that.
DirectedYield is an attempt to make Windows tasks seem to act like "processes"... in the Communicating Sequential Processes sense, at least.
But it doesn't really accomplish this. From the Windows 3.1 API Reference Guide:
> If an application uses DirectedYield for a task with no events scheduled, the task will not be executed. Instead, Windows searches the task queue. In some cases, however, you may want the application to force a specific task to be scheduled. The application can do this by calling the PostAppMessage function, specifying a WM_NULL message identifier. Then, when the application calls DirectedYield, the scheduler will run the task regardless of the task's event status.
In other words, what's really acting as CSPs here, are the windows. :)