Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Examples  

vpr::ThreadPosix Class Reference

Threads implementation using POSIX threads (both Draft 4 and the "final" draft of the standard are supported). More...

#include <ThreadPosix.h>

Inheritance diagram for vpr::ThreadPosix:

Inheritance graph
[legend]
Collaboration diagram for vpr::ThreadPosix:

Collaboration graph
[legend]
List of all members.

Public Methods

 ThreadPosix (VPRThreadPriority priority=VPR_PRIORITY_NORMAL, VPRThreadScope scope=VPR_GLOBAL_THREAD, VPRThreadState state=VPR_JOINABLE_THREAD, size_t stack_size=0)
 Non-spawning constructor. More...

 ThreadPosix (thread_func_t func, void *arg=NULL, VPRThreadPriority priority=VPR_PRIORITY_NORMAL, VPRThreadScope scope=VPR_GLOBAL_THREAD, VPRThreadState state=VPR_JOINABLE_THREAD, size_t stack_size=0)
 Spawning constructor with argument. More...

 ThreadPosix (BaseThreadFunctor *functorPtr, VPRThreadPriority priority=VPR_PRIORITY_NORMAL, VPRThreadScope scope=VPR_GLOBAL_THREAD, VPRThreadState state=VPR_JOINABLE_THREAD, size_t stack_size=0)
 Spawning constructor (functor version). More...

virtual ~ThreadPosix ()
 Destructor. More...

virtual void setFunctor (BaseThreadFunctor *functorPtr)
 Sets the functor that this thread will execute. More...

virtual vpr::ReturnStatus start ()
 Starts this thread's execution. More...

virtual int join (void **status=0)
 Makes the calling thread wait for the termination of this thread. More...

virtual int resume (void)
 Resumes the execution of a thread that was previously suspended using suspend(). More...

virtual int suspend (void)
 Suspends the execution of this thread. More...

virtual int getPrio (VPRThreadPriority *prio)
 Gets this thread's priority. More...

virtual int setPrio (VPRThreadPriority prio)
 Sets this thread's priority. More...

virtual int setRunOn (int cpu)
 Sets the CPU affinity for this thread (the CPU on which this thread will exclusively run). More...

virtual int getRunOn (int *cur_cpu)
 Gets the CPU affinity for this thread (the CPU on which this thread exclusively runs). More...

virtual int kill (int signum)
 Sends the specified signal to this thread (not necessarily SIGKILL). More...

virtual void kill ()
 Kills (cancels) this thread. More...

std::ostream & outStream (std::ostream &out)
 Provides a way of printing the process ID neatly. More...


Static Public Methods

void yield ()
 Yields execution of the calling thread to allow a different blocked thread to execute. More...

BaseThreadself ()
 Get a ptr to the thread we are in. More...


Protected Methods

vpr::ReturnStatus spawn (BaseThreadFunctor *functorPtr)
 Creates a new thread that will execute functorPtr. More...

void startThread (void *nullParam)
 Called by the spawn routine to start the user thread function. More...


Detailed Description

Threads implementation using POSIX threads (both Draft 4 and the "final" draft of the standard are supported).

Functions by recieving a function in the constructor that is the function to call when the new thread is created. This function is stored internally to the class, then the class is "boot-strapped" by spawning a call to the startThread function with in turn will call the previously set thread function

Definition at line 80 of file ThreadPosix.h.


Constructor & Destructor Documentation

vpr::ThreadPosix::ThreadPosix VPRThreadPriority    priority = VPR_PRIORITY_NORMAL,
VPRThreadScope    scope = VPR_GLOBAL_THREAD,
VPRThreadState    state = VPR_JOINABLE_THREAD,
size_t    stack_size = 0
 

Non-spawning constructor.

This will not start a thread.

Definition at line 75 of file ThreadPosix.cpp.

00077    : mUserThreadFunctor(NULL)
00078    , mDeleteThreadFunctor(false)
00079    , mRunning(false)
00080    , mPriority(priority)
00081    , mScope(scope)
00082    , mState(state)
00083    , mStackSize(stackSize)
00084    , mThreadStartCompleted(false)
00085    , mStartFunctor(NULL)
00086 {
00087    /* Do nothing. */ ;
00088 }

vpr::ThreadPosix::ThreadPosix thread_func_t    func,
void *    arg = NULL,
VPRThreadPriority    priority = VPR_PRIORITY_NORMAL,
VPRThreadScope    scope = VPR_GLOBAL_THREAD,
VPRThreadState    state = VPR_JOINABLE_THREAD,
size_t    stack_size = 0
 

Spawning constructor with argument.

This will start a new thread that will execute the specified function.

Definition at line 92 of file ThreadPosix.cpp.

References setFunctor, start, and vpr::thread_func_t.

00095    : mUserThreadFunctor(NULL)
00096    , mDeleteThreadFunctor(false)
00097    , mRunning(false)
00098    , mPriority(priority)
00099    , mScope(scope)
00100    , mState(state)
00101    , mStackSize(stackSize)
00102    , mThreadStartCompleted(false)
00103    , mStartFunctor(NULL)
00104 {
00105    // Create the thread functor to start.  This will be deleted in the
00106    // destructor.
00107    setFunctor(new ThreadNonMemberFunctor(func, arg));
00108    mDeleteThreadFunctor = true;
00109    start();
00110 }

vpr::ThreadPosix::ThreadPosix BaseThreadFunctor   functorPtr,
VPRThreadPriority    priority = VPR_PRIORITY_NORMAL,
VPRThreadScope    scope = VPR_GLOBAL_THREAD,
VPRThreadState    state = VPR_JOINABLE_THREAD,
size_t    stack_size = 0
 

Spawning constructor (functor version).

This will start a new thread that will execute the function encapsulated by the functor.

Definition at line 114 of file ThreadPosix.cpp.

References setFunctor, and start.

00117    : mUserThreadFunctor(NULL)
00118    , mDeleteThreadFunctor(false)
00119    , mRunning(false)
00120    , mPriority(priority)
00121    , mScope(scope)
00122    , mState(state)
00123    , mStackSize(stackSize)
00124    , mThreadStartCompleted(false)
00125    , mStartFunctor(NULL)
00126 {
00127    setFunctor(functorPtr);
00128    start();
00129 }

vpr::ThreadPosix::~ThreadPosix   [virtual]
 

Destructor.

Precondition:
None.
Postcondition:
This thread is removed from the thread table and from the local thread hash.

Definition at line 132 of file ThreadPosix.cpp.

00133 {
00134    if ( mDeleteThreadFunctor )
00135    {
00136       delete mUserThreadFunctor;
00137    }
00138 
00139    if ( NULL != mStartFunctor )
00140    {
00141       delete mStartFunctor;
00142    }
00143 }


Member Function Documentation

void vpr::ThreadPosix::setFunctor BaseThreadFunctor   functorPtr [virtual]
 

Sets the functor that this thread will execute.

Precondition:
The thread is not already running. The functor is valid.

Implements vpr::BaseThread.

Definition at line 145 of file ThreadPosix.cpp.

References vprASSERT.

Referenced by ThreadPosix.

00146 {
00147    vprASSERT(! mRunning && "Thread already running.");
00148    vprASSERT(functorPtr->isValid() && "Invalid functor.");
00149 
00150    mUserThreadFunctor = functorPtr;
00151 }

vpr::ReturnStatus vpr::ThreadPosix::start   [virtual]
 

Starts this thread's execution.

Precondition:
The functor to execute has been set. The thread is not already running.
Postcondition:
A thread (with any specified attributes) is created that begins executing our functor. Depending on the scheduler, it may begin execution immediately, or it may block for a short time before beginning execution.

Implements vpr::BaseThread.

Definition at line 153 of file ThreadPosix.cpp.

References vpr::CondVarPosix::acquire, vpr::ReturnStatus::Fail, vpr::BaseThread::registerThread, vpr::CondVarPosix::release, vpr::ReturnStatus::setCode, spawn, vpr::ReturnStatus::success, vprASSERT, and vpr::CondVarPosix::wait.

Referenced by ThreadPosix.

00154 {
00155    vpr::ReturnStatus status;
00156 
00157    if ( mRunning )
00158    {
00159       vprASSERT(false && "Thread already started");
00160       status.setCode(vpr::ReturnStatus::Fail);
00161    }
00162    else if ( NULL == mUserThreadFunctor )
00163    {
00164       vprASSERT(false && "No functor set");
00165       status.setCode(vpr::ReturnStatus::Fail);
00166    }
00167    else
00168    {
00169       mStartFunctor =
00170          new ThreadMemberFunctor<ThreadPosix>(this, &ThreadPosix::startThread,
00171                                               NULL);
00172 
00173       // Spawn the thread.  If the thread is spawned successfully, the method
00174       // startThread() will register the actual thread info.
00175       mThreadStartCompleted = false;  // Make sure this is set correctly
00176       status = spawn(mStartFunctor);
00177 
00178       // Thread spawned successfully.
00179       if ( status.success() )
00180       {
00181          // startThread() will register the thread, so we wait for
00182          // registration to complete here.
00183          mThreadStartCondVar.acquire();
00184          {
00185             while ( ! mThreadStartCompleted )
00186             {
00187                mThreadStartCondVar.wait();
00188             }
00189          }
00190          mThreadStartCondVar.release();
00191 
00192          mRunning = true;
00193       }
00194       // Thread spawning failed.  Yikes!
00195       else
00196       {
00197          ThreadManager::instance()->lock();
00198          {
00199             registerThread(false);
00200          }
00201          ThreadManager::instance()->unlock();
00202       }
00203    }
00204 
00205    return status;
00206 }

vpr::ReturnStatus vpr::ThreadPosix::spawn BaseThreadFunctor   functorPtr [protected]
 

Creates a new thread that will execute functorPtr.

Precondition:
None.
Postcondition:
A thread (with any specified attributes) is created that begins executing func(). Depending on the scheduler, it may begin execution immediately, or it may block for a short time before beginning execution.
Parameters:
functorPtr  Function to be executed by the thread.
Returns:
A vpr::ReturnStatus obj is returned to indicate the result of the thread creation.
Note:
The pthreads implementation on HP-UX 10.20 does not allow the stack address to be changed.

Definition at line 209 of file ThreadPosix.cpp.

References vpr::ReturnStatus::Fail, sched_param_t, vpr::ReturnStatus::setCode, and vpr::vprThreadFunctorFunction.

Referenced by start.

00210 {
00211    vpr::ReturnStatus status;
00212    int ret_val;
00213    pthread_attr_t thread_attrs;
00214 
00215    int pthread_prio = vprThreadPriorityToPOSIX(mPriority);
00216 
00217    // Initialize thread_attrs and set the priority of the thread if it is
00218    // supported.
00219    sched_param_t prio_param;
00220 
00221    pthread_attr_init(&thread_attrs);
00222    pthread_attr_setdetachstate(&thread_attrs, vprThreadStateToPOSIX(mState));
00223 
00224    // If thread priority scheduling is available, set the thread's priority
00225    // if it is set to be higher than 0.
00226 #  ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00227    int thread_scope = vprThreadScopeToPOSIX(mScope);
00228 
00229 #  if defined(HAVE_SYS_CAPABILITY_H) && ! defined(VPR_OS_FreeBSD) && \
00230       ! defined(VPR_OS_Linux)
00231    cap_t capabilities = cap_get_proc();
00232 
00233    // If we have the capability to do so, set the scope of the threads
00234    // to system scope.
00235    if ( capabilities->cap_effective & CAP_SCHED_MGT )
00236    {
00237       thread_scope = PTHREAD_SCOPE_SYSTEM;
00238    }
00239 #  endif   /* HAVE_SYS_CAPABILITY_H */
00240 
00241    pthread_attr_setscope(&thread_attrs, thread_scope);
00242 
00243    if ( pthread_prio > 0 )
00244    {
00245       prio_param.sched_priority = pthread_prio;
00246       pthread_attr_setschedparam(&thread_attrs, &prio_param);
00247    }
00248 #  endif   /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00249 
00250    // Set the stack size if a value greater than 0 is specified and this
00251    // pthreads implementation supports it.  Ensure that
00252    // _POSIX_THREAD_ATTR_STACKSIZE is defined before trying to test its
00253    // value.
00254 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
00255    if ( mStackSize > 0 )
00256    {
00257       // XXX: ** STACK SIZE CHECK NEEDED **
00258 
00259       pthread_attr_setstacksize(&thread_attrs, mStackSize);
00260    }
00261 #endif
00262 
00263    // Finally create the thread.
00264    ret_val = pthread_create(&(mThread), &thread_attrs,
00265                             vprThreadFunctorFunction, (void *) functorPtr);
00266 
00267    // Inform the caller if the thread was not created successfully.
00268    if ( ret_val != 0 )
00269    {
00270       status.setCode(vpr::ReturnStatus::Fail);
00271       std::cerr << "vpr::ThreadPosix::spawn() - Cannot create thread:"
00272                 << strerror(ret_val) << std::endl;
00273    }
00274 
00275    return status;
00276 }

void vpr::ThreadPosix::startThread void *    nullParam [protected]
 

Called by the spawn routine to start the user thread function.

Precondition:
Called ONLY by a new thread.
Postcondition:
The new thread will have started the user thread function. Any necessary thread registration is performed. The user thread functor is called.
Parameters:
nullParam  Unused.

Definition at line 279 of file ThreadPosix.cpp.

References vpr::CondVarPosix::acquire, vpr::BaseThread::registerThread, vpr::CondVarPosix::release, and vpr::CondVarPosix::signal.

00280 {
00281    boost::ignore_unused_variable_warning(nullParam);
00282 
00283    // WE are a new thread... yeah!!!!
00284    // TELL EVERYONE THAT WE LIVE!!!!
00285    ThreadManager::instance()->lock();      // Lock manager
00286    {
00287       threadIdKey().setspecific((void*)this);  // Store the pointer to me
00288       registerThread(true);                    // Finish thread initialization
00289    }
00290    ThreadManager::instance()->unlock();
00291 
00292    // Signal that thread registration is complete.
00293    mThreadStartCondVar.acquire();
00294    {
00295       mThreadStartCompleted = true;
00296       mThreadStartCondVar.signal();
00297    }
00298    mThreadStartCondVar.release();
00299 
00300    // --- CALL USER FUNCTOR --- //
00301    (*mUserThreadFunctor)();
00302 }

virtual int vpr::ThreadPosix::join void **    status = 0 [inline, virtual]
 

Makes the calling thread wait for the termination of this thread.

Precondition:
None.
Postcondition:
The caller blocks until this thread finishes its execution (i.e., calls the exit() method). This routine may return immediately if this thread has already exited.
Parameters:
status  Current state of the terminating thread when that thread calls the exit routine (optional).
Returns:
0 is returned if this thread is "joined" successfully.
-1 is returned on an error condition.

Reimplemented from vpr::BaseThread.

Definition at line 192 of file ThreadPosix.h.

00193    {
00194       return pthread_join(mThread, status);
00195    }

virtual int vpr::ThreadPosix::resume void    [inline, virtual]
 

Resumes the execution of a thread that was previously suspended using suspend().

Precondition:
This thread was previously suspended using the suspend() member function.
Postcondition:
This thread is sent the SIGCONT signal and is allowed to begin executing again.
Returns:
0 is returned if this thread resumes execuation successfully.
-1 is returned otherwise.
Note:
This is not currently supported on HP-UX 10.20.

Reimplemented from vpr::BaseThread.

Definition at line 211 of file ThreadPosix.h.

References kill.

00212    {
00213       return kill(SIGCONT);
00214    }

virtual int vpr::ThreadPosix::suspend void    [inline, virtual]
 

Suspends the execution of this thread.

