Example #1
0
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;
}
Example #2
0
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);
	}
}
Example #4
0
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);
}
Example #6
0
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 ;
}
Example #7
0
// 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();
}
Example #8
0
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;
}
Example #9
0
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();
    }
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
0
File: sched.c Project: cvivas/Zeos
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 );
}
Example #13
0
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();
}
Example #14
0
File: timer.c Project: huu12/testOS
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;
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
0
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(&current_task->sp, next_task->sp);
}
Example #19
0
void task_exit(int exit_code) {
  task_switch(&mainTask);

  #ifdef DEBUG
  printf("task_exit: Encerrando a tarefa %d.\n", currentTask->tid);
  #endif
}
Example #20
0
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);
}
Example #21
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
}
Example #22
0
File: main.c Project: monaka/B-Free
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);
}
Example #23
0
/*---
 * 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);
}
Example #24
0
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);
    }
}
Example #25
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);
}
Example #26
0
File: task.c Project: konyavic/os
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); */
}
Example #27
0
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);
    }
}
Example #28
0
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);
}
Example #29
0
/*-----------------------------------------------------------------------------
 *
 *---------------------------------------------------------------------------*/
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();
}
Example #30
0
File: sched.c Project: texane/muk
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;
}