How are you going to support multiple timecounters on an architecture?
Let's say tsc sets tc_user=1 and acpihpet sets tc_user=2. Then in
libc/arch/amd64/gen/usertc.c I do:
static uint64_t
rdtsc()
{
uint32_t hi, lo;
asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint64_t)lo)|(((uint64_t)hi)<<32);
}
static uint64_t
acpihpet()
{
return rdtsc(); /* JUST TO COMPILE */
}
static uint64_t (*get_tc[])(void) =
{
rdtsc,
acpihpet,
};
uint64_t
tc_get_timecount_md(struct timekeep *tk)
{
return (*get_tc[tk->tk_user])();
}
Ignoring the off-by-one in the array access, how is this going to work
if we add a new timecounter on the kernel side that has tc_user = 3?
We can add a check for array length. It was just code to prove how we
could do it. Kernel tc_user values have to be in sync with libc, of
course. No matter if we go this way or not.
So I'm suggesting again that we need a function that checks whether
libc actually supports a particular timecounter type. And I propose
that we implement that function on *all* architectures which solves
the issue of finding an MD header file.
Note that implementing this isn't entirely trivial as there are
potential TOCTOU issues.
Ok. If we do that, then isn't this just going to be a sparse function
pointer table on each arhitecture: most entries are NULL and the ones
for the current arch are set to gettime functions for the corresponding
clocks. And then things would look like above, right? But with no MD
includes. Yes. Is that how you see it?