Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Thread.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 
00003 // This file is part of Vesta.
00004 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Tue Aug  9 14:23:25 EDT 2005 by ken@xorian.net        
00020 //      modified on Fri Jul 22 15:17:47 EDT 2005 by irina.furman@intel.com
00021 //      modified on Fri Aug 11 15:49:52 PDT 2000 by yuanyu 
00022 //      modified on Tue Feb  8 11:27:25 PST 2000 by mann  
00023 //      modified on Fri Mar 28 11:00:11 PST 1997 by heydon
00024 //      modified on Mon Jan 23 12:18:09 PST 1995 by levin
00025 
00026 #ifndef _thread
00027 #define _thread
00028 
00029 //  ***************************************
00030 //  *  Simplified threads implementation  *
00031 //  ***************************************
00032 
00033 namespace Basics
00034 {
00035   class thread;
00036 
00037   //  ****************************
00038   //  *  Mutex class definition  *
00039   //  ****************************
00040 
00041   class mutex {
00042     friend class cond;
00043   public:
00044     // The default constructor creates a mutex of default type.
00045     mutex() throw ();
00046 
00047     // This constructor creates a mutex of specified type. Valid types:
00048 
00049     //   PTHREAD_MUTEX_NORMAL
00050     //   PTHREAD_MUTEX_ERRORCHECK
00051     //   PTHREAD_MUTEX_RECURSIVE
00052     //   PTHREAD_MUTEX_DEFAULT
00053 
00054     // See pthread_mutexattr_settype(3) manual for descriptions of the
00055     // mutex types
00056     mutex(int type) throw();
00057 
00058     ~mutex() throw ();
00059 
00060     void lock() throw ();
00061     void unlock() throw ();
00062 
00063   private:
00064     pthread_mutex_t m;
00065     // Try to ensure that the mutex doesn't share a cache line with
00066     // anything else.
00067     char pad[64];
00068   };
00069 
00070   //  *****************************************
00071   //  *  Condition variable class definition  *
00072   //  *****************************************
00073 
00074   // The Linux system headers define "signal" as a macro with non-GNU
00075   // compilers.  This causes us trouble, since we have a method named
00076   // "signal" and want to compile with the Compaq compiler on Linux.
00077 #ifdef signal
00078 #undef signal
00079 #endif
00080 
00081   class cond {
00082   public:
00083     cond() throw ();
00084     ~cond() throw ();
00085 
00086     void wait(mutex &m) throw ();
00087     int timedwait(mutex &m, struct timespec *abstime) throw ();
00088     /* This returns 0 if the condition variable was signalled, or
00089        ETIMEDOUT if the condition variable was not signalled before
00090        time "abstime". */
00091 
00092     void signal() throw ();
00093     void broadcast() throw ();
00094 
00095   private:
00096     pthread_cond_t c;
00097     // Try to ensure that the condition variable doesn't share a cache
00098     // line with anything else.
00099     char pad[64];
00100   };
00101 
00102   class thread_attr
00103   {
00104   public:
00105     thread_attr() throw ();
00106     // Convenience constructor provided to make it easier to support
00107     // existing code that onyl wants to specify a stack size.
00108     thread_attr(size_t stacksize) throw ();
00109     thread_attr(const thread_attr &other) throw();
00110     ~thread_attr() throw ();
00111 
00112     void set_guardsize(size_t guardsize) throw();
00113     size_t get_guardsize() const throw();
00114     void set_stacksize(size_t stacksize) throw();
00115     size_t get_stacksize() const throw();
00116 
00117 #if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
00118     void set_schedpolicy(int policy) throw();
00119     int get_schedpolicy() const throw();
00120     void set_inheritsched(int inheritsched) throw();
00121     int get_inheritsched() const throw();
00122     void set_sched_priority(int sched_priority) throw();
00123     int get_sched_priority() const throw();
00124 #endif
00125 
00126     thread_attr &operator=(const thread_attr &other) throw();
00127 
00128   private:
00129     pthread_attr_t attr;
00130 
00131     // Allow the thread class to reach inside and get our
00132     // pthread_attr_t.
00133     friend class thread;
00134   };
00135 
00136   //  *****************************
00137   //  *  Thread class definition  *
00138   //  *****************************
00139 
00140   class thread {
00141   public:
00142     thread() throw () { /* SKIP */ }
00143     thread(const thread &other) throw() : t(other.t) { }
00144     ~thread() throw () { /* SKIP */ }
00145 
00146     typedef void* (*StartRoutine)(void *arg) /*throw ()*/;
00147     // pointer to function (pointer to void) returning pointer to void
00148     // The thread should not call pthread_exit() or be cancelled.
00149 
00150     void fork(StartRoutine proc, void *arg, const thread_attr &attr) throw ();
00151     void fork(StartRoutine proc, void *arg) throw ()
00152     {
00153       thread_attr attr;
00154       fork(proc, arg, attr);
00155     }
00156     void fork(StartRoutine proc, void *arg, long stacksize) throw ()
00157     {
00158       thread_attr attr;
00159       if(stacksize > 0)
00160         attr.set_stacksize(stacksize);
00161       fork(proc, arg, attr);
00162     }
00163     /* If "stacksize" is not defaulted, it specifies the stack size (in bytes)
00164        of the forked thread. */
00165 
00166     void detach() throw ();
00167 
00168     void fork_and_detach(StartRoutine proc, void *arg, const thread_attr &attr)
00169       throw ();
00170     void fork_and_detach(StartRoutine proc, void *arg) throw ()
00171     {
00172       thread_attr attr;
00173       fork_and_detach(proc, arg, attr);
00174     }
00175     void fork_and_detach(StartRoutine proc, void *arg, long stacksize) throw ()
00176     {
00177       thread_attr attr;
00178       if(stacksize > 0)
00179         attr.set_stacksize(stacksize);
00180       fork_and_detach(proc, arg, attr);
00181     }
00182     /* If "stacksize" is not defaulted, it specifies the stack size (in bytes)
00183        of the forked thread. */
00184 
00185     void *join() throw ();
00186 
00187     thread &operator=(const thread &other) throw()
00188     {
00189       t = other.t;
00190       return *this;
00191     }
00192 
00193     void get_sched_param(/*OUT*/ int &policy,
00194                          /*OUT*/ int &sched_priority) throw();
00195     void set_sched_param(int policy, int sched_priority) throw();
00196 
00197     static void pause(int secs, int usecs = 0) throw ();
00198     /* Pause the calling thread for "secs" seconds plus "usecs"
00199        microseconds. */
00200 
00201     static thread self() throw();
00202     // Return a thread object referring to the calling thread.
00203 
00204   private:
00205     thread(pthread_t existing) throw () : t(existing) { }
00206     pthread_t t;
00207     void fork_inner(StartRoutine proc, void *arg, const thread_attr &attr)
00208       throw ();
00209   };
00210 }
00211 
00212 #endif  /* _thread */

Generated on Mon May 8 00:48:29 2006 for Vesta by  doxygen 1.4.2