linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* tiny patch for sys_time() and sys_stime()
@ 2003-05-01 12:09 Urs Thuermann
  0 siblings, 0 replies; only message in thread
From: Urs Thuermann @ 2003-05-01 12:09 UTC (permalink / raw)
  To: linux-kernel

A couple of years ago, when some 2.0.x kernel was current, I did a
patch for the time() and stime() system call, which I also sent for
inclusion, AFAIR to LKML.  However I didn't get any response to it.

Now I see that the patch went partially in, i.e. for the sys_time()
syscall but not sys_stime().

These syscalls were implemented as they are still in 2.0.40-rc6 and
2.2.25 like this


    asmlinkage int sys_time(int * tloc)
    {
    	    int i;
    
    	    /* SMP: This is fairly trivial. We grab CURRENT_TIME and 
    	       stuff it to user space. No side effects */
    	    i = CURRENT_TIME;
    	    if (tloc) {
    		    if (put_user(i,tloc))
    			    i = -EFAULT;
    	    }
    	    return i;
    }

where CURRENT_TIME is defined as xtime.tv_sec and
    
    asmlinkage int sys_stime(int * tptr)
    {
    	    int value;
    
    	    if (!capable(CAP_SYS_TIME))
    		    return -EPERM;
    	    if (get_user(value, tptr))
    		    return -EFAULT;
    	    write_lock_irq(&xtime_lock);
    	    xtime.tv_sec = value;
    	    xtime.tv_usec = 0;
    	    time_adjust = 0;	/* stop active adjtime() */
    	    time_status |= STA_UNSYNC;
    	    time_maxerror = NTP_PHASE_LIMIT;
    	    time_esterror = NTP_PHASE_LIMIT;
    	    write_unlock_irq(&xtime_lock);
    	    return 0;
    }

Both calls do not take into account the hardware timer, which may
cause the time read or set to be offset by almost one tick.
sys_settimeofday() and sys_gettimeofday() do take into account the
value of the hardware timer (i8254 or tsc on x86).

My patch was to make sys_time() and sys_stime() to be just wrappers to
do_gettimeofday() and do_settimeofday().  In 2.4.17 this was done
for sys_time() but not sys_stime().  In 2.5.x the macro CURRENT_TIME
was replaced by an inline function get_seconds() which also only does
return the value of xtime.tv_sec.

I append patches for 2.0.40-rc6, 2.2.25, 2.4.20-rc1 and 2.5.68 which
make both, sys_time() and sys_stime() just wrappers for the
do_{get,set}timeofday() calls.  This looks cleaner, eliminates a small
amount of code duplication of code already present in
do_{get,set}timeofday, and it reduces the possibility of overseeing
necessary changes, like the call to clock_was_set() in the 2.5.x
version of do_settimeofday() for some architectures.

For 2.5.x and 2.6 kernels I'd actually like too see these calls
eliminated completely, as is the case for alpha and ia64 already.


urs


