runqueues and schedule()
This commit is contained in:
@@ -10,6 +10,14 @@
|
||||
#include <process.h>
|
||||
#include <page.h>
|
||||
|
||||
#define DEBUG_PRINT_HOST
|
||||
|
||||
#ifdef DEBUG_PRINT_HOST
|
||||
#define dkprintf kprintf
|
||||
#else
|
||||
#define dkprintf(...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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)
|
||||
+ 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;
|
||||
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);
|
||||
|
||||
aal_mc_free(pn);
|
||||
@@ -143,14 +151,14 @@ static void process_msg_init_acked(unsigned long pphys)
|
||||
|
||||
lparam->post_fin = 1;
|
||||
|
||||
kprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id());
|
||||
kprintf(" Response: %lx, %p\n",
|
||||
dkprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id());
|
||||
dkprintf(" Response: %lx, %p\n",
|
||||
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);
|
||||
kprintf(" Doorbell: %lx, %lx, %p\n",
|
||||
dkprintf(" Doorbell: %lx, %lx, %p\n",
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -168,7 +176,7 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
|
||||
|
||||
switch (packet->msg) {
|
||||
case SCD_MSG_INIT_CHANNEL_ACKED:
|
||||
kprintf("init channel acked!\n");
|
||||
dkprintf("SCD_MSG_INIT_CHANNEL_ACKED\n");
|
||||
process_msg_init_acked(packet->arg);
|
||||
return 0;
|
||||
|
||||
@@ -183,9 +191,12 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
|
||||
return 0;
|
||||
|
||||
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;
|
||||
@@ -202,12 +213,12 @@ void init_host_syscall_channel(void)
|
||||
param.magic = 0x1129;
|
||||
param.handler = syscall_packet_handler;
|
||||
|
||||
kprintf("(syscall) Trying to connect host ...");
|
||||
dkprintf("(syscall) Trying to connect host ...");
|
||||
while (aal_ikc_connect(NULL, ¶m) != 0) {
|
||||
kprintf(".");
|
||||
dkprintf(".");
|
||||
aal_mc_delay_us(1000 * 1000);
|
||||
}
|
||||
kprintf("connected.\n");
|
||||
dkprintf("connected.\n");
|
||||
|
||||
get_this_cpu_local_var()->syscall_channel = param.channel;
|
||||
|
||||
|
||||
@@ -25,8 +25,10 @@ struct cpu_local_var {
|
||||
struct process idle;
|
||||
struct process_vm idle_vm;
|
||||
|
||||
aal_spinlock_t runq_lock;
|
||||
struct process *current;
|
||||
struct process *next;
|
||||
struct list_head runq;
|
||||
size_t runq_len;
|
||||
|
||||
struct aal_ikc_channel_desc *syscall_channel;
|
||||
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
#define VR_IO_NOCACHE 0x100
|
||||
#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 list_head list;
|
||||
@@ -41,12 +45,15 @@ struct process_vm {
|
||||
struct process {
|
||||
int pid;
|
||||
int status;
|
||||
int cpu_id;
|
||||
|
||||
struct process_vm *vm;
|
||||
|
||||
aal_mc_kernel_context_t ctx;
|
||||
aal_mc_user_context_t *uctx;
|
||||
|
||||
struct list_head sched_list; // Runqueue
|
||||
|
||||
struct thread {
|
||||
int *clear_child_tid;
|
||||
} thread;
|
||||
@@ -69,5 +76,7 @@ unsigned long extend_process_region(struct process *proc,
|
||||
unsigned long address);
|
||||
|
||||
void schedule(void);
|
||||
void runq_add_proc(struct process *proc, int cpu_id);
|
||||
void runq_del_proc(struct process *proc, int cpu_id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@ void init_process_vm(struct process_vm *vm)
|
||||
aal_atomic_set(&vm->refcount, 1);
|
||||
INIT_LIST_HEAD(&vm->vm_range_list);
|
||||
vm->page_table = aal_mc_pt_create();
|
||||
vm->region.tlsblock_base = 0;
|
||||
}
|
||||
|
||||
struct process *create_process(unsigned long user_pc)
|
||||
@@ -248,28 +249,56 @@ void sched_init(void)
|
||||
idle_process->vm = &cpu_local_var(idle_vm);
|
||||
|
||||
aal_mc_init_context(&idle_process->ctx, NULL, idle);
|
||||
idle_process->pid = aal_mc_get_processor_id();
|
||||
|
||||
cpu_local_var(next) = idle_process;
|
||||
cpu_local_var(status) = CPU_STATUS_RUNNING;
|
||||
INIT_LIST_HEAD(&cpu_local_var(runq));
|
||||
cpu_local_var(runq_len) = 0;
|
||||
aal_mc_spinlock_init(&cpu_local_var(runq_lock));
|
||||
}
|
||||
|
||||
void schedule(void)
|
||||
{
|
||||
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;
|
||||
unsigned long irqstate;
|
||||
|
||||
cpu_disable_interrupt();
|
||||
if (v->next && v->next != v->current) {
|
||||
prev = v->current;
|
||||
next = v->next;
|
||||
irqstate = aal_mc_spinlock_lock(&(v->runq_lock));
|
||||
|
||||
switch_ctx = 1;
|
||||
next = NULL;
|
||||
prev = v->current;
|
||||
|
||||
v->current = next;
|
||||
v->next = NULL;
|
||||
/* All runnable processes are on the runqueue */
|
||||
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) {
|
||||
dkprintf("[%d] schedule: %d => %d \n",
|
||||
@@ -277,7 +306,6 @@ void schedule(void)
|
||||
prev ? prev->pid : 0, next ? next->pid : 0);
|
||||
|
||||
aal_mc_load_page_table(next->vm->page_table);
|
||||
|
||||
do_arch_prctl(ARCH_SET_FS, next->vm->region.tlsblock_base);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,9 +213,12 @@ SYSCALL_DECLARE(exit_group)
|
||||
SYSCALL_HEADER;
|
||||
do_syscall(&request, ctx);
|
||||
|
||||
runq_del_proc(cpu_local_var(current), aal_mc_get_processor_id());
|
||||
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();
|
||||
|
||||
return 0;
|
||||
@@ -422,7 +425,7 @@ SYSCALL_DECLARE(clone)
|
||||
unsigned long pptid;
|
||||
int *vptid;
|
||||
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;
|
||||
|
||||
vptid = (int *)phys_to_virt(pptid);
|
||||
@@ -430,13 +433,15 @@ SYSCALL_DECLARE(clone)
|
||||
}
|
||||
|
||||
new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID)
|
||||
? aal_mc_syscall_arg3(ctx)
|
||||
? (int*)aal_mc_syscall_arg3(ctx)
|
||||
: NULL;
|
||||
|
||||
|
||||
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_interrupt_cpu(aal_mc_get_cpu_info()->hw_ids[cpuid], 0xd1);
|
||||
|
||||
@@ -446,6 +451,18 @@ SYSCALL_DECLARE(clone)
|
||||
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)
|
||||
{
|
||||
@@ -510,7 +527,10 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
||||
[110] = sys_getxid,
|
||||
[111] = sys_getxid,
|
||||
[158] = sys_arch_prctl,
|
||||
[218] = sys_set_tid_address,
|
||||
[231] = sys_exit_group,
|
||||
[273] = sys_set_robust_list,
|
||||
[288] = NULL,
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
Reference in New Issue
Block a user