00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #include "src/common/shared.hpp"
00018 #include "src/common/blist.hpp"
00019 #include "src/common/blistsort.hpp"
00020 #include "src/arch/x86/interr.hpp"
00021 #include "src/arch/x86/except_c.hpp"
00022 #include "src/arch/x86/rtc.hpp"
00023 #include "src/thread/scheduler.hpp"
00024 #include "src/thread/thread.hpp"
00025 #include "src/thread/process.hpp"
00026 
00034 namespace Thread {
00035 
00036 
00037 class IPC::Lock::lock_t lock_queues("queues");
00038 class IPC::Lock::lock_t lock_sleep("sleep");
00039 class Memory::Heap::heapbox heap;       
00040 class blist_t threads_queue[THREAD_QUEUES];
00041 
00042 class blist_t threads_sleep;    
00043 class blist_t threads_dead;     
00044 
00045 
00046 int wake_threads()
00047  { _PF;
00048 blist_s *item, *next;
00049 thread_t *thread;
00050 
00051         if (!Thread::Scheduler::multitasking_running)
00052                 Preturn(EFAIL);
00053 
00054         if (lock_system.locked())
00055                 Preturn(EFAIL);
00056         if (lock_queues.locked())
00057                 Preturn(EFAIL);
00058         if (lock_sleep.locked())
00059                 Preturn(EFAIL);
00060 
00061         for (item=threads_sleep.head;item;item=next)
00062          {
00063                 next=item->next;
00064                 thread=bli_dt(item,thread_t*);
00065         
00066                 if (thread->awake_time > Arch::x86::RTC::up_time)
00067                         break;
00068                 awake(thread);
00069          }
00070 
00071         Preturn(ESUCCESS);
00072  }
00073 
00074 
00075 int enqueue_thread(thread_t *thread, blist_t *queue)
00076  {
00077 int i;
00078         lock_queues.lock();
00079         i= (queue->ptr(thread, NULL)==NULL? EFAIL : ESUCCESS);
00080         lock_queues.ulock();
00081         return i;
00082  }
00083 
00084 
00085 int unqueue_thread(thread_t *thread, blist_t *queue)
00086  { _Pf("T'::unqueue_thread");
00087 blist_s *item;
00088         lock_queues.lock();
00089         for (item=queue->head;item;item=item->next)
00090          {
00091                 if (bli_dt(item,thread_t*) != thread)
00092                         continue;
00093                 queue->del(item);
00094                 lock_queues.ulock();
00095                 preturn( ESUCCESS );
00096          }
00097 
00098         lock_queues.ulock();
00099         preturn( EFAIL );
00100  }
00101 
00102 
00103 uint32 thread_load(thread_t *thread) { _Pf("Thread::thread_load");
00104 uint32 i;
00105         if (Arch::x86::RTC::up_time - thread->save1_time > 29)  
00106          {
00107                 thread->save1_time=thread->save2_time;
00108                 thread->run1_time=thread->run2_time;
00109                 thread->save2_time=Arch::x86::RTC::up_time;
00110                 thread->run2_time=thread->running_time;
00111          }
00112 
00113         i= 2000 * (thread->running_time) /
00114                 ( Arch::x86::RTC::up_time-thread->creation_time);
00115         if (thread->run1_time != 0) {
00116 
00117 
00118 
00119         if (thread->save1_time >= Arch::x86::RTC::up_time)
00120            i+= 8000 * (thread->running_time) /
00121                 ( Arch::x86::RTC::up_time-thread->creation_time);
00122            else
00123         i+= 8000 * (thread->running_time-thread->run1_time) /
00124                 ( Arch::x86::RTC::up_time-thread->save1_time);
00125    }
00126 
00127 
00128 
00129 
00130 
00131 
00132         thread->load=i;
00133         preturn( thread->load );
00134 
00135  }
00136 
00137 
00138 int sleepcompar(const void *a, const void *b)
00139  { _Pf("T'::sleepcompar");
00140 uint64 A, B;
00141         A= bli_dt(a,thread_t*)->awake_time;
00142         B= bli_dt(b,thread_t*)->awake_time;
00143 
00144         if (A > B)
00145                 preturn( 1);
00146         if (B > A)
00147                 preturn( -1);
00148         preturn( 0);
00149  }
00150 
00151 
00152 int sleep(thread_t *thread, uint64 time)
00153  { _Pf("Thread::sleep");
00154 int i;
00155 
00156 
00157 uint32 fl;
00158         asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00159         Scheduler::lock_scheduler.lock();
00160         lock_sleep.lock();
00161         lock_system.lock();
00162         if (time != 0)
00163                 thread->awake_time=Arch::x86::RTC::up_time+time;
00164         else
00165                 thread->awake_time=0xffffffffffffffffll;
00166 
00167 
00168         i=unqueue_thread(thread, &threads_queue[thread->priority]);
00169         if (i!= ESUCCESS)
00170                 if (current_thread==thread) i=ESUCCESS;
00171 
00172         if (i!= ESUCCESS) {
00173                 lock_system.ulock();
00174                 lock_sleep.ulock();
00175                 Scheduler::lock_scheduler.ulock();
00176                 asm volatile("pushl %0\npopf"::"g"(fl));
00177                 preturn( i ); }
00178 
00179 
00180         if ((thread->state & TH_DYING) == 0) {
00181                 lock_queues.lock();
00182                 i= (blistsort_ptr(&threads_sleep, thread, NULL, &sleepcompar)==NULL? EFAIL:ESUCCESS);
00183                 lock_queues.ulock(); }
00184 
00185 
00186 
00187         thread->state&=(0xFFFFFFFF- TH_ACTIVE-TH_BUSY);
00188         thread->state|=TH_ASLEEP;
00189 
00190 
00191 
00192 
00193         lock_system.ulock();
00194         lock_sleep.ulock();
00195         Scheduler::lock_scheduler.ulock();
00196         asm volatile("pushl %0\npopf"::"g"(fl));
00197 
00198 
00199         if (thread==current_thread) {
00200            asm volatile ("int $0x20":::"memory");       
00201                 do {} while (thread->state & TH_ASLEEP);
00202    }
00203 
00204         preturn(  i  );
00205  }
00206 
00207 
00208 int sleep(uint64 time) {
00209         return sleep((Thread::thread_t*)current_thread, time);
00210  }
00211 
00212 
00213 int awake(thread_t *thread)
00214  { _Pf("Thread::awake");
00215 int i;
00216 uint32 fl;
00217         asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00218         if (Thread::Scheduler::multitasking_running==false)
00219                 { asm volatile ("pushl %0\npopf"::"g"(fl)); preturn( EINVAL ); }
00220 
00221         if ((thread->state&TH_ASLEEP)==0)
00222                 { asm volatile ("pushl %0\npopf"::"g"(fl)); preturn( EINVAL ); }
00223 
00224         Scheduler::lock_scheduler.lock();
00225         lock_sleep.lock();
00226         lock_system.lock();
00227 
00228         i=unqueue_thread(thread, &threads_sleep);
00229         if (i!= ESUCCESS) {
00230                 lock_system.ulock();
00231                 Scheduler::lock_scheduler.ulock();
00232                 lock_sleep.ulock();
00233                 asm volatile ("pushl %0\npopf"::"g"(fl));
00234                 preturn( i ); }
00235 
00236         thread->state&=(0xffffffff-TH_ASLEEP);
00237         thread->state|=TH_ACTIVE;
00238 
00239 
00240         enqueue_thread(thread, &threads_queue[thread->priority]);
00241 
00242         lock_system.ulock();
00243         lock_sleep.ulock();
00244         Scheduler::lock_scheduler.ulock();
00245 
00246         asm volatile ("pushl %0\npopf"::"g"(fl));
00247         preturn( ESUCCESS );
00248  }
00249 
00250 
00251 int sem_sleep(thread_t *thread, struct sem_t *sem_id, uint64 sem_dt)
00252  {
00253         thread->sem_id=sem_id;
00254         thread->sem_dt=sem_dt;
00255         return sleep(thread,0);
00256  }
00257 
00258 
00259 int sem_sleep(struct sem_t *sem_id, uint64 sem_dt) {
00260         return sem_sleep((Thread::thread_t*)current_thread, sem_id, sem_dt);
00261  }
00262 
00263 
00264 int sem_awake(thread_t *thread)
00265  {
00266         thread->sem_id=NULL;
00267         thread->sem_dt=0;
00268         return awake(thread);
00269  }
00270 
00271 thread_t *ThreadGet(int procno, int threadno)
00272  {
00273 process_t *proc;
00274         proc= ProcessGet(procno);
00275         if (proc==NULL) return NULL;
00276 
00277 blist_s *item;
00278         for(item=proc->thread_list.head;item&&(bli_dt(item,thread_t*)->no<=threadno);item=item->next)
00279                 if (bli_dt(item,thread_t*)->no==threadno)
00280                         return bli_dt(item,thread_t*);
00281 
00282         return NULL;
00283  }
00284 
00285 int ThreadKill(thread_t *thread)
00286  {
00287 uint32 fl;
00288         asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00289 
00290         thread->state|=TH_DYING;
00291         threads_dead.ptr(thread, NULL);
00292         asm volatile("pushl %0\npopf"::"g"(fl));
00293 
00294         return sleep(thread, 0);
00295  }
00296 
00297 int ThreadKill(int procno, int threadno) {
00298         return ThreadKill(ThreadGet(procno, threadno));
00299  }
00300 
00301  };     
00302 
00303 
00304 
00305 
00306 
00307