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; 014 015import org.jikesrvm.adaptive.controller.Controller; 016import org.jikesrvm.runtime.Magic; 017import org.jikesrvm.scheduler.RVMThread; 018import org.jikesrvm.scheduler.SystemThread; 019import org.vmmagic.pragma.Uninterruptible; 020import org.vmmagic.pragma.NonMoving; 021 022/** 023 * Organizer thread collects OSR requests and inserted in controller queue 024 * The producers are application threads, and the consumer thread is the 025 * organizer. The buffer is RVMThread.threads array. The producer set 026 * it is own flag "requesting_osr" and notify the consumer. The consumer 027 * scans the threads array and collect requests. 028 */ 029@NonMoving 030public final class OSROrganizerThread extends SystemThread { 031 /** Constructor */ 032 public OSROrganizerThread() { 033 super("OSR_Organizer"); 034 } 035 036 public boolean osr_flag = false; 037 038 @Override 039 public void run() { 040 while (true) { 041 rvmThread.monitor().lockNoHandshake(); 042 if (!this.osr_flag) { 043 rvmThread.monitor().waitWithHandshake(); 044 } 045 this.osr_flag = false; /* if we get another activation after here 046 then we should rescan the threads array */ 047 rvmThread.monitor().unlock(); 048 049 processOsrRequest(); 050 } 051 } 052 053 /** 054 * Activates organizer thread if it is waiting. 055 */ 056 @Uninterruptible 057 public void activate() { 058 rvmThread.monitor().lockNoHandshake(); 059 osr_flag = true; 060 rvmThread.monitor().broadcast(); 061 rvmThread.monitor().unlock(); 062 } 063 064 private void processOsrRequest() { 065 // scan RVMThread.threads (scan down so we don't miss anything) 066 for (int i = RVMThread.numThreads - 1; i >= 0; i--) { 067 Magic.sync(); 068 RVMThread t = RVMThread.threads[i]; 069 if (t != null) { 070 boolean go = false; 071 t.monitor().lockNoHandshake(); 072 // NOTE: if threads are being removed, we may see a thread twice 073 if (t.requesting_osr) { 074 t.requesting_osr = false; 075 go = true; 076 } 077 t.monitor().unlock(); 078 if (go) { 079 Controller.controllerInputQueue.insert(5.0, t.onStackReplacementEvent); 080 } 081 } 082 } 083 } 084}