StuBS
Loading...
Searching...
No Matches
Glossary

Bitfield

Bit field refers to a field of bits, each with its own semantics. For example, an 8-bit integer could be a bit field if it is to be used as an attribute entry in the CGA video memory. Bits 0-3 would then have their own meaning (foreground color), 4-6 (background color) and bit 7 would have a different meaning (flashing).

A bit field can also be a C/C++ construct in which the length of a member is specified in bits at a struct. It should be noted that C/C++ then constructs the field "the wrong way round", i.e. from the Least Significant Bit (LSB) to the Most Significant Bit (MSB).

Caution: The C++ compiler only guarantees that the length of the individual attributes is at least the desired number of bits. In order to achieve that they have exactly the number of bits, it is necessary to instruct the compiler to create the entire structure in the memory as space-saving as possible.

For example

struct CGA_Cell {
unsigned int character: 8;
unsigned int fg : 4;
unsigned int bg : 3;
unsigned int blink : 1;
} __attribute__((packed));

Critical Section

A critical section is a section in the code where the simultaneous execution of two CPUs can lead to problems, e.g. because data structures are split and access must take place atomically, but cannot do so without further ado. For example, two pointer values must be updated "simultaneously" so that a doubly linked list remains consistent, but this is not possible without further ado. If two processors access inconsistent data at the same time, Race Condition s can occur if one processor changes the data structure while the other wants to read it. To protect a critical section, a Mutual Exclusion (Mutex) must be implemented.

Dispatcher

The dispatcher implements the thread switching mechanism. It does not make any scheduling decisions, i.e. it has no knowledge of the threads in the system or the strategy used to select the next thread.

Interrupt-based Signaling

With interrupt-based signaling, an interrupt request is sent from the external device to the processor when the state of the device changes. This can happen, for example, if there is a new code in the receive buffer of the keyboard controller that is to be fetched by the processor. The control flow of the processor is then interrupted and an interrupt service routine is executed.

Interrupt Descriptor Table (IDT)

The Interrupt Descriptor Table (IDT) is the Intel x86 name for the Interrupt Vector Table. It contains entries for each possible interrupt vector that the CPU can process. Using the vector sent by the interrupt controller, the CPU can find the pointer to the Interrupt Service Routine (ISR) to be executed in this table. Interrupt vector tables can also contain information about privilege levels, information about the mode to be used, etc.

Interrupt request (interrupt request)

An interrupt request is sent by devices by activating the interrupt line of the device. Then the interrupt controllers (I/O APIC and LAPIC) recognize that there is a request and activate the interrupt line of the processor.

Interrupt Service Routine (ISR)

An interrupt service routine is a subroutine in the code that is called by the processor when an interrupt is handled. The ISR is responsible for handling the interrupt so that the processor can continue to execute its normal control flow. Depending on the source of the interruption, it may be necessary to read from a buffer of the device or to set a status bit in a register. On x86, the LAPIC must be signaled after handling that the interruption has been handled.

Interrupt masking

Masking refers to switching off the interrupt line or certain inputs of the interrupt controller. This allows individual interrupt sources or external interrupts to be switched off completely so that requests no longer get through to the CPU. On x86, interrupts are masked out on the executing CPU with the command cli and switched on again there with sti.

Interrupt Vector Table

see Interrupt Descriptor Table (IDT).

Lost Wakeup

A thread goes to sleep due to a condition. During the process, however, the value of the condition changes so that the thread could continue to run. However, it is no longer aware of the change and sleeps forever because the wake-up interrupt has already occurred and is not sent again. The wake-up call was therefore missed.

Mutual Exclusion (Mutex)

Mutual exclusion is the protection of a Critical Section s against simultaneous execution on two different processors.

Memory Mapped I/O

The internal registers of a device are mapped in the physical address space of the processor like normal memory. In contrast to Port-based I/O, the internal registers of the device can therefore be accessed directly with normal mov instructions. This means that the device can be used without a wrapper in a high-level language that allows access to any memory locations via pointers.

