#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/hwt.h>
#include <dev/hwt/hwt_owner.h>
#include <dev/hwt/hwt_ownerhash.h>
#define HWT_DEBUG
#undef HWT_DEBUG
#ifdef HWT_DEBUG
#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define dprintf(fmt, ...)
#endif
#define HWT_OWNERHASH_SIZE 1024
static MALLOC_DEFINE(M_HWT_OWNERHASH, "hwt_ohash", "Hardware Trace");
#define _HWT_HM 11400714819323198486u
#define HWT_HASH_PTR(P, M) ((((unsigned long) (P) >> 2) * _HWT_HM) & (M))
static struct mtx hwt_ownerhash_mtx;
static u_long hwt_ownerhashmask;
static LIST_HEAD(hwt_ownerhash, hwt_owner) *hwt_ownerhash;
struct hwt_owner *
hwt_ownerhash_lookup(struct proc *p)
{
struct hwt_ownerhash *hoh;
struct hwt_owner *ho;
int hindex;
hindex = HWT_HASH_PTR(p, hwt_ownerhashmask);
hoh = &hwt_ownerhash[hindex];
HWT_OWNERHASH_LOCK();
LIST_FOREACH(ho, hoh, next) {
if (ho->p == p) {
HWT_OWNERHASH_UNLOCK();
return (ho);
}
}
HWT_OWNERHASH_UNLOCK();
return (NULL);
}
void
hwt_ownerhash_insert(struct hwt_owner *ho)
{
struct hwt_ownerhash *hoh;
int hindex;
hindex = HWT_HASH_PTR(ho->p, hwt_ownerhashmask);
hoh = &hwt_ownerhash[hindex];
HWT_OWNERHASH_LOCK();
LIST_INSERT_HEAD(hoh, ho, next);
HWT_OWNERHASH_UNLOCK();
}
void
hwt_ownerhash_remove(struct hwt_owner *ho)
{
HWT_OWNERHASH_LOCK();
LIST_REMOVE(ho, next);
HWT_OWNERHASH_UNLOCK();
}
void
hwt_ownerhash_load(void)
{
hwt_ownerhash = hashinit(HWT_OWNERHASH_SIZE, M_HWT_OWNERHASH,
&hwt_ownerhashmask);
mtx_init(&hwt_ownerhash_mtx, "hwt-owner-hash", "hwt-owner", MTX_DEF);
}
void
hwt_ownerhash_unload(void)
{
struct hwt_ownerhash *hoh;
struct hwt_owner *ho, *tmp;
HWT_OWNERHASH_LOCK();
for (hoh = hwt_ownerhash;
hoh <= &hwt_ownerhash[hwt_ownerhashmask];
hoh++) {
LIST_FOREACH_SAFE(ho, hoh, next, tmp) {
}
}
HWT_OWNERHASH_UNLOCK();
mtx_destroy(&hwt_ownerhash_mtx);
hashdestroy(hwt_ownerhash, M_HWT_OWNERHASH, hwt_ownerhashmask);
}