Precondition:
None.
Postcondition:
This thread is sent the SIGSTOP signal and is thus suspended from execution until the member function resume() is called.
Returns:
0 is returned if this thread is suspended successfully.
-1 is returned otherwise.
Note:
This is not currently supported on HP-UX 10.20.

Reimplemented from vpr::BaseThread.

Definition at line 228 of file ThreadPosix.h.

References kill.

00229    {
00230       return kill(SIGSTOP);
00231    }

int vpr::ThreadPosix::getPrio VPRThreadPriority   prio [virtual]
 

Gets this thread's priority.

Precondition:
None.
Postcondition:
The priority of this thread is returned in the integer pointer variable.
Parameters:
prio  Pointer to an int variable that will have the thread's priority stored in it.
Returns:
0 is returned if the priority was retrieved successfully.
-1 is returned if the priority could not be read.
Note:
This is only supported on systems that support thread priority scheduling in their pthreads implementation.

Reimplemented from vpr::BaseThread.

Definition at line 305 of file ThreadPosix.cpp.

References sched_param_t.

00306 {
00307 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00308    int policy, ret_val;
00309    sched_param_t fifo_sched_param;
00310 
00311    ret_val = pthread_getschedparam(mThread, &policy, &fifo_sched_param);
00312    *prio = posixThreadPriorityToVPR(fifo_sched_param.sched_priority);
00313 
00314    return ret_val;
00315 #else
00316    std::cerr << "vpr::ThreadPosix::getPrio(): Not supported\n";
00317 
00318    return -1;
00319 #endif
00320 }

int vpr::ThreadPosix::setPrio VPRThreadPriority    prio [virtual]
 

Sets this thread's priority.

Precondition:
None.
Postcondition:
This thread has its priority set to the specified value.
Parameters:
prio  The new priority for this thread.
Returns:
0 is returned if this thread's priority was set successfully.
-1 is returned otherwise.
NOTE: This is only supported on systems that support thread priority scheduling in their pthreads implementation.

Reimplemented from vpr::BaseThread.

Definition at line 323 of file ThreadPosix.cpp.

References sched_param_t.

00324 {
00325 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00326    sched_param_t sched_param;
00327    sched_param.sched_priority = prio;
00328 
00329    return pthread_setschedparam(mThread, SCHED_RR, &sched_param);
00330 #else
00331    boost::ignore_unused_variable_warning(prio);
00332    std::cerr << "vpr::ThreadPosix::setPrio(): Not supported\n";
00333 
00334    return -1;
00335 #endif
00336 }

int vpr::ThreadPosix::setRunOn int    cpu [virtual]
 

Sets the CPU affinity for this thread (the CPU on which this thread will exclusively run).

Precondition:
The thread must have been set to be a system-scope thread.
Postcondition:
The CPU affinity is set or an error status is returned.
Parameters:
cpu  The CPU on which this thread will run exclusively.
Returns:
0 is returned if the affinity is set successfully.
-1 is returned otherwise.
Note:
This is currently only available on IRIX 6.5 and is non-portable.

Definition at line 338 of file ThreadPosix.cpp.

00339 {
00340 #ifdef VPR_OS_IRIX
00341    int ret_val;
00342 
00343    if ( mScope == PTHREAD_SCOPE_SYSTEM )
00344    {
00345       ret_val = pthread_setrunon_np(cpu);
00346    }
00347    else
00348    {
00349       std::cerr << "This thread is not a system-scope thread!\n";
00350       ret_val = -1;
00351    }
00352 
00353    return ret_val;
00354 #else
00355    boost::ignore_unused_variable_warning(cpu);
00356    std::cerr << "vpr::ThreadPosix::setRunOn(): Not available on this system.\n";
00357 
00358    return -1;
00359 #endif
00360 }

int vpr::ThreadPosix::getRunOn int *    cur_cpu [virtual]
 

Gets the CPU affinity for this thread (the CPU on which this thread exclusively runs).

