static int svc_acquire(struct mutex *mutex) { int ret; if (get_lock(mutex)) { /* Success */ ret = 1; } else { /* Failure */ ret = 0; if (task_runnable(mutex->held_by) && (task_compare(mutex->held_by, curr_task) <= 0)) { task_switch(mutex->held_by); } else { /* If task was not runnable, it was either a period task * between runs, or it recently ended without releasing * the mutex. In that case, the kernel task will * release the mutex on its next run. */ task_switch(NULL); } } return ret; }
void task_exit(int exit_code) { #ifdef DEBUG printf("task_exit: Encerrando a tarefa %d.\n", currentTask->tid); #endif // Libera a memória usada pela tarefa atual if(exec && exec->task == currentTask) free(exec); if(exit_code == TO_DISPATCHER) task_switch(&dispatcher); else task_switch(&mainTask); }
// Termina a tarefa corrente, indicando um valor de status encerramento void task_exit (int exitCode){ #ifdef DEBUG printf("task_exit: tarefa %d sendo encerrada \n",task_corrente->tid); #endif task_corrente->flag=TRUE; if (task_corrente == &dispatcher){ task_switch(&task_main); } else { queue_remove((queue_t **) &ready,(queue_t*)task_corrente); task_switch(&dispatcher); } }
void task_yield() { // Adiciona a tarefa em execução na fila de prontas queue_append((queue_t**) &ready, (queue_t*) exec); // Retorna o controle para a tarefa dispatcher task_switch(&dispatcher); }
// Termina a tarefa corrente, indicando um valor de status encerramento void task_exit (int exitCode){ #ifdef DEBUG printf("task_exit: tarefa %d sendo encerrada \n",task_corrente->tid); #endif task_corrente->flag=TRUE; task_switch(&task_main); }
void inthandler20(int *esp) { char ts = 0; struct TIMER *timer; io_out8(PIC0_OCW2, 0x60); timerctl.count ++ ; if ( timerctl.next > timerctl.count ) return; timer = timerctl.t0; while (1) { if ( timer->timeout > timerctl.count ) break; timer->flags = TIMER_FLAGS_ALLOC; if ( timer != task_timer ) { queue8_put ( timer->queue, timer->data ); } else { ts = 1; } timer = timer->next; } timerctl.t0 = timer; timerctl.next = timerctl.t0->timeout; if ( ts != 0 ) task_switch(); return ; }
// IRQ-20 : Timer interrupt. void inthandler20(int* esp) { (void)esp; char switch_task = FALSE; io_out8(PIC0_OCW2, 0x60); // Notify IRQ-00 recv to PIC ++timerctl.count; if (timerctl.next_time > timerctl.count) return; TIMER* timer = timerctl.t0; for (;;) { if (timer->timeout > timerctl.count) break; timer->flags = TIMER_FLAGS_ALLOCATED; if (timer != task_timer) { fifo_put(timer->fifo, timer->data); } else { switch_task = TRUE; } timer = timer->next_timer; } timerctl.t0 = timer; timerctl.next_time = timerctl.t0->timeout; if (switch_task) task_switch(); }
void inthandler20(int *esp) { struct TIMER *timer; char ts = 0; io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接收完了的信息通知给PIC */ timerctl.count++; if (timerctl.nextTime > timerctl.count) { return; /* 还不到下一个时刻,所以结束 */ } timer = timerctl.t0; /* 首先把最前面的地址赋给timer */ for (;;) { /* timers的定时器都处于动作中,所以不确认flags */ if (timer->timeout > timerctl.count) { break; } /* 超时 */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) { fifo32_put(timer->fifo, timer->data); } else { ts = 1; // task_timer标记 } timer = timer->nextTimer; /* 下一定时器的地址赋给timer */ } /* 新移位 */ timerctl.t0 = timer; /* timerctl.nextTime的设定 */ timerctl.nextTime = timer->timeout; if (ts != 0) { task_switch(); } return; }
void int_handler_20(int *esp){ extern struct TIMERCTRL timerctrl; extern struct TIMER *task_timer; char ts_flag = 0; io_out8(PIC0_OCW2, 0x60); timerctrl.count++; if(timerctrl.next > timerctrl.count){ return; } else{ while(timerctrl.head->timeout <= timerctrl.count){ timerctrl.head->flags = TIMER_FLAGS_ALLOC; if(timerctrl.head != task_timer) fifo8_put(timerctrl.head->fifo, timerctrl.head->data); else{ ts_flag = 1; } timerctrl.head = timerctrl.head->next; } } timerctrl.next = timerctrl.head->timeout; if(ts_flag != 0){ task_switch(); } }
void inthandler20(int *esp) { int flag_switch = 0; struct CLOCK *clock; io_cli(); io_out8(PIC0_OCW2, 0x60); clock_ctl->count++; if (clock_ctl->next > clock_ctl->count) { return; } clock = clock_ctl->c0; for (;;) { if (clock->time_out > clock_ctl->count) { break; } if(clock != task_clock){ fifo32_put(clock->fifo, clock->data); }else{ flag_switch = 1; } clock->flag_usage = CLOCK_FLAGS_ALLOC; clock = clock->next; } clock_ctl->c0 = clock; clock_ctl->next = clock->time_out; io_sti(); if(flag_switch == 1){ task_switch(); } return; }
void inthandler20(int *esp) { struct TIMER *timer; char ts = 0; io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00接收信号结束的信息通知给PIC */ timerctl.count++; if (timerctl.next > timerctl.count) { return; } timer = timerctl.t0; /* 首先把最前面的地址赋给timer */ for (;;) { /* 因为timers的定时器都处于运行状态,所以不确认flags */ if (timer->timeout > timerctl.count) { break; } /* 超时 */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) { fifo32_put(timer->fifo, timer->data); } else { ts = 1; /* mt_timer超时*/ } timer = timer->next; /* 将下一个定时器的地址赋给timer*/ } timerctl.t0 = timer; timerctl.next = timer->timeout; if (ts != 0) { task_switch(); } return; }
void bloquear_proceso(struct list_head * l) { struct list_head * lh = list_first(&runqueue); list_del(lh); list_add_tail(lh,l); task_switch( (union task_union *)list_first(&runqueue) , NO_INT ); }
void interrupt_handler20(int* esp) { timer_t* timer; char ts = 0; io_out8(PIC0_OCW2, 0x60); /* send sign to PIC from IRQ-00 */ ++g_timerctl.count; if (g_timerctl.next > g_timerctl.count) return; /* not the next timeout timer, break */ timer = g_timerctl.timer0; for ( ; ; ) { /* timers are all using, donot need to check flags */ if (timer->timeout > g_timerctl.count) break; /* timeout */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != g_task_timer) fifo_put(timer->fifo, timer->data); else ts = 1; /* g_task_timer timeout */ timer = timer->next; } g_timerctl.timer0 = timer; g_timerctl.next = timer->timeout; /* task switch */ if (0 != ts) task_switch(); }
void inthandler20(int *esp) { struct TIMER *timer; char ts = 0; io_out8(PIC0_OCW2, 0x60); /* IRQ-00受付完了をPICに通知 */ timerctl.count++; if (timerctl.next > timerctl.count) { return; } timer = timerctl.t0; /* とりあえず先頭の番地をtimerに代入 */ for (;;) { /* timersのタイマは全て動作中のものなので、flagsを確認しない */ if (timer->timeout > timerctl.count) { break; } /* タイムアウト */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) { fifo32_put(timer->fifo, timer->data); } else { ts = 1; /* task_timerがタイムアウトした */ } timer = timer->next; /* 次のタイマの番地をtimerに代入 */ } timerctl.t0 = timer; timerctl.next = timer->timeout; if (ts != 0) { task_switch(); } return; }
void inthandler20(int *esp) { int i; char ts = 0; io_out8 (PIC0_OCW2, 0x60); timerctl.count ++; if (timerctl.next > timerctl.count) { return; } struct TIMER *timer = timerctl.t0; for (;;) { if (timer->timeout > timerctl.count) { break; } /* Timeout */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) { fifo32_put(timer->fifo, timer->data); } else { ts = 1; } timer = timer->next; } timerctl.t0 = timer; timerctl.next = timerctl.t0->timeout; if (ts != 0) { task_switch (); } return; }
void inthandler20(int *esp) { char ts = 0; struct TIMER *timer; io_out8(PIC0_OCW2, 0x60); timerctl.count++; if (timerctl.next > timerctl.count) return; timer = timerctl.t0; for (;;) { if (timer->timeout > timerctl.count) break; timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) fifo32_put(timer->fifo, timer->data); else ts = 1; timer = timer->next; } timerctl.t0 = timer; timerctl.next = timerctl.t0->timeout; if (ts != 0) task_switch(); return; }
void inthandler20(int* esp) { io_out8(PIC0_OCW2, 0x60); /* 接收到IRQ-00后通知PIC */ timerctl.count++; if (timerctl.next > timerctl.count) { return; /* 还不到下个时刻 */ } timer_t* timer = timerctl.t0; /* 首地址 */ char ts = 0; for (;;) { /* timers定时器都在使用中,不确认flags */ if (timer->timeout > timerctl.count) { break; } /* 超时 */ timer->flags = TIMER_FLAGS_ALLOC; if (timer != task_timer) { fifo32_put(timer->fifo, timer->data); } else { ts = 1; } timer = timer->next; /* 代入下个地址 */ } /* 新版移位 */ timerctl.t0 = timer; timerctl.next = timer->timeout; if (ts != 0) { task_switch(); } return; }
void task_yield() { disable_irq(); struct task_t *current_task = task_current(); struct list_node_t *next_task_it; struct task_t *next_task; if ( task_is_active(current_task) ) { next_task_it = current_task_it->next; } else { next_task_it = list_first(active_tasks); } next_task = (struct task_t *)next_task_it->data; task_print("task_yield:", current_task, next_task); if ( current_task == next_task ) { return; }; if ( next_task == 0 ) { print_buf("ERROR: next_task=0\n"); }; current_task_it = next_task_it; task_switch(¤t_task->sp, next_task->sp); }
void task_exit(int exit_code) { task_switch(&mainTask); #ifdef DEBUG printf("task_exit: Encerrando a tarefa %d.\n", currentTask->tid); #endif }
void dispatcher_body() { int err, t0, t1; task_t* next; // Tarefa que ocupara o processador. enable_preemption(0); // Caso haver alguma tarefa na lista de prontas // o while eh executado. while (list_size(ready_list) > 0) { t0 = systime(); next = scheduler(); if (next) { ticks = 20; enable_preemption(1); t1 = systime(); curr_task->proc_time += t0 - t1; t0 = systime(); err = task_switch(next); t1 = systime(); next->proc_time += t1 - t0; if (err == -1) { perror("dispatcher_body: task_switch failed.\n"); return; } } } // Finaliza o dispatcher, voltando para o main. task_exit(0); }
void task_yield() { int err; //enable_preemption(0); #ifdef DEBUG printf(">> task_yield()\n"); #endif // Cada tarefa que chama task_yield() eh colocada no // fim da fila de tarefas prontas, menos o main(). //if (curr_task != &main_task) list_append(&ready_list, curr_task); err = task_switch(&dispatcher); if (err == -1) { perror("task_yield: dispatcher switch failed.\n"); return; } #ifdef DEBUG printf("<< task_yield()\n"); #endif }
void run (W entry) { W i; struct boot_header *info; struct module_info *modulep; ID rid; T_CTSK pktsk; T_TCB *new_taskp; info = (struct boot_header *)MODULE_TABLE; if ((entry < 1) || (entry >= info->count)) { printf ("module is overflow.\n"); return; } modulep = info->modules; pktsk.tskatr = TA_HLNG; pktsk.itskpri = 2; pktsk.stksz = PAGE_SIZE * 2; pktsk.addrmap = NULL; pktsk.startaddr = (FP)modulep[entry].entry; if (new_task (&pktsk, &rid, FALSE) != E_OK) { printf ("Can not make new task.\n"); return; } printf ("Task id = %d, eip = 0x%x\n", rid, modulep[entry].entry); new_taskp = get_tskp (rid); if (new_taskp == NULL) { printf ("new task is NULL.\n"); return; } /* 生成したタスクの仮想メモリにモジュールをマッピング */ /* ただしドライバの場合には、マッピングしない */ if (modulep[entry].type == driver) { printf ("This module is driver. not mapped\n"); } else { for (i = 0; i < ROUNDUP (modulep[entry].length, PAGE_SIZE) / PAGE_SIZE; i++) { if (vmap (new_taskp, modulep[entry].vaddr + i * PAGE_SIZE, modulep[entry].paddr + i * PAGE_SIZE) == FALSE) { printf ("Cannot memory map: virtual addr: 0x%x, phisical addr = 0x%x\n", modulep[entry].vaddr + i * PAGE_SIZE, modulep[entry].paddr + i * PAGE_SIZE); } } } sta_tsk (rid, 0); task_switch (TRUE); }
/*--- * CALLfar_pm: task gate */ static void CALLfar_pm_task_gate(selector_t *taskgate_sel) { selector_t tss_sel; int rv; VERBOSE(("CALLfar_pm: TASK-GATE")); /* check privilege level */ if (taskgate_sel->desc.dpl < CPU_STAT_CPL) { VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", taskgate_sel->desc.dpl, CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); } if (taskgate_sel->desc.dpl < taskgate_sel->rpl) { VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", taskgate_sel->desc.dpl, taskgate_sel->rpl)); EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); } /* not present */ if (selector_is_not_present(taskgate_sel)) { VERBOSE(("CALLfar_pm: selector is not present")); EXCEPTION(NP_EXCEPTION, taskgate_sel->idx); } /* tss descriptor */ rv = parse_selector(&tss_sel, taskgate_sel->desc.u.gate.selector); if (rv < 0 || tss_sel.ldt) { VERBOSE(("CALLfar_pm: parse_selector (selector = %04x, rv = %d, %cDT)", tss_sel.selector, rv, tss_sel.ldt ? 'L' : 'G')); EXCEPTION(GP_EXCEPTION, tss_sel.idx); } /* check descriptor type */ switch (tss_sel.desc.type) { case CPU_SYSDESC_TYPE_TSS_16: case CPU_SYSDESC_TYPE_TSS_32: break; case CPU_SYSDESC_TYPE_TSS_BUSY_16: case CPU_SYSDESC_TYPE_TSS_BUSY_32: VERBOSE(("CALLfar_pm: task is busy")); /*FALLTHROUGH*/ default: VERBOSE(("CALLfar_pm: invalid descriptor type (type = %d)", tss_sel.desc.type)); EXCEPTION(GP_EXCEPTION, tss_sel.idx); break; } /* not present */ if (selector_is_not_present(&tss_sel)) { VERBOSE(("CALLfar_pm: TSS selector is not present")); EXCEPTION(NP_EXCEPTION, tss_sel.idx); } task_switch(&tss_sel, TASK_SWITCH_CALL); }
static void CPUCALL interrupt_task_gate(const descriptor_t *gsdp, int intrtype, int errorp, int error_code) { selector_t task_sel; int rv; VERBOSE(("interrupt: TASK-GATE")); rv = parse_selector(&task_sel, gsdp->u.gate.selector); if (rv < 0 || task_sel.ldt || !SEG_IS_SYSTEM(&task_sel.desc)) { VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT, type = %s)", gsdp->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G', task_sel.desc.s ? "code/data" : "system")); EXCEPTION(TS_EXCEPTION, task_sel.idx); } /* check gate type */ switch (task_sel.desc.type) { case CPU_SYSDESC_TYPE_TSS_16: case CPU_SYSDESC_TYPE_TSS_32: break; case CPU_SYSDESC_TYPE_TSS_BUSY_16: case CPU_SYSDESC_TYPE_TSS_BUSY_32: VERBOSE(("interrupt: task is busy.")); /*FALLTHROUGH*/ default: VERBOSE(("interrupt: invalid gate type (%d)", task_sel.desc.type)); EXCEPTION(TS_EXCEPTION, task_sel.idx); break; } /* not present */ if (selector_is_not_present(&task_sel)) { VERBOSE(("interrupt: selector is not present")); EXCEPTION(NP_EXCEPTION, task_sel.idx); } task_switch(&task_sel, TASK_SWITCH_INTR); CPU_SET_PREV_ESP(); if (errorp) { VERBOSE(("interrupt: push error code (%08x)", error_code)); if (task_sel.desc.type == CPU_SYSDESC_TYPE_TSS_32) { PUSH0_32(error_code); } else { PUSH0_16(error_code); } } /* out of range */ if (CPU_EIP > CPU_STAT_CS_LIMIT) { VERBOSE(("interrupt: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); EXCEPTION(GP_EXCEPTION, 0); } }
void dispatcher_body(void* arg) { // Enquanto houverem tarefas prontas para serem executadas while(queue_size((queue_t*) ready) > 0) { task_t* next = scheduler(); if(next) task_switch(next); } // Retorna o controle para a tarefa main task_exit(TO_MAIN); }
void task_switch_c(uint32_t task1_num, uint32_t task2_num) { /* printf(TEXT_MODE_SCREEN_RIGHT, "before %d: 0x%x", */ /* task1_num, task_management_data[task1_num].eip); */ /* printf(TEXT_MODE_SCREEN_RIGHT, "before %d: 0x%x", */ /* task1_num, task_management_data[task2_num].eip); */ task_switch(&task_management_data[task1_num], &task_management_data[task2_num]); /* printf(TEXT_MODE_SCREEN_RIGHT, "after %d: 0x%x", */ /* task1_num, task_management_data[task1_num].eip); */ /* printf(TEXT_MODE_SCREEN_RIGHT, "after %d: 0x%x", */ /* task1_num, task_management_data[task2_num].eip); */ }
static void svc_release(struct mutex *mutex) { mutex->lock = 0; mutex->held_by = NULL; held_mutexes_remove(curr_task->mutex_data.held_mutexes, mutex); if (mutex->waiting && (task_compare(mutex->waiting, curr_task) >= 0)) { task_t *task = mutex->waiting; mutex->waiting = NULL; task_switch(task); } }
void stask_switch(sched_task_t from, sched_task_t to) { assert (from != to); executor_t exec = from->executor; exec->prev_stask = from; if (to == NULL) { task_switch(from->task, exec->stask->task); } else { assert (exec != NULL); to->executor = exec; /* // If this task is to finish, it should come back to this processor. */ /* // This decision may be dubious, perhaps it should switch to the */ /* // executor? */ /* if (proc->task->state == TASK_TRANSITION_TO_RUNNABLE) */ /* { */ /* next_proc->task->next = proc->task; */ /* } */ /* else */ /* { */ /* next_proc->task->next = exec->task; */ /* } */ to->task->next = exec->stask->task; /* printf("%p directly yielding to %p\n", from, to); */ // Switch to the task we found. task_switch(from->task, to->task); } stask_step_previous(from); }
/*----------------------------------------------------------------------------- * *---------------------------------------------------------------------------*/ void destroy_proc(void) { thread_t* thread; process_t* proc; /*asm volatile ("cli");*/ stop(); thread = get_current_thread(); proc = thread->process; remove_thread(thread); /* Free process memory pages */ kfree(thread->stack); thread->stack = NULL; free_phys_pages(proc->user_stack_paddr, proc->stack_page_count); free_phys_pages(proc->seg_paddr, proc->seg_page_count); free_phys_pages(proc->heap_paddr, proc->heap_page_count); free_phys_pages(proc->blocks_paddr, proc->blocks_page_count); kfree(thread); thread = NULL; proc->threads_count--; while (proc->threads_count > 0) { thread = get_thread(proc->thread_id[proc->threads_count - 1]); remove_thread(thread); thread->process->threads_count--; /* Free thread's memory (handler and stack) */ kfree(thread->stack); thread->stack = NULL; kfree(thread); thread = NULL; } /* Here we must free memory!!! */ /*asm volatile ("sti");*/ start(); task_switch(); }
error_t sched_yield(void) { struct task* first; struct task* pos; struct task* ready; bool_t is_done; cpu_cli(); task_set_timeslice(g_current_task, 0); /* find next ready task */ is_done = false; ready = NULL; first = g_current_task->next; pos = g_current_task->next; while (is_done == false) { if (pos->state == TASK_STATE_READY) { ready = pos; ready->timeslice = TASK_SCHED_TIMESLICE; is_done = true; } else { pos = pos->next; if (pos == first) is_done = true; } } /* switch to ready */ if (ready != NULL) { if (ready->timeslice == 0) task_set_timeslice(ready, TASK_SCHED_TIMESLICE); task_switch(g_current_task, ready); } else { cpu_sti(); } return ERROR_SUCCESS; }