mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
pass compilation with semget and part of semop.
This commit is contained in:
parent
374c34cd34
commit
64cdfa277f
@ -1,3 +1,3 @@
|
||||
mod semary;
|
||||
pub mod semary;
|
||||
|
||||
pub use self::semary::*;
|
@ -1,39 +1,50 @@
|
||||
use lazy_static::lazy_static;
|
||||
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, sync::Weak, vec::Vec};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::sync::Semaphore;
|
||||
use spin::RwLock;
|
||||
|
||||
pub struct SemArray {
|
||||
pub mut key: i32,
|
||||
pub mut sems: Vec<Semaphore>,
|
||||
pub key: usize,
|
||||
pub sems: Vec<Semaphore>
|
||||
}
|
||||
|
||||
impl SemArray {
|
||||
pub fn new(key: usize, sems: Vec<Semaphore>) -> SemArray {
|
||||
SemArray {
|
||||
key,
|
||||
sems
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SemBuf {
|
||||
pub mut sem_num: i16,
|
||||
pub mut sem_op: i16,
|
||||
pub mut sem_flg: i16,
|
||||
pub sem_num: i16,
|
||||
pub sem_op: i16,
|
||||
pub sem_flg: i16,
|
||||
}
|
||||
|
||||
pub struct
|
||||
lazy_static! {
|
||||
pub static ref KEY2SEM: RwLock<BTreeMap<usize, Arc<Mutex<SemArray>>>> =
|
||||
pub static ref KEY2SEM: RwLock<BTreeMap<usize, Weak<Mutex<SemArray>>>> =
|
||||
RwLock::new(BTreeMap::new()); // not mentioned.
|
||||
}
|
||||
|
||||
fn new_semary(key: i32, nsems: i32, semflg: i32) -> Arc<Mutex<SemArray>> {
|
||||
pub fn new_semary(key: usize, nsems: usize, semflg: usize) -> Arc<Mutex<SemArray>> {
|
||||
|
||||
let mut key2sem_table = KEY2SEM.write();
|
||||
let mut sem_array_ref: Arc<Mutex<SemArray>>;
|
||||
|
||||
if key2sem_table.get(key) == None {
|
||||
if key2sem_table.get(&key).is_none() {
|
||||
let mut semaphores: Vec<Semaphore> = Vec::new();
|
||||
for i in 0..nsems {
|
||||
semaphores.push(Semaphore::new());
|
||||
semaphores.push(Semaphore::new(0));
|
||||
}
|
||||
|
||||
let mut sem_array = SemArray::new();
|
||||
sem_array.key = key;
|
||||
sem_array.sems = semaphores;
|
||||
sem_array_ref = Arc::new(sem_array);
|
||||
key2sem_table.insert(key, sem_array_ref);
|
||||
let mut sem_array = SemArray::new(key, semaphores);
|
||||
sem_array_ref = Arc::new(Mutex::new(sem_array));
|
||||
key2sem_table.insert(key, Arc::downgrade(&sem_array_ref));
|
||||
} else {
|
||||
sem_array_ref = key2sem_table.get(key).clone(); // no security check
|
||||
sem_array_ref = key2sem_table.get(&key).unwrap().upgrade().unwrap(); // no security check
|
||||
}
|
||||
|
||||
sem_array_ref
|
||||
|
@ -41,6 +41,7 @@ pub mod shell;
|
||||
pub mod sync;
|
||||
pub mod syscall;
|
||||
pub mod trap;
|
||||
pub mod ipc;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -18,7 +18,7 @@ use crate::memory::{
|
||||
ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
|
||||
};
|
||||
use crate::sync::{Condvar, SpinNoIrqLock as Mutex};
|
||||
use crate::ipc::SemArray;
|
||||
use crate::ipc::*;
|
||||
|
||||
use super::abi::{self, ProcInitInfo};
|
||||
use crate::processor;
|
||||
@ -127,6 +127,8 @@ impl Thread {
|
||||
files: BTreeMap::default(),
|
||||
cwd: String::from("/"),
|
||||
exec_path: String::new(),
|
||||
semaphores: RwLock::new(BTreeMap::new()),
|
||||
semops: Vec::new(),
|
||||
futexes: BTreeMap::default(),
|
||||
pid: Pid(0),
|
||||
parent: Weak::new(),
|
||||
@ -311,6 +313,8 @@ impl Thread {
|
||||
cwd: String::from("/"),
|
||||
exec_path: String::from(exec_path),
|
||||
futexes: BTreeMap::default(),
|
||||
semaphores: RwLock::new(BTreeMap::new()),
|
||||
semops: Vec::new(),
|
||||
pid: Pid(0),
|
||||
parent: Weak::new(),
|
||||
children: Vec::new(),
|
||||
@ -337,6 +341,8 @@ impl Thread {
|
||||
cwd: proc.cwd.clone(),
|
||||
exec_path: proc.exec_path.clone(),
|
||||
futexes: BTreeMap::default(),
|
||||
semaphores: RwLock::new(BTreeMap::new()),
|
||||
semops: Vec::new(),
|
||||
pid: Pid(0),
|
||||
parent: Arc::downgrade(&self.proc),
|
||||
children: Vec::new(),
|
||||
|
@ -41,7 +41,7 @@ impl Semaphore {
|
||||
count = self.cvar.wait(count);
|
||||
}
|
||||
*count -= 1;
|
||||
if (count > 0) {
|
||||
if (*count > 0) {
|
||||
self.cvar.notify_one();
|
||||
}
|
||||
}
|
||||
@ -65,23 +65,34 @@ impl Semaphore {
|
||||
SemaphoreGuard { sem: self }
|
||||
}
|
||||
|
||||
/// Modify by k atomically
|
||||
pub fn modify(&self, k: isize, wait: bool) -> Result {
|
||||
/// Modify by k atomically. when wait is false avoid waiting.
|
||||
pub fn modify(&self, k: isize, wait: bool) -> Result<usize, usize> {
|
||||
match(k) {
|
||||
k if k > 0 {
|
||||
self.lock.lock() += k;
|
||||
k if k > 0 => {
|
||||
*(self.lock.lock()) += k;
|
||||
self.cvar.notify_one();
|
||||
},
|
||||
k if k <= 0 {
|
||||
k if k <= 0 => {
|
||||
let mut count = self.lock.lock();
|
||||
while *count < k {
|
||||
let mut temp_k = k;
|
||||
while *count < temp_k {
|
||||
if wait == false {
|
||||
return Err(EAGAIN)
|
||||
return Err(1)
|
||||
}
|
||||
temp_k -= *count;
|
||||
*count = 0;
|
||||
count = self.cvar.wait(count);
|
||||
}
|
||||
*count -= temp_k;
|
||||
if (*count > 0) {
|
||||
self.cvar.notify_one();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(1); //unknown error?
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,26 @@
|
||||
use crate::sync::Mutex;
|
||||
|
||||
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, sync::Weak, vec::Vec};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::sync::Semaphore;
|
||||
use spin::RwLock;
|
||||
use bitflags::*;
|
||||
|
||||
pub use crate::ipc::SemArray;
|
||||
pub use crate::ipc::SemBuf;
|
||||
pub use crate::ipc::new_semary;
|
||||
//use crate::ipc::semary::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Syscall<'_> {
|
||||
pub fn sys_semget(key: i32, nsems: i32, semflg: i32) -> SysResult { // ipc not supported yet
|
||||
i32 SEMMSL = 256;
|
||||
pub fn sys_semget(&self, key: usize, nsems: usize, semflg: usize) -> SysResult { // ipc not supported yet
|
||||
let SEMMSL: usize = 256;
|
||||
if (nsems < 0 || nsems > SEMMSL) {
|
||||
return Err(SysError::EINVAL);
|
||||
}
|
||||
|
||||
let mut semarray_table = self.process.semaphores.write();
|
||||
let mut proc = self.process();
|
||||
let mut semarray_table = proc.semaphores.write();
|
||||
let sem_id = (0..)
|
||||
.find(|i| match semarray_table.get(i) {
|
||||
Some(p) => false,
|
||||
@ -23,45 +31,40 @@ impl Syscall<'_> {
|
||||
let mut sem_array : Arc<Mutex<SemArray>> = new_semary(key, nsems, semflg);
|
||||
|
||||
semarray_table.insert(sem_id, sem_array);
|
||||
OK(sem_id)
|
||||
Ok(sem_id)
|
||||
}
|
||||
|
||||
pub fn sys_semop(sem_id: i32, sem_opa: *const SemBuf, num_sem_ops: i32) -> SysResult {
|
||||
let mut sem_bufs:Vec<SemBuf> = Vec::new();
|
||||
unsafe {
|
||||
for i in 0..num_sem_ops {
|
||||
sem_bufs.push(*(sem_opa + i));
|
||||
}
|
||||
}
|
||||
pub fn sys_semop(&self, sem_id: usize, sem_ops: *const SemBuf, num_sem_ops: usize) -> SysResult {
|
||||
//let mut sem_bufs:Vec<SemBuf> = Vec::new();
|
||||
let sem_ops = unsafe { self.vm().check_read_array(sem_ops, num_sem_ops)? };
|
||||
|
||||
let mut semarray_table = self.process.semaphores.write();
|
||||
let mut proc = self.process();
|
||||
let mut semarray_table = proc.semaphores.write();
|
||||
|
||||
for sembuf: SemBuf in sem_ops {
|
||||
for sembuf in sem_ops.iter() {
|
||||
let mut wait = true;
|
||||
if (sembuf.flg == IPC_NOWAIT) {
|
||||
if (sembuf.sem_flg == (SEMFLAGS::IPC_NOWAIT.bits())) {
|
||||
wait = false;
|
||||
}
|
||||
/*match(sembuf.sem_op) {
|
||||
x if x > 0 => {
|
||||
let mut semarray: SemArray = semarray_table.get(sem_id).lock();
|
||||
semarray.sems[sembuf.sem_num].modify(x, wait);
|
||||
let mut semarray_arc: Arc<Mutex<SemArray>> = (*semarray_table.get(&sem_id).unwrap()).clone();
|
||||
let mut semarray: &SemArray = &*semarray_arc.lock();
|
||||
match((*semarray).sems[sembuf.sem_num as usize].modify(sembuf.sem_op as isize, wait)) {
|
||||
Ok(0) => {},
|
||||
Err(1) => {
|
||||
return Err(SysError::EAGAIN);
|
||||
},
|
||||
x if x == 0 => {
|
||||
|
||||
},
|
||||
x if x < 0 => {
|
||||
|
||||
_ => {
|
||||
return Err(SysError::EUNDEF); // unknown error?
|
||||
}
|
||||
}*/
|
||||
let mut semarray: SemArray = semarray_table.get(sem_id).lock();
|
||||
semarray.sems[sembuf.sem_num].modify(x, wait);
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct SEMFLAGS: usize {
|
||||
pub struct SEMFLAGS: i16 {
|
||||
/// For SemOP
|
||||
const IPC_NOWAIT = 0x800;
|
||||
const SEM_UNDO = 0x1000;
|
||||
|
@ -34,6 +34,7 @@ mod misc;
|
||||
mod net;
|
||||
mod proc;
|
||||
mod time;
|
||||
mod ipc;
|
||||
|
||||
#[cfg(feature = "profile")]
|
||||
use alloc::collections::BTreeMap;
|
||||
@ -263,7 +264,7 @@ impl Syscall<'_> {
|
||||
// sem
|
||||
SYS_SEMGET => self.sys_semget(args[0], args[1], args[2]),
|
||||
SYS_SEMOP => self.sys_semop(args[0], args[1] as *const SemBuf, args[2]),
|
||||
SYS_SEMCTL => self.sys_semctl(args[0], args[1], args[2], args[3]),
|
||||
//SYS_SEMCTL => self.sys_semctl(args[0], args[1], args[2], args[3]),
|
||||
|
||||
// system
|
||||
SYS_GETPID => self.sys_getpid(),
|
||||
|
Loading…
Reference in New Issue
Block a user