| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_ARM) | 9 #if defined(TARGET_ARCH_ARM) |
| 10 | 10 |
| (...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 | 1075 |
| 1076 | 1076 |
| 1077 void Simulator::WriteB(uword addr, uint8_t value) { | 1077 void Simulator::WriteB(uword addr, uint8_t value) { |
| 1078 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1078 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| 1079 *ptr = value; | 1079 *ptr = value; |
| 1080 } | 1080 } |
| 1081 | 1081 |
| 1082 | 1082 |
| 1083 // Synchronization primitives support. | 1083 // Synchronization primitives support. |
| 1084 void Simulator::SetExclusiveAccess(uword addr) { | 1084 void Simulator::SetExclusiveAccess(uword addr) { |
| 1085 Isolate* isolate = Isolate::Current(); | 1085 Thread* thread = Thread::Current(); |
| 1086 ASSERT(isolate != NULL); | 1086 ASSERT(thread != NULL); |
| 1087 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1087 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
| 1088 int i = 0; | 1088 int i = 0; |
| 1089 // Find an entry for this isolate in the exclusive access state. | 1089 // Find an entry for this thread in the exclusive access state. |
| 1090 while ((i < kNumAddressTags) && | 1090 while ((i < kNumAddressTags) && |
| 1091 (exclusive_access_state_[i].isolate != isolate)) { | 1091 (exclusive_access_state_[i].thread != thread)) { |
| 1092 i++; | 1092 i++; |
| 1093 } | 1093 } |
| 1094 // Round-robin replacement of previously used entries. | 1094 // Round-robin replacement of previously used entries. |
| 1095 if (i == kNumAddressTags) { | 1095 if (i == kNumAddressTags) { |
| 1096 i = next_address_tag_; | 1096 i = next_address_tag_; |
| 1097 if (++next_address_tag_ == kNumAddressTags) { | 1097 if (++next_address_tag_ == kNumAddressTags) { |
| 1098 next_address_tag_ = 0; | 1098 next_address_tag_ = 0; |
| 1099 } | 1099 } |
| 1100 exclusive_access_state_[i].isolate = isolate; | 1100 exclusive_access_state_[i].thread = thread; |
| 1101 } | 1101 } |
| 1102 // Remember the address being reserved. | 1102 // Remember the address being reserved. |
| 1103 exclusive_access_state_[i].addr = addr; | 1103 exclusive_access_state_[i].addr = addr; |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 | 1106 |
| 1107 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1107 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
| 1108 Isolate* isolate = Isolate::Current(); | 1108 Thread* thread = Thread::Current(); |
| 1109 ASSERT(isolate != NULL); | 1109 ASSERT(thread != NULL); |
| 1110 ASSERT(addr != 0); | 1110 ASSERT(addr != 0); |
| 1111 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1111 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
| 1112 bool result = false; | 1112 bool result = false; |
| 1113 for (int i = 0; i < kNumAddressTags; i++) { | 1113 for (int i = 0; i < kNumAddressTags; i++) { |
| 1114 if (exclusive_access_state_[i].isolate == isolate) { | 1114 if (exclusive_access_state_[i].thread == thread) { |
| 1115 // Check whether the current isolate's address reservation matches. | 1115 // Check whether the current thread's address reservation matches. |
| 1116 if (exclusive_access_state_[i].addr == addr) { | 1116 if (exclusive_access_state_[i].addr == addr) { |
| 1117 result = true; | 1117 result = true; |
| 1118 } | 1118 } |
| 1119 exclusive_access_state_[i].addr = 0; | 1119 exclusive_access_state_[i].addr = 0; |
| 1120 } else if (exclusive_access_state_[i].addr == addr) { | 1120 } else if (exclusive_access_state_[i].addr == addr) { |
| 1121 // Other isolates with matching address lose their reservations. | 1121 // Other threads with matching address lose their reservations. |
| 1122 exclusive_access_state_[i].addr = 0; | 1122 exclusive_access_state_[i].addr = 0; |
| 1123 } | 1123 } |
| 1124 } | 1124 } |
| 1125 return result; | 1125 return result; |
| 1126 } | 1126 } |
| 1127 | 1127 |
| 1128 | 1128 |
| 1129 void Simulator::ClearExclusive() { | 1129 void Simulator::ClearExclusive() { |
| 1130 MutexLocker ml(exclusive_access_lock_); | 1130 MutexLocker ml(exclusive_access_lock_); |
| 1131 // Remove the reservation for this isolate. | 1131 // Remove the reservation for this thread. |
| 1132 SetExclusiveAccess(NULL); | 1132 SetExclusiveAccess(NULL); |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 | 1135 |
| 1136 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { | 1136 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { |
| 1137 MutexLocker ml(exclusive_access_lock_); | 1137 MutexLocker ml(exclusive_access_lock_); |
| 1138 SetExclusiveAccess(addr); | 1138 SetExclusiveAccess(addr); |
| 1139 return ReadW(addr, instr); | 1139 return ReadW(addr, instr); |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 | 1142 |
| 1143 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { | 1143 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { |
| 1144 MutexLocker ml(exclusive_access_lock_); | 1144 MutexLocker ml(exclusive_access_lock_); |
| 1145 bool write_allowed = HasExclusiveAccessAndOpen(addr); | 1145 bool write_allowed = HasExclusiveAccessAndOpen(addr); |
| 1146 if (write_allowed) { | 1146 if (write_allowed) { |
| 1147 WriteW(addr, value, instr); | 1147 WriteW(addr, value, instr); |
| 1148 return 0; // Success. | 1148 return 0; // Success. |
| 1149 } | 1149 } |
| 1150 return 1; // Failure. | 1150 return 1; // Failure. |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 | 1153 |
| 1154 uword Simulator::CompareExchange(uword* address, | 1154 uword Simulator::CompareExchange(uword* address, |
| 1155 uword compare_value, | 1155 uword compare_value, |
| 1156 uword new_value) { | 1156 uword new_value) { |
| 1157 MutexLocker ml(exclusive_access_lock_); | 1157 MutexLocker ml(exclusive_access_lock_); |
| 1158 // We do not get a reservation as it would be guaranteed to be found when | 1158 // We do not get a reservation as it would be guaranteed to be found when |
| 1159 // writing below. No other isolate is able to make a reservation while we | 1159 // writing below. No other thread is able to make a reservation while we |
| 1160 // hold the lock. | 1160 // hold the lock. |
| 1161 uword value = *address; | 1161 uword value = *address; |
| 1162 if (value == compare_value) { | 1162 if (value == compare_value) { |
| 1163 *address = new_value; | 1163 *address = new_value; |
| 1164 // Same effect on exclusive access state as a successful STREX. | 1164 // Same effect on exclusive access state as a successful STREX. |
| 1165 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); | 1165 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); |
| 1166 } else { | 1166 } else { |
| 1167 // Same effect on exclusive access state as an LDREX. | 1167 // Same effect on exclusive access state as an LDREX. |
| 1168 SetExclusiveAccess(reinterpret_cast<uword>(address)); | 1168 SetExclusiveAccess(reinterpret_cast<uword>(address)); |
| 1169 } | 1169 } |
| (...skipping 2701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3871 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 3871 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 3872 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 3872 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 3873 buf->Longjmp(); | 3873 buf->Longjmp(); |
| 3874 } | 3874 } |
| 3875 | 3875 |
| 3876 } // namespace dart | 3876 } // namespace dart |
| 3877 | 3877 |
| 3878 #endif // !defined(HOST_ARCH_ARM) | 3878 #endif // !defined(HOST_ARCH_ARM) |
| 3879 | 3879 |
| 3880 #endif // defined TARGET_ARCH_ARM | 3880 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |