diff options
Diffstat (limited to 'src/cpu/x86/mp_init.c')
-rw-r--r-- | src/cpu/x86/mp_init.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 57a5648ad4..61f153ea3d 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -138,14 +138,37 @@ struct cpu_map { /* Keep track of APIC and device structure for each CPU. */ static struct cpu_map cpus[CONFIG_MAX_CPUS]; -static inline void barrier_wait(atomic_t *b) +inline void barrier_wait(atomic_t *b) { while (atomic_read(b) == 0) asm ("pause"); mfence(); } -static inline void release_barrier(atomic_t *b) +/* Returns 1 if timeout occurs before barier is released. + * returns 0 if barrier is released before timeout. */ +int barrier_wait_timeout(atomic_t *b, uint32_t timeout_ms) +{ + int timeout = 0; + struct mono_time current, end; + + timer_monotonic_get(¤t); + end = current; + mono_time_add_msecs(&end, timeout_ms); + + while ((atomic_read(b) == 0) && (!mono_time_after(¤t, &end))) { + timer_monotonic_get(¤t); + asm ("pause"); + } + mfence(); + + if (mono_time_after(¤t, &end)) + timeout = 1; + + return timeout; +} + +inline void release_barrier(atomic_t *b) { mfence(); atomic_set(b, 1); |