]> granicus.if.org Git - esp-idf/commitdiff
apptrace lock acquire function was re-designed to minimize waiting time with disabled...
authorAlexey Gerenkov <alexey@espressif.com>
Sun, 3 Sep 2017 00:44:21 +0000 (03:44 +0300)
committerIvan Grokhotkov <ivan@espressif.com>
Mon, 4 Sep 2017 12:44:11 +0000 (20:44 +0800)
components/app_trace/app_trace_util.c
components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c

index e268c81abacbee075715f3d5d816ffdd42491232..524a861abe390c8ff3070b9144d156b5afb011e3 100644 (file)
@@ -46,29 +46,37 @@ esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo)
 
 esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo)
 {
-    lock->int_state = portENTER_CRITICAL_NESTED();
+    int res;
 
-    unsigned now = ESP_APPTRACE_CPUTICKS2US(portGET_RUN_TIME_COUNTER_VALUE()); // us
-    unsigned end = tmo->start + tmo->tmo;
-    if (now > end) {
-        goto timeout;
-    }
-    unsigned remaining = end - now; // us
-
-    bool success = vPortCPUAcquireMutexTimeout(&lock->mux, ESP_APPTRACE_US2CPUTICKS(remaining));
-    if (success) {
-        return ESP_OK;
+    while (1) {
+        // do not overwrite lock->int_state before we actually acquired the mux
+        unsigned int_state = portENTER_CRITICAL_NESTED();
+        // FIXME: if mux is busy it is not good idea to loop during the whole tmo with disabled IRQs.
+        // So we check mux state using zero tmo, restore IRQs and let others tasks/IRQs to run on this CPU
+        // while we are doing our own tmo check.
+        bool success = vPortCPUAcquireMutexTimeout(&lock->mux, 0);
+        if (success) {
+            lock->int_state = int_state;
+            return ESP_OK;
+        }
+        portEXIT_CRITICAL_NESTED(int_state);
+        // we can be preempted from this place till the next call (above) to portENTER_CRITICAL_NESTED()
+        res = esp_apptrace_tmo_check(tmo);
+        if (res != ESP_OK) {
+            break;
+        }
     }
-
- timeout:
-    portEXIT_CRITICAL_NESTED(lock->int_state);
-    return ESP_ERR_TIMEOUT;
+    return res;
 }
 
 esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock)
 {
+    // save lock's irq state value for this CPU
+    unsigned int_state = lock->int_state;
+    // after call to the following func we can not be sure that lock->int_state
+    // is not overwritten by other CPU who has acquired the mux just after we released it. See esp_apptrace_lock_take().
     vPortCPUReleaseMutex(&lock->mux);
-    portEXIT_CRITICAL_NESTED(lock->int_state);
+    portEXIT_CRITICAL_NESTED(int_state);
     return ESP_OK;
 }
 
index 52bc27d0664a1136d9eed72efecca3772bfec4ef..87d76f32ab443e51b8a4e17ad9a815c92184fe62 100644 (file)
@@ -115,7 +115,7 @@ static timer_group_t s_ts_timer_group;
 // everything is fine, so for multi-core env we have to wait on underlying lock forever
 #define SEGGER_LOCK_WAIT_TMO  ESP_APPTRACE_TMO_INFINITE
 
-static esp_apptrace_lock_t s_sys_view_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED};
+static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
 
 static const char * const s_isr_names[] = {
     [0] = "WIFI_MAC",