-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Arnaldo Carvalho de Melo
authored and
David S. Miller
committed
Jan 28, 2008
1 parent
e44ec58
commit 3bd2680
Showing
4 changed files
with
130 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 0c884439dbd7c895cce61c4974c8868b0f6cd4a1 | ||
refs/heads/master: de4d1db369785c29d68915edfee0cb70e8199f4c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#ifndef __LINUX_PCOUNTER_H | ||
#define __LINUX_PCOUNTER_H | ||
|
||
struct pcounter { | ||
#ifdef CONFIG_SMP | ||
void (*add)(struct pcounter *self, int inc); | ||
int (*getval)(const struct pcounter *self); | ||
int *per_cpu_values; | ||
#else | ||
int val; | ||
#endif | ||
}; | ||
|
||
/* | ||
* Special macros to let pcounters use a fast version of {getvalue|add} | ||
* using a static percpu variable per pcounter instead of an allocated one, | ||
* saving one dereference. | ||
* This might be changed if/when dynamic percpu vars become fast. | ||
*/ | ||
#ifdef CONFIG_SMP | ||
#include <linux/cpumask.h> | ||
#include <linux/percpu.h> | ||
|
||
#define DEFINE_PCOUNTER(NAME) \ | ||
static DEFINE_PER_CPU(int, NAME##_pcounter_values); \ | ||
static void NAME##_pcounter_add(struct pcounter *self, int inc) \ | ||
{ \ | ||
__get_cpu_var(NAME##_pcounter_values) += inc; \ | ||
} \ | ||
\ | ||
static int NAME##_pcounter_getval(const struct pcounter *self) \ | ||
{ \ | ||
int res = 0, cpu; \ | ||
\ | ||
for_each_possible_cpu(cpu) \ | ||
res += per_cpu(NAME##_pcounter_values, cpu); \ | ||
return res; \ | ||
} | ||
|
||
#define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER) \ | ||
MEMBER = { \ | ||
.add = NAME##_pcounter_add, \ | ||
.getval = NAME##_pcounter_getval, \ | ||
} | ||
|
||
extern void pcounter_def_add(struct pcounter *self, int inc); | ||
extern int pcounter_def_getval(const struct pcounter *self); | ||
|
||
static inline int pcounter_alloc(struct pcounter *self) | ||
{ | ||
int rc = 0; | ||
if (self->add == NULL) { | ||
self->per_cpu_values = alloc_percpu(int); | ||
if (self->per_cpu_values != NULL) { | ||
self->add = pcounter_def_add; | ||
self->getval = pcounter_def_getval; | ||
} else | ||
rc = 1; | ||
} | ||
return rc; | ||
} | ||
|
||
static inline void pcounter_free(struct pcounter *self) | ||
{ | ||
if (self->per_cpu_values != NULL) { | ||
free_percpu(self->per_cpu_values); | ||
self->per_cpu_values = NULL; | ||
self->getval = NULL; | ||
self->add = NULL; | ||
} | ||
} | ||
|
||
static inline void pcounter_add(struct pcounter *self, int inc) | ||
{ | ||
self->add(self, inc); | ||
} | ||
|
||
static inline int pcounter_getval(const struct pcounter *self) | ||
{ | ||
return self->getval(self); | ||
} | ||
|
||
#else /* CONFIG_SMP */ | ||
|
||
static inline void pcounter_add(struct pcounter *self, int inc) | ||
{ | ||
self->value += inc; | ||
} | ||
|
||
static inline int pcounter_getval(const struct pcounter *self) | ||
{ | ||
return self->val; | ||
} | ||
|
||
#define DEFINE_PCOUNTER(NAME) | ||
#define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER) | ||
#define pcounter_alloc(self) 0 | ||
#define pcounter_free(self) | ||
|
||
#endif /* CONFIG_SMP */ | ||
|
||
#endif /* __LINUX_PCOUNTER_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Define default pcounter functions | ||
* Note that often used pcounters use dedicated functions to get a speed increase. | ||
* (see DEFINE_PCOUNTER/REF_PCOUNTER_MEMBER) | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/pcounter.h> | ||
#include <linux/smp.h> | ||
|
||
void pcounter_def_add(struct pcounter *self, int inc) | ||
{ | ||
per_cpu_ptr(self->per_cpu_values, smp_processor_id())[0] += inc; | ||
} | ||
|
||
EXPORT_SYMBOL_GPL(pcounter_def_add); | ||
|
||
int pcounter_def_getval(const struct pcounter *self) | ||
{ | ||
int res = 0, cpu; | ||
for_each_possible_cpu(cpu) | ||
res += per_cpu_ptr(self->per_cpu_values, cpu)[0]; | ||
return res; | ||
} | ||
|
||
EXPORT_SYMBOL_GPL(pcounter_def_getval); |