lockref.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #pragma once
  2. #include <common/sys/types.h>
  3. #include <common/spinlock.h>
  4. #if ARCH(X86_64)
  5. // 仅在x64架构下启用cmpxchg
  6. #define __LOCKREF_ENABLE_CMPXCHG__
  7. #endif
  8. struct lockref
  9. {
  10. union
  11. {
  12. #ifdef __LOCKREF_ENABLE_CMPXCHG__
  13. aligned_u64 lock_count; // 通过该变量的声明,使得整个lockref按照8字节对齐
  14. #endif
  15. struct
  16. {
  17. spinlock_t lock;
  18. int count;
  19. };
  20. };
  21. };
  22. /**
  23. * @brief 原子的将引用计数加1
  24. *
  25. * @param lock_ref 要被操作的lockref变量
  26. */
  27. void lockref_inc(struct lockref *lock_ref);
  28. /**
  29. * @brief 原子地将引用计数加1.如果原来的count≤0,则操作失败。
  30. *
  31. * @param lock_ref 指向要被操作的lockref变量的指针
  32. * @return int 操作成功=>true
  33. * 操作失败=>false
  34. */
  35. bool lockref_inc_not_zero(struct lockref *lock_ref);
  36. /**
  37. * @brief 原子地减少引用计数。如果已处于count≤0的状态,则返回-1
  38. *
  39. * 本函数与lockref_dec_return()的区别在于,当在cmpxchg()中检测到count<=0或已加锁,本函数会再次尝试通过加锁来执行操作
  40. * 而后者会直接返回错误
  41. *
  42. * @param lock_ref 指向要被操作的lockref变量的指针
  43. * @return int 操作成功 => 返回新的引用变量值
  44. * lockref处于count≤0的状态 => 返回-1
  45. */
  46. int lockref_dec(struct lockref *lock_ref);
  47. /**
  48. * @brief 原子地减少引用计数。如果处于已加锁或count≤0的状态,则返回-1
  49. *
  50. * 本函数与lockref_dec()的区别在于,当在cmpxchg()中检测到count<=0或已加锁,本函数会直接返回错误
  51. * 而后者会再次尝试通过加锁来执行操作
  52. *
  53. * @param lock_ref 指向要被操作的lockref变量的指针
  54. * @return int 操作成功 => 返回新的引用变量值
  55. * lockref处于已加锁或count≤0的状态 => 返回-1
  56. */
  57. int lockref_dec_return(struct lockref *lock_ref);
  58. /**
  59. * @brief 原子地减少引用计数。若当前的引用计数≤1,则操作失败
  60. *
  61. * 该函数与lockref_dec_or_lock_not_zero()的区别在于,当cmpxchg()时发现old.count≤1时,该函数会直接返回false.
  62. * 而后者在这种情况下,会尝试加锁来进行操作。
  63. *
  64. * @param lock_ref 指向要被操作的lockref变量的指针
  65. * @return true 成功将引用计数减1
  66. * @return false 如果当前的引用计数≤1,操作失败
  67. */
  68. bool lockref_dec_not_zero(struct lockref *lock_ref);
  69. /**
  70. * @brief 原子地减少引用计数。若当前的引用计数≤1,则操作失败
  71. *
  72. * 该函数与lockref_dec_not_zero()的区别在于,当cmpxchg()时发现old.count≤1时,该函数会尝试加锁来进行操作。
  73. * 而后者在这种情况下,会直接返回false.
  74. *
  75. * @param lock_ref 指向要被操作的lockref变量的指针
  76. * @return true 成功将引用计数减1
  77. * @return false 如果当前的引用计数≤1,操作失败
  78. */
  79. bool lockref_dec_or_lock_not_zero(struct lockref *lock_ref);
  80. /**
  81. * @brief 将lockref变量标记为已经死亡(将count设置为负值)
  82. *
  83. * @param lock_ref 指向要被操作的lockref变量的指针
  84. */
  85. void lockref_mark_dead(struct lockref * lock_ref);
  86. /**
  87. * @brief 自增引用计数。(除非该lockref已经死亡)
  88. *
  89. * @param lock_ref 指向要被操作的lockref变量的指针
  90. * @return true 操作成功
  91. * @return false 操作失败,lockref已死亡
  92. */
  93. bool lockref_inc_not_dead(struct lockref *lock_ref);