pudding_kernel/
semaphore.rs1use crate::system::*;
2use crate::*;
3
4pub struct Semaphore {
6 queue: TaskQueue,
7 order: Order,
8 count: SemaphoreCount,
9}
10
11impl Semaphore {
12 pub const fn new(init_count: SemaphoreCount, order: Order) -> Self {
13 Semaphore {
14 queue: TaskQueue::new(),
15 order: order,
16 count: init_count,
17 }
18 }
19
20 pub fn signal(&mut self) {
21 let _sc = SystemCall::new();
22 let head = self.queue.pop_front();
23 match head {
24 None => {
25 self.count += 1;
26 }
27 Some(task) => {
28 task.detach_from_timeout();
29 task.attach_to_ready_queue();
30 set_dispatch_reserve_flag();
31 }
32 };
33 }
34
35 pub fn wait(&mut self) {
36 let _sc = SystemCall::new();
37 if self.count > 0 {
38 self.count -= 1;
39 } else {
40 let task = detach_current_task().unwrap();
41 task.attach_to_queue(&mut self.queue, self.order);
42 set_dispatch_reserve_flag();
43 }
44 }
45
46 pub fn polling(&mut self) -> Result<(), Error> {
47 let _sc = SystemCall::new();
48 if self.count > 0 {
49 self.count -= 1;
50 Ok(())
51 } else {
52 Err(Error::Timeout)
53 }
54 }
55
56 pub fn wait_with_timeout(&mut self, time: RelativeTime) -> Result<(), Error> {
57 let task = current_task().unwrap();
58 {
59 let _sc = SystemCall::new();
60 if self.count > 0 {
61 self.count -= 1;
62 task.set_result(Ok(()));
63 } else {
64 let task = detach_current_task().unwrap();
65 task.attach_to_queue(&mut self.queue, self.order);
66 task.attach_to_timeout(time);
67 set_dispatch_reserve_flag();
68 }
69 }
70 task.result()
71 }
72}