精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

鴻蒙內核源碼分析(信號量篇) | 信號量解決任務同步問題

系統
文章由鴻蒙社區產出,想要了解更多內容請前往:51CTO和華為官方戰略合作共建的鴻蒙技術社區https://harmonyos.51cto.com

[[392644]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

基本概念

信號量(Semaphore) 是一種實現任務間通信的機制,可以實現任務間同步或共享資源的互斥訪問。 一個信號量的數據結構中,通常有一個計數值,用于對有效資源數的計數,表示剩下的可被使用的共享資源數,其值的含義分兩種情況:

[[392645]]

  • 0,表示該信號量當前不可獲取,因此可能存在正在等待該信號量的任務。 正值,表示該信號量當前可被獲取。

以同步為目的的信號量和以互斥為目的的信號量在使用上有如下不同:

  • 用作互斥時,初始信號量計數值不為0,表示可用的共享資源個數。在需要使用共享資源前,先獲取信號量,然后使用一個共享資源,使用完畢后釋放信號量。這樣在共享資源被取完,即信號量計數減至0時,其他需要獲取信號量的任務將被阻塞,從而保證了共享資源的互斥訪問。另外,當共享資源數為1時,建議使用二值信號量,一種類似于互斥鎖的機制。
  • 用作同步時,初始信號量計數值為0。任務1獲取信號量而阻塞,直到任務2或者某中斷釋放信號量,任務1才得以進入Ready或Running態,從而達到了任務間的同步。

信號量運作原理

信號量初始化,為配置的N個信號量申請內存(N值可以由用戶自行配置,通過 LOSCFG_BASE_IPC_SEM_LIMIT 宏實現),并把所有信號量初始化成未使用,加入到未使用鏈表中供系統使用。

● 信號量創建,從未使用的信號量鏈表中獲取一個信號量,并設定初值。

● 信號量申請,若其計數器值大于0,則直接減1返回成功。否則任務阻塞,等待其它任務釋放該信號量, 等待的超時時間可設定。當任務被一個信號量阻塞時,將該任務掛到信號量等待任務隊列的隊尾。

● 信號量釋放,若沒有任務等待該信號量,則直接將計數器加1返回。否則喚醒該信號量等待任務隊列上的第一個任務。

● 信號量刪除,將正在使用的信號量置為未使用信號量,并掛回到未使用鏈表。

信號量允許多個任務在同一時刻訪問共享資源,但會限制同一時刻訪問此資源的最大任務數目。 當訪問資源的任務數達到該資源允許的最大數量時,會阻塞其他試圖獲取該資源的任務,直到有任務釋放該信號量。

信號量長什么樣?

  1. typedef struct { 
  2.     UINT8 semStat; /**< Semaphore state *///信號量的狀態 
  3.     UINT16 semCount; /**< Number of available semaphores *///有效信號量的數量 
  4.     UINT16 maxSemCount;  /**< Max number of available semaphores *///有效信號量的最大數量 
  5.     UINT32 semID; /**< Semaphore control structure ID *///信號量索引號 
  6.     LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore *///等待信號量的任務隊列,任務通過阻塞節點掛上去 
  7. } LosSemCB; 

semList,這又是一個雙向鏈表, 雙向鏈表是內核最重要的結構體, 可前往 鴻蒙內核源碼分析(總目錄) 查看雙向鏈表篇, LOS_DL_LIST像狗皮膏藥一樣牢牢的寄生在宿主結構體上semList上掛的是未來所有等待這個信號量的任務.

初始化信號量模塊

  1. #ifndef LOSCFG_BASE_IPC_SEM_LIMIT 
  2. #define LOSCFG_BASE_IPC_SEM_LIMIT 1024 //信號量的最大個數 
  3. #endif 
  4.  
  5. LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)//信號量初始化 
  6.     LosSemCB *semNode = NULL
  7.     UINT32 index
  8.  
  9.     LOS_ListInit(&g_unusedSemList);//初始 
  10.     /* system resident memory, don't free */ 
  11.     g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信號池 
  12.     if (g_allSem == NULL) { 
  13.         return LOS_ERRNO_SEM_NO_MEMORY; 
  14.     } 
  15.  
  16.     for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { 
  17.         semNode = ((LosSemCB *)g_allSem) + index;//拿信號控制塊, 可以直接g_allSem[index]來嘛 
  18.         semNode->semID = SET_SEM_ID(0, index);//保存ID 
  19.         semNode->semStat = OS_SEM_UNUSED;//標記未使用 
  20.         LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通過semList把 信號塊掛到空閑鏈表上 
  21.     } 
  22.  
  23.     if (OsSemDbgInitHook() != LOS_OK) { 
  24.         return LOS_ERRNO_SEM_NO_MEMORY; 
  25.     } 
  26.     return LOS_OK; 

