mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-21 23:56:18 +04:00
fix data racing on thread crate
The key point is that all methods on 'Processor' must be called with interrupt disabled. Otherwise if an interrupt happened inside a method, and then the thread is switched to other CPUs, it will touch other 'Processor'.
This commit is contained in:
parent
20f8b45888
commit
af83913188
6
kernel/Cargo.lock
generated
6
kernel/Cargo.lock
generated
@ -356,7 +356,7 @@ dependencies = [
|
||||
"rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=d8d6119)",
|
||||
"rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=d8d6119)",
|
||||
"rcore-memory 0.1.0",
|
||||
"rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=95e716a2)",
|
||||
"rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=d727949b)",
|
||||
"riscv 0.5.0 (git+https://github.com/rcore-os/riscv)",
|
||||
"smoltcp 0.5.0 (git+https://github.com/rcore-os/smoltcp?rev=5bd87c7c)",
|
||||
"spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -436,7 +436,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rcore-thread"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rcore-os/rcore-thread?rev=95e716a2#95e716a2d3c315b19dda787cfe7302957b66f80b"
|
||||
source = "git+https://github.com/rcore-os/rcore-thread?rev=d727949b#d727949b8ea20c2e3a94f8ba015652c9eff8b53c"
|
||||
dependencies = [
|
||||
"deque 0.3.2 (git+https://github.com/rcore-os/deque.git?branch=no_std)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -707,7 +707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rcore-fs-mountfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=d8d6119)" = "<none>"
|
||||
"checksum rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=d8d6119)" = "<none>"
|
||||
"checksum rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=d8d6119)" = "<none>"
|
||||
"checksum rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=95e716a2)" = "<none>"
|
||||
"checksum rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=d727949b)" = "<none>"
|
||||
"checksum register 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e10f31b6d2299e5620986ad9fcdd66463e125ad72af4f403f9aedf7592d5ccdb"
|
||||
"checksum riscv 0.5.0 (git+https://github.com/rcore-os/riscv)" = "<none>"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
|
@ -62,7 +62,7 @@ smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", defau
|
||||
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator" }
|
||||
rcore-console = { git = "https://github.com/rcore-os/rcore-console", rev = "b7bacf9", default-features = false }
|
||||
rcore-memory = { path = "../crate/memory" }
|
||||
rcore-thread = { git = "https://github.com/rcore-os/rcore-thread", rev = "95e716a2" }
|
||||
rcore-thread = { git = "https://github.com/rcore-os/rcore-thread", rev = "d727949b" }
|
||||
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "d8d6119" }
|
||||
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "d8d6119" }
|
||||
rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "d8d6119" }
|
||||
|
@ -69,10 +69,10 @@ impl Log for SimpleLogger {
|
||||
if let Some(tid) = processor().tid_option() {
|
||||
print_in_color(
|
||||
format_args!(
|
||||
"[{:>5}][{}][{}] {}\n",
|
||||
"[{:>5}][{},{}] {}\n",
|
||||
record.level(),
|
||||
crate::arch::cpu::id(),
|
||||
tid,
|
||||
record.target(),
|
||||
record.args()
|
||||
),
|
||||
level_to_color_code(record.level()),
|
||||
@ -80,9 +80,9 @@ impl Log for SimpleLogger {
|
||||
} else {
|
||||
print_in_color(
|
||||
format_args!(
|
||||
"[{:>5}][-][{}] {}\n",
|
||||
"[{:>5}][{},-] {}\n",
|
||||
record.level(),
|
||||
record.target(),
|
||||
crate::arch::cpu::id(),
|
||||
record.args()
|
||||
),
|
||||
level_to_color_code(record.level()),
|
||||
|
@ -90,22 +90,6 @@ static PROCESSORS: [Processor; MAX_CPU_NUM] = [
|
||||
Processor::new(),
|
||||
Processor::new(),
|
||||
Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
// Processor::new(), Processor::new(), Processor::new(), Processor::new(),
|
||||
];
|
||||
|
||||
/// Get current thread
|
||||
@ -118,6 +102,11 @@ pub unsafe fn current_thread() -> &'static mut Thread {
|
||||
process
|
||||
}
|
||||
|
||||
/// Get global thread manager.
|
||||
pub fn thread_manager() -> &'static ThreadPool {
|
||||
processor().manager()
|
||||
}
|
||||
|
||||
// Implement dependencies for std::thread
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -21,7 +21,7 @@ use crate::memory::{
|
||||
use crate::sync::{Condvar, SpinNoIrqLock as Mutex};
|
||||
|
||||
use super::abi::{self, ProcInitInfo};
|
||||
use crate::processor;
|
||||
use crate::process::thread_manager;
|
||||
use core::mem::MaybeUninit;
|
||||
use rcore_fs::vfs::INode;
|
||||
|
||||
@ -420,7 +420,7 @@ impl Process {
|
||||
pub fn exit(&mut self, exit_code: usize) {
|
||||
// quit all threads
|
||||
for tid in self.threads.iter() {
|
||||
processor().manager().exit(*tid, 1);
|
||||
thread_manager().exit(*tid, 1);
|
||||
}
|
||||
// notify parent and fill exit code
|
||||
if let Some(parent) = self.parent.upgrade() {
|
||||
|
@ -38,7 +38,7 @@ pub fn add_user_shell() {
|
||||
.manager()
|
||||
.add(Thread::new_user(&inode, init_shell, init_args, init_envs));
|
||||
} else {
|
||||
processor().manager().add(Thread::new_kernel(shell, 0));
|
||||
thread_manager().add(Thread::new_kernel(shell, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ pub fn add_user_shell() {
|
||||
use crate::drivers::CMDLINE;
|
||||
let cmdline = CMDLINE.read();
|
||||
let inode = ROOT_INODE.lookup(&cmdline).unwrap();
|
||||
processor().manager().add(Thread::new_user(
|
||||
thread_manager().add(Thread::new_user(
|
||||
&inode,
|
||||
&cmdline,
|
||||
cmdline.split(' ').map(|s| s.into()).collect(),
|
||||
@ -68,7 +68,7 @@ pub extern "C" fn shell(_arg: usize) -> ! {
|
||||
}
|
||||
let name = cmd.trim().split(' ').next().unwrap();
|
||||
if let Ok(inode) = ROOT_INODE.lookup(name) {
|
||||
let _tid = processor().manager().add(Thread::new_user(
|
||||
let _tid = thread_manager().add(Thread::new_user(
|
||||
&inode,
|
||||
&cmd,
|
||||
cmd.split(' ').map(|s| s.into()).collect(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::*;
|
||||
use crate::process::Process;
|
||||
use crate::process::{current_thread, processor};
|
||||
use crate::process::{current_thread, thread_manager};
|
||||
use crate::thread;
|
||||
use alloc::collections::VecDeque;
|
||||
use alloc::sync::Arc;
|
||||
@ -63,19 +63,19 @@ impl Condvar {
|
||||
let mut lock = condvar.wait_queue.lock();
|
||||
locks.push(lock);
|
||||
}
|
||||
processor().manager().sleep(tid, 0);
|
||||
thread_manager().sleep(tid, 0);
|
||||
locks.clear();
|
||||
|
||||
if let Some(res) = condition() {
|
||||
let _ = FlagsGuard::no_irq_region();
|
||||
processor().manager().cancel_sleeping(tid);
|
||||
thread_manager().cancel_sleeping(tid);
|
||||
for condvar in condvars {
|
||||
let mut lock = condvar.wait_queue.lock();
|
||||
lock.retain(|t| !Arc::ptr_eq(t, &token));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
processor().yield_now();
|
||||
thread::yield_now();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ impl Syscall<'_> {
|
||||
let begin_time = unsafe { core::arch::x86_64::_rdtsc() };
|
||||
let cid = cpu::id();
|
||||
let pid = self.process().pid.clone();
|
||||
let tid = processor().tid();
|
||||
let tid = thread::current().id();
|
||||
if !pid.is_init() {
|
||||
// we trust pid 0 process
|
||||
debug!("{}:{}:{} syscall id {} begin", cid, pid, tid, id);
|
||||
|
@ -7,8 +7,8 @@ impl Syscall<'_> {
|
||||
pub fn sys_fork(&mut self) -> SysResult {
|
||||
let new_thread = self.thread.fork(self.tf);
|
||||
let pid = new_thread.proc.lock().pid.get();
|
||||
let tid = processor().manager().add(new_thread);
|
||||
processor().manager().detach(tid);
|
||||
let tid = thread_manager().add(new_thread);
|
||||
thread_manager().detach(tid);
|
||||
info!("fork: {} -> {}", thread::current().id(), pid);
|
||||
Ok(pid)
|
||||
}
|
||||
@ -53,8 +53,8 @@ impl Syscall<'_> {
|
||||
let new_thread = self
|
||||
.thread
|
||||
.clone(self.tf, newsp, newtls, child_tid as usize);
|
||||
let tid = processor().manager().add(new_thread);
|
||||
processor().manager().detach(tid);
|
||||
let tid = thread_manager().add(new_thread);
|
||||
thread_manager().detach(tid);
|
||||
info!("clone: {} -> {}", thread::current().id(), tid);
|
||||
*parent_tid_ref = tid as u32;
|
||||
*child_tid_ref = tid as u32;
|
||||
@ -172,10 +172,10 @@ impl Syscall<'_> {
|
||||
|
||||
// Kill other threads
|
||||
proc.threads.retain(|&tid| {
|
||||
if tid != processor().tid() {
|
||||
processor().manager().exit(tid, 1);
|
||||
if tid != thread::current().id() {
|
||||
thread_manager().exit(tid, 1);
|
||||
}
|
||||
tid == processor().tid()
|
||||
tid == thread::current().id()
|
||||
});
|
||||
|
||||
// Read program file
|
||||
@ -280,8 +280,8 @@ impl Syscall<'_> {
|
||||
|
||||
drop(proc);
|
||||
|
||||
processor().manager().exit(tid, exit_code as usize);
|
||||
processor().yield_now();
|
||||
thread_manager().exit(tid, exit_code as usize);
|
||||
thread::yield_now();
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ impl Syscall<'_> {
|
||||
|
||||
proc.exit(exit_code);
|
||||
|
||||
processor().yield_now();
|
||||
thread::yield_now();
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ impl Syscall<'_> {
|
||||
|
||||
pub fn sys_set_priority(&mut self, priority: usize) -> SysResult {
|
||||
let pid = thread::current().id();
|
||||
processor().manager().set_priority(pid, priority as u8);
|
||||
thread_manager().set_priority(pid, priority as u8);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use crate::arch::interrupt::TrapFrame;
|
||||
use crate::consts::INFORM_PER_MSEC;
|
||||
use crate::process::*;
|
||||
use crate::sync::Condvar;
|
||||
use log::*;
|
||||
use rcore_thread::std_thread as thread;
|
||||
|
||||
pub static mut TICK: usize = 0;
|
||||
|
||||
@ -33,7 +33,7 @@ pub fn error(tf: &TrapFrame) -> ! {
|
||||
let mut proc = current_thread().proc.lock();
|
||||
proc.exit(0x100);
|
||||
}
|
||||
processor().yield_now();
|
||||
thread::yield_now();
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user