aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiao Wang <miaowang@google.com>2016-07-12 22:41:18 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-12 22:41:18 +0000
commit9b33f095ef3f3995abae72b8fa160fb720f4bbd6 (patch)
tree050c6790ceb2f1fdd1d02f63a82134d1e9e660d4
parentabfc746e70a31fa6ad2a2ca9e76df81115097cf1 (diff)
parentd2f96f0c9363004d5bd8d042dbc70c1519875d33 (diff)
downloadgemmlowp-9b33f095ef3f3995abae72b8fa160fb720f4bbd6.tar.gz
Fix worker race condition in gemmlowp.
am: d2f96f0c93 Change-Id: Ied1b937c9a7a3e23c2b288e9aa35f83ae2b84e43
-rw-r--r--internal/multi_thread_gemm.h26
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);
}