1 //****************************************************************************** 2 // 3 // File: WorkerConstruct.java 4 // Package: edu.rit.pj 5 // Unit: Class edu.rit.pj.WorkerConstruct 6 // 7 // This Java source file is copyright (C) 2010 by Alan Kaminsky. All rights 8 // reserved. For further information, contact the author, Alan Kaminsky, at 9 // ark@cs.rit.edu. 10 // 11 // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free 12 // software; you can redistribute it and/or modify it under the terms of the GNU 13 // General Public License as published by the Free Software Foundation; either 14 // version 3 of the License, or (at your option) any later version. 15 // 16 // PJ is distributed in the hope that it will be useful, but WITHOUT ANY 17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 18 // A PARTICULAR PURPOSE. See the GNU General Public License for more details. 19 // 20 // Linking this library statically or dynamically with other modules is making a 21 // combined work based on this library. Thus, the terms and conditions of the GNU 22 // General Public License cover the whole combination. 23 // 24 // As a special exception, the copyright holders of this library give you 25 // permission to link this library with independent modules to produce an 26 // executable, regardless of the license terms of these independent modules, and 27 // to copy and distribute the resulting executable under terms of your choice, 28 // provided that you also meet, for each linked independent module, the terms 29 // and conditions of the license of that module. An independent module is a module 30 // which is not derived from or based on this library. If you modify this library, 31 // you may extend this exception to your version of the library, but you are not 32 // obligated to do so. If you do not wish to do so, delete this exception 33 // statement from your version. 34 // 35 // A copy of the GNU General Public License is provided in the file gpl.txt. You 36 // may also obtain a copy of the GNU General Public License on the World Wide 37 // Web at http://www.gnu.org/licenses/gpl.html. 38 // 39 //****************************************************************************** 40 package edu.rit.pj; 41 42 /** 43 * Class WorkerConstruct is the common base class for all worker constructs that 44 * are executed by a {@linkplain WorkerTeam}. 45 * 46 * @author Alan Kaminsky 47 * @version 19-Jan-2010 48 */ 49 public abstract class WorkerConstruct { 50 51 // Hidden data members. 52 // 128 bytes of extra padding to avert cache interference. 53 private long p0, p1, p2, p3, p4, p5, p6, p7; 54 private long p8, p9, pa, pb, pc, pd, pe, pf; 55 56 // Worker team that is executing this worker construct, or null if none. 57 WorkerTeam myTeam; 58 59 // Exported constructors. 60 /** 61 * Construct a new worker construct. 62 */ 63 public WorkerConstruct() { 64 } 65 66 // Exported operations. 67 /** 68 * Determine if a worker team is executing this worker construct. 69 * 70 * @return True if a worker team is executing this worker construct, false 71 * otherwise. 72 */ 73 public final boolean isExecutingInParallel() { 74 return myTeam != null; 75 } 76 77 /** 78 * Returns the worker team that is executing this worker construct. 79 * 80 * @return Worker team. 81 * @exception IllegalStateException (unchecked exception) Thrown if no 82 * worker team is executing this worker construct. 83 */ 84 public final WorkerTeam team() { 85 if (myTeam == null) { 86 throw new IllegalStateException("WorkerConstruct.team(): No worker team executing"); 87 } 88 return myTeam; 89 } 90 91 /** 92 * Returns the worker region of code within which a worker team is executing 93 * this worker construct. 94 * 95 * @return Worker region. 96 * @exception IllegalStateException (unchecked exception) Thrown if no 97 * worker team is executing this worker construct. 98 */ 99 public final WorkerRegion region() { 100 if (myTeam == null) { 101 throw new IllegalStateException("WorkerConstruct.region(): No worker team executing"); 102 } 103 return myTeam.myRegion; 104 } 105 106 /** 107 * Determine the number of worker threads in the current process in the 108 * worker team executing this worker construct. This does not include the 109 * master thread if any. 110 * 111 * @return Number of worker threads in the current process. 112 * @exception IllegalStateException (unchecked exception) Thrown if no 113 * worker team is executing this worker construct. 114 */ 115 public final int getThreadCount() { 116 if (myTeam == null) { 117 throw new IllegalStateException("WorkerConstruct.getThreadCount(): No worker team executing"); 118 } 119 return myTeam.K; 120 } 121 122 /** 123 * Determine the total number of worker threads in all processes in the 124 * worker team executing this worker construct. This does not include the 125 * master thread. 126 * 127 * @return Number of worker threads in all processes. 128 * @exception IllegalStateException (unchecked exception) Thrown if no 129 * worker team is executing this worker construct. 130 */ 131 public final int getTotalThreadCount() { 132 if (myTeam == null) { 133 throw new IllegalStateException("WorkerConstruct.getTotalThreadCount(): No worker team executing"); 134 } 135 return myTeam.count; 136 } 137 138 /** 139 * Determine the index of the calling thread in the worker team executing 140 * this worker construct. Every worker thread in every process has a unique 141 * index, going from index 0 for the first thread in the first process to 142 * index <I>K</I>−1 for the last thread in the last process, where 143 * <I>K</I> is the total number of worker threads in all the processes. The 144 * master thread's index is −1. 145 * 146 * @return Index of the calling thread. 147 * @exception IllegalStateException (unchecked exception) Thrown if no 148 * worker team is executing this worker construct. Thrown if the thread 149 * calling 150 * <code>getThreadIndex()</code> is not part of the worker team executing this 151 * worker construct. 152 */ 153 public final int getThreadIndex() { 154 return getCurrentThread().myIndex; 155 } 156 157 /** 158 * Determine if the calling thread is the master thread in the worker team 159 * executing this worker construct. 160 * 161 * @return True if the calling thread is the master thread, false if the 162 * calling thread is a worker thread. 163 * @exception IllegalStateException (unchecked exception) Thrown if no 164 * worker team is executing this worker construct. Thrown if the thread 165 * calling 166 * <code>getThreadIndex()</code> is not part of the worker team executing this 167 * worker construct. 168 */ 169 public final boolean isMasterThread() { 170 return getThreadIndex() == -1; 171 } 172 173 // Hidden operations. 174 /** 175 * Get the worker team thread that is calling this method. 176 * 177 * @return Worker team thread. 178 * 179 * @exception IllegalStateException (unchecked exception) Thrown if the 180 * calling thread is not one of the worker team threads executing this 181 * worker construct. 182 */ 183 WorkerTeamThread getCurrentThread() { 184 if (myTeam == null) { 185 throw new IllegalStateException("WorkerConstruct.getCurrentThread(): No worker team executing"); 186 } 187 try { 188 WorkerTeamThread current = (WorkerTeamThread) Thread.currentThread(); 189 if (current.myTeam != this.myTeam) { 190 throw new IllegalStateException("WorkerConstruct.getCurrentThread(): Current thread is not executing this worker construct"); 191 } 192 return current; 193 } catch (ClassCastException exc) { 194 throw new IllegalStateException("WorkerConstruct.getCurrentThread(): Current thread is not a worker team thread", 195 exc); 196 } 197 } 198 199 }