|
@@ -1,6 +1,9 @@
|
|
|
#include <memory>
|
|
|
+#include <queue>
|
|
|
#include <utility>
|
|
|
|
|
|
+#include <stdint.h>
|
|
|
+#include <stdio.h>
|
|
|
#include <bits/alltypes.h>
|
|
|
|
|
|
#include <asm/port_io.h>
|
|
@@ -15,8 +18,8 @@
|
|
|
#include <kernel/process.hpp>
|
|
|
#include <kernel/signal.hpp>
|
|
|
#include <kernel/vfs.hpp>
|
|
|
-#include <stdint.h>
|
|
|
-#include <stdio.h>
|
|
|
+#include <kernel/user/thread_local.hpp>
|
|
|
+
|
|
|
#include <types/allocator.hpp>
|
|
|
#include <types/bitmap.hpp>
|
|
|
#include <types/cplusplus.hpp>
|
|
@@ -50,52 +53,6 @@ struct no_irq_guard {
|
|
|
|
|
|
} // namespace kernel
|
|
|
|
|
|
-static types::bitmap* pkstack_bmp;
|
|
|
-
|
|
|
-void kernel::tasks::thread::alloc_kstack(void)
|
|
|
-{
|
|
|
- static int __allocated;
|
|
|
- if (!pkstack_bmp)
|
|
|
- pkstack_bmp = new types::bitmap((0x1000000 - 0xc00000) / THREAD_KERNEL_STACK_SIZE);
|
|
|
-
|
|
|
- for (int i = 0; i < __allocated; ++i) {
|
|
|
- if (pkstack_bmp->test(i) == 0) {
|
|
|
- pkstack = 0xffc00000 + THREAD_KERNEL_STACK_SIZE * (i + 1);
|
|
|
- esp = reinterpret_cast<uint32_t*>(pkstack);
|
|
|
-
|
|
|
- pkstack_bmp->set(i);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // kernel stack pt is at page#0x00005
|
|
|
- kernel::paccess pa(0x00005);
|
|
|
- auto pt = (pt_t)pa.ptr();
|
|
|
- assert(pt);
|
|
|
-
|
|
|
- auto cnt = THREAD_KERNEL_STACK_SIZE / PAGE_SIZE;
|
|
|
- pte_t* pte = *pt + __allocated * cnt;
|
|
|
-
|
|
|
- for (uint32_t i = 0; i < cnt; ++i) {
|
|
|
- pte[i].v = 0x3;
|
|
|
- pte[i].in.page = __alloc_raw_page();
|
|
|
- }
|
|
|
-
|
|
|
- pkstack = 0xffc00000 + THREAD_KERNEL_STACK_SIZE * (__allocated + 1);
|
|
|
- esp = reinterpret_cast<uint32_t*>(pkstack);
|
|
|
-
|
|
|
- pkstack_bmp->set(__allocated);
|
|
|
- ++__allocated;
|
|
|
-}
|
|
|
-
|
|
|
-void kernel::tasks::thread::free_kstack(uint32_t p)
|
|
|
-{
|
|
|
- p -= 0xffc00000;
|
|
|
- p /= THREAD_KERNEL_STACK_SIZE;
|
|
|
- p -= 1;
|
|
|
- pkstack_bmp->clear(p);
|
|
|
-}
|
|
|
-
|
|
|
int filearr::allocate_fd(int from)
|
|
|
{
|
|
|
if (from < min_avail)
|
|
@@ -252,6 +209,56 @@ void process::send_signal(signo_type signal)
|
|
|
thd.send_signal(signal);
|
|
|
}
|
|
|
|
|
|
+static std::priority_queue<std::byte*> s_kstacks;
|
|
|
+thread::kernel_stack::kernel_stack()
|
|
|
+{
|
|
|
+ static int allocated;
|
|
|
+ static types::mutex mtx;
|
|
|
+ types::lock_guard lck(mtx);
|
|
|
+
|
|
|
+ if (!s_kstacks.empty()) {
|
|
|
+ stack_base = s_kstacks.top();
|
|
|
+ esp = (uint32_t*)stack_base;
|
|
|
+ s_kstacks.pop();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // kernel stack pt is at page#0x00005
|
|
|
+ kernel::paccess pa(0x00005);
|
|
|
+ auto pt = (pt_t)pa.ptr();
|
|
|
+ assert(pt);
|
|
|
+
|
|
|
+ int cnt = THREAD_KERNEL_STACK_SIZE / PAGE_SIZE;
|
|
|
+ pte_t* pte = *pt + allocated * cnt;
|
|
|
+
|
|
|
+ for (int i = 0; i < cnt; ++i) {
|
|
|
+ pte[i].v = 0x3;
|
|
|
+ pte[i].in.page = __alloc_raw_page();
|
|
|
+ }
|
|
|
+
|
|
|
+ stack_base = (std::byte*)(0xffc00000 + THREAD_KERNEL_STACK_SIZE * (allocated + 1));
|
|
|
+ esp = (uint32_t*)stack_base;
|
|
|
+
|
|
|
+ ++allocated;
|
|
|
+}
|
|
|
+
|
|
|
+thread::kernel_stack::kernel_stack(const kernel_stack& other)
|
|
|
+ : kernel_stack()
|
|
|
+{
|
|
|
+ auto offset = vptrdiff(other.stack_base, other.esp);
|
|
|
+ esp = (uint32_t*)(stack_base - offset);
|
|
|
+ memcpy(esp, other.esp, offset);
|
|
|
+}
|
|
|
+
|
|
|
+thread::kernel_stack::kernel_stack(kernel_stack&& other)
|
|
|
+ : stack_base(std::exchange(other.stack_base, nullptr))
|
|
|
+ , esp(std::exchange(other.esp, nullptr)) { }
|
|
|
+
|
|
|
+thread::kernel_stack::~kernel_stack()
|
|
|
+{
|
|
|
+ s_kstacks.push(stack_base);
|
|
|
+}
|
|
|
+
|
|
|
void thread::sleep()
|
|
|
{
|
|
|
attr.ready = 0;
|
|
@@ -270,6 +277,40 @@ void thread::send_signal(signo_type signal)
|
|
|
this->wakeup();
|
|
|
}
|
|
|
|
|
|
+int thread::set_thread_area(kernel::user::user_desc* ptr)
|
|
|
+{
|
|
|
+ if (ptr->read_exec_only && ptr->seg_not_present) {
|
|
|
+ void* dst = (void*)ptr->base_addr;
|
|
|
+ std::size_t len = ptr->limit;
|
|
|
+ if (len > 0 && dst)
|
|
|
+ memset(dst, 0x00, len);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ptr->entry_number == -1U)
|
|
|
+ ptr->entry_number = 6;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ tls_desc.limit_low = ptr->limit & 0xFFFF;
|
|
|
+ tls_desc.base_low = ptr->base_addr & 0xFFFF;
|
|
|
+ tls_desc.base_mid = (ptr->base_addr >> 16) & 0xFF;
|
|
|
+ tls_desc.access = SD_TYPE_DATA_USER;
|
|
|
+ tls_desc.limit_high = (ptr->limit >> 16) & 0xF;
|
|
|
+ tls_desc.flags = (ptr->limit_in_pages << 3) | (ptr->seg_32bit << 2);
|
|
|
+ tls_desc.base_high = (ptr->base_addr >> 24) & 0xFF;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int thread::load_thread_area() const
|
|
|
+{
|
|
|
+ if (tls_desc.flags == 0)
|
|
|
+ return -1;
|
|
|
+ kernel::user::load_thread_area(tls_desc);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void proclist::kill(pid_t pid, int exit_code)
|
|
|
{
|
|
|
auto& proc = this->find(pid);
|
|
@@ -400,8 +441,8 @@ static void create_kthreadd_process()
|
|
|
assert(inserted);
|
|
|
auto& thd = *iter_thd;
|
|
|
|
|
|
- auto* esp = &thd.esp;
|
|
|
- auto old_esp = (uint32_t)thd.esp;
|
|
|
+ auto* esp = &thd.kstack.esp;
|
|
|
+ auto old_esp = (uint32_t)thd.kstack.esp;
|
|
|
|
|
|
// return(start) address
|
|
|
push_stack(esp, (uint32_t)kernel_threadd_main);
|
|
@@ -529,7 +570,7 @@ void NORETURN init_scheduler(void)
|
|
|
readythds->push(current_thread);
|
|
|
|
|
|
tss.ss0 = KERNEL_DATA_SEGMENT;
|
|
|
- tss.esp0 = current_thread->pkstack;
|
|
|
+ tss.esp0 = (uint32_t)current_thread->kstack.esp;
|
|
|
|
|
|
current_process->mms.switch_pd();
|
|
|
|
|
@@ -556,7 +597,7 @@ void NORETURN init_scheduler(void)
|
|
|
"%=:\n"
|
|
|
"ud2"
|
|
|
:
|
|
|
- : "a"(current_thread->esp), "c"(_kernel_init)
|
|
|
+ : "a"(current_thread->kstack.esp), "c"(_kernel_init)
|
|
|
: "memory");
|
|
|
|
|
|
freeze();
|
|
@@ -581,10 +622,12 @@ bool schedule()
|
|
|
curr_thd = current_thread;
|
|
|
|
|
|
current_thread = next_thd;
|
|
|
- tss.esp0 = (uint32_t)next_thd->esp;
|
|
|
+ tss.esp0 = (uint32_t)next_thd->kstack.esp;
|
|
|
+
|
|
|
+ next_thd->load_thread_area();
|
|
|
|
|
|
- asm_ctx_switch(&curr_thd->esp, &next_thd->esp);
|
|
|
- tss.esp0 = (uint32_t)curr_thd->esp;
|
|
|
+ asm_ctx_switch(&curr_thd->kstack.esp, &next_thd->kstack.esp);
|
|
|
+ tss.esp0 = (uint32_t)curr_thd->kstack.esp;
|
|
|
|
|
|
_end:
|
|
|
|