I want to describe a pattern of computation which can be provided or even imposed by an operating system. I will call this pattern OSD here for Operating System Determinism. Two languages achieve the goals of OSD: Sisal and perhaps Kappa. I explore here how to provide OSD then even impose it, all the while supporting multiprocessing. Some of the language theorists adopt determinism so as to make the programs easier to understand and debug. I describe here a sort of environment DE (deterministic environment).
A DE permits arbitrary machine language.
A DE provides access to MP.
A DE is deterministic.
OSD delivers DE’s.

I suspect that an OS that provides OSD provides other environments too.

When an OS first lets an unexamined program out of the gate it provides an initial state which includes conventional memory, which, in turn, initially includes the program.

The environment is in user mode, of course. We first delete the system clock for the same program reading it twice will get different answers. This requires hardware mods on some computers. Conventional OS facilities to call for more CPU’s, such as the Unix pthread_create are removed. This is necessary to prevent one thread from observing modifications to memory into which the other asynchronous thread is storing. There are other noise sources which we must find and annihilate. Threads and clocks are the difficult ones we consider here.

In return we must provide something new to use those other CPUs and even IO channels. We make heavy use of snap shots instead of shared read write memory which conventional MP relies on.

I switch into sloppy mode here. The basic idea here to introduce the notion of creating a new DE to do a calculation on demand by some program running in a DE. This is very much like calling a subroutine but ODS limits communication with the new DE to snapshots of memory supplied at the beginning, as in subroutine arguments, and as the routine returns values. By itself this ‘new DE’ feature provides no MP. But if several new DE’s can be launched simultaneously and the launcher gets the collective return values when they have all been produced, then we can run multiple CPU’s and remain deterministic.
The fork logic in a Linux kernel has some of this snapshot logic.