分析如下:

● 初始化創建了信號量池來統一管理信號量, 默認 1024 個信號量

● 信號ID范圍從 [0,1023]

● 未分配使用的信號量都掛到了全局變量 g_unusedSemList 上.

小建議:鴻蒙內核其他池(如進程池,任務池)都采用free來命名空閑鏈表,而此處使用unused,命名風格不太嚴謹,有待改善.

創建信號量

  1. LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle) 
  2.     unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);//從未使用信號量池中取首個 
  3.     LOS_ListDelete(unusedSem);//從空閑鏈表上摘除 
  4.     semCreated = GET_SEM_LIST(unusedSem);//通過semList掛到鏈表上的,這里也要通過它把LosSemCB頭查到. 進程,線程等結構體也都是這么干的. 
  5.     semCreated->semCount = count;//設置數量 
  6.     semCreated->semStat = OS_SEM_USED;//設置可用狀態 
  7.     semCreated->maxSemCount = maxCount;//設置最大信號數量 
  8.     LOS_ListInit(&semCreated->semList);//初始化鏈表,后續阻塞任務通過task->pendList掛到semList鏈表上,就知道哪些任務在等它了. 
  9.     *semHandle = semCreated->semID;//參數帶走 semID 
  10.     OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); 
  11.     return LOS_OK; 
  12.  
  13. ERR_HANDLER: 
  14.     OS_RETURN_ERROR_P2(errLine, errNo); 

分析如下:

● 從未使用的空閑鏈表中拿首個信號量供分配使用.

● 信號量的最大數量和信號量個數都由參數指定.

● 信號量狀態由 OS_SEM_UNUSED 變成了 OS_SEM_USED

● semHandle帶走信號量ID,外部由此知道成功創建了一個編號為 *semHandle 的信號量

申請信號量

  1. LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) 
  2.     UINT32 intSave; 
  3.     LosSemCB *semPended = GET_SEM(semHandle);//通過ID拿到信號體 
  4.     UINT32 retErr = LOS_OK; 
  5.     LosTaskCB *runTask = NULL
  6.  
  7.     if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { 
  8.         OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); 
  9.     } 
  10.  
  11.     if (OS_INT_ACTIVE) { 
  12.         PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); 
  13.         OsBackTrace(); 
  14.         return LOS_ERRNO_SEM_PEND_INTERR; 
  15.     } 
  16.  
  17.     runTask = OsCurrTaskGet();//獲取當前任務 
  18.     if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { 
  19.         OsBackTrace(); 
  20.         return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK; 
  21.     } 
  22.  
  23.     SCHEDULER_LOCK(intSave); 
  24.  
  25.     if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) { 
  26.         retErr = LOS_ERRNO_SEM_INVALID; 
  27.         goto OUT
  28.     } 
  29.  
  30.     /* Update the operate timeno matter the actual Pend success or not */ 
  31.     OsSemDbgTimeUpdateHook(semHandle); 
  32.  
  33.     if (semPended->semCount > 0) {//還有資源可用,返回肯定得成功,semCount=0時代表沒資源了,task會必須去睡眠了 
  34.         semPended->semCount--;//資源少了一個 
  35.         goto OUT;//注意這里 retErr = LOS_OK ,所以返回是OK的  
  36.     } else if (!timeout) { 
  37.         retErr = LOS_ERRNO_SEM_UNAVAILABLE; 
  38.         goto OUT
  39.     } 
  40.  
  41.     if (!OsPreemptableInSched()) {//不能申請調度 (不能調度的原因是因為沒有持有調度任務自旋鎖) 
  42.         PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); 
  43.         OsBackTrace(); 
  44.         retErr = LOS_ERRNO_SEM_PEND_IN_LOCK; 
  45.         goto OUT
  46.     } 
  47.  
  48.     runTask->taskSem = (VOID *)semPended;//標記當前任務在等這個信號量 
  49.     retErr = OsTaskWait(&semPended->semList, timeout, TRUE);//任務進入等待狀態,當前任務會掛到semList上,并在其中切換任務上下文 
  50.     if (retErr == LOS_ERRNO_TSK_TIMEOUT) {//注意:這里是涉及到task切換的,把自己掛起,喚醒其他task  
  51.         runTask->taskSem = NULL
  52.         retErr = LOS_ERRNO_SEM_TIMEOUT; 
  53.     } 
  54.  
  55. OUT
  56.     SCHEDULER_UNLOCK(intSave); 
  57.     return retErr; 

