From 7aff059fd0ff158d8126983d76f9198df5361c6a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 13 Dec 2013 07:57:13 -0600 Subject: [PATCH] Move sleep() and usleep() from sched/ to libc/unistd/. These functions now are simple wrappers for nanosleep(). Remove sleep() and usleep() from system calls; add nanosleep() to system calls --- ChangeLog | 6 ++ include/sys/syscall.h | 7 +- libc/unistd/Make.defs | 8 +- sched/sleep.c => libc/unistd/lib_sleep.c | 86 +++++++--------------- sched/usleep.c => libc/unistd/lib_usleep.c | 41 +++-------- sched/Makefile | 12 +-- sched/nanosleep.c | 10 +-- syscall/syscall.csv | 5 +- syscall/syscall_lookup.h | 5 +- syscall/syscall_stublookup.c | 3 +- 10 files changed, 68 insertions(+), 115 deletions(-) rename sched/sleep.c => libc/unistd/lib_sleep.c (73%) rename sched/usleep.c => libc/unistd/lib_usleep.c (84%) diff --git a/ChangeLog b/ChangeLog index e3bc66089b..99f0ce24c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6211,3 +6211,9 @@ * lbc/time/lib_strftime.c: Need null-termination on the the string generated by strftime(). From Max Holtzberg (2013-12-12). * sched/nanosleep.c and include/time.h: Add nanosleep() (2013-12-12). + * libc/unistd/lib_sleep.c and lib_usleep.c. Move sleep() and + usleep() from sched/sleep.c and usleep.c to libc/unistd. These + functions now just call nanosleep(). (2013-12-13). + * syscall/ and include/sys/syscall.h: Remove sleep and usleep + system calls. Add nanosleep system call (2013-12-13). + diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 24743679ad..58ed508bfd 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -162,9 +162,8 @@ # define SYS_sigsuspend (__SYS_signals+5) # define SYS_sigtimedwait (__SYS_signals+6) # define SYS_sigwaitinfo (__SYS_signals+7) -# define SYS_sleep (__SYS_signals+8) -# define SYS_usleep (__SYS_signals+9) -# define __SYS_clock (__SYS_signals+10) +# define SYS_nanosleep (__SYS_signals+8) +# define __SYS_clock (__SYS_signals+9) #else # define __SYS_clock __SYS_signals #endif @@ -206,7 +205,7 @@ # define CONFIG_NSOCKET_DESCRIPTORS 0 #endif -#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 +#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 # define SYS_close (__SYS_descriptors+0) # define SYS_ioctl (__SYS_descriptors+1) # define SYS_read (__SYS_descriptors+2) diff --git a/libc/unistd/Make.defs b/libc/unistd/Make.defs index ee3ac0fc93..69f371d8c0 100644 --- a/libc/unistd/Make.defs +++ b/libc/unistd/Make.defs @@ -39,14 +39,18 @@ CSRCS += lib_getopt.c lib_getoptargp.c lib_getoptindp.c lib_getoptoptp.c ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) ifneq ($(CONFIG_DISABLE_ENVIRON),y) -CSRCS += lib_chdir.c lib_getcwd.c +CSRCS += lib_chdir.c lib_getcwd.c endif ifeq ($(CONFIG_LIBC_EXECFUNCS),y) -CSRCS += lib_execl.c lib_execv.c lib_execsymtab.c +CSRCS += lib_execl.c lib_execv.c lib_execsymtab.c endif endif +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CSRCS += lib_sleep.c lib_usleep.c +endif + # Add the unistd directory to the build DEPPATH += --dep-path unistd diff --git a/sched/sleep.c b/libc/unistd/lib_sleep.c similarity index 73% rename from sched/sleep.c rename to libc/unistd/lib_sleep.c index 9b3b6d57fc..408077075f 100644 --- a/sched/sleep.c +++ b/libc/unistd/lib_sleep.c @@ -1,7 +1,7 @@ /**************************************************************************** - * sched/sleep.c + * lib/lib_sleep.c * - * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -108,10 +108,10 @@ * Implementations may place limitations on the granularity of timer values. * For each interval timer, if the requested timer value requires a finer * granularity than the implementation supports, the actual timer value will - * be rounded up to the next supported value. + * be rounded up to the next supported value. * * Interactions between sleep() and any of setitimer(), ualarm() or sleep() - * are unspecified. + * are unspecified. * * Parameters: * seconds @@ -128,69 +128,39 @@ unsigned int sleep(unsigned int seconds) { - sigset_t set; - struct timespec ts; - struct siginfo value; - irqstate_t flags; - uint32_t start; - int32_t elapsed; - int32_t remaining = 0; + struct timespec rqtp; + struct timespec rmtp; + unsigned int remaining = 0; + int ret; /* Don't sleep if seconds == 0 */ if (seconds) { - /* Set up for the sleep. Using the empty set means that we are not - * waiting for any particular signal. However, any unmasked signal - * can still awaken sigtimedwait(). + /* Let nanosleep() do all of the work. */ + + rqtp.tv_sec = seconds; + rqtp.tv_nsec = 0; + + ret = nanosleep(&rqtp, &rmtp); + + /* nanosleep() should only fail if it was interrupted by a signal, + * but we treat all errors the same, */ - (void)sigemptyset(&set); - ts.tv_sec = seconds; - ts.tv_nsec = 0; - - /* Interrupts are disabled around the following so that it is atomic */ - - flags = irqsave(); - - /* Get the current time then sleep for the requested time. - * sigtimedwait() cannot succeed. It should always return error with - * either (1) EAGAIN meaning that the timeout occurred, or (2) EINTR - * meaning that some other unblocked signal was caught. - */ - - start = clock_systimer(); - (void)sigtimedwait(&set, &value, &ts); - - /* Calculate the elapsed time (in clock ticks) when we wake up from the sleep. - * This is really only necessary if we were awakened from the sleep early - * due to the receipt of a signal. - */ - - elapsed = clock_systimer() - start; - irqrestore(flags); - - /* Get the remaining, un-waited seconds. Note that this calculation - * truncates the elapsed seconds in the division. We may have slept some - * fraction of a second longer than this! But if the calculation is less - * than the 'seconds', we certainly did not sleep for the complete - * requested interval. - */ - - remaining = (int32_t)seconds - elapsed / TICK_PER_SEC; - - /* Make sure that the elapsed time is non-negative (this should always - * be the case unless something exceptional happened while were we - * sleeping -- like the clock was reset or we went into a low power mode, - * OR if we had to wait a long time to run again after calling - * sigtimedwait() making 'elapsed' bigger than it should have been). - */ - - if (remaining < 0) + if (ret < 0) { - remaining = 0; + remaining = rmtp.tv_nsec; + if (remaining < seconds && rmtp.tv_nsec >= 500000000) + { + /* Round up */ + + remaining++; + } } + + return remaining; } - return (unsigned int)remaining; + return 0; } diff --git a/sched/usleep.c b/libc/unistd/lib_usleep.c similarity index 84% rename from sched/usleep.c rename to libc/unistd/lib_usleep.c index 893a420f4e..e48ae4267e 100644 --- a/sched/usleep.c +++ b/libc/unistd/lib_usleep.c @@ -1,7 +1,7 @@ /**************************************************************************** - * sched/usleep.c + * lib/lib_usleep.c * - * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -108,7 +108,7 @@ * Implementations may place limitations on the granularity of timer values. * For each interval timer, if the requested timer value requires a finer * granularity than the implementation supports, the actual timer value will - * be rounded up to the next supported value. + * be rounded up to the next supported value. * * Interactions between usleep() and any of the following are unspecified: * @@ -120,7 +120,7 @@ * * Returned Value: * On successful completion, usleep() returns 0. Otherwise, it returns -1 - * and sets errno to indicate the error. + * and sets errno to indicate the error. * * Assumptions: * @@ -128,40 +128,17 @@ int usleep(useconds_t usec) { - sigset_t set; - struct timespec ts; - struct siginfo value; - int errval; + struct timespec rqtp; int ret = 0; if (usec) { - /* Set up for the sleep. Using the empty set means that we are not - * waiting for any particular signal. However, any unmasked signal - * can still awaken sigtimedwait(). - */ + /* Let nanosleep() do all of the work. */ - (void)sigemptyset(&set); - ts.tv_sec = usec / 1000000; - ts.tv_nsec = (usec % 1000000) * 1000; + rqtp.tv_sec = usec / 1000000; + rqtp.tv_nsec = (usec % 1000000) * 1000; - /* usleep is a simple application of sigtimedwait. */ - - ret = sigtimedwait(&set, &value, &ts); - - /* sigtimedwait() cannot succeed. It should always return error with - * either (1) EAGAIN meaning that the timeout occurred, or (2) EINTR - * meaning that some other unblocked signal was caught. - */ - - errval = errno; - DEBUGASSERT(ret < 0 && (errval == EAGAIN || errval == EINTR)); - if (errval == EAGAIN) - { - /* The timeout "error" is the normal, successful result */ - - ret = 0; - } + ret = nanosleep(&rqtp, NULL); } return ret; diff --git a/sched/Makefile b/sched/Makefile index 60d280cb83..f815090718 100644 --- a/sched/Makefile +++ b/sched/Makefile @@ -35,7 +35,7 @@ -include $(TOPDIR)/Make.defs -ASRCS = +ASRCS = AOBJS = $(ASRCS:.S=$(OBJEXT)) MISC_SRCS = os_start.c os_bringup.c errno_getptr.c errno_get.c errno_set.c @@ -71,15 +71,15 @@ SCHED_SRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c SCHED_SRCS += sched_lock.c sched_unlock.c sched_lockcount.c sched_self.c ifeq ($(CONFIG_SCHED_ATEXIT),y) -SCHED_SRCS += atexit.c +SCHED_SRCS += atexit.c endif ifeq ($(CONFIG_SCHED_ONEXIT),y) -SCHED_SRCS += on_exit.c +SCHED_SRCS += on_exit.c endif ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -SCHED_SRCS += sched_reprioritize.c +SCHED_SRCS += sched_reprioritize.c endif ifeq ($(CONFIG_SCHED_WAITPID),y) @@ -96,7 +96,7 @@ GRP_SRCS += task_getgroup.c group_foreachchild.c group_killchildren.c ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) GRP_SRCS += task_reparent.c ifeq ($(CONFIG_SCHED_CHILD_STATUS),y) -GRP_SRCS += group_childstatus.c +GRP_SRCS += group_childstatus.c endif endif @@ -114,7 +114,7 @@ WDOG_SRCS += wd_gettime.c TIME_SRCS = sched_processtimer.c ifneq ($(CONFIG_DISABLE_SIGNALS),y) -TIME_SRCS += sleep.c usleep.c nanosleep.c +TIME_SRCS += nanosleep.c endif CLOCK_SRCS = clock_initialize.c clock_settime.c clock_gettime.c clock_getres.c diff --git a/sched/nanosleep.c b/sched/nanosleep.c index 8a092c32bc..f6eeae11fd 100644 --- a/sched/nanosleep.c +++ b/sched/nanosleep.c @@ -89,7 +89,7 @@ * measured by the system clock, CLOCK_REALTIME. * * The use of the nanosleep() function has no effect on the action or - * blockage of any signal. + * blockage of any signal. * * Parameters: * rqtp - The amount of time to be suspended from execution. @@ -115,9 +115,9 @@ * * EINTR - The nanosleep() function was interrupted by a signal. * EINVAL - The rqtp argument specified a nanosecond value less than - * zero or greater than or equal to 1000 million. + * zero or greater than or equal to 1000 million. * ENOSYS - The nanosleep() function is not supported by this - * implementation. + * implementation. * ****************************************************************************/ @@ -140,7 +140,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) * timer interrupts while we do tick-related calculations before and * after the wait. */ - + flags = irqsave(); starttick = clock_systimer(); @@ -208,7 +208,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) } irqrestore(flags); - + errout: set_errno(errval); return ERROR; diff --git a/syscall/syscall.csv b/syscall/syscall.csv index e470b91a76..3ae366a390 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -40,11 +40,12 @@ "mq_timedsend","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const char*","size_t","int","const struct timespec*" "mq_unlink","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","const char*" "on_exit","stdlib.h","defined(CONFIG_SCHED_ONEXIT)","int","CODE void (*)(int, FAR void *)","FAR void *" +"nanosleep","time.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR const struct timespec *", "FAR struct timespec*" "open","fcntl.h","CONFIG_NFILE_DESCRIPTORS > 0","int","const char*","int","..." "opendir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","FAR DIR*","FAR const char*" "pipe","unistd.h","CONFIG_NFILE_DESCRIPTORS > 0","int","int [2]|int*" "poll","poll.h","!defined(CONFIG_DISABLE_POLL) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","FAR struct pollfd*","nfds_t","int" -"prctl","sys/prctl.h", "CONFIG_TASK_NAME_SIZE > 0","int","int","..." +"prctl","sys/prctl.h", "CONFIG_TASK_NAME_SIZE > 0","int","int","..." "posix_spawnp","spawn.h","!defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_BINFMT_EXEPATH)","int","FAR pid_t *","FAR const char *","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char *const []","FAR char *const []" "posix_spawn","spawn.h","!defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_LIBC_EXECFUNCS) && !defined(CONFIG_BINFMT_EXEPATH)","int","FAR pid_t *","FAR const char *","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char *const []","FAR char *const []" "pthread_barrier_destroy","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_barrier_t*" @@ -118,7 +119,6 @@ "sigsuspend","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR const sigset_t*" "sigtimedwait","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR const sigset_t*","FAR struct siginfo*","FAR const struct timespec*" "sigwaitinfo","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR const sigset_t*","FAR struct siginfo*" -"sleep","unistd.h","!defined(CONFIG_DISABLE_SIGNALS)","unsigned int","unsigned int" "socket","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int" "stat","sys/stat.h","CONFIG_NFILE_DESCRIPTORS > 0","int","const char*","FAR struct stat*" #"statfs","stdio.h","","int","FAR const char*","FAR struct statfs*" @@ -138,7 +138,6 @@ "unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","const char*" "up_assert","assert.h","","void","FAR const uint8_t*","int" #"up_assert","assert.h","","void" -"usleep","unistd.h","!defined(CONFIG_DISABLE_SIGNALS)","int","useconds_t" "vfork","unistd.h","defined(CONFIG_ARCH_HAVE_VFORK)","pid_t" "wait","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","pid_t","int*" "waitid","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","int","idtype_t","id_t"," FAR siginfo_t *","int" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index b370bdd5b2..7f6da78ab8 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -118,8 +118,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) SYSCALL_LOOKUP(sigsuspend, 1, STUB_sigsuspend) SYSCALL_LOOKUP(sigtimedwait, 3, STUB_sigtimedwait) SYSCALL_LOOKUP(sigwaitinfo, 2, STUB_sigwaitinfo) - SYSCALL_LOOKUP(sleep, 1, STUB_sleep) - SYSCALL_LOOKUP(usleep, 1, STUB_usleep) + SYSCALL_LOOKUP(nanosleep, 2, STUB_nanosleep) #endif /* The following are only defined if the system clock is enabled in the @@ -148,7 +147,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) * enabled. */ -#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 +#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 SYSCALL_LOOKUP(close, 1, STUB_close) SYSCALL_LOOKUP(ioctl, 3, STUB_ioctl) SYSCALL_LOOKUP(read, 3, STUB_read) diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 65d7a35038..50e302e59f 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -132,8 +132,7 @@ uintptr_t STUB_sigsuspend(int nbr, uintptr_t parm1); uintptr_t STUB_sigtimedwait(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3); uintptr_t STUB_sigwaitinfo(int nbr, uintptr_t parm1, uintptr_t parm2); -uintptr_t STUB_sleep(int nbr, uintptr_t parm1); -uintptr_t STUB_usleep(int nbr, uintptr_t parm1); +uintptr_t STUB_nanosleep(int nbr, uintptr_t parm1, uintptr_t parm2); /* The following are only defined if the system clock is enabled in the * NuttX configuration.