Re: OT: down with memory protection!
I'm uncertain as to how to answer this, but I'll give a few comments:
On Fri, Dec 03, 2004 at 02:30:10AM +1100, Sam Watkins wrote:
> I have this somewhat crazy idea about systems design which is highly off topic
> here but maybe someone would be interested. (I'm not subscribed to any more
> appropriate groups at the moment.) If this is _too_ OT please let me know.
> I want to be able to write programs with lots and lots of coroutines or
> "sub-processes", which means a lot of context switching - but context switching
> is expensive, such programs would go slow!
The several coroutines in your project can be implemented as very
"light weight" processes. The context switch could be simulated (in
C++, for example) by having each process be an instance of a process
class. These could be arranged to each maintain its own internal
state, and each give up control of the CPU on a regular basis. Context
switch need not be expensive, if you think carefully about what you
really need to preserve and restore during the switch.
I would not want to arrange the internals of an OS this way, but a
simulation of a transport system or of highway traffic might be done
> Current mainstream OSes like Linux implement memory protection primarily to
> prevent buggy or malicious processes trampling on each-others memory and
> memory-mapped devices, or spying on other processes. The system must do this
Buggy code is the real world. Hardware that sets limits on what
software is allowed to do is essential. Mostly memory protection
hardware allows one to get a memory dump while there is still enough
evidence in the dump to allow one to figure out what went wrong.
Also, hardware _does_ malfunction. Hardware checks and redundancy
helps catch hardware malfunction.
> because we have no way to be sure that buggy or malicious C programs will not
> peek or poke where they should not. In contrast, programs written in python,
> Perl or Java cannot peek or poke at other processes (unless there is something
> wrong with the language implementation).
So, memory protection is needed on the computers on which new versions
of these languages are tested. But, in the open source community that
is all user computers.
> It should be possible to create a C-like language, with unconstrained memory
> access, but an additional requirement that the intended range and access type
> of each pointer must be declared or implied in the code. The compiler could
> then attempt to _prove_ to itself that the code did not access memory it should
> not. I expect in many cases a good proof engine would be able to do this.
> Otherwise, the compiler could require the programmer to provide a formal proof
> that the program's memory access is bounded. If the program is well
> structured, this should not be too difficult. If the programmer can't be sure
> that the program is well behaved, I would suggest that program should not be
> used anyway!
Most software, the vast preponderance of software, has no proof as to
its correctness. Quicksort algorithm has a correctness proof, but that
proof applies _only_ to the algorithm, not to any particular
implementation in software. I don't think requiring proof of correctness
will go very far.
> Anyway, if we assume this is possible, and if all compiled-to-machine-code
> programs were written in such a way, and if the final stage of compilation were
> done by a trusted party (preferably on the local machine), perhaps we wouldn't
> need to implement memory protection in the VM.
> All processes could run on a single address space, there would be no need for
> context-switching, pipes could be implemented as shared buffers, and processes
> could send messages to eachother without needing to copy memory. There would
> be no need for a kernel/userland distinction. It would be unnecessary to copy
> things around so much when doing IO.
> I think people don't normally use more than 4GB of VM on 32-bit computers, at
> least they won't now that 64 bit CPUs are taking off, so this single address
> space model would be ok for 32 bit as well as 64 bit.
> The need for preemptive multiprocessing could be reduced or eliminated in a
> similar way. Programs could call "yield" every now and again, and the compiler
Multiprocessing is not necessary for successful computing, but it is
very nice to have it as the complexity of the problems that you are
trying to solve grow. On any computer that is adequate to run Linux
(sort of the bottom end of serious modern computing), you really need
a way to stop some process that has run amok without having to pull
the plug or press the hardware reset. You need some way to gather data
as to what is going wrong. That is why one really must have
Once you have multiprocessing, the cost of using it to provide added
features is small.
> and programmer could be required to prove that the code would not loop forever
> without calling yield. An interrupt-driven alarm could be used as a last
An interrupt is the start of a second process within a multiprocessing
environment. The alarm is implemented as a second process. An
alternative to a second process would be a second computer with hard
wired probes into the internals of the first computer. I prefer
> resort to suspend an offending process after an unacceptable amount of CPU
> hogging. Without the kernel/userland distinction, yield and other "syscalls"
> could be implemented cheaply.
In the real world, multiprocessing and memory protection are
implemented cheaply. (By cheaply, I mean at low cost.)
> On multi-CPU machines, the scheduler could make sure that shared memory was
> written safely (when no other CPU can be accessing that memory). This would
> work best if programs were written in a highly threaded / many coroutines
> style, with dedicated sub-processes for IO. It would be efficient to have
> small-scale process modularity in a system which did not need context
> Regarding "the stack", I would like to see the demise of the stack altogether!
The stack is a really important innovation in organizing algorithms and
thinking about algorithms. Without it, one cannot think about recursive
descent. If you think it would be nice to see its demise, you have
probably never confronted a real algorithm.
> Files could be accessed by partially mapping them to memory. The common case
> of reading a file a-buffer-at-a-time would translate to a moving window mapped
> onto the file. File locking would therefore usually be automatic and implicit.
> I used to use "RISC OS" on Acorn computers in "the good old days", it used
> non-preemptive multitasking. RISC OS has a lot going for it.
I think Acorn has a stack, and its op-code set would be a shambles
without it. Non-preemptive multitasking is OK on a computer that
can boot up in a flash after a crash, except that after a quick
reboot, you have no idea why the crash happened or what to do
to fix a problem.
> Anyway, if anyone would comment on any of this vapourware, I'd like to hear it
> - off the list if you think it's too off topic.
> It's not completely dreamware, I am developing a progamming language called
> nipl (at the moment it's basically C, but with a python-like syntax, it is
> evolving from C and translates to C), I will have a go at implementing
> "compile-time memory protection" in it. It is definitely going to have
The cost of compute hardware is in a long term downward trend. The cost
of computer software is driven by the time it takes to write it. (and
assuming one pays programmers a living wage.) A language to help
write software needs to address the root causes of software cost.
One can get buggy software to run on a computer with memory
protection faster than getting it to run on a computer without
memory protection. I think the combo of memory protection and
buggy software will win the competition against other approaches.
Just my $.02 worth.
Paul E Condon