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