aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2023-01-14 02:15:10 +0100
committerBen Hutchings <ben@decadent.org.uk>2023-02-12 22:10:18 +0100
commit0b35ac6c018c83be12a66db6b026b81b3321846a (patch)
tree95992b0bec6ae3fd3267af3ee58f2b196c9257b4
parentdf8acc6168d9abd9dee5c2eb6b9e6a25311676bc (diff)
downloadklibc-0b35ac6c018c83be12a66db6b026b81b3321846a.tar.gz
[klibc] time: Use clock_* system calls for time-of-day and sleep
{get,set}timeofday(), nanosleep(), and time() on't have direct replacements that use 64-bit time on 32-bit architectures. Instead, we have to use the clock_*() system calls. In preparation for using 64-bit time everywhere: - Make clock_{gettime,nanosleep,settime}() required system calls - Make {get,set}timeofday(), nanosleep(), and time() use them. We still need to use the {get,set}timeofday() system calls to get and set the time zone. Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/include/sys/time.h3
-rw-r--r--usr/include/sys/types.h1
-rw-r--r--usr/klibc/Kbuild6
-rw-r--r--usr/klibc/SYSCALLS.def9
-rw-r--r--usr/klibc/clock_nanosleep.c17
-rw-r--r--usr/klibc/gettimeofday.c22
-rw-r--r--usr/klibc/nanosleep.c8
-rw-r--r--usr/klibc/settimeofday.c22
-rw-r--r--usr/klibc/time.c4
9 files changed, 82 insertions, 10 deletions
diff --git a/usr/include/sys/time.h b/usr/include/sys/time.h
index da9f58099da194..e81633034fe8be 100644
--- a/usr/include/sys/time.h
+++ b/usr/include/sys/time.h
@@ -50,6 +50,9 @@ static inline int FD_ISSET(int __fd, fd_set *__fdsetp)
__extern int gettimeofday(struct timeval *, struct timezone *);
__extern int settimeofday(const struct timeval *, const struct timezone *);
+__extern int clock_gettime(clockid_t, struct timespec *);
+__extern int clock_settime(clockid_t, const struct timespec *);
+__extern int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
__extern int getitimer(int, struct itimerval *);
__extern int setitimer(int, const struct itimerval *, struct itimerval *);
__extern int utimes(const char *, const struct timeval[2]);
diff --git a/usr/include/sys/types.h b/usr/include/sys/types.h
index b8cdb8cf161de4..e17bc87f08f0ef 100644
--- a/usr/include/sys/types.h
+++ b/usr/include/sys/types.h
@@ -33,6 +33,7 @@ typedef __kernel_key_t key_t;
typedef __kernel_suseconds_t suseconds_t;
/* typedef __kernel_timer_t timer_t; */
typedef int timer_t;
+typedef __kernel_clockid_t clockid_t;
typedef __kernel_uid32_t uid_t;
typedef __kernel_gid32_t gid_t;
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 02a18e643fadc3..8b132190a12db1 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -29,7 +29,8 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \
statfs.o fstatfs.o umount.o \
creat.o open.o openat.o \
fread2.o fwrite2.o fgets.o fputc.o fputs.o puts.o putchar.o \
- sleep.o usleep.o strtotimespec.o strtotimeval.o \
+ clock_nanosleep.o nanosleep.o sleep.o usleep.o \
+ strtotimespec.o strtotimeval.o \
raise.o abort.o assert.o alarm.o pause.o \
__signal.o sysv_signal.o bsd_signal.o siglist.o sigabbrev.o \
siglongjmp.o \
@@ -53,7 +54,8 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \
clearenv.o nullenv.o \
getopt.o getopt_long.o readdir.o scandir.o alphasort.o remove.o \
syslog.o closelog.o pty.o isatty.o reboot.o \
- time.o lseek.o nice.o getpriority.o \
+ gettimeofday.o settimeofday.o time.o \
+ lseek.o nice.o getpriority.o \
futimesat.o utime.o utimes.o \
qsort.o bsearch.o \
lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index ad8eefa45bf2e4..d46bb548484cf0 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -201,11 +201,12 @@ int setitimer(int, const struct itimerval *, struct itimerval *);
/*
* Time-related system calls
*/
-<?> time_t time(time_t *);
clock_t times(struct tms *);
-int gettimeofday(struct timeval *, struct timezone *);
-int settimeofday(const struct timeval *, const struct timezone *);
-int nanosleep(const struct timespec *, struct timespec *);
+int gettimeofday::__gettimeofday(void *, struct timezone *);
+int settimeofday::__settimeofday(const void *, const struct timezone *);
+int clock_gettime(clockid_t, struct timespec *);
+int clock_settime(clockid_t, const struct timespec *);
+int clock_nanosleep::__clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
<?> int pause();
/*
diff --git a/usr/klibc/clock_nanosleep.c b/usr/klibc/clock_nanosleep.c
new file mode 100644
index 00000000000000..b4fd1e2c485bb7
--- /dev/null
+++ b/usr/klibc/clock_nanosleep.c
@@ -0,0 +1,17 @@
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+extern int __clock_nanosleep(clockid_t, int,
+ const struct timespec *, struct timespec *);
+
+/*
+ * POSIX says this has to return a positive error code, but the system
+ * call returns error codes in the usual way.
+ */
+int clock_nanosleep(clockid_t clock_id, int flags,
+ const struct timespec *request, struct timespec *remain)
+{
+ return __clock_nanosleep(clock_id, flags, request, remain) ?
+ errno : 0;
+}
diff --git a/usr/klibc/gettimeofday.c b/usr/klibc/gettimeofday.c
new file mode 100644
index 00000000000000..919c46dfd2a42d
--- /dev/null
+++ b/usr/klibc/gettimeofday.c
@@ -0,0 +1,22 @@
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+extern int __gettimeofday(void *, struct timezone *);
+
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ struct timespec ts;
+
+ if (tv) {
+ if (clock_gettime(CLOCK_REALTIME, &ts))
+ return -1;
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+
+ if (tz && __gettimeofday(NULL, tz))
+ return -1;
+
+ return 0;
+}
diff --git a/usr/klibc/nanosleep.c b/usr/klibc/nanosleep.c
new file mode 100644
index 00000000000000..11412196a5dbe1
--- /dev/null
+++ b/usr/klibc/nanosleep.c
@@ -0,0 +1,8 @@
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+int nanosleep(const struct timespec *request, struct timespec *remain)
+{
+ return clock_nanosleep(CLOCK_MONOTONIC, 0, request, remain) ? -1 : 0;
+}
diff --git a/usr/klibc/settimeofday.c b/usr/klibc/settimeofday.c
new file mode 100644
index 00000000000000..75754db3c3298d
--- /dev/null
+++ b/usr/klibc/settimeofday.c
@@ -0,0 +1,22 @@
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+extern int __settimeofday(const void *, const struct timezone *);
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+ struct timespec ts;
+
+ if (tz && __settimeofday(NULL, tz))
+ return -1;
+
+ if (tv) {
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ if (clock_settime(CLOCK_REALTIME, &ts))
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/usr/klibc/time.c b/usr/klibc/time.c
index a0c366b9be23a5..e8129316ec8ff4 100644
--- a/usr/klibc/time.c
+++ b/usr/klibc/time.c
@@ -6,8 +6,6 @@
#include <sys/time.h>
#include <sys/syscall.h>
-#ifndef __NR_time
-
time_t time(time_t * t)
{
struct timeval tv;
@@ -19,5 +17,3 @@ time_t time(time_t * t)
return (time_t) tv.tv_sec;
}
-
-#endif