Files
zinnia/include/zinnia/percpu.h
T
2026-10-11 17:43:21 +02:00

47 lines
1.3 KiB
C

#pragma once
#include <zinnia/compiler.h>
#include <zinnia/sched.h>
#include <zinnia/usercopy.h>
#include <stddef.h>
// # On using per-CPU data
//
// Defining variables with `[[__percpu]]` will put them in a special section.
// This section is unique for every CPU. To access the correct memory of the
// caller's CPU, use `percpu_ref`. To access another CPU's copy, use `percpu_ref_on`.
//
// ## Example
//
// ```
// [[__percpu]]
// int my_cpu_data = 0;
//
// int get_foo() {
// return *percpu_ref(my_cpu_data);
// }
// ```
#define __percpu __used, __section(".percpu.data")
#define percpu_ref_on(cpu, x) ((typeof(&(x)))((void*)(cpu) + ((void*)&(x) - (void*)&percpu_bsp)))
#define percpu_ref(x) percpu_ref_on(percpu_get(), x)
// CPU-relative information.
struct percpu {
struct percpu* self; // A pointer to this structure.
size_t id; // The virtual ID of this CPU.
bool online; // Whether this CPU is initialized and active.
uintptr_t kernel_stack; // The kernel mode stack.
uintptr_t user_stack; // The user mode stack.
struct scheduler sched; // Scheduler information.
};
struct percpu* percpu_new();
size_t percpu_max_cpus();
struct percpu* percpu_get();
void percpu_bsp_init();
void percpu_init();
// Per-CPU data for the bootstrap processor.
extern struct percpu percpu_bsp;