Skip to content

Make clock API POSIX-compliant and implement clock IDs - #538

Open
adamgreloch wants to merge 5 commits into
masterfrom
adamgreloch/RTOS-1472
Open

adamgreloch wants to merge 5 commits into
masterfrom
adamgreloch/RTOS-1472

Conversation

@adamgreloch

@adamgreloch adamgreloch commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

TASK: RTOS-1472

Fixes: phoenix-rtos/phoenix-rtos-project#1685

Description

Motivation and Context

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: (list targets here).

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for process and thread CPU-time clocks, implementing POSIX-compliant APIs such as pthread_getcpuclockid, clock_getcpuclockid, and clock_getres, while expanding clock_gettime and clock_nanosleep capabilities. It also refactors internal priority and tick interval handling, and updates the times system call implementation. Feedback on these changes highlights critical safety and portability improvements: first, pthread_getcpuclockid should verify thread existence via the thread list to prevent segmentation faults on invalid thread IDs; second, clock_nanosleep must validate that the req timespec pointer is non-NULL before dereferencing; and third, the CPU clock macros in common/cpuclock.h should cast the clock ID to an unsigned type to avoid implementation-defined behavior during right-shift operations.

Comment thread pthread/pthread.c
Comment thread time/time.c
Comment thread common/cpuclock.h Outdated
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Unit Test Results

13 884 tests  +154   13 024 ✅ +153   1h 6m 27s ⏱️ + 9m 55s
   791 suites + 11      859 💤 ±  0 
     1 files   ±  0        1 ❌ +  1 

For more details on these failures, see this check.

Results for commit ef2d465. ± Comparison against base commit 9bffcee.

♻️ This comment has been updated with latest results.

@adamgreloch
adamgreloch marked this pull request as ready for review September 30, 2026 15:01
@adamgreloch
adamgreloch requested a review from a team September 30, 2026 15:01

@Darchiv Darchiv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments.

Comment thread time/time.c
@@ -564,15 +564,29 @@ int nanosleep(const struct timespec *req, struct timespec *rem)
/* clock_nanosleep() shall return **positive** errors codes directly, without setting errno */
int clock_nanosleep(clockid_t clock, int flags, const struct timespec *req, struct timespec *rem)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function parameter names are different than in POSIX

@adamgreloch adamgreloch Oct 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that there are multiple functions with argument naming deviating from POSIX spec. Will do this in a separate PR in one sweep.

Comment thread sys/times.c Outdated
#include <sys/time.h>
#include <sys/types.h>
#include <sys/times.h>
#include <time.h>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to sort these alphabetically?

Applies in other places too

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe let's do it for the whole libphoenix in one sweep in a separate PR

Comment thread time/time.c
Comment thread common/cpuclock.h Outdated
Comment thread time/time.c Outdated
us = __getSystickInterval();
}
else if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_MONOTONIC || clock_id == CLOCK_MONOTONIC_RAW) {
us = 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the actual resolution for CLOCK_REALTIME depends on the per-platform hardware clock used by the kernel. Usually this is a typical 32,768 kHz calibrated built-in RTC, so the resolution would be ~30 us. This aligns with clock_settime() POSIX behavior, which truncates the actually set time to match the resolution (e.g. a write and read from HW RTC registers will yield a truncated value).

I think platform-dependent parameters should at least be defined by kernel per-arch headers. Maybe it should also be a part of sysctl-like mechanism to query/set the kernel tick frequency and other runtime parameters.

Or maybe this can't be done due to compatibility concerns?

(Of course we could enhance the realtime clock by complementing it with a high-resolution clock in short timeframes, but I'm almost positive this is only in a sphere of dreams, so your 1 us seems not to come from that.)

@adamgreloch adamgreloch Oct 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but userspace doesn't need to know the real resolution. It must be the smallest increment by which the clock can change, so 1 us is fine for ~30 us clocks.

I agree that, long term, it would be nice to have this sorted out precisely, but from the POSIX perspective it's not required. I'd prefer to exploit this fact, since currently we don't have the API to pass the true resolution to the userspace.

Comment thread time/time.c Outdated
Comment thread time/time.c Outdated
clock_t clock(void)
{
return (clock_t)-1;
time_t res = cpuclockGet(0, 0);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this value normalized so that it can be used with CLOCKS_PER_SEC? Note that the (legacy) functions clock() and times() operate on different clocks - clock() returns the number of ticks which must be divided by CLOCKS_PER_SEC to get the time and times() returns other, "virtual" number of ticks which must be divided by the value of sysconf(_SC_CLK_TCK). to get the time.

Why "virtual" and not real ticks? If we decide that system tick interval can be changed at runtime, then the output of times() would not be comparable with other invocations' output and, more importantly, sysconf(_SC_CLK_TCK) would need to be a dynamic variable. So, times() can be implemented in the same way as clock(), just with a (possibly) different "clocks per sec" constant.

Let's treat clock() and times() as legacy functions mainly used by ports, so that their behavior does not affect how we account time in the kernel.

@adamgreloch adamgreloch Oct 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you ask whether it is POSIX compliant, it is. Kernel provides microseconds, clock() is supposed to return a value sanely divisible by CLOCKS_PER_SEC which could very well be called MS_PER_SEC, since it is specified to be equal 1000000.

Let's treat clock() and times() as legacy functions mainly used by ports, so that their behavior does not affect how we account time in the kernel.

Agreed.

@adamgreloch
adamgreloch force-pushed the adamgreloch/RTOS-1472 branch from cea7694 to 9b8b952 Compare October 2, 2026 16:14
nsleep is a native syscall, so it should operate on PH_CLOCK_*
definitions.

TASK: RTOS-1472
Breaking change: depends on newly added sys_cpuTime syscall and
PH_CLK_TCK definition.

TASK: RTOS-1472
@adamgreloch
adamgreloch force-pushed the adamgreloch/RTOS-1472 branch from 9b8b952 to ef2d465 Compare October 2, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clock_nanosleep() fails with EINVAL for a relative sleep on CLOCK_REALTIME

2 participants