vdso.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
  3. * Copyright 2003 Andi Kleen, SuSE Labs.
  4. *
  5. * Thanks to hpa@transmeta.com for some useful hint.
  6. * Special thanks to Ingo Molnar for his early experience with
  7. * a different vsyscall implementation for Linux/IA32 and for the name.
  8. */
  9. #include <linux/seqlock.h>
  10. #include <linux/time.h>
  11. #include <linux/timekeeper_internal.h>
  12. #include <asm/vvar.h>
  13. void update_vsyscall_tz(void)
  14. {
  15. if (unlikely(vvar_data == NULL))
  16. return;
  17. vvar_data->tz_minuteswest = sys_tz.tz_minuteswest;
  18. vvar_data->tz_dsttime = sys_tz.tz_dsttime;
  19. }
  20. void update_vsyscall(struct timekeeper *tk)
  21. {
  22. struct vvar_data *vdata = vvar_data;
  23. if (unlikely(vdata == NULL))
  24. return;
  25. vvar_write_begin(vdata);
  26. vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
  27. vdata->clock.cycle_last = tk->tkr_mono.cycle_last;
  28. vdata->clock.mask = tk->tkr_mono.mask;
  29. vdata->clock.mult = tk->tkr_mono.mult;
  30. vdata->clock.shift = tk->tkr_mono.shift;
  31. vdata->wall_time_sec = tk->xtime_sec;
  32. vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec;
  33. vdata->monotonic_time_sec = tk->xtime_sec +
  34. tk->wall_to_monotonic.tv_sec;
  35. vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec +
  36. (tk->wall_to_monotonic.tv_nsec <<
  37. tk->tkr_mono.shift);
  38. while (vdata->monotonic_time_snsec >=
  39. (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
  40. vdata->monotonic_time_snsec -=
  41. ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
  42. vdata->monotonic_time_sec++;
  43. }
  44. vdata->wall_time_coarse_sec = tk->xtime_sec;
  45. vdata->wall_time_coarse_nsec =
  46. (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
  47. vdata->monotonic_time_coarse_sec =
  48. vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
  49. vdata->monotonic_time_coarse_nsec =
  50. vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec;
  51. while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) {
  52. vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC;
  53. vdata->monotonic_time_coarse_sec++;
  54. }
  55. vvar_write_end(vdata);
  56. }