分析如下: 這個函數有點復雜,大量的goto,但別被它繞暈了,盯著返回值看. 先說結果只有一種情況下申請信號量能成功(即 retErr == LOS_OK)

  1. if (semPended->semCount > 0) {//還有資源可用,返回肯定得成功,semCount=0時代表沒資源了,task會必須去睡眠了 
  2.       semPended->semCount--;//資源少了一個 
  3.       goto OUT;//注意這里 retErr = LOS_OK ,所以返回是OK的  
  4.   } 

其余申請失敗的原因有:

● 信號量ID超出范圍(默認1024)

● 中斷發生期間

● 系統任務

● 信號量狀態不對,信號量ID不匹配

以上都是異常的判斷,再說正常情況下 semPended->semCount = 0時的情況,沒有資源了怎么辦? 任務進入 OsTaskWait 睡眠狀態,怎么睡,睡多久,由參數 timeout 定 timeout 值分以下三種模式:

  • 無阻塞模式:即任務申請信號量時,入參 timeout 等于0。若當前信號量計數值不為0,則申請成功,否則立即返回申請失敗。
  • 永久阻塞模式:即任務申請信號量時,入參 timeout 等于0xFFFFFFFF。若當前信號量計數值不為0,則申請成功。 否則該任務進入阻塞態,系統切換到就緒任務中優先級最高者繼續執行。任務進入阻塞態后,直到有其他任務釋放該信號量,阻塞任務才會重新得以執行。
  • 定時阻塞模式:即任務申請信號量時,0

在 OsTaskWait 中,任務將被掛入semList鏈表,semList上掛的都是等待這個信號量的任務.

釋放信號量

  1. LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) 
  2.     LosSemCB *semPosted = NULL
  3.     LosTaskCB *resumedTask = NULL
  4.  
  5.     if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) { 
  6.         return LOS_ERRNO_SEM_INVALID; 
  7.     } 
  8.  
  9.     semPosted = GET_SEM(semHandle); 
  10.     if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) { 
  11.         return LOS_ERRNO_SEM_INVALID; 
  12.     } 
  13.  
  14.     /* Update the operate timeno matter the actual Post success or not */ 
  15.     OsSemDbgTimeUpdateHook(semHandle); 
  16.  
  17.     if (semPosted->semCount == OS_SEM_COUNT_MAX) {//當前信號資源不能大于最大資源量 
  18.         return LOS_ERRNO_SEM_OVERFLOW; 
  19.     } 
  20.     if (!LOS_ListEmpty(&semPosted->semList)) {//當前有任務掛在semList上,要去喚醒任務 
  21.         resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));//semList上面掛的都是task->pendlist節點,取第一個task下來喚醒 
  22.         resumedTask->taskSem = NULL;//任務不用等信號了,重新變成NULL值 
  23.         OsTaskWake(resumedTask);//喚醒任務,注意resumedTask一定不是當前任務,OsTaskWake里面并不會自己切換任務上下文,只是設置狀態 
  24.         if (needSched != NULL) {//參數不為空,就返回需要調度的標簽 
  25.             *needSched = TRUE;//TRUE代表需要調度 
  26.         } 
  27.     } else {//當前沒有任務掛在semList上, 
  28.         semPosted->semCount++;//信號資源多一個 
  29.     } 
  30.  
  31.     return LOS_OK; 
  32.  
  33. LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) 
  34.     UINT32 intSave; 
  35.     UINT32 ret; 
  36.     BOOL needSched = FALSE
  37.  
  38.     SCHEDULER_LOCK(intSave); 
  39.     ret = OsSemPostUnsafe(semHandle, &needSched); 
  40.         SCHEDULER_UNLOCK(intSave); 
  41.     if (needSched) {//需要調度的情況 
  42.         LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU發送調度指令 
  43.         LOS_Schedule();////發起調度 
  44.     } 
  45.  
  46.     return ret; 

