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 }