| 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
|