void sys_thread_switch(l4_threadid_t tid) { TRACEPOINT_1PAR(SYS_THREAD_SWITCH, tid.raw); #if defined (CONFIG_DEBUG_TRACE_SYSCALLS) if (tid == L4_NIL_ID) spin1(75); else printf("sys_thread_switch(tid: %x)\n", tid); #endif /* Make sure we are in the ready queue to * find at least ourself and ensure that the thread * is rescheduled */ thread_enqueue_ready(get_current_tcb()); tcb_t * tcb = tid_to_tcb(tid); if (!(!l4_is_nil_id(tid) && (tcb->myself == tid ) && (IS_RUNNING(tcb)))) tcb = find_next_thread(); /* do dispatch only if necessary */ if (tcb != get_current_tcb()) dispatch_thread(tcb); return_thread_switch(); }
/* this function is called from the hardware dependend * interrupt service routine for a timer tick */ void handle_timer_interrupt() { #if (defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB)) && defined(CONFIG_DEBUG_BREAKIN) kdebug_check_breakin(); #endif TRACEPOINT(HANDLE_TIMER_INTERRUPT, printf("timer interrupt (curr=%p)\n", get_current_tcb())); #if defined(CONFIG_SMP) /* only cpu 0 maintains the clock */ if (get_cpu_id() == 0) #endif kernel_info_page.clock += TIME_QUANTUM; tcb_t * current = get_current_tcb(); tcb_t * wakeup = parse_wakeup_queue(current->priority, kernel_info_page.clock); current->current_timeslice -= TIME_QUANTUM; /* make sure runable threads are in the run queue */ if (current != get_idle_tcb()) thread_enqueue_ready(current); if (wakeup) { dispatch_thread(wakeup); return; } if (current->current_timeslice <= 0) { spin1(78); current->current_timeslice = current->timeslice; dispatch_thread(find_next_thread()); } }
void* scheduler(void* p) { //這裡還要加上signal mask防止interrupt過來 th_queue_t* queueSche; th_queue_t* nextQueueTh; // queueSche = th_queue_head(ready_queueHead); // srand(time(NULL)); //seed rand() //disable_timer(); pthread_mutex_lock(&output_lock); pthread_mutex_lock(&output_lock); printf("I`m in %d, %d\n", getpid(), sched_queueHead==NULL);fflush(stdout); pthread_mutex_unlock(&output_lock); for(;;) //infinite loop { if((queueSche = find_thread_by_tid(sched_queueHead, getpid())) == NULL) abort(); pthread_mutex_lock(&kill_lock); if(wait_for_kill>0) { if(getpid() != main_kernel_id) { th_queue_delete(sched_queueHead, queueSche->thread); wait_for_kill--; pthread_mutex_unlock(&kill_lock); pthread_mutex_lock(&output_lock); printf("kill %d, wait = %d\n", getpid(),wait_for_kill );fflush(stdout); pthread_mutex_unlock(&output_lock); exit(0); abort(); } } pthread_mutex_unlock(&kill_lock); pthread_mutex_lock(&findthread_lock); for(;;) { if((nextQueueTh = find_next_thread(ready_queueHead, queueSche->thread->current_tid)) == NULL) abort(); queueSche->thread->current_tid = nextQueueTh->thread->tid; if(nextQueueTh->thread->mctx.status == TH_WAITING) { break; } } pthread_mutex_lock(&output_lock); printf("I`m %d find out %d, %dn", getpid(), nextQueueTh->thread->tid, nextQueueTh->thread->mctx.status);fflush(stdout); pthread_mutex_unlock(&output_lock); nextQueueTh->thread->mctx.status = TH_RUNNING; queueSche->thread->current_tid = nextQueueTh->thread->tid; pthread_mutex_unlock(&findthread_lock); enable_timer(); mctx_switch(&(queueSche->thread->mctx), &(nextQueueTh->thread->mctx)); if(nextQueueTh->thread->mctx.status !=TH_EXITED && \ nextQueueTh->thread->mctx.status !=TH_KILLED) nextQueueTh->thread->mctx.status = TH_WAITING; pthread_mutex_lock(&output_lock); //printf("I`m %d comeback from %d\n", getpid(), nextQueueTh->thread->tid);fflush(stdout); pthread_mutex_unlock(&output_lock); /* mctx_list[currentTid].status=TH_RUNNING; mctx_switch(&mctx_list[0],&mctx_list[currentTid]); */ } return NULL; }