runqueues and schedule()
This commit is contained in:
@ -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, ¶m) != 0) {
|
while (aal_ikc_connect(NULL, ¶m) != 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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user