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_MIPS) | 9 #if defined(TARGET_ARCH_MIPS) |
10 | 10 |
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 double* ptr = reinterpret_cast<double*>(addr); | 1095 double* ptr = reinterpret_cast<double*>(addr); |
1096 *ptr = value; | 1096 *ptr = value; |
1097 return; | 1097 return; |
1098 } | 1098 } |
1099 UnalignedAccess("double-precision floating point write", addr, instr); | 1099 UnalignedAccess("double-precision floating point write", addr, instr); |
1100 } | 1100 } |
1101 | 1101 |
1102 | 1102 |
1103 // Synchronization primitives support. | 1103 // Synchronization primitives support. |
1104 void Simulator::SetExclusiveAccess(uword addr) { | 1104 void Simulator::SetExclusiveAccess(uword addr) { |
1105 Isolate* isolate = Isolate::Current(); | 1105 Thread* thread = Thread::Current(); |
1106 ASSERT(isolate != NULL); | 1106 ASSERT(thread != NULL); |
1107 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1107 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
1108 int i = 0; | 1108 int i = 0; |
1109 // Find an entry for this isolate in the exclusive access state. | 1109 // Find an entry for this thread in the exclusive access state. |
1110 while ((i < kNumAddressTags) && | 1110 while ((i < kNumAddressTags) && |
1111 (exclusive_access_state_[i].isolate != isolate)) { | 1111 (exclusive_access_state_[i].thread != thread)) { |
1112 i++; | 1112 i++; |
1113 } | 1113 } |
1114 // Round-robin replacement of previously used entries. | 1114 // Round-robin replacement of previously used entries. |
1115 if (i == kNumAddressTags) { | 1115 if (i == kNumAddressTags) { |
1116 i = next_address_tag_; | 1116 i = next_address_tag_; |
1117 if (++next_address_tag_ == kNumAddressTags) { | 1117 if (++next_address_tag_ == kNumAddressTags) { |
1118 next_address_tag_ = 0; | 1118 next_address_tag_ = 0; |
1119 } | 1119 } |
1120 exclusive_access_state_[i].isolate = isolate; | 1120 exclusive_access_state_[i].thread = thread; |
1121 } | 1121 } |
1122 // Remember the address being reserved. | 1122 // Remember the address being reserved. |
1123 exclusive_access_state_[i].addr = addr; | 1123 exclusive_access_state_[i].addr = addr; |
1124 } | 1124 } |
1125 | 1125 |
1126 | 1126 |
1127 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1127 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
1128 Isolate* isolate = Isolate::Current(); | 1128 Thread* thread = Thread::Current(); |
1129 ASSERT(isolate != NULL); | 1129 ASSERT(thread != NULL); |
1130 ASSERT(addr != 0); | 1130 ASSERT(addr != 0); |
1131 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1131 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
1132 bool result = false; | 1132 bool result = false; |
1133 for (int i = 0; i < kNumAddressTags; i++) { | 1133 for (int i = 0; i < kNumAddressTags; i++) { |
1134 if (exclusive_access_state_[i].isolate == isolate) { | 1134 if (exclusive_access_state_[i].thread == thread) { |
1135 // Check whether the current isolate's address reservation matches. | 1135 // Check whether the current thread's address reservation matches. |
1136 if (exclusive_access_state_[i].addr == addr) { | 1136 if (exclusive_access_state_[i].addr == addr) { |
1137 result = true; | 1137 result = true; |
1138 } | 1138 } |
1139 exclusive_access_state_[i].addr = 0; | 1139 exclusive_access_state_[i].addr = 0; |
1140 } else if (exclusive_access_state_[i].addr == addr) { | 1140 } else if (exclusive_access_state_[i].addr == addr) { |
1141 // Other isolates with matching address lose their reservations. | 1141 // Other threads with matching address lose their reservations. |
1142 exclusive_access_state_[i].addr = 0; | 1142 exclusive_access_state_[i].addr = 0; |
1143 } | 1143 } |
1144 } | 1144 } |
1145 return result; | 1145 return result; |
1146 } | 1146 } |
1147 | 1147 |
1148 | 1148 |
1149 void Simulator::ClearExclusive() { | 1149 void Simulator::ClearExclusive() { |
1150 MutexLocker ml(exclusive_access_lock_); | 1150 MutexLocker ml(exclusive_access_lock_); |
1151 // Remove the reservation for this isolate. | 1151 // Remove the reservation for this thread. |
1152 SetExclusiveAccess(NULL); | 1152 SetExclusiveAccess(NULL); |
1153 } | 1153 } |
1154 | 1154 |
1155 | 1155 |
1156 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { | 1156 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { |
1157 MutexLocker ml(exclusive_access_lock_); | 1157 MutexLocker ml(exclusive_access_lock_); |
1158 SetExclusiveAccess(addr); | 1158 SetExclusiveAccess(addr); |
1159 return ReadW(addr, instr); | 1159 return ReadW(addr, instr); |
1160 } | 1160 } |
1161 | 1161 |
1162 | 1162 |
1163 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { | 1163 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { |
1164 MutexLocker ml(exclusive_access_lock_); | 1164 MutexLocker ml(exclusive_access_lock_); |
1165 bool write_allowed = HasExclusiveAccessAndOpen(addr); | 1165 bool write_allowed = HasExclusiveAccessAndOpen(addr); |
1166 if (write_allowed) { | 1166 if (write_allowed) { |
1167 WriteW(addr, value, instr); | 1167 WriteW(addr, value, instr); |
1168 return 0; // Success. | 1168 return 0; // Success. |
1169 } | 1169 } |
1170 return 1; // Failure. | 1170 return 1; // Failure. |
1171 } | 1171 } |
1172 | 1172 |
1173 | 1173 |
1174 uword Simulator::CompareExchange(uword* address, | 1174 uword Simulator::CompareExchange(uword* address, |
1175 uword compare_value, | 1175 uword compare_value, |
1176 uword new_value) { | 1176 uword new_value) { |
1177 MutexLocker ml(exclusive_access_lock_); | 1177 MutexLocker ml(exclusive_access_lock_); |
1178 // We do not get a reservation as it would be guaranteed to be found when | 1178 // We do not get a reservation as it would be guaranteed to be found when |
1179 // writing below. No other isolate is able to make a reservation while we | 1179 // writing below. No other thread is able to make a reservation while we |
1180 // hold the lock. | 1180 // hold the lock. |
1181 uword value = *address; | 1181 uword value = *address; |
1182 if (value == compare_value) { | 1182 if (value == compare_value) { |
1183 *address = new_value; | 1183 *address = new_value; |
1184 // Same effect on exclusive access state as a successful SC. | 1184 // Same effect on exclusive access state as a successful SC. |
1185 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); | 1185 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); |
1186 } else { | 1186 } else { |
1187 // Same effect on exclusive access state as an LL. | 1187 // Same effect on exclusive access state as an LL. |
1188 SetExclusiveAccess(reinterpret_cast<uword>(address)); | 1188 SetExclusiveAccess(reinterpret_cast<uword>(address)); |
1189 } | 1189 } |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 2487 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
2488 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2488 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
2489 buf->Longjmp(); | 2489 buf->Longjmp(); |
2490 } | 2490 } |
2491 | 2491 |
2492 } // namespace dart | 2492 } // namespace dart |
2493 | 2493 |
2494 #endif // !defined(HOST_ARCH_MIPS) | 2494 #endif // !defined(HOST_ARCH_MIPS) |
2495 | 2495 |
2496 #endif // defined TARGET_ARCH_MIPS | 2496 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |