The basic concept
behind the GCOS operating system is the architecture based on threads (then named processes
terminology borrowed then from Multics). Threads are sequence of instructions executed in
a processor on a set of data. Recently, several types of threads had appeared in technical
literature: kernel threads, user threads and light weight processes. The most common to
express parallelism is "thread"; "process" is associated to a unique
address space that can be shared between threads. GCOS use a specific address space to
each thread and also use a large amount of sharing with other threads. For the purpose of
this document, let's call "GCOS processes" "threads".
The sequence of
instructions executed in a thread is gathered in a structure named a procedure. A
procedure is generally derived from the output of a program.
The program is
usually designed by the programmer as a sequence of phrases (statements) executed
sequentially. However, some of those statements are in fact referencing actions (services)
to be executed on behalf of the program by the operating system. Those actions may be
divided in two kinds: the synchronous services that might be bound to the thread (e.g.
GET_TIME) or be calls to services (e.g. SET_TIMER) and asynchronous services that might
cause the thread to be put in a WAIT state (because they rely on a resource with a
response time much longer than a few processor cycles or because they cause the thread to
wait for a resource locked by another thread).
The choices made
in GCOS architecture were to provide the maximum efficiency in both cases and to do it
whatever number of physical processors the hardware includes.
Procedure and Data
referenced by a thread constitute what is called the address space of the thread.
It could be seen that the synchronous services of the operating system are included in
this address space, including their private data resources invisible to the application
The choice of a segmented
address space has been made, under the influence of MULTICS. The main advantage of a
segmented address space was to allow the sharing of common procedures and data,
with a minimal overhead: the same object or copies of the same object may have the same
address in several threads. Such features is not necessary inherent to segmentation
(Multics allocating segments number dynamically did not guarantee such unicity), but GCOS
choose such design to reduce the overhead. In a system with limited memory and slow
processor speed, it would have been prohibitive to perform dynamic binding of common
resources continually. It is true that segmentation deserves a bad reputation since the
messy implementation of Intel 286 and early versions of Windows. GCOS design preceded
Intel's one by twelve years.
The GCOS address
several operating systems, all threads of GCOS have their own (potentially shared) address
space. The address space was specified in a control structure, named "process control
block" that pointed to shared and private tables of segments.
The address space
of the thread contains procedure segments and data segments. Procedure segments are NOT
normally to be modified during execution, a strong departure from the habits of the time
where clever programmers modified instructions during the execution to save space. A
special system service had to be requested to change the state of a segment when needed by
just in-time compilers, for example.
Data segments were
often static in usual programming languages derived from early computers (COBOL, FORTRAN).
But, ALGOL derived, blocks-languages were relying of dynamic allocation of memory in a stack
specifically allocated to the thread.
in the system address space are identified uniquely by their process-group id (J#), their
process-id (within a J) (P#), a segment table number (STN #), and a segment number (STE
#). However, by GCOS convention a part of the segment table number is common to all
threads and another part of the segment table number is common to all threads in a
segments included privileged instructions and were performing services that could alter
the whole system (by accessing system tables...). That privileged address space had to be
isolated from application programs. A ring attribute was given to the thread during
the execution of such services. Three levels of privileges were used in GCOS systems: a
ring -1 (or firmware ring, not visible to software) during the execution of the
micro-kernel services, a ring 0 allowing the "privileged" instructions and a
ring 1 allowing to reference system wide tables. Application programs were running in ring
3. Ring 2 was reserved for the implementation of a subsystem requiring some internal
protection between its components).
implemented a concept of multi-threading since its origin. While the definition of threads
was absent in user languages, it was possible at application linkage time to specify that
several threads have to be run and subsystems such as emulators and later transaction
processing had to be multi-threaded. Such architecture could be ported without almost any
change to multi-processor configurations. Up to 24 physical processors were eventually
supporting the same GCOS.
requirements and multiprogramming lead to avoid several copies of the system code to be
present memory for different threads. So the address space has been divided in four
classes (named types of segments).
Note that normally
segments are not overlapping, i.e. a word of memory has only one segmented address. There
are exceptions to this rule. Some system tables such as process group control tables and
process control segment overlap. A large segment describes Main memory. And, dynamically
linked load modules have different segment numbers (but same displacements).
Native mode Addressing
The GCOS native
decor is known through an internal Bull document named PA800, a, evolution of the original
reference document published in 1971 BL011. Those documents describe the architecture
visible to the programmer and not the actual hardware features of a given processor.
Several families of processors have been built in Bull and in NEC from Japan for that
contain a type of operation (op-code), one or two addresses and/or several registers. The
architectured system offers to the programmer up to 16 general-purpose 32-bits registers
that may be used either as deposit of data or as index registers. Addresses are made of
two parts: the number of a base register and a displacement within the segment referenced
through the base register. There is an additional feature in the address: an
"indirect addressing" flag that indicates that the location is actually a
pointer containing another address. There are 8 base registers available. A base registers
specifies a 16-bits segment number and an offset within that segment.
Out of the
programmer visible space, are segment tables that contains for each entry the physical
location of the segment in real memory and the length of the segment (actually a boundary
for accesses). The segments are allocated modulo 16-bytes (in BL011).
feature of the architecture is the existence of procedure descriptors for each code
segment. The procedure descriptor, built by the compilers specify the size of the stack
section to be pulled down at each entry in the procedure, a mask for registers passed as
parameters, and the size of the parameters area passed through the stack. A
given code segment may have several entry points, the list of which being part of the
procedure descriptor structure.
When the pointed
object is not present in physical memory a fault occurs in the thread. If the fault
occurred in the segment table, the virtual memory manager is entered and the segment
descriptor updated when the data are really available. When the fault occurs in a pointer,
it might be a programming error or an uncompleted reference, which is interpreted by the
debugger or the dynamic linker.
using segmentation was helped by the fact that the full logical address J, P, STN,
STE did reference a unique -by software convention- piece of information (data
or code). However, that convention was violated in the case of dynamically shared load
modules, where the segment name (STE) space was overlaid. That part of the address
space was easily identified by its reserved table numbers (STN).
difference with S/360 Principles of Operation was the inclusion of indirect addressing in
the instructions. Patterned after Multics, it allowed to identify data descriptors and
pointers as objects of the architecture and to avoid a frequent reloading of base
registers as in IBM architecture.
and Fault Traps,
signals interrupting asynchronously the normal processing. The most frequent are related
to the synchronization of input-output devices and of the signaling by the timers.
Abnormal environment conditions and operator interventions are also causing interrupts.
Fault traps are
derailing of normal processing caused from the processor reactions to the process
instructions. The most frequent cause is related to the absence of operand in physical
memory. Other causes are protection violation, illegal operand format and process
Each thread is
associated to a "fault vector" specifying the procedure descriptors to be called
for each type of fault trap and for some interrupts that are caused by the action of the
thread. It is possible to specify a specific action for a given process, through a service
call that updates the fault vector.
memory of the first Level 64 systems was limited to 512 KB, and there was a marketing
requirement to support systems with only 64 KB. This goal was not achieved, it was
probably unachievable, and the absolute minimum physical memory in which GCOS run was 256
KB. In fact an additional chunk of 256 KB was delivered to customers ordering 64KB or 128
KB of memory.
virtual memory did not replace segmented virtual memory but was a layer exercised
first before segments were moved out. In addition, Segmentation was a basic feature of the
architecture and not just a trick to implement a virtual memory larger than the physical.
is achieved by the combination of access rings and segmentation. A user thread cannot
reference segments outside its system created address space. Absolute address of memory is
only made within ring 0 procedures (Physical I/O handling and Virtual Memory manager).
We will use here
the GCOS original name of process group for the entity made of a group of threads
sharing a large part of their address space and being " loaded" simultaneously.
A process group is the entity of scheduling. Application process groups are also called
Job Steps. They are characterized by an identifier J (for job step), a process group
control segment containing the threads " process control blocks", the segment
tables specifying their private address spaces (located in real and virtual memory).
© 2001-2003 Jean Bellec