Precondition:
The thread must have been set to be a system-scope thread, and a previous affinity must have been set using setRunOn().
Postcondition:
The CPU affinity for this thread is stored in the cur_cpu pointer.
Parameters:
cur_cpu  The CPU affinity for this thread (set by a previous call to setRunOn().
Returns:
0 is returned if the affinity is retrieved successfully.
-1 is returned otherwise.
Note:
This is currently only available on IRIX 6.5 and is non-portable.

Definition at line 362 of file ThreadPosix.cpp.

00363 {
00364 #ifdef VPR_OS_IRIX
00365    int ret_val;
00366 
00367    if ( mScope == PTHREAD_SCOPE_SYSTEM )
00368    {
00369       ret_val = pthread_getrunon_np(cur_cpu);
00370    }
00371    else
00372    {
00373       std::cerr << "This thread is not a system-scope thread!\n";
00374       ret_val = -1;
00375    }
00376 
00377    return ret_val;
00378 #else
00379    boost::ignore_unused_variable_warning(cur_cpu);
00380    std::cerr << "vpr::ThreadPosix::getRunOn(): Not available on this system.\n";
00381 
00382    return -1;
00383 #endif
00384 }

void vpr::ThreadPosix::yield void    [inline, static]
 

Yields execution of the calling thread to allow a different blocked thread to execute.

Precondition:
None.
Postcondition:
The caller yields its execution control to another thread or process.

Definition at line 311 of file ThreadPosix.h.

00312    {
00313       sched_yield();
00314    }

int vpr::ThreadPosix::kill int    signum [virtual]
 

Sends the specified signal to this thread (not necessarily SIGKILL).

Precondition:
None.
Postcondition:
This thread receives the specified signal.
Parameters:
signum  The signal to send to the specified thread.
Returns:
0 is returned if the signal was sent successfully.
-1 is returned otherwise.
Note:
This is not currently supported with Pthreads Draft 4.

Reimplemented from vpr::BaseThread.

Definition at line 386 of file ThreadPosix.cpp.

00387 {
00388    return pthread_kill(mThread, signum);
00389 }

virtual void vpr::ThreadPosix::kill   [inline, virtual]
 

Kills (cancels) this thread.

Precondition:
None.
Postcondition:
This thread is cancelled. Depending on the cancellation attributes of the specified thread, it may terminate immediately, it may wait until a pre-defined cancel point to stop or it may ignore the cancel altogether. Thus, immediate cancellation is not guaranteed.
Note:
For the sake of clarity, it is probably better to use the cancel() routine instead of kill() because a two-argument version of kill() is also used for sending signals to threads. This kill() and cancel() do exactly the same thing.

Reimplemented from vpr::BaseThread.

Definition at line 346 of file ThreadPosix.h.

Referenced by resume, and suspend.

00347    {
00348       pthread_cancel(mThread);
00349    }

BaseThread * vpr::ThreadPosix::self   [static]
 

Get a ptr to the thread we are in.

Returns:
NULL is returned if this thread is not in the global table.
A non-NULL pointer is returned that points to the thread in which we are currently running.

Definition at line 391 of file ThreadPosix.cpp.

References vpr::BaseThread::BaseThread, and vprASSERT.

00392 {
00393    vprASSERT((statics.mStaticsInitialized==1221) && "Trying to call vpr::ThreadPosix::self before statics are initialized. Don't do that");
00394 
00395    BaseThread* my_thread;
00396    threadIdKey().getspecific((void**)&my_thread);
00397 
00398    return my_thread;
00399 }

std::ostream & vpr::ThreadPosix::outStream std::ostream &    out [virtual]
 

Provides a way of printing the process ID neatly.

Reimplemented from vpr::BaseThread.

Definition at line 402 of file ThreadPosix.cpp.

00403 {
00404    out.setf(std::ios::right);
00405    out << std::setw(7) << std::setfill('0') << getpid() << "/";
00406    out.unsetf(std::ios::right);
00407    BaseThread::outStream(out);
00408    out << std::setfill(' ');
00409    return out;
00410 }


The documentation for this class was generated from the following files:
Generated on Sun May 2 14:47:06 2004 for VR Juggler Portable Runtime by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002