From: ljsebald <ljs...@us...> - 2024-01-12 04:06:46
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 21bd0321caafefd7c56daecc4dcfffdd41289de0 (commit) from 5de19ac63011e4bdb45da7b6c6bbd329f330b3dd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 21bd0321caafefd7c56daecc4dcfffdd41289de0 Author: Falco Girgis <gyr...@gm...> Date: Thu Jan 11 22:06:35 2024 -0600 Added CLOCK_PROCESS_CPUTIME_ID + clock_getcpuclockid() (#427) * CLOCK_PROCESS_CPUTIME_ID + clock_getcpuclockid() - Removed some unecessary defines from time.h for different clock types, apparently defining the correct POSIX support makes Newlib do it for you. - Removed support for CLOCK_THREAD_CPUTIME_ID, because it was a lie. We don't support that. - Made CLOCK_PROCESS_CPUTIME_ID actually measure real active CPU time now, by using the performance counters (which don't run during sleep), when they're configured properly - added clock_getcpuclockid(), which gets the CPU click ID for the given process ID. Yes, we're single-process, but the standard actually states it should then work with just pid 0 (current) and fail for any other pid. * Updated include path for <dc/perfctr.h> - We moved it from arch/ to dc/ when the driver update got commited. * Updated copyright dates, CHANGELOG, docs * Addressed code review feedback. - ENOSYS swapped to ESRCH for when an invalid pid_t is supplied to clock_getcpuclockid(). ----------------------------------------------------------------------- Summary of changes: AUTHORS | 2 +- doc/CHANGELOG | 1 + include/kos/time.h | 25 ++++++++++++-------- kernel/libc/posix/clock_gettime.c | 48 +++++++++++++++++++++++++++++++++++---- 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/AUTHORS b/AUTHORS index 0110f61e..163b5384 100644 --- a/AUTHORS +++ b/AUTHORS @@ -43,7 +43,7 @@ Joe Fenton: 2016 Stefan Galowicz: 2016, 2017 Luke Benstead: 2020, 2021, 2022, 2023 Eric Fradella: 2023, 2024 -Falco Girgis: 2023 +Falco Girgis: 2023, 2024 Ruslan Rostovtsev: 2014, 2016, 2023 Colton Pawielski: 2023 Andy Barajas: 2023, 2024 diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 4597f56f..07a3840a 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -214,6 +214,7 @@ KallistiOS version 2.1.0 ----------------------------------------------- - DC Increased resolution of TMU timers + date/time functions [FG && PC] - *** Increased resolution of clock() and CLOCKS_PER_SEC to microseconds [FG] - DC Created separate performance counter driver and enhanced API [FG] +- *** Implemented _POSIX_CPUTIME in clock_gettime() using perf counter timer [FG] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Megan Potter == MP] diff --git a/include/kos/time.h b/include/kos/time.h index 5ebc30ae..67f28d4a 100644 --- a/include/kos/time.h +++ b/include/kos/time.h @@ -2,18 +2,21 @@ kos/time.h Copyright (C) 2023 Lawrence Sebald + Copyright (C) 2024 Falco Girgis */ /** \file kos/time.h - \brief KOS-implementation of select POSIX extensions + \brief KOS-implementation of select C11 and POSIX extensions - Add select POSIX extensions to time.h which are not present within Newlib. + Add select POSIX extensions and C11 functionality to time.h which are not + present within Newlib. \remark This will probably go away at some point in the future, if/when Newlib gets an implementation of this function. But for now, it's here. \author Lawrence Sebald + \author Falco Girgis */ @@ -42,22 +45,24 @@ extern int timespec_get(struct timespec *ts, int base); #if !defined(__STRICT_ANSI__) || (_POSIX_C_SOURCE >= 199309L) +/* We do not support POSIX timers! #ifndef _POSIX_TIMERS #define _POSIX_TIMERS 1 -#endif -#ifdef _POSIX_MONOTONIC_CLOCK +#endif */ + +#ifndef _POSIX_MONOTONIC_CLOCK #define _POSIX_MONOTONIC_CLOCK 1 #endif -#ifdef _POSIX_CPUTIME + +#ifndef _POSIX_CPUTIME #define _POSIX_CPUTIME 1 #endif -#ifdef _POSIX_THREAD_CPU_TIME + +/* We do NOT support thread-specific CPU time! +#ifndef _POSIX_THREAD_CPU_TIME #define _POSIX_THREAD_CPUTIME 1 #endif - -#define CLOCK_MONOTONIC (CLOCK_REALTIME + 1) -#define CLOCK_PROCESS_CPUTIME_ID (CLOCK_REALTIME + 2) -#define CLOCK_THREAD_CPUTIME_ID (CLOCK_REALTIME + 3) +*/ #endif /* !defined(__STRICT_ANSI__) || (_POSIX_C_SOURCE >= 199309L) */ diff --git a/kernel/libc/posix/clock_gettime.c b/kernel/libc/posix/clock_gettime.c index a9cdbdda..0ec1ea06 100644 --- a/kernel/libc/posix/clock_gettime.c +++ b/kernel/libc/posix/clock_gettime.c @@ -1,24 +1,42 @@ /* KallistiOS ##version## clock_gettime.c - Copyright (C) 2023 Falco Girgis + Copyright (C) 2023, 2024 Falco Girgis */ -#include <time.h> #include <arch/timer.h> #include <arch/rtc.h> + +#include <dc/perfctr.h> + +#include <time.h> #include <errno.h> +#include <assert.h> +#include <stdlib.h> + +int clock_getcpuclockid(pid_t pid, clockid_t *clock_id) { + /* pid of 0 means the current process, + and we only support a single process. */ + if(pid) + return ESRCH; + + assert(clock_id); + + *clock_id = CLOCK_PROCESS_CPUTIME_ID; + + return 0; +} int clock_getres(clockid_t clk_id, struct timespec *ts) { switch(clk_id) { case CLOCK_REALTIME: case CLOCK_MONOTONIC: case CLOCK_PROCESS_CPUTIME_ID: - case CLOCK_THREAD_CPUTIME_ID: if(!ts) { errno = EFAULT; return -1; } + ts->tv_sec = 0; ts->tv_nsec = 1; return 0; @@ -30,6 +48,8 @@ int clock_getres(clockid_t clk_id, struct timespec *ts) { } int clock_gettime(clockid_t clk_id, struct timespec *ts) { + lldiv_t div_result; + uint64_t ns64; uint32_t secs, nsecs; if(!ts) { @@ -38,17 +58,34 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts) { } switch(clk_id) { + /* Use C11's nanosecond-resolution timestamp */ case CLOCK_REALTIME: return timespec_get(ts, TIME_UTC) == TIME_UTC ? 0 : -1; + /* Use the nanosecond resolution boot time */ case CLOCK_MONOTONIC: - case CLOCK_PROCESS_CPUTIME_ID: - case CLOCK_THREAD_CPUTIME_ID: timer_ns_gettime(&secs, &nsecs); ts->tv_sec = secs; ts->tv_nsec = nsecs; return 0; + /* Use the performance counters */ + case CLOCK_PROCESS_CPUTIME_ID: + /* Check whether they are configured properly + as an interval timer. */ + if(!perf_cntr_timer_enabled()) { + errno = EINVAL; + return -1; + } + + ns64 = perf_cntr_timer_ns(); + div_result = lldiv(ns64, 1000000000); + ts->tv_sec = div_result.quot; + ts->tv_nsec = div_result.rem; + return 0; + + /* Fail out for any other unsupported CPU type */ + /* case CLOCK_THREAD_CPUTIME_ID: */ default: errno = EINVAL; return -1; @@ -62,6 +99,7 @@ int clock_settime(clockid_t clk_id, const struct timespec *ts) { errno = EFAULT; return -1; } + return rtc_set_unix_secs(ts->tv_sec); default: hooks/post-receive -- A pseudo Operating System for the Dreamcast. |