user/kernel stack size, clear content of ANONYMOUS mmap, changes to scheduler (CPU idle state)

This commit is contained in:
Balazs Gerofi
2012-05-10 14:20:52 +09:00
parent d679844685
commit 97d4c85195
3 changed files with 72 additions and 83 deletions

View File

@ -15,6 +15,10 @@
#define dkprintf(...)
#endif
#define USER_STACK_NR_PAGES 4
#define KERNEL_STACK_NR_PAGES 4
extern long do_arch_prctl(unsigned long code, unsigned long address);
void init_process_vm(struct process_vm *vm)
@ -35,14 +39,15 @@ struct process *create_process(unsigned long user_pc)
{
struct process *proc;
proc = aal_mc_alloc_pages(3, 0);
proc = aal_mc_alloc_pages(KERNEL_STACK_NR_PAGES, 0);
if (!proc)
return NULL;
memset(proc, 0, sizeof(struct process));
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
((char *)proc) + 3 * PAGE_SIZE, user_pc, 0);
((char *)proc) +
KERNEL_STACK_NR_PAGES * PAGE_SIZE, user_pc, 0);
proc->vm = (struct process_vm *)(proc + 1);
@ -56,18 +61,18 @@ struct process *clone_process(struct process *org, unsigned long pc,
{
struct process *proc;
proc = aal_mc_alloc_pages(1, 0);
proc = aal_mc_alloc_pages(KERNEL_STACK_NR_PAGES, 0);
memset(proc, 0, sizeof(*proc));
memset(proc, 0, KERNEL_STACK_NR_PAGES);
/* NOTE: sp is the user mode stack! */
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
((char *)proc) + PAGE_SIZE, pc, sp);
((char *)proc) +
KERNEL_STACK_NR_PAGES * PAGE_SIZE, pc, sp);
memcpy(proc->uctx, org->uctx, sizeof(*org->uctx));
aal_mc_modify_user_context(proc->uctx, AAL_UCR_STACK_POINTER,
sp);
aal_mc_modify_user_context(proc->uctx, AAL_UCR_PROGRAM_COUNTER,
pc);
aal_mc_modify_user_context(proc->uctx, AAL_UCR_STACK_POINTER, sp);
aal_mc_modify_user_context(proc->uctx, AAL_UCR_PROGRAM_COUNTER, pc);
aal_atomic_inc(&org->vm->refcount);
proc->vm = org->vm;
@ -131,16 +136,17 @@ int add_process_memory_range(struct process *process,
}
#define NR_STACK_PAGES 2
void init_process_stack(struct process *process)
{
char *stack = aal_mc_alloc_pages(NR_STACK_PAGES, 0);
unsigned long *p = (unsigned long *)(stack + (NR_STACK_PAGES * PAGE_SIZE));
char *stack = aal_mc_alloc_pages(USER_STACK_NR_PAGES, 0);
unsigned long *p = (unsigned long *)(stack +
(USER_STACK_NR_PAGES * PAGE_SIZE));
memset(stack, 0, NR_STACK_PAGES * PAGE_SIZE);
memset(stack, 0, USER_STACK_NR_PAGES * PAGE_SIZE);
add_process_memory_range(process, USER_END - (NR_STACK_PAGES * PAGE_SIZE),
add_process_memory_range(process, USER_END -
(USER_STACK_NR_PAGES * PAGE_SIZE),
USER_END,
virt_to_phys(stack), VR_STACK);
@ -158,7 +164,8 @@ void init_process_stack(struct process *process)
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
USER_END - sizeof(unsigned long) * 9);
process->vm->region.stack_end = USER_END;
process->vm->region.stack_start = USER_END - (NR_STACK_PAGES * PAGE_SIZE);
process->vm->region.stack_start = USER_END -
(USER_STACK_NR_PAGES * PAGE_SIZE);
}
@ -181,14 +188,18 @@ unsigned long extend_process_region(struct process *proc,
aligned_new_end = (address + PAGE_SIZE - 1) & PAGE_MASK;
p = allocate_pages((aligned_new_end - aligned_end) >> PAGE_SHIFT,
0);
p = allocate_pages((aligned_new_end - aligned_end) >> PAGE_SHIFT, 0);
if (!p) {
return end;
}
/* Clear content! */
memset(p, 0, aligned_new_end - aligned_end);
add_process_memory_range(proc, aligned_end, aligned_new_end,
virt_to_phys(p), 0);
return address;
}
@ -243,10 +254,12 @@ static void idle(void)
//unsigned int flags;
//flags = aal_mc_spinlock_lock(&cpu_status_lock);
//aal_mc_spinlock_unlock(&cpu_status_lock, flags);
cpu_local_var(status) = CPU_STATUS_IDLE;
while (1) {
cpu_enable_interrupt();
schedule();
cpu_local_var(status) = CPU_STATUS_IDLE;
//cpu_local_var(status) = CPU_STATUS_IDLE;
cpu_halt();
}
}
@ -321,14 +334,14 @@ void schedule(void)
kprintf("[%d] schedule: tlsblock_base: 0x%lX\n",
aal_mc_get_processor_id(), next->thread.tlsblock_base);
/* Set up new TLS.. */
do_arch_prctl(ARCH_SET_FS, next->thread.tlsblock_base);
if (next != &cpu_local_var(idle))
cpu_local_var(status) = CPU_STATUS_RUNNING;
if (prev) {
aal_mc_switch_context(&prev->ctx, &next->ctx);
} else {
}
else {
aal_mc_switch_context(NULL, &next->ctx);
}
}
@ -386,12 +399,13 @@ void runq_add_proc(struct process *proc, int cpu_id)
__runq_add_proc(proc, cpu_id);
aal_mc_spinlock_unlock(&(v->runq_lock), irqstate);
/*
if (cpu != this_cpu)
xcall_reschedule(cpu);
*/
/* Kick scheduler */
if (cpu_id != aal_mc_get_processor_id())
aal_mc_interrupt_cpu(
get_x86_cpu_local_variable(cpu_id)->apic_id, 0xd1);
}
/* NOTE: shouldn't remove a running process! */
void runq_del_proc(struct process *proc, int cpu_id)
{
struct cpu_local_var *v = get_cpu_local_var(cpu_id);
@ -399,7 +413,11 @@ void runq_del_proc(struct process *proc, int cpu_id)
irqstate = aal_mc_spinlock_lock(&(v->runq_lock));
list_del(&proc->sched_list);
++v->runq_len;
--v->runq_len;
if (!v->runq_len)
get_cpu_local_var(cpu_id)->status = CPU_STATUS_IDLE;
aal_mc_spinlock_unlock(&(v->runq_lock), irqstate);
}