summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--big-little/include/events.h5
-rw-r--r--big-little/lib/virt_events.c54
2 files changed, 34 insertions, 25 deletions
diff --git a/big-little/include/events.h b/big-little/include/events.h
index 629404f..abebaa9 100644
--- a/big-little/include/events.h
+++ b/big-little/include/events.h
@@ -68,11 +68,12 @@
#define FLUSH_L2 2
#define SETUP_RST 3
+
extern void set_event(unsigned, unsigned);
-extern void set_events(unsigned);
+extern void set_events(unsigned, unsigned);
extern unsigned get_event(unsigned, unsigned);
extern void reset_event(unsigned, unsigned);
extern void wait_for_event(unsigned, unsigned);
-extern void wait_for_events(unsigned);
+extern void wait_for_events(unsigned, unsigned);
#endif /* __EVENTS_H__ */
diff --git a/big-little/lib/virt_events.c b/big-little/lib/virt_events.c
index 33e9d3b..ec5c468 100644
--- a/big-little/lib/virt_events.c
+++ b/big-little/lib/virt_events.c
@@ -66,6 +66,15 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
return;
}
+static unsigned count_set_bits(unsigned mask)
+{
+ unsigned i;
+ for (i = 0; mask; i++)
+ mask &= mask - 1;
+
+ return i;
+}
+
/*
* Wait for events from each core. Its a little trickier than
* waiting for a single event. The event register as per the
@@ -74,26 +83,29 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
* the time we enter wfe() then each flag variable should be
* checked.
*/
-void wait_for_events(unsigned event_id)
+void wait_for_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, event_count = 0, num_cpus = 0;
+ unsigned mask = 0, event_count = 0, cpu_count = 0;
+ int cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ cpu_count = count_set_bits(cpu_mask);
do {
- for (ctr = 0; ctr < num_cpus; ctr++) {
- if (TRUE == get_event(event_id, ctr)) {
+ for (mask = cpu_mask; mask;) {
+
+ /* Find the first set msb */
+ cpu_id = bitindex(mask);
+
+ /* Unset the recorded bit */
+ mask &= ~(1 << cpu_id);
+
+ if (TRUE == get_event(event_id, cpu_id)) {
event_count++;
- reset_event(event_id, ctr);
+ reset_event(event_id, cpu_id);
}
}
- if (event_count != num_cpus)
+ if (event_count != cpu_count)
wfe();
else
break;
@@ -102,19 +114,15 @@ void wait_for_events(unsigned event_id)
return;
}
-void set_events(unsigned event_id)
+void set_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, num_cpus = 0;
+ unsigned cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ while (cpu_mask) {
+ cpu_id = bitindex(cpu_mask);
+ set_event(event_id, cpu_id);
+ cpu_mask &= ~(1 << cpu_id);
+ };
- for (ctr = 0; ctr < num_cpus; ctr++) {
- set_event(event_id, ctr);
- }
return;
}