From 37cba9c93ba2e763b5f3bf75dcb9fdeb1a314a9d Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 20 Oct 2018 14:18:04 +0200 Subject: [PATCH] core: Support time functions. * lib/linux/clock_gettime.c: New file, move from gnu.c. * lib/linux/gettimeofday.c: New file, move from tcc.c. * lib/linux/time.c: New file, move from tcc.c. * lib/linux/libc.c: Include them. * lib/linux/gnu.c (clock_gettime): Remove. * lib/linux/tcc.c (time, gettimeofday): Remove. * include/time.h (CLOCK_PROCESS_CPUTIME_ID): New define. * src/posix.c (init_time, current_time, gettimeofday_, seconds_and_nanoseconds_to_long, get_internal_run_time): New function. * src/mes.c (scm_symbol_internal_time_units_per_second): New symbol. (main): Call init_time. --- include/time.h | 1 + lib/linux/clock_gettime.c | 27 ++++++++++++++++++++ lib/linux/gettimeofday.c | 27 ++++++++++++++++++++ lib/linux/gnu.c | 6 ----- lib/linux/libc.c | 4 +++ lib/linux/tcc.c | 12 --------- lib/linux/time.c | 27 ++++++++++++++++++++ scaffold/mini-mes.c | 1 + src/mes.c | 4 ++- src/posix.c | 53 +++++++++++++++++++++++++++++++++++++-- 10 files changed, 141 insertions(+), 21 deletions(-) create mode 100644 lib/linux/clock_gettime.c create mode 100644 lib/linux/gettimeofday.c create mode 100644 lib/linux/time.c diff --git a/include/time.h b/include/time.h index 366eba33..e60a49a4 100644 --- a/include/time.h +++ b/include/time.h @@ -54,6 +54,7 @@ struct timespec #endif // __MES_STRUCT_TIMESPEC +#define CLOCK_PROCESS_CPUTIME_ID 2 int clock_gettime (clockid_t clk_id, struct timespec *tp); struct tm *localtime (time_t const *timep); struct tm *gmtime (time_t const *time); diff --git a/lib/linux/clock_gettime.c b/lib/linux/clock_gettime.c new file mode 100644 index 00000000..a23572eb --- /dev/null +++ b/lib/linux/clock_gettime.c @@ -0,0 +1,27 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include + +int +clock_gettime (clockid_t clk_id, struct timespec *tp) +{ + return _sys_call2 (SYS_clock_gettime, (long)clk_id, (long)tp); +} diff --git a/lib/linux/gettimeofday.c b/lib/linux/gettimeofday.c new file mode 100644 index 00000000..0e427856 --- /dev/null +++ b/lib/linux/gettimeofday.c @@ -0,0 +1,27 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include + +int +gettimeofday (struct timeval *tv, struct timezone *tz) +{ + return _sys_call2 (SYS_gettimeofday, (long)tv, (long)tz); +} diff --git a/lib/linux/gnu.c b/lib/linux/gnu.c index ecc2c3de..7fc5a8be 100644 --- a/lib/linux/gnu.c +++ b/lib/linux/gnu.c @@ -173,9 +173,3 @@ chdir (char const *file_name) { return _sys_call1 (SYS_chdir, (long)file_name); } - -int -clock_gettime (clockid_t clk_id, struct timespec *tp) -{ - return _sys_call2 (SYS_clock_gettime, (long)clk_id, (long)tp); -} diff --git a/lib/linux/libc.c b/lib/linux/libc.c index 8231a778..011d20d6 100644 --- a/lib/linux/libc.c +++ b/lib/linux/libc.c @@ -149,3 +149,7 @@ fsync (int filedes) { return _sys_call1 (SYS_fsync, (int)filedes); } + +#include "linux/clock_gettime.c" +#include "linux/gettimeofday.c" +#include "linux/time.c" diff --git a/lib/linux/tcc.c b/lib/linux/tcc.c index f912db8a..57bdde58 100644 --- a/lib/linux/tcc.c +++ b/lib/linux/tcc.c @@ -60,15 +60,3 @@ getcwd (char *buffer, size_t size) { return _sys_call2 (SYS_getcwd, (long)buffer, (long)size); } - -time_t -time (time_t *result) -{ - return _sys_call1 (SYS_time, (long)result); -} - -int -gettimeofday (struct timeval *tv, struct timezone *tz) -{ - return _sys_call2 (SYS_gettimeofday, (long)tv, (long)tz); -} diff --git a/lib/linux/time.c b/lib/linux/time.c new file mode 100644 index 00000000..863a13c9 --- /dev/null +++ b/lib/linux/time.c @@ -0,0 +1,27 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include + +time_t +time (time_t *result) +{ + return _sys_call1 (SYS_time, (long)result); +} diff --git a/scaffold/mini-mes.c b/scaffold/mini-mes.c index 961b7051..0391b556 100644 --- a/scaffold/mini-mes.c +++ b/scaffold/mini-mes.c @@ -205,6 +205,7 @@ struct scm scm_type_variable = {TSYMBOL, "",0}; struct scm scm_type_vector = {TSYMBOL, "",0}; struct scm scm_type_broken_heart = {TSYMBOL, "",0}; +struct scm scm_symbol_internal_time_units_per_second = {TSYMBOL, "internal-time-units-per-second",0}; struct scm scm_symbol_compiler = {TSYMBOL, "%compiler",0}; struct scm scm_symbol_arch = {TSYMBOL, "%arch",0}; diff --git a/src/mes.c b/src/mes.c index 71cd8afb..44d3fa8c 100644 --- a/src/mes.c +++ b/src/mes.c @@ -26,7 +26,7 @@ //#define MES_MINI 1 #if POSIX -long ARENA_SIZE = 100000000; +long ARENA_SIZE = 100000000; // 2.3GiB #else long ARENA_SIZE = 300000; // 32b: 3MiB, 64b: 6 MiB #endif @@ -271,6 +271,7 @@ struct scm scm_type_variable = {TSYMBOL, "",0}; struct scm scm_type_vector = {TSYMBOL, "",0}; struct scm scm_type_broken_heart = {TSYMBOL, "",0}; +struct scm scm_symbol_internal_time_units_per_second = {TSYMBOL, "internal-time-units-per-second",0}; struct scm scm_symbol_compiler = {TSYMBOL, "%compiler",0}; struct scm scm_symbol_arch = {TSYMBOL, "%arch",0}; @@ -2546,6 +2547,7 @@ main (int argc, char *argv[]) SCM a = mes_environment (argc, argv); a = mes_builtins (a); + a = init_time (a); m0 = make_initial_module (a); g_macros = make_hash_table_ (0); diff --git a/src/posix.c b/src/posix.c index f6c34484..acd77e48 100644 --- a/src/posix.c +++ b/src/posix.c @@ -18,10 +18,12 @@ * along with GNU Mes. If not, see . */ -#include -#include #include #include +#include +#include +#include +#include #include int readchar (); @@ -303,3 +305,50 @@ waitpid_ (SCM pid, SCM options) int child = waitpid (VALUE (pid), &status, VALUE (options)); return cons (MAKE_NUMBER (child), MAKE_NUMBER (status)); } + +#if __x86_64__ +/* Nanoseconds on 64-bit systems with POSIX timers. */ +#define TIME_UNITS_PER_SECOND 1000000000 +#else +/* Milliseconds for everyone else. */ +#define TIME_UNITS_PER_SECOND 1000 +#endif + +struct timespec g_start_time; +SCM +init_time (SCM a) ///((internal)) +{ + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &g_start_time); + a = acons (cell_symbol_internal_time_units_per_second, MAKE_NUMBER (TIME_UNITS_PER_SECOND), a); +} + +SCM +current_time () +{ + return MAKE_NUMBER (time (0)); +} + +SCM +gettimeofday_ () ///((name . "gettimeofday")) +{ + struct timeval time; + gettimeofday (&time, 0); + return cons (MAKE_NUMBER (time.tv_sec), MAKE_NUMBER (time.tv_usec)); +} + +long +seconds_and_nanoseconds_to_long (long s, long ns) +{ + return s * TIME_UNITS_PER_SECOND + + ns / (1000000000 / TIME_UNITS_PER_SECOND); +} + +SCM +get_internal_run_time () +{ + struct timespec ts; + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts); + long time = seconds_and_nanoseconds_to_long (ts.tv_sec - g_start_time.tv_sec, + ts.tv_nsec - g_start_time.tv_nsec); + return MAKE_NUMBER (time); +}