semaphore.rs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. use core::sync::atomic::{AtomicI32, Ordering};
  2. use log::debug;
  3. use system_error::SystemError;
  4. use crate::process::ProcessManager;
  5. use super::wait_queue::WaitQueue;
  6. /// @brief 信号量的结构体
  7. #[derive(Debug)]
  8. struct Semaphore {
  9. counter: AtomicI32,
  10. wait_queue: WaitQueue,
  11. }
  12. impl Semaphore {
  13. #[allow(dead_code)]
  14. #[inline]
  15. /// @brief 初始化信号量
  16. ///
  17. /// @param count 信号量的初始值
  18. /// @return 条件满足返回semaphore对象,条件不满足返回err信息
  19. fn new(counter: i32) -> Result<Self, SystemError> {
  20. if counter > 0 {
  21. Ok(Self {
  22. counter: AtomicI32::new(counter),
  23. wait_queue: WaitQueue::default(),
  24. })
  25. } else {
  26. return Err(SystemError::EOVERFLOW);
  27. }
  28. }
  29. #[allow(dead_code)]
  30. #[inline]
  31. fn down(&self) {
  32. if self.counter.fetch_sub(1, Ordering::Release) <= 0 {
  33. self.counter.fetch_add(1, Ordering::Relaxed);
  34. self.wait_queue.sleep().ok();
  35. //资源不充足,信号量<=0, 此时进程睡眠
  36. }
  37. }
  38. #[allow(dead_code)]
  39. #[inline]
  40. fn up(&self) {
  41. // 判断有没有进程在等待资源
  42. if self.wait_queue.len() > 0 {
  43. self.counter.fetch_add(1, Ordering::Release);
  44. } else {
  45. //尝试唤醒
  46. if !self.wait_queue.wakeup(None) {
  47. //如果唤醒失败,打印错误信息
  48. debug!(
  49. "Semaphore wakeup failed: current pid= {}, semaphore={:?}",
  50. ProcessManager::current_pcb().pid().into(),
  51. self
  52. );
  53. }
  54. }
  55. }
  56. }