New alloca#43
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new allocator system with a garbage collector and refactors the memory management architecture. The changes implement a hierarchical allocator with thread management, garbage collection capabilities, and a more sophisticated arena-based memory allocation system.
Key changes include:
- Introduction of a hierarchical allocator (
HAllocator) with garbage collection support - New thread management system with mutable/immutable phases and thread pools
- Replacement of simple Object trait with a concrete Object struct containing size and bitset information
Reviewed Changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| runtime/src/utils/object.rs | Defines new Object struct with size and bitset fields |
| runtime/src/utils/mod.rs | Introduces reg type alias and exports Object utilities |
| runtime/src/threads/threadpool.rs | Implements ThreadPool for managing worker threads with state transitions |
| runtime/src/threads/nthread.rs | Defines thread state management with phases and contexts |
| runtime/src/threads/mod.rs | Main thread management interface with stop-the-world coordination |
| runtime/src/gc/mod.rs | Core garbage collector implementation with mark-and-sweep algorithm |
| runtime/src/gc/markqueue.rs | Queue system for GC marking phase |
| runtime/src/lib.rs | Main runtime interface with initialization and allocation functions |
| runtime/src/alloca/mod.rs | Refactored allocator module exports and test updates |
| runtime/src/alloca/hedgearena.rs | Enhanced arena implementation with GC support |
| runtime/src/alloca/hallocator.rs | Hierarchical allocator with tiered block management |
| runtime/src/alloca/cfg.rs | Configuration system for allocator parameters |
| runtime/src/alloca/arena.rs | Updated Arena3 trait with new lifecycle methods |
| runtime/src/alloca/allocator.rs | Simplified allocator trait interface |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| fn alloc3() { | ||
| let mut aa = HAllocator::new(config1()); | ||
| let inst = Object { | ||
| size: 48, | ||
| bitset: &[0], | ||
| }; | ||
| for i in 0..100_000_000 { | ||
| test_alloc(&inst, &mut aa); | ||
| } | ||
| } |
There was a problem hiding this comment.
не проходит если поставить размер >=64
There was a problem hiding this comment.
при i in 0..2048 ещё всё хорошо а на 2049 уже ломается
| pub fn popn(&self, n: usize) -> Vec<MarkQueueElement> { | ||
| let mut lock = self.queue.write().expect("popn"); | ||
| let bound = min(lock.len(), n); | ||
| let mut result = vec![]; | ||
| for _ in 0..bound { | ||
| result.push(lock.pop().expect("popn copy")); | ||
| } | ||
| result | ||
| } |
| pub struct Gc<U: Arena3 + Send + Sync + 'static> { | ||
| pub alloca: Arc<Mutex<alloca::HAllocator<U>>>, | ||
|
|
||
| threads: Arc<Mutex<threads::Threads>>, | ||
|
|
||
| stw_is_done: Arc<Mutex<bool>>, | ||
| stw_cv: Arc<std::sync::Condvar>, | ||
|
|
||
| heap_is_done: Arc<Mutex<bool>>, | ||
| heap_cv: Arc<std::sync::Condvar>, | ||
|
|
||
| mark_is_done: Arc<Mutex<bool>>, | ||
| mark_cv: Arc<std::sync::Condvar>, | ||
|
|
||
| root_is_done: Arc<Mutex<bool>>, | ||
| root_cv: Arc<std::sync::Condvar>, | ||
|
|
||
| work_is_done: Arc<Mutex<bool>>, | ||
| work_cv: Arc<std::sync::Condvar>, | ||
| workers: Vec<JoinHandle<()>>, | ||
| count_active_workers: Arc<AtomicUsize>, | ||
|
|
||
| root: Arc<Vec<ptr>>, | ||
| mark_queue: Arc<MarkQueue>, | ||
| } |
| if !(local_queue.len() & 15 == 0) { | ||
| // TODO: make somethink like cfg | ||
| (*thread_mark_queue).pushn(&mut local_queue); |
| loop { | ||
| if (*thread_mark_queue).last_is_end() { | ||
| thread_count_active_workers.fetch_add(1, Ordering::SeqCst); | ||
| { | ||
| let mut work_is_done_flag = | ||
| thread_work_is_done.lock().unwrap(); | ||
| while !*work_is_done_flag { | ||
| work_is_done_flag = | ||
| thread_work_cv.wait(work_is_done_flag).unwrap() | ||
| } | ||
| } | ||
| break 'external; | ||
| } else { | ||
| local_queue = (*thread_mark_queue).popn(16); | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
там кстати все таки нужен этот луп, там если в очередь не попал конец, и при этом в ней никого нет, то надо покрутиться
я пофиксил, го новое ревью |
|
соре за спам :3 |
|
Ревью нэ будэ |
| } | ||
| } | ||
|
|
||
| 'external: loop { |
There was a problem hiding this comment.
а че экстернал не ушёл в итоге
There was a problem hiding this comment.
потому что все таки не ушел внутрений цикл который в else, потому что там есть кейс, в котором надо нихуя не делать и сидеть ждать конец
There was a problem hiding this comment.
надо этот цикл разнести по методам постараться наверное всё таки, слишком крепко
There was a problem hiding this comment.
попозже посмотрю че куда можно будет
| while local_queue.len() > 0 { | ||
| Self::mark(thread_alloca.clone(), local_queue.pop_front().unwrap()); | ||
| } |
There was a problem hiding this comment.
учитывая что это локальная история это просто фолд
| let bound = min(lock.len(), n); | ||
| let mut result = VecDeque::new(); | ||
| for _ in 0..bound { | ||
| result.push_back(lock.pop_front().expect("popn copy")); | ||
| } |
There was a problem hiding this comment.
0..min(lock.len(), n).map(|_| lock.pop_front().expect(...))
There was a problem hiding this comment.
ну конкретно тут то не только дело вкуса ибо оно ресайзится никогда не будет с мапом, а вот с циклом не факт
| let thread_root_is_done = self.root_is_done.clone(); | ||
| let thread_root_cv = self.root_cv.clone(); | ||
| let mut thread_root = self.root.clone(); | ||
| let thread_alloca = self.alloca.clone(); | ||
| let thread_mark_queue = self.mark_queue.clone().clone(); | ||
| let thread_count_active_workers = self.count_active_workers.clone(); | ||
| let thread_mark_is_done = self.mark_is_done.clone(); | ||
| let thread_mark_cv = self.mark_cv.clone(); |
There was a problem hiding this comment.
может это в отдельный стракт какой-то логический и просто клонить его сразу весь?
There was a problem hiding this comment.
не вижу смысл, тут либо вынести сигнальное говно, но там есть мьютекс+кондд вар которые не нужны именно треду, можно вынести то, что нужно треду, но аллока, count_active_workers и тд нужны не только воркерам, + все равно эти 8 строчек надо будет перенести в метод клон, будто мы все равно метод останется едва читаемым
There was a problem hiding this comment.
не, там задерайвить клон можно будет просто, не нужно будет писать эти строчки
There was a problem hiding this comment.
так пусть будут нужны никто же не забирает, пусть они просто вместе в одном стракте лежать будут а так останутся на месте
| let mut local_queue = VecDeque::new(); | ||
|
|
||
| let count_for_scan = thread_root.len() / count + 1; | ||
| for j in min(i * count_for_scan, thread_root.len())..thread_root.len() { |
There was a problem hiding this comment.
этот min наверное стоит вынести перед циклом всё таки, для уверенности в завтрашнем дне
| } | ||
|
|
||
| local_queue = (*thread_mark_queue).popn(16); | ||
| if local_queue.len() == 0 { |
There was a problem hiding this comment.
is_empty или как-то по другому но точно есть чето такое
new allocator and refactoring