分析如下:

● 注意看在什么情況下 semPosted->semCount 才會 ++ ,是在LOS_ListEmpty為真的時候,semList是等待這個信號量的任務. semList上的任務是在OsTaskWait中掛入的.都在等這個信號.

● 每次OsSemPost都會喚醒semList鏈表上一個任務,直到semList為空.

● 掌握信號量的核心是理解 LOS_SemPend 和 LOS_SemPost

編程示例

本實例實現如下功能:

● 測試任務Example_TaskEntry創建一個信號量,鎖任務調度,創建兩個任務Example_SemTask1、Example_SemTask2,Example_SemTask2優先級高于Example_SemTask1,兩個任務中申請同一信號量,解鎖任務調度后兩任務阻塞,測試任務Example_TaskEntry釋放信號量。

● Example_SemTask2得到信號量,被調度,然后任務休眠20Tick,Example_SemTask2延遲,Example_SemTask1被喚醒。

● Example_SemTask1定時阻塞模式申請信號量,等待時間為10Tick,因信號量仍被Example_SemTask2持有,Example_SemTask1掛起,10Tick后仍未得到信號量, Example_SemTask1被喚醒,試圖以永久阻塞模式申請信號量,Example_SemTask1掛起。

● 20Tick后Example_SemTask2喚醒, 釋放信號量后,Example_SemTask1得到信號量被調度運行,最后釋放信號量。

