vgtod.h 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #ifndef _ASM_X86_VGTOD_H
  2. #define _ASM_X86_VGTOD_H
  3. #include <linux/compiler.h>
  4. #include <linux/clocksource.h>
  5. #ifdef BUILD_VDSO32_64
  6. typedef u64 gtod_long_t;
  7. #else
  8. typedef unsigned long gtod_long_t;
  9. #endif
  10. /*
  11. * vsyscall_gtod_data will be accessed by 32 and 64 bit code at the same time
  12. * so be carefull by modifying this structure.
  13. */
  14. struct vsyscall_gtod_data {
  15. unsigned seq;
  16. int vclock_mode;
  17. cycle_t cycle_last;
  18. cycle_t mask;
  19. u32 mult;
  20. u32 shift;
  21. /* open coded 'struct timespec' */
  22. u64 wall_time_snsec;
  23. gtod_long_t wall_time_sec;
  24. gtod_long_t monotonic_time_sec;
  25. u64 monotonic_time_snsec;
  26. gtod_long_t wall_time_coarse_sec;
  27. gtod_long_t wall_time_coarse_nsec;
  28. gtod_long_t monotonic_time_coarse_sec;
  29. gtod_long_t monotonic_time_coarse_nsec;
  30. int tz_minuteswest;
  31. int tz_dsttime;
  32. };
  33. extern struct vsyscall_gtod_data vsyscall_gtod_data;
  34. static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s)
  35. {
  36. unsigned ret;
  37. repeat:
  38. ret = ACCESS_ONCE(s->seq);
  39. if (unlikely(ret & 1)) {
  40. cpu_relax();
  41. goto repeat;
  42. }
  43. smp_rmb();
  44. return ret;
  45. }
  46. static inline int gtod_read_retry(const struct vsyscall_gtod_data *s,
  47. unsigned start)
  48. {
  49. smp_rmb();
  50. return unlikely(s->seq != start);
  51. }
  52. static inline void gtod_write_begin(struct vsyscall_gtod_data *s)
  53. {
  54. ++s->seq;
  55. smp_wmb();
  56. }
  57. static inline void gtod_write_end(struct vsyscall_gtod_data *s)
  58. {
  59. smp_wmb();
  60. ++s->seq;
  61. }
  62. #endif /* _ASM_X86_VGTOD_H */