• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            jake1036

            linux內(nèi)核之進(jìn)程管理模塊sched.c

             一 功能描述
                   1,sched.c 是內(nèi)核中有關(guān)進(jìn)程調(diào)度管理的程序,其中有關(guān)調(diào)度的基本函數(shù)(sleep_on() , wakeup() ,schedule() 函數(shù)等) ,其中比較重要的一個(gè)函數(shù)是schedule()函數(shù),
                         該函數(shù)負(fù)責(zé)選擇系統(tǒng)中,下一個(gè)將要運(yùn)行的進(jìn)程,它首先對(duì)所有的任務(wù)進(jìn)行選擇,喚醒任何一個(gè)已經(jīng)得到信號(hào)的任務(wù)。
                         具體方法是針對(duì)任務(wù)數(shù)組中的每個(gè)任務(wù),檢查其報(bào)警定時(shí)值alarm。如果任務(wù)的alarm時(shí)間已經(jīng)過(guò)期(alarm < jiffies), 則在它的信號(hào)位圖中設(shè)置SIGALRM信號(hào),
                         然后清alarm的值,jiffies是系統(tǒng)是從開(kāi)機(jī)開(kāi)始算起的滴答數(shù),如果進(jìn)程的信號(hào)位圖中除被阻塞的的信號(hào)外還有其他的信號(hào),并且讀進(jìn)程處于可中斷睡眠狀態(tài),
            則置進(jìn)程為就緒狀態(tài)。
                        隨后是調(diào)度函數(shù)的核心處理部分,這部分代碼根據(jù)進(jìn)程的時(shí)間片和優(yōu)先權(quán)調(diào)度機(jī)制,來(lái)選擇隨后要執(zhí)行的任務(wù)。它首先循環(huán)檢查任務(wù)數(shù)組中的所有任務(wù),根據(jù)每個(gè)就緒態(tài)任務(wù)剩余執(zhí)行時(shí)間的值counter,來(lái)選取該值最大的一個(gè)任務(wù),并利用switch_to()函數(shù)切換到該任務(wù)。若所有就緒態(tài)任務(wù)該值都為0,表示此刻所有任務(wù)的時(shí)間片都
             已經(jīng)運(yùn)行完畢,于是就根據(jù)任務(wù)的優(yōu)先權(quán)值priority,重置每個(gè)任務(wù)的運(yùn)行時(shí)間片值counter,再重新執(zhí)行循環(huán)檢查所有任務(wù)的執(zhí)行時(shí)間片值。

                 sleep_on()函數(shù)的主要功能是當(dāng)一個(gè)進(jìn)程所請(qǐng)求的資源正忙或不在內(nèi)存中時(shí)暫時(shí)切換出去,放在等待隊(duì)列中等待一段時(shí)間, 當(dāng)切換回來(lái)之后再繼續(xù)運(yùn)行,放入等待隊(duì)列的方式利用了函數(shù)中的tmp指針作為各個(gè)正在等待任務(wù)的聯(lián)系。
             以下是 內(nèi)核模塊中的 sched.c函數(shù)代碼

            #include <linux/sched.h>
            #include 
            <linux/kernel.h>
            #include 
            <linux/sys.h>
            #include 
            <linux/fdreg.h>
            #include 
            <asm/system.h>
            #include 
            <asm/io.h>
            #include 
            <asm/segment.h>

            #include 
            <signal.h>

            //讀宏取信號(hào)nr在信號(hào)位圖中對(duì)應(yīng)位的二進(jìn)制數(shù)值,信號(hào)編號(hào)1-32.比如信號(hào)5的位圖就是1<<(5-1),等于0010000b
            #define _S(nr) (1<<((nr)-1))

            //定義阻塞信號(hào)位圖
            #define _BLOCKABLE(~(_S(SIGKILL) | _S(SIGSTOP)))

            //內(nèi)核調(diào)試函數(shù)。顯示任務(wù)號(hào)nr的進(jìn)程號(hào),進(jìn)程狀態(tài),和內(nèi)核堆棧空閑字節(jié)數(shù)
            void show_task(int nr , struct task_struct * p)
            {
                
            int i , j = 4096 - sizeof(struct task_struct) ;
                printk(
            "%d: pid= %d , state=%d," , nr, p->pid , p->state) ;
                i 
            = 0 ;
                
            while(i < j && !((char *)(p + 1))[i]) //檢測(cè)指定任務(wù)數(shù)據(jù)結(jié)構(gòu)以后等于0的字節(jié)數(shù)
                  i++ ;
                
                printk(
            "%d(of%d) chars free in kernel stack \n\r" , i , j) ;

            }


            //顯示所有任務(wù)的任務(wù)號(hào),進(jìn)程號(hào),進(jìn)程狀態(tài)和內(nèi)核堆棧空閑字節(jié)數(shù)
            void show_stat(void)
            {
               
            int i ;
               
            for(i = 0 ; i < NR_TASKS ; i++)
                  
            if(task[i])
                      show_task(i , task[i]) ;
            }



            ///設(shè)置8253芯片初值
            #define LATCH(1193180/HZ)

            extern void mem_use(void) ;

            extern int timer_interrupt(void) ;

            extern int system_call(void) ;

            //每個(gè)任務(wù)在內(nèi)核態(tài)運(yùn)行時(shí),都會(huì)有自己的內(nèi)核態(tài)堆棧,這里定義了任務(wù)的內(nèi)核態(tài)堆棧結(jié)構(gòu)
            union task_union{
              
            struct task_struct_task ;  //因?yàn)橐粋€(gè)任務(wù)的數(shù)據(jù)結(jié)構(gòu)與其內(nèi)核態(tài)堆棧結(jié)構(gòu)在同一個(gè)內(nèi)存頁(yè)中
              char stack[PAGE_SIZE] ;    //所以從堆棧段寄存器ss可以獲得其數(shù)據(jù)段選擇符
            }
             ;



            static union task_union init_task = {INIT_TASK , } ;
            long volatile jiffies = 0 ; //volatile 表示要從內(nèi)存取值,因?yàn)镃PU會(huì)把經(jīng)常使用的變量放在
                                        
            //通用寄存器中,但是若其他的程序修改這些變量之后,寄存器中的值,可能
                                        
            //并不發(fā)生變化,這就造成了臟數(shù)據(jù)。 使用volatile 表示每次取值,都會(huì)從內(nèi)存取值

            long start_time = 0 ;
            struct task_struct * current = &(init_task.task) ; //當(dāng)前任務(wù)指針,默認(rèn)指向任務(wù)0
            struct task_struct * last_task_uesd_math = NULL ;  //使用協(xié)處理器的任務(wù)指針
            struct task_struct * task[NR_TASKS] = {&(init_task.task) , } ; //定義任務(wù)指針數(shù)組

            long user_stack[PAGE_SIZE >> 2] ;
            struct {

               
            long * a ;
               
            short  b ;
              
            }
             stack_start = {&user_stack[PAGE_SIZE >> 2] , 0x10} ; 

            void math_state_restore()
            {
              
            //如果任務(wù)沒(méi)變,則返回
              if(last_task_used_math == current)
                
            return ;

              _asm_(
            "fwait") ; 
              
            if(last_task_used_math)
              
            {
                _asm_(
            "fnsave %0" :: "m"(last_task_used_math->tss.i387)) ;
              }


              last_task_used_math 
            = current ;
              
            if(current->uesd_math){  //已經(jīng)使用過(guò)協(xié)處理器
                 _asm_("frstor %0"::"m"(current->tss.i387)) ;
              }
             else{   //第一次使用協(xié)處理器,需要初始化相關(guān)信息
                _asm_("fninit"::) ;
                current
            ->used_math = 1 ;//設(shè)置已經(jīng)使用過(guò)協(xié)處理器  
                
              }

               

            }


            void schedule(void)
            {
              
            int i , next , c ;
              
            struct task_struct **p ;//任務(wù)結(jié)構(gòu)指針的指針
              for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
                
            if(*p){
                  
            //如果設(shè)置國(guó)任務(wù)的定時(shí)值alarm,并且已經(jīng)過(guò)期(alarm<jiffies),則在信號(hào)位圖中置SIGRAM信號(hào),
                  
            //即向任務(wù)發(fā)送SIGRAM信號(hào)。然后清alarm。 該信號(hào)的默認(rèn)操作是終止進(jìn)程。
                  
            //jiffies是從系統(tǒng)開(kāi)始啟動(dòng)算起的滴答數(shù)。
                  if((*p)->alarm && (*p)->alarm < jiffies)
                   
            {
                      (
            *p)->signal |= (1<<(SIGALRM - 1)) ;
                      (
            *P)->alarm = 0 ; 
                   }

                  
                   
            //如果信號(hào)位圖中除被阻塞的信號(hào)外還有其他的信號(hào),并且任務(wù)處于可中斷狀態(tài),則置任務(wù)為就緒狀態(tài)。
                   if(((*p)->signal & ~(_BLOCKABLE&(*p)->blocked))&&(*p)->state == TASK_INTERRUPTIBLE)
                     (
            *p)->state - TASK_RUNNING ; //置為就緒狀態(tài)

                }


                 
            //這是調(diào)度程序的主要部分
                while(1)
               
            {
                 c 
            = -1 ;
                 next 
            = 0 ;
                 i 
            = NR_TASKS ;
                 p 
            = &task[NR_TASKS] ;  
                 
            //這段代碼也是從任務(wù)數(shù)組的最后一個(gè)任務(wù)開(kāi)始循環(huán)處理,并跳過(guò)不含任務(wù)的數(shù)組槽
                 
            //比較每個(gè)就緒狀態(tài)任務(wù)的counter(任務(wù)運(yùn)行時(shí)間的遞減滴答數(shù)),哪個(gè)值最大,運(yùn)行時(shí)間還不長(zhǎng),
                 
            //next就指向哪個(gè)任務(wù)號(hào)
                 while(--i){
                   
            if(!*--p)
                     
            continue ;
                   
            if((*p)->state == TASK_RUNNING && (*p)->counter > c) 
                      c 
            = (*p)->counter, next = i ;
                 }
             

                 
            //如果比較得出有counter值不等于0的結(jié)果,或者系統(tǒng)中沒(méi)有一個(gè)可以運(yùn)行的程序,那么就跳出最上層的
                 
            //while循環(huán),執(zhí)行任務(wù)切換程序
                 if(c != 0 ) break ;
              
                 
            //全部的任務(wù)的時(shí)間片都已經(jīng)使用完畢,那么就需要重新設(shè)置時(shí)間片值,重新執(zhí)行。
                 
            // counter值最大的先執(zhí)行
                 for(p = &LAST_TASK ; p > &FIRST_TASK ;p++)  
                   
            if(*p)
                     (
            *p)->counter = ((*p)->counter >> 1+ (*p)->priority ;

               }



                switch_to(next) ;  
            //切換到任務(wù)號(hào)為next的任務(wù),并運(yùn)行之

            }



               
            /*
                 線程中斷系統(tǒng)調(diào)用
               
            */

               
            int sys_pause(void)
               
            {
                  current
            ->state = TASK_INTERRUPTIBLE ;
                  schedule() ;  
                  
            return 0 ;
               }

             
               
            //把任務(wù)變?yōu)椴豢芍袛嗟牡却隣顟B(tài),并讓睡眠隊(duì)列的頭指針指向當(dāng)前的任務(wù)
               
            //只有明確的喚醒,才會(huì)返回,該函數(shù)提供了進(jìn)程與中斷處理程序之間的同步機(jī)制
               
            //函數(shù)參數(shù)P是等待任務(wù)隊(duì)列的頭指針,為了修改調(diào)用該函數(shù)程序中原來(lái)的指針變量的值,
               
            //就需要提供(*p)指針的指針。
              


               
            void sleep_on(struct task_struct **p)   //等待任務(wù)隊(duì)列的頭指針
              {
                  
            struct task_struct * tmp ;
                  
            if(!p)  
                     
            return ;
                  
            //如果進(jìn)程0將要休眠,則死機(jī) 
                  if(current == &(init_task.task))   
                    panic(
            "task[0] trying to sleep");
                  
            //讓tmp指向已經(jīng)在等待隊(duì)列之上的任務(wù),并且將等待隊(duì)列頭的等待指針指向當(dāng)前任務(wù)
                  
            //這樣就把當(dāng)前任務(wù)插入到了*p的等待隊(duì)列中。然后將當(dāng)前任務(wù)變?yōu)椴豢芍袛嗟牡却隣顟B(tài),并執(zhí)行重新調(diào)度
                   
                  tmp 
            = *p ;
                  
            *= current ;
                  current
            ->state = TASK_UNINTERRUPTIBLE ;
                  schedule() ;
                  
                  
            if(tmp)        //若在其前還有等待任務(wù),則將其變?yōu)榫途w狀態(tài)
                    tmp->state = 0 ;
                    


              }
             
              
            //將當(dāng)前的任務(wù)置為可中斷的等待狀態(tài),并放入*p指定的等待隊(duì)列中
              void interruptible_sleep_on(struct task_struct ** p)
              
            {
                 
            struct task_struct * tmp ;
                 
            if(!p)
                    
            return ;
                 
            if(current == &(init_task.task)) 
                    panic(
            "task[0] trying to sleep") ;
                 tmp 
            = *p ;
                 
            *= current ;
             repeat:     
                  current
            ->state = TASK_INTERRUPTIBLE ;
                  schedule() ;
            //執(zhí)行調(diào)度程序,切換任務(wù)
                  
            //只有當(dāng)這個(gè)等待程序被喚醒的時(shí)候,程序才會(huì)又回到這里執(zhí)行,表示進(jìn)程已被明確地喚醒并執(zhí)行。 
                  if(*&& *p!= current){
                    (
            **p).state = 0 ;
                    
            goto repeat ;
                  }

                  
            *= NULL ;
                  
            if(tmp)
                    tmp
            ->state = 0 ;
              }
                


              
            /*喚醒等待的任務(wù)*/
              
            void wake_up(struct task_struct **p)
              
            {
                
            if(p && *p)
                
            {
                   (
            **p).state = 0 ;//置為就緒狀態(tài)        
                   *= NULL ;
                }


              }

               
               
            //下列進(jìn)程數(shù)組存放的是軟驅(qū)馬達(dá)啟動(dòng)到正常轉(zhuǎn)數(shù)的進(jìn)程指針,數(shù)組索引0-3對(duì)應(yīng)軟驅(qū)A-D
               static struct task_struct  * wait_motor[4= {NULL , NULL , NULL , NULL} ;
               
            //每個(gè)馬達(dá)啟動(dòng)所需要的時(shí)間數(shù)
               static int mon_timer[4= {0 , 0 , 0 ,0} ;
               
            //記錄每個(gè)馬達(dá)停轉(zhuǎn)之前維持的時(shí)間 
               static int moff_timer[4= {0,0,0,0} ;
               unsigned 
            char current_DOR = 0x0C ;//這里設(shè)置初值,允許DMA和中斷請(qǐng)求。啟動(dòng)FDC
               
            //指定軟驅(qū)啟動(dòng)到正常運(yùn)轉(zhuǎn)狀態(tài)所需要的等待時(shí)間
               int ticks_to_floppy_on(unsigned int nr)
               
            {
                 
            extern unsigned char selected ;
                 unsigned 
            char mask = 0x10 << nr ;
                 
            if(nr > 3)
                   panic(
            "floppy_on : nr > 3") ; 
                 moff_timer[nr] 
            = 10000 ; 
                 cli() ;
                 mask 
            |= current_DOR ;
                 
            if(!selected){
                   mask 
            &= 0xFC ;
                   mask 
            |= nr ;
                 }

                 

                 
            if(mask != current_DOR)
                 
            {
                     outb(mask , FD_DOR) ;
                     
            if((mask ^ current_DOR) & 0xf0)
                        mon_timer[nr] 
            = HZ / 2 ;
                     
            else if(mon_timer[nr] < 2)
                        mon_timer[nr]  
            = 2 ; 

                     current_DOR 
            = mask ; 
                 }

                   
                 sti() ;
                 
            return mon_timer[nr] ; 
             
              }


               
            void floppy_on(unsigned int nr)
               
            {
                   cli() ;  
                   
            while(ticks_to_floppy_on(nr))
                     sleep_on(nr 
            + wait_motor) ;
                   sti() ;
               }


              
            void floppy_off(unsigned int nr)
              
            {
                 moff_timer[nr] 
            = 3 * HZ ;
              }
              
              

              
            /*軟盤(pán)定時(shí)處理子程序*/
              
            /*更新馬達(dá)啟動(dòng)定時(shí)值和馬達(dá)關(guān)閉停轉(zhuǎn)定時(shí)值*/
              
            /*系統(tǒng)每當(dāng)經(jīng)過(guò)一個(gè)滴答就會(huì)被調(diào)用一次,隨時(shí)更新馬達(dá)開(kāi)啟或者停轉(zhuǎn)的時(shí)間*/
              
            void do_floppy_timer(void)
              
            {
                 
            int i ;
                 unsigned 
            char mask = 0x10 ;
                 
            for(i = 0 ; i < 4 ; i ++ , mask <<= 1)
                 
            {
                    
            if(!(mask & current_DOR))         
                     
            continue ;

                    
            if(mon_timer[i]){
                       
            if(!--mon_timer[i]) 
                         wake_up(i 
            + wait_motor) ;
                    }
             else if(!moff_timer[i])
                     
            {
                       current_DOR 
            &= ~mask ;
                       outb(current_DOR , FD_DOR) ;
                     }
             else
                       moff_timer[i]
            -- ;

                 }


              }


            #define TIME_REQUEST 64
               
            //下面是定時(shí)器的代碼。最多可以有64個(gè)計(jì)時(shí)器
              static struct timer_list  {
                 
            long jiffies ; //定時(shí)滴答數(shù)
                 void(* fn)() ; //定時(shí)處理程序
                 struct timer_list * next ; //鏈接指向下一個(gè)定時(shí)器
             }
              timer_list[TIME_REQUEST] , * next_timer = NULL ;

            /*添加一個(gè)新的定時(shí)器*/
             
            void add_timer(long jiffies , void(*fn)(void))
             
            {
               
            struct timer_list * p ;
               
               
            if(!fn)
                 
            return ;
               cli() ;
               
            if(jiffies <= 0)//如果定時(shí)值為0,則立即執(zhí)行處理程序,并且該定時(shí)器不加入鏈表
                  (fn)() ;
              
              
            //否則從定時(shí)器數(shù)組中,找出一個(gè)空的項(xiàng)
               else
                 
            for(p = timer_list ; p < timer_list + TIMER_REQUEST ; p++)  
                  
            if(!p->fn)  //找到一個(gè)空項(xiàng),然后退出
                    break ;

                
            //如果已經(jīng)用完了定時(shí)器數(shù)組,則系統(tǒng)崩潰,否則向定時(shí)器的數(shù)據(jù)結(jié)構(gòu)中填入相應(yīng)的信息,并連入鏈表頭
                    
                 
            if(p >= timer_list + TIME_REQUEST)
                   panic(
            "no more time request free");

                 p
            ->fn = fn ;
                 p
            ->jiffies = jiffies ;
                 p
            ->next = next_timer ;
                 next_timer 
            = p ;
                 
                 
            //下面的函數(shù)其實(shí)是一個(gè) 雙向隊(duì)列
                 while(p->next && p->next->jiffies < p->jiffies){
                   p
            ->jiffies -= p->next->jiffies ;
                   fn 
            = p->fn ;
                   p
            ->fn = p->next->fn ;
                   p
            ->next->fn = fn ;
                   jiffies 
            = p->jiffies ;
                   p
            ->next->jiffies = jiffies ;
                   p 
            = p->next ;
                 }

               }
             

             }


              
            void do_timer(long cpl)
              
            {
                
            extern int beepcount ; //揚(yáng)聲器發(fā)生時(shí)間滴答數(shù)
                extern void sysbeepstop (void) ; //關(guān)閉揚(yáng)聲器
                if(beepcount)      
                  
            if(!--beppcount)
                     sysbeepstop() ;
                
            if(cpl)
                  current
            ->utime++ ;
                
            else
                  current
            ->stime++ ;
                
            if(next_timer){
                  next_timer
            ->jiffies-- ;
                  
            while(next_timer && next_timer->jiffies <= 0){
                    
            void(*fn)(void) ;
                    fn 
            = next_timer->fn ;
                    next_timer
            ->fn = NULL ;
                    next_timer 
            = next_timer->next ; 
                    (fn)() ;
                  }

                }



               
            if(current_DOR & 0xf0)
                 do_floppy_timer() ;
               
            if((--current->counter) > 0)  return ;
               current
            ->counter = 0;
               
            if(!cpl)  return ;
               schedule() ;

              }



              
            //系統(tǒng)調(diào)用功能,設(shè)置報(bào)警定時(shí)時(shí)間值
               int sys_alarm(long seconds)
               
            {
                 
            int old = current->alarm ;
                 
            if(old)
                   old 
            = (old - jiffies) / HZ ;
                 current
            ->alarm = (seconds > 0 ) ? (jiffies + HZ * seconds):0 ;
                 
            return old ;
               }


               
            //取當(dāng)前的進(jìn)程號(hào)pid

               
            int sys_getpid(void)
              
            {

                 
            return current->pid ;
              }


               
            //取父進(jìn)程號(hào)ppid
               int sys_getppid(void)
             
            {
                
            return current->father ;
             }


              
            //取用戶號(hào)
              int sys_getuid(void)
              
            {
                
            return current->uid ;
              }

              
              
            //取有效的用戶號(hào)euid
              int sys_geteuid(void)
              
            {
                
            return current->euid ;
              }


              
            //取組號(hào)gid
              int sys_getgid(void)
              
            {
                 
            return current->gid ;
              }


              
            //取有效的組號(hào)
              int sys_getegid(void)
              
            {
                
            return current->egid ;
              }

              
            //系統(tǒng)調(diào)用功能---降低對(duì)CPU的優(yōu)先使用權(quán)
              int sys_nice(long increment)
              
            {
                
            if(current->priority - increment > 0)
                   current
            ->priority -= increment ;
                 
            return 0 ;
             }

             
              
            //內(nèi)核調(diào)度程序初始化

              
            void sched_init(void)
              
            {
                 
            int  i ;
                 
            struct desc_struct * p ; //描述符表結(jié)構(gòu)指針  
                 set_tss_desc(gdt + FIRST_TSS_ENTRY , &(init_task.tss)) ;
                 set_ldt_desc(gdt 
            + FIRST_LDT_ENTRY , &(init_task.task.ldt));
                 p 
            = gdt + 2 + FIRST_TSS_ENTRY ;
                 
            for(i = 1 ; i < NR_TASKS ;i++
                 
            {
                   task[i] 
            = NULL ;
                   p
            ->= p->= 0 ;        
                   p
            ++ ;
                   p
            ->= p->= 0 ;
                   p
            ++ ;
                 }
             

                 _asm_(
            "pushfl ; andl $0xffffbfff , (%esp) ; popfl" ) ;
             
                 ltr(
            0) ;
                 lldt(
            0) ;

                 outb_p(
            0x36 , 0x43) ;
                 outb_p(LATCH 
            & 0xff , 0x40) ;
                 outb(LATCH 
            >> 8 , 0x40) ;

                 set_intr_gate(
            0x20 , &timer_interrupt) ;
                 outb(inb_p(
            0x21)&~0x01 , 0x21) ;
                 set_system_gate(
            0x80 , &system_call) ;

              }

             







            posted on 2010-10-31 16:11 kahn 閱讀(2856) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久A级毛片免费观看| 欧美精品国产综合久久| 亚洲中文久久精品无码| 久久综合九色综合网站| 亚洲欧美日韩久久精品第一区| 亚洲国产美女精品久久久久∴| 久久超碰97人人做人人爱| 99久久久精品| 午夜精品久久久久久影视777| 亚洲人成电影网站久久| 男女久久久国产一区二区三区| 天天综合久久久网| 欧美激情精品久久久久久久九九九| 中文精品99久久国产| 精品久久久久久久无码| 精品无码久久久久久久久久| 99久久这里只精品国产免费| 久久se精品一区二区| 热99RE久久精品这里都是精品免费| 久久精品人人做人人妻人人玩| 久久最新免费视频| 69久久夜色精品国产69 | 久久99精品久久久久久hb无码| 69久久精品无码一区二区| 久久无码高潮喷水| 色婷婷久久综合中文久久一本| 久久综合丝袜日本网| 伊人久久大香线焦AV综合影院| 久久精品国产99国产精偷 | 国产精品无码久久久久| 色综合久久精品中文字幕首页 | 久久亚洲精品视频| 久久久久久久亚洲Av无码| 国产亚洲成人久久| 久久综合久久鬼色| 久久99热这里只有精品66| 久久亚洲春色中文字幕久久久| 久久99国产精品尤物| 色综合色天天久久婷婷基地| 久久久九九有精品国产| 久久国产精品无码网站|