diff options
author | Dietmar Eggemann <dietmar.eggemann@arm.com> | 2012-03-15 12:09:41 +0000 |
---|---|---|
committer | Dave Martin <dave.martin@linaro.org> | 2012-04-19 11:18:43 +0100 |
commit | 2b011732345db02b80958848fc0f81b4300e4bb4 (patch) | |
tree | 6639364d97612e302a251e4d2bdc4f5c97e63091 | |
parent | c8f957411e0f92dd509c750801181b53c2191131 (diff) |
Hotplug: Add a cpu mask argument to event functions.
To be able to cluster switch with cpus in hotplug, the event mechanism must
be able to inform only cpus which are online when the cluster switch
occurs. Thus the event functions need the online cpu mask as an argument.
Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
-rw-r--r-- | big-little/include/events.h | 5 | ||||
-rw-r--r-- | big-little/lib/virt_events.c | 54 |
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; } |