/** * Spins/blocks until node s is matched by a fulfill operation. * * @param s the waiting node * @param timed true if timed wait * @param nanos timeout value * @return matched node, or s if cancelled */ SNode awaitFulfill(SNode s, boolean timed, long nanos) { /* * When a node/thread is about to block, it sets its waiter * field and then rechecks state at least one more time * before actually parking, thus covering race vs * fulfiller noticing that waiter is non-null so should be * woken. * * When invoked by nodes that appear at the point of call * to be at the head of the stack, calls to park are * preceded by spins to avoid blocking when producers and * consumers are arriving very close in time. This can * happen enough to bother only on multiprocessors. * * The order of checks for returning out of main loop * reflects fact that interrupts have precedence over * normal returns, which have precedence over * timeouts. (So, on timeout, one last check for match is * done before giving up.) Except that calls from untimed * SynchronousQueue.{poll/offer} don't check interrupts * and don't wait at all, so are trapped in transfer * method rather than calling awaitFulfill. */ long lastTime = timed ? System.nanoTime() : 0; Thread w = Thread.currentThread(); SNode h = head; int spins = (shouldSpin(s) ? (timed ? maxTimedSpins : maxUntimedSpins) : 0); for (; ; ) { if (w.isInterrupted()) s.tryCancel(); SNode m = s.match; if (m != null) return m; if (timed) { long now = System.nanoTime(); nanos -= now - lastTime; lastTime = now; if (nanos <= 0) { s.tryCancel(); continue; } } if (spins > 0) spins = shouldSpin(s) ? (spins - 1) : 0; else if (s.waiter == null) s.waiter = w; // establish waiter so can park next iter else if (!timed) LockSupport.park(this); else if (nanos > spinForTimeoutThreshold) LockSupport.parkNanos(this, nanos); } }
/** * Spins/blocks until node s is fulfilled. * * @param s the waiting node * @param e the comparison value for checking match * @param timed true if timed wait * @param nanos timeout value * @return matched item, or s if cancelled */ Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) { /* Same idea as TransferStack.awaitFulfill */ long lastTime = timed ? System.nanoTime() : 0; Thread w = Thread.currentThread(); int spins = ((head.next == s) ? (timed ? maxTimedSpins : maxUntimedSpins) : 0); for (; ; ) { if (w.isInterrupted()) s.tryCancel(e); Object x = s.item; if (x != e) return x; if (timed) { long now = System.nanoTime(); nanos -= now - lastTime; lastTime = now; if (nanos <= 0) { s.tryCancel(e); continue; } } if (spins > 0) --spins; else if (s.waiter == null) s.waiter = w; else if (!timed) LockSupport.park(this); else if (nanos > spinForTimeoutThreshold) LockSupport.parkNanos(this, nanos); } }
public DispatcherResult dispatch( final ExecutionContext context, final ExecutionItem item, final Dispatchable toDispatch) throws DispatcherException { final NodesSelector nodesSelector = context.getNodeSelector(); INodeSet nodes = null; try { nodes = framework.filterAuthorizedNodes( context.getFrameworkProject(), new HashSet<String>(Arrays.asList("read", "run")), framework.filterNodeSet( nodesSelector, context.getFrameworkProject(), context.getNodesFile())); } catch (NodeFileParserException e) { throw new DispatcherException(e); } if (nodes.getNodes().size() < 1) { throw new DispatcherException("No nodes matched"); } boolean keepgoing = context.isKeepgoing(); context .getExecutionListener() .log(4, "preparing for sequential execution on " + nodes.getNodes().size() + " nodes"); final HashSet<String> nodeNames = new HashSet<String>(nodes.getNodeNames()); final HashMap<String, Object> failures = new HashMap<String, Object>(); FailedNodesListener failedListener = context.getExecutionListener().getFailedNodesListener(); if (null != failedListener) { failedListener.matchedNodes(nodeNames); } boolean interrupted = false; final Thread thread = Thread.currentThread(); boolean success = true; final HashMap<String, StatusResult> resultMap = new HashMap<String, StatusResult>(); final Collection<INodeEntry> nodes1 = nodes.getNodes(); // reorder based on configured rank property and order final String rankProperty = null != context.getNodeRankAttribute() ? context.getNodeRankAttribute() : "nodename"; final boolean rankAscending = context.isNodeRankOrderAscending(); final INodeEntryComparator comparator = new INodeEntryComparator(rankProperty); final TreeSet<INodeEntry> orderedNodes = new TreeSet<INodeEntry>(rankAscending ? comparator : Collections.reverseOrder(comparator)); orderedNodes.addAll(nodes1); for (final Object node1 : orderedNodes) { if (thread.isInterrupted() || thread instanceof ExecutionServiceThread && ((ExecutionServiceThread) thread).isAborted()) { interrupted = true; break; } final INodeEntry node = (INodeEntry) node1; context .getExecutionListener() .log( Constants.DEBUG_LEVEL, "Executing command on node: " + node.getNodename() + ", " + node.toString()); try { if (thread.isInterrupted() || thread instanceof ExecutionServiceThread && ((ExecutionServiceThread) thread).isAborted()) { interrupted = true; break; } final StatusResult result; final ExecutionContext interimcontext = new ExecutionContextImpl.Builder(context) .nodeSelector(SelectorUtils.singleNode(node.getNodename())) .build(); if (null != item) { result = framework.getExecutionService().interpretCommand(interimcontext, item, node); } else { result = toDispatch.dispatch(interimcontext, node); } if (null != result) { resultMap.put(node.getNodename(), result); } if (null == result || !result.isSuccess()) { success = false; // context.getExecutionListener().log(Constants.ERR_LEVEL, // "Failed execution for node " + node.getNodename() + ": " + // result); if (null != result) { failures.put(node.getNodename(), result); } else { failures.put(node.getNodename(), "Failed execution, result was null"); } if (!keepgoing) { break; } } else { nodeNames.remove(node.getNodename()); } } catch (Throwable e) { success = false; failures.put( node.getNodename(), "Error dispatching command to the node: " + e.getMessage()); context .getExecutionListener() .log( Constants.ERR_LEVEL, "Failed dispatching to node " + node.getNodename() + ": " + e.getMessage()); final StringWriter stringWriter = new StringWriter(); e.printStackTrace(new PrintWriter(stringWriter)); context .getExecutionListener() .log( Constants.DEBUG_LEVEL, "Failed dispatching to node " + node.getNodename() + ": " + stringWriter.toString()); if (!keepgoing) { if (failures.size() > 0 && null != failedListener) { // tell listener of failed node list failedListener.nodesFailed(failures); } throw new DispatcherException( "Failed dispatching to node " + node.getNodename() + ": " + e.getMessage(), e, node); } } } if (keepgoing && nodeNames.size() > 0) { if (null != failedListener) { // tell listener of failed node list failedListener.nodesFailed(failures); } // now fail // XXX: needs to change from exception throw new NodesetFailureException(failures); } else if (null != failedListener && failures.isEmpty() && !interrupted) { failedListener.nodesSucceeded(); } if (interrupted) { throw new DispatcherException("Node dispatch interrupted"); } final boolean status = success; return new DispatcherResult() { public Map<String, ? extends StatusResult> getResults() { return resultMap; } public boolean isSuccess() { return status; } @Override public String toString() { return "DispatcherResult{" + "status=" + isSuccess() + ", " + "results=" + getResults() + "}"; } }; }
/** * Execute applet events. Here is the state transition diagram * * <pre>{@literal * Note: (XXX) is the action * APPLET_XXX is the state * (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT -- * (applet start called) --> APPLET_START -- (applet stop called) --> APPLET_STOP -- * (applet destroyed called) --> APPLET_DESTROY --> (applet gets disposed) --> * APPLET_DISPOSE --> ... * }</pre> * * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays in the * APPLET_START state unless the applet goes away(refresh page or leave the page). So the applet * stop method called and the applet enters APPLET_STOP state. Then if the applet is revisited, it * will call applet start method and enter the APPLET_START state and stay there. * * <p>In the modern lifecycle model. When the applet first time visited, it is same as legacy * lifecycle model. However, when the applet page goes away. It calls applet stop method and * enters APPLET_STOP state and then applet destroyed method gets called and enters APPLET_DESTROY * state. * * <p>This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump * from APPLET_STOP to APPLET_DESTROY and to APPLET_INIT . * * <p>Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla * case). Same as APPLET_LOAD to APPLET_DISPOSE since all of this are triggered by browser. */ @Override public void run() { Thread curThread = Thread.currentThread(); if (curThread == loaderThread) { // if we are in the loader thread, cause // loading to occur. We may exit this with // status being APPLET_DISPOSE, APPLET_ERROR, // or APPLET_LOAD runLoader(); return; } boolean disposed = false; while (!disposed && !curThread.isInterrupted()) { AppletEvent evt; try { evt = getNextEvent(); } catch (InterruptedException e) { showAppletStatus("bail"); return; } // showAppletStatus("EVENT = " + evt.getID()); try { switch (evt.getID()) { case APPLET_LOAD: if (!okToLoad()) { break; } // This complexity allows loading of applets to be // interruptable. The actual thread loading runs // in a separate thread, so it can be interrupted // without harming the applet thread. // So that we don't have to worry about // concurrency issues, the main applet thread waits // until the loader thread terminates. // (one way or another). if (loaderThread == null) { setLoaderThread(new Thread(null, this, "AppletLoader", 0, false)); loaderThread.start(); // we get to go to sleep while this runs loaderThread.join(); setLoaderThread(null); } else { // REMIND: issue an error -- this case should never // occur. } break; case APPLET_INIT: // AppletViewer "Restart" will jump from destroy method to // init, that is why we need to check status w/ APPLET_DESTROY if (status != APPLET_LOAD && status != APPLET_DESTROY) { showAppletStatus("notloaded"); break; } applet.resize(defaultAppletSize); if (PerformanceLogger.loggingEnabled()) { PerformanceLogger.setTime("Applet Init"); PerformanceLogger.outputLog(); } applet.init(); // Need the default(fallback) font to be created in this AppContext Font f = getFont(); if (f == null || "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) && f.getSize() == 12 && f.getStyle() == Font.PLAIN) { setFont(new Font(Font.DIALOG, Font.PLAIN, 12)); } // Validate the applet in event dispatch thread // to avoid deadlock. try { final AppletPanel p = this; Runnable r = new Runnable() { @Override public void run() { p.validate(); } }; AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); } catch (InterruptedException ie) { } catch (InvocationTargetException ite) { } status = APPLET_INIT; showAppletStatus("inited"); break; case APPLET_START: { if (status != APPLET_INIT && status != APPLET_STOP) { showAppletStatus("notinited"); break; } applet.resize(currentAppletSize); applet.start(); // Validate and show the applet in event dispatch thread // to avoid deadlock. try { final AppletPanel p = this; final Applet a = applet; Runnable r = new Runnable() { @Override public void run() { p.validate(); a.setVisible(true); // Fix for BugTraq ID 4041703. // Set the default focus for an applet. if (hasInitialFocus()) { setDefaultFocus(); } } }; AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); } catch (InterruptedException ie) { } catch (InvocationTargetException ite) { } status = APPLET_START; showAppletStatus("started"); break; } case APPLET_STOP: if (status != APPLET_START) { showAppletStatus("notstarted"); break; } status = APPLET_STOP; // Hide the applet in event dispatch thread // to avoid deadlock. try { final Applet a = applet; Runnable r = new Runnable() { @Override public void run() { a.setVisible(false); } }; AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); } catch (InterruptedException ie) { } catch (InvocationTargetException ite) { } // During Applet.stop(), any AccessControlException on an involved Class remains in // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is // reused, the same exception will occur during class loading. Set the // AppletClassLoader's // exceptionStatusSet flag to allow recognition of what had happened // when reusing AppletClassLoader object. try { applet.stop(); } catch (java.security.AccessControlException e) { setExceptionStatus(e); // rethrow exception to be handled as it normally would be. throw e; } showAppletStatus("stopped"); break; case APPLET_DESTROY: if (status != APPLET_STOP && status != APPLET_INIT) { showAppletStatus("notstopped"); break; } status = APPLET_DESTROY; // During Applet.destroy(), any AccessControlException on an involved Class remains in // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is // reused, the same exception will occur during class loading. Set the // AppletClassLoader's // exceptionStatusSet flag to allow recognition of what had happened // when reusing AppletClassLoader object. try { applet.destroy(); } catch (java.security.AccessControlException e) { setExceptionStatus(e); // rethrow exception to be handled as it normally would be. throw e; } showAppletStatus("destroyed"); break; case APPLET_DISPOSE: if (status != APPLET_DESTROY && status != APPLET_LOAD) { showAppletStatus("notdestroyed"); break; } status = APPLET_DISPOSE; try { final Applet a = applet; Runnable r = new Runnable() { @Override public void run() { remove(a); } }; AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); } catch (InterruptedException ie) { } catch (InvocationTargetException ite) { } applet = null; showAppletStatus("disposed"); disposed = true; break; case APPLET_QUIT: return; } } catch (Exception e) { status = APPLET_ERROR; if (e.getMessage() != null) { showAppletStatus("exception2", e.getClass().getName(), e.getMessage()); } else { showAppletStatus("exception", e.getClass().getName()); } showAppletException(e); } catch (ThreadDeath e) { showAppletStatus("death"); return; } catch (Error e) { status = APPLET_ERROR; if (e.getMessage() != null) { showAppletStatus("error2", e.getClass().getName(), e.getMessage()); } else { showAppletStatus("error", e.getClass().getName()); } showAppletException(e); } clearLoadAbortRequest(); } }
@SuppressWarnings("unchecked") public static void main(String[] args) { String dbname; Properties props = new Properties(); Properties fileprops = new Properties(); boolean dotransactions = true; int threadcount = 1; int target = 0; boolean status = false; String label = ""; // parse arguments int argindex = 0; if (args.length == 0) { usageMessage(); System.exit(0); } while (args[argindex].startsWith("-")) { if (args[argindex].compareTo("-threads") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int tcount = Integer.parseInt(args[argindex]); props.setProperty("threadcount", tcount + ""); argindex++; } else if (args[argindex].compareTo("-target") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int ttarget = Integer.parseInt(args[argindex]); props.setProperty("target", ttarget + ""); argindex++; } else if (args[argindex].compareTo("-load") == 0) { dotransactions = false; argindex++; } else if (args[argindex].compareTo("-t") == 0) { dotransactions = true; argindex++; } else if (args[argindex].compareTo("-s") == 0) { status = true; argindex++; } else if (args[argindex].compareTo("-db") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } props.setProperty("db", args[argindex]); argindex++; } else if (args[argindex].compareTo("-l") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } label = args[argindex]; argindex++; } else if (args[argindex].compareTo("-P") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } String propfile = args[argindex]; argindex++; Properties myfileprops = new Properties(); try { myfileprops.load(new FileInputStream(propfile)); } catch (IOException e) { System.out.println(e.getMessage()); System.exit(0); } // Issue #5 - remove call to stringPropertyNames to make compilable under Java 1.5 for (Enumeration e = myfileprops.propertyNames(); e.hasMoreElements(); ) { String prop = (String) e.nextElement(); fileprops.setProperty(prop, myfileprops.getProperty(prop)); } } else if (args[argindex].compareTo("-p") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int eq = args[argindex].indexOf('='); if (eq < 0) { usageMessage(); System.exit(0); } String name = args[argindex].substring(0, eq); String value = args[argindex].substring(eq + 1); props.put(name, value); // System.out.println("["+name+"]=["+value+"]"); argindex++; } else { System.out.println("Unknown option " + args[argindex]); usageMessage(); System.exit(0); } if (argindex >= args.length) { break; } } if (argindex != args.length) { usageMessage(); System.exit(0); } // set up logging // BasicConfigurator.configure(); // overwrite file properties with properties from the command line // Issue #5 - remove call to stringPropertyNames to make compilable under Java 1.5 for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) { String prop = (String) e.nextElement(); fileprops.setProperty(prop, props.getProperty(prop)); } props = fileprops; if (!checkRequiredProperties(props)) { System.exit(0); } long maxExecutionTime = Integer.parseInt(props.getProperty(MAX_EXECUTION_TIME, "0")); // get number of threads, target and db threadcount = Integer.parseInt(props.getProperty("threadcount", "1")); dbname = props.getProperty("db", "com.yahoo.ycsb.BasicDB"); target = Integer.parseInt(props.getProperty("target", "0")); // compute the target throughput double targetperthreadperms = -1; if (target > 0) { double targetperthread = ((double) target) / ((double) threadcount); targetperthreadperms = targetperthread / 1000.0; } System.out.println("YCSB Client 0.1"); System.out.print("Command line:"); for (int i = 0; i < args.length; i++) { System.out.print(" " + args[i]); } System.out.println(); System.err.println("Loading workload..."); // show a warning message that creating the workload is taking a while // but only do so if it is taking longer than 2 seconds // (showing the message right away if the setup wasn't taking very long was confusing people) Thread warningthread = new Thread() { public void run() { try { sleep(2000); } catch (InterruptedException e) { return; } System.err.println(" (might take a few minutes for large data sets)"); } }; warningthread.start(); // set up measurements Measurements.setProperties(props); // load the workload ClassLoader classLoader = Client.class.getClassLoader(); Workload workload = null; try { Class workloadclass = classLoader.loadClass(props.getProperty(WORKLOAD_PROPERTY)); workload = (Workload) workloadclass.newInstance(); } catch (Exception e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } try { workload.init(props); } catch (WorkloadException e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } warningthread.interrupt(); // run the workload System.err.println("Starting test."); int opcount; if (dotransactions) { opcount = Integer.parseInt(props.getProperty(OPERATION_COUNT_PROPERTY, "0")); } else { if (props.containsKey(INSERT_COUNT_PROPERTY)) { opcount = Integer.parseInt(props.getProperty(INSERT_COUNT_PROPERTY, "0")); } else { opcount = Integer.parseInt(props.getProperty(RECORD_COUNT_PROPERTY, "0")); } } Vector<Thread> threads = new Vector<Thread>(); for (int threadid = 0; threadid < threadcount; threadid++) { DB db = null; try { db = DBFactory.newDB(dbname, props); } catch (UnknownDBException e) { System.out.println("Unknown DB " + dbname); System.exit(0); } Thread t = new ClientThread( db, dotransactions, workload, threadid, threadcount, props, opcount / threadcount, targetperthreadperms); threads.add(t); // t.start(); } StatusThread statusthread = null; if (status) { boolean standardstatus = false; if (props.getProperty("measurementtype", "").compareTo("timeseries") == 0) { standardstatus = true; } statusthread = new StatusThread(threads, label, standardstatus); statusthread.start(); } long st = System.currentTimeMillis(); for (Thread t : threads) { t.start(); } Thread terminator = null; if (maxExecutionTime > 0) { terminator = new TerminatorThread(maxExecutionTime, threads, workload); terminator.start(); } int opsDone = 0; for (Thread t : threads) { try { t.join(); opsDone += ((ClientThread) t).getOpsDone(); } catch (InterruptedException e) { } } long en = System.currentTimeMillis(); if (terminator != null && !terminator.isInterrupted()) { terminator.interrupt(); } if (status) { statusthread.interrupt(); } try { workload.cleanup(); } catch (WorkloadException e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } try { exportMeasurements(props, opsDone, en - st); } catch (IOException e) { System.err.println("Could not export measurements, error: " + e.getMessage()); e.printStackTrace(); System.exit(-1); } System.exit(0); }