261 } |
261 } |
262 } |
262 } |
263 |
263 |
264 private Node mergeImplLoad(Node startNode, Node expectedNext, Node head) { |
264 private Node mergeImplLoad(Node startNode, Node expectedNext, Node head) { |
265 // Atomic load version |
265 // Atomic load version |
266 Node temp = (Node) UNSAFE.getObject(startNode, offset); |
266 Node temp = (Node) UNSAFE.getReference(startNode, offset); |
267 startNode.setNext(head); |
267 startNode.setNext(head); |
268 return temp; |
268 return temp; |
269 } |
269 } |
270 |
270 |
271 private Node mergeImplSwap(Node startNode, Node expectedNext, Node head) { |
271 private Node mergeImplSwap(Node startNode, Node expectedNext, Node head) { |
272 // Swap version |
272 // Swap version |
273 return (Node) UNSAFE.getAndSetObject(startNode, offset, head); |
273 return (Node) UNSAFE.getAndSetReference(startNode, offset, head); |
274 } |
274 } |
275 |
275 |
276 private Node mergeImplCAS(Node startNode, Node expectedNext, Node head) { |
276 private Node mergeImplCAS(Node startNode, Node expectedNext, Node head) { |
277 // CAS - should always be true within a single thread - no other thread can have overwritten |
277 // CAS - should always be true within a single thread - no other thread can have overwritten |
278 if (!UNSAFE.compareAndSetObject(startNode, offset, expectedNext, head)) { |
278 if (!UNSAFE.compareAndSetReference(startNode, offset, expectedNext, head)) { |
279 throw new Error("CAS should always succeed on thread local objects, check you barrier implementation"); |
279 throw new Error("CAS should always succeed on thread local objects, check you barrier implementation"); |
280 } |
280 } |
281 return expectedNext; // continue on old circle |
281 return expectedNext; // continue on old circle |
282 } |
282 } |
283 |
283 |
284 private Node mergeImplCASFail(Node startNode, Node expectedNext, Node head) { |
284 private Node mergeImplCASFail(Node startNode, Node expectedNext, Node head) { |
285 // Force a fail |
285 // Force a fail |
286 if (UNSAFE.compareAndSetObject(startNode, offset, "fail", head)) { |
286 if (UNSAFE.compareAndSetReference(startNode, offset, "fail", head)) { |
287 throw new Error("This CAS should always fail, check you barrier implementation"); |
287 throw new Error("This CAS should always fail, check you barrier implementation"); |
288 } |
288 } |
289 if (startNode.next() != expectedNext) { |
289 if (startNode.next() != expectedNext) { |
290 throw new Error("Shouldn't have changed"); |
290 throw new Error("Shouldn't have changed"); |
291 } |
291 } |
292 return current; |
292 return current; |
293 } |
293 } |
294 |
294 |
295 private Node mergeImplWeakCAS(Node startNode, Node expectedNext, Node head) { |
295 private Node mergeImplWeakCAS(Node startNode, Node expectedNext, Node head) { |
296 // Weak CAS - should always be true within a single thread - no other thread can have overwritten |
296 // Weak CAS - should always be true within a single thread - no other thread can have overwritten |
297 if (!UNSAFE.weakCompareAndSetObject(startNode, offset, expectedNext, head)) { |
297 if (!UNSAFE.weakCompareAndSetReference(startNode, offset, expectedNext, head)) { |
298 throw new Error("Weak CAS should always succeed on thread local objects, check you barrier implementation"); |
298 throw new Error("Weak CAS should always succeed on thread local objects, check you barrier implementation"); |
299 } |
299 } |
300 return expectedNext; // continue on old circle |
300 return expectedNext; // continue on old circle |
301 } |
301 } |
302 |
302 |
303 private Node mergeImplWeakCASFail(Node startNode, Node expectedNext, Node head) { |
303 private Node mergeImplWeakCASFail(Node startNode, Node expectedNext, Node head) { |
304 // Force a fail |
304 // Force a fail |
305 if (UNSAFE.weakCompareAndSetObject(startNode, offset, "fail", head)) { |
305 if (UNSAFE.weakCompareAndSetReference(startNode, offset, "fail", head)) { |
306 throw new Error("This weak CAS should always fail, check you barrier implementation"); |
306 throw new Error("This weak CAS should always fail, check you barrier implementation"); |
307 } |
307 } |
308 if (startNode.next() != expectedNext) { |
308 if (startNode.next() != expectedNext) { |
309 throw new Error("Shouldn't have changed"); |
309 throw new Error("Shouldn't have changed"); |
310 } |
310 } |
311 return current; |
311 return current; |
312 } |
312 } |
313 |
313 |
314 private Node mergeImplCMPX(Node startNode, Node expectedNext, Node head) { |
314 private Node mergeImplCMPX(Node startNode, Node expectedNext, Node head) { |
315 // CmpX - should always be true within a single thread - no other thread can have overwritten |
315 // CmpX - should always be true within a single thread - no other thread can have overwritten |
316 Object res = UNSAFE.compareAndExchangeObject(startNode, offset, expectedNext, head); |
316 Object res = UNSAFE.compareAndExchangeReference(startNode, offset, expectedNext, head); |
317 if (!res.equals(expectedNext)) { |
317 if (!res.equals(expectedNext)) { |
318 throw new Error("Fail CmpX should always succeed on thread local objects, check you barrier implementation"); |
318 throw new Error("Fail CmpX should always succeed on thread local objects, check you barrier implementation"); |
319 } |
319 } |
320 return expectedNext; // continue on old circle |
320 return expectedNext; // continue on old circle |
321 } |
321 } |
322 |
322 |
323 private Node mergeImplCMPXFail(Node startNode, Node expectedNext, Node head) { |
323 private Node mergeImplCMPXFail(Node startNode, Node expectedNext, Node head) { |
324 Object res = UNSAFE.compareAndExchangeObject(startNode, offset, head, head); |
324 Object res = UNSAFE.compareAndExchangeReference(startNode, offset, head, head); |
325 if (startNode.next() != expectedNext) { |
325 if (startNode.next() != expectedNext) { |
326 throw new Error("Shouldn't have changed"); |
326 throw new Error("Shouldn't have changed"); |
327 } |
327 } |
328 if (head == expectedNext) { |
328 if (head == expectedNext) { |
329 throw new Error("Test malfunction"); |
329 throw new Error("Test malfunction"); |