runqueues and schedule()

This commit is contained in:
Balazs Gerofi
2012-05-03 18:38:08 +09:00
parent c3226018b9
commit 8c34463dd4
5 changed files with 140 additions and 32 deletions

View File

@ -10,6 +10,14 @@
#include <process.h> #include <process.h>
#include <page.h> #include <page.h>
#define DEBUG_PRINT_HOST
#ifdef DEBUG_PRINT_HOST
#define dkprintf kprintf
#else
#define dkprintf(...)
#endif
/* /*
* Communication with host * Communication with host
*/ */
@ -29,7 +37,7 @@ static void process_msg_prepare_process(unsigned long rphys)
p = aal_mc_map_virtual(phys, npages, PTATTR_WRITABLE); p = aal_mc_map_virtual(phys, npages, PTATTR_WRITABLE);
n = p->num_sections; n = p->num_sections;
kprintf("# of sections: %d\n", n); dkprintf("# of sections: %d\n", n);
pn = aal_mc_allocate(sizeof(struct program_load_desc) pn = aal_mc_allocate(sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * n, 0); + sizeof(struct program_image_section) * n, 0);
@ -92,7 +100,7 @@ static void process_msg_prepare_process(unsigned long rphys)
p->rprocess = (unsigned long)proc; p->rprocess = (unsigned long)proc;
init_process_stack(proc); init_process_stack(proc);
kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid, dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
proc->vm->page_table); proc->vm->page_table);
aal_mc_free(pn); aal_mc_free(pn);
@ -143,14 +151,14 @@ static void process_msg_init_acked(unsigned long pphys)
lparam->post_fin = 1; lparam->post_fin = 1;
kprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id()); dkprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id());
kprintf(" Response: %lx, %p\n", dkprintf(" Response: %lx, %p\n",
lparam->response_pa, lparam->response_va); lparam->response_pa, lparam->response_va);
kprintf(" Request : %lx, %lx, %p\n", dkprintf(" Request : %lx, %lx, %p\n",
lparam->request_pa, lparam->request_rpa, lparam->request_va); lparam->request_pa, lparam->request_rpa, lparam->request_va);
kprintf(" Doorbell: %lx, %lx, %p\n", dkprintf(" Doorbell: %lx, %lx, %p\n",
lparam->doorbell_pa, lparam->doorbell_rpa, lparam->doorbell_va); lparam->doorbell_pa, lparam->doorbell_rpa, lparam->doorbell_va);
kprintf(" Post: %lx, %lx, %p\n", dkprintf(" Post: %lx, %lx, %p\n",
lparam->post_pa, lparam->post_rpa, lparam->post_va); lparam->post_pa, lparam->post_rpa, lparam->post_va);
} }
@ -168,7 +176,7 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
switch (packet->msg) { switch (packet->msg) {
case SCD_MSG_INIT_CHANNEL_ACKED: case SCD_MSG_INIT_CHANNEL_ACKED:
kprintf("init channel acked!\n"); dkprintf("SCD_MSG_INIT_CHANNEL_ACKED\n");
process_msg_init_acked(packet->arg); process_msg_init_acked(packet->arg);
return 0; return 0;
@ -183,9 +191,12 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
return 0; return 0;
case SCD_MSG_SCHEDULE_PROCESS: case SCD_MSG_SCHEDULE_PROCESS:
kprintf("next one : %lx\n", packet->arg); dkprintf("SCD_MSG_SCHEDULE_PROCESS: %lx\n", packet->arg);
cpu_local_var(next) = (struct process *)packet->arg; runq_add_proc((struct process *)packet->arg,
aal_mc_get_processor_id());
//cpu_local_var(next) = (struct process *)packet->arg;
return 0; return 0;
} }
return 0; return 0;
@ -202,12 +213,12 @@ void init_host_syscall_channel(void)
param.magic = 0x1129; param.magic = 0x1129;
param.handler = syscall_packet_handler; param.handler = syscall_packet_handler;
kprintf("(syscall) Trying to connect host ..."); dkprintf("(syscall) Trying to connect host ...");
while (aal_ikc_connect(NULL, &param) != 0) { while (aal_ikc_connect(NULL, &param) != 0) {
kprintf("."); dkprintf(".");
aal_mc_delay_us(1000 * 1000); aal_mc_delay_us(1000 * 1000);
} }
kprintf("connected.\n"); dkprintf("connected.\n");
get_this_cpu_local_var()->syscall_channel = param.channel; get_this_cpu_local_var()->syscall_channel = param.channel;

View File

