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

thread.C

Go to the documentation of this file.
00001 #include "bcsignals.h"
00002 #include <sys/wait.h>
00003 #include <sched.h>
00004 #include <signal.h>
00005 #include <stdio.h>
00006 #include <unistd.h>
00007 #include "thread.h"
00008 
00009 
00010 Thread::Thread(int synchronous, int realtime, int autodelete)
00011 {
00012         this->synchronous = synchronous;
00013         this->realtime = realtime;
00014         this->autodelete = autodelete;
00015         tid = (pthread_t)-1;
00016         tid_valid = 0;
00017         thread_running = 0;
00018         cancel_enabled = 0;
00019 }
00020 
00021 Thread::~Thread()
00022 {
00023 }
00024 
00025 void* Thread::entrypoint(void *parameters)
00026 {
00027         Thread *thread = (Thread*)parameters;
00028 
00029 // allow thread to be cancelled at any point during a region where it is enabled.
00030         pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00031 // Disable cancellation by default.
00032         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00033         thread->cancel_enabled = 0;
00034 
00035 // Set realtime here seince it doesn't work in start
00036         if(thread->realtime && getuid() == 0)
00037         {
00038                 struct sched_param param = 
00039                 {
00040                         sched_priority : 1
00041                 };
00042                 if(pthread_setschedparam(thread->tid, SCHED_RR, &param) < 0)
00043                         perror("Thread::entrypoint pthread_attr_setschedpolicy");
00044         }
00045 
00046         thread->run();
00047 
00048         thread->thread_running = 0;
00049 
00050         if(thread->autodelete && !thread->synchronous) delete thread;
00051         return NULL;
00052 }
00053 
00054 void Thread::start()
00055 {
00056         pthread_attr_t  attr;
00057         struct sched_param param;
00058 
00059         pthread_attr_init(&attr);
00060 
00061         thread_running = 1;
00062 
00063 // Inherit realtime from current thread the easy way.
00064         if(!realtime) realtime = calculate_realtime();
00065 
00066 
00067         if(!synchronous) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00068 
00069         if(realtime && getuid() == 0)
00070         {
00071                 if(pthread_attr_setschedpolicy(&attr, SCHED_RR) < 0)
00072                         perror("Thread::start pthread_attr_setschedpolicy");
00073                 param.sched_priority = 50;
00074                 if(pthread_attr_setschedparam(&attr, &param) < 0)
00075                         perror("Thread::start pthread_attr_setschedparam");
00076         }
00077         else
00078         {
00079                 if(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) < 0)
00080                         perror("Thread::start pthread_attr_setinheritsched");
00081         }
00082 
00083         pthread_create(&tid, &attr, Thread::entrypoint, this);
00084         tid_valid = 1;
00085 }
00086 
00087 int Thread::end(pthread_t tid)           // need to join after this if synchronous
00088 {
00089         if(tid_valid)
00090         {
00091                 pthread_cancel(tid);
00092         }
00093         return 0;
00094 }
00095 
00096 int Thread::end()           // need to join after this if synchronous
00097 {
00098         cancel();
00099         return 0;
00100 }
00101 
00102 int Thread::cancel()
00103 {
00104         if(tid_valid) pthread_cancel(tid);
00105         if(!synchronous)
00106         {
00107                 tid = (pthread_t)-1;
00108                 tid_valid = 0;
00109         }
00110         return 0;
00111 }
00112 
00113 int Thread::join()   // join this thread
00114 {
00115         int result = 0;
00116         if(tid_valid)
00117         {
00118                 result = pthread_join(tid, 0);
00119         }
00120 
00121         tid = (pthread_t)-1;
00122         tid_valid = 0;
00123 
00124 // Don't execute anything after this.
00125         if(autodelete && synchronous) delete this;
00126         return 0;
00127 }
00128 
00129 int Thread::enable_cancel()
00130 {
00131         cancel_enabled = 1;
00132         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00133         return 0;
00134 }
00135 
00136 int Thread::disable_cancel()
00137 {
00138         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
00139         cancel_enabled = 0;
00140         return 0;
00141 }
00142 
00143 int Thread::get_cancel_enabled()
00144 {
00145         return cancel_enabled;
00146 }
00147 
00148 int Thread::exit_thread()
00149 {
00150         pthread_exit(0);
00151         if(!synchronous)
00152         {
00153                 tid = (pthread_t)-1;
00154                 tid_valid = 0;
00155         }
00156         return 0;
00157 }
00158 
00159 
00160 int Thread::suspend_thread()
00161 {
00162         if(tid_valid) pthread_kill(tid, SIGSTOP);
00163         return 0;
00164 }
00165 
00166 int Thread::continue_thread()
00167 {
00168         if(tid_valid) pthread_kill(tid, SIGCONT);
00169         return 0;
00170 }
00171 
00172 int Thread::running()
00173 {
00174         return thread_running;
00175 }
00176 
00177 int Thread::set_synchronous(int value)
00178 {
00179         this->synchronous = value;
00180         return 0;
00181 }
00182 
00183 int Thread::set_realtime(int value)
00184 {
00185         this->realtime = value;
00186         return 0;
00187 }
00188 
00189 int Thread::set_autodelete(int value)
00190 {
00191         this->autodelete = value;
00192         return 0;
00193 }
00194 
00195 int Thread::get_autodelete()
00196 {
00197         return autodelete;
00198 }
00199 
00200 int Thread::get_synchronous()
00201 {
00202         return synchronous;
00203 }
00204 
00205 int Thread::calculate_realtime()
00206 {
00207 //printf("Thread::calculate_realtime %d %d\n", getpid(), sched_getscheduler(0));
00208         return (sched_getscheduler(0) == SCHED_RR ||
00209                 sched_getscheduler(0) == SCHED_FIFO);
00210 }
00211 
00212 int Thread::get_realtime()
00213 {
00214         return realtime;
00215 }
00216 
00217 int Thread::get_tid()
00218 {
00219         return tid;
00220 }
00221 

Generated on Sun Jan 8 13:26:35 2006 for Guicast-svn by  doxygen 1.4.4