root/juggler/tags/1.0.7/Threads/vjThreadSGI.h

Revision 8789, 10.3 kB (checked in by patrickh, 7 years ago)

Copyright update.

  • 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, 2001, 2002
4  *   by Iowa State University
5  *
6  * Original Authors:
7  *   Allen Bierbaum, Christopher Just,
8  *   Patrick Hartling, Kevin Meinert,
9  *   Carolina Cruz-Neira, Albert Baker
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  *
26  * -----------------------------------------------------------------
27  * File:          $RCSfile$
28  * Date modified: $Date$
29  * Version:       $Revision$
30  * -----------------------------------------------------------------
31  *
32  *************** <auto-copyright.pl END do not edit this line> ***************/
33
34
35 #ifndef _THREAD_SGI_H_
36 #define _THREAD_SGI_H_
37 //#pragma once
38
39 // NOTE: This file(vjThreadSGI.h) MUST be included by vjThread.h.
40 // Not the other way around
41
42 #include <vjConfig.h>
43 #include <sys/resource.h>
44 #include <sys/types.h>
45 #include <sys/prctl.h>
46 #include <signal.h>
47 #include <sched.h>
48 #include <unistd.h>
49
50 #include <Threads/vjThreadFunctor.h>
51 #include <Threads/vjBaseThread.h>
52
53 //: Threads implementation using multiple processes created with sproc(2).
54
55 //!PUBLIC_API:
56 class vjThreadSGI : public vjBaseThread
57 {
58 public:
59    /***** CONSTRUCTORS ******/
60
61    // -----------------------------------------------------------------------
62    //: Spawning constructor.
63    //  This will actually start a new thread that will execute the specified
64    //  function.
65    // -----------------------------------------------------------------------
66    vjThreadSGI(vj_thread_func_t func, void* arg = 0, long flags = 0,
67                u_int priority = 0, void* stack_addr = NULL,
68                size_t stack_size = 0);
69
70    // -----------------------------------------------------------------------
71    //: Spawning constructor with arguments (functor version).
72    //  This will start a new thread that will execute the specified
73    //  function.
74    // -----------------------------------------------------------------------
75    vjThreadSGI(vjBaseThreadFunctor* functorPtr, long flags = 0,
76                u_int priority = 0, void* stack_addr = NULL,
77                size_t stack_size = 0);
78
79    virtual ~vjThreadSGI()
80    {;}
81
82    // -----------------------------------------------------------------------
83    //: Spawns a new thread that will execute functorPtr.
84    //
85    //! PRE: None.
86    //! POST: A thread (with any specified attributes) is created that begins
87    //+       executing func().  Depending on the scheduler, it may being
88    //+       execution immediately, or it may block for a short time before
89    //+       beginning execution.
90    //
91    //! ARGS: functorPtr - Function to be executed by the thread.
92    //! ARGS: flags - Flags for the thread--not currently used in this
93    //+               implementation (optional).
94    //
95    //! RETURNS: non-zero - Successful thread creation
96    //! RETURNS:       -1 - Error
97    // -----------------------------------------------------------------------
98    virtual int
99    spawn (vjBaseThreadFunctor* functorPtr, long flags = 0, u_int priority = 0,
100           void* stack_addr = NULL, size_t stack_size = 0)
101    {
102       mThreadPID = sproc(vj_thread_func_t(&ThreadFunctorFunction), PR_SADDR,
103                          functorPtr);
104       return mThreadPID;
105    }
106
107    // Called by the spawn routine to start the user thread function
108     // PRE: Called ONLY by a new thread
109     // POST: The new thread will have started the user thread function
110     void startThread(void* null_param);
111
112 private:
113    // The functor to call from startThread
114    vjBaseThreadFunctor* mUserThreadFunctor;
115
116 public:
117
118    // -----------------------------------------------------------------------
119    //: Make the calling thread wait for the termination of the specified
120    //+ thread.
121    //
122    //! RETURNS:  0 - Successful completion
123    //! RETURNS: -1 - Error
124    // -----------------------------------------------------------------------
125    virtual int join (void** = 0);
126
127    // -----------------------------------------------------------------------
128    //: Resume the execution of a thread that was previously suspended using
129    //+ suspend().
130    //
131    //! PRE: The specified thread was previously suspended using the
132    //+      suspend() member function.
133    //! POST: The specified thread is sent the SIGCONT signal and is allowed
134    //+       to begin executing again.
135    //
136    //! RETURNS:  0 - Successful completion
137    //! RETURNS: -1 - Error
138    // -----------------------------------------------------------------------
139    virtual int resume (void)
140    { return ::kill(mThreadPID, SIGCONT);}
141
142    // -----------------------------------------------------------------------
143    //: Suspend the execution of this thread.
144    //
145    //! PRE: None.
146    //! POST: This thread is sent the SIGSTOP signal and is thus suspended
147    //+       from execution until the member function resume() is called.
148    //
149    //! RETURNS:  0 - Successful completion
150    //! RETURNS: -1 - Error
151    // -----------------------------------------------------------------------
152    virtual int suspend (void)
153    { return ::kill(mThreadPID, SIGSTOP);}
154
155    // -----------------------------------------------------------------------
156    //: Get this thread's priority.
157    //
158    //! PRE: None.
159    //! POST: The priority of this thread is returned in the integer pointer
160    //+       variable.
161    //
162    //! ARGS: prio - Pointer to an int variable that will have the thread's
163    //+              priority stored in it.
164    //
165    //! RETURNS:  0 - Successful completion
166    //! RETURNS: -1 - Error
167    // -----------------------------------------------------------------------
168    virtual int getprio (int* prio)
169    {
170       *prio = getpriority(PRIO_PROCESS, mThreadPID);
171
172       if ((*prio)== -1)
173          return -1;
174       else
175          return 0;
176    }
177
178    // -----------------------------------------------------------------------
179    //: Set this thread's priority.
180    //
181    //! PRE: None.
182    //! POST: This thread has its priority set to the specified value.
183    //
184    //! ARGS: prio - The new priority of the specified thread.
185    //
186    //! RETURNS:  0 - Successful completion
187    //! RETURNS: -1 - Error
188    // -----------------------------------------------------------------------
189    inline int
190    setprio (int prio)
191    {
192       return setpriority(PRIO_PROCESS, mThreadPID, prio);
193    }
194
195    // -----------------------------------------------------------------------
196    //: Yield execution of the calling thread to allow a different blocked
197    //+ thread to execute.
198    //
199    //! PRE: None.
200    //! POST: The caller yields its execution control to another thread or
201    //+       process.
202    // -----------------------------------------------------------------------
203    virtual void yield (void)
204    { sginap(0);}
205
206
207    // -----------------------------------------------------------------------
208    //: Send the specified signal to this thread (not necessarily SIGKILL).
209    //
210    //! PRE: None.
211    //! POST: This thread receives the specified signal.
212    //
213    //! ARGS: signum - The signal to send to the specified thread.
214    //
215    //! RETURNS:  0 - Successful completion
216    //! RETURNS: -1 - Error
217    // -----------------------------------------------------------------------
218    virtual int kill (int signum)
219    { return ::kill(mThreadPID, signum);}
220
221    // -----------------------------------------------------------------------
222    //: Kill (cancel) this thread.
223    //
224    //! PRE: None.
225    //! POST: This thread is cancelled.  Depending on the cancellation
226    //+       attributes of the specified thread, it may terminate
227    //+       immediately, it may wait until a pre-defined cancel point to
228    //+       stop or it may ignore the cancel altogether.  Thus, immediate
229    //+       cancellation is not guaranteed.
230    //
231    //! NOTE: For the sake of clarity, it is probably better to use the
232    //+       cancel() routine instead of kill() because a two-argument
233    //+       version of kill() is also used for sending signals to threads.
234    // -----------------------------------------------------------------------
235    virtual void kill (void)
236    { kill(SIGKILL);}
237
238
239    // -----------------------------------------------------------------------
240    //: Output the state of the object.
241    // -----------------------------------------------------------------------
242    std::ostream& outStream(std::ostream& out)
243    {
244       out.setf(std::ios::right);
245       out << std::setw(7) << std::setfill('0') << mThreadPID << "/";
246       out.unsetf(std::ios::right);
247       vjBaseThread::outStream(out);
248       out << std::setfill(' ');
249       return out;
250    }
251
252 private:
253    pid_t mThreadPID;      //: pid_t data structure for this thread
254
255    // --------  STATICS ------ //
256    // This data is used to maintain a thread table in the system
257    // It is here because the self() function needs to use system specific
258    // information.
259 public:
260    // -----------------------------------------------------------------------
261    //: Get a ptr to the thread we are in.
262    //
263    //! RETURNS: NULL - Thread is not in global table
264    //! RETURNS: NonNull - Ptr to the thread that we are running within
265    // -----------------------------------------------------------------------
266    static vjBaseThread* self()
267    {
268       return getLocalThreadPtr();
269    }
270
271 private:
272    // Set the thread ptr stored in the local PRDA area
273    // NOTE: PRDA is a memory address that each thread has a seperate copy of.
274    static void setLocalThreadPtr(vjThreadSGI* threadPtr)
275    {
276       ((ThreadInfo*)PRDA->usr_prda.fill)->mThreadPtr = threadPtr;
277    }
278
279    // Get the thread ptr stored in the local PRDA area
280    static vjThreadSGI* getLocalThreadPtr()
281    {
282       return ((ThreadInfo*)PRDA->usr_prda.fill)->mThreadPtr;
283    }
284
285    // Structure for storing thread specific information
286    struct ThreadInfo
287    {
288       vjThreadSGI* mThreadPtr;
289    };
290 };
291
292
293 #endif   /* _THREAD_SGI_H_ */
Note: See TracBrowser for help on using the browser.