diff options
author | Miao Wang <miaowang@google.com> | 2016-07-12 14:27:21 -0700 |
---|---|---|
committer | Miao Wang <miaowang@google.com> | 2016-07-12 14:27:21 -0700 |
commit | d2f96f0c9363004d5bd8d042dbc70c1519875d33 (patch) | |
tree | 050c6790ceb2f1fdd1d02f63a82134d1e9e660d4 | |
parent | 8ffa615a12f5065af8a8eb5619fbce7c85936d77 (diff) | |
download | gemmlowp-d2f96f0c9363004d5bd8d042dbc70c1519875d33.tar.gz |
Fix worker race condition in gemmlowp.
Bug: 29993722
- Merge upstream change 67949d5f0f0e00d44709570d87f5ffa43b81e4f1
- Fix race condition by adding explicit memory barriers
Change-Id: Ie3e72ac3307e6b205d9f473aac3eb19ea43866f8
-rw-r--r-- | internal/multi_thread_gemm.h | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/internal/multi_thread_gemm.h b/internal/multi_thread_gemm.h index be33d5f..9223a42 100644 --- a/internal/multi_thread_gemm.h +++ b/internal/multi_thread_gemm.h @@ -66,6 +66,30 @@ inline int Do256NOPs() { return 0; } #endif // not GEMMLOWP_ALLOW_INLINE_ASM +inline void WriteBarrier() { +#ifdef GEMMLOWP_ARM_32 + MemoryBarrier(); +#elif defined(GEMMLOWP_ARM_64) + asm volatile("dmb ishst" ::: "memory"); +#elif defined(GEMMLOWP_X86) + asm volatile("sfence" ::: "memory"); +#else +#error "Unsupported architecture for WriteBarrier." +#endif +} + +inline void ReadBarrier() { +#ifdef GEMMLOWP_ARM_32 + MemoryBarrier(); +#elif defined(GEMMLOWP_ARM_64) + asm volatile("dmb ishld" ::: "memory"); +#elif defined(GEMMLOWP_X86) + asm volatile("lfence" ::: "memory"); +#else +#error "Unsupported architecture for ReadBarrier." +#endif +} + // Waits until *var != initial_value. // // Returns the new value of *var. The guarantee here is that @@ -255,6 +279,7 @@ class Worker { switch (state_to_act_upon) { case State::HasWork: // Got work to do! So do it, and then revert to 'Ready' state. + ReadBarrier(); assert(task_); task_->Run(); delete task_; @@ -280,6 +305,7 @@ class Worker { assert(!task_); task->local_allocator = &local_allocator_; task_ = task; + WriteBarrier(); assert(state_ == State::Ready); ChangeState(State::HasWork); } |