__alloc_user_thread_stack(struct proc_info* proc,
struct mm_region** stack_region, ptr_t vm_mnt)
{
- ptr_t th_stack_top = (proc->thread_count + 1) * USR_STACK_SIZE;
- th_stack_top = ROUNDUP(USR_STACK_END - th_stack_top, MEM_PAGE);
+ ptr_t th_stack_top = (proc->thread_count + 1) * USR_STACK_SIZE_THREAD;
+ th_stack_top = ROUNDUP(USR_STACK_END - th_stack_top, PAGE_SIZE);
struct mm_region* vmr;
struct proc_mm* mm = vmspace(proc);
struct mmap_param param = { .vms_mnt = vm_mnt,
.pvms = mm,
- .mlen = USR_STACK_SIZE,
+ .mlen = USR_STACK_SIZE_THREAD,
.proct = PROT_READ | PROT_WRITE,
.flags = MAP_ANON | MAP_PRIVATE,
.type = REGION_TYPE_STACK };
return 0;
}
- set_pte(mkptep_va(vm_mnt, vmr->start), guard_pte);
+ pte_t* guardp = mkptep_va(vm_mnt, vmr->start);
+ set_pte(guardp, guard_pte);
*stack_region = vmr;
- ptr_t stack_top = align_stack(th_stack_top + USR_STACK_SIZE - 1);
+ ptr_t stack_top = align_stack(th_stack_top + USR_STACK_SIZE_THREAD - 1);
return stack_top;
}
pfn_t kstack_end = pfn(KSTACK_AREA);
pte_t* ptep = mkptep_pn(vm_mnt, kstack_top);
while (ptep_pfn(ptep) > kstack_end) {
- ptep -= KSTACK_PAGES;
+ ptep -= KSTACK_PAGES + 1;
- // first page in the kernel stack is guardian page
- pte_t pte = *(ptep + 1);
+ pte_t pte = pte_at(ptep + 1);
if (pte_isnull(pte)) {
goto found;
}
return 0;
found:;
- // KSTACK_PAGES = 3, removal one guardian pte, give order 1 page
- struct leaflet* leaflet = alloc_leaflet(1);
+ unsigned int po = count_order(KSTACK_PAGES);
+ struct leaflet* leaflet = alloc_leaflet(po);
if (!leaflet) {
WARN("failed to create kernel stack: nomem\n");
th->kstack = kstack;
th->ustack = ustack_region;
+
+ if (ustack_region) {
+ th->ustack_top = align_stack(ustack_region->end - 1);
+ }
return th;
}
if (!kernel_addr(entry)) {
assert(th->ustack);
- ptr_t ustack_top = align_stack(th->ustack->end - 1);
- ustack_top -= 16; // pre_allocate a 16 byte for inject parameter
- hart_user_transfer(&transition, th->kstack, ustack_top, entry);
-
- th->ustack_top = ustack_top;
+ hart_user_transfer(&transition, th->kstack, th->ustack_top, entry);
}
else {
hart_kernel_transfer(&transition, th->kstack, entry);
return NULL;
}
-__DEFINE_LXSYSCALL4(int, th_create, tid_t*, tid, struct uthread_info*, thinfo,
- void*, entry, void*, param)
+__DEFINE_LXSYSCALL3(int, th_create, tid_t*, tid,
+ struct uthread_param*, thparam, void*, entry)
{
struct thread* th = create_thread(__current, true);
if (!th) {
return EAGAIN;
}
- start_thread(th, (ptr_t)entry);
+ ptr_t ustack_top;
+
+ ustack_top = th->ustack_top;
+ ustack_top = align_stack(ustack_top - sizeof(*thparam));
- ptr_t ustack_top = th->ustack_top;
- *((void**)ustack_top) = param;
+ memcpy((void*)ustack_top, thparam, sizeof(*thparam));
- thinfo->th_stack_sz = region_size(th->ustack);
- thinfo->th_stack_top = (void*)ustack_top;
+ th->ustack_top = ustack_top;
+ start_thread(th, (ptr_t)entry);
if (tid) {
*tid = th->tid;