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;
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;
}
#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)
{
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;
}
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;
}
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);
*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;
}
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)",
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);
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);
}
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);
}
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);
}
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;
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;
}