Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: runtime/vm/simulator_arm.cc

Issue 677193002: - Use the simulator to do atomic operations that could also (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/simulator_arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_arm.cc
===================================================================
--- runtime/vm/simulator_arm.cc (revision 41327)
+++ runtime/vm/simulator_arm.cc (working copy)
@@ -678,55 +678,14 @@
// Synchronization primitives support.
Mutex* Simulator::exclusive_access_lock_ = NULL;
-Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags];
-int Simulator::next_address_tag_;
+Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] =
+ {{NULL, 0}};
+int Simulator::next_address_tag_ = 0;
-void Simulator::SetExclusiveAccess(uword addr) {
- Isolate* isolate = Isolate::Current();
- ASSERT(isolate != NULL);
- int i = 0;
- while ((i < kNumAddressTags) &&
- (exclusive_access_state_[i].isolate != isolate)) {
- i++;
- }
- if (i == kNumAddressTags) {
- i = next_address_tag_;
- if (++next_address_tag_ == kNumAddressTags) next_address_tag_ = 0;
- exclusive_access_state_[i].isolate = isolate;
- }
- exclusive_access_state_[i].addr = addr;
-}
-
-
-bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
- Isolate* isolate = Isolate::Current();
- ASSERT(isolate != NULL);
- bool result = false;
- for (int i = 0; i < kNumAddressTags; i++) {
- if (exclusive_access_state_[i].isolate == isolate) {
- if (exclusive_access_state_[i].addr == addr) {
- result = true;
- }
- exclusive_access_state_[i].addr = NULL;
- continue;
- }
- if (exclusive_access_state_[i].addr == addr) {
- exclusive_access_state_[i].addr = NULL;
- }
- }
- return result;
-}
-
-
void Simulator::InitOnce() {
- // Setup exclusive access state.
+ // Setup exclusive access state lock.
exclusive_access_lock_ = new Mutex();
- for (int i = 0; i < kNumAddressTags; i++) {
- exclusive_access_state_[i].isolate = NULL;
- exclusive_access_state_[i].addr = NULL;
- }
- next_address_tag_ = 0;
}
@@ -1112,16 +1071,59 @@
// Synchronization primitives support.
+void Simulator::SetExclusiveAccess(uword addr) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate);
+ int i = 0;
+ // Find an entry for this isolate in the exclusive access state.
+ while ((i < kNumAddressTags) &&
+ (exclusive_access_state_[i].isolate != isolate)) {
+ i++;
+ }
+ // Round-robin replacement of previously used entries.
+ if (i == kNumAddressTags) {
+ i = next_address_tag_;
+ if (++next_address_tag_ == kNumAddressTags) {
+ next_address_tag_ = 0;
+ }
+ exclusive_access_state_[i].isolate = isolate;
+ }
+ // Remember the address being reserved.
+ exclusive_access_state_[i].addr = addr;
+}
+
+
+bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ ASSERT(addr != 0);
+ DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate);
+ bool result = false;
+ for (int i = 0; i < kNumAddressTags; i++) {
+ if (exclusive_access_state_[i].isolate == isolate) {
+ // Check whether the current isolate's address reservation matches.
+ if (exclusive_access_state_[i].addr == addr) {
+ result = true;
+ }
+ exclusive_access_state_[i].addr = 0;
+ } else if (exclusive_access_state_[i].addr == addr) {
+ // Other isolates with matching address lose their reservations.
+ exclusive_access_state_[i].addr = 0;
+ }
+ }
+ return result;
+}
+
+
void Simulator::ClearExclusive() {
- // This lock is initialized in Simulator::InitOnce().
MutexLocker ml(exclusive_access_lock_);
- // Set exclusive access to open state for this isolate.
- HasExclusiveAccessAndOpen(NULL);
+ // Remove the reservation for this isolate.
+ SetExclusiveAccess(NULL);
}
intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
- // This lock is initialized in Simulator::InitOnce().
MutexLocker ml(exclusive_access_lock_);
SetExclusiveAccess(addr);
return ReadW(addr, instr);
@@ -1129,7 +1131,6 @@
intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
- // This lock is initialized in Simulator::InitOnce().
MutexLocker ml(exclusive_access_lock_);
bool write_allowed = HasExclusiveAccessAndOpen(addr);
if (write_allowed) {
@@ -1143,8 +1144,10 @@
uword Simulator::CompareExchange(uword* address,
uword compare_value,
uword new_value) {
- // This lock is initialized in Simulator::InitOnce().
MutexLocker ml(exclusive_access_lock_);
+ // We do not get a reservation as it would be guaranteed to be found when
+ // writing below. No other isolate is able to make a reservation while we
+ // hold the lock.
uword value = *address;
if (value == compare_value) {
*address = new_value;
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/simulator_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698