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 */ 013package org.jikesrvm.adaptive.measurements.organizers; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.adaptive.measurements.listeners.Listener; 017import org.jikesrvm.scheduler.Latch; 018import org.jikesrvm.scheduler.SystemThread; 019import org.vmmagic.pragma.Uninterruptible; 020import org.vmmagic.pragma.Unpreemptible; 021import 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 030public abstract class Organizer extends SystemThread { 031 032 /** Constructor */ 033 public Organizer() { 034 super("Organizer"); 035 } 036 037 /** 038 * The listener associated with this organizer. 039 * May be {@code 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 (i.e. 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}