diff --git a/.vscode/launch.json b/.vscode/launch.json index 82cd0891..1124e9b4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,7 @@ { "configurations": [ { - "name": "GUI (Qt)", + "name": "Qt", "type": "lldb", "request": "launch", "args": [ @@ -23,20 +23,22 @@ } }, { - "name": "GUI (Slint)", + "name": "Slint", "type": "lldb", "request": "launch", "cargo": { - "args": [ - "build", - "--manifest-path", - "${workspaceFolder}/gui/Cargo.toml", - "--features", - "slint" - ], - "filter": { - "kind": "bin" - } + "args": [ + "build", + "-p", + "gui", + "--bin", + "obliteration", + "--features", + "slint" + ], + "filter": { + "kind": "bin" + } }, "cwd": "${workspaceFolder}" }, @@ -49,10 +51,10 @@ "target create ${workspaceFolder}/build/obkrnl", "target modules load --file ${workspaceFolder}/build/obkrnl -s 0xffffffff82200000" ], - "processCreateCommands": ["gdb-remote 1234"] + "processCreateCommands": [ + "gdb-remote 1234" + ] } ], "version": "2.0.0" } - - diff --git a/kernel/src/context/local.rs b/kernel/src/context/local.rs index 7f42e7b8..16c6b294 100644 --- a/kernel/src/context/local.rs +++ b/kernel/src/context/local.rs @@ -5,9 +5,12 @@ use core::ops::Deref; /// Encapsulates per-CPU value. /// -/// Use `RefCell` if you need interior mutability but it will make that code not safe to call from -/// any interrupt handler. You can't use mutex here because once the thread is pinned to a CPU it -/// cannot go to sleep. +/// `T` need to implement [Send] for this type to implement [Send] and [Sync] because its value +/// created by one thread then access from another thread. +/// +/// Use [RefCell](core::cell::RefCell) if you need interior mutability but it will make that value +/// not safe to access from any interrupt handler. You can't use mutex here because once the thread +/// is pinned it cannot go to sleep. pub struct CpuLocal(Vec); impl CpuLocal { diff --git a/kernel/src/uma/mod.rs b/kernel/src/uma/mod.rs index 16676972..8afdea01 100644 --- a/kernel/src/uma/mod.rs +++ b/kernel/src/uma/mod.rs @@ -2,6 +2,7 @@ use self::bucket::UmaBucket; use crate::context::{current_thread, CpuLocal}; use crate::lock::{Gutex, GutexGroup}; use alloc::borrow::Cow; +use alloc::collections::VecDeque; use core::cell::RefCell; use core::num::NonZero; use core::ops::DerefMut; @@ -11,10 +12,12 @@ mod bucket; /// Implementation of `uma_zone` structure. pub struct UmaZone { - size: NonZero, // uz_size - caches: CpuLocal>, // uz_cpu - allocs: Gutex, // uz_allocs - frees: Gutex, // uz_frees + size: NonZero, // uz_size + caches: CpuLocal>, // uz_cpu + full_buckets: Gutex>, // uz_full_bucket + free_buckets: Gutex>, // uz_free_bucket + alloc_count: Gutex, // uz_allocs + free_count: Gutex, // uz_frees } impl UmaZone { @@ -30,8 +33,10 @@ impl UmaZone { Self { size, caches: CpuLocal::new(|_| RefCell::default()), - allocs: gg.clone().spawn(0), - frees: gg.spawn(0), + full_buckets: gg.clone().spawn(VecDeque::new()), + free_buckets: gg.clone().spawn(VecDeque::new()), + alloc_count: gg.clone().spawn(0), + free_count: gg.spawn(0), } } @@ -60,8 +65,7 @@ impl UmaZone { // Cache not found, allocate from the zone. We need to re-check the cache again because we // may on a different CPU since we drop the CPU pinning on the above. - let mut allocs = self.allocs.write(); - let mut frees = self.frees.write(); + let mut frees = self.free_buckets.write(); let caches = self.caches.lock(); let mut cache = caches.borrow_mut(); let mem = Self::alloc_from_cache(&mut cache); @@ -70,8 +74,30 @@ impl UmaZone { return mem; } - *allocs += core::mem::take(&mut cache.allocs); - *frees += core::mem::take(&mut cache.frees); + // TODO: What actually we are doing here? + *self.alloc_count.write() += core::mem::take(&mut cache.allocs); + *self.free_count.write() += core::mem::take(&mut cache.frees); + + if let Some(b) = cache.alloc.take() { + frees.push_front(b); + } + + if let Some(b) = self.full_buckets.write().pop_front() { + cache.alloc = Some(b); + + // Seems like this should never fail. + let m = Self::alloc_from_cache(&mut cache); + + assert!(!m.is_null()); + + return m; + } + + drop(cache); + drop(caches); + + // TODO: Why the PS4 check if this zone is zone_pack, zone_jumbop, zone_mbuf or zone_clust? + self.alloc_bucket(); todo!() } @@ -92,6 +118,11 @@ impl UmaZone { null_mut() } + + /// See `zone_alloc_bucket` on the PS4 for a reference. + fn alloc_bucket(&self) -> bool { + todo!() + } } /// Implementation of `uma_cache` structure.