1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 16:16:16 +04:00

write code for semget and semop. not compiled yet.

This commit is contained in:
HongboKang 2019-10-14 23:30:20 +08:00
parent 3caa091ec5
commit 374c34cd34
6 changed files with 143 additions and 0 deletions

3
kernel/src/ipc/mod.rs Normal file
View File

@ -0,0 +1,3 @@
mod semary;
pub use self::semary::*;

40
kernel/src/ipc/semary.rs Normal file
View File

@ -0,0 +1,40 @@
pub struct SemArray {
pub mut key: i32,
pub mut sems: Vec<Semaphore>,
}
pub struct SemBuf {
pub mut sem_num: i16,
pub mut sem_op: i16,
pub mut sem_flg: i16,
}
pub struct
lazy_static! {
pub static ref KEY2SEM: RwLock<BTreeMap<usize, Arc<Mutex<SemArray>>>> =
RwLock::new(BTreeMap::new()); // not mentioned.
}
fn new_semary(key: i32, nsems: i32, semflg: i32) -> Arc<Mutex<SemArray>> {
let mut key2sem_table = KEY2SEM.write();
let mut sem_array_ref: Arc<Mutex<SemArray>>;
if key2sem_table.get(key) == None {
let mut semaphores: Vec<Semaphore> = Vec::new();
for i in 0..nsems {
semaphores.push(Semaphore::new());
}
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);
} else {
sem_array_ref = key2sem_table.get(key).clone(); // no security check
}
sem_array_ref
}

View File

@ -18,6 +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 super::abi::{self, ProcInitInfo};
use crate::processor;
@ -64,6 +65,8 @@ pub struct Process {
pub cwd: String,
pub exec_path: String,
futexes: BTreeMap<usize, Arc<Condvar>>,
pub semaphores: RwLock<BTreeMap<usize, Arc<Mutex<SemArray>>>>,
pub semops: Vec<SemBuf>,
// relationship
pub pid: Pid, // i.e. tgid, usually the tid of first thread

View File

@ -41,6 +41,9 @@ impl Semaphore {
count = self.cvar.wait(count);
}
*count -= 1;
if (count > 0) {
self.cvar.notify_one();
}
}
/// Release a resource from this semaphore.
@ -61,6 +64,25 @@ impl Semaphore {
self.acquire();
SemaphoreGuard { sem: self }
}
/// Modify by k atomically
pub fn modify(&self, k: isize, wait: bool) -> Result {
match(k) {
k if k > 0 {
self.lock.lock() += k;
self.cvar.notify_one();
},
k if k <= 0 {
let mut count = self.lock.lock();
while *count < k {
if wait == false {
return Err(EAGAIN)
}
count = self.cvar.wait(count);
}
}
}
}
}
impl<'a> Drop for SemaphoreGuard<'a> {

69
kernel/src/syscall/ipc.rs Normal file
View File

@ -0,0 +1,69 @@
use crate::sync::Mutex;
use crate::sync::Semaphore;
use spin::RwLock;
pub use crate::ipc::SemArray;
pub use crate::ipc::SemBuf;
impl Syscall<'_> {
pub fn sys_semget(key: i32, nsems: i32, semflg: i32) -> SysResult { // ipc not supported yet
i32 SEMMSL = 256;
if (nsems < 0 || nsems > SEMMSL) {
return Err(SysError::EINVAL);
}
let mut semarray_table = self.process.semaphores.write();
let sem_id = (0..)
.find(|i| match semarray_table.get(i) {
Some(p) => false,
_ => true,
})
.unwrap();
let mut sem_array : Arc<Mutex<SemArray>> = new_semary(key, nsems, semflg);
semarray_table.insert(sem_id, sem_array);
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));
}
}
let mut semarray_table = self.process.semaphores.write();
for sembuf: SemBuf in sem_ops {
let mut wait = true;
if (sembuf.flg == IPC_NOWAIT) {
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);
},
x if x == 0 => {
},
x if x < 0 => {
}
}*/
let mut semarray: SemArray = semarray_table.get(sem_id).lock();
semarray.sems[sembuf.sem_num].modify(x, wait);
}
}
}
bitflags! {
pub struct SEMFLAGS: usize {
/// For SemOP
const IPC_NOWAIT = 0x800;
const SEM_UNDO = 0x1000;
}
}

View File

@ -24,6 +24,7 @@ pub use self::misc::*;
pub use self::net::*;
pub use self::proc::*;
pub use self::time::*;
pub use self::ipc::*;
mod custom;
mod fs;
@ -259,6 +260,11 @@ impl Syscall<'_> {
}
SYS_CLOCK_GETTIME => self.sys_clock_gettime(args[0], args[1] as *mut TimeSpec),
// 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]),
// system
SYS_GETPID => self.sys_getpid(),
SYS_GETTID => self.sys_gettid(),