afile_pos.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: afile_pos.h
  5. *
  6. * Description: afile_pos class definition.
  7. *
  8. * Version: 1.0
  9. * Created: 04/01/2021
  10. * Revision: none
  11. * Compiler: gcc
  12. *
  13. * Author: chenyujie, chenyujie28@jd.com@jd.com
  14. * Company: JD.com, Inc.
  15. *
  16. * =====================================================================================
  17. */
  18. #ifndef __HB_ASYNCFILE_POS_H
  19. #define __HB_ASYNCFILE_POS_H
  20. /*
  21. *
  22. * to prevent the compiler optimization
  23. *
  24. */
  25. #if __GNUC__ < 4
  26. # define MEMORY_BARRIER() __asm__ __volatile__("" : : : "memory")
  27. #else
  28. # define MEMORY_BARRIER() __sync_synchronize()
  29. #endif
  30. /*
  31. * 模拟异步文件
  32. */
  33. struct CAsyncFilePos {
  34. public:
  35. uint32_t serial;
  36. uint32_t offset;
  37. public:
  38. CAsyncFilePos() {
  39. MEMORY_BARRIER();
  40. serial = 0;
  41. offset = 0;
  42. MEMORY_BARRIER();
  43. }
  44. CAsyncFilePos(const CAsyncFilePos & v) {
  45. MEMORY_BARRIER();
  46. serial = v.serial;
  47. offset = v.offset;
  48. MEMORY_BARRIER();
  49. }
  50. /*
  51. * 向前移动v bytes
  52. */
  53. inline void Front(int v) {
  54. MEMORY_BARRIER();
  55. serial = serial;
  56. offset += v;
  57. MEMORY_BARRIER();
  58. }
  59. /*
  60. * 递增一个文件编号
  61. */
  62. inline void Shift(void) {
  63. MEMORY_BARRIER();
  64. offset = 0;
  65. /*
  66. * 有可能在这个点出现暂态,读者会认为自己GT写者,从而出错
  67. */
  68. serial += 1;
  69. MEMORY_BARRIER();
  70. }
  71. inline int EQ(const CAsyncFilePos & v) {
  72. return serial == v.serial && offset == v.offset;
  73. }
  74. inline int GT(const CAsyncFilePos & v) {
  75. return (serial > v.serial) || ((serial == v.serial)
  76. && (offset > v.offset) && v.offset != 0);
  77. }
  78. inline int Zero() {
  79. return serial == 0 && offset == 0;
  80. }
  81. /*
  82. * 切换文件时,有可能出现暂态出错,见Shift中的解释
  83. *
  84. * 因为是无锁判定,所以在读者判定时,我们先调用IsTransient来检测是否暂态,如果是则sespend读者
  85. */
  86. inline int IsTransient(const CAsyncFilePos &v) {
  87. return (serial == v.serial) && (offset > 0) && (v.offset == 0);
  88. }
  89. }__attribute__ ((packed));
  90. typedef CAsyncFilePos CReaderPos;
  91. typedef CAsyncFilePos CWriterPos;
  92. #endif