static void myth_eco_sched_loop(myth_running_env_t env) { // printf("%d\n",FINISH); while (1) { //sched_yield(); myth_thread_t next_run; //Get runnable thread next_run=myth_queue_pop(&env->runnable_q); #ifdef MYTH_WRAP_SOCKIO //If there is no runnable thread, check I/O if (!next_run){ next_run=myth_io_polling(env); } #endif //If there is no runnable thread after I/O checking, try work-stealing if (!next_run){ //next_run=myth_steal_from_others(env); //next_run=g_myth_steal_func(env->rank); next_run=myth_eco_steal(env->rank); } if ((worker_cond_t)next_run == FINISH) { //next_run == FINISH if(env->rank != 0) { env->this_thread=NULL; return; } else { while(1) { int temp = 0; int j; for(j = 1; j < g_worker_thread_num; j++) { if(g_envs[j].c != EXITED) { temp = 1; } } if(temp == 0) return; } } } if (next_run) { //sanity check myth_assert(next_run->status==MYTH_STATUS_READY); env->this_thread=next_run; next_run->env=env; //Switch to runnable thread #ifdef MYTH_SCHED_LOOP_DEBUG myth_dprintf("myth_sched_loop:switching to thread:%p\n",next_run); #endif myth_assert(next_run->status==MYTH_STATUS_READY); myth_swap_context(&env->sched.context, &next_run->context); #ifdef MYTH_SCHED_LOOP_DEBUG myth_dprintf("myth_sched_loop:returned from thread:%p\n",(void*)next_run); #endif env->this_thread=NULL; } //Check exit flag if (env->exit_flag==1){ if(env->rank == 0) while(1) { int temp = 0; int j; for(j = 1; j < g_worker_thread_num; j++) { if(g_envs[j].c != EXITED) { temp = 1; } } if(temp == 0) return; } env->this_thread=NULL; #ifdef MYTH_SCHED_LOOP_DEBUG myth_dprintf("env %p received exit signal,exiting\n",env); #endif return; } } }
myth_thread_t myth_wsapi_runqueue_pop(void) { myth_running_env_t env=myth_get_current_env(); return myth_queue_pop(&env->runnable_q); }