00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #include "src/common/shared.hpp"
00019 #include "src/common/string.hpp"
00020 #include "src/common/blist.hpp"
00021 #include "src/common/blistsort.hpp"
00022 #include "src/common/qsort.hpp"
00023 #include "src/memory/memset.hpp"
00024 #include "src/memory/align.hpp"
00025 #include "src/memory/alloc4k.hpp"
00026 #include "src/memory/heap.hpp"
00027 #include "src/memory/pager.hpp"
00028 #include "src/arch/x86/context.hpp"
00029 #include "src/arch/x86/interr.hpp"
00030 #include "src/arch/x86/except_c.hpp"
00031 #include "src/arch/x86/rtc.hpp"
00032 #include "src/thread/scheduler.hpp"
00033 #include "src/thread/process.hpp"
00034 
00035 inline void *kmalloc (size_t size, size_t alignment, uint32 facility, int (*destruct)(class Memory::Heap::heapbox*,void*))
00036  {
00037         return Memory::Heap::heap0.malloc(size,alignment,facility,destruct);
00038  }
00039 
00040 inline int kfree(void *ptr)
00041  {
00042         return Memory::Heap::heap0.free(ptr);
00043  }
00044 
00045 
00046 int EnvGet(struct env_t *env)
00047  {
00048         memset(env,0,sizeof(struct env_t));
00049         if (Thread::Scheduler::multitasking_running) {
00050                 env->thread= (Thread::thread_t*)current_thread;
00051                 env->proc= current_thread->proc;
00052                 env->mtree= env->proc->mem;
00053                 env->code= env->thread->env.cd;
00054         } else {
00055                 env->mtree= &Memory::Pager::kmem;
00056         }
00057 
00058         return ESUCCESS;
00059  }
00060 
00063 namespace Thread {
00064 
00065 
00066 
00067 process_t kernel_process;       
00068 class blist_t Processes;        
00069 
00070 int LastProcessNum= 1;
00071 
00072 
00073 int ProcessRegister(class process_t *proc)
00074  {
00075         proc->no= LastProcessNum++;
00076         Processes.ptr(proc, NULL);
00077 
00078         return proc->no;
00079  }
00080 
00081 
00082 int ProcessKill(int no)
00083  {
00084 process_t *proc;
00085         proc= ProcessGet(no);
00086         if (proc == NULL) return EFAIL;
00087 
00088 blist_s *item;
00089 bool b=false;
00090         for(item=proc->thread_list.head;item;item=item->next)
00091                 if (bli_dt(item,thread_t*)!=current_thread) ThreadKill(bli_dt(item,thread_t*));
00092                         else b=true;
00093 
00094         if (b) ThreadKill((Thread::thread_t*)current_thread);
00095         return ESUCCESS;
00096  }
00097 
00098 
00099 process_t *ProcessGet(int i)
00100  {
00101 blist_s *item;
00102         for (item=Processes.head;item && (bli_dt(item,process_t*)->no <= i) ;item=item->next)
00103                 if (bli_dt(item,process_t*)->no == i) return bli_dt(item,process_t*);
00104         return NULL;
00105  }
00106 
00107 
00108 void process_t::init(char *nam, Memory::Pager::memtree *mtree)
00109  {
00110 
00111         memset(this,0,sizeof(process_t));
00112 
00113         mem= mtree;
00114         memmove(&name, nam, ( lgth(nam)<PROC_NAME-1 )? lgth(nam): PROC_NAME-1);
00115         thread_list.init(FAC_THREAD|FAC_THRLIST);
00116         allocate_heapbox(&heap, name);
00117  }
00118 
00119 
00120 void process_t::InitKeepHeap(const char *nam, Memory::Pager::memtree *mtree)
00121  {
00122 Memory::Heap::heapbox hp;
00123 
00124         memmove(&hp, &heap, sizeof(hp));
00125         memset(this,0,sizeof(process_t));
00126         memmove(&heap, &hp, sizeof(hp));
00127 
00128         mem= mtree;
00129         memmove(&name, nam, ( lgth(nam)<PROC_NAME-1 )? lgth(nam): PROC_NAME-1);
00130         thread_list.init(FAC_THREAD|FAC_THRLIST);
00131  }
00132 
00133 
00134 thread_t *process_t::create_thread(bool supervisor, uint32 proc_addr, uint32 worst_priority, uint32 best_priority,
00135                 const char name[])
00136  {
00137 
00138    best_priority = 0;
00139    worst_priority = 0;
00140 
00141 
00142 thread_t new_thread;
00143 uint32 stack;
00144         memset(&new_thread, 0, sizeof(thread_t));
00145    
00146         new_thread.no= ++max_thread_no; 
00147 
00148         stack= alloc_stack(supervisor, 0x2000, new_thread.no);
00149         if (stack == NULL)
00150          {
00151                 complain("alloc_stack failed");
00152                 return NULL; };
00153 
00154         new_thread.state=TH_ACTIVE;
00155         new_thread.creation_time=Arch::x86::RTC::up_time;
00156         new_thread.proc=this;
00157         allocate_context(&new_thread, supervisor, stack, proc_addr);
00158         new_thread.priority= MIN(DEF_THREAD_PRIOR,worst_priority);
00159         new_thread.worst_priority=worst_priority;
00160         new_thread.best_priority=best_priority;
00161 uint32 cnt = lgth(const_cast<char*>(name)) < THREAD_NAME-1 ? lgth(const_cast<char*>(name)) : THREAD_NAME-1;
00162         memmove(&new_thread.name, const_cast<char*>(name), cnt);
00163 
00164 thread_t *thr;
00165         thr=(thread_t*) 
00166                 thread_list.add(&new_thread, sizeof(thread_t), NULL)->data;
00167         allocate_mailbox(&thr->inbox, thr, &heap);
00168 
00169         Thread::enqueue_thread(thr, &Thread::threads_queue[thr->priority]);
00170 
00171         return thr;
00172  }
00173 
00174 int MmapDestroyStack(class mmap_t *m, struct mmap_s *s)
00175  {
00176 process_t *proc;
00177 uint32 i,addr;
00178         proc=(process_t*) (uint32) s->info;
00179         for (i=s->start;i<s->end; i+=PAGE_SIZE) {
00180                 addr= proc->mem->pte_val(i);
00181                 if (addr & PTE_PRESENT)         
00182 
00183                         disalloc4k(addr&0xfffff000);
00184          }
00185 
00186         return ESUCCESS;
00187  }
00188 
00189 
00190 uint32 process_t::alloc_stack(bool supervisor, size_t size, uint32 threadno)
00191  {
00192 
00193         if (supervisor)
00194                 return size + (uint32) heap.malloc(size, PAGE_ALIGN, "kernel thread heap", NULL);
00195 
00196 uint32 addr;
00197 int i;
00198         i= mem->memory_map.fitbelow(size, PAGE_ALIGN, mem_user_end+1, ME_STACK, NULL, (uint32)this, &addr, threadno, &MmapDestroyStack, false);
00199         if (i!= ESUCCESS)
00200                 return NULL;
00201 
00202 uint32 n;
00203         for (n=addr; n<addr+size;n+=PAGE_SIZE)
00204                 if (Memory::Pager::lazy_enable)
00205                         mem->pte_lazy(n, PTE_USER|PTE_WRITEABLE);
00206                 else
00207                         mem->pte_map(n, alloc4k(1,false)|PTE_WRITEABLE|PTE_USER|PTE_PRESENT);
00208 
00209         return addr+size;
00210  }
00211 
00212 
00213  };     
00214 
00215 
00216 
00217 
00218 
00219 
00220