add more comments and call portYIELD when necessary

This commit is contained in:
Liu Zhi Fu 2016-12-15 15:06:00 +08:00
parent 5e2ae7ac19
commit 55726385a4

View file

@ -43,6 +43,7 @@
#define SYS_THREAD_MAX 4 #define SYS_THREAD_MAX 4
static bool g_lwip_in_critical_section = false; static bool g_lwip_in_critical_section = false;
static BaseType_t g_lwip_critical_section_needs_taskswitch;
#if !LWIP_COMPAT_MUTEX #if !LWIP_COMPAT_MUTEX
/** Create a new mutex /** Create a new mutex
@ -125,7 +126,14 @@ void
sys_sem_signal(sys_sem_t *sem) sys_sem_signal(sys_sem_t *sem)
{ {
if (g_lwip_in_critical_section){ 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 { } else {
xSemaphoreGive(*sem); xSemaphoreGive(*sem);
} }
@ -476,6 +484,10 @@ sys_arch_unprotect(sys_prot_t pval)
(void) pval; (void) pval;
g_lwip_in_critical_section = false; g_lwip_in_critical_section = false;
portEXIT_CRITICAL(&g_lwip_mux); portEXIT_CRITICAL(&g_lwip_mux);
if (g_lwip_critical_section_needs_taskswitch){
g_lwip_critical_section_needs_taskswitch = 0;
portYIELD();
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/