summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2011-04-07 23:28:28 +0000
committerjkim <jkim@FreeBSD.org>2011-04-07 23:28:28 +0000
commit95c723445e6a8035e5b4b318941c66ac674cd16c (patch)
tree664d6632a866948517ff612d5ccfb37cd5bf91db /sys/i386/isa
parent824b228f1c496d62e28a46c5b32fbd974d60a42e (diff)
downloadFreeBSD-src-95c723445e6a8035e5b4b318941c66ac674cd16c.zip
FreeBSD-src-95c723445e6a8035e5b4b318941c66ac674cd16c.tar.gz
Use atomic load & store for TSC frequency. It may be overkill for amd64 but
safer for i386 because it can be easily over 4 GHz now. More worse, it can be easily changed by user with 'machdep.tsc_freq' tunable (directly) or cpufreq(4) (indirectly). Note it is intentionally not used in performance critical paths to avoid performance regression (but we should, in theory). Alternatively, we may add "virtual TSC" with lower frequency if maximum frequency overflows 32 bits (and ignore possible incoherency as we do now).
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/prof_machdep.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/i386/isa/prof_machdep.c b/sys/i386/isa/prof_machdep.c
index adeddf2..bdcd7e4 100644
--- a/sys/i386/isa/prof_machdep.c
+++ b/sys/i386/isa/prof_machdep.c
@@ -170,8 +170,8 @@ cputime()
{
u_int count;
int delta;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) && \
- defined(PERFMON) && defined(I586_PMC_GUPROF)
+#if (defined(I586_CPU) || defined(I686_CPU)) && \
+ defined(PERFMON) && defined(I586_PMC_GUPROF) && !defined(SMP)
u_quad_t event_count;
#endif
u_char high, low;
@@ -286,21 +286,23 @@ void
startguprof(gp)
struct gmonparam *gp;
{
- if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
- cputime_clock = CPUTIME_CLOCK_I8254;
#if defined(I586_CPU) || defined(I686_CPU)
- if (tsc_freq != 0 && mp_ncpus == 1)
+ uint64_t freq;
+
+ freq = atomic_load_acq_64(&tsc_freq);
+ if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
+ if (freq != 0 && mp_ncpus == 1)
cputime_clock = CPUTIME_CLOCK_TSC;
-#endif
+ else
+ cputime_clock = CPUTIME_CLOCK_I8254;
}
- gp->profrate = i8254_freq << CPUTIME_CLOCK_I8254_SHIFT;
-#if defined(I586_CPU) || defined(I686_CPU)
if (cputime_clock == CPUTIME_CLOCK_TSC) {
- gp->profrate = tsc_freq >> 1;
+ gp->profrate = freq >> 1;
cputime_prof_active = 1;
- }
+ } else
+ gp->profrate = i8254_freq << CPUTIME_CLOCK_I8254_SHIFT;
#if defined(PERFMON) && defined(I586_PMC_GUPROF)
- else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
+ if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
if (perfmon_avail() &&
perfmon_setup(0, cputime_clock_pmc_conf) == 0) {
if (perfmon_start(0) != 0)
@@ -325,6 +327,10 @@ startguprof(gp)
}
}
#endif /* PERFMON && I586_PMC_GUPROF */
+#else /* !(I586_CPU || I686_CPU) */
+ if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED)
+ cputime_clock = CPUTIME_CLOCK_I8254;
+ gp->profrate = i8254_freq << CPUTIME_CLOCK_I8254_SHIFT;
#endif /* I586_CPU || I686_CPU */
cputime_bias = 0;
cputime();
OpenPOWER on IntegriCloud