257 } 258 default: 259 throw new Error("Unimplemented"); 260 } 261 } 262 263 private Node mergeImplLoad(Node startNode, Node expectedNext, Node head) { 264 // Atomic load version 265 Node temp = (Node) UNSAFE.getObject(startNode, offset); 266 startNode.setNext(head); 267 return temp; 268 } 269 270 private Node mergeImplSwap(Node startNode, Node expectedNext, Node head) { 271 // Swap version 272 return (Node) UNSAFE.getAndSetObject(startNode, offset, head); 273 } 274 275 private Node mergeImplCAS(Node startNode, Node expectedNext, Node head) { 276 // CAS - should always be true within a single thread - no other thread can have overwritten 277 if (!UNSAFE.compareAndSwapObject(startNode, offset, expectedNext, head)) { 278 throw new Error("CAS should always succeed on thread local objects, check you barrier implementation"); 279 } 280 return expectedNext; // continue on old circle 281 } 282 283 private Node mergeImplCASFail(Node startNode, Node expectedNext, Node head) { 284 // Force a fail 285 if (UNSAFE.compareAndSwapObject(startNode, offset, "fail", head)) { 286 throw new Error("This CAS should always fail, check you barrier implementation"); 287 } 288 if (startNode.next() != expectedNext) { 289 throw new Error("Shouldn't have changed"); 290 } 291 return current; 292 } 293 294 private Node mergeImplWeakCAS(Node startNode, Node expectedNext, Node head) { 295 // Weak CAS - should always be true within a single thread - no other thread can have overwritten 296 if (!UNSAFE.weakCompareAndSwapObject(startNode, offset, expectedNext, head)) { 297 throw new Error("Weak CAS should always succeed on thread local objects, check you barrier implementation"); 298 } 299 return expectedNext; // continue on old circle 300 } 301 302 private Node mergeImplWeakCASFail(Node startNode, Node expectedNext, Node head) { 303 // Force a fail 304 if (UNSAFE.weakCompareAndSwapObject(startNode, offset, "fail", head)) { 305 throw new Error("This weak CAS should always fail, check you barrier implementation"); 306 } 307 if (startNode.next() != expectedNext) { 308 throw new Error("Shouldn't have changed"); 309 } 310 return current; 311 } 312 313 private Node mergeImplCMPX(Node startNode, Node expectedNext, Node head) { 314 // CmpX - should always be true within a single thread - no other thread can have overwritten 315 Object res = UNSAFE.compareAndExchangeObjectVolatile(startNode, offset, expectedNext, head); 316 if (!res.equals(expectedNext)) { 317 throw new Error("Fail CmpX should always succeed on thread local objects, check you barrier implementation"); 318 } 319 return expectedNext; // continue on old circle 320 } 321 322 private Node mergeImplCMPXFail(Node startNode, Node expectedNext, Node head) { 323 Object res = UNSAFE.compareAndExchangeObjectVolatile(startNode, offset, head, head); 324 if (startNode.next() != expectedNext) { 325 throw new Error("Shouldn't have changed"); 326 } 327 if (head == expectedNext) { 328 throw new Error("Test malfunction"); 329 } 330 if (!res.equals(expectedNext)) { 331 throw new Error("This CmpX should have returned 'expectedNext' when it failed"); 332 } 333 if (res.equals(head)) { 334 throw new Error("This CmpX shouldn't have returned head when it failed. count: "+ iterations); 335 } 336 337 return current; 338 } 339 340 // Create a new branch that will replace a part of the circle 341 public Node makeBranch(Node end_node, int count) { 342 Node head = end_node; 343 for (int i = 0; i < count; i++) { | 257 } 258 default: 259 throw new Error("Unimplemented"); 260 } 261 } 262 263 private Node mergeImplLoad(Node startNode, Node expectedNext, Node head) { 264 // Atomic load version 265 Node temp = (Node) UNSAFE.getObject(startNode, offset); 266 startNode.setNext(head); 267 return temp; 268 } 269 270 private Node mergeImplSwap(Node startNode, Node expectedNext, Node head) { 271 // Swap version 272 return (Node) UNSAFE.getAndSetObject(startNode, offset, head); 273 } 274 275 private Node mergeImplCAS(Node startNode, Node expectedNext, Node head) { 276 // CAS - should always be true within a single thread - no other thread can have overwritten 277 if (!UNSAFE.compareAndSetObject(startNode, offset, expectedNext, head)) { 278 throw new Error("CAS should always succeed on thread local objects, check you barrier implementation"); 279 } 280 return expectedNext; // continue on old circle 281 } 282 283 private Node mergeImplCASFail(Node startNode, Node expectedNext, Node head) { 284 // Force a fail 285 if (UNSAFE.compareAndSetObject(startNode, offset, "fail", head)) { 286 throw new Error("This CAS should always fail, check you barrier implementation"); 287 } 288 if (startNode.next() != expectedNext) { 289 throw new Error("Shouldn't have changed"); 290 } 291 return current; 292 } 293 294 private Node mergeImplWeakCAS(Node startNode, Node expectedNext, Node head) { 295 // Weak CAS - should always be true within a single thread - no other thread can have overwritten 296 if (!UNSAFE.weakCompareAndSetObject(startNode, offset, expectedNext, head)) { 297 throw new Error("Weak CAS should always succeed on thread local objects, check you barrier implementation"); 298 } 299 return expectedNext; // continue on old circle 300 } 301 302 private Node mergeImplWeakCASFail(Node startNode, Node expectedNext, Node head) { 303 // Force a fail 304 if (UNSAFE.weakCompareAndSetObject(startNode, offset, "fail", head)) { 305 throw new Error("This weak CAS should always fail, check you barrier implementation"); 306 } 307 if (startNode.next() != expectedNext) { 308 throw new Error("Shouldn't have changed"); 309 } 310 return current; 311 } 312 313 private Node mergeImplCMPX(Node startNode, Node expectedNext, Node head) { 314 // CmpX - should always be true within a single thread - no other thread can have overwritten 315 Object res = UNSAFE.compareAndExchangeObject(startNode, offset, expectedNext, head); 316 if (!res.equals(expectedNext)) { 317 throw new Error("Fail CmpX should always succeed on thread local objects, check you barrier implementation"); 318 } 319 return expectedNext; // continue on old circle 320 } 321 322 private Node mergeImplCMPXFail(Node startNode, Node expectedNext, Node head) { 323 Object res = UNSAFE.compareAndExchangeObject(startNode, offset, head, head); 324 if (startNode.next() != expectedNext) { 325 throw new Error("Shouldn't have changed"); 326 } 327 if (head == expectedNext) { 328 throw new Error("Test malfunction"); 329 } 330 if (!res.equals(expectedNext)) { 331 throw new Error("This CmpX should have returned 'expectedNext' when it failed"); 332 } 333 if (res.equals(head)) { 334 throw new Error("This CmpX shouldn't have returned head when it failed. count: "+ iterations); 335 } 336 337 return current; 338 } 339 340 // Create a new branch that will replace a part of the circle 341 public Node makeBranch(Node end_node, int count) { 342 Node head = end_node; 343 for (int i = 0; i < count; i++) { |