MINI SHELL

Server : Apache/2.2.2 (Fedora)
System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686
User : apache ( 48)
PHP Version : 5.2.9
Disable Function : NONE
Directory :  /usr/share/systemtap/runtime/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/systemtap/runtime/counter.c
/* -*- linux-c -*- 
 * Counter aggregation Functions
 * Copyright (C) 2005 Red Hat Inc.
 *
 * This file is part of systemtap, and is free software.  You can
 * redistribute it and/or modify it under the terms of the GNU General
 * Public License (GPL); either version 2, or (at your option) any
 * later version.
 */

#ifndef _COUNTER_C_
#define _COUNTER_C_

/** @file counter.c
 * @brief Counter Aggregation
 */

/** @addtogroup counter Counter Aggregation
 * This is a 64-bit per-cpu Counter.  It is much more efficient than an atomic counter
 * because there is no contention between processors and caches in an SMP system. Use
 * it when you want to count things and do not read the counter often.  Ideally you
 * should wait until probe exit time to read the Counter.
 * @{
 */

/* This define will probably go away with the next checkin. */
/* locks are only here for testing */
#ifndef NEED_COUNTER_LOCKS
#define NEED_COUNTER_LOCKS 0
#endif

#if NEED_COUNTER_LOCKS == 1
#define COUNTER_LOCK(c) spin_lock(&c->lock)
#define COUNTER_UNLOCK(c) spin_unlock(&c->lock)
#else
#define COUNTER_LOCK(c) ;
#define COUNTER_UNLOCK(c) ;
#endif

struct _counter {
	int64_t count;
#if NEED_COUNTER_LOCKS == 1
	spinlock_t lock;
#endif
};

typedef struct _counter *Counter;


/** Initialize a Counter.
 * Call this during probe initialization to create a Counter
 * 
 * @return a Counter. Will be NULL on error.
 */
Counter _stp_counter_init (void)
{
	Counter cnt = alloc_percpu (struct _counter);
#if NEED_COUNTER_LOCKS == 1
	{
		int i;
		for_each_cpu(i) {
			Counter c = per_cpu_ptr (cnt, i);
			c->lock = SPIN_LOCK_UNLOCKED;
		}
	}
#endif
	return cnt;
}

/** Add to a Counter.
 * Adds an int64 to a Counter
 * 
 * @param cnt Counter
 * @param val int64 value
 */
void _stp_counter_add (Counter cnt,  int64_t val)
{
	Counter c = per_cpu_ptr (cnt, get_cpu());
	COUNTER_LOCK(c);
	c->count += val;
	COUNTER_UNLOCK(c);
	put_cpu();
}

/** Get a Counter's per-cpu value.
 * Get the value of a Counter for a specific CPU.
 * 
 * @param cnt Counter
 * @param cpu CPU number
 * @param clear Set this to have the value cleared after reading.
 * @return An int64 value.
 */
int64_t _stp_counter_get_cpu (Counter cnt, int cpu, int clear)
{
	int64_t val;
	Counter c = per_cpu_ptr (cnt, cpu);
	COUNTER_LOCK(c);
	val = c->count;
	if (clear)
		c->count = 0;
	COUNTER_UNLOCK(c);
	return val;
}

/** Get a Counter's value.
 * Get the value of a Counter. This is the sum of the counters for
 * all CPUs. Because computing this sum requires reading all of the
 * per-cpu values, doing it often will result in poor performance in
 * multiprocessor systems.
 * 
 * The clear parameter is intended for use in a polling situation when the
 * values should be immediately cleared after reading.  
 * @param cnt Counter
 * @param clear Set this to have the value cleared after reading.
 * @return An int64 value.
 */
int64_t _stp_counter_get (Counter cnt, int clear)
{
	int i;
	int64_t sum = 0;

	for_each_cpu(i) {
		Counter c = per_cpu_ptr (cnt, i);
		COUNTER_LOCK(c);
		sum += c->count;
		if (clear)
			c->count = 0;
		COUNTER_UNLOCK(c);
	}
	return sum;
}

/** Free a Counter.
 * @param cnt Counter
 */
void _stp_counter_free (Counter cnt)
{
	free_percpu (cnt);
}

/** @} */

#undef COUNTER_LOCK
#undef COUNTER_UNLOCK
#endif /* _COUNTER_C_ */


Anon7 - 2021