syscall.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. use system_error::SystemError;
  2. use crate::{
  3. libs::futex::futex::RobustListHead,
  4. mm::{verify_area, VirtAddr},
  5. syscall::Syscall,
  6. time::PosixTimeSpec,
  7. };
  8. use super::{constant::*, futex::Futex};
  9. impl Syscall {
  10. pub fn do_futex(
  11. uaddr: VirtAddr,
  12. operation: FutexFlag,
  13. val: u32,
  14. timeout: Option<PosixTimeSpec>,
  15. uaddr2: VirtAddr,
  16. val2: u32,
  17. val3: u32,
  18. ) -> Result<usize, SystemError> {
  19. verify_area(uaddr, core::mem::size_of::<u32>())?;
  20. verify_area(uaddr2, core::mem::size_of::<u32>())?;
  21. let cmd = FutexArg::from_bits(operation.bits() & FutexFlag::FUTEX_CMD_MASK.bits())
  22. .ok_or(SystemError::ENOSYS)?;
  23. let mut flags = FutexFlag::FLAGS_MATCH_NONE;
  24. if !operation.contains(FutexFlag::FUTEX_PRIVATE_FLAG) {
  25. flags.insert(FutexFlag::FLAGS_SHARED);
  26. }
  27. if operation.contains(FutexFlag::FUTEX_CLOCK_REALTIME) {
  28. flags.insert(FutexFlag::FLAGS_CLOCKRT);
  29. if cmd != FutexArg::FUTEX_WAIT_BITSET
  30. && cmd != FutexArg::FUTEX_WAIT_REQUEUE_PI
  31. && cmd != FutexArg::FUTEX_LOCK_PI2
  32. {
  33. return Err(SystemError::ENOSYS);
  34. }
  35. }
  36. match cmd {
  37. FutexArg::FUTEX_WAIT => {
  38. return Futex::futex_wait(uaddr, flags, val, timeout, FUTEX_BITSET_MATCH_ANY);
  39. }
  40. FutexArg::FUTEX_WAIT_BITSET => {
  41. return Futex::futex_wait(uaddr, flags, val, timeout, val3);
  42. }
  43. FutexArg::FUTEX_WAKE => {
  44. return Futex::futex_wake(uaddr, flags, val, FUTEX_BITSET_MATCH_ANY);
  45. }
  46. FutexArg::FUTEX_WAKE_BITSET => {
  47. return Futex::futex_wake(uaddr, flags, val, val3);
  48. }
  49. FutexArg::FUTEX_REQUEUE => {
  50. return Futex::futex_requeue(
  51. uaddr,
  52. flags,
  53. uaddr2,
  54. val as i32,
  55. val2 as i32,
  56. None,
  57. false,
  58. );
  59. }
  60. FutexArg::FUTEX_CMP_REQUEUE => {
  61. return Futex::futex_requeue(
  62. uaddr,
  63. flags,
  64. uaddr2,
  65. val as i32,
  66. val2 as i32,
  67. Some(val3),
  68. false,
  69. );
  70. }
  71. FutexArg::FUTEX_WAKE_OP => {
  72. return Futex::futex_wake_op(
  73. uaddr,
  74. flags,
  75. uaddr2,
  76. val as i32,
  77. val2 as i32,
  78. val3 as i32,
  79. );
  80. }
  81. FutexArg::FUTEX_LOCK_PI => {
  82. todo!()
  83. }
  84. FutexArg::FUTEX_LOCK_PI2 => {
  85. todo!()
  86. }
  87. FutexArg::FUTEX_UNLOCK_PI => {
  88. todo!()
  89. }
  90. FutexArg::FUTEX_TRYLOCK_PI => {
  91. todo!()
  92. }
  93. FutexArg::FUTEX_WAIT_REQUEUE_PI => {
  94. todo!()
  95. }
  96. FutexArg::FUTEX_CMP_REQUEUE_PI => {
  97. todo!()
  98. }
  99. _ => {
  100. return Err(SystemError::ENOSYS);
  101. }
  102. }
  103. }
  104. pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
  105. //判断用户空间地址的合法性
  106. verify_area(head_uaddr, core::mem::size_of::<u32>())?;
  107. let ret = RobustListHead::set_robust_list(head_uaddr, len);
  108. // log::debug!(
  109. // "set_robust_list: pid: {} head_uaddr={:?}",
  110. // crate::process::ProcessManager::current_pid(),
  111. // head_uaddr
  112. // );
  113. return ret;
  114. }
  115. pub fn get_robust_list(
  116. pid: usize,
  117. head_uaddr: VirtAddr,
  118. len_ptr_uaddr: VirtAddr,
  119. ) -> Result<usize, SystemError> {
  120. //判断用户空间地址的合法性
  121. verify_area(head_uaddr, core::mem::size_of::<u32>())?;
  122. verify_area(len_ptr_uaddr, core::mem::size_of::<u32>())?;
  123. let ret = RobustListHead::get_robust_list(pid, head_uaddr, len_ptr_uaddr);
  124. return ret;
  125. }
  126. }