diff options
author | David Leonard <d@cvs.openbsd.org> | 1999-11-25 07:01:48 +0000 |
---|---|---|
committer | David Leonard <d@cvs.openbsd.org> | 1999-11-25 07:01:48 +0000 |
commit | 0fe78c3128864d128b2b10153b8d533ff8c00375 (patch) | |
tree | 5229c3d97eed15f4d71927a5f454180aef2632f6 /lib/libpthread/uthread/uthread_nanosleep.c | |
parent | ed00fa742a6455d22e3b56cf846dc5acd7a51fd7 (diff) |
sync with FreeBSD
Diffstat (limited to 'lib/libpthread/uthread/uthread_nanosleep.c')
-rw-r--r-- | lib/libpthread/uthread/uthread_nanosleep.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/lib/libpthread/uthread/uthread_nanosleep.c b/lib/libpthread/uthread/uthread_nanosleep.c index 4e182adfb6c..583e94e983f 100644 --- a/lib/libpthread/uthread/uthread_nanosleep.c +++ b/lib/libpthread/uthread/uthread_nanosleep.c @@ -1,3 +1,4 @@ +/* $OpenBSD: uthread_nanosleep.c,v 1.5 1999/11/25 07:01:40 d Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -20,7 +21,7 @@ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_nanosleep.c,v 1.4 1999/06/09 07:16:17 d Exp $ + * $FreeBSD: uthread_nanosleep.c,v 1.10 1999/08/28 00:03:41 peter Exp $ */ #include <stdio.h> #include <errno.h> @@ -42,9 +43,8 @@ nanosleep(const struct timespec * time_to_sleep, struct timespec * time_remaining) { int ret = 0; - struct timespec start_time; - struct timespec wakeup_time; struct timespec current_time; + struct timespec current_time1; struct timespec remaining_time; struct timeval tv; @@ -52,20 +52,26 @@ nanosleep(const struct timespec * time_to_sleep, _thread_enter_cancellation_point(); /* Check if the time to sleep is legal: */ - if (time_to_sleep == NULL || time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec > 1000000000 || time_to_sleep->tv_sec < 0) { + if (time_to_sleep == NULL || time_to_sleep->tv_sec < 0 || + time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec >= 1000000000) { /* Return an EINVAL error : */ errno = EINVAL; ret = -1; } else { /* Get the current time: */ gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, &start_time); + TIMEVAL_TO_TIMESPEC(&tv, ¤t_time); /* Calculate the time for the current thread to wake up: */ - timespecadd(time_to_sleep, &start_time, &wakeup_time); + _thread_run->wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec; + _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec; - _thread_run->wakeup_time.tv_sec = wakeup_time.tv_sec; - _thread_run->wakeup_time.tv_nsec = wakeup_time.tv_nsec; + /* Check if the nanosecond field has overflowed: */ + if (_thread_run->wakeup_time.tv_nsec >= 1000000000) { + /* Wrap the nanosecond field: */ + _thread_run->wakeup_time.tv_sec += 1; + _thread_run->wakeup_time.tv_nsec -= 1000000000; + } _thread_run->interrupted = 0; /* Reschedule the current thread to sleep: */ @@ -73,15 +79,31 @@ nanosleep(const struct timespec * time_to_sleep, /* Get the current time: */ gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, ¤t_time); + TIMEVAL_TO_TIMESPEC(&tv, ¤t_time1); /* Calculate the remaining time to sleep: */ - timespecsub(&wakeup_time, ¤t_time, &remaining_time); + remaining_time.tv_sec = time_to_sleep->tv_sec + current_time.tv_sec - current_time1.tv_sec; + remaining_time.tv_nsec = time_to_sleep->tv_nsec + current_time.tv_nsec - current_time1.tv_nsec; + + /* Check if the nanosecond field has underflowed: */ + if (remaining_time.tv_nsec < 0) { + /* Handle the underflow: */ + remaining_time.tv_sec -= 1; + remaining_time.tv_nsec += 1000000000; + } + + /* Check if the nanosecond field has overflowed: */ + if (remaining_time.tv_nsec >= 1000000000) { + /* Handle the overflow: */ + remaining_time.tv_sec += 1; + remaining_time.tv_nsec -= 1000000000; + } /* Check if the sleep was longer than the required time: */ if (remaining_time.tv_sec < 0) { /* Reset the time left: */ - timespecclear(&remaining_time); + remaining_time.tv_sec = 0; + remaining_time.tv_nsec = 0; } /* Check if the time remaining is to be returned: */ |