BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / bb0cb7718204df7c0cbaf87484b1def3c4b2880f / include / nucleus / cpu.h

// Related

Nucleus

Barry Per-CPU Scheduler bb0cb77 (3 years, 2 months ago)
diff --git a/include/nucleus/cpu.h b/include/nucleus/cpu.h
index f4d7175..2a8c52b 100644
--- a/include/nucleus/cpu.h
+++ b/include/nucleus/cpu.h
@@ -2,14 +2,20 @@
 #define _NUCLEUS_CPU_H
 
 #include <stdint.h>
+#include <stddef.h>
 #include <nucleus/types.h>
 
 typedef unsigned int cpu_t;
+typedef struct Processor Processor;
 
 /* Structure for CPU specific data */
-struct CPUData {
+struct Processor {
+	Processor *self;
 	cpu_t id;
-	Task *task;
+	uint32_t inCriticalSection;
+	uint32_t critFlags;
+	Scheduler *scheduler;
+	struct IPIQueue *ipiq;
 };
 
 /* Structure for an Interrupt Frame */
@@ -20,12 +26,22 @@ struct InterruptFrame {
 	uint32_t eip, cs, eflags, useresp, ss;
 };
 
-typedef void (*exc_handler_t)(struct InterruptFrame *);
-typedef void (*int_handler_t)(struct InterruptFrame *);
+/* Flags for IPI Queue Messages */
+enum IPIQFlag {
+	IPIQ_ASYNC,
+	IPIQ_SYNC,
+	IPIQ_DONE,
+};
 
-extern struct CPUData __seg_gs *cpu;
+typedef void (*int_handler_t)(struct InterruptFrame *);
+typedef void (*ipiq_func_t)(void *);
 
+extern Processor __seg_gs *const cpu;
+extern Processor *cpus[];
+extern size_t ncpus;
 extern int apic;
+#define for_each_cpu(c) for (cpu_t __i_ ## c = 0; ((c) = cpus[__i_ ## c]) && \
+                             __i_ ## c < ncpus; __i_ ## c++)
 
 extern uintptr_t lapicPtr, ioapicPtr;
 #define LAPIC(off)  (*((uint32_t *) ((uint32_t)  lapicPtr + (off))))
@@ -35,8 +51,38 @@ extern cpu_t lapicNums[];
 #define CPUID (apic ? lapicNums[(cpu_t) (LAPIC(0x20) >> 24)] : 0)
 #define MAX_CPUS 2
 
-void register_exception(int num, exc_handler_t addr);
-void register_interrupt(int num, int_handler_t addr);
+/* Enter a critical section */
+static inline void
+enter_critical_section(void)
+{
+	uint32_t *ics = &cpu->self->inCriticalSection;
+	if (__atomic_fetch_add(ics, 1, __ATOMIC_RELAXED) == 0)
+		asm volatile (
+			"pushf;"
+			"cli;"
+			"pop %0"
+			: "=r" (cpu->critFlags)
+			: : "memory"
+		);
+}
+/* Exit a critical section */
+static inline void
+exit_critical_section(void)
+{
+	uint32_t *ics = &cpu->self->inCriticalSection;
+	if (__atomic_sub_fetch(ics, 1, __ATOMIC_RELAXED) == 0)
+		asm volatile (
+			"push %0;"
+			"popf"
+			: : "rm" (cpu->critFlags)
+			: "memory","cc"
+		);
+}
+
+void register_exception(uint8_t num, int_handler_t addr);
+void register_interrupt(uint8_t num, int_handler_t addr);
+void register_ipi(uint8_t num, int_handler_t addr);
+void send_ipiq(cpu_t targid, ipiq_func_t func, void *arg, enum IPIQFlag flags);
 
 void set_fs_base(uintptr_t base);
 void set_gs_base(uintptr_t base);