提交 da450a4f 创建 作者: Austin Clements's avatar Austin Clements

Support static construction of lockstat-enabled locks

This works by lazily allocating a lock's klockstat structure when the lock is first acquired.
上级 b6308520
#pragma once
#include "lockstat.h"
#if LOCKSTAT
extern klockstat klockstat_lazy;
#endif
// Mutual exclusion lock.
struct spinlock {
u32 locked; // Is the lock held?
......@@ -29,16 +33,15 @@ struct spinlock {
#endif
{ }
// Create a spinlock without lockstat tracking. This is constexpr,
// so it can be used for global spinlocks without incurring a static
// constructor.
constexpr spinlock(const char *name)
// Create a spinlock. This is constexpr, so it can be used for
// global spinlocks without incurring a static constructor.
constexpr spinlock(const char *name, bool lockstat = false)
: locked(0)
#if SPINLOCK_DEBUG
, name(name), cpu(nullptr), pcs{}
#endif
#if LOCKSTAT
, stat(nullptr)
, stat(lockstat ? nullptr : &klockstat_lazy)
#endif
{ }
};
......
......@@ -13,8 +13,14 @@
#include "major.h"
#if LOCKSTAT
// The klockstat structure pointed to by spinlocks that want lockstat,
// but have never been acquired.
struct klockstat klockstat_lazy("<lazy>");
static int lockstat_enable;
void lockstat_init(struct spinlock *lk, bool lazy);
static inline struct cpulockstat *
mylockstat(struct spinlock *lk)
{
......@@ -49,8 +55,11 @@ locking(struct spinlock *lk)
#endif
#if LOCKSTAT
if (lockstat_enable && lk->stat != nullptr)
if (lockstat_enable && lk->stat != nullptr) {
if (lk->stat == &klockstat_lazy)
lockstat_init(lk, true);
mylockstat(lk)->locking_ts = rdtsc();
}
#endif
mtlock(lk);
......@@ -128,12 +137,21 @@ klockstat::klockstat(const char *name) :
};
void
lockstat_init(struct spinlock *lk)
lockstat_init(struct spinlock *lk, bool lazy)
{
lk->stat = new klockstat(lk->name);
if (lk->stat == 0)
klockstat *ls = new klockstat(lk->name);
if (!ls)
return;
if (lazy) {
if (!__sync_bool_compare_and_swap(&lk->stat, &klockstat_lazy, ls)) {
delete ls;
return;
}
} else {
lk->stat = ls;
}
acquire(&lockstat_lock);
LIST_INSERT_HEAD(&lockstat_list, lk->stat, link);
release(&lockstat_lock);
......@@ -256,7 +274,7 @@ initlock(struct spinlock *lk, const char *name, int lockstat)
#if LOCKSTAT
lk->stat = (struct klockstat*) nullptr;
if (lockstat)
lockstat_init(lk);
lockstat_init(lk, false);
#endif
lk->locked = 0;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论