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