summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/pmtmr.c
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2013-01-07 04:51:43 +0000
committergrehan <grehan@FreeBSD.org>2013-01-07 04:51:43 +0000
commit540789547feb13a366239f027262bcbdf3ae479a (patch)
treeaa3a00d280a7f03e05240573379e3bba1e482b05 /usr.sbin/bhyve/pmtmr.c
parentd184bb1077cf7d96f98f7b5b1fb24951ff6a80e7 (diff)
downloadFreeBSD-src-540789547feb13a366239f027262bcbdf3ae479a.zip
FreeBSD-src-540789547feb13a366239f027262bcbdf3ae479a.tar.gz
Use 64-bit arithmetic throughout, and lock accesses to globals.
With this change, dbench with >= 4 processes runs without getting weird jumps forward in time when the APCI pmtimer is the default timecounter. Obtained from: NetApp
Diffstat (limited to 'usr.sbin/bhyve/pmtmr.c')
-rw-r--r--usr.sbin/bhyve/pmtmr.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/usr.sbin/bhyve/pmtmr.c b/usr.sbin/bhyve/pmtmr.c
index 11e7ae0..78d14eb 100644
--- a/usr.sbin/bhyve/pmtmr.c
+++ b/usr.sbin/bhyve/pmtmr.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <time.h>
#include <assert.h>
+#include <pthread.h>
#include "inout.h"
@@ -51,36 +52,42 @@ __FBSDID("$FreeBSD$");
#define PMTMR_FREQ 3579545 /* 3.579545MHz */
-static uint32_t pmtmr_tscf;
-static uint32_t pmtmr_old;
+static pthread_mutex_t pmtmr_mtx;
+static uint64_t pmtmr_tscf;
+static uint64_t pmtmr_old;
static uint64_t pmtmr_tsc_old;
static uint32_t
pmtmr_val(void)
{
uint64_t pmtmr_tsc_new;
- uint32_t pmtmr_new;
+ uint64_t pmtmr_new;
static int inited = 0;
if (!inited) {
size_t len;
+ uint32_t tmpf;
inited = 1;
- len = sizeof(pmtmr_tscf);
- sysctlbyname("machdep.tsc_freq", &pmtmr_tscf, &len,
+ pthread_mutex_init(&pmtmr_mtx, NULL);
+ len = sizeof(tmpf);
+ sysctlbyname("machdep.tsc_freq", &tmpf, &len,
NULL, 0);
+ pmtmr_tscf = tmpf;
pmtmr_tsc_old = rdtsc();
pmtmr_old = pmtmr_tsc_old / pmtmr_tscf * PMTMR_FREQ;
return (pmtmr_old);
}
+ pthread_mutex_lock(&pmtmr_mtx);
pmtmr_tsc_new = rdtsc();
pmtmr_new = (pmtmr_tsc_new - pmtmr_tsc_old) * PMTMR_FREQ / pmtmr_tscf +
pmtmr_old;
pmtmr_old = pmtmr_new;
pmtmr_tsc_old = pmtmr_tsc_new;
+ pthread_mutex_unlock(&pmtmr_mtx);
- return (pmtmr_old);
+ return (pmtmr_new);
}
static int
OpenPOWER on IntegriCloud