Vystem 0.2
This commit is contained in:
54
docs/shelter/std/smp.md
Normal file
54
docs/shelter/std/smp.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# SMP services
|
||||
|
||||
## Introduction
|
||||
|
||||
The SMP services provide various abstractions related to SMP programming. It is defined inside `shelter/lib/include/std/smp.h` and implemented in `shelter/lib/src/std/smp.c`
|
||||
|
||||
## GS register
|
||||
|
||||
Regarding the GS register, two functions are provided:
|
||||
- `sh_smp_write_gs_base(sh_uint64 value)`: Write the `IA32_GS_BASE` MSR. with a value, return nothing
|
||||
- `sh_smp_gs_base()`: take no argument and return a `sh_ap_CPU_STRUCT*`
|
||||
|
||||
## Spinlocks
|
||||
|
||||
The SMP services provide a basic implementation for a spinlock, which look like this:
|
||||
|
||||
``` C
|
||||
typedef struct {
|
||||
volatile sh_uint32 spinlock;
|
||||
sh_uint32 lapic_id;
|
||||
} sh_SPIN_LOCK;
|
||||
```
|
||||
|
||||
Two macros are provided to initialize an unlocked spinlock:
|
||||
- `SH_LOCK()`: intended for spinlocks stored as global variables
|
||||
- `SH_LOCK_LOCAL()`: intended for spinlocks stored as local variables or into structs
|
||||
|
||||
This spinlock implementation requires `sh_smp_gs_base()` to return a valid pointer to a CPU struct. It uses the atomics primitives provided by compilers. Spinlock operations provide full memory ordering guarantees.
|
||||
|
||||
Four functions are provided for spinlock manipulation:
|
||||
- `sh_spin_lock(sh_SPIN_LOCK *lock)`: lock a spinlock, block until the lock is acquired. Return nothing
|
||||
- `sh_spin_unlock(sh_SPIN_LOCK *lock)`: unlock a spinlock, return nothing
|
||||
- `sh_spin_trylock(sh_SPIN_LOCK *lock)`: Attempt to acquire the lock without blocking., return `SH_TRUE` if successfull, `SH_FALSE` otherwise.
|
||||
- `sh_spin_wholock(sh_SPIN_LOCK *lock)`: return the LAPIC id of the CPU locking the spinlock. Return `SH_UINT32_MAX` if the spinlock isn't owned by any CPU
|
||||
|
||||
Current implementation doesn't disable interrupts while holding locks.
|
||||
|
||||
## CPU count
|
||||
|
||||
SMP services can store the amount of CPU cores using the following functions:
|
||||
- `sh_smp_set_cpu_count(sh_int16 cpu_count)`: set the count of CPU. It is only called one time by `sh_ap_prepare_for_smp_launch()`
|
||||
- `sh_smp_get_cpu_count()`: return the count of CPU, return `-1` if value isn't initialized
|
||||
|
||||
## Memory barrier
|
||||
|
||||
The SMP services provide the following primitives:
|
||||
|
||||
Function name | Role
|
||||
--------------|-----
|
||||
`sh_mb()` | Full memory barrier
|
||||
`sh_rmb()` | Read memory barrier
|
||||
`sh_wmb()` | Write memory barrier
|
||||
|
||||
Current x86_64 implementation uses mfence/lfence/sfence.
|
||||
Reference in New Issue
Block a user