Skip to content

Commit

Permalink
lib: floating proportions
Browse files Browse the repository at this point in the history
Given a set of objects, floating proportions aims to efficiently give the
proportional 'activity' of a single item as compared to the whole set. Where
'activity' is a measure of a temporal property of the items.

It is efficient in that it need not inspect any other items of the set
in order to provide the answer. It is not even needed to know how many
other items there are.

It has one parameter, and that is the period of 'time' over which the
'activity' is measured.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Peter Zijlstra authored and Linus Torvalds committed Oct 17, 2007
1 parent 69cb51d commit 145ca25
Show file tree
Hide file tree
Showing 3 changed files with 505 additions and 1 deletion.
119 changes: 119 additions & 0 deletions include/linux/proportions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* FLoating proportions
*
* Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
*
* This file contains the public data structure and API definitions.
*/

#ifndef _LINUX_PROPORTIONS_H
#define _LINUX_PROPORTIONS_H

#include <linux/percpu_counter.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>

struct prop_global {
/*
* The period over which we differentiate
*
* period = 2^shift
*/
int shift;
/*
* The total event counter aka 'time'.
*
* Treated as an unsigned long; the lower 'shift - 1' bits are the
* counter bits, the remaining upper bits the period counter.
*/
struct percpu_counter events;
};

/*
* global proportion descriptor
*
* this is needed to consitently flip prop_global structures.
*/
struct prop_descriptor {
int index;
struct prop_global pg[2];
struct mutex mutex; /* serialize the prop_global switch */
};

int prop_descriptor_init(struct prop_descriptor *pd, int shift);
void prop_change_shift(struct prop_descriptor *pd, int new_shift);

/*
* ----- PERCPU ------
*/

struct prop_local_percpu {
/*
* the local events counter
*/
struct percpu_counter events;

/*
* snapshot of the last seen global state
*/
int shift;
unsigned long period;
spinlock_t lock; /* protect the snapshot state */
};

int prop_local_init_percpu(struct prop_local_percpu *pl);
void prop_local_destroy_percpu(struct prop_local_percpu *pl);
void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl);
void prop_fraction_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl,
long *numerator, long *denominator);

static inline
void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
{
unsigned long flags;

local_irq_save(flags);
__prop_inc_percpu(pd, pl);
local_irq_restore(flags);
}

/*
* ----- SINGLE ------
*/

struct prop_local_single {
/*
* the local events counter
*/
unsigned long events;

/*
* snapshot of the last seen global state
* and a lock protecting this state
*/
int shift;
unsigned long period;
spinlock_t lock; /* protect the snapshot state */
};

#define INIT_PROP_LOCAL_SINGLE(name) \
{ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
}

int prop_local_init_single(struct prop_local_single *pl);
void prop_local_destroy_single(struct prop_local_single *pl);
void __prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl);
void prop_fraction_single(struct prop_descriptor *pd, struct prop_local_single *pl,
long *numerator, long *denominator);

static inline
void prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl)
{
unsigned long flags;

local_irq_save(flags);
__prop_inc_single(pd, pl);
local_irq_restore(flags);
}

#endif /* _LINUX_PROPORTIONS_H */
3 changes: 2 additions & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o irq_regs.o reciprocal_div.o argv_split.o
sha1.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o

lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
Expand Down
Loading

0 comments on commit 145ca25

Please sign in to comment.