mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 13:13:08 +08:00
sched/clock: add perf overflow offset for clock perf
dd ARCH_PERF_COUNT_BITWIDTH configuration to support architectures with different perf counter bit widths (TriCore 31-bit, others 32-bit), enabling proper overflow correction across diverse platforms. Signed-off-by: zhangyuan29 <zhangyuan29@xiaomi.com>
This commit is contained in:
@@ -614,6 +614,15 @@ config ARCH_PERF_EVENTS
|
||||
Enable hardware performance counter support for perf events. If
|
||||
disabled, perf events will use software events only.
|
||||
|
||||
config ARCH_PERF_COUNT_BITWIDTH
|
||||
int "Bit width of the perf count"
|
||||
default 31 if ARCH_TRICORE
|
||||
default 32 if !ARCH_TRICORE
|
||||
depends on PERF_OVERFLOW_CORRECTION
|
||||
---help---
|
||||
Bit width of the perf count. When arch is tricore, the value is 31.
|
||||
When arch is not tricore, the value is 32.
|
||||
|
||||
config ARCH_HAVE_BOOTLOADER
|
||||
bool
|
||||
default n
|
||||
|
||||
@@ -43,6 +43,7 @@ struct perf_s
|
||||
spinlock_t lock;
|
||||
unsigned long last;
|
||||
unsigned long overflow;
|
||||
clock_t timeout;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -61,10 +62,10 @@ static struct perf_s g_perf;
|
||||
|
||||
static void perf_update(wdparm_t arg)
|
||||
{
|
||||
clock_t tick = (clock_t)LONG_MAX * TICK_PER_SEC / up_perf_getfreq();
|
||||
FAR struct perf_s *perf = &g_perf;
|
||||
|
||||
perf_gettime();
|
||||
wd_start_next((FAR struct wdog_s *)arg, tick, perf_update, arg);
|
||||
wd_start_next((FAR struct wdog_s *)arg, perf->timeout, perf_update, arg);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -78,13 +79,14 @@ static void perf_update(wdparm_t arg)
|
||||
void perf_init(void)
|
||||
{
|
||||
FAR struct perf_s *perf = &g_perf;
|
||||
clock_t tick = (clock_t)LONG_MAX * TICK_PER_SEC / up_perf_getfreq();
|
||||
|
||||
perf->timeout = (((clock_t)1 << (CONFIG_ARCH_PERF_COUNT_BITWIDTH - 1)) - 1)
|
||||
* TICK_PER_SEC / up_perf_getfreq();
|
||||
perf->last = up_perf_gettime();
|
||||
|
||||
/* Periodic check for overflow */
|
||||
|
||||
wd_start(&perf->wdog, tick, perf_update, (wdparm_t)perf);
|
||||
wd_start(&perf->wdog, perf->timeout, perf_update, (wdparm_t)perf);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -106,7 +108,8 @@ clock_t perf_gettime(void)
|
||||
}
|
||||
|
||||
perf->last = now;
|
||||
result = (clock_t)now | (clock_t)perf->overflow << 32;
|
||||
result = (clock_t)now | \
|
||||
(clock_t)perf->overflow << CONFIG_ARCH_PERF_COUNT_BITWIDTH;
|
||||
spin_unlock_irqrestore(&perf->lock, flags);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user