os/syscall/
sync.rs

1use crate::sync::{Condvar, Mutex, MutexBlocking, MutexSpin, Semaphore};
2use crate::task::{block_current_and_run_next, current_process, current_task};
3use crate::timer::{add_timer, get_time_ms};
4use alloc::sync::Arc;
5
6pub fn sys_sleep(ms: usize) -> isize {
7    let expire_ms = get_time_ms() + ms;
8    let task = current_task().unwrap();
9    add_timer(expire_ms, task);
10    block_current_and_run_next();
11    0
12}
13
14pub fn sys_mutex_create(blocking: bool) -> isize {
15    let process = current_process();
16    let mutex: Option<Arc<dyn Mutex>> = if !blocking {
17        Some(Arc::new(MutexSpin::new()))
18    } else {
19        Some(Arc::new(MutexBlocking::new()))
20    };
21    let mut process_inner = process.inner_exclusive_access();
22    if let Some(id) = process_inner
23        .mutex_list
24        .iter()
25        .enumerate()
26        .find(|(_, item)| item.is_none())
27        .map(|(id, _)| id)
28    {
29        process_inner.mutex_list[id] = mutex;
30        id as isize
31    } else {
32        process_inner.mutex_list.push(mutex);
33        process_inner.mutex_list.len() as isize - 1
34    }
35}
36
37pub fn sys_mutex_lock(mutex_id: usize) -> isize {
38    let process = current_process();
39    let process_inner = process.inner_exclusive_access();
40    let mutex = Arc::clone(process_inner.mutex_list[mutex_id].as_ref().unwrap());
41    drop(process_inner);
42    drop(process);
43    mutex.lock();
44    0
45}
46
47pub fn sys_mutex_unlock(mutex_id: usize) -> isize {
48    let process = current_process();
49    let process_inner = process.inner_exclusive_access();
50    let mutex = Arc::clone(process_inner.mutex_list[mutex_id].as_ref().unwrap());
51    drop(process_inner);
52    drop(process);
53    mutex.unlock();
54    0
55}
56
57pub fn sys_semaphore_create(res_count: usize) -> isize {
58    let process = current_process();
59    let mut process_inner = process.inner_exclusive_access();
60    let id = if let Some(id) = process_inner
61        .semaphore_list
62        .iter()
63        .enumerate()
64        .find(|(_, item)| item.is_none())
65        .map(|(id, _)| id)
66    {
67        process_inner.semaphore_list[id] = Some(Arc::new(Semaphore::new(res_count)));
68        id
69    } else {
70        process_inner
71            .semaphore_list
72            .push(Some(Arc::new(Semaphore::new(res_count))));
73        process_inner.semaphore_list.len() - 1
74    };
75    id as isize
76}
77
78pub fn sys_semaphore_up(sem_id: usize) -> isize {
79    let process = current_process();
80    let process_inner = process.inner_exclusive_access();
81    let sem = Arc::clone(process_inner.semaphore_list[sem_id].as_ref().unwrap());
82    drop(process_inner);
83    sem.up();
84    0
85}
86
87pub fn sys_semaphore_down(sem_id: usize) -> isize {
88    let process = current_process();
89    let process_inner = process.inner_exclusive_access();
90    let sem = Arc::clone(process_inner.semaphore_list[sem_id].as_ref().unwrap());
91    drop(process_inner);
92    sem.down();
93    0
94}
95
96pub fn sys_condvar_create() -> isize {
97    let process = current_process();
98    let mut process_inner = process.inner_exclusive_access();
99    let id = if let Some(id) = process_inner
100        .condvar_list
101        .iter()
102        .enumerate()
103        .find(|(_, item)| item.is_none())
104        .map(|(id, _)| id)
105    {
106        process_inner.condvar_list[id] = Some(Arc::new(Condvar::new()));
107        id
108    } else {
109        process_inner
110            .condvar_list
111            .push(Some(Arc::new(Condvar::new())));
112        process_inner.condvar_list.len() - 1
113    };
114    id as isize
115}
116
117pub fn sys_condvar_signal(condvar_id: usize) -> isize {
118    let process = current_process();
119    let process_inner = process.inner_exclusive_access();
120    let condvar = Arc::clone(process_inner.condvar_list[condvar_id].as_ref().unwrap());
121    drop(process_inner);
122    condvar.signal();
123    0
124}
125
126pub fn sys_condvar_wait(condvar_id: usize, mutex_id: usize) -> isize {
127    let process = current_process();
128    let process_inner = process.inner_exclusive_access();
129    let condvar = Arc::clone(process_inner.condvar_list[condvar_id].as_ref().unwrap());
130    let mutex = Arc::clone(process_inner.mutex_list[mutex_id].as_ref().unwrap());
131    drop(process_inner);
132    condvar.wait(mutex);
133    0
134}