Added mutex for protecting vblank resources. 35/268435/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Thu, 23 Dec 2021 01:41:04 +0000 (10:41 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Thu, 23 Dec 2021 01:39:06 +0000 (10:39 +0900)
 As-Is :
  - vblank resource was protected via surf_mutex.
 To-Be :
  - It will be protected via its own mutex.

Change-Id: Iff4084a4f8271b8cbe4a7ece308b98915d9641af
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wl_egl_thread.c

index 06abb41..62fba27 100755 (executable)
@@ -149,6 +149,7 @@ struct _surface_vblank {
        tdm_client_vblank            *tdm_vblank;
        tpl_wl_egl_surface_t         *wl_egl_surface;
        tpl_list_t                   *waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
+       tpl_gmutex                    mutex;
 };
 
 typedef enum buffer_status {
@@ -1546,9 +1547,20 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface)
                wl_egl_surface->tss_flusher = NULL;
        }
 #endif
+
+       if (wl_egl_surface->tbm_queue) {
+               TPL_INFO("[TBM_QUEUE_DESTROY]",
+                                "wl_egl_surface(%p) tbm_queue(%p)",
+                                wl_egl_surface, wl_egl_surface->tbm_queue);
+               tbm_surface_queue_destroy(wl_egl_surface->tbm_queue);
+               wl_egl_surface->tbm_queue = NULL;
+       }
+
        if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {
+               tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
                __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL);
                wl_egl_surface->vblank->waiting_buffers = NULL;
+               tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
        }
 
        if (wl_egl_surface->vblank) {
@@ -1559,14 +1571,6 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface)
                wl_egl_surface->vblank = NULL;
        }
 
-       if (wl_egl_surface->tbm_queue) {
-               TPL_INFO("[TBM_QUEUE_DESTROY]",
-                                "wl_egl_surface(%p) tbm_queue(%p)",
-                                wl_egl_surface, wl_egl_surface->tbm_queue);
-               tbm_surface_queue_destroy(wl_egl_surface->tbm_queue);
-               wl_egl_surface->tbm_queue = NULL;
-       }
-
        tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
 }
 
@@ -1891,6 +1895,7 @@ __cb_surface_vblank_free(void *data)
        tdm_client_vblank_destroy(vblank->tdm_vblank);
        vblank->tdm_vblank = NULL;
        vblank->wl_egl_surface = NULL;
+       tpl_gmutex_clear(&vblank->mutex);
 
        free(vblank);
 
@@ -1938,6 +1943,7 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface)
                        } else {
                                vblank->waiting_buffers = __tpl_list_alloc();
                                vblank->wl_egl_surface = wl_egl_surface;
+                               tpl_gmutex_init(&vblank->mutex);
 
                                __tpl_list_push_back(wl_egl_display->tdm.surface_vblanks,
                                                                         (void *)vblank);
@@ -2778,9 +2784,12 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
 
        if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done)
                _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
-       else
+       else {
+               tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
                __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers,
                                                         wl_egl_buffer);
+               tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
+       }
 
        tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
 
@@ -2864,7 +2873,9 @@ _thread_surface_queue_acquire(tpl_wl_egl_surface_t *wl_egl_surface)
                                ready_to_commit = TPL_TRUE;
                        else {
                                wl_egl_buffer->status = WAITING_VBLANK;
+                               tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
                                __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers, wl_egl_buffer);
+                               tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
                                ready_to_commit = TPL_FALSE;
                        }
                }
@@ -2898,19 +2909,25 @@ __cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error,
 
        tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
        if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {
-               while (!__tpl_list_is_empty(wl_egl_surface->vblank->waiting_buffers)) {
+               tpl_bool_t is_empty = TPL_TRUE;
+               do {
+                       tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
                        wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front(
                                                                wl_egl_surface->vblank->waiting_buffers,
                                                                NULL);
-                       if (wl_egl_buffer)
-                               _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
+                       is_empty = __tpl_list_is_empty(wl_egl_surface->vblank->waiting_buffers);
+                       tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
+
+                       if (!wl_egl_buffer) break;
+
+                       _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
 
-                       /* If tdm error such as TIEMOUT occured,
+                       /* If tdm error such as TIMEOUT occured,
                         * flush all vblank waiting buffers of its wl_egl_surface.
                         * Otherwise, only one wl_egl_buffer will be commited per one vblank event.
                         */
                        if (error == TDM_ERROR_NONE) break;
-               }
+               } while (!is_empty);
        }
        tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
 }
@@ -3487,12 +3504,14 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer)
        }
        tpl_gmutex_unlock(&wl_egl_surface->buffers_mutex);
 
-       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
-       __tpl_list_remove_data(wl_egl_surface->vblank->waiting_buffers,
-                                                  (void *)wl_egl_buffer,
-                                                  TPL_FIRST,
-                                                  NULL);
-       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+       if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {
+               tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
+               __tpl_list_remove_data(wl_egl_surface->vblank->waiting_buffers,
+                                                          (void *)wl_egl_buffer,
+                                                          TPL_FIRST,
+                                                          NULL);
+               tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
+       }
 
        if (wl_egl_display) {
                if (wl_egl_buffer->wl_buffer) {