Per Brinch Hansen announced Sequenatila and Concurrent Pascal in the Pascal User Group Newsletter nr 4, July 1976:
Concurrent Pascal is a programming language designed by Per Brinch Hansen for writing concurrent computing programs such as operating systems and real-time computing monitoring systems on shared memory computers. A separate language, Sequential Pascal, is used as the language for applications programs run by the operating systems written in Concurrent Pascal. Both languages are extensions of Niklaus Wirth’s Pascal, and share a common threaded code interpreter.
Several constructs in Pascal were removed from Concurrent Pascal for simplicity and security:
– Variant records
– Goto statement, and labels
– Procedures as parameters
– Packed arrays
– Pointer types
– File types, and associated standard input/output procedures
These omissions make it possible to guarantee, by a combination of compile-time checks and minimal run-time checking in the threaded-code interpreter, that a program can not damage itself or another program by addressing outside its allotted space.
Concurrent Pascal includes class, monitor, and process data types. Instances of these types are declared as variables, and initialized in an init statement.
Classes and monitors are similar: both package private variables and procedures with public procedures (called procedure entries). A class instance can be used by only one process, whereas a monitor instance may be shared by processes. Monitors provide the only mechanism for interprocess communication in a Concurrent Pascal program.
Only one process can execute within a given monitor instance at a time. A built in data type, the queue, together with operations delay and continue, are used for scheduling within monitors. Each variable of type queue can hold one process. If many processes are to be delayed in a monitor, multiple queue variables, usually organized as an array, must be provided. The single process queue variable gives a monitor full control over medium-term scheduling, but the programmer is responsible for unblocking the correct process.
A process, like a class or monitor, has local variables, procedures, and an initial statement, but has no procedure entries. The initial statement ordinarily executes forever, calling local procedures, class procedures, and monitor procedures. Processes communicate through monitor procedures. Language rules prevent deadlock by imposing a hierarchy on monitors. But nothing can prevent a monitor from erroneously forgetting to unblock a delayed process (by not calling continue) so the system can still effectively hang up through programming errors.
The configuration of processes, monitors, and classes in a Concurrent Pascal program is normally established at the start of execution, and is not changed thereafter. The communication paths between these components are established by variables passed in the init statements, since class and monitor instance variables cannot be used as procedure parameters.
The single-user operating system Solo is written in the programming language Concurrent Pascal. It supports the development of Sequential and Concurrent Pascal programs for the PDP 11/45 computer. Input/output are handled by concurrent processes. Pascal programs can call one another recursively and pass arbitrary parameters among themselves. This makes it possible to use Pascal as a job control language. Solo is the first major example of a hierarchical concurrent program implemented in terms of abstract data types (classes, monitors and processes) with compile-time control of most access rights
The archive with the sources of Solo and the Pascal compilers Concurrent and Sequential Pascal for a PDP-11/34
LIST(CATALOG,ALL,CONSOLE) CONSOLE: SOLO SYSTEM FILES AUTOLOAD SCRATCH PROTECTED 1 PAGES BACKUP SEQCODE PROTECTED 4 PAGES BACKUPMAN ASCII PROTECTED 3 PAGES BACKUPTEXT ASCII PROTECTED 14 PAGES BUILDBATTEXT ASCII UNPROTECTED 1 PAGES BUILDTEXT ASCII UNPROTECTED 4 PAGES CARDS SEQCODE PROTECTED 5 PAGES CARDSMAN ASCII PROTECTED 2 PAGES CARDSTEXT ASCII PROTECTED 12 PAGES CATALOG SCRATCH PROTECTED 15 PAGES CDISKTEXT ASCII UNPROTECTED 10 PAGES COMMANDS ASCII UNPROTECTED 1 PAGES CONSOLE SEQCODE PROTECTED 1 PAGES CONSOLEMAN ASCII PROTECTED 1 PAGES CONSOLETEXT ASCII PROTECTED 8 PAGES COPY SEQCODE PROTECTED 4 PAGES COPYMAN ASCII PROTECTED 2 PAGES COPYTEXT ASCII PROTECTED 12 PAGES CPASCAL SEQCODE PROTECTED 7 PAGES CPASCALMAN ASCII PROTECTED 3 PAGES CPASCALTEXT ASCII PROTECTED 18 PAGES CPASS1 SEQCODE PROTECTED 20 PAGES CPASS1TEXT ASCII PROTECTED 54 PAGES CPASS2 SEQCODE PROTECTED 26 PAGES CPASS2TEXT ASCII PROTECTED 72 PAGES CPASS3 SEQCODE PROTECTED 35 PAGES CPASS3TEXT ASCII PROTECTED 90 PAGES CPASS4 SEQCODE PROTECTED 27 PAGES CPASS4TEXT ASCII PROTECTED 71 PAGES CPASS5 SEQCODE PROTECTED 20 PAGES CPASS5TEXT ASCII PROTECTED 56 PAGES CPASS6 SEQCODE PROTECTED 16 PAGES CPASS6TEXT ASCII PROTECTED 53 PAGES CPASS7 SEQCODE PROTECTED 18 PAGES CPASS7TEXT ASCII PROTECTED 56 PAGES CPTEXT ASCII UNPROTECTED 2 PAGES DISK SEQCODE PROTECTED 2 PAGES DISKMAN ASCII PROTECTED 1 PAGES DISKTEXT ASCII PROTECTED 9 PAGES DO SEQCODE PROTECTED 11 PAGES DOMAN ASCII PROTECTED 3 PAGES DOTEXT ASCII PROTECTED 26 PAGES EDIT SEQCODE PROTECTED 8 PAGES EDITMAN ASCII PROTECTED 5 PAGES EDITTEXT ASCII PROTECTED 20 PAGES FILE SEQCODE PROTECTED 20 PAGES FILEMAN ASCII PROTECTED 3 PAGES FILETEXT ASCII PROTECTED 54 PAGES IO SEQCODE PROTECTED 4 PAGES IOTEXT ASCII PROTECTED 13 PAGES JOB SEQCODE PROTECTED 40 PAGES JOBBUFFER1 SCRATCH PROTECTED 20 PAGES JOBBUFFER2 SCRATCH PROTECTED 20 PAGES JOBINPUT SEQCODE PROTECTED 3 PAGES JOBINPUTTEXT ASCII PROTECTED 6 PAGES JOBOUTPUT SEQCODE PROTECTED 2 PAGES JOBOUTPUTTXT ASCII PROTECTED 6 PAGES JOBPREFIX ASCII PROTECTED 1 PAGES JOBSERVICE SEQCODE PROTECTED 3 PAGES JOBSERVICETX ASCII PROTECTED 8 PAGES JOBSTREAM CONCODE PROTECTED 17 PAGES JOBSTREAMTXT ASCII PROTECTED 50 PAGES KERNELTEXT1 ASCII UNPROTECTED 134 PAGES KERNELTEXT2 ASCII UNPROTECTED 129 PAGES KERNELTEXT3 ASCII UNPROTECTED 147 PAGES KERNELTEXT4 ASCII UNPROTECTED 171 PAGES LIST SEQCODE PROTECTED 7 PAGES LISTMAN ASCII PROTECTED 2 PAGES LISTTEXT ASCII PROTECTED 19 PAGES MAKETEMP SEQCODE PROTECTED 4 PAGES MAKETEMPMAN ASCII PROTECTED 1 PAGES MAKETEMPTEXT ASCII PROTECTED 12 PAGES MOVE SEQCODE PROTECTED 2 PAGES MOVEMAN ASCII PROTECTED 1 PAGES MOVETEXT ASCII PROTECTED 10 PAGES MTOPTEXT ASCII UNPROTECTED 4 PAGES NEXT SCRATCH PROTECTED 255 PAGES PIPELINE CONCODE PROTECTED 4 PAGES PIPELINETEXT ASCII PROTECTED 8 PAGES PREFIX ASCII PROTECTED 6 PAGES PRINTER SEQCODE PROTECTED 3 PAGES PRINTERMAN ASCII PROTECTED 2 PAGES PRINTERTEXT ASCII PROTECTED 11 PAGES READ SEQCODE PROTECTED 4 PAGES READMAN ASCII PROTECTED 2 PAGES READTEXT ASCII PROTECTED 12 PAGES REALTIME CONCODE PROTECTED 11 PAGES REALTIMETEXT ASCII PROTECTED 23 PAGES RKBOOTTEXT ASCII UNPROTECTED 6 PAGES SOLO CONCODE PROTECTED 18 PAGES SOLOBATTEXT ASCII UNPROTECTED 4 PAGES SOLOCOPY ASCII PROTECTED 1 PAGES SOLOFILES ASCII PROTECTED 1 PAGES SOLOTEXT ASCII PROTECTED 52 PAGES SPASCAL SEQCODE PROTECTED 7 PAGES SPASCALMAN ASCII PROTECTED 3 PAGES SPASCALTEXT ASCII PROTECTED 18 PAGES SPASS1 SEQCODE PROTECTED 20 PAGES SPASS1TEXT ASCII PROTECTED 53 PAGES SPASS2 SEQCODE PROTECTED 26 PAGES SPASS2TEXT ASCII PROTECTED 73 PAGES SPASS3 SEQCODE PROTECTED 35 PAGES SPASS3TEXT ASCII PROTECTED 91 PAGES SPASS4 SEQCODE PROTECTED 26 PAGES SPASS4TEXT ASCII PROTECTED 65 PAGES SPASS5 SEQCODE PROTECTED 19 PAGES SPASS5TEXT ASCII PROTECTED 54 PAGES SPASS6 SEQCODE PROTECTED 16 PAGES SPASS6TEXT ASCII PROTECTED 53 PAGES SPASS7 SEQCODE PROTECTED 18 PAGES SPASS7TEXT ASCII PROTECTED 56 PAGES START SEQCODE PROTECTED 3 PAGES STARTMAN ASCII PROTECTED 3 PAGES STARTTEXT ASCII PROTECTED 11 PAGES SUPERMAC ASCII UNPROTECTED 30 PAGES TAPE SEQCODE PROTECTED 3 PAGES TAPEMAN ASCII PROTECTED 2 PAGES TAPETEXT ASCII PROTECTED 14 PAGES TEMP1 SCRATCH PROTECTED 255 PAGES TEMP2 SCRATCH PROTECTED 255 PAGES TOTAPETEXT ASCII UNPROTECTED 4 PAGES WRITE SEQCODE PROTECTED 2 PAGES WRITEMAN ASCII PROTECTED 1 PAGES WRITETEXT ASCII PROTECTED 9 PAGES XMAC ASCII UNPROTECTED 1 PAGES 125 ENTRIES 3391 PAGES