Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
0003  *  Copyright 2003 Andi Kleen, SuSE Labs.
0004  *
0005  *  Thanks to hpa@transmeta.com for some useful hint.
0006  *  Special thanks to Ingo Molnar for his early experience with
0007  *  a different vsyscall implementation for Linux/IA32 and for the name.
0008  */
0009 
0010 #include <linux/time.h>
0011 #include <linux/timekeeper_internal.h>
0012 
0013 #include <asm/vvar.h>
0014 
0015 void update_vsyscall_tz(void)
0016 {
0017     if (unlikely(vvar_data == NULL))
0018         return;
0019 
0020     vvar_data->tz_minuteswest = sys_tz.tz_minuteswest;
0021     vvar_data->tz_dsttime = sys_tz.tz_dsttime;
0022 }
0023 
0024 void update_vsyscall(struct timekeeper *tk)
0025 {
0026     struct vvar_data *vdata = vvar_data;
0027 
0028     if (unlikely(vdata == NULL))
0029         return;
0030 
0031     vvar_write_begin(vdata);
0032     vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
0033     vdata->clock.cycle_last = tk->tkr_mono.cycle_last;
0034     vdata->clock.mask = tk->tkr_mono.mask;
0035     vdata->clock.mult = tk->tkr_mono.mult;
0036     vdata->clock.shift = tk->tkr_mono.shift;
0037 
0038     vdata->wall_time_sec = tk->xtime_sec;
0039     vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec;
0040 
0041     vdata->monotonic_time_sec = tk->xtime_sec +
0042                     tk->wall_to_monotonic.tv_sec;
0043     vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec +
0044                       (tk->wall_to_monotonic.tv_nsec <<
0045                        tk->tkr_mono.shift);
0046 
0047     while (vdata->monotonic_time_snsec >=
0048            (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
0049         vdata->monotonic_time_snsec -=
0050                 ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
0051         vdata->monotonic_time_sec++;
0052     }
0053 
0054     vdata->wall_time_coarse_sec = tk->xtime_sec;
0055     vdata->wall_time_coarse_nsec =
0056             (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
0057 
0058     vdata->monotonic_time_coarse_sec =
0059         vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
0060     vdata->monotonic_time_coarse_nsec =
0061         vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec;
0062 
0063     while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) {
0064         vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC;
0065         vdata->monotonic_time_coarse_sec++;
0066     }
0067 
0068     vvar_write_end(vdata);
0069 }