From 00af9731c9222d8b48655e01fadef7161f8b64dc Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Sat, 4 Apr 1998 13:26:20 +0000 Subject: [PATCH] Time changes mark 2: * Figure out UTC relative to boottime. Four new functions provide time relative to boottime. * move "runtime" into struct proc. This helps fix the calcru() problem in SMP. * kill mono_time. * add timespec{add|sub|cmp} macros to time.h. (XXX: These may change!) * nanosleep, select & poll takes long sleeps one day at a time Reviewed by: bde Tested by: ache and others --- sys/amd64/amd64/exception.S | 8 +- sys/amd64/amd64/exception.s | 8 +- sys/amd64/amd64/genassym.c | 3 +- sys/amd64/amd64/locore.S | 6 +- sys/amd64/amd64/locore.s | 6 +- sys/dev/syscons/syscons.c | 22 +++--- sys/fs/msdosfs/msdosfs_denode.c | 8 +- sys/i386/i386/exception.s | 8 +- sys/i386/i386/genassym.c | 3 +- sys/i386/i386/locore.s | 6 +- sys/i386/include/asnames.h | 3 +- sys/i386/isa/syscons.c | 22 +++--- sys/isa/syscons.c | 22 +++--- sys/kern/init_main.c | 14 ++-- sys/kern/kern_clock.c | 125 +++++++++++++++++++++++--------- sys/kern/kern_resource.c | 17 +++-- sys/kern/kern_synch.c | 10 +-- sys/kern/kern_tc.c | 125 +++++++++++++++++++++++--------- sys/kern/kern_time.c | 90 ++++++++--------------- sys/kern/sys_generic.c | 58 +++++++++------ sys/kern/uipc_sockbuf.c | 11 +-- sys/kern/uipc_socket2.c | 11 +-- sys/msdosfs/msdosfs_denode.c | 8 +- sys/net/if_spppsubr.c | 10 ++- sys/sys/kernel.h | 5 +- sys/sys/proc.h | 4 +- sys/sys/time.h | 44 ++++++++++- sys/sys/timetc.h | 44 ++++++++++- sys/ufs/ufs/ufs_vnops.c | 8 +- 29 files changed, 448 insertions(+), 261 deletions(-) diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 0b16ebe110d0..d308e8e9698b 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.47 1997/10/27 17:19:20 bde Exp $ + * $Id: exception.s,v 1.48 1998/03/23 19:52:23 jlemon Exp $ */ #include "npx.h" @@ -343,8 +343,10 @@ IDTVEC(int0x80_syscall) ENTRY(fork_trampoline) call _spl0 - pushl $_runtime - call _microtime + movl _curproc,%eax + addl $P_RUNTIME,%eax + pushl %eax + call _getmicroruntime popl %eax /* diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s index 0b16ebe110d0..d308e8e9698b 100644 --- a/sys/amd64/amd64/exception.s +++ b/sys/amd64/amd64/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.47 1997/10/27 17:19:20 bde Exp $ + * $Id: exception.s,v 1.48 1998/03/23 19:52:23 jlemon Exp $ */ #include "npx.h" @@ -343,8 +343,10 @@ IDTVEC(int0x80_syscall) ENTRY(fork_trampoline) call _spl0 - pushl $_runtime - call _microtime + movl _curproc,%eax + addl $P_RUNTIME,%eax + pushl %eax + call _getmicroruntime popl %eax /* diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index d08b27438069..34d5c44fca6b 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.50 1997/10/10 12:38:27 peter Exp $ + * $Id: genassym.c,v 1.51 1998/02/01 18:53:09 bde Exp $ */ #include "opt_vm86.h" @@ -95,6 +95,7 @@ main() printf("#define\tP_WCHAN %p\n", &p->p_wchan); printf("#define\tP_FLAG %p\n", &p->p_flag); printf("#define\tP_PID %p\n", &p->p_pid); + printf("#define\tP_RUNTIME %p\n", &p->p_runtime); #ifdef SMP printf("#define\tP_ONCPU %p\n", &p->p_oncpu); printf("#define\tP_LASTCPU %p\n", &p->p_lastcpu); diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index a7f04365cb7c..67ce91e22f3a 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.104 1998/01/31 02:53:41 eivind Exp $ + * $Id: locore.s,v 1.105 1998/03/23 19:52:27 jlemon Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -105,7 +105,7 @@ .set _prv_CPAGE3,_SMP_prvstart + ((5 + UPAGES) * PAGE_SIZE) .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) - .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _cpuid,_curproc,_curpcb,_npxproc,_cpu_lockid .globl _common_tss,_other_cpus,_my_idlePTD,_ss_tpr .globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3 .globl _inside_intr @@ -113,7 +113,7 @@ .set _curproc,_SMP_prvpage+4 /* [1] */ .set _curpcb,_SMP_prvpage+8 /* [2] */ .set _npxproc,_SMP_prvpage+12 /* [3] */ - .set _runtime,_SMP_prvpage+16 /* [4,5] */ + /* [4,5] was runtime, free */ .set _cpu_lockid,_SMP_prvpage+24 /* [6] */ .set _other_cpus,_SMP_prvpage+28 /* [7] bitmap of available CPUs, excluding ourself */ diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index a7f04365cb7c..67ce91e22f3a 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.104 1998/01/31 02:53:41 eivind Exp $ + * $Id: locore.s,v 1.105 1998/03/23 19:52:27 jlemon Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -105,7 +105,7 @@ .set _prv_CPAGE3,_SMP_prvstart + ((5 + UPAGES) * PAGE_SIZE) .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) - .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _cpuid,_curproc,_curpcb,_npxproc,_cpu_lockid .globl _common_tss,_other_cpus,_my_idlePTD,_ss_tpr .globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3 .globl _inside_intr @@ -113,7 +113,7 @@ .set _curproc,_SMP_prvpage+4 /* [1] */ .set _curpcb,_SMP_prvpage+8 /* [2] */ .set _npxproc,_SMP_prvpage+12 /* [3] */ - .set _runtime,_SMP_prvpage+16 /* [4,5] */ + /* [4,5] was runtime, free */ .set _cpu_lockid,_SMP_prvpage+24 /* [6] */ .set _other_cpus,_SMP_prvpage+28 /* [7] bitmap of available CPUs, excluding ourself */ diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 6eed3c40185e..547e350afafb 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.255 1998/02/13 11:31:34 phk Exp $ + * $Id: syscons.c,v 1.256 1998/02/13 17:54:53 phk Exp $ */ #include "sc.h" @@ -158,7 +158,7 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static long scrn_time_stamp; +static struct timeval scrn_time_stamp; u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; @@ -1030,7 +1030,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; scrn_blank_time = *(int *)data; if (scrn_blank_time == 0) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1385,7 +1385,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; } @@ -2228,6 +2228,7 @@ get_scr_num() static void scrn_timer(void *arg) { + struct timeval tv; scr_stat *scp = cur_console; int s; @@ -2269,9 +2270,10 @@ scrn_timer(void *arg) } /* should we stop the screen saver? */ + getmicroruntime(&tv); if (panicstr) - scrn_time_stamp = mono_time.tv_sec; - if (mono_time.tv_sec <= scrn_time_stamp + scrn_blank_time) + scrn_time_stamp = tv; + if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) if (scrn_blanked > 0) stop_scrn_saver(current_saver); scp = cur_console; @@ -2279,7 +2281,7 @@ scrn_timer(void *arg) scrn_update(scp, TRUE); /* should we activate the screen saver? */ if ((scrn_blank_time != 0) - && (mono_time.tv_sec > scrn_time_stamp + scrn_blank_time)) + && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) (*current_saver)(TRUE); timeout(scrn_timer, NULL, hz / 25); @@ -2387,7 +2389,7 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); mark_all(cur_console); } @@ -3038,7 +3040,7 @@ ansi_put(scr_stat *scp, u_char *buf, int len) /* make screensaver happy */ if (scp == cur_console) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); write_in_progress++; outloop: @@ -3488,7 +3490,7 @@ next_code: /* make screensaver happy */ if (!(scancode & 0x80)) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c index 6c4513d813c6..65dfabb6e461 100644 --- a/sys/fs/msdosfs/msdosfs_denode.c +++ b/sys/fs/msdosfs/msdosfs_denode.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_denode.c,v 1.33 1998/03/20 02:33:35 kato Exp $ */ +/* $Id: msdosfs_denode.c,v 1.34 1998/03/26 20:52:51 phk Exp $ */ /* $NetBSD: msdosfs_denode.c,v 1.28 1998/02/10 14:10:00 mrg Exp $ */ /*- @@ -198,6 +198,7 @@ deget(pmp, dirclust, diroffset, depp) struct vnode *nvp; struct buf *bp; struct proc *p = curproc; /* XXX */ + struct timeval tv; #ifdef MSDOSFS_DEBUG printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n", @@ -345,8 +346,9 @@ deget(pmp, dirclust, diroffset, depp) } } else nvp->v_type = VREG; - SETHIGH(ldep->de_modrev, mono_time.tv_sec); - SETLOW(ldep->de_modrev, mono_time.tv_usec * 4294); + getmicroruntime(&tv); + SETHIGH(ldep->de_modrev, tv.tv_sec); + SETLOW(ldep->de_modrev, tv.tv_usec * 4294); VREF(ldep->de_devvp); *depp = ldep; return (0); diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index 0b16ebe110d0..d308e8e9698b 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.47 1997/10/27 17:19:20 bde Exp $ + * $Id: exception.s,v 1.48 1998/03/23 19:52:23 jlemon Exp $ */ #include "npx.h" @@ -343,8 +343,10 @@ IDTVEC(int0x80_syscall) ENTRY(fork_trampoline) call _spl0 - pushl $_runtime - call _microtime + movl _curproc,%eax + addl $P_RUNTIME,%eax + pushl %eax + call _getmicroruntime popl %eax /* diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index d08b27438069..34d5c44fca6b 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.50 1997/10/10 12:38:27 peter Exp $ + * $Id: genassym.c,v 1.51 1998/02/01 18:53:09 bde Exp $ */ #include "opt_vm86.h" @@ -95,6 +95,7 @@ main() printf("#define\tP_WCHAN %p\n", &p->p_wchan); printf("#define\tP_FLAG %p\n", &p->p_flag); printf("#define\tP_PID %p\n", &p->p_pid); + printf("#define\tP_RUNTIME %p\n", &p->p_runtime); #ifdef SMP printf("#define\tP_ONCPU %p\n", &p->p_oncpu); printf("#define\tP_LASTCPU %p\n", &p->p_lastcpu); diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index a7f04365cb7c..67ce91e22f3a 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.104 1998/01/31 02:53:41 eivind Exp $ + * $Id: locore.s,v 1.105 1998/03/23 19:52:27 jlemon Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -105,7 +105,7 @@ .set _prv_CPAGE3,_SMP_prvstart + ((5 + UPAGES) * PAGE_SIZE) .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) - .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _cpuid,_curproc,_curpcb,_npxproc,_cpu_lockid .globl _common_tss,_other_cpus,_my_idlePTD,_ss_tpr .globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3 .globl _inside_intr @@ -113,7 +113,7 @@ .set _curproc,_SMP_prvpage+4 /* [1] */ .set _curpcb,_SMP_prvpage+8 /* [2] */ .set _npxproc,_SMP_prvpage+12 /* [3] */ - .set _runtime,_SMP_prvpage+16 /* [4,5] */ + /* [4,5] was runtime, free */ .set _cpu_lockid,_SMP_prvpage+24 /* [6] */ .set _other_cpus,_SMP_prvpage+28 /* [7] bitmap of available CPUs, excluding ourself */ diff --git a/sys/i386/include/asnames.h b/sys/i386/include/asnames.h index 4c40c93ffbac..4e1cce58d2d3 100644 --- a/sys/i386/include/asnames.h +++ b/sys/i386/include/asnames.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: asnames.h,v 1.16 1998/01/26 04:44:32 peter Exp $ + * $Id: asnames.h,v 1.17 1998/03/04 09:55:13 peter Exp $ */ #ifndef _MACHINE_ASNAMES_H_ @@ -316,7 +316,6 @@ #define _rel_mplock rel_mplock #define _round_reg round_reg #define _rtqs rtqs -#define _runtime runtime #define _s_lock s_lock #define _s_unlock s_unlock #define _secondary_main secondary_main diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index 6eed3c40185e..547e350afafb 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.255 1998/02/13 11:31:34 phk Exp $ + * $Id: syscons.c,v 1.256 1998/02/13 17:54:53 phk Exp $ */ #include "sc.h" @@ -158,7 +158,7 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static long scrn_time_stamp; +static struct timeval scrn_time_stamp; u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; @@ -1030,7 +1030,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; scrn_blank_time = *(int *)data; if (scrn_blank_time == 0) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1385,7 +1385,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; } @@ -2228,6 +2228,7 @@ get_scr_num() static void scrn_timer(void *arg) { + struct timeval tv; scr_stat *scp = cur_console; int s; @@ -2269,9 +2270,10 @@ scrn_timer(void *arg) } /* should we stop the screen saver? */ + getmicroruntime(&tv); if (panicstr) - scrn_time_stamp = mono_time.tv_sec; - if (mono_time.tv_sec <= scrn_time_stamp + scrn_blank_time) + scrn_time_stamp = tv; + if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) if (scrn_blanked > 0) stop_scrn_saver(current_saver); scp = cur_console; @@ -2279,7 +2281,7 @@ scrn_timer(void *arg) scrn_update(scp, TRUE); /* should we activate the screen saver? */ if ((scrn_blank_time != 0) - && (mono_time.tv_sec > scrn_time_stamp + scrn_blank_time)) + && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) (*current_saver)(TRUE); timeout(scrn_timer, NULL, hz / 25); @@ -2387,7 +2389,7 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); mark_all(cur_console); } @@ -3038,7 +3040,7 @@ ansi_put(scr_stat *scp, u_char *buf, int len) /* make screensaver happy */ if (scp == cur_console) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); write_in_progress++; outloop: @@ -3488,7 +3490,7 @@ next_code: /* make screensaver happy */ if (!(scancode & 0x80)) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c index 6eed3c40185e..547e350afafb 100644 --- a/sys/isa/syscons.c +++ b/sys/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.255 1998/02/13 11:31:34 phk Exp $ + * $Id: syscons.c,v 1.256 1998/02/13 17:54:53 phk Exp $ */ #include "sc.h" @@ -158,7 +158,7 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static long scrn_time_stamp; +static struct timeval scrn_time_stamp; u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; @@ -1030,7 +1030,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; scrn_blank_time = *(int *)data; if (scrn_blank_time == 0) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1385,7 +1385,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; } @@ -2228,6 +2228,7 @@ get_scr_num() static void scrn_timer(void *arg) { + struct timeval tv; scr_stat *scp = cur_console; int s; @@ -2269,9 +2270,10 @@ scrn_timer(void *arg) } /* should we stop the screen saver? */ + getmicroruntime(&tv); if (panicstr) - scrn_time_stamp = mono_time.tv_sec; - if (mono_time.tv_sec <= scrn_time_stamp + scrn_blank_time) + scrn_time_stamp = tv; + if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) if (scrn_blanked > 0) stop_scrn_saver(current_saver); scp = cur_console; @@ -2279,7 +2281,7 @@ scrn_timer(void *arg) scrn_update(scp, TRUE); /* should we activate the screen saver? */ if ((scrn_blank_time != 0) - && (mono_time.tv_sec > scrn_time_stamp + scrn_blank_time)) + && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) (*current_saver)(TRUE); timeout(scrn_timer, NULL, hz / 25); @@ -2387,7 +2389,7 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); mark_all(cur_console); } @@ -3038,7 +3040,7 @@ ansi_put(scr_stat *scp, u_char *buf, int len) /* make screensaver happy */ if (scp == cur_console) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); write_in_progress++; outloop: @@ -3488,7 +3490,7 @@ next_code: /* make screensaver happy */ if (!(scancode & 0x80)) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 2372c264ab59..d4bb6d15ed42 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.84 1998/02/15 04:16:57 dyson Exp $ + * $Id: init_main.c,v 1.85 1998/03/30 09:49:52 phk Exp $ */ #include "opt_devfs.h" @@ -104,10 +104,6 @@ static int shutdowntimeout = 120; SYSCTL_INT(_kern, OID_AUTO, shutdown_timeout, CTLFLAG_RW, &shutdowntimeout, 0, ""); -#ifndef SMP /* per-cpu on smp */ -struct timeval runtime; -#endif - /* * Promiscuous argument pass for start_init() * @@ -441,21 +437,21 @@ proc0_post(dummy) void *dummy; { struct timeval tv; + struct timespec ts; /* * Now can look at time, having had a chance to verify the time * from the file system. Reset p->p_rtime as it may have been * munched in mi_switch() after the time got set. */ - getmicrotime(&boottime); - proc0.p_stats->p_start = runtime = mono_time = boottime; + proc0.p_stats->p_start = boottime; proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; /* * Give the ``random'' number generator a thump. */ - microtime(&tv); - srandom(tv.tv_sec ^ tv.tv_usec); + nanotime(&ts); + srandom(ts.tv_sec ^ ts.tv_nsec); /* Initialize signal state for process 0. */ siginit(&proc0); diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index e3fb79847465..cf25a4671855 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -39,7 +39,7 @@ static volatile int print_tci = 1; * SUCH DAMAGE. * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_clock.c,v 1.61 1998/03/31 10:44:56 phk Exp $ + * $Id: kern_clock.c,v 1.62 1998/03/31 10:47:01 phk Exp $ */ #include @@ -138,8 +138,6 @@ int ticks; static int psdiv, pscnt; /* prof => stat divider */ int psratio; /* ratio: prof / stat */ -volatile struct timeval mono_time; - /* * Initialize clock frequencies and start both clocks running. */ @@ -232,7 +230,6 @@ tvtohz(tv) { register unsigned long ticks; register long sec, usec; - int s; /* * If the number of usecs in the whole seconds part of the time @@ -292,7 +289,6 @@ int hzto(tv) struct timeval *tv; { - register long sec, usec; struct timeval t2; getmicrotime(&t2); @@ -511,13 +507,72 @@ getmicrotime(struct timeval *tvp) { struct timecounter *tc; + tc = timecounter; + *tvp = tc->microtime; +} + +void +getnanotime(struct timespec *tsp) +{ + struct timecounter *tc; + + tc = timecounter; + *tsp = tc->nanotime; +} + +void +microtime(struct timeval *tv) +{ + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + tv->tv_usec = tc->offset_micro; + tv->tv_usec += + ((u_int64_t)tc->get_timedelta(tc) * tc->scale_micro) >> 32; + tv->tv_usec += boottime.tv_usec; + tv->tv_sec += boottime.tv_sec; + if (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } +} + +void +nanotime(struct timespec *tv) +{ + u_int count; + u_int64_t delta; + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + count = tc->get_timedelta(tc); + delta = tc->offset_nano; + delta += ((u_int64_t)count * tc->scale_nano_f); + delta >>= 32; + delta += ((u_int64_t)count * tc->scale_nano_i); + delta += boottime.tv_usec * 1000; + tv->tv_sec += boottime.tv_sec; + if (delta >= 1000000000) { + delta -= 1000000000; + tv->tv_sec++; + } + tv->tv_nsec = delta; +} + +void +getmicroruntime(struct timeval *tvp) +{ + struct timecounter *tc; + tc = timecounter; tvp->tv_sec = tc->offset_sec; tvp->tv_usec = tc->offset_micro; } void -getnanotime(struct timespec *tsp) +getnanoruntime(struct timespec *tsp) { struct timecounter *tc; @@ -527,7 +582,7 @@ getnanotime(struct timespec *tsp) } void -microtime(struct timeval *tv) +microruntime(struct timeval *tv) { struct timecounter *tc; @@ -543,7 +598,7 @@ microtime(struct timeval *tv) } void -nanotime(struct timespec *tv) +nanoruntime(struct timespec *tv) { u_int count; u_int64_t delta; @@ -601,7 +656,7 @@ init_timecounter(struct timecounter *tc) tc[2] = tc[1] = tc[0]; tc[1].other = &tc[2]; tc[2].other = &tc[1]; - if (!timecounter) + if (!timecounter || !strcmp(timecounter->name, "dummy")) timecounter = &tc[2]; tc = &tc[1]; @@ -634,27 +689,21 @@ init_timecounter(struct timecounter *tc) void set_timecounter(struct timespec *ts) { - struct timecounter *tc, *tco; - int s; + struct timespec ts2; - /* - * XXX we must be called at splclock() to preven *ts becoming - * invalid, so there is no point in spls here. - */ - s = splclock(); - tc = timecounter->other; - tco = tc->other; - *tc = *timecounter; - tc->other = tco; - tc->offset_sec = ts->tv_sec; - tc->offset_nano = (u_int64_t)ts->tv_nsec << 32; - tc->offset_micro = ts->tv_nsec / 1000; - tc->offset_count = tc->get_timecount(); - time_second = tc->offset_sec; - timecounter = tc; - splx(s); + nanoruntime(&ts2); + boottime.tv_sec = ts->tv_sec - ts2.tv_sec; + boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000; + if (boottime.tv_usec < 0) { + boottime.tv_usec += 1000000; + boottime.tv_sec--; + } + /* fiddle all the little crinkly bits around the fiords... */ + tco_forward(); } + +#if 0 /* Currently unused */ void switch_timecounter(struct timecounter *newtc) { @@ -676,6 +725,7 @@ switch_timecounter(struct timecounter *newtc) timecounter = newtc; splx(s); } +#endif static struct timecounter * sync_other_counter(void) @@ -703,14 +753,8 @@ tco_forward(void) tc = sync_other_counter(); if (timedelta != 0) { tc->offset_nano += (u_int64_t)(tickdelta * 1000) << 32; - mono_time.tv_usec += tickdelta; timedelta -= tickdelta; } - mono_time.tv_usec += tick; - if (mono_time.tv_usec >= 1000000) { - mono_time.tv_usec -= 1000000; - mono_time.tv_sec++; - } if (tc->offset_nano >= 1000000000ULL << 32) { tc->offset_nano -= 1000000000ULL << 32; @@ -723,7 +767,17 @@ tco_forward(void) tc->offset_micro = (tc->offset_nano / 1000) >> 32; - time_second = tc->offset_sec; + /* Figure out the wall-clock time */ + tc->nanotime.tv_sec = tc->offset_sec + boottime.tv_sec; + tc->nanotime.tv_nsec = (tc->offset_nano >> 32) + boottime.tv_usec * 1000; + tc->microtime.tv_usec = tc->offset_micro + boottime.tv_usec; + if (tc->nanotime.tv_nsec > 1000000000) { + tc->nanotime.tv_nsec -= 1000000000; + tc->microtime.tv_usec -= 1000000; + tc->nanotime.tv_sec++; + } + time_second = tc->microtime.tv_sec = tc->nanotime.tv_sec; + timecounter = tc; } @@ -775,8 +829,7 @@ static struct timecounter dummy_timecounter[3] = { }; static void -initdummytimecounter(dummy) - void *dummy; +initdummytimecounter(void *dummy) { init_timecounter(dummy_timecounter); } diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 1b034cac5797..004a446ca3bb 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_resource.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_resource.c,v 1.32 1998/02/09 06:09:24 eivind Exp $ + * $Id: kern_resource.c,v 1.33 1998/03/04 10:25:52 dufault Exp $ */ #include "opt_compat.h" @@ -491,6 +491,7 @@ calcru(p, up, sp, ip) int s; struct timeval tv; + /* XXX: why spl-protect ? worst case is an off-by-one report */ s = splstatclock(); st = p->p_sticks; ut = p->p_uticks; @@ -505,23 +506,25 @@ calcru(p, up, sp, ip) sec = p->p_rtime.tv_sec; usec = p->p_rtime.tv_usec; - if (p == curproc) { /* XXX what if it's running on another cpu?? */ +#ifdef SMP + if (p->p_oncpu != 0xff) { +#else + if (p == curproc) { +#endif /* * Adjust for the current time slice. This is actually fairly * important since the error here is on the order of a time * quantum, which is much greater than the sampling error. */ - microtime(&tv); - sec += tv.tv_sec - runtime.tv_sec; - usec += tv.tv_usec - runtime.tv_usec; + microruntime(&tv); + sec += tv.tv_sec - p->p_runtime.tv_sec; + usec += tv.tv_usec - p->p_runtime.tv_usec; } totusec = (quad_t)sec * 1000000 + usec; if (totusec < 0) { -#ifndef SMP /* sigh, microtime and fork/exit madness here */ /* XXX no %qd in kernel. Truncate. */ printf("calcru: negative time of %ld usec for pid %d (%s)\n", (long)totusec, p->p_pid, p->p_comm); -#endif totusec = 0; } u = totusec; diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index c2f7eb06a389..4499554a1686 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 - * $Id: kern_synch.c,v 1.52 1998/03/28 11:49:55 dufault Exp $ + * $Id: kern_synch.c,v 1.53 1998/03/28 18:16:29 dufault Exp $ */ #include "opt_ktrace.h" @@ -621,9 +621,9 @@ mi_switch() * Compute the amount of time during which the current * process was running, and add that to its total so far. */ - microtime(&tv); - u = p->p_rtime.tv_usec + (tv.tv_usec - runtime.tv_usec); - s = p->p_rtime.tv_sec + (tv.tv_sec - runtime.tv_sec); + microruntime(&tv); + u = p->p_rtime.tv_usec + (tv.tv_usec - p->p_runtime.tv_usec); + s = p->p_rtime.tv_sec + (tv.tv_sec - p->p_runtime.tv_sec); if (u < 0) { u += 1000000; s--; @@ -660,7 +660,7 @@ mi_switch() */ cnt.v_swtch++; cpu_switch(p); - microtime(&runtime); + microruntime(&p->p_runtime); splx(x); } diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index e3fb79847465..cf25a4671855 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -39,7 +39,7 @@ static volatile int print_tci = 1; * SUCH DAMAGE. * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_clock.c,v 1.61 1998/03/31 10:44:56 phk Exp $ + * $Id: kern_clock.c,v 1.62 1998/03/31 10:47:01 phk Exp $ */ #include @@ -138,8 +138,6 @@ int ticks; static int psdiv, pscnt; /* prof => stat divider */ int psratio; /* ratio: prof / stat */ -volatile struct timeval mono_time; - /* * Initialize clock frequencies and start both clocks running. */ @@ -232,7 +230,6 @@ tvtohz(tv) { register unsigned long ticks; register long sec, usec; - int s; /* * If the number of usecs in the whole seconds part of the time @@ -292,7 +289,6 @@ int hzto(tv) struct timeval *tv; { - register long sec, usec; struct timeval t2; getmicrotime(&t2); @@ -511,13 +507,72 @@ getmicrotime(struct timeval *tvp) { struct timecounter *tc; + tc = timecounter; + *tvp = tc->microtime; +} + +void +getnanotime(struct timespec *tsp) +{ + struct timecounter *tc; + + tc = timecounter; + *tsp = tc->nanotime; +} + +void +microtime(struct timeval *tv) +{ + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + tv->tv_usec = tc->offset_micro; + tv->tv_usec += + ((u_int64_t)tc->get_timedelta(tc) * tc->scale_micro) >> 32; + tv->tv_usec += boottime.tv_usec; + tv->tv_sec += boottime.tv_sec; + if (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } +} + +void +nanotime(struct timespec *tv) +{ + u_int count; + u_int64_t delta; + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + count = tc->get_timedelta(tc); + delta = tc->offset_nano; + delta += ((u_int64_t)count * tc->scale_nano_f); + delta >>= 32; + delta += ((u_int64_t)count * tc->scale_nano_i); + delta += boottime.tv_usec * 1000; + tv->tv_sec += boottime.tv_sec; + if (delta >= 1000000000) { + delta -= 1000000000; + tv->tv_sec++; + } + tv->tv_nsec = delta; +} + +void +getmicroruntime(struct timeval *tvp) +{ + struct timecounter *tc; + tc = timecounter; tvp->tv_sec = tc->offset_sec; tvp->tv_usec = tc->offset_micro; } void -getnanotime(struct timespec *tsp) +getnanoruntime(struct timespec *tsp) { struct timecounter *tc; @@ -527,7 +582,7 @@ getnanotime(struct timespec *tsp) } void -microtime(struct timeval *tv) +microruntime(struct timeval *tv) { struct timecounter *tc; @@ -543,7 +598,7 @@ microtime(struct timeval *tv) } void -nanotime(struct timespec *tv) +nanoruntime(struct timespec *tv) { u_int count; u_int64_t delta; @@ -601,7 +656,7 @@ init_timecounter(struct timecounter *tc) tc[2] = tc[1] = tc[0]; tc[1].other = &tc[2]; tc[2].other = &tc[1]; - if (!timecounter) + if (!timecounter || !strcmp(timecounter->name, "dummy")) timecounter = &tc[2]; tc = &tc[1]; @@ -634,27 +689,21 @@ init_timecounter(struct timecounter *tc) void set_timecounter(struct timespec *ts) { - struct timecounter *tc, *tco; - int s; + struct timespec ts2; - /* - * XXX we must be called at splclock() to preven *ts becoming - * invalid, so there is no point in spls here. - */ - s = splclock(); - tc = timecounter->other; - tco = tc->other; - *tc = *timecounter; - tc->other = tco; - tc->offset_sec = ts->tv_sec; - tc->offset_nano = (u_int64_t)ts->tv_nsec << 32; - tc->offset_micro = ts->tv_nsec / 1000; - tc->offset_count = tc->get_timecount(); - time_second = tc->offset_sec; - timecounter = tc; - splx(s); + nanoruntime(&ts2); + boottime.tv_sec = ts->tv_sec - ts2.tv_sec; + boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000; + if (boottime.tv_usec < 0) { + boottime.tv_usec += 1000000; + boottime.tv_sec--; + } + /* fiddle all the little crinkly bits around the fiords... */ + tco_forward(); } + +#if 0 /* Currently unused */ void switch_timecounter(struct timecounter *newtc) { @@ -676,6 +725,7 @@ switch_timecounter(struct timecounter *newtc) timecounter = newtc; splx(s); } +#endif static struct timecounter * sync_other_counter(void) @@ -703,14 +753,8 @@ tco_forward(void) tc = sync_other_counter(); if (timedelta != 0) { tc->offset_nano += (u_int64_t)(tickdelta * 1000) << 32; - mono_time.tv_usec += tickdelta; timedelta -= tickdelta; } - mono_time.tv_usec += tick; - if (mono_time.tv_usec >= 1000000) { - mono_time.tv_usec -= 1000000; - mono_time.tv_sec++; - } if (tc->offset_nano >= 1000000000ULL << 32) { tc->offset_nano -= 1000000000ULL << 32; @@ -723,7 +767,17 @@ tco_forward(void) tc->offset_micro = (tc->offset_nano / 1000) >> 32; - time_second = tc->offset_sec; + /* Figure out the wall-clock time */ + tc->nanotime.tv_sec = tc->offset_sec + boottime.tv_sec; + tc->nanotime.tv_nsec = (tc->offset_nano >> 32) + boottime.tv_usec * 1000; + tc->microtime.tv_usec = tc->offset_micro + boottime.tv_usec; + if (tc->nanotime.tv_nsec > 1000000000) { + tc->nanotime.tv_nsec -= 1000000000; + tc->microtime.tv_usec -= 1000000; + tc->nanotime.tv_sec++; + } + time_second = tc->microtime.tv_sec = tc->nanotime.tv_sec; + timecounter = tc; } @@ -775,8 +829,7 @@ static struct timecounter dummy_timecounter[3] = { }; static void -initdummytimecounter(dummy) - void *dummy; +initdummytimecounter(void *dummy) { init_timecounter(dummy_timecounter); } diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index f0897d72b28c..786f67f3fcbf 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 - * $Id: kern_time.c,v 1.43 1998/03/26 20:51:41 phk Exp $ + * $Id: kern_time.c,v 1.44 1998/03/30 09:50:23 phk Exp $ */ #include @@ -84,9 +84,8 @@ settime(tv) s = splclock(); microtime(&tv1); - delta.tv_sec = tv->tv_sec - tv1.tv_sec; - delta.tv_usec = tv->tv_usec - tv1.tv_usec; - timevalfix(&delta); + delta = *tv; + timevalsub(&delta, &tv1); /* * If the system is secure, we do not allow the time to be @@ -103,13 +102,9 @@ settime(tv) ts.tv_nsec = tv->tv_usec * 1000; set_timecounter(&ts); (void) splsoftclock(); - timevaladd(&boottime, &delta); - timevaladd(&runtime, &delta); for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { if (timerisset(&p->p_realtimer.it_value)) timevaladd(&p->p_realtimer.it_value, &delta); - if (p->p_sleepend) - timevaladd(p->p_sleepend, &delta); } lease_updatetime(delta.tv_sec); splx(s); @@ -203,69 +198,44 @@ nanosleep1(p, rqt, rmt) struct proc *p; struct timespec *rqt, *rmt; { - struct timeval atv, utv, rtv; - int error, s, timo, i, n; + struct timespec ts, ts2; + int error, timo; if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) return (EINVAL); if (rqt->tv_sec < 0 || rqt->tv_sec == 0 && rqt->tv_nsec == 0) return (0); - TIMESPEC_TO_TIMEVAL(&atv, rqt) - if (itimerfix(&atv)) { - n = atv.tv_sec / 100000000; - rtv = atv; - rtv.tv_sec %= 100000000; - (void)itimerfix(&rtv); - } else - n = 0; - - for (i = 0, error = EWOULDBLOCK; i <= n && error == EWOULDBLOCK; i++) { - if (n > 0) { - if (i == n) - atv = rtv; - else { - atv.tv_sec = 100000000; - atv.tv_usec = 0; - } + getnanoruntime(&ts); + timespecadd(&ts, rqt); + error = 0; + while (1) { + getnanoruntime(&ts2); + if (timespeccmp(&ts2, &ts, >=)) + break; + else if (ts2.tv_sec + 60 * 60 * 24 * hz < ts.tv_sec) + timo = 60 * 60 * 24 * hz; + else if (ts2.tv_sec + 2 < ts.tv_sec) { + /* Leave one second for the difference in tv_nsec */ + timo = ts.tv_sec - ts2.tv_sec - 1; + timo *= hz; + } else { + timo = (ts.tv_sec - ts2.tv_sec) * 1000000000; + timo += ts.tv_nsec - ts2.tv_nsec; + timo /= (1000000000 / hz); + timo ++; } - timo = tvtohz(&atv); - - p->p_sleepend = &atv; error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp", timo); - p->p_sleepend = NULL; - if (error == ERESTART) + if (error == ERESTART) { error = EINTR; - if (rmt != NULL && (i == n || error != EWOULDBLOCK)) { - /*- - * XXX this is unnecessary and possibly wrong if the timeout - * expired. Then the remaining time should be zero. If the - * calculation gives a nonzero value, then we have a bug. - * (1) if settimeofday() was called, then the calculation is - * probably wrong, since `time' has probably become - * inconsistent with the ending time `atv'. - * XXX (1) should be fixed now with p->p_sleepend; - * (2) otherwise, our calculation of `timo' was wrong, perhaps - * due to `tick' being wrong when hzto() was called or - * changing afterwards (it can be wrong or change due to - * hzto() not knowing about adjtime(2) or tickadj(8)). - * Then we should be sleeping again instead instead of - * returning. Rounding up in hzto() probably fixes this - * problem for small timeouts, but the absolute error may - * be large for large timeouts. - */ - getmicrotime(&utv); - if (i != n) { - atv.tv_sec += (n - i - 1) * 100000000; - timevaladd(&atv, &rtv); - } - timevalsub(&atv, &utv); - if (atv.tv_sec < 0) - timerclear(&atv); - TIMEVAL_TO_TIMESPEC(&atv, rmt); + break; } } - return (error == EWOULDBLOCK ? 0 : error); + if (rmt) { + *rmt = ts; + timespecsub(rmt, &ts2); + } + return(error); } #ifndef _SYS_SYSPROTO_H_ diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index fb0034f63f30..ee056f0bc710 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 - * $Id: sys_generic.c,v 1.34 1998/03/30 09:50:29 phk Exp $ + * $Id: sys_generic.c,v 1.35 1998/04/02 07:22:17 phk Exp $ */ #include "opt_ktrace.h" @@ -538,8 +538,8 @@ select(p, uap) */ fd_mask s_selbits[howmany(2048, NFDBITS)]; fd_mask *ibits[3], *obits[3], *selbits, *sbp; - struct timeval atv; - int s, ncoll, error, timo, term; + struct timeval atv, rtv, ttv; + int s, ncoll, error, timo; u_int nbufbytes, ncpbytes, nfdbits; if (uap->nd < 0) @@ -600,21 +600,29 @@ select(p, uap) error = EINVAL; goto done; } - term = ticks + tvtohz(&atv); - } else - term = 0; + getmicroruntime(&rtv); + timevaladd(&atv, &rtv); + } else { + atv.tv_sec = 0; + atv.tv_usec = 0; + } + timo = 0; retry: ncoll = nselcoll; p->p_flag |= P_SELECT; error = selscan(p, ibits, obits, uap->nd); if (error || p->p_retval[0]) goto done; - s = splhigh(); - if (term && term <= ticks) { - splx(s); - goto done; + if (atv.tv_sec) { + getmicroruntime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + goto done; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); } - timo = term ? term - ticks : 0; + s = splhigh(); if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { splx(s); goto retry; @@ -701,8 +709,8 @@ poll(p, uap) { caddr_t bits; char smallbits[32 * sizeof(struct pollfd)]; - struct timeval atv; - int s, ncoll, error = 0, timo, term; + struct timeval atv, rtv, ttv; + int s, ncoll, error = 0, timo; size_t ni; if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) { @@ -724,21 +732,29 @@ poll(p, uap) error = EINVAL; goto done; } - term = ticks + tvtohz(&atv); - } else - term = 0; + getmicroruntime(&rtv); + timevaladd(&atv, &rtv); + } else { + atv.tv_sec = 0; + atv.tv_usec = 0; + } + timo = 0; retry: ncoll = nselcoll; p->p_flag |= P_SELECT; error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds)); if (error || p->p_retval[0]) goto done; + if (atv.tv_sec) { + getmicroruntime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + goto done; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); + } s = splhigh(); - if (term && term <= ticks) { - splx(s); - goto done; - } - timo = term ? term - ticks : 0; if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { splx(s); goto retry; diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 997442dc1d5f..47df800c71eb 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.30 1997/09/07 16:53:48 bde Exp $ + * $Id: uipc_socket2.c,v 1.31 1998/03/01 19:39:19 guido Exp $ */ #include @@ -157,13 +157,14 @@ sodropablereq(head) { register struct socket *so; unsigned int i, j, qlen; - static int rnd; - static long old_mono_secs; + static struct timeval old_runtime; static unsigned int cur_cnt, old_cnt; + struct timeval tv; - if ((i = (mono_time.tv_sec - old_mono_secs)) != 0) { - old_mono_secs = mono_time.tv_sec; + getmicroruntime(&tv); + if ((i = (tv.tv_sec - old_runtime.tv_sec)) != 0) { + old_runtime = tv; old_cnt = cur_cnt / i; cur_cnt = 0; } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 997442dc1d5f..47df800c71eb 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.30 1997/09/07 16:53:48 bde Exp $ + * $Id: uipc_socket2.c,v 1.31 1998/03/01 19:39:19 guido Exp $ */ #include @@ -157,13 +157,14 @@ sodropablereq(head) { register struct socket *so; unsigned int i, j, qlen; - static int rnd; - static long old_mono_secs; + static struct timeval old_runtime; static unsigned int cur_cnt, old_cnt; + struct timeval tv; - if ((i = (mono_time.tv_sec - old_mono_secs)) != 0) { - old_mono_secs = mono_time.tv_sec; + getmicroruntime(&tv); + if ((i = (tv.tv_sec - old_runtime.tv_sec)) != 0) { + old_runtime = tv; old_cnt = cur_cnt / i; cur_cnt = 0; } diff --git a/sys/msdosfs/msdosfs_denode.c b/sys/msdosfs/msdosfs_denode.c index 6c4513d813c6..65dfabb6e461 100644 --- a/sys/msdosfs/msdosfs_denode.c +++ b/sys/msdosfs/msdosfs_denode.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_denode.c,v 1.33 1998/03/20 02:33:35 kato Exp $ */ +/* $Id: msdosfs_denode.c,v 1.34 1998/03/26 20:52:51 phk Exp $ */ /* $NetBSD: msdosfs_denode.c,v 1.28 1998/02/10 14:10:00 mrg Exp $ */ /*- @@ -198,6 +198,7 @@ deget(pmp, dirclust, diroffset, depp) struct vnode *nvp; struct buf *bp; struct proc *p = curproc; /* XXX */ + struct timeval tv; #ifdef MSDOSFS_DEBUG printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n", @@ -345,8 +346,9 @@ deget(pmp, dirclust, diroffset, depp) } } else nvp->v_type = VREG; - SETHIGH(ldep->de_modrev, mono_time.tv_sec); - SETLOW(ldep->de_modrev, mono_time.tv_usec * 4294); + getmicroruntime(&tv); + SETHIGH(ldep->de_modrev, tv.tv_sec); + SETLOW(ldep->de_modrev, tv.tv_usec * 4294); VREF(ldep->de_devvp); *depp = ldep; return (0); diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 0f890cbc13d5..74310e31859f 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -17,7 +17,7 @@ * * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 * - * $Id: if_spppsubr.c,v 1.34 1998/03/01 06:01:33 bde Exp $ + * $Id: if_spppsubr.c,v 1.35 1998/03/30 09:52:06 phk Exp $ */ #include "opt_inet.h" @@ -1018,8 +1018,10 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2) struct ppp_header *h; struct cisco_packet *ch; struct mbuf *m; - u_long t = (time_second - boottime.tv_sec) * 1000; + struct timeval tv; + getmicroruntime(&tv); + MGETHDR (m, M_DONTWAIT, MT_DATA); if (! m) return; @@ -1036,8 +1038,8 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2) ch->par1 = htonl (par1); ch->par2 = htonl (par2); ch->rel = -1; - ch->time0 = htons ((u_short) (t >> 16)); - ch->time1 = htons ((u_short) t); + ch->time0 = htons ((u_short) (tv.tv_sec >> 16)); + ch->time1 = htons ((u_short) tv.tv_sec); if (debug) log(LOG_DEBUG, diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index e5c14f6b0c6e..dddd5fc0bfc2 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)kernel.h 8.3 (Berkeley) 1/21/94 - * $Id: kernel.h,v 1.36 1997/12/12 04:00:47 dyson Exp $ + * $Id: kernel.h,v 1.37 1998/03/28 11:50:35 dufault Exp $ */ #ifndef _SYS_KERNEL_H_ @@ -58,11 +58,8 @@ extern int domainnamelen; extern char kernelname[MAXPATHLEN]; /* 1.2 */ -extern volatile struct timeval mono_time; extern struct timeval boottime; -extern struct timeval runtime; -extern struct timeval time; /* nonvolatile at ipl >= splclock() */ extern struct timezone tz; /* XXX */ extern int tick; /* usec per tick (1000000 / hz) */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 1b58ebd1a9e4..40460b623897 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)proc.h 8.15 (Berkeley) 5/19/95 - * $Id: proc.h,v 1.55 1998/03/04 10:26:37 dufault Exp $ + * $Id: proc.h,v 1.56 1998/03/28 10:33:23 bde Exp $ */ #ifndef _SYS_PROC_H_ @@ -135,10 +135,10 @@ struct proc { struct itimerval p_realtimer; /* Alarm timer. */ struct timeval p_rtime; /* Real time. */ + struct timeval p_runtime; /* When last scheduled */ u_quad_t p_uticks; /* Statclock hits in user mode. */ u_quad_t p_sticks; /* Statclock hits in system mode. */ u_quad_t p_iticks; /* Statclock hits processing intr. */ - struct timeval *p_sleepend; /* Wake time for nanosleep & friends */ int p_traceflag; /* Kernel trace points. */ struct vnode *p_tracep; /* Trace to vnode. */ diff --git a/sys/sys/time.h b/sys/sys/time.h index 30b1b4cd3bf3..6d5a80336cd5 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)time.h 8.5 (Berkeley) 5/4/95 - * $Id: time.h,v 1.21 1998/03/26 20:53:36 phk Exp $ + * $Id: time.h,v 1.22 1998/03/30 09:55:35 phk Exp $ */ #ifndef _SYS_TIME_H_ @@ -149,10 +149,45 @@ struct timecounter { u_int32_t offset_sec; u_int32_t offset_micro; u_int64_t offset_nano; + struct timeval microtime; + struct timespec nanotime; struct timecounter *other; struct timecounter *tweak; }; +#ifdef KERNEL +/* Operations on timespecs */ +#define timespecclear(tvp) (tvp)->tv_sec = (tvp)->tv_nsec = 0 +#define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) +#define timespeccmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timespecadd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_nsec += (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec >= 1000000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_nsec -= 1000000000; \ + } \ + } while (0) +#define timespecsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_nsec -= (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_nsec += 1000000000; \ + } \ + } while (0) +/* Operations on timevals. */ +#define timevalcmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#endif /* KERNEL */ + /* Operations on timevals. */ #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) @@ -224,14 +259,17 @@ extern struct timecounter *timecounter; extern time_t time_second; void forward_timecounter __P((void)); +void getmicroruntime __P((struct timeval *tv)); void getmicrotime __P((struct timeval *tv)); +void getnanoruntime __P((struct timespec *tv)); void getnanotime __P((struct timespec *tv)); void init_timecounter __P((struct timecounter *tc)); -int itimerfix __P((struct timeval *tv)); int itimerdecr __P((struct itimerval *itp, int usec)); +int itimerfix __P((struct timeval *tv)); +void microruntime __P((struct timeval *tv)); void microtime __P((struct timeval *tv)); +void nanoruntime __P((struct timespec *ts)); void nanotime __P((struct timespec *ts)); -void second_overflow __P((u_int32_t *psec)); void set_timecounter __P((struct timespec *ts)); void timevaladd __P((struct timeval *, struct timeval *)); void timevalsub __P((struct timeval *, struct timeval *)); diff --git a/sys/sys/timetc.h b/sys/sys/timetc.h index 30b1b4cd3bf3..6d5a80336cd5 100644 --- a/sys/sys/timetc.h +++ b/sys/sys/timetc.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)time.h 8.5 (Berkeley) 5/4/95 - * $Id: time.h,v 1.21 1998/03/26 20:53:36 phk Exp $ + * $Id: time.h,v 1.22 1998/03/30 09:55:35 phk Exp $ */ #ifndef _SYS_TIME_H_ @@ -149,10 +149,45 @@ struct timecounter { u_int32_t offset_sec; u_int32_t offset_micro; u_int64_t offset_nano; + struct timeval microtime; + struct timespec nanotime; struct timecounter *other; struct timecounter *tweak; }; +#ifdef KERNEL +/* Operations on timespecs */ +#define timespecclear(tvp) (tvp)->tv_sec = (tvp)->tv_nsec = 0 +#define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) +#define timespeccmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timespecadd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_nsec += (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec >= 1000000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_nsec -= 1000000000; \ + } \ + } while (0) +#define timespecsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_nsec -= (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_nsec += 1000000000; \ + } \ + } while (0) +/* Operations on timevals. */ +#define timevalcmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#endif /* KERNEL */ + /* Operations on timevals. */ #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) @@ -224,14 +259,17 @@ extern struct timecounter *timecounter; extern time_t time_second; void forward_timecounter __P((void)); +void getmicroruntime __P((struct timeval *tv)); void getmicrotime __P((struct timeval *tv)); +void getnanoruntime __P((struct timespec *tv)); void getnanotime __P((struct timespec *tv)); void init_timecounter __P((struct timecounter *tc)); -int itimerfix __P((struct timeval *tv)); int itimerdecr __P((struct itimerval *itp, int usec)); +int itimerfix __P((struct timeval *tv)); +void microruntime __P((struct timeval *tv)); void microtime __P((struct timeval *tv)); +void nanoruntime __P((struct timespec *ts)); void nanotime __P((struct timespec *ts)); -void second_overflow __P((u_int32_t *psec)); void set_timecounter __P((struct timespec *ts)); void timevaladd __P((struct timeval *, struct timeval *)); void timevalsub __P((struct timeval *, struct timeval *)); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 30042b7d87ba..5ab71a5df3bf 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 - * $Id: ufs_vnops.c,v 1.80 1998/03/26 20:54:05 phk Exp $ + * $Id: ufs_vnops.c,v 1.81 1998/03/30 09:56:37 phk Exp $ */ #include "opt_quota.h" @@ -1965,6 +1965,7 @@ ufs_vinit(mntp, specops, fifoops, vpp) { struct inode *ip; struct vnode *vp, *nvp; + struct timeval tv; vp = *vpp; ip = VTOI(vp); @@ -2003,8 +2004,9 @@ ufs_vinit(mntp, specops, fifoops, vpp) /* * Initialize modrev times */ - SETHIGH(ip->i_modrev, mono_time.tv_sec); - SETLOW(ip->i_modrev, mono_time.tv_usec * 4294); + getmicroruntime(&tv); + SETHIGH(ip->i_modrev, tv.tv_sec); + SETLOW(ip->i_modrev, tv.tv_usec * 4294); *vpp = vp; return (0); }