diff -ru linux-2.0.40-rc6/kernel/time.c linux-2.0.40-rc6-ut/kernel/time.c
--- linux-2.0.40-rc6/kernel/time.c	1998-06-04 00:17:50.000000000 +0200
+++ linux-2.0.40-rc6-ut/kernel/time.c	2003-04-04 20:14:48.000000000 +0200
@@ -52,9 +52,11 @@
  */
 asmlinkage int sys_time(int * tloc)
 {
+	struct timeval now;
 	int i;
 
-	i = CURRENT_TIME;
+	do_gettimeofday(&now);
+	i = now.tv_sec;
 	if (tloc) {
 		int error = verify_area(VERIFY_WRITE, tloc, sizeof(*tloc));
 		if (error)
@@ -73,6 +75,7 @@
 asmlinkage int sys_stime(int * tptr)
 {
 	int error, value;
+	struct timeval new_tv;
 
 	if (!suser())
 		return -EPERM;
@@ -80,15 +83,9 @@
 	if (error)
 		return error;
 	value = get_user(tptr);
-	cli();
-	xtime.tv_sec = value;
-	xtime.tv_usec = 0;
-	time_adjust = 0;	/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_state = TIME_ERROR;	/* p. 24, (a) */
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	sti();
+	new_tv.tv_sec  = value;
+	new_tv.tv_usec = 0;
+	do_settimeofday(&new_tv);
 	return 0;
 }
 





diff -ru linux-2.2.25/kernel/time.c linux-2.2.25-ut/kernel/time.c
--- linux-2.2.25/kernel/time.c	2001-03-25 18:31:02.000000000 +0200
+++ linux-2.2.25-ut/kernel/time.c	2003-04-04 18:18:17.000000000 +0200
@@ -73,11 +73,11 @@
  */
 asmlinkage int sys_time(int * tloc)
 {
+	struct timeval now;
 	int i;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
-	   stuff it to user space. No side effects */
-	i = CURRENT_TIME;
+	do_gettimeofday(&now);
+	i = now.tv_sec;
 	if (tloc) {
 		if (put_user(i,tloc))
 			i = -EFAULT;
@@ -95,19 +95,15 @@
 asmlinkage int sys_stime(int * tptr)
 {
 	int value;
+	struct timeval new_tv;
 
 	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
-	write_lock_irq(&xtime_lock);
-	xtime.tv_sec = value;
-	xtime.tv_usec = 0;
-	time_adjust = 0;	/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	new_tv.tv_sec  = value;
+	new_tv.tv_usec = 0;
+	do_settimeofday(&new_tv);
 	return 0;
 }
 





diff -ru linux-2.4.20-rc1/kernel/time.c linux-2.4.20-rc1-ut/kernel/time.c
--- linux-2.4.20-rc1/kernel/time.c	2003-04-04 17:41:41.000000000 +0200
+++ linux-2.4.20-rc1-ut/kernel/time.c	2003-04-04 20:39:14.000000000 +0200
@@ -74,21 +74,15 @@
 asmlinkage long sys_stime(int * tptr)
 {
 	int value;
+	struct timeval new_tv;
 
 	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
-	write_lock_irq(&xtime_lock);
-	vxtime_lock();
-	xtime.tv_sec = value;
-	xtime.tv_usec = 0;
-	vxtime_unlock();
-	time_adjust = 0;	/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	new_tv.tv_sec  = value;
+	new_tv.tv_usec = 0;
+	do_settimeofday(&new_tv);
 	return 0;
 }
 





diff -ru linux-2.5.68/kernel/time.c linux-2.5.68-ut/kernel/time.c
--- linux-2.5.68/kernel/time.c	2003-05-01 12:26:40.000000000 +0200
+++ linux-2.5.68-ut/kernel/time.c	2003-05-01 12:29:10.000000000 +0200
@@ -49,11 +49,11 @@
  */
 asmlinkage long sys_time(int * tloc)
 {
+	struct timeval now; 
 	int i;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
-	   stuff it to user space. No side effects */
-	i = get_seconds();
+	do_gettimeofday(&now);
+	i = now.tv_sec;
 	if (tloc) {
 		if (put_user(i,tloc))
 			i = -EFAULT;
@@ -71,20 +71,15 @@
 asmlinkage long sys_stime(int * tptr)
 {
 	int value;
+	struct timeval new_tv;
 
 	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
-	write_seqlock_irq(&xtime_lock);
-	xtime.tv_sec = value;
-	xtime.tv_nsec = 0;
-	last_time_offset = 0;
-	time_adjust = 0;	/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	write_sequnlock_irq(&xtime_lock);
+	new_tv.tv_sec  = value;
+	new_tv.tv_usec = 0;
+	do_settimeofday(&new_tv);
 	return 0;
 }
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-05-01 11:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-01 12:09 tiny patch for sys_time() and sys_stime() Urs Thuermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).