View Javadoc
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>&minus;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 &minus;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 }