]> granicus.if.org Git - esp-idf/commitdiff
add more comments and call portYIELD when necessary
authorLiu Zhi Fu <liuzhifu@espressif.com>
Thu, 15 Dec 2016 07:06:00 +0000 (15:06 +0800)
committerLiu Zhi Fu <liuzhifu@espressif.com>
Thu, 15 Dec 2016 07:06:00 +0000 (15:06 +0800)
components/lwip/port/freertos/sys_arch.c

index 9efb151e8ef856e78101de7a9237a5ad84387597..97ee32d1bd005abc2a9681484949349a29c1e976 100755 (executable)
@@ -43,6 +43,7 @@
 #define SYS_THREAD_MAX 4
 
 static bool g_lwip_in_critical_section = false;
+static BaseType_t g_lwip_critical_section_needs_taskswitch;
 
 #if !LWIP_COMPAT_MUTEX
 /** Create a new mutex
@@ -125,7 +126,14 @@ void
 sys_sem_signal(sys_sem_t *sem)
 {
   if (g_lwip_in_critical_section){
-    xSemaphoreGiveFromISR(*sem, NULL);
+    /* In function event_callback in sockets.c, lwip signals a semaphore inside a critical 
+     * section. According to the FreeRTOS documentation for FreertosTaskEnterCritical, it's 
+     * not allowed to call any FreeRTOS API function within a critical region. Unfortunately,  
+     * it's not feasible to rework the affected region in LWIP. As a solution, when in a 
+     * critical region, we call xSemaphoreGiveFromISR. This routine is hand-vetted to work 
+     * in a critical region and it will not cause a task switch.
+     */
+    xSemaphoreGiveFromISR(*sem, &g_lwip_critical_section_needs_taskswitch);
   } else {
     xSemaphoreGive(*sem);
   }
@@ -476,6 +484,10 @@ sys_arch_unprotect(sys_prot_t pval)
   (void) pval;
   g_lwip_in_critical_section = false;
   portEXIT_CRITICAL(&g_lwip_mux);
+  if (g_lwip_critical_section_needs_taskswitch){
+    g_lwip_critical_section_needs_taskswitch = 0;
+    portYIELD();
+  }
 }
 
 /*-----------------------------------------------------------------------------------*/