Principle Analysis of Libraries St (State Threads Library)

Source: Internet
Author: User
Tags epoll

The Libraries State Threads Library (hereinafter referred to as ST) is a C-language user line libraries or co-Libraries (User level thread) based on the SETJMP/LONGJMP implementation. Basic introduction in this http://state-threads.sourceforge.net/docs/st.html. Here is a basic example of the http://www.csl.mtu.edu/cs4411.ck/www/NOTES/non-local-goto/coroutine.html, which can be used to understand the basic usage of setjmp and longjmp. If you still do not understand, please consult other information yourself.

As you can see, the evolution History of the IA (Internet application) Architecture:

1. Multi-process MP

A Web server that is represented by Apache. Creating a Process service new user is too expensive. The dispatch unit is a process.

2. Multi-threaded MT

Create new thread service new user, inter-thread context switch, lock competition, etc., additional overhead. The dispatch unit is a thread.

3. Event-driven state machine EDSM

Based on the IO multiplexing mechanism, a large number of concurrent request processing is implemented. But the program is one, not thread-based, and the new program needs to start from scratch. In this mode, the main use of the back harmonic state parameters for context switching, in fact, in a very difficult and painful way to implement the idea of similar threads and stacks. The biggest problem with ESDM is that it " decomposes the linear idea into the complexity inherent in a large number of callbacks ", which makes the program difficult to implement, extend and maintain.

Traditional EDSM Program Architecture:

4. Co-process

The dispatch unit is reduced to a function, the context switch does not require kernel involvement, and there is no system call. The context switching overhead is minimized, system calls are minimized, there is no lock contention, and no signal processing. The linear processing logic of the request is preserved, which improves the development efficiency, expansibility and maintainability of the program.

ST-based ESDM program model:

The basic steps for implementing the libraries based on setjmp and longjmp (the following thread refers to the user thread):

1. The runtime environment of each thread needs to be saved with a jmpbuf variable, called the thread context.

2. Allocate (MALLOC/MMAP) a stack for each thread that is used for the thread runtime stack, which is exactly equivalent to the function call stack of a normal system thread. The stack address is set when the thread is initialized, so you do not need to consider setjmp when saving frames data on the stack of threads.

3. The context data is stored in the JMPBUF structure by invoking setjmp to initialize the thread runtime contexts. Then modify the stack pointer in which the SP points to the stack assigned in the previous step. Sets the SP to the lowest or highest address of the stack, based on the current system stack's growth direction.

4. When the thread exits, it needs to return to a secure system location. That is, you need to have a main thread, main thread, or idle thread to be the final exit jump address for other threads. You need to save a jmpbuf for the main thread.

5. After setting the jmpbuf of the main thread, you need to jump to another thread to start executing the business thread.

6. Implement a context exchange function to jump between multiple threads: Save your own jmpbuf,longjmp to another thread's jmpbuf.

St based on SETJMP and longjmp specific implementations:

Thread initialization:

#define Md_init_context (_thread, _sp, _main) \  st_begin_macro                               if (md_setjmp (_thread)  context))             _main ();                                    = (long) (_SP);           St_end_macro

It is obvious to see that after setjmp (storing jmpbuf to Thread->context), the stack pointer to the SP points to the newly assigned thread STACK->SP address. The SP pointer is used for subsequent stack frames data storage for that thread.

Thread Switching:

#define _st_switch_context (_thread)       \    st_begin_macro                            ST_SWITCH_OUT_CB (_thread);                 if (! MD_SETJMP ((_thread)){       _st_vp_schedule ();                      }                                         St_debug_iterate_threads ();               ST_SWITCH_IN_CB (_thread);                 St_end_macro

The primary md_setjmp is to save the current context, and then call _st_vp_schedule () to fetch the first running thread from _ST_RUNQ and call _st_restore_context to resume the thread.

Thread Recovery:

#define _st_restore_context (_thread)   \    st_begin_macro                         _st_set_current_thread (_thread);       MD_LONGJMP ((_thread)1);     St_end_macro

Main thread primordial thread:

/** Initialize this Virtual Processor*/intSt_init (void) {_st_thread_t*thread; if(_st_active_count) {/*already initialized*/    return 0; }  /*We can ignore return value here*/St_set_eventsys (St_eventsys_default); if(_st_io_init () <0)    return-1; memset (&AMP;_ST_THIS_VP,0,sizeof(_st_vp_t)); St_init_clist (&_ST_RUNQ); St_init_clist (&_ST_IOQ); St_init_clist (&_st_zombieq); #ifdef DEBUG st_init_clist (&_ST_THREADQ);#endif  if((*_st_eventsys->init) () <0)    return-1; _st_this_vp.pagesize=getpagesize (); _st_this_vp.last_clock=St_utime (); /** Create Idle thread*/_st_this_vp.idle_thread=st_thread_create (_st_idle_thread_start, NULL,0,0); if(!_st_this_vp.idle_thread)return-1; _st_this_vp.idle_thread->flags =_st_fl_idle_thread; _st_active_count--;  _ST_DEL_RUNQ (_st_this_vp.idle_thread); /** Initialize Primordial thread*/Thread= (_st_thread_t *)calloc(1,sizeof(_st_thread_t) +(St_keys_max*sizeof(void*))); if(!thread)return-1; Thread->private_data = (void* *) (thread +1); Thread->state =_st_st_running; Thread->flags =_st_fl_primordial;  _st_set_current_thread (THREAD); _st_active_count++; #ifdef DEBUG _ST_ADD_THREADQ (thread);#endif  return 0;}

Inside the St_init, create the primordial thread.

ST Program Structure:

The St bottom layer is based on Event-driven Select/poll/kqueue/epoll and other IO multiplexing mechanisms. Below take Epoll as an example to illustrate the St underlying event management mechanism.

There are several queues in St with IOQ,ZOMBIEQ,RUNQ,SLEEPQ, which are used to store threads in the corresponding state.

    • The RUNQ store is a threads that can be scheduled to run, and each time the _st_vp_schedule is called, a thread is removed from the queue to run.
    • IOQ stores the threads in the IO wait state, when the upper layer calls St_poll, the thread is placed in Ioq, and when the underlying epoll has an IO event arrives, the thread is removed from the IOQ and placed in Runq.
    • When thread exits, it is placed in Zombieq.
    • When St_poll passes the timeout parameter >0 or calls St_usleep and st_cond_timewait, the thread is added to the SLEEPQ.

Principle Analysis of Libraries St (State Threads Library)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.