Support O2 optimization
This commit is contained in:
@@ -47,7 +47,7 @@ static inline struct CPU* cur_cpu(void)
|
||||
return &global_cpus[cur_cpuid()];
|
||||
}
|
||||
|
||||
struct spinlock whole_kernel_lock;
|
||||
extern struct spinlock whole_kernel_lock;
|
||||
|
||||
void xizi_enter_kernel();
|
||||
bool xizi_try_enter_kernel();
|
||||
|
||||
@@ -92,7 +92,7 @@ int sys_kill(int id);
|
||||
int sys_register_as_server(char* name);
|
||||
int sys_connect_session(char* path, int capacity, struct Session* user_session);
|
||||
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity);
|
||||
int sys_close_session(struct Session* session);
|
||||
int sys_close_session(struct TaskMicroDescriptor* task, struct Session* session);
|
||||
|
||||
int sys_exec(char* img_start, char* name, char** argv);
|
||||
int sys_state(sys_state_option option, sys_state_info* info);
|
||||
|
||||
@@ -35,12 +35,14 @@ Modification:
|
||||
#include "assert.h"
|
||||
#include "task.h"
|
||||
|
||||
struct spinlock whole_kernel_lock;
|
||||
|
||||
extern uint32_t _binary_init_start[], _binary_default_fs_start[];
|
||||
extern int sys_spawn(char* img_start, char* name, char** argv);
|
||||
|
||||
static struct TraceTag hardkernel_tag, softkernel_tag;
|
||||
static int core_init_done = 0;
|
||||
int main(void)
|
||||
static volatile int core_init_done = 0;
|
||||
__attribute__((optimize("O0"))) int main(void)
|
||||
{
|
||||
/* init tracer */
|
||||
uint32_t cpu_id = cur_cpuid();
|
||||
|
||||
@@ -294,11 +294,9 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv
|
||||
_map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SZ, dev_attr);
|
||||
|
||||
_p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr));
|
||||
// _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag);
|
||||
}
|
||||
|
||||
void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag)
|
||||
{
|
||||
_p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr));
|
||||
// _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag);
|
||||
}
|
||||
@@ -33,9 +33,8 @@ Modification:
|
||||
#include "syscall.h"
|
||||
#include "task.h"
|
||||
|
||||
int sys_close_session(struct Session* session)
|
||||
int sys_close_session(struct TaskMicroDescriptor* cur_task, struct Session* session)
|
||||
{
|
||||
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
|
||||
assert(cur_task != NULL);
|
||||
/* check if session is available */
|
||||
if (session->buf == NULL || (uintptr_t)session->buf < USER_IPC_SPACE_BASE || (uintptr_t)session->buf > USER_IPC_SPACE_TOP) {
|
||||
|
||||
@@ -35,7 +35,6 @@ Modification:
|
||||
#include "assert.h"
|
||||
#include "ipc.h"
|
||||
#include "kalloc.h"
|
||||
#include "mmu_common.h"
|
||||
#include "multicores.h"
|
||||
#include "share_page.h"
|
||||
#include "syscall.h"
|
||||
@@ -51,33 +50,35 @@ static struct {
|
||||
|
||||
static void send_irq_to_user(int irq_num)
|
||||
{
|
||||
struct Session* session = &irq_forward_table[irq_num].session;
|
||||
int len = IPC_ARG_INFO_BASE_OFFSET;
|
||||
len += sizeof(struct IpcArgInfo);
|
||||
if (irq_forward_table[irq_num].handle_task != NULL) {
|
||||
struct Session* session = &irq_forward_table[irq_num].session;
|
||||
int len = IPC_ARG_INFO_BASE_OFFSET;
|
||||
len += sizeof(struct IpcArgInfo);
|
||||
|
||||
/* get message space and add session tail */
|
||||
void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf));
|
||||
struct IpcMsg* buf = session_kern_vaddr + session->tail;
|
||||
/* get message space and add session tail */
|
||||
void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf));
|
||||
struct IpcMsg* buf = session_kern_vaddr + session->tail;
|
||||
|
||||
/* check if server session is full */
|
||||
if (buf->header.magic == IPC_MSG_MAGIC && buf->header.done == 0) {
|
||||
DEBUG("irq server cannot handle new interrupt by now.\n");
|
||||
return;
|
||||
/* check if server session is full */
|
||||
if (buf->header.magic == IPC_MSG_MAGIC && buf->header.done == 0) {
|
||||
DEBUG("irq server cannot handle new interrupt by now.\n");
|
||||
return;
|
||||
}
|
||||
memset((void*)buf, 0, len);
|
||||
session->tail = (session->tail + len) % session->capacity;
|
||||
|
||||
/* construct message */
|
||||
buf->header.len = len;
|
||||
buf->header.nr_args = 1;
|
||||
buf->header.init = 1;
|
||||
buf->header.opcode = irq_forward_table[irq_num].opcode;
|
||||
buf->header.done = 0;
|
||||
buf->header.magic = IPC_MSG_MAGIC;
|
||||
buf->header.valid = 1;
|
||||
|
||||
/* add session head */
|
||||
session->head = (session->head + len) % session->capacity;
|
||||
}
|
||||
memset((void*)buf, 0, len);
|
||||
session->tail = (session->tail + len) % session->capacity;
|
||||
|
||||
/* construct message */
|
||||
buf->header.len = len;
|
||||
buf->header.nr_args = 1;
|
||||
buf->header.init = 1;
|
||||
buf->header.opcode = irq_forward_table[irq_num].opcode;
|
||||
buf->header.done = 0;
|
||||
buf->header.magic = IPC_MSG_MAGIC;
|
||||
buf->header.valid = 1;
|
||||
|
||||
/* add session head */
|
||||
session->head = (session->head + len) % session->capacity;
|
||||
}
|
||||
|
||||
int user_irq_handler(int irq, void* tf, void* arg)
|
||||
@@ -118,7 +119,7 @@ int sys_register_irq(int irq_num, int irq_opcode)
|
||||
}
|
||||
|
||||
// bind irq to session
|
||||
if (p_intr_driver->sw_irqtbl[irq_num].handler != NULL) {
|
||||
if (irq_forward_table[irq_num].handle_task != NULL) {
|
||||
ERROR("irq %d is occupied.\n", irq_num);
|
||||
return -1;
|
||||
}
|
||||
@@ -139,7 +140,7 @@ int sys_unbind_irq(struct TaskMicroDescriptor* task, int irq_num)
|
||||
}
|
||||
|
||||
irq_forward_table[irq_num].handle_task = NULL;
|
||||
sys_close_session(&irq_forward_table[irq_num].session);
|
||||
sys_close_session(kernel_irq_proxy, &irq_forward_table[irq_num].session);
|
||||
DEBUG("Unbind: %s to irq %d", task->name, irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
|
||||
ret = sys_poll_session((struct Session*)param1, (int)param2);
|
||||
break;
|
||||
case SYSCALL_CLOSE_SESSION:
|
||||
ret = sys_close_session((struct Session*)param1);
|
||||
ret = sys_close_session(cur_cpu()->task, (struct Session*)param1);
|
||||
break;
|
||||
case SYSCALL_EXEC:
|
||||
ret = sys_exec((char*)param1, (char*)param2, (char**)param3);
|
||||
|
||||
@@ -167,7 +167,7 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task)
|
||||
|
||||
/* alloc a new task with init */
|
||||
extern void trap_return(void);
|
||||
void task_prepare_enter()
|
||||
__attribute__((optimize("O0"))) void task_prepare_enter()
|
||||
{
|
||||
xizi_leave_kernel();
|
||||
trap_return();
|
||||
@@ -227,6 +227,7 @@ static void _scheduler(struct SchedulerRightGroup right_group)
|
||||
{
|
||||
struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag);
|
||||
struct TaskMicroDescriptor* next_task;
|
||||
struct CPU* cpu = cur_cpu();
|
||||
|
||||
while (1) {
|
||||
next_task = NULL;
|
||||
@@ -238,29 +239,21 @@ static void _scheduler(struct SchedulerRightGroup right_group)
|
||||
next_task = xizi_task_manager.next_runnable_task();
|
||||
}
|
||||
next_task_emergency = NULL;
|
||||
if (next_task != NULL) {
|
||||
assert(next_task->state == READY);
|
||||
}
|
||||
spinlock_unlock(&whole_kernel_lock);
|
||||
|
||||
/* not a runnable task */
|
||||
if (UNLIKELY(next_task == NULL)) {
|
||||
spinlock_lock(&whole_kernel_lock);
|
||||
/* if there's not a runnable task, wait for one */
|
||||
if (next_task == NULL) {
|
||||
xizi_leave_kernel();
|
||||
/* leave kernel for other cores, so they may create a runnable task */
|
||||
xizi_enter_kernel();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* a runnable task */
|
||||
spinlock_lock(&whole_kernel_lock);
|
||||
if (next_task->state == READY) {
|
||||
next_task->state = RUNNING;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
struct CPU* cpu = cur_cpu();
|
||||
/* run the chosen task */
|
||||
assert(next_task->state == READY);
|
||||
next_task->state = RUNNING;
|
||||
cpu->task = next_task;
|
||||
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
|
||||
context_switch(&cpu->scheduler, next_task->main_thread.context);
|
||||
assert(cur_cpu()->task == NULL);
|
||||
assert(next_task->state != RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ Modification:
|
||||
#include "task.h"
|
||||
|
||||
extern void context_switch(struct context**, struct context*);
|
||||
void dabort_handler(struct trapframe* r)
|
||||
__attribute__((optimize("O0"))) void dabort_handler(struct trapframe* r)
|
||||
{
|
||||
if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) {
|
||||
assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock));
|
||||
@@ -69,7 +69,7 @@ void dabort_handler(struct trapframe* r)
|
||||
panic("dabort end should never be reashed.\n");
|
||||
}
|
||||
|
||||
void iabort_handler(struct trapframe* r)
|
||||
__attribute__((optimize("O0"))) void iabort_handler(struct trapframe* r)
|
||||
{
|
||||
if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) {
|
||||
assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock));
|
||||
|
||||
@@ -54,7 +54,7 @@ void default_interrupt_routine(void)
|
||||
}
|
||||
|
||||
extern void context_switch(struct context**, struct context*);
|
||||
void intr_irq_dispatch(struct trapframe* tf)
|
||||
__attribute__((optimize("O0"))) void intr_irq_dispatch(struct trapframe* tf)
|
||||
{
|
||||
xizi_enter_kernel();
|
||||
|
||||
@@ -101,7 +101,7 @@ void xizi_enter_kernel()
|
||||
spinlock_lock(&whole_kernel_lock);
|
||||
}
|
||||
|
||||
bool xizi_try_enter_kernel()
|
||||
inline bool xizi_try_enter_kernel()
|
||||
{
|
||||
/// @warning trampoline is responsible for closing interrupt
|
||||
if (spinlock_try_lock(&whole_kernel_lock)) {
|
||||
@@ -111,7 +111,7 @@ bool xizi_try_enter_kernel()
|
||||
return false;
|
||||
}
|
||||
|
||||
void xizi_leave_kernel()
|
||||
inline void xizi_leave_kernel()
|
||||
{
|
||||
/// @warning trampoline is responsible for eabling interrupt by using user's state register
|
||||
spinlock_unlock(&whole_kernel_lock);
|
||||
|
||||
@@ -46,7 +46,7 @@ bool swi_distributer_init(struct SwiDispatcherRightGroup* _right_group)
|
||||
}
|
||||
|
||||
extern void context_switch(struct context**, struct context*);
|
||||
void software_irq_dispatch(struct trapframe* tf)
|
||||
__attribute__((optimize("O0"))) void software_irq_dispatch(struct trapframe* tf)
|
||||
{
|
||||
xizi_enter_kernel();
|
||||
assert(p_intr_driver != NULL);
|
||||
|
||||
Reference in New Issue
Block a user