1 23 24 package EDU.oswego.cs.dl.util.concurrent.misc; 25 26 28 import javax.swing.*; 29 import javax.swing.border.*; 30 31 34 import EDU.oswego.cs.dl.util.concurrent.*; 35 import java.awt.*; 36 import java.awt.event.*; 37 import java.io.*; 38 import java.net.*; 39 import java.lang.reflect.*; 40 41 273 274 public class SynchronizationTimer { 275 276 277 public static void main(String [] args) { 278 279 JFrame frame = new JFrame("Times per call in microseconds"); 280 281 frame.addWindowListener(new WindowAdapter() { 282 public void windowClosing(WindowEvent e) {System.exit(0);} 283 }); 284 285 frame.getContentPane().add(new SynchronizationTimer().mainPanel()); 286 frame.pack(); 287 frame.setVisible(true); 288 } 289 290 293 static class TestedClass { 294 final String name; 295 final Class cls; 296 final boolean multipleOK; 297 final boolean singleOK; 298 final Class buffCls; 299 Boolean enabled_ = new Boolean (true); 300 301 synchronized void setEnabled(Boolean b) { enabled_ = b; } 302 synchronized Boolean getEnabled() { return enabled_; } 303 304 synchronized void toggleEnabled() { 305 boolean enabled = enabled_.booleanValue(); 306 enabled_ = new Boolean (!enabled); 307 } 308 309 synchronized boolean isEnabled(int nthreads, Fraction shared) { 310 boolean enabled = enabled_.booleanValue(); 311 if (!enabled) return false; 312 if (!singleOK && nthreads <= 1) return false; 313 if (!multipleOK && nthreads > 1 && shared.compareTo(0) > 0) return false; 314 return true; 315 } 316 317 318 TestedClass(String n, Class c, boolean m, boolean sok) { 319 name = n; cls = c; multipleOK = m; singleOK = sok; 320 buffCls = null; 321 } 322 323 TestedClass(String n, Class c, boolean m, boolean sok, Class bc) { 324 name = n; cls = c; multipleOK = m; singleOK = sok; 325 buffCls = bc; 326 } 327 328 static final TestedClass dummy = 329 new TestedClass("", null, false, false); 330 331 static final TestedClass[] classes = { 332 333 new TestedClass("NoSynchronization", NoSynchRNG.class, false, true), 334 new TestedClass("PublicSynchronization", PublicSynchRNG.class, true, true), 335 new TestedClass("NestedSynchronization", AllSynchRNG.class, true, true), 336 337 new TestedClass("SDelegated", SDelegatedRNG.class, true, true), 338 339 new TestedClass("SynchLongUsingSet", SynchLongRNG.class, true, true), 340 new TestedClass("SynchLongUsingCommit", AClongRNG.class, true, true), 341 342 new TestedClass("Semaphore", SemRNG.class, true, true), 343 new TestedClass("WaiterPrefSemaphore", WpSemRNG.class, true, true), 344 new TestedClass("FIFOSemaphore", FifoRNG.class, true, true), 345 new TestedClass("PrioritySemaphore", PrioritySemRNG.class, true, true), 346 new TestedClass("Mutex", MutexRNG.class, true, true), 347 new TestedClass("ReentrantLock", RlockRNG.class, true, true), 348 349 new TestedClass("WriterPrefRWLock", WpRWlockRNG.class, true, true), 350 new TestedClass("ReaderPrefRWLock", ReaderPrefRWlockRNG.class, true, true), 351 new TestedClass("FIFORWLock", FIFORWlockRNG.class, true, true), 352 new TestedClass("ReentrantRWL", ReentrantRWlockRNG.class, true, true), 353 354 355 356 new TestedClass("LinkedQueue", ChanRNG.class, true, true, 357 LinkedQueue.class), 358 359 new TestedClass("WaitFreeQueue", ChanRNG.class, true, true, 360 WaitFreeQueue.class), 361 362 new TestedClass("BoundedLinkedQueue", ChanRNG.class, true, true, 363 BoundedLinkedQueue.class), 364 new TestedClass("BoundedBuffer", ChanRNG.class, true, true, 365 BoundedBuffer.class), 366 new TestedClass("CondVarBoundedBuffer", ChanRNG.class, true, true, 367 CVBuffer.class), 368 new TestedClass("BoundedPriorityQueue", ChanRNG.class, true, true, 369 BoundedPriorityQueue.class), 370 new TestedClass("Slot", ChanRNG.class, true, true, 371 Slot.class), 372 new TestedClass("SynchronousChannel", ChanRNG.class, true, false, 374 SynchronousChannel.class), 375 376 377 new TestedClass("DirectExecutor", DirectExecutorRNG.class, true, true), 378 new TestedClass("SemaphoreLckExecutor", LockedSemRNG.class, true, true), 379 new TestedClass("QueuedExecutor", QueuedExecutorRNG.class, true, true), 380 new TestedClass("ThreadedExecutor", ThreadedExecutorRNG.class, true, true), 381 new TestedClass("PooledExecutor", PooledExecutorRNG.class, true, true), 382 383 }; 385 } 386 387 388 389 391 static final int[] nthreadsChoices = { 392 1, 393 2, 394 4, 395 8, 396 16, 397 32, 398 64, 399 128, 400 256, 401 512, 402 1024 403 }; 404 405 static final int BLOCK_MODE = 0; 406 static final int TIMEOUT_MODE = 1; 407 408 static final int[] syncModes = { BLOCK_MODE, TIMEOUT_MODE, }; 409 410 412 static String modeToString(int m) { 413 String sms; 414 if (m == BLOCK_MODE) sms = "block"; 415 else if (m == TIMEOUT_MODE) sms = "timeout"; 416 else sms = "No such mode"; 417 return sms; 418 } 419 420 static String biasToString(int b) { 421 String sms; 422 if (b < 0) sms = "slower producer"; 423 else if (b == 0) sms = "balanced prod/cons rate"; 424 else if (b > 0) sms = "slower consumer"; 425 else sms = "No such bias"; 426 return sms; 427 } 428 429 430 static String p2ToString(int n) { String suf = ""; 432 if (n >= 1024) { 433 n = n / 1024; 434 suf = "K"; 435 if (n >= 1024) { 436 n = n / 1024; 437 suf = "M"; 438 } 439 } 440 return n + suf; 441 } 442 443 static final int PRECISION = 10; 445 static String formatTime(long ns, boolean showDecimal) { 446 long intpart = ns / PRECISION; 447 long decpart = ns % PRECISION; 448 if (!showDecimal) { 449 if (decpart >= PRECISION/2) 450 ++intpart; 451 return Long.toString(intpart); 452 } 453 else { 454 String sint = Long.toString(intpart); 455 String sdec = Long.toString(decpart); 456 if (decpart == 0) { 457 int z = PRECISION; 458 while (z > 10) { 459 sdec = "0" + sdec; 460 z /= 10; 461 } 462 } 463 String ts = sint + "." + sdec; 464 return ts; 465 } 466 } 467 468 static class ThreadInfo { 469 final String name; 470 final int number; 471 Boolean enabled; 472 ThreadInfo(int nthr) { 473 number = nthr; 474 name = p2ToString(nthr); 475 enabled = new Boolean (true); 476 } 477 478 synchronized Boolean getEnabled() { return enabled; } 479 synchronized void setEnabled(Boolean v) { enabled = v; } 480 synchronized void toggleEnabled() { 481 enabled = new Boolean (!enabled.booleanValue()); 482 } 483 } 484 485 final ThreadInfo[] threadInfo = new ThreadInfo[nthreadsChoices.length]; 486 487 boolean threadEnabled(int nthreads) { 488 return threadInfo[nthreads].getEnabled().booleanValue(); 489 } 490 491 493 final static int headerRows = 1; 494 final static int classColumn = 0; 495 final static int headerColumns = 1; 496 final int tableRows = TestedClass.classes.length + headerRows; 497 final int tableColumns = nthreadsChoices.length + headerColumns; 498 499 final JComponent[][] resultTable_ = new JComponent[tableRows][tableColumns]; 500 501 JPanel resultPanel() { 502 503 JPanel[] colPanel = new JPanel[tableColumns]; 504 for (int col = 0; col < tableColumns; ++col) { 505 colPanel[col] = new JPanel(); 506 colPanel[col].setLayout(new GridLayout(tableRows, 1)); 507 if (col != 0) 508 colPanel[col].setBackground(Color.white); 509 } 510 511 Color hdrbg = colPanel[0].getBackground(); 512 Border border = new LineBorder(hdrbg); 513 514 Font font = new Font("Dialog", Font.PLAIN, 12); 515 Dimension labDim = new Dimension(40, 16); 516 Dimension cbDim = new Dimension(154, 16); 517 518 JLabel cornerLab = new JLabel(" Classes \\ Threads"); 519 cornerLab.setMinimumSize(cbDim); 520 cornerLab.setPreferredSize(cbDim); 521 cornerLab.setFont(font); 522 resultTable_[0][0] = cornerLab; 523 colPanel[0].add(cornerLab); 524 525 for (int col = 1; col < tableColumns; ++col) { 526 final int nthreads = col - headerColumns; 527 JCheckBox tcb = new JCheckBox(threadInfo[nthreads].name, true); 528 tcb.addActionListener(new ActionListener() { 529 public void actionPerformed(ActionEvent evt) { 530 threadInfo[nthreads].toggleEnabled(); 531 }}); 532 533 534 tcb.setMinimumSize(labDim); 535 tcb.setPreferredSize(labDim); 536 tcb.setFont(font); 537 tcb.setBackground(hdrbg); 538 resultTable_[0][col] = tcb; 539 colPanel[col].add(tcb); 540 } 541 542 543 for (int row = 1; row < tableRows; ++row) { 544 final int cls = row - headerRows; 545 546 JCheckBox cb = new JCheckBox(TestedClass.classes[cls].name, true); 547 cb.addActionListener(new ActionListener() { 548 public void actionPerformed(ActionEvent evt) { 549 TestedClass.classes[cls].toggleEnabled(); 550 }}); 551 552 resultTable_[row][0] = cb; 553 cb.setMinimumSize(cbDim); 554 cb.setPreferredSize(cbDim); 555 cb.setFont(font); 556 colPanel[0].add(cb); 557 558 for (int col = 1; col < tableColumns; ++col) { 559 int nthreads = col - headerColumns; 560 JLabel lab = new JLabel(""); 561 resultTable_[row][col] = lab; 562 563 lab.setMinimumSize(labDim); 564 lab.setPreferredSize(labDim); 565 lab.setBorder(border); 566 lab.setFont(font); 567 lab.setBackground(Color.white); 568 lab.setForeground(Color.black); 569 lab.setHorizontalAlignment(JLabel.RIGHT); 570 571 colPanel[col].add(lab); 572 } 573 } 574 575 JPanel tblPanel = new JPanel(); 576 tblPanel.setLayout(new BoxLayout(tblPanel, BoxLayout.X_AXIS)); 577 for (int col = 0; col < tableColumns; ++col) { 578 tblPanel.add(colPanel[col]); 579 } 580 581 return tblPanel; 582 583 } 584 585 void setTime(final long ns, int clsIdx, int nthrIdx) { 586 int row = clsIdx+headerRows; 587 int col = nthrIdx+headerColumns; 588 final JLabel cell = (JLabel)(resultTable_[row][col]); 589 590 SwingUtilities.invokeLater(new Runnable () { 591 public void run() { 592 cell.setText(formatTime(ns, true)); 593 } 594 }); 595 } 596 597 598 599 void clearTable() { 600 for (int i = 1; i < tableRows; ++i) { 601 for (int j = 1; j < tableColumns; ++j) { 602 ((JLabel)(resultTable_[i][j])).setText(""); 603 } 604 } 605 } 606 607 void setChecks(final boolean setting) { 608 for (int i = 0; i < TestedClass.classes.length; ++i) { 609 TestedClass.classes[i].setEnabled(new Boolean (setting)); 610 ((JCheckBox)resultTable_[i+1][0]).setSelected(setting); 611 } 612 } 613 614 615 public SynchronizationTimer() { 616 for (int i = 0; i < threadInfo.length; ++i) 617 threadInfo[i] = new ThreadInfo(nthreadsChoices[i]); 618 619 } 620 621 final SynchronizedInt nextClassIdx_ = new SynchronizedInt(0); 622 final SynchronizedInt nextThreadIdx_ = new SynchronizedInt(0); 623 624 625 JPanel mainPanel() { 626 new PrintStart(); JPanel paramPanel = new JPanel(); 628 paramPanel.setLayout(new GridLayout(5, 3)); 629 630 JPanel buttonPanel = new JPanel(); 631 buttonPanel.setLayout(new GridLayout(1, 3)); 632 633 startstop_.addActionListener(new ActionListener() { 634 public void actionPerformed(ActionEvent evt) { 635 if (running_.get()) 636 cancel(); 637 else { 638 try { 639 startTestSeries(new TestSeries()); 640 } 641 catch (InterruptedException ex) { 642 endTestSeries(); 643 } 644 } 645 }}); 646 647 paramPanel.add(startstop_); 648 649 JPanel p1 = new JPanel(); 650 p1.setLayout(new GridLayout(1, 2)); 651 652 JButton continueButton = new JButton("Continue"); 653 654 continueButton.addActionListener(new ActionListener() { 655 public void actionPerformed(ActionEvent evt) { 656 if (!running_.get()) { 657 try { 658 startTestSeries(new TestSeries(nextClassIdx_.get(), 659 nextThreadIdx_.get())); 660 } 661 catch (InterruptedException ex) { 662 endTestSeries(); 663 } 664 } 665 }}); 666 667 p1.add(continueButton); 668 669 JButton clearButton = new JButton("Clear cells"); 670 671 clearButton.addActionListener(new ActionListener(){ 672 public void actionPerformed(ActionEvent evt) { 673 clearTable(); 674 } 675 }); 676 677 p1.add(clearButton); 678 679 paramPanel.add(p1); 680 681 JPanel p3 = new JPanel(); 682 p3.setLayout(new GridLayout(1, 2)); 683 684 JButton setButton = new JButton("All classes"); 685 686 setButton.addActionListener(new ActionListener(){ 687 public void actionPerformed(ActionEvent evt) { 688 setChecks(true); 689 } 690 }); 691 692 p3.add(setButton); 693 694 695 JButton unsetButton = new JButton("No classes"); 696 697 unsetButton.addActionListener(new ActionListener(){ 698 public void actionPerformed(ActionEvent evt) { 699 setChecks(false); 700 } 701 }); 702 703 p3.add(unsetButton); 704 paramPanel.add(p3); 705 706 JPanel p2 = new JPanel(); 707 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS)); 709 710 711 JCheckBox consoleBox = new JCheckBox("Console echo"); 712 consoleBox.addItemListener(new ItemListener() { 713 public void itemStateChanged(ItemEvent evt) { 714 echoToSystemOut.complement(); 715 } 716 }); 717 718 719 720 JLabel poolinfo = new JLabel("Active threads: 0"); 721 722 p2.add(poolinfo); 723 p2.add(consoleBox); 724 725 paramPanel.add(p2); 726 727 paramPanel.add(contentionBox()); 728 paramPanel.add(itersBox()); 729 paramPanel.add(cloopBox()); 730 paramPanel.add(barrierBox()); 731 paramPanel.add(exchangeBox()); 732 paramPanel.add(biasBox()); 733 paramPanel.add(capacityBox()); 734 paramPanel.add(timeoutBox()); 735 paramPanel.add(syncModePanel()); 736 paramPanel.add(producerSyncModePanel()); 737 paramPanel.add(consumerSyncModePanel()); 738 739 startPoolStatus(poolinfo); 740 741 JPanel mainPanel = new JPanel(); 742 mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); 743 744 JPanel tblPanel = resultPanel(); 745 746 mainPanel.add(tblPanel); 747 mainPanel.add(paramPanel); 748 return mainPanel; 749 } 750 751 752 753 754 JComboBox syncModePanel() { 755 JComboBox syncModeComboBox = new JComboBox(); 756 757 for (int j = 0; j < syncModes.length; ++j) { 758 String lab = "Locks: " + modeToString(syncModes[j]); 759 syncModeComboBox.addItem(lab); 760 } 761 syncModeComboBox.addItemListener(new ItemListener() { 762 public void itemStateChanged(ItemEvent evt) { 763 JComboBox src = (JComboBox)(evt.getItemSelectable()); 764 int idx = src.getSelectedIndex(); 765 RNG.syncMode.set(syncModes[idx]); 766 } 767 }); 768 769 RNG.syncMode.set(syncModes[0]); 770 syncModeComboBox.setSelectedIndex(0); 771 return syncModeComboBox; 772 } 773 774 JComboBox producerSyncModePanel() { 775 JComboBox producerSyncModeComboBox = new JComboBox(); 776 777 for (int j = 0; j < syncModes.length; ++j) { 778 String lab = "Producers: " + modeToString(syncModes[j]); 779 producerSyncModeComboBox.addItem(lab); 780 } 781 producerSyncModeComboBox.addItemListener(new ItemListener() { 782 public void itemStateChanged(ItemEvent evt) { 783 JComboBox src = (JComboBox)(evt.getItemSelectable()); 784 int idx = src.getSelectedIndex(); 785 RNG.producerMode.set(syncModes[idx]); 786 } 787 }); 788 789 RNG.producerMode.set(syncModes[0]); 790 producerSyncModeComboBox.setSelectedIndex(0); 791 return producerSyncModeComboBox; 792 } 793 794 JComboBox consumerSyncModePanel() { 795 JComboBox consumerSyncModeComboBox = new JComboBox(); 796 797 for (int j = 0; j < syncModes.length; ++j) { 798 String lab = "Consumers: " + modeToString(syncModes[j]); 799 consumerSyncModeComboBox.addItem(lab); 800 } 801 consumerSyncModeComboBox.addItemListener(new ItemListener() { 802 public void itemStateChanged(ItemEvent evt) { 803 JComboBox src = (JComboBox)(evt.getItemSelectable()); 804 int idx = src.getSelectedIndex(); 805 RNG.consumerMode.set(syncModes[idx]); 806 } 807 }); 808 809 RNG.consumerMode.set(syncModes[0]); 810 consumerSyncModeComboBox.setSelectedIndex(0); 811 return consumerSyncModeComboBox; 812 } 813 814 815 816 JComboBox contentionBox() { 817 final Fraction[] contentionChoices = { 818 new Fraction(0, 1), 819 new Fraction(1, 16), 820 new Fraction(1, 8), 821 new Fraction(1, 4), 822 new Fraction(1, 2), 823 new Fraction(1, 1) 824 }; 825 826 JComboBox contentionComboBox = new JComboBox(); 827 828 for (int j = 0; j < contentionChoices.length; ++j) { 829 String lab = contentionChoices[j].asDouble() * 100.0 + 830 "% contention/sharing"; 831 contentionComboBox.addItem(lab); 832 } 833 contentionComboBox.addItemListener(new ItemListener() { 834 public void itemStateChanged(ItemEvent evt) { 835 JComboBox src = (JComboBox)(evt.getItemSelectable()); 836 int idx = src.getSelectedIndex(); 837 contention_.set(contentionChoices[idx]); 838 } 839 }); 840 841 contention_.set(contentionChoices[3]); 842 contentionComboBox.setSelectedIndex(3); 843 return contentionComboBox; 844 } 845 846 JComboBox itersBox() { 847 final int[] loopsPerTestChoices = { 848 1, 849 16, 850 256, 851 1024, 852 2 * 1024, 853 4 * 1024, 854 8 * 1024, 855 16 * 1024, 856 32 * 1024, 857 64 * 1024, 858 128 * 1024, 859 256 * 1024, 860 512 * 1024, 861 1024 * 1024, 862 }; 863 864 JComboBox precComboBox = new JComboBox(); 865 866 for (int j = 0; j < loopsPerTestChoices.length; ++j) { 867 String lab = p2ToString(loopsPerTestChoices[j]) + 868 " calls per thread per test"; 869 precComboBox.addItem(lab); 870 } 871 precComboBox.addItemListener(new ItemListener() { 872 public void itemStateChanged(ItemEvent evt) { 873 JComboBox src = (JComboBox)(evt.getItemSelectable()); 874 int idx = src.getSelectedIndex(); 875 loopsPerTest_.set(loopsPerTestChoices[idx]); 876 } 877 }); 878 879 loopsPerTest_.set(loopsPerTestChoices[8]); 880 precComboBox.setSelectedIndex(8); 881 882 return precComboBox; 883 } 884 885 JComboBox cloopBox() { 886 final int[] computationsPerCallChoices = { 887 1, 888 2, 889 4, 890 8, 891 16, 892 32, 893 64, 894 128, 895 256, 896 512, 897 1024, 898 2 * 1024, 899 4 * 1024, 900 8 * 1024, 901 16 * 1024, 902 32 * 1024, 903 64 * 1024, 904 }; 905 906 JComboBox cloopComboBox = new JComboBox(); 907 908 for (int j = 0; j < computationsPerCallChoices.length; ++j) { 909 String lab = p2ToString(computationsPerCallChoices[j]) + 910 " computations per call"; 911 cloopComboBox.addItem(lab); 912 } 913 cloopComboBox.addItemListener(new ItemListener() { 914 public void itemStateChanged(ItemEvent evt) { 915 JComboBox src = (JComboBox)(evt.getItemSelectable()); 916 int idx = src.getSelectedIndex(); 917 RNG.computeLoops.set(computationsPerCallChoices[idx]); 918 } 919 }); 920 921 RNG.computeLoops.set(computationsPerCallChoices[3]); 922 cloopComboBox.setSelectedIndex(3); 923 return cloopComboBox; 924 } 925 926 JComboBox barrierBox() { 927 final int[] itersPerBarrierChoices = { 928 1, 929 2, 930 4, 931 8, 932 16, 933 32, 934 64, 935 128, 936 256, 937 512, 938 1024, 939 2 * 1024, 940 4 * 1024, 941 8 * 1024, 942 16 * 1024, 943 32 * 1024, 944 64 * 1024, 945 128 * 1024, 946 256 * 1024, 947 512 * 1024, 948 1024 * 1024, 949 }; 950 951 JComboBox barrierComboBox = new JComboBox(); 952 953 for (int j = 0; j < itersPerBarrierChoices.length; ++j) { 954 String lab = p2ToString(itersPerBarrierChoices[j]) + 955 " iterations per barrier"; 956 barrierComboBox.addItem(lab); 957 } 958 barrierComboBox.addItemListener(new ItemListener() { 959 public void itemStateChanged(ItemEvent evt) { 960 JComboBox src = (JComboBox)(evt.getItemSelectable()); 961 int idx = src.getSelectedIndex(); 962 RNG.itersPerBarrier.set(itersPerBarrierChoices[idx]); 963 } 964 }); 965 966 RNG.itersPerBarrier.set(itersPerBarrierChoices[13]); 967 barrierComboBox.setSelectedIndex(13); 968 969 972 return barrierComboBox; 973 } 974 975 JComboBox exchangeBox() { 976 final int[] exchangerChoices = { 977 1, 978 2, 979 4, 980 8, 981 16, 982 32, 983 64, 984 128, 985 256, 986 512, 987 1024, 988 }; 989 990 JComboBox exchComboBox = new JComboBox(); 991 992 for (int j = 0; j < exchangerChoices.length; ++j) { 993 String lab = p2ToString(exchangerChoices[j]) + 994 " max threads per barrier"; 995 exchComboBox.addItem(lab); 996 } 997 exchComboBox.addItemListener(new ItemListener() { 998 public void itemStateChanged(ItemEvent evt) { 999 JComboBox src = (JComboBox)(evt.getItemSelectable()); 1000 int idx = src.getSelectedIndex(); 1001 RNG.exchangeParties.set(exchangerChoices[idx]); 1002 } 1003 }); 1004 1005 RNG.exchangeParties.set(exchangerChoices[1]); 1006 exchComboBox.setSelectedIndex(1); 1007 return exchComboBox; 1008 } 1009 1010 JComboBox biasBox() { 1011 final int[] biasChoices = { 1012 -1, 1013 0, 1014 1 1015 }; 1016 1017 1018 JComboBox biasComboBox = new JComboBox(); 1019 1020 for (int j = 0; j < biasChoices.length; ++j) { 1021 String lab = biasToString(biasChoices[j]); 1022 biasComboBox.addItem(lab); 1023 } 1024 biasComboBox.addItemListener(new ItemListener() { 1025 public void itemStateChanged(ItemEvent evt) { 1026 JComboBox src = (JComboBox)(evt.getItemSelectable()); 1027 int idx = src.getSelectedIndex(); 1028 RNG.bias.set(biasChoices[idx]); 1029 } 1030 }); 1031 1032 RNG.bias.set(biasChoices[1]); 1033 biasComboBox.setSelectedIndex(1); 1034 return biasComboBox; 1035 } 1036 1037 JComboBox capacityBox() { 1038 1039 final int[] bufferCapacityChoices = { 1040 1, 1041 4, 1042 64, 1043 256, 1044 1024, 1045 4096, 1046 16 * 1024, 1047 64 * 1024, 1048 256 * 1024, 1049 1024 * 1024, 1050 }; 1051 1052 JComboBox bcapComboBox = new JComboBox(); 1053 1054 for (int j = 0; j < bufferCapacityChoices.length; ++j) { 1055 String lab = p2ToString(bufferCapacityChoices[j]) + 1056 " element bounded buffers"; 1057 bcapComboBox.addItem(lab); 1058 } 1059 bcapComboBox.addItemListener(new ItemListener() { 1060 public void itemStateChanged(ItemEvent evt) { 1061 JComboBox src = (JComboBox)(evt.getItemSelectable()); 1062 int idx = src.getSelectedIndex(); 1063 DefaultChannelCapacity.set(bufferCapacityChoices[idx]); 1064 } 1065 }); 1066 1067 1068 DefaultChannelCapacity.set(bufferCapacityChoices[3]); 1069 bcapComboBox.setSelectedIndex(3); 1070 return bcapComboBox; 1071 } 1072 1073 JComboBox timeoutBox() { 1074 1075 1076 final long[] timeoutChoices = { 1077 0, 1078 1, 1079 10, 1080 100, 1081 1000, 1082 10000, 1083 100000, 1084 }; 1085 1086 1087 JComboBox timeoutComboBox = new JComboBox(); 1088 1089 for (int j = 0; j < timeoutChoices.length; ++j) { 1090 String lab = timeoutChoices[j] + " msec timeouts"; 1091 timeoutComboBox.addItem(lab); 1092 } 1093 timeoutComboBox.addItemListener(new ItemListener() { 1094 public void itemStateChanged(ItemEvent evt) { 1095 JComboBox src = (JComboBox)(evt.getItemSelectable()); 1096 int idx = src.getSelectedIndex(); 1097 RNG.timeout.set(timeoutChoices[idx]); 1098 } 1099 }); 1100 1101 RNG.timeout.set(timeoutChoices[3]); 1102 timeoutComboBox.setSelectedIndex(3); 1103 return timeoutComboBox; 1104 } 1105 1106 ClockDaemon timeDaemon = new ClockDaemon(); 1107 1108 void startPoolStatus(final JLabel status) { 1109 Runnable updater = new Runnable () { 1110 int lastps = 0; 1111 public void run() { 1112 final int ps = Threads.activeThreads.get(); 1113 if (lastps != ps) { 1114 lastps = ps; 1115 SwingUtilities.invokeLater(new Runnable () { 1116 public void run() { 1117 status.setText("Active threads: " + ps); 1118 } } ); 1119 } 1120 } 1121 }; 1122 timeDaemon.executePeriodically(250, updater, false); 1123 } 1124 1125 private final SynchronizedRef contention_ = new SynchronizedRef(null); 1126 private final SynchronizedInt loopsPerTest_ = new SynchronizedInt(0); 1127 1128 private final SynchronizedBoolean echoToSystemOut = 1129 new SynchronizedBoolean(false); 1130 1131 1132 private final JButton startstop_ = new JButton("Start"); 1133 1134 private WaitableInt testNumber_ = new WaitableInt(1); 1135 1136 private void runOneTest(Runnable tst) throws InterruptedException { 1137 int nt = testNumber_.get(); 1138 Threads.pool.execute(tst); 1139 testNumber_.whenNotEqual(nt, null); 1140 } 1141 1142 private void endOneTest() { 1143 testNumber_.increment(); 1144 } 1145 1146 private SynchronizedBoolean running_ = new SynchronizedBoolean(false); 1147 1148 void cancel() { 1149 synchronized (RNG.constructionLock) { 1151 try { 1152 Threads.pool.interruptAll(); 1153 } 1154 catch(Exception ex) { 1155 System.out.println("\nException during cancel:\n" + ex); 1156 return; 1157 } 1158 } 1159 } 1160 1161 1162 void startTestSeries(Runnable tst) throws InterruptedException { 1163 running_.set(true); 1164 startstop_.setText("Stop"); 1165 Threads.pool.execute(tst); 1166 } 1167 1168 class PrintStart implements Runnable { 1170 public void run() { 1171 startstop_.setText("Start"); 1172 } 1173 } 1174 1175 1176 void endTestSeries() { 1177 running_.set(false); 1178 SwingUtilities.invokeLater(new PrintStart()); 1179 } 1180 1181 1190 1191 class TestSeries implements Runnable { 1192 final int firstclass; 1193 final int firstnthreads; 1194 1195 TestSeries() { 1196 firstclass = 0; 1197 firstnthreads = 0; 1198 } 1199 1200 TestSeries(final int firstc, final int firstnt) { 1201 firstclass = firstc; 1202 firstnthreads = firstnt; 1203 } 1204 1205 public void run() { 1206 Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 1207 1208 try { 1209 int t = firstnthreads; 1210 int c = firstclass; 1211 1212 if (t < nthreadsChoices.length && 1213 c < TestedClass.classes.length) { 1214 1215 for (;;) { 1216 1217 1218 1222 if (threadEnabled(t)) { 1223 1224 TestedClass entry = TestedClass.classes[c]; 1225 1226 int nthreads = nthreadsChoices[t]; 1227 int iters = loopsPerTest_.get(); 1228 Fraction pshr = (Fraction)(contention_.get()); 1229 1230 if (entry.isEnabled(nthreads, pshr)) { 1231 1232 runOneTest(new OneTest(c, t)); 1233 } 1234 } 1235 1236 if (++c >= TestedClass.classes.length) { 1237 c = 0; 1238 if (++t >= nthreadsChoices.length) 1239 break; 1240 } 1241 1242 nextClassIdx_.set(c); 1243 nextThreadIdx_.set(t); 1244 1245 } 1246 } 1247 1248 } 1249 catch (InterruptedException ex) { 1250 Thread.currentThread().interrupt(); 1251 } 1252 finally { 1253 endTestSeries(); 1254 } 1255 } 1256 } 1257 1258 static class BarrierTimer implements Runnable { 1259 private long startTime_ = 0; 1260 private long endTime_ = 0; 1261 1262 public synchronized long getTime() { 1263 return endTime_ - startTime_; 1264 } 1265 1266 public synchronized void run() { 1267 long now = System.currentTimeMillis(); 1268 if (startTime_ == 0) 1269 startTime_ = now; 1270 else 1271 endTime_ = now; 1272 } 1273 } 1274 1275 class OneTest implements Runnable { 1276 final int clsIdx; 1277 final int nthreadsIdx; 1278 1279 OneTest(int idx, int t) { 1280 clsIdx = idx; 1281 nthreadsIdx = t; 1282 } 1283 1284 public void run() { 1285 Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3); 1286 1287 boolean wasInterrupted = false; 1288 1289 final TestedClass entry = TestedClass.classes[clsIdx]; 1290 1291 final JLabel cell = (JLabel)(resultTable_[clsIdx+1][nthreadsIdx+1]); 1292 final Color oldfg = cell.getForeground(); 1293 1294 try { 1295 1296 1297 if (Thread.interrupted()) return; 1298 if (!threadEnabled(nthreadsIdx)) return; 1299 1300 int nthreads = nthreadsChoices[nthreadsIdx]; 1301 int iters = loopsPerTest_.get(); 1302 Fraction pshr = (Fraction)(contention_.get()); 1303 1304 if (!entry.isEnabled(nthreads, pshr)) return; 1305 1306 BarrierTimer timer = new BarrierTimer(); 1307 CyclicBarrier barrier = new CyclicBarrier(nthreads+1, timer); 1308 1309 Class cls = entry.cls; 1310 Class chanCls = entry.buffCls; 1311 1312 try { 1313 SwingUtilities.invokeAndWait(new Runnable () { 1314 public void run() { 1315 cell.setForeground(Color.blue); 1316 cell.setText("RUN"); 1317 cell.repaint(); 1318 } 1319 }); 1320 } 1321 catch (InvocationTargetException ex) { 1322 ex.printStackTrace(); 1323 System.exit(-1); 1324 } 1325 synchronized (RNG.constructionLock) { 1326 RNG.reset(nthreads); 1327 1328 if (chanCls == null) { 1329 RNG shared = (RNG)(cls.newInstance()); 1330 for (int k = 0; k < nthreads; ++k) { 1331 RNG pri = (RNG)(cls.newInstance()); 1332 TestLoop l = new TestLoop(shared, pri, pshr, iters, barrier); 1333 Threads.pool.execute(l.testLoop()); 1334 } 1335 } 1336 else { 1337 Channel shared = (Channel)(chanCls.newInstance()); 1338 if (nthreads == 1) { 1339 ChanRNG single = (ChanRNG)(cls.newInstance()); 1340 single.setSingle(true); 1341 PCTestLoop l = new PCTestLoop(single.getDelegate(), single, pshr, 1342 iters, barrier, 1343 shared, shared); 1344 Threads.pool.execute(l.testLoop(true)); 1345 } 1346 else if (nthreads % 2 != 0) 1347 throw new Error ("Must have even number of threads!"); 1348 else { 1349 int npairs = nthreads / 2; 1350 1351 for (int k = 0; k < npairs; ++k) { 1352 ChanRNG t = (ChanRNG)(cls.newInstance()); 1353 t.setSingle(false); 1354 Channel chan = (Channel)(chanCls.newInstance()); 1355 1356 PCTestLoop l = new PCTestLoop(t.getDelegate(), t, pshr, 1357 iters, barrier, 1358 shared, chan); 1359 1360 Threads.pool.execute(l.testLoop(false)); 1361 Threads.pool.execute(l.testLoop(true)); 1362 1363 } 1364 } 1365 } 1366 1367 if (echoToSystemOut.get()) { 1368 System.out.print( 1369 entry.name + " " + 1370 nthreads + "T " + 1371 pshr + "S " + 1372 RNG.computeLoops.get() + "I " + 1373 RNG.syncMode.get() + "Lm " + 1374 RNG.timeout.get() + "TO " + 1375 RNG.producerMode.get() + "Pm " + 1376 RNG.consumerMode.get() + "Cm " + 1377 RNG.bias.get() + "B " + 1378 DefaultChannelCapacity.get() + "C " + 1379 RNG.exchangeParties.get() + "Xp " + 1380 RNG.itersPerBarrier.get() + "Ib : " 1381 ); 1382 } 1383 1384 } 1385 1386 1389 barrier.barrier(); 1391 barrier.barrier(); 1393 long tm = timer.getTime(); 1394 long totalIters = nthreads * iters; 1395 double dns = tm * 1000.0 * PRECISION / totalIters; 1396 long ns = Math.round(dns); 1397 1398 setTime(ns, clsIdx, nthreadsIdx); 1399 1400 if (echoToSystemOut.get()) { 1401 System.out.println(formatTime(ns, true)); 1402 } 1403 1404 } 1405 catch (BrokenBarrierException ex) { 1406 wasInterrupted = true; 1407 } 1408 catch (InterruptedException ex) { 1409 wasInterrupted = true; 1410 Thread.currentThread().interrupt(); 1411 } 1412 catch (Exception ex) { 1413 ex.printStackTrace(); 1414 System.out.println("Construction Exception?"); 1415 System.exit(-1); 1416 } 1417 finally { 1418 final boolean clear = wasInterrupted; 1419 SwingUtilities.invokeLater(new Runnable () { 1420 public void run() { 1421 if (clear) cell.setText(""); 1422 cell.setForeground(oldfg); 1423 cell.repaint(); 1424 } 1425 }); 1426 1427 Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 1428 endOneTest(); 1429 } 1430 } 1431 } 1432 1433} 1434 1435class Threads implements ThreadFactory { 1436 1437 static final SynchronizedInt activeThreads = new SynchronizedInt(0); 1438 1439 static final Threads factory = new Threads(); 1440 1441 static final PooledExecutor pool = new PooledExecutor(); 1442 1443 static { 1444 pool.setKeepAliveTime(10000); 1445 pool.setThreadFactory(factory); 1446 } 1447 1448 static class MyThread extends Thread { 1449 public MyThread(Runnable cmd) { 1450 super(cmd); 1451 } 1452 1453 public void run() { 1454 activeThreads.increment(); 1455 1456 try { 1457 super.run(); 1458 } 1459 finally { 1460 activeThreads.decrement(); 1461 } 1462 } 1463 } 1464 1465 public Thread newThread(Runnable cmd) { 1466 return new MyThread(cmd); 1467 } 1468} 1469 1470 1471 1472class TestLoop { 1473 1474 final RNG shared; 1475 final RNG primary; 1476 final int iters; 1477 final Fraction pshared; 1478 final CyclicBarrier barrier; 1479 final boolean[] useShared; 1480 final int firstidx; 1481 1482 public TestLoop(RNG sh, RNG pri, Fraction pshr, int it, CyclicBarrier br) { 1483 shared = sh; 1484 primary = pri; 1485 pshared = pshr; 1486 iters = it; 1487 barrier = br; 1488 1489 firstidx = (int)(primary.get()); 1490 1491 int num = (int)(pshared.numerator()); 1492 int denom = (int)(pshared.denominator()); 1493 1494 if (num == 0 || primary == shared) { 1495 useShared = new boolean[1]; 1496 useShared[0] = false; 1497 } 1498 else if (num >= denom) { 1499 useShared = new boolean[1]; 1500 useShared[0] = true; 1501 } 1502 else { 1503 1506 int xfactor = 1024 / denom; 1508 if (xfactor < 1) xfactor = 1; 1509 useShared = new boolean[denom * xfactor]; 1510 for (int i = 0; i < num * xfactor; ++i) 1511 useShared[i] = true; 1512 for (int i = num * xfactor; i < denom * xfactor; ++i) 1513 useShared[i] = false; 1514 1515 for (int i = 1; i < useShared.length; ++i) { 1516 int j = ((int) (shared.next() & 0x7FFFFFFF)) % (i + 1); 1517 boolean tmp = useShared[i]; 1518 useShared[i] = useShared[j]; 1519 useShared[j] = tmp; 1520 } 1521 } 1522 } 1523 1524 public Runnable testLoop() { 1525 return new Runnable () { 1526 public void run() { 1527 int itersPerBarrier = RNG.itersPerBarrier.get(); 1528 try { 1529 int delta = -1; 1530 if (primary.getClass().equals(PrioritySemRNG.class)) { 1531 delta = 2 - (int)((primary.get() % 5)); 1532 } 1533 Thread.currentThread().setPriority(Thread.NORM_PRIORITY+delta); 1534 1535 int nshared = (int)(iters * pshared.asDouble()); 1536 int nprimary = iters - nshared; 1537 int idx = firstidx; 1538 1539 barrier.barrier(); 1540 1541 for (int i = iters; i > 0; --i) { 1542 ++idx; 1543 if (i % itersPerBarrier == 0) 1544 primary.exchange(); 1545 else { 1546 1547 RNG r; 1548 1549 if (nshared > 0 && useShared[idx % useShared.length]) { 1550 --nshared; 1551 r = shared; 1552 } 1553 else { 1554 --nprimary; 1555 r = primary; 1556 } 1557 long rnd = r.next(); 1558 if (rnd % 2 == 0 && Thread.currentThread().isInterrupted()) 1559 break; 1560 } 1561 } 1562 } 1563 catch (BrokenBarrierException ex) { 1564 } 1565 catch (InterruptedException ex) { 1566 Thread.currentThread().interrupt(); 1567 } 1568 finally { 1569 try { 1570 barrier.barrier(); 1571 } 1572 catch (BrokenBarrierException ex) { 1573 } 1574 catch (InterruptedException ex) { 1575 Thread.currentThread().interrupt(); 1576 } 1577 finally { 1578 Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 1579 } 1580 1581 } 1582 } 1583 }; 1584 } 1585} 1586 1587class PCTestLoop extends TestLoop { 1588 final Channel primaryChannel; 1589 final Channel sharedChannel; 1590 1591 public PCTestLoop(RNG sh, RNG pri, Fraction pshr, int it, 1592 CyclicBarrier br, Channel shChan, Channel priChan) { 1593 super(sh, pri, pshr, it, br); 1594 sharedChannel = shChan; 1595 primaryChannel = priChan; 1596 } 1597 1598 public Runnable testLoop(final boolean isProducer) { 1599 return new Runnable () { 1600 public void run() { 1601 int delta = -1; 1602 Thread.currentThread().setPriority(Thread.NORM_PRIORITY+delta); 1603 int itersPerBarrier = RNG.itersPerBarrier.get(); 1604 try { 1605 1606 int nshared = (int)(iters * pshared.asDouble()); 1607 int nprimary = iters - nshared; 1608 int idx = firstidx; 1609 1610 barrier.barrier(); 1611 1612 ChanRNG target = (ChanRNG)(primary); 1613 1614 for (int i = iters; i > 0; --i) { 1615 ++idx; 1616 if (i % itersPerBarrier == 0) 1617 primary.exchange(); 1618 else { 1619 Channel c; 1620 1621 if (nshared > 0 && useShared[idx % useShared.length]) { 1622 --nshared; 1623 c = sharedChannel; 1624 } 1625 else { 1626 --nprimary; 1627 c = primaryChannel; 1628 } 1629 1630 long rnd; 1631 if (isProducer) 1632 rnd = target.producerNext(c); 1633 else 1634 rnd = target.consumerNext(c); 1635 1636 if (rnd % 2 == 0 && Thread.currentThread().isInterrupted()) 1637 break; 1638 } 1639 } 1640 } 1641 catch (BrokenBarrierException ex) { 1642 } 1643 catch (InterruptedException ex) { 1644 Thread.currentThread().interrupt(); 1645 } 1646 finally { 1647 try { 1648 barrier.barrier(); 1649 } 1650 catch (InterruptedException ex) { 1651 Thread.currentThread().interrupt(); 1652 } 1653 catch (BrokenBarrierException ex) { 1654 } 1655 finally { 1656 Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 1657 } 1658 } 1659 } 1660 }; 1661 } 1662} 1663 1664 1666 1667abstract class RNG implements Serializable, Comparable { 1668 static final int firstSeed = 4321; 1669 static final int rmod = 2147483647; 1670 static final int rmul = 16807; 1671 1672 static int lastSeed = firstSeed; 1673 static final int smod = 32749; 1674 static final int smul = 3125; 1675 1676 static final Object constructionLock = RNG.class; 1677 1678 1681 static final SynchronizedInt computeLoops = 1682 new SynchronizedInt(16, constructionLock); 1683 static final SynchronizedInt syncMode = 1684 new SynchronizedInt(0, constructionLock); 1685 static final SynchronizedInt producerMode = 1686 new SynchronizedInt(0, constructionLock); 1687 static final SynchronizedInt consumerMode = 1688 new SynchronizedInt(0, constructionLock); 1689 static final SynchronizedInt bias = 1690 new SynchronizedInt(0, constructionLock); 1691 static final SynchronizedLong timeout = 1692 new SynchronizedLong(100, constructionLock); 1693 static final SynchronizedInt exchangeParties = 1694 new SynchronizedInt(1, constructionLock); 1695 static final SynchronizedInt sequenceNumber = 1696 new SynchronizedInt(0, constructionLock); 1697 static final SynchronizedInt itersPerBarrier = 1698 new SynchronizedInt(0, constructionLock); 1699 1700 static Rendezvous[] exchangers_; 1701 1702 static void reset(int nthreads) { 1703 synchronized(constructionLock) { 1704 sequenceNumber.set(-1); 1705 int parties = exchangeParties.get(); 1706 if (nthreads < parties) parties = nthreads; 1707 if (nthreads % parties != 0) 1708 throw new Error ("need even multiple of parties"); 1709 exchangers_ = new Rendezvous[nthreads / parties]; 1710 for (int i = 0; i < exchangers_.length; ++i) { 1711 exchangers_[i] = new Rendezvous(parties); 1712 } 1713 } 1714 } 1715 1716 static long nextSeed() { 1717 synchronized(constructionLock) { 1718 long s = lastSeed; 1719 lastSeed = (lastSeed * smul) % smod; 1720 if (lastSeed == 0) 1721 lastSeed = (int)(System.currentTimeMillis()); 1722 return s; 1723 } 1724 } 1725 1726 final int cloops = computeLoops.get(); 1727 final int pcBias = bias.get(); 1728 final int smode = syncMode.get(); 1729 final int pmode = producerMode.get(); 1730 final int cmode = consumerMode.get(); 1731 final long waitTime = timeout.get(); 1732 Rendezvous exchanger_ = null; 1733 1734 synchronized Rendezvous getExchanger() { 1735 if (exchanger_ == null) { 1736 synchronized (constructionLock) { 1737 int idx = sequenceNumber.increment(); 1738 exchanger_ = exchangers_[idx % exchangers_.length]; 1739 } 1740 } 1741 return exchanger_; 1742 } 1743 1744 public void exchange() throws InterruptedException { 1745 Rendezvous ex = getExchanger(); 1746 Runnable r = (Runnable )(ex.rendezvous(new UpdateCommand(this))); 1747 if (r != null) r.run(); 1748 } 1749 1750 public int compareTo(Object other) { 1751 int h1 = hashCode(); 1752 int h2 = other.hashCode(); 1753 if (h1 < h2) return -1; 1754 else if (h1 > h2) return 1; 1755 else return 0; 1756 } 1757 1758 protected final long compute(long l) { 1759 int loops = (int)((l & 0x7FFFFFFF) % (cloops * 2)) + 1; 1760 for (int i = 0; i < loops; ++i) l = (l * rmul) % rmod; 1761 return (l == 0)? firstSeed : l; 1762 } 1763 1764 abstract protected void set(long l); 1765 abstract protected long internalGet(); 1766 abstract protected void internalUpdate(); 1767 1768 public long get() { return internalGet(); } 1769 public void update() { internalUpdate(); } 1770 public long next() { internalUpdate(); return internalGet(); } 1771} 1772 1773 1774class UpdateCommand implements Runnable , Serializable, Comparable { 1775 private final RNG obj_; 1776 final long cmpVal; 1777 public UpdateCommand(RNG o) { 1778 obj_ = o; 1779 cmpVal = o.get(); 1780 } 1781 1782 public void run() { obj_.update(); } 1783 1784 public int compareTo(Object x) { 1785 UpdateCommand u = (UpdateCommand)x; 1786 if (cmpVal < u.cmpVal) return -1; 1787 else if (cmpVal > u.cmpVal) return 1; 1788 else return 0; 1789 } 1790} 1791 1792 1793class GetFunction implements Callable { 1794 private final RNG obj_; 1795 public GetFunction(RNG o) { obj_ = o; } 1796 public Object call() { return new Long (obj_.get()); } 1797} 1798 1799class NextFunction implements Callable { 1800 private final RNG obj_; 1801 public NextFunction(RNG o) { obj_ = o; } 1802 public Object call() { return new Long (obj_.next()); } 1803} 1804 1805 1806class NoSynchRNG extends RNG { 1807 protected long current_ = nextSeed(); 1808 1809 protected void set(long l) { current_ = l; } 1810 protected long internalGet() { return current_; } 1811 protected void internalUpdate() { set(compute(internalGet())); } 1812} 1813 1814class PublicSynchRNG extends NoSynchRNG { 1815 public synchronized long get() { return internalGet(); } 1816 public synchronized void update() { internalUpdate(); } 1817 public synchronized long next() { internalUpdate(); return internalGet(); } 1818} 1819 1820class AllSynchRNG extends PublicSynchRNG { 1821 protected synchronized void set(long l) { current_ = l; } 1822 protected synchronized long internalGet() { return current_; } 1823 protected synchronized void internalUpdate() { set(compute(internalGet())); } 1824} 1825 1826 1827class AClongRNG extends RNG { 1828 protected final SynchronizedLong acurrent_ = 1829 new SynchronizedLong(nextSeed()); 1830 1831 protected void set(long l) { throw new Error ("No set allowed"); } 1832 protected long internalGet() { return acurrent_.get(); } 1833 1834 protected void internalUpdate() { 1835 int retriesBeforeSleep = 100; 1836 int maxSleepTime = 100; 1837 int retries = 0; 1838 for (;;) { 1839 long v = internalGet(); 1840 long n = compute(v); 1841 if (acurrent_.commit(v, n)) 1842 return; 1843 else if (++retries >= retriesBeforeSleep) { 1844 try { 1845 Thread.sleep(n % maxSleepTime); 1846 } 1847 catch (InterruptedException ex) { 1848 Thread.currentThread().interrupt(); 1849 } 1850 retries = 0; 1851 } 1852 } 1853 } 1854 1855} 1856 1857class SynchLongRNG extends RNG { 1858 protected final SynchronizedLong acurrent_ = 1859 new SynchronizedLong(nextSeed()); 1860 1861 protected void set(long l) { acurrent_.set(l); } 1862 protected long internalGet() { return acurrent_.get(); } 1863 protected void internalUpdate() { set(compute(internalGet())); } 1864 1865} 1866 1867abstract class DelegatedRNG extends RNG { 1868 protected RNG delegate_ = null; 1869 public synchronized void setDelegate(RNG d) { delegate_ = d; } 1870 protected synchronized RNG getDelegate() { return delegate_; } 1871 1872 public long get() { return getDelegate().get(); } 1873 public void update() { getDelegate().update(); } 1874 public long next() { return getDelegate().next(); } 1875 1876 protected void set(long l) { throw new Error (); } 1877 protected long internalGet() { throw new Error (); } 1878 protected void internalUpdate() { throw new Error (); } 1879 1880} 1881 1882class SDelegatedRNG extends DelegatedRNG { 1883 public SDelegatedRNG() { setDelegate(new NoSynchRNG()); } 1884 public synchronized long get() { return getDelegate().get(); } 1885 public synchronized void update() { getDelegate().update(); } 1886 public synchronized long next() { return getDelegate().next(); } 1887} 1888 1889 1890class SyncDelegatedRNG extends DelegatedRNG { 1891 protected final Sync cond_; 1892 public SyncDelegatedRNG(Sync c) { 1893 cond_ = c; 1894 setDelegate(new NoSynchRNG()); 1895 } 1896 1897 1898 protected final void acquire() throws InterruptedException { 1899 if (smode == 0) { 1900 cond_.acquire(); 1901 } 1902 else { 1903 while (!cond_.attempt(waitTime)) {} 1904 } 1905 } 1906 1907 public long next() { 1908 try { 1909 acquire(); 1910 1911 getDelegate().update(); 1912 long l = getDelegate().get(); 1913 cond_.release(); 1914 return l; 1915 } 1916 catch(InterruptedException x) { 1917 Thread.currentThread().interrupt(); 1918 return 0; 1919 } 1920 } 1921 1922 public long get() { 1923 try { 1924 acquire(); 1925 long l = getDelegate().get(); 1926 cond_.release(); 1927 return l; 1928 } 1929 catch(InterruptedException x) { 1930 Thread.currentThread().interrupt(); 1931 return 0; 1932 } 1933 } 1934 1935 public void update() { 1936 try { 1937 acquire(); 1938 getDelegate().update(); 1939 cond_.release(); 1940 } 1941 catch(InterruptedException x) { 1942 Thread.currentThread().interrupt(); 1943 } 1944 } 1945 1946 1947} 1948 1949class MutexRNG extends SyncDelegatedRNG { 1950 public MutexRNG() { super(new Mutex()); } 1951} 1952 1953 1954class SemRNG extends SyncDelegatedRNG { 1955 public SemRNG() { super(new Semaphore(1)); } 1956} 1957 1958class WpSemRNG extends SyncDelegatedRNG { 1959 public WpSemRNG() { super(new WaiterPreferenceSemaphore(1)); } 1960} 1961 1962class FifoRNG extends SyncDelegatedRNG { 1963 public FifoRNG() { super(new FIFOSemaphore(1)); } 1964} 1965 1966class PrioritySemRNG extends SyncDelegatedRNG { 1967 public PrioritySemRNG() { super(new PrioritySemaphore(1)); } 1968} 1969 1970class RlockRNG extends SyncDelegatedRNG { 1971 public RlockRNG() { super(new ReentrantLock()); } 1972} 1973 1974 1975class RWLockRNG extends NoSynchRNG { 1976 protected final ReadWriteLock lock_; 1977 public RWLockRNG(ReadWriteLock l) { 1978 lock_ = l; 1979 } 1980 1981 protected final void acquireR() throws InterruptedException { 1982 if (smode == 0) { 1983 lock_.readLock().acquire(); 1984 } 1985 else { 1986 while (!lock_.readLock().attempt(waitTime)) {} 1987 } 1988 } 1989 1990 protected final void acquireW() throws InterruptedException { 1991 if (smode == 0) { 1992 lock_.writeLock().acquire(); 1993 } 1994 else { 1995 while (!lock_.writeLock().attempt(waitTime)) {} 1996 } 1997 } 1998 1999 2000 public long next() { 2001 long l = 0; 2002 try { 2003 acquireR(); 2004 l = current_; 2005 lock_.readLock().release(); 2006 } 2007 catch(InterruptedException x) { 2008 Thread.currentThread().interrupt(); 2009 return 0; 2010 } 2011 2012 l = compute(l); 2013 2014 try { 2015 acquireW(); 2016 set(l); 2017 lock_.writeLock().release(); 2018 return l; 2019 } 2020 catch(InterruptedException x) { 2021 Thread.currentThread().interrupt(); 2022 return 0; 2023 } 2024 } 2025 2026 2027 public long get() { 2028 try { 2029 acquireR(); 2030 long l = current_; 2031 lock_.readLock().release(); 2032 return l; 2033 } 2034 catch(InterruptedException x) { 2035 Thread.currentThread().interrupt(); 2036 return 0; 2037 } 2038 } 2039 2040 public void update() { 2041 long l = 0; 2042 2043 try { 2044 acquireR(); 2045 l = current_; 2046 lock_.readLock().release(); 2047 } 2048 catch(InterruptedException x) { 2049 Thread.currentThread().interrupt(); 2050 return; 2051 } 2052 2053 l = compute(l); 2054 2055 try { 2056 acquireW(); 2057 set(l); 2058 lock_.writeLock().release(); 2059 } 2060 catch(InterruptedException x) { 2061 Thread.currentThread().interrupt(); 2062 } 2063 } 2064 2065} 2066 2067class WpRWlockRNG extends RWLockRNG { 2068 public WpRWlockRNG() { super(new WriterPreferenceReadWriteLock()); } 2069} 2070 2071class ReaderPrefRWlockRNG extends RWLockRNG { 2072 public ReaderPrefRWlockRNG() { 2073 super(new ReaderPreferenceReadWriteLock()); 2074 } 2075 2076 2077} 2078 2079class FIFORWlockRNG extends RWLockRNG { 2080 public FIFORWlockRNG() { super(new FIFOReadWriteLock()); } 2081} 2082 2083 2084class ReentrantRWlockRNG extends RWLockRNG { 2085 public ReentrantRWlockRNG() { 2086 super(new ReentrantWriterPreferenceReadWriteLock()); 2087 } 2088 2089 public void update() { long l = 0; 2091 2092 try { 2093 acquireW(); 2094 2095 try { 2096 acquireR(); 2097 l = current_; 2098 lock_.readLock().release(); 2099 } 2100 catch(InterruptedException x) { 2101 Thread.currentThread().interrupt(); 2102 return; 2103 } 2104 2105 l = compute(l); 2106 2107 set(l); 2108 lock_.writeLock().release(); 2109 } 2110 catch(InterruptedException x) { 2111 Thread.currentThread().interrupt(); 2112 } 2113 } 2114 2115} 2116 2117 2118abstract class ExecutorRNG extends DelegatedRNG { 2119 Executor executor_; 2120 2121 2122 synchronized void setExecutor(Executor e) { executor_ = e; } 2123 synchronized Executor getExecutor() { return executor_; } 2124 2125 Runnable delegatedUpdate_ = null; 2126 Callable delegatedNext_ = null; 2127 2128 synchronized Runnable delegatedUpdateCommand() { 2129 if (delegatedUpdate_ == null) 2130 delegatedUpdate_ = new UpdateCommand(getDelegate()); 2131 return delegatedUpdate_; 2132 } 2133 2134 synchronized Callable delegatedNextFunction() { 2135 if (delegatedNext_ == null) 2136 delegatedNext_ = new NextFunction(getDelegate()); 2137 return delegatedNext_; 2138 } 2139 2140 public void update() { 2141 try { 2142 getExecutor().execute(delegatedUpdateCommand()); 2143 } 2144 catch (InterruptedException ex) { 2145 Thread.currentThread().interrupt(); 2146 } 2147 } 2148 2149 FutureResult nextResult_ = null; 2151 2152 public synchronized long next() { 2153 long res = 0; 2154 try { 2155 if (nextResult_ == null) { nextResult_ = new FutureResult(); 2157 nextResult_.set(new Long (getDelegate().next())); 2158 } 2159 FutureResult currentResult = nextResult_; 2160 2161 nextResult_ = new FutureResult(); 2162 Runnable r = nextResult_.setter(delegatedNextFunction()); 2163 getExecutor().execute(r); 2164 2165 res = ((Long )(currentResult.get())).longValue(); 2166 2167 } 2168 catch (InterruptedException ex) { 2169 Thread.currentThread().interrupt(); 2170 } 2171 catch (InvocationTargetException ex) { 2172 ex.printStackTrace(); 2173 throw new Error ("Bad Callable?"); 2174 } 2175 return res; 2176 } 2177} 2178 2179class DirectExecutorRNG extends ExecutorRNG { 2180 public DirectExecutorRNG() { 2181 setDelegate(new PublicSynchRNG()); 2182 setExecutor(new DirectExecutor()); 2183 } 2184} 2185 2186class LockedSemRNG extends ExecutorRNG { 2187 public LockedSemRNG() { 2188 setDelegate(new NoSynchRNG()); 2189 setExecutor(new LockedExecutor(new Semaphore(1))); 2190 } 2191} 2192 2193class QueuedExecutorRNG extends ExecutorRNG { 2194 static final QueuedExecutor exec = new QueuedExecutor(); 2195 static { exec.setThreadFactory(Threads.factory); } 2196 public QueuedExecutorRNG() { 2197 setDelegate(new PublicSynchRNG()); 2198 setExecutor(exec); 2199 } 2200} 2201 2202class ForcedStartRunnable implements Runnable { 2203 protected final Latch latch_ = new Latch(); 2204 protected final Runnable command_; 2205 2206 ForcedStartRunnable(Runnable command) { command_ = command; } 2207 2208 public Latch started() { return latch_; } 2209 2210 public void run() { 2211 latch_.release(); 2212 command_.run(); 2213 } 2214} 2215 2216 2217class ForcedStartThreadedExecutor extends ThreadedExecutor { 2218 public void execute(Runnable command) throws InterruptedException { 2219 ForcedStartRunnable wrapped = new ForcedStartRunnable(command); 2220 super.execute(wrapped); 2221 wrapped.started().acquire(); 2222 } 2223} 2224 2225class ThreadedExecutorRNG extends ExecutorRNG { 2226 static final ThreadedExecutor exec = new ThreadedExecutor(); 2227 static { exec.setThreadFactory(Threads.factory); } 2228 2229 public ThreadedExecutorRNG() { 2230 setDelegate(new PublicSynchRNG()); 2231 setExecutor(exec); 2232 } 2233} 2234 2235 2236class PooledExecutorRNG extends ExecutorRNG { 2237 static final PooledExecutor exec = Threads.pool; 2238 2239 public PooledExecutorRNG() { 2240 setDelegate(new PublicSynchRNG()); 2241 setExecutor(exec); 2242 } 2243} 2244 2245 2246class ChanRNG extends DelegatedRNG { 2247 2248 boolean single_; 2249 2250 ChanRNG() { 2251 setDelegate(new PublicSynchRNG()); 2252 } 2253 2254 public synchronized void setSingle(boolean s) { single_ = s; } 2255 public synchronized boolean isSingle() { return single_; } 2256 2257 public long producerNext(Channel c) throws InterruptedException { 2258 RNG r = getDelegate(); 2259 if (isSingle()) { 2260 c.put(r); 2261 r = (RNG)(c.take()); 2262 r.update(); 2263 } 2264 else { 2265 if (pcBias < 0) { 2266 r.update(); 2267 r.update(); } 2269 else if (pcBias == 0) { 2270 r.update(); 2271 } 2272 2273 if (pmode == 0) { 2274 c.put(r); 2275 } 2276 else { 2277 while (!(c.offer(r, waitTime))) {} 2278 } 2279 } 2280 return r.get(); 2281 } 2282 2283 public long consumerNext(Channel c) throws InterruptedException { 2284 RNG r = null; 2285 if (cmode == 0) { 2286 r = (RNG)(c.take()); 2287 } 2288 else { 2289 while (r == null) r = (RNG)(c.poll(waitTime)); 2290 } 2291 2292 if (pcBias == 0) { 2293 r.update(); 2294 } 2295 else if (pcBias > 0) { 2296 r.update(); 2297 r.update(); 2298 } 2299 return r.get(); 2300 } 2301} 2302 2303 | Popular Tags |