root/juggler/tags/1.0.5/Threads/vjBaseThread.h

Revision 4719, 12.7 kB (checked in by patrickh, 8 years ago)

At long last, support for HP-UX 11.00 has been added! Most of the changes
had to be made to the build system which says a lot for the portability of
VR Juggler. Other changes reflect the differences between HP-UX 10.20
(where I originally tried to do the port) and HP-UX 11.00. Please note
that support for HP-UX 10.20 is now officially disabled on this branch.
There is still some hope for it in VR Juggler 1.1 and beyond where we can
run on top of NSPR.

Submitted by: Daniel Heath <DHeath@fueltechnv.com>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          $RCSfile$
27  * Date modified: $Date$
28  * Version:       $Revision$
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32 #ifndef _VJ_BASE_THREAD_H_
33 #define _VJ_BASE_THREAD_H_
34
35 #include <vjConfig.h>
36 #include <map>
37 #include <Threads/vjThreadFunctor.h>
38 #include <Threads/vjTSTable.h>            // Needed to cache a copy here
39
40 // --------------------------------------------------------------------------
41 // NOTES:
42 //    - This is used as the base class for all thread classes.
43 // --------------------------------------------------------------------------
44 class vjBaseThread
45 {
46 public:
47    vjBaseThread()
48       :  mThreadId(0)
49    {;}
50
51    virtual ~vjBaseThread()
52    {
53       ;
54    }
55
56 public:     // Thread specific data caching
57    //: Get the Thread specific data table
58    // NOTE: Users should NOT access the table directly
59    // instead, use vjTSObjectProxies
60    vjTSTable* getTSTable()
61    { return &mTSTable; }
62
63 private:
64    vjTSTable  mTSTable;      // Thread specific data for the thread
65
66 protected:
67    //: After the object has been created, call this routine to complete
68    //+ initialization.
69    // Done this way, because I need to call this based on stuff that happens
70    // in derived class's constructor.
71    //! POST: Thread is setup correctly to run.
72    //+       The thread has been registered with the system.
73    //+       Creates the thread's id (mThreadId)
74    //! ARGS: successfulCreation - Did the thread get created correctly
75    void registerThread(bool succesfulCreation);
76
77 public:
78    // -----------------------------------------------------------------------
79    //: Create a new thread that will execute functorPtr.
80    //
81    //! PRE: None.
82    //! POST: A thread (with any specified attributes) is created that begins
83    //+       executing func().
84    //
85    //! ARGS: functorPtr - Function to be executed by the thread.
86    //! ARGS: flags - Flags for the thread--not currently used in this
87    //+               implementation (optional).
88    //! ARGS: priority - Priority of created thread (optional).
89    //! ARGS: stack_addr - Alternate address for thread's stack (optional).
90    //! ARGS: stack_size - Size for thread's stack (optional).
91    //
92    //! RETURNS:  non-zero - Successful thread creation
93    //! RETURNS: -1 - Error
94    // -----------------------------------------------------------------------
95    virtual int spawn (vjBaseThreadFunctor* functorPtr, long flags = 0,
96                       u_int priority = 0, void* stack_addr = NULL,
97                       size_t stack_size = 0)
98    {
99       std::cerr << "Base spawn.  Should NOT be called." << std::endl;
100       return -1;
101    }
102
103    // -----------------------------------------------------------------------
104    //: Make the calling thread wait for the termination of this thread.
105    //
106    //! PRE: None.
107    //! POST: The caller blocks until this thread finishes its execution
108    //+       (i.e., calls the exit() method).  This routine may return
109    //+       immediately if this thread has already exited.
110    //
111    //! ARGS: status - Status value of the terminating thread when that
112    //+                thread calls the exit routine (optional).
113    //
114    //! RETURNS:  0 - Successful completion
115    //! RETURNS: -1 - Error
116    // -----------------------------------------------------------------------
117    virtual int join (void** status = 0)
118    {return -1;}
119
120    // -----------------------------------------------------------------------
121    //: Wait for one or more threads to exit.
122    //
123    //! PRE: None.
124    //! POST: The caller blocks until the specified threads finish their
125    //+       execution (i.e., call the exit() method).  This routine may
126    //+       return immediately if the specified threads have already
127    //+       exited.
128    //
129    //! ARGS: thread_array - Array of one or more thread IDs to be joined.
130    //! ARGS: n - The number of threads to join.
131    //! ARGS: ret_val - Storage for return value of an exiting thread
132    //+                 (optional).
133    //
134    //! RETURNS:  0 - Successful completion
135    //! RETURNS: -1 - Error
136    // -----------------------------------------------------------------------
137    int join (vjBaseThread* thread_array[], int n, void** ret_val = 0)
138    { return -1;}
139
140    // -----------------------------------------------------------------------
141    //: Resume the execution of a thread that was previously suspended using
142    //+ suspend().
143    //
144    //! RETURNS:  0 - Successful completion
145    //! RETURNS: -1 - Error
146    // -----------------------------------------------------------------------
147    virtual int resume()
148    {return -1;}
149
150    // -----------------------------------------------------------------------
151    //: Suspend the execution of this thread.
152    //
153    //! RETURNS:  0 - Successful completion
154    //! RETURNS: -1 - Error
155    // -----------------------------------------------------------------------
156    virtual int suspend()
157    {return -1;}
158
159    // -----------------------------------------------------------------------
160    //: Get this thread's priority.
161    //
162    //! PRE: None.
163    //! POST: The priority of this thread is returned in the integer pointer
164    //+       variable.
165    //
166    //! ARGS: prio - Pointer to an int variable that will have the thread's
167    //+              priority stored in it.
168    //
169    //! RETURNS:  0 - Successful completion
170    //! RETURNS: -1 - Error
171    // -----------------------------------------------------------------------
172    virtual int getPrio(int* prio)
173    { return -1;}
174
175    // -----------------------------------------------------------------------
176    //: Set this thread's priority.
177    //
178    //! ARGS: prio - The new priority for this thread.
179    //
180    //! RETURNS:  0 - Successful completion
181    //! RETURNS: -1 - Error
182    // -----------------------------------------------------------------------
183    virtual int setPrio(int prio)
184    { return -1;}
185
186    // -----------------------------------------------------------------------
187    //: Set the CPU affinity for this thread (the CPU on which this thread
188    //+ will exclusively run).
189    //
190    //! PRE: The thread must have been set to be a system-scope thread.
191    //! POST: The CPU affinity is set or an error status is returned.
192    //
193    //! ARGS: cpu - The CPU on which this thread will run exclusively.
194    //
195    //! RETURNS:  0 - Successful completion
196    //! RETURNS: -1 - Error
197    // -----------------------------------------------------------------------
198    virtual int setRunOn (int cpu) {
199       return -1;
200    }
201
202    // -----------------------------------------------------------------------
203    //: Get the CPU affinity for this thread (the CPU on which this thread
204    //+ exclusively runs).
205    //
206    //! PRE: The thread must have been set to be a system-scope thread, and
207    //+      a previous affinity must have been set using setRunOn().
208    //! POST: The CPU affinity for this thread is stored in the cur_cpu
209    //+       pointer.
210    //
211    //! ARGS: cur_cpu - The CPU affinity for this thread (set by a previous
212    //+                 call to setRunOn().
213    //
214    //! RETURNS:  0 - Successful completion
215    //! RETURNS: -1 - Error
216    // -----------------------------------------------------------------------
217    virtual int getRunOn (int* cur_cpu) {
218       return -1;
219    }
220
221    // -----------------------------------------------------------------------
222    //: Yield execution of the calling thread to allow a different blocked
223    //+ thread to execute.
224    // -----------------------------------------------------------------------
225    virtual void yield()
226    {;}
227
228    // -----------------------------------------------------------------------
229    //: Get the "thread ID" of this vjBaseThread object.  This is a unique
230    //+ integer value assigned when the thread was created.
231    //
232    //! RETURNS: -1 - Bad thread. Creation error.
233    //! RETURNS: other - id of thread in Juggler
234    // -----------------------------------------------------------------------
235    int32_t getTID()
236    { return mThreadId; }
237
238    // -----------------------------------------------------------------------
239    //: Is this a valid thread?
240    //
241    //! RETURNS: true - object represents a thread that has been created
242    //+                 correctly.
243    // -----------------------------------------------------------------------
244    bool valid()
245    {
246       return (mThreadId != -1);
247    }
248
249    // -----------------------------------------------------------------------
250    //: Send the specified signal to this thread (not necessarily SIGKILL).
251    //
252    //! POST: This thread receives the specified signal.
253    //
254    //! ARGS: signum - The signal to send to the specified thread.
255    //
256    //! RETURNS:  0 - Successful completion
257    //! RETURNS: -1 - Error
258    // -----------------------------------------------------------------------
259    virtual int kill (int signum)
260    { return -1;}
261
262    // -----------------------------------------------------------------------
263    //: Kill (cancel) this thread.
264    //
265    //! PRE: None.
266    //! POST: This thread is cancelled. Immediate
267    //+       cancellation is not guaranteed.
268    // -----------------------------------------------------------------------
269    virtual void kill()
270    {;}
271
272    // -----------------------------------------------------------------------
273    //: Ouput the state of the object.
274    // -----------------------------------------------------------------------
275    virtual std::ostream& outStream(std::ostream& out)
276    {
277       out.setf(std::ios::right);
278       out << std::setw(3) << mThreadId;
279       out.unsetf(std::ios::right);
280       return out;
281    }
282
283 protected:
284    // -----------------------------------------------------------------------
285    //: Initialize the state of the object.
286    // -----------------------------------------------------------------------
287    void create_thread_id()
288    {
289       mThreadId = getNextThreadId();
290    }
291
292 private:
293    // Don't allow copy
294    vjBaseThread(vjBaseThread& other)
295    {;}
296
297 private:
298    int32_t  mThreadId;    // The local id for the thread, -1 ==> invalid thread
299
300    // --- STATICS ---- //
301
302 private:
303    // XXX: What happens when it rolls over after we have been running for a LONG time.
304    int32_t getNextThreadId()
305    {
306       return mNextThreadId++;
307    }
308
309    static int32_t mNextThreadId;    // Initialized to 0
310 };
311
312 // Ouput operator
313 std::ostream& operator<<(std::ostream& out, vjBaseThread* threadPtr);
314
315
316 //: Helper class fot vjThread that maintains a list of threads and ides
317 //
318 // Basically maps from system specific index ==> vjThread*
319 //
320 // Used internally because we can have many types of indexes for the thread
321 // list depending upon the type of threads being used.
322 template <class IdxType>
323 class vjThreadTable
324 {
325 public:
326    // -----------------------------------------------------------------------
327    //: Add a thread to the list.
328    // -----------------------------------------------------------------------
329    void addThread(vjBaseThread* threadPtr, IdxType index)
330    {
331       mThreadMap[index] = threadPtr;
332    }
333
334    // -----------------------------------------------------------------------
335    //: Get a thread from the list.
336    // -----------------------------------------------------------------------
337    vjBaseThread* getThread(IdxType index)
338    {
339       //std::hash_map<IdxType, vjBaseThread*>::iterator i;
340       typename std::map<IdxType, vjBaseThread*>::iterator i;
341       i = mThreadMap.find(index);
342       if(i == mThreadMap.end())
343          return NULL;
344       else
345          return (*i).second;
346    }
347
348    // -----------------------------------------------------------------------
349    //: Remove a thread from the list.
350    // -----------------------------------------------------------------------
351    void removeThread(IdxType index)
352    {
353       mThreadMap.erase(index);
354    }
355
356 private:
357    std::map<IdxType, vjBaseThread*> mThreadMap;
358    //std::hash_map<IdxType, vjBaseThread*> mThreadMap;
359 };
360
361 #endif
Note: See TracBrowser for help on using the browser.