AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
lock.c File Reference

The kernel lock. More...

#include <core/system.h>
#include <sys/cpu.h>
#include <sys/lock.h>

Go to the source code of this file.

Functions

void kernel_lock (void)
 Takes the kernel lock, waiting for its turn if another CPU holds it.
void kernel_unlock (void)
 Lets go of the kernel lock, for the next CPU waiting for it.
int kernel_lock_held (void)
 Says whether this CPU holds the kernel lock.
int kernel_enter (void)
 Takes the kernel lock on entering the kernel, unless this CPU holds it already (an exception inside the kernel).
void kernel_leave (int took)
 Lets go of the kernel lock on leaving the kernel, if kernel_enter() took it.

Variables

static volatile uint32_t next_ticket
static volatile uint32_t serving
static volatile int owner = -1

Detailed Description

The kernel lock.

The kernel was written for one CPU, running with interrupts off: what it does isn't interrupted, and nothing else runs kernel code meanwhile. With several CPUs, this lock keeps that true. A CPU takes it when it enters the kernel (an interrupt, an exception or a system call) from user mode or from its idle loop, and lets it go when it goes back to either. So user mode runs on every CPU at once, but the kernel on only one at a time.

It is a ticket lock: the CPUs that wait for it get it in the order they came. While a CPU waits, it does what the CPU that holds the lock asks of the others (arch_lock_spin(): a TLB to flush), since that CPU may be waiting for them to do it. Once a CPU has the lock, it catches up on what was left for then (arch_lock_taken(): the kernel's mappings that changed).

Definition in file lock.c.

Function Documentation

◆ kernel_enter()

int kernel_enter ( void )

Takes the kernel lock on entering the kernel, unless this CPU holds it already (an exception inside the kernel).

Returns
1 if it took the lock, for kernel_leave(), or 0

Definition at line 68 of file lock.c.

References kernel_enter(), kernel_lock(), and kernel_lock_held().

Referenced by __x86_irq_handler(), __x86_isr(), aarch64_irq(), aarch64_sync(), and kernel_enter().

◆ kernel_leave()

void kernel_leave ( int took)

Lets go of the kernel lock on leaving the kernel, if kernel_enter() took it.

Parameters
tookwhat kernel_enter() returned

Definition at line 83 of file lock.c.

References kernel_leave(), and kernel_unlock().

Referenced by __x86_irq_handler(), __x86_isr(), aarch64_irq(), aarch64_sync(), and kernel_leave().

◆ kernel_lock()

void kernel_lock ( void )

Takes the kernel lock, waiting for its turn if another CPU holds it.

Definition at line 32 of file lock.c.

References arch_lock_spin(), arch_lock_taken(), kernel_lock(), next_ticket, owner, and serving.

Referenced by aarch64_init(), kernel_enter(), kernel_lock(), and x86_cpu_init().

◆ kernel_lock_held()

int kernel_lock_held ( void )

Says whether this CPU holds the kernel lock.

Returns
1 if it does, 0 if not

Definition at line 57 of file lock.c.

References kernel_lock_held(), and owner.

Referenced by __arch_idle(), kernel_enter(), and kernel_lock_held().

◆ kernel_unlock()

void kernel_unlock ( void )

Lets go of the kernel lock, for the next CPU waiting for it.

Definition at line 46 of file lock.c.

References kernel_unlock(), owner, and serving.

Referenced by __arch_idle(), kernel_leave(), kernel_unlock(), and thread_spawn().

Variable Documentation

◆ next_ticket

volatile uint32_t next_ticket
static

Definition at line 24 of file lock.c.

Referenced by kernel_lock().

◆ owner

volatile int owner = -1
static

Definition at line 27 of file lock.c.

Referenced by kernel_lock(), kernel_lock_held(), and kernel_unlock().

◆ serving

volatile uint32_t serving
static

Definition at line 24 of file lock.c.

Referenced by kernel_lock(), and kernel_unlock().