vblank: use mutex to protect the vblank lists for multi-thread 66/112566/1
authorBoram Park <boram1288.park@samsung.com>
Wed, 1 Feb 2017 12:07:02 +0000 (21:07 +0900)
committerBoram Park <boram1288.park@samsung.com>
Wed, 1 Feb 2017 12:07:11 +0000 (21:07 +0900)
Change-Id: I332407aeb258b7b51165db87bfa47405d3c82efa

src/tdm_vblank.c

index 8e3f7dbb1a412a5785b0cc2686c9c5ad6cc61875..0e3c1aae214bd962da23ad9f81b2d912f02f845a 100644 (file)
@@ -80,7 +80,7 @@ typedef enum {
 typedef struct _tdm_vblank_wait_info tdm_vblank_wait_info;
 
 typedef struct _tdm_private_vblank {
-       struct list_head link;
+       struct list_head valid_link;
 
        double stamp;
        pid_t owner_tid;
@@ -131,8 +131,11 @@ struct _tdm_vblank_wait_info {
        unsigned int target_seq;
 };
 
-static pthread_mutex_t vblank_list_lock;
-static struct list_head vblank_list;
+/* valid_vblank_list and valid_wait_list should be protected by valid_list_lock because
+ * tdm_vblank can be used in multi-thread.
+ */
+static pthread_mutex_t valid_list_lock;
+static struct list_head valid_vblank_list;
 static struct list_head valid_wait_list;
 static unsigned int vblank_list_inited;
 static double stamp = 0;
@@ -153,6 +156,22 @@ _print_list(struct list_head *list)
 }
 #endif
 
+static void
+_tdm_vblank_valid_list_add(struct list_head *valid_link, struct list_head *valid_list)
+{
+       pthread_mutex_lock(&valid_list_lock);
+       LIST_ADDTAIL(valid_link, valid_list);
+       pthread_mutex_unlock(&valid_list_lock);
+}
+
+static void
+_tdm_vblank_valid_list_del(struct list_head *valid_link)
+{
+       pthread_mutex_lock(&valid_list_lock);
+       LIST_DEL(valid_link);
+       pthread_mutex_unlock(&valid_list_lock);
+}
+
 static inline tdm_private_vblank*
 _tdm_vblank_find(double vblank_stamp)
 {
@@ -161,14 +180,14 @@ _tdm_vblank_find(double vblank_stamp)
        if (!vblank_stamp)
                return 0;
 
-       pthread_mutex_lock(&vblank_list_lock);
-       LIST_FOR_EACH_ENTRY(v, &vblank_list, link) {
+       pthread_mutex_lock(&valid_list_lock);
+       LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) {
                if (v->stamp == vblank_stamp) {
-                       pthread_mutex_unlock(&vblank_list_lock);
+                       pthread_mutex_unlock(&valid_list_lock);
                        return v;
                }
        }
-       pthread_mutex_unlock(&vblank_list_lock);
+       pthread_mutex_unlock(&valid_list_lock);
 
        return 0;
 }
@@ -181,10 +200,14 @@ _tdm_vblank_check_valid_wait(tdm_vblank_wait_info *wait_info)
        if (!wait_info)
                return 0;
 
+       pthread_mutex_lock(&valid_list_lock);
        LIST_FOR_EACH_ENTRY(w, &valid_wait_list, valid_link) {
-               if (w->stamp == wait_info->stamp)
+               if (w->stamp == wait_info->stamp) {
+                       pthread_mutex_unlock(&valid_list_lock);
                        return 1;
+               }
        }
+       pthread_mutex_unlock(&valid_list_lock);
 
        return 0;
 }
@@ -257,7 +280,7 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un
 
        LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) {
                LIST_DEL(&w->link);
-               LIST_DEL(&w->valid_link);
+               _tdm_vblank_valid_list_del(&w->valid_link);
 
                if (call_cb && w->func)
                        w->func(private_vblank, error, 0, 0, 0, w->user_data);
@@ -313,13 +336,13 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error)
                *error = TDM_ERROR_NONE;
 
        if (!vblank_list_inited) {
-               if (pthread_mutex_init(&vblank_list_lock, NULL)) {
+               if (pthread_mutex_init(&valid_list_lock, NULL)) {
                        TDM_ERR("mutex init failed: %m");
                        if (error)
                                *error = TDM_ERROR_OPERATION_FAILED;
                        return NULL;
                }
-               LIST_INITHEAD(&vblank_list);
+               LIST_INITHEAD(&valid_vblank_list);
                LIST_INITHEAD(&valid_wait_list);
                vblank_list_inited = 1;
        }
@@ -358,9 +381,7 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error)
        LIST_INITHEAD(&private_vblank->HW_wait_list);
        LIST_INITHEAD(&private_vblank->SW_wait_list);
 
-       pthread_mutex_lock(&vblank_list_lock);
-       LIST_ADD(&private_vblank->link, &vblank_list);
-       pthread_mutex_unlock(&vblank_list_lock);
+       _tdm_vblank_valid_list_add(&private_vblank->valid_link, &valid_vblank_list);
 
        if (tdm_debug_module & TDM_DEBUG_VBLANK)
                VIN("created. vrefresh(%d) dpms(%d)",
@@ -378,9 +399,7 @@ tdm_vblank_destroy(tdm_vblank *vblank)
        if (!private_vblank)
                return;
 
-       pthread_mutex_lock(&vblank_list_lock);
-       LIST_DEL(&private_vblank->link);
-       pthread_mutex_unlock(&vblank_list_lock);
+       _tdm_vblank_valid_list_del(&private_vblank->valid_link);
 
        if (private_vblank->SW_timer) {
                tdm_display_lock(private_vblank->dpy);
@@ -395,7 +414,7 @@ tdm_vblank_destroy(tdm_vblank *vblank)
 
        LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) {
                LIST_DEL(&w->link);
-               LIST_DEL(&w->valid_link);
+               _tdm_vblank_valid_list_del(&w->valid_link);
                free(w);
        }
 
@@ -599,7 +618,7 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence,
                                                tv_sec, tv_usec, wait_info->user_data);
 
        LIST_DEL(&wait_info->link);
-       LIST_DEL(&wait_info->valid_link);
+       _tdm_vblank_valid_list_del(&wait_info->valid_link);
        free(wait_info);
 }
 
@@ -737,7 +756,7 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp)
                        break;
 
                LIST_DEL(&w->link);
-               LIST_DEL(&w->valid_link);
+               _tdm_vblank_valid_list_del(&w->valid_link);
 
                if (w->func) {
                        tdm_display_unlock(private_vblank->dpy);
@@ -845,7 +864,9 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
        }
 
        LIST_INITHEAD(&wait_info->link);
-       LIST_ADDTAIL(&wait_info->valid_link, &valid_wait_list);
+
+       _tdm_vblank_valid_list_add(&wait_info->valid_link, &valid_wait_list);
+
        wait_info->stamp = ++stamp;
        wait_info->req_time = TDM_TIME(req_sec, req_usec);
        wait_info->interval = interval;
@@ -884,7 +905,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
 
        if (ret != TDM_ERROR_NONE) {
                LIST_DEL(&wait_info->link);
-               LIST_DEL(&wait_info->valid_link);
+               _tdm_vblank_valid_list_del(&wait_info->valid_link);
                free(wait_info);
                return ret;
        }