C++程序  |  88行  |  1.97 KB

/**
 * @file op_dcache.h
 * Compatibility functions for dcache lookups
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#ifndef OP_DCACHE_H
#define OP_DCACHE_H

#include <linux/sched.h>
#include <linux/unistd.h>
#include <linux/mman.h>
#include <linux/file.h>

#include "oprofile.h"

extern uint op_dname_top;
extern struct qstr **op_dname_stack;
extern char * op_pool_pos;
extern char * op_pool_start;
extern char * op_pool_end;

uint do_hash(struct dentry * dentry, struct vfsmount * vfsmnt, struct dentry * root, struct vfsmount * rootmnt);

inline static uint alloc_in_pool(char const * str, uint len);
inline static int add_hash_entry(struct op_hash_index * entry, uint parent, char const * name, uint len);
inline static uint name_hash(char const * name, uint len, uint parent);

inline static uint name_hash(char const * name, uint len, uint parent)
{
	uint hash=0;

	while (len--)
		hash = (hash + (name[len] << 4) + (name[len] >> 4)) * 11;

	return (hash ^ parent) % OP_HASH_MAP_NR;
}

/* empty ascending dname stack */
inline static void push_dname(struct qstr * dname)
{
	op_dname_stack[op_dname_top] = dname;
	if (op_dname_top != DNAME_STACK_MAX)
		op_dname_top++;
	else
		printk(KERN_ERR "oprofile: overflowed dname stack !\n");
}

inline static struct qstr * pop_dname(void)
{
	if (op_dname_top == 0)
		return NULL;

	return op_dname_stack[--op_dname_top];
}

inline static uint alloc_in_pool(char const * str, uint len)
{
	char * place = op_pool_pos;
	if (op_pool_pos + len + 1 >= op_pool_end)
		return 0;

	strcpy(place, str);
	op_pool_pos += len + 1;
	return place - op_pool_start;
}

inline static char * get_from_pool(uint index)
{
	return op_pool_start + index;
}

inline static int add_hash_entry(struct op_hash_index * entry, uint parent, char const * name, uint len)
{
	entry->name = alloc_in_pool(name, len);
	if (!entry->name)
		return -1;
	entry->parent = parent;
	return 0;
}

#endif /* OP_DCACHE_H */