/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.harness.scheduler.javathreads; import java.util.HashMap; import java.util.Map; import org.mmtk.vm.VM; /** * Rendezvous of all collector threads in the Java threading model. * * Each rendezvous is mediated by a separate Rendezvous object, 'current'. The * first thread to arrive will find this static field null, and create the * current Rendezvous object. Subsequent threads will rendezvous on the existing object. * * The last thread to arrive clears the 'current' field, ready for the next * rendezvous to start. */ final class Rendezvous { /** * The current active rendezvous. If this is null, the most recent rendezvous * (if any) has reached its quota, and the next thread to arrive will start * a new rendezvous. */ //private static Rendezvous current = null; private static final Map<String,Rendezvous> current = new HashMap<String,Rendezvous>(); /** * Return the current rendezvous, creating a new one if required. * @param where * @return */ private static synchronized Rendezvous current(String where, int expected) { Rendezvous cur = current.get(where); if (cur == null) { cur = new Rendezvous(where,expected); current.put(where, cur); } else { if (!where.equals(cur.where)) { /* Logic error - this should never happen */ throw new RuntimeException(String.format("Arriving at barrier %d when %s is active", where,cur.where)); } assert expected == cur.expected : "At barrier "+where+", expected="+expected+", but existing barrier expects "+cur.expected; } return cur; } /** * Clear the <code>current</code> field atomically. * @param where TODO */ private static synchronized void clearCurrent(String where) { current.put(where,null); } /** * Create a new rendezvous with the given identifier * @param where The rendezvous identifier */ private Rendezvous(String where, int expected) { this.where = where; this.expected = expected; } /** The rendezvous identifier */ private final String where; /** The rank that was given to the last thread to arrive at the rendezvous */ private int currentRank = 0; /** The expected number of threads */ private final int expected; /** * Rendezvous with all other processors, returning the rank * (that is, the order this processor arrived at the barrier). * @param expected TODO */ private synchronized int rendezvous() { int rank = ++currentRank; if (currentRank == expected) { /* This is no longer the current barrier */ clearCurrent(where); notifyAll(); } else { while (currentRank != expected) { try { /* Wait for the remaining collectors to arrive */ wait(); } catch (InterruptedException ie) { } } } return rank; } /** * Dispatch to the current collector rendezvous object * @param where * @return */ static int rendezvous(String where) { return current(where,VM.activePlan.collectorCount()).rendezvous(); } /** * Dispatch to the named mutator rendezvous object * @param where * @return */ static int rendezvous(String where, int expected) { return current("Barrier-"+where,expected).rendezvous(); } }