Track lock contends

上级 21daa928
......@@ -24,7 +24,7 @@ stats(void)
if (fd < 0)
die("lockstat: open failed");
printf(1, "## name acquires locking locked\n");
printf(1, "## name acquires contends locking locked\n");
while (1) {
r = read(fd, &ls, sz);
if (r < 0)
......@@ -34,16 +34,18 @@ stats(void)
if (r != sz)
die("lockstat: unexpected read");
u64 acquires = 0, locking = 0, locked = 0;
u64 acquires = 0, contends = 0,
locking = 0, locked = 0;
for (int i = 0; i < NCPU; i++) {
acquires += ls.cpu[i].acquires;
acquires += ls.cpu[i].acquires;
contends += ls.cpu[i].contends;
locking += ls.cpu[i].locking;
locked += ls.cpu[i].locked;
}
if (acquires > 0)
printf(1, "%s %lu %lu %lu\n",
ls.name, acquires, locking, locked);
if (contends > 0)
printf(1, "%s %lu %lu %lu %lu\n",
ls.name, acquires, contends, locking, locked);
}
}
......
......@@ -2,8 +2,10 @@
struct cpulockstat {
u64 acquires;
u64 contends;
u64 locking;
u64 locked;
u64 locking_ts;
u64 locked_ts;
__padout__;
......
......@@ -40,7 +40,7 @@ locking(struct spinlock *lk)
}
static inline void
locked(struct spinlock *lk)
locked(struct spinlock *lk, u64 retries)
{
mtacquired(lk);
......@@ -53,6 +53,8 @@ locked(struct spinlock *lk)
#if LOCKSTAT
if (lockstat_enable && lk->stat != NULL) {
struct cpulockstat *s = mylockstat(lk);
if (retries > 0)
s->contends++;
s->acquires++;
s->locked_ts = rdtsc();
}
......@@ -117,7 +119,7 @@ tryacquire(struct spinlock *lk)
popcli();
return 0;
}
locked(lk);
locked(lk, 0);
return 1;
}
......@@ -128,14 +130,15 @@ tryacquire(struct spinlock *lk)
void
acquire(struct spinlock *lk)
{
u64 retries;
pushcli();
locking(lk);
// The xchg is atomic.
// It also serializes, so that reads after acquire are not
// reordered before it.
retries = 0;
while(xchg32(&lk->locked, 1) != 0)
;
locked(lk);
retries++;
locked(lk, retries);
}
// Release the lock.
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论