Polling

Polling is the process of cyclically interrogating a status register of a device in order to detect changes. This consumes a lot of CPU time, even if there have been no changes to the corresponding device. In addition, the CPU time is not available for application programs, but is spent in the operating system, which would greatly reduce throughput. In many cases, however, a single query is faster than an interrupt, so polling can be useful in certain scenarios. Polling is also more deterministic overall, which is useful in real-time operating systems, for example.

Port-based I/O

The internal registers of a device are not mapped in the physical address space of the processor, but must be accessed via so-called I/O ports. There are separate instructions for handling I/O ports, in and out (on x86 in byte and word variants respectively, i.e. access to 8 or 16 bits). Access to I/O ports from a high-level language is only possible with an assembler wrapper, which makes the corresponding commands usable within the language (in our case in machine/ioport.h). The I/O port address space is separate from the physical address space.

Prolog/Epilog model

The Prolog-Epilog model is characterized by the fact that the interrupt service routines are divided into two parts. The very short prologue (sometimes also called bottom half, in Linux top half) does what is absolutely necessary to satisfy the hardware and handle the interrupt. The epilog (sometimes also Top Half, in Linux Bottom Half, in Windows Deferred Procedure Call) can be displaced by prologs, but can only be executed in mutual exclusion with all CPUs. It makes modifications to core data structures that may not be touched by the prolog. This keeps the interrupt latency short because logs have the highest priority in the system, then epilogs, then the normal control flow.

Process

A process is the unit of isolation. In BSB we are not concerned with isolation, which is why the distinction between process and thread does not exist. In Linux, the open files, the environment and the memory management are linked to the process.

Race Condition

A race condition occurs when two (or more) processors access the same data. Due to the "coincidental" interlocking of the executed instructions, updates may be lost (lost update) because a processor writes back an outdated value and thus overwrites a newer value. Serialization of Critical Section with Mutual Exclusion (Mutex), i.e. protection against simultaneous execution, helps against race conditions.

Scheduler

The scheduler implements the decision as to which thread is executed next. It relies on the mechanism of Dispatcher, which has to bring the decision to the hardware, i.e. which ultimately implements the switching mechanism.

Semaphore

A semaphore is a synchronization object that contains an integer counter. The counter can be decremented by the operations P() (Prolaag, in Python acquire) and incremented by V() (Verhoog, in Python release). The counter value can be pre-initialized. If the counter drops to zero during a P() call, the calling thread must wait.

Spinlock

A lock that realizes the mutual exclusion between processors. A boolean variable is used to indicate whether the critical section is free or not. In the lock operation, this variable is tested and written atomically; if the critical section is free, the calling thread can return, otherwise it must wait until the test-and-set indicates a free section. The boolean variable is reset in the unlock operation.

Thread

The thread (sometimes also lightweight process) is the unit of scheduling. It shares memory with all other threads in a process, which is why it is possible to switch between threads of a process quickly and efficiently (and sometimes transparently for the operating system). In BSB we do not care about isolation, so there is no difference between a process and a thread.

Ticketlock

A lock that realizes the mutual exclusion between processors. Two integer counters are used, one indicating the next ticket to be output, the other the ticket currently being processed. In the lock operation, a ticket is output and actively waited for until the ticket matches the next ticket to be processed. In the unlock operation, only the ticket to be processed next is incremented by one.

Wait

When waiting, a basic distinction is made between active waiting (busy waiting) and passive waiting. With active waiting, the processor repeatedly checks the condition and can continue running as soon as it has been fulfilled. With passive waiting, the waiting thread is displaced and not put into the ready state as long as the condition is not fulfilled. Only when it is fulfilled is the waiting thread woken up again and put into the ready state so that the Scheduler can schedule it again. During active waiting, there is no other activity on the processor, while other threads can be executed during passive waiting.