st_utime_t last_clock; /* The last time we went into vp_check_clock() */
//下面是四种线程状态 _st_thread_t *idle_thread; //idle微线程是框架创建的微线程,只有在没有其他微线程可以调度时,才会被调度执行。主要任务是调用IO多路复用函数等待IO事件和处理定时器。 _st_clist_t run_q; //可运行的微线程,等待框架调度即可运行。 _st_clist_t io_q; //当微线程需要等待IO事件时,会被放到IO等待队列中。当等待的IO事件发生 或者 超时 或者 被中断时,会从IO等待队列中移除并加入到runable队列中。 _st_clist_t zombie_q; //当微线程结束时,如果设置了joinable,即需要其他微线程‘收尸’,就会添加到zombie队列。 #ifdef DEBUG _st_clist_t thread_q; /* all threads of this vp */ #endif int pagesize;
_st_thread_t *sleep_q; //数据结构为完全二叉树组织的最小堆结构,当微线程设置了定时器时,就会根据超时时间添加到树中。 int sleepq_size; /* number of threads on sleep queue */
#ifdef ST_SWITCH_CB st_switch_cb_t switch_out_cb; /* called when a thread is switched out */ st_switch_cb_t switch_in_cb; /* called when a thread is switched in */ #endif } _st_vp_t;
typedefstruct_st_thread { int state; /* Thread's state */ int flags; /* Thread's flags */
void *(*start)(void *arg); /* The start function of the thread */ void *arg; /* Argument of the start function */ void *retval; /* Return value of the start function */
_st_stack_t *stack; /* Info about thread's stack */
_st_clist_t links; /* For putting on run/sleep/zombie queue */ _st_clist_t wait_links; /* For putting on mutex/condvar wait queue */
st_utime_t due; /* Wakeup time when thread is sleeping */ _st_thread_t *left; /* For putting in timeout heap */ _st_thread_t *right; /* -- see docs/timeout_heap.txt for details */ int heap_index;
void **private_data; /* Per thread private data */
_st_cond_t *term; /* Termination condition variable for join */
while (_st_active_count > 0) { /* Idle vp till I/O is ready or the smallest timeout expired */ // 调用IO多路复用函数(epoll,select等)等待IO事件发生,并处理所有发生的IO事件, // 如果微线程等待的IO事件发生,会将微线程从io等待队列st_vp_t.io_q中移除 // 并加入到runable队列st_vp_t.run_q _ST_VP_IDLE();
/* * Cap the stack by zeroing out the saved return address register * value. This allows some debugging/profiling tools to know when * to stop unwinding the stack. It's a no-op on most platforms. */ MD_CAP_STACK(&thread);