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
00030 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00031
00032 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00033 thread->cancel_enabled = 0;
00034
00035
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, ¶m) < 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
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, ¶m) < 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)
00088 {
00089 if(tid_valid)
00090 {
00091 pthread_cancel(tid);
00092 }
00093 return 0;
00094 }
00095
00096 int Thread::end()
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()
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
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
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