● Example_SemTask1執行完,40Tick后任務Example_TaskEntry被喚醒,執行刪除信號量,刪除兩個任務。

  1. /* 任務ID */ 
  2. static UINT32 g_testTaskId01; 
  3. static UINT32 g_testTaskId02; 
  4. /* 測試任務優先級 */ 
  5. #define TASK_PRIO_TEST  5 
  6. /* 信號量結構體id */ 
  7. static UINT32 g_semId; 
  8.  
  9. VOID Example_SemTask1(VOID) 
  10.     UINT32 ret; 
  11.  
  12.     printf("Example_SemTask1 try get sem g_semId ,timeout 10 ticks.\n"); 
  13.     /* 定時阻塞模式申請信號量,定時時間為10ticks */ 
  14.     ret = LOS_SemPend(g_semId, 10); 
  15.  
  16.     /*申請到信號量*/ 
  17.     if (ret == LOS_OK) { 
  18.          LOS_SemPost(g_semId); 
  19.          return
  20.     } 
  21.     /* 定時時間到,未申請到信號量 */ 
  22.     if (ret == LOS_ERRNO_SEM_TIMEOUT) { 
  23.         printf("Example_SemTask1 timeout and try get sem g_semId wait forever.\n"); 
  24.         /*永久阻塞模式申請信號量*/ 
  25.         ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); 
  26.         printf("Example_SemTask1 wait_forever and get sem g_semId .\n"); 
  27.         if (ret == LOS_OK) { 
  28.             LOS_SemPost(g_semId); 
  29.             return
  30.         } 
  31.     } 
  32.  
  33. VOID Example_SemTask2(VOID) 
  34.     UINT32 ret; 
  35.     printf("Example_SemTask2 try get sem g_semId wait forever.\n"); 
  36.     /* 永久阻塞模式申請信號量 */ 
  37.     ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); 
  38.  
  39.     if (ret == LOS_OK) { 
  40.         printf("Example_SemTask2 get sem g_semId and then delay 20ticks .\n"); 
  41.     } 
  42.  
  43.     /* 任務休眠20 ticks */ 
  44.     LOS_TaskDelay(20); 
  45.  
  46.     printf("Example_SemTask2 post sem g_semId .\n"); 
  47.     /* 釋放信號量 */ 
  48.     LOS_SemPost(g_semId); 
  49.     return
  50.  
  51. UINT32 ExampleTaskEntry(VOID) 
  52.     UINT32 ret; 
  53.     TSK_INIT_PARAM_S task1; 
  54.     TSK_INIT_PARAM_S task2; 
  55.  
  56.    /* 創建信號量 */ 
  57.     LOS_SemCreate(0,&g_semId); 
  58.  
  59.     /* 鎖任務調度 */ 
  60.     LOS_TaskLock(); 
  61.  
  62.     /*創建任務1*/ 
  63.     (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 
  64.     task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; 
  65.     task1.pcName       = "TestTsk1"
  66.     task1.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE; 
  67.     task1.usTaskPrio   = TASK_PRIO_TEST; 
  68.     ret = LOS_TaskCreate(&g_testTaskId01, &task1); 
  69.     if (ret != LOS_OK) { 
  70.         printf("task1 create failed .\n"); 
  71.         return LOS_NOK; 
  72.     } 
  73.  
  74.     /* 創建任務2 */ 
  75.     (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 
  76.     task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; 
  77.     task2.pcName       = "TestTsk2"
  78.     task2.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE; 
  79.     task2.usTaskPrio   = (TASK_PRIO_TEST - 1); 
  80.     ret = LOS_TaskCreate(&g_testTaskId02, &task2); 
  81.     if (ret != LOS_OK) { 
  82.         printf("task2 create failed .\n"); 
  83.         return LOS_NOK; 
  84.     } 
  85.  
  86.     /* 解鎖任務調度 */ 
  87.     LOS_TaskUnlock(); 
  88.  
  89.     ret = LOS_SemPost(g_semId); 
  90.  
  91.     /* 任務休眠40 ticks */ 
  92.     LOS_TaskDelay(40); 
  93.  
  94.     /* 刪除信號量 */ 
  95.     LOS_SemDelete(g_semId); 
  96.  
  97.     /* 刪除任務1 */ 
  98.     ret = LOS_TaskDelete(g_testTaskId01); 
  99.     if (ret != LOS_OK) { 
  100.         printf("task1 delete failed .\n"); 
  101.         return LOS_NOK; 
  102.     } 
  103.     /* 刪除任務2 */ 
  104.     ret = LOS_TaskDelete(g_testTaskId02); 
  105.     if (ret != LOS_OK) { 
  106.         printf("task2 delete failed .\n"); 
  107.         return LOS_NOK; 
  108.     } 
  109.  
  110.     return LOS_OK; 

實例運行結果:

  1. Example_SemTask2 try get sem g_semId wait forever. 
  2. Example_SemTask1 try get sem g_semId ,timeout 10 ticks. 
  3. Example_SemTask2 get sem g_semId and then delay 20ticks . 
  4. Example_SemTask1 timeout and try get sem g_semId wait forever. 
  5. Example_SemTask2 post sem g_semId . 
  6. Example_SemTask1 wait_forever and get sem g_semId . 

參與貢獻

訪問注解倉庫地址

Fork 本倉庫 >> 新建 Feat_xxx 分支 >> 提交代碼注解 >> 新建 Pull Request

新建 Issue

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-09-07 07:53:42

Semaphore 信號量源碼

2020-11-05 09:59:24

Linux內核信號量

2022-04-13 11:12:43

鴻蒙輕內核信號量模塊操作系統

2021-05-31 20:30:55

鴻蒙HarmonyOS應用

2010-04-21 16:50:31

Unix信號量

2010-04-21 16:25:13

Unix信號量

2010-04-21 16:42:48

Unix信號量

2020-09-25 07:34:40

Linux系統編程信號量

2010-04-21 15:37:38

Unix信號量

2024-07-25 11:53:53

2025-04-16 08:50:00

信號量隔離線程池隔離并發控制

2024-10-29 15:23:45

Python線程安全

2013-08-21 14:06:05

iOS隊列信號

2019-11-19 09:00:38

JavaAND信號量

2010-03-17 16:36:10

Java信號量模型

2010-04-21 17:10:25

Unix信號量

2010-07-15 15:32:10

Perl線程

2009-12-08 12:14:43

2016-11-23 16:08:24

Python處理器分布式系統

2010-03-16 17:52:27

Java多線程信號量
點贊
收藏

51CTO技術棧公眾號

亚洲成人av影片| 熟女少妇在线视频播放| 97人妻人人澡人人爽人人精品 | 国产麻豆乱码精品一区二区三区 | 欧美日本亚洲韩国国产| 精品久久久网站| 熟妇人妻无乱码中文字幕真矢织江| 麻豆网在线观看| 成人毛片老司机大片| 欧美一级淫片丝袜脚交| 小泽玛利亚一区| 欧美激情99| 超薄肉色丝袜脚交一区二区| 国产大片一区| 亚洲国产精品va在线看黑人动漫| 黑鬼大战白妞高潮喷白浆| 蜜桃视频在线观看www社区 | 手机看片国产日韩| 成人在线tv视频| 欧美日韩免费在线视频| 亚洲人精品午夜射精日韩| 日韩美女网站| 久久久久久久综合色一本| 91视频99| 91片黄在线观看喷潮| 亚洲伊人网站| 欧美巨大黑人极品精男| 东京热无码av男人的天堂| 欧美a大片欧美片| 日韩欧美卡一卡二| 欧美第一页浮力影院| 蜜桃视频在线观看播放| 一区二区三区四区亚洲| 亚洲一区二区三区涩| 人成在线免费视频| 成人av高清在线| 999国产在线| 99久久精品免费看国产交换| 日本一不卡视频| 欧美一级大片视频| 日韩欧美一区二区一幕| 国产精品大片免费观看| 欧美大片在线免费观看| 免费看一级大片| 国产精品99久久精品| 国产亚洲美女精品久久久| av直播在线观看| 女仆av观看一区| 亚洲精品mp4| 国产精品久久久久久亚洲色 | av在线加勒比| 一区二区免费在线| 国产91在线亚洲| www在线观看播放免费视频日本| 国产精品久久久久7777按摩| 日韩资源av在线| 可以在线观看的av网站| 久久精品视频在线免费观看| 欧美日韩在线高清| 高清av电影在线观看| 国产欧美日韩在线| 亚洲五月六月| 黄色动漫在线| 一区二区三区高清在线| 欧美中文字幕在线观看视频| 美女尤物在线视频| 精品久久久久久中文字幕大豆网| 97成人在线免费视频| 周于希免费高清在线观看| 色美美综合视频| 超碰在线人人爱| 9999精品视频| 精品粉嫩aⅴ一区二区三区四区 | 精品亚洲免a| 精品视频在线播放免| 谁有免费的黄色网址| 99久久综合狠狠综合久久aⅴ| 久久艹在线视频| 日韩精品一区二区在线播放| 亚洲一区亚洲| 国产欧美精品在线播放| va视频在线观看| 99久久精品国产麻豆演员表| 日韩欧美一区二区视频在线播放| 五月天婷婷在线视频| 亚洲一区二区五区| 欧美激情国产精品日韩| 亚洲精品一区二区在线播放∴| 日韩精品一区二区三区在线观看| 国产麻豆xxxvideo实拍| 欧美亚洲激情| 久久久久久12| 伊人亚洲综合网| 福利一区二区在线| 日韩精品伦理第一区| 污污视频在线| 在线欧美小视频| 亚洲国产精品第一页| 国模精品一区| 性欧美视频videos6一9| 中文字幕在线网站| 99久免费精品视频在线观看| 视频一区国产精品| 182在线视频观看| 欧美日本不卡视频| 亚洲国产果冻传媒av在线观看| 久久人体视频| 人妖精品videosex性欧美| 99国产精品欲| 国产女人18水真多18精品一级做| 欧美国产日韩激情| 欧美成人毛片| 亚洲欧洲国产伦综合| 男女免费视频网站| 美国欧美日韩国产在线播放| 久久本道综合色狠狠五月| 粗大黑人巨茎大战欧美成人| 在线视频国内一区二区| 日本一区二区在线免费观看| 欧美/亚洲一区| 国产日韩视频在线观看| 欧洲亚洲精品视频| 亚洲成人激情av| 乳色吐息在线观看| 99久久影视| 国产欧美欧洲在线观看| 美女做暖暖视频免费在线观看全部网址91 | 青青草av在线播放| 国产精品香蕉一区二区三区| 亚洲视频欧美在线| 日本欧美韩国| 亚洲新中文字幕| 国产区一区二区三| 国产99久久久国产精品潘金| 中文字幕第一页亚洲| 香蕉成人影院| 在线色欧美三级视频| 国产成人一级片| 久久这里只有精品视频网| 黄色三级中文字幕| 亚洲午夜免费| 免费不卡欧美自拍视频| 国产精品特级毛片一区二区三区| 国产精品国产三级国产普通话99| 欧美日韩大尺度| 国产精品探花在线观看| 日韩美女毛茸茸| 国产在线一在线二| 国产一区二区三区在线观看视频| 一区二区不卡在线视频 午夜欧美不卡' | 男人天堂视频网| 99久久亚洲一区二区三区青草| 69sex久久精品国产麻豆| av不卡一区| 欧美激情在线有限公司| 内射后入在线观看一区| 午夜精品久久久久久久蜜桃app| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 毛片网站在线看| 日韩欧美国产一二三区| 久草视频在线资源| 成人禁用看黄a在线| 久久成人免费观看| 少妇久久久久| 国产精品九九久久久久久久| 91福利在线视频| 7777精品伊人久久久大香线蕉完整版 | 嫩草研究院在线观看| 91福利在线导航| sm捆绑调教视频| 国产福利一区二区三区视频在线| 999一区二区三区| 天堂资源在线亚洲| 国产精品视频导航| 污污视频在线| 亚洲日本欧美日韩高观看| 中文字幕码精品视频网站| 少妇高潮喷水久久久久久久久久| 国产91绿帽单男绿奴| 亚洲夂夂婷婷色拍ww47| 午夜男人的天堂| 久久激情久久| 亚洲精品自在在线观看| 中文国产在线观看| 天天久久综合| 国产区一区二区| 99一区二区| 麻豆传媒视频在线观看| 日韩欧美国产电影| 日本熟女毛茸茸| 亚洲图片你懂的| 激情综合丁香五月| 美国毛片一区二区| 九九爱精品视频| 日韩在线欧美| 精品免费一区二区三区蜜桃| 欧美成人毛片| 国产91精品久久久久久久| 午夜在线视频| 亚洲精品成人免费| 一本色道久久综合亚洲| 亚洲线精品一区二区三区八戒| 国产激情在线免费观看| 狠狠久久亚洲欧美| 欧美精品一区免费| 欧美在线资源| 欧美一区二区三区成人久久片| 精品午夜视频| 国产精品久久久久99| 高清电影在线免费观看| 在线观看精品自拍私拍| 视频一区二区在线播放| 精品婷婷伊人一区三区三| 日韩精品在线免费看| 日韩一区在线看| 波多野结衣av在线观看| 精品成人一区二区三区免费视频| 色综合久久天天综合网| 麻豆亚洲av熟女国产一区二| 中文在线免费一区三区高中清不卡 | 亚洲在线免费视频| 三级成人在线| 777午夜精品福利在线观看| 成人免费网站在线观看视频| 亚洲欧美自拍一区| 天天干,天天操,天天射| 欧美一级二级在线观看| 91 中文字幕| 欧洲精品视频在线观看| 波多野结衣视频网站| 亚洲国产精品久久久男人的天堂| 日韩影院一区二区| 国产精品国产三级国产有无不卡| 337人体粉嫩噜噜噜| 国产日韩欧美不卡在线| 泷泽萝拉在线播放| 99re热视频这里只精品| 95视频在线观看| 高清免费成人av| 欧美黑人xx片| 香蕉国产精品偷在线观看不卡| 在线成人性视频| 国产99亚洲| 蜜桃日韩视频| 久久人人爽人人爽人人片av不| 91久久精品国产91久久性色tv| **欧美日韩在线| 国产日韩欧美91| 少妇高潮一区二区三区99| 国产精品美女网站| 国产福利亚洲| 成人久久久久久久| 国产精一区二区| 97久久夜色精品国产九色| 日韩一二三区| 国产精品theporn88| 福利在线一区| 精品国产91亚洲一区二区三区www| aaa国产精品视频| 国产一区在线免费| 色婷婷狠狠五月综合天色拍 | 成人在线免费在线观看| 国产精品丝袜xxxxxxx| 欧美色图另类小说| 日韩成人精品视频| 手机版av在线| 国产成人精品免费| 一起草在线视频| 国产视频一区在线播放| 91香蕉视频网| 亚洲一级二级在线| 国产午夜免费福利| 欧美视频在线一区二区三区 | av不卡免费电影| 好吊视频在线观看| 国产精品的网站| 伊人国产在线观看| 色香蕉成人二区免费| 在线观看中文字幕2021| 日韩女优av电影在线观看| 婷婷在线免费视频| 中文字幕日本精品| 蜜桃成人365av| 国产精品久久久久久久久久新婚 | 性欧美videos| 婷婷国产在线综合| 在线观看免费视频a| 精品日韩在线观看| 二区在线观看| 欧美丰满少妇xxxx| 搜成人激情视频| 肥熟一91porny丨九色丨| 国产区精品区| 大片在线观看网站免费收看| 99在线精品免费视频九九视 | 精品一二三四五区| 视频一区二区国产| 中文字幕无人区二| 中文字幕第一区第二区| 日韩av在线播| 7777女厕盗摄久久久| 黄网在线观看| 久久久亚洲精选| 亚洲精品成人一区| 久久婷婷人人澡人人喊人人爽| 99久久综合| 蜜臀av午夜一区二区三区| 国产高清在线精品| 妖精视频在线观看免费| 黑人巨大精品欧美一区二区一视频 | 在线视频国产区| 国产精品久久一| 欧美深夜视频| 人人妻人人澡人人爽欧美一区| 日韩电影免费在线| 黄色性生活一级片| 亚洲精品国久久99热| 中文在线最新版天堂| 日韩黄色在线免费观看| 日韩三级电影视频| 成人做爰www免费看视频网站| 国语产色综合| 欧美色图色综合| 成人免费毛片片v| 亚洲国产精品久| 欧美一区二区三区男人的天堂| 日韩黄色影院| 国产日本欧美视频| 欧美在线电影| 午夜免费一区二区| 久久久国际精品| 国产91国语对白在线| 亚洲美女中文字幕| 亚洲精品一区| 婷婷中文字幕一区| 亚洲黄色一区二区三区| 中文在线一区| 性农村xxxxx小树林| 亚洲综合激情小说| 好吊妞www.84com只有这里才有精品| 97视频精品| 亚洲精品20p| 中文字幕第一区第二区| 中文字幕+乱码+中文字幕明步| 亚洲欧洲在线视频| 日韩三级影视| 午夜精品一区二区三区四区| 日本色综合中文字幕| 国产性猛交xx乱| 欧美午夜影院一区| 98在线视频| 成人免费看吃奶视频网站| 香蕉国产精品| 操人视频免费看| 亚洲国产一区二区a毛片| 丰满肥臀噗嗤啊x99av| 久久久久久中文| 同性恋视频一区| 黄色三级视频片| 国产精品嫩草影院av蜜臀| 国产精品高潮呻吟av| 精品少妇一区二区30p| 中文字幕久久精品一区二区 | 日本少妇色视频| 色视频成人在线观看免| 91精品国产综合久久久久久豆腐| 国产美女精品免费电影| 亚洲一区欧美| 亚洲天堂av网站| 色94色欧美sute亚洲线路一ni | 中文字幕欧美人妻精品一区| 国产欧美日韩麻豆91| 国产又大又粗又硬| 欧美激情亚洲一区| 日韩av网站在线免费观看| 成年人视频在线免费| 亚洲欧洲日韩在线| 亚洲精品国产av| 国产成人av在线播放| 婷婷久久一区| av黄色一级片| 欧美日韩免费不卡视频一区二区三区| 女子免费在线观看视频www| 久久久神马电影| 激情综合网最新| 久草手机在线观看| 最近免费中文字幕视频2019| 中文一区二区三区四区| 免费激情视频在线观看| 亚洲欧美国产77777| 十九岁完整版在线观看好看云免费| 国产精品流白浆视频| 精品动漫av| 亚洲天堂av中文字幕| 精品1区2区在线观看| 成人亚洲免费| 久久亚洲中文字幕无码| **欧美大码日韩| 久热av在线| 成人欧美一区二区三区视频xxx|