001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.adaptive.measurements.organizers;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.adaptive.measurements.listeners.Listener;
017 import org.jikesrvm.scheduler.RVMThread;
018 import org.jikesrvm.scheduler.Latch;
019 import org.vmmagic.pragma.Uninterruptible;
020 import org.vmmagic.pragma.Unpreemptible;
021 import org.vmmagic.pragma.NonMoving;
022
023 /**
024 * An Organizer acts an an intermediary between the low level
025 * online measurements and the controller. An organizer may perform
026 * simple or complex tasks, but it is always simply following the
027 * instructions given by the controller.
028 */
029 @NonMoving
030 public abstract class Organizer extends RVMThread {
031
032 /** Constructor */
033 public Organizer() {
034 super("Organizer");
035 }
036
037 /**
038 * The listener associated with this organizer.
039 * May be null if the organizer has no associated listener.
040 */
041 protected Listener listener;
042
043 /** A latch used for activate/passivate. */
044 private final Latch latch = new Latch(false);
045
046 /**
047 * Called when thread is scheduled.
048 */
049 @Override
050 public void run() {
051 initialize();
052 while (true) {
053 passivate(); // wait until externally scheduled to run
054 try {
055 thresholdReached(); // we've been scheduled; do our job!
056 if (listener != null) listener.reset();
057 } catch (Exception e) {
058 e.printStackTrace();
059 if (VM.ErrorsFatal) VM.sysFail("Exception in organizer " + this);
060 }
061 }
062 }
063
064 /**
065 * Last opportunity to say something.
066 */
067 public void report() {}
068
069 /**
070 * Method that is called when the sampling threshold is reached
071 */
072 abstract void thresholdReached();
073
074 /**
075 * Organizer specific setup.
076 * A good place to install and activate any listeners.
077 */
078 protected abstract void initialize();
079
080 /*
081 * Can access the thread queue without locking because
082 * Only listener and organizer operate on the thread queue and the
083 * listener uses its own protocol to ensure that exactly 1
084 * thread will attempt to activate the organizer.
085 */
086 @Unpreemptible
087 private void passivate() {
088 if (listener != null) {
089 if (VM.VerifyAssertions) VM._assert(!listener.isActive());
090 listener.activate();
091 }
092 latch.waitAndCloseWithHandshake();
093 }
094
095 /**
096 * Called to activate the organizer thread (ie schedule it for execution).
097 */
098 @Uninterruptible
099 public void activate() {
100 if (listener != null) {
101 if (VM.VerifyAssertions) VM._assert(listener.isActive());
102 listener.passivate();
103 }
104 latch.openNoHandshake();
105 }
106 }