@ -25,8 +25,10 @@ struct cpu_local_var {
struct process idle; struct process idle;
struct process_vm idle_vm; struct process_vm idle_vm;
aal_spinlock_t runq_lock;
struct process *current; struct process *current;
struct process *next; struct list_head runq;
size_t runq_len;
struct aal_ikc_channel_desc *syscall_channel; struct aal_ikc_channel_desc *syscall_channel;

View File

@ -12,7 +12,11 @@
#define VR_IO_NOCACHE 0x100 #define VR_IO_NOCACHE 0x100
#define VR_REMOTE 0x200 #define VR_REMOTE 0x200
#define PS_ZOMBIE 0x1 #define PS_RUNNING 0x1
#define PS_INTERRUPTIBLE 0x2
#define PS_UNINTERRUPTIBLE 0x3
#define PS_ZOMBIE 0x4
#define PS_EXITED 0x5
struct vm_range { struct vm_range {
struct list_head list; struct list_head list;
@ -41,12 +45,15 @@ struct process_vm {
struct process { struct process {
int pid; int pid;
int status; int status;
int cpu_id;
struct process_vm *vm; struct process_vm *vm;
aal_mc_kernel_context_t ctx; aal_mc_kernel_context_t ctx;
aal_mc_user_context_t *uctx; aal_mc_user_context_t *uctx;
struct list_head sched_list; // Runqueue
struct thread { struct thread {
int *clear_child_tid; int *clear_child_tid;
} thread; } thread;
@ -69,5 +76,7 @@ unsigned long extend_process_region(struct process *proc,
unsigned long address); unsigned long address);
void schedule(void); void schedule(void);
void runq_add_proc(struct process *proc, int cpu_id);
void runq_del_proc(struct process *proc, int cpu_id);
#endif #endif

View File

@ -21,6 +21,7 @@ void init_process_vm(struct process_vm *vm)
aal_atomic_set(&vm->refcount, 1); aal_atomic_set(&vm->refcount, 1);
INIT_LIST_HEAD(&vm->vm_range_list); INIT_LIST_HEAD(&vm->vm_range_list);
vm->page_table = aal_mc_pt_create(); vm->page_table = aal_mc_pt_create();
vm->region.tlsblock_base = 0;
} }
struct process *create_process(unsigned long user_pc) struct process *create_process(unsigned long user_pc)
@ -248,28 +249,56 @@ void sched_init(void)
idle_process->vm = &cpu_local_var(idle_vm); idle_process->vm = &cpu_local_var(idle_vm);
aal_mc_init_context(&idle_process->ctx, NULL, idle); aal_mc_init_context(&idle_process->ctx, NULL, idle);
idle_process->pid = aal_mc_get_processor_id();
cpu_local_var(next) = idle_process; INIT_LIST_HEAD(&cpu_local_var(runq));
cpu_local_var(status) = CPU_STATUS_RUNNING; cpu_local_var(runq_len) = 0;
aal_mc_spinlock_init(&cpu_local_var(runq_lock));
} }
void schedule(void) void schedule(void)
{ {
struct cpu_local_var *v = get_this_cpu_local_var(); struct cpu_local_var *v = get_this_cpu_local_var();
struct process *next, *prev; struct process *next, *prev, *proc, *tmp = NULL;
int switch_ctx = 0; int switch_ctx = 0;
unsigned long irqstate;
cpu_disable_interrupt(); irqstate = aal_mc_spinlock_lock(&(v->runq_lock));
if (v->next && v->next != v->current) {
prev = v->current;
next = v->next;
switch_ctx = 1; next = NULL;
prev = v->current;
v->current = next; /* All runnable processes are on the runqueue */
v->next = NULL; if (prev && prev != &cpu_local_var(idle)) {
list_del(&prev->sched_list);
--v->runq_len;
/* Round-robin if not exited yet */
if (prev->status != PS_EXITED) {
list_add_tail(&prev->sched_list, &(v->runq));
++v->runq_len;
}
} }
cpu_enable_interrupt();
/* Pick a new running process */
list_for_each_entry_safe(proc, tmp, &(v->runq), sched_list) {
if (proc->status == PS_RUNNING) {
next = proc;
break;
}
}
/* No process? Run idle.. */
if (!next) {
next = &cpu_local_var(idle);
}
if (prev != next) {
switch_ctx = 1;
v->current = next;
}
aal_mc_spinlock_unlock(&(v->runq_lock), irqstate);
if (switch_ctx) { if (switch_ctx) {
dkprintf("[%d] schedule: %d => %d \n", dkprintf("[%d] schedule: %d => %d \n",
@ -277,7 +306,6 @@ void schedule(void)
prev ? prev->pid : 0, next ? next->pid : 0); prev ? prev->pid : 0, next ? next->pid : 0);
aal_mc_load_page_table(next->vm->page_table); aal_mc_load_page_table(next->vm->page_table);
do_arch_prctl(ARCH_SET_FS, next->vm->region.tlsblock_base); do_arch_prctl(ARCH_SET_FS, next->vm->region.tlsblock_base);
if (prev) { if (prev) {
@ -288,4 +316,42 @@ void schedule(void)
} }
} }
/* Runq lock must be held here */
void __runq_add_proc(struct process *proc, int cpu_id)
{
struct cpu_local_var *v = get_cpu_local_var(cpu_id);
list_add_tail(&proc->sched_list, &v->runq);
++v->runq_len;
proc->cpu_id = cpu_id;
proc->status = PS_RUNNING;
dkprintf("runq_add_proc(): pid %d added to CPU[%d]'s runq\n",
proc->pid, cpu_id);
}
void runq_add_proc(struct process *proc, int cpu_id)
{
struct cpu_local_var *v = get_cpu_local_var(cpu_id);
unsigned long irqstate;
irqstate = aal_mc_spinlock_lock(&(v->runq_lock));
__runq_add_proc(proc, cpu_id);
aal_mc_spinlock_unlock(&(v->runq_lock), irqstate);
/*
if (cpu != this_cpu)
xcall_reschedule(cpu);
*/
}
void runq_del_proc(struct process *proc, int cpu_id)
{
struct cpu_local_var *v = get_cpu_local_var(cpu_id);
unsigned long irqstate;
irqstate = aal_mc_spinlock_lock(&(v->runq_lock));
list_del(&proc->sched_list);
++v->runq_len;
aal_mc_spinlock_unlock(&(v->runq_lock), irqstate);
}

View File

@ -213,9 +213,12 @@ SYSCALL_DECLARE(exit_group)
SYSCALL_HEADER; SYSCALL_HEADER;
do_syscall(&request, ctx); do_syscall(&request, ctx);
runq_del_proc(cpu_local_var(current), aal_mc_get_processor_id());
free_process_memory(cpu_local_var(current)); free_process_memory(cpu_local_var(current));
cpu_local_var(next) = &cpu_local_var(idle);
//cpu_local_var(next) = &cpu_local_var(idle);
cpu_local_var(current) = NULL;
schedule(); schedule();
return 0; return 0;
@ -422,7 +425,7 @@ SYSCALL_DECLARE(clone)
unsigned long pptid; unsigned long pptid;
int *vptid; int *vptid;
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table,
aal_mc_syscall_arg2(ctx), &pptid)) (int*)aal_mc_syscall_arg2(ctx), &pptid))
return -EFAULT; return -EFAULT;
vptid = (int *)phys_to_virt(pptid); vptid = (int *)phys_to_virt(pptid);
@ -430,13 +433,15 @@ SYSCALL_DECLARE(clone)
} }
new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID)
? aal_mc_syscall_arg3(ctx) ? (int*)aal_mc_syscall_arg3(ctx)
: NULL; : NULL;
aal_mc_syscall_ret(new->uctx) = 0; aal_mc_syscall_ret(new->uctx) = 0;
get_cpu_local_var(cpuid)->next = new;
get_cpu_local_var(cpuid)->status = CPU_STATUS_RUNNING; runq_add_proc(new, cpuid);
//get_cpu_local_var(cpuid)->next = new;
//get_cpu_local_var(cpuid)->status = CPU_STATUS_RUNNING;
//aal_mc_spinlock_unlock(&cpu_status_lock, flags); //aal_mc_spinlock_unlock(&cpu_status_lock, flags);
aal_mc_interrupt_cpu(aal_mc_get_cpu_info()->hw_ids[cpuid], 0xd1); aal_mc_interrupt_cpu(aal_mc_get_cpu_info()->hw_ids[cpuid], 0xd1);
@ -446,6 +451,18 @@ SYSCALL_DECLARE(clone)
return new->pid; return new->pid;
} }
SYSCALL_DECLARE(set_tid_address)
{
cpu_local_var(current)->thread.clear_child_tid =
(int*)aal_mc_syscall_arg2(ctx);
return cpu_local_var(current)->pid;
}
SYSCALL_DECLARE(set_robust_list)
{
return -ENOSYS;
}
SYSCALL_DECLARE(writev) SYSCALL_DECLARE(writev)
{ {
@ -510,7 +527,10 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
[110] = sys_getxid, [110] = sys_getxid,
[111] = sys_getxid, [111] = sys_getxid,
[158] = sys_arch_prctl, [158] = sys_arch_prctl,
[218] = sys_set_tid_address,
[231] = sys_exit_group, [231] = sys_exit_group,
[273] = sys_set_robust_list,
[288] = NULL,
}; };
#if 0 #if 0