From dabc423ed0f946bc32268a42dc8fee12a1cd0b0a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 10 Nov 2015 14:38:25 -0700 Subject: [PATCH] st/wgl: reimplement stw_framebuffer::mutex with CRITICAL_SECTION v2: update comments on the stw_framebuffer::mutex field regarding locking order. Reviewed-by: Sinclair Yeh Reviewed-by: Charmaine Lee --- src/gallium/state_trackers/wgl/stw_device.h | 1 - .../state_trackers/wgl/stw_framebuffer.c | 27 +++++------------ .../state_trackers/wgl/stw_framebuffer.h | 29 ++++++++++++++----- src/gallium/state_trackers/wgl/stw_st.c | 4 +-- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h index d695e8f4e12..3f0dffe408b 100644 --- a/src/gallium/state_trackers/wgl/stw_device.h +++ b/src/gallium/state_trackers/wgl/stw_device.h @@ -30,7 +30,6 @@ #include "pipe/p_compiler.h" -#include "os/os_thread.h" #include "util/u_handle_table.h" #include "stw_icd.h" #include "stw_pixelformat.h" diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index ce5b2c3e0b8..a3342ab2562 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -54,7 +54,7 @@ stw_framebuffer_from_hwnd_locked(HWND hwnd) for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next) if (fb->hWnd == hwnd) { - pipe_mutex_lock(fb->mutex); + stw_framebuffer_lock(fb); return fb; } @@ -77,7 +77,7 @@ stw_framebuffer_destroy_locked(struct stw_framebuffer *fb) /* check the reference count */ fb->refcnt--; if (fb->refcnt) { - pipe_mutex_unlock( fb->mutex ); + stw_framebuffer_release(fb); return; } @@ -95,25 +95,14 @@ stw_framebuffer_destroy_locked(struct stw_framebuffer *fb) stw_st_destroy_framebuffer_locked(fb->stfb); - pipe_mutex_unlock( fb->mutex ); + stw_framebuffer_release(fb); - pipe_mutex_destroy( fb->mutex ); + DeleteCriticalSection(&fb->mutex); FREE( fb ); } -/** - * Unlock the given stw_framebuffer object. - */ -void -stw_framebuffer_release(struct stw_framebuffer *fb) -{ - assert(fb); - pipe_mutex_unlock( fb->mutex ); -} - - /** * Query the size of the given framebuffer's on-screen window and update * the stw_framebuffer's width/height. @@ -296,13 +285,13 @@ stw_framebuffer_create(HDC hdc, int iPixelFormat) stw_framebuffer_get_size(fb); - pipe_mutex_init( fb->mutex ); + InitializeCriticalSection(&fb->mutex); /* This is the only case where we lock the stw_framebuffer::mutex before * stw_dev::fb_mutex, since no other thread can know about this framebuffer * and we must prevent any other thread from destroying it before we return. */ - pipe_mutex_lock( fb->mutex ); + stw_framebuffer_lock(fb); stw_lock_framebuffers(stw_dev); fb->next = stw_dev->fb_head; @@ -330,7 +319,7 @@ stw_framebuffer_reference(struct stw_framebuffer **ptr, if (old_fb) { stw_lock_framebuffers(stw_dev); - pipe_mutex_lock(old_fb->mutex); + stw_framebuffer_lock(old_fb); stw_framebuffer_destroy_locked(old_fb); stw_unlock_framebuffers(stw_dev); @@ -378,7 +367,7 @@ stw_framebuffer_cleanup(void) while (fb) { next = fb->next; - pipe_mutex_lock(fb->mutex); + stw_framebuffer_lock(fb); stw_framebuffer_destroy_locked(fb); fb = next; diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h index c7498b245cb..ce9aace7aa0 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h @@ -30,7 +30,8 @@ #include -#include "os/os_thread.h" +#include "util/u_debug.h" + struct pipe_resource; struct st_framebuffer_iface; @@ -45,11 +46,11 @@ struct stw_framebuffer * This mutex has two purposes: * - protect the access to the mutable data members below * - prevent the framebuffer from being deleted while being accessed. - * - * It is OK to lock this mutex while holding the stw_device::fb_mutex lock, - * but the opposite must never happen. + * + * Note: if both this mutex and the stw_device::fb_mutex need to be locked, + * the stw_device::fb_mutex needs to be locked first. */ - pipe_mutex mutex; + CRITICAL_SECTION mutex; /* * Immutable members. @@ -148,13 +149,27 @@ stw_framebuffer_present_locked(HDC hdc, void stw_framebuffer_update(struct stw_framebuffer *fb); + +static inline void +stw_framebuffer_lock(struct stw_framebuffer *fb) +{ + assert(fb); + EnterCriticalSection(&fb->mutex); +} + + /** * Release stw_framebuffer::mutex lock. This framebuffer must not be accessed * after calling this function, as it may have been deleted by another thread * in the meanwhile. */ -void -stw_framebuffer_release(struct stw_framebuffer *fb); +static inline void +stw_framebuffer_release(struct stw_framebuffer *fb) +{ + assert(fb); + LeaveCriticalSection(&fb->mutex); +} + /** * Cleanup any existing framebuffers when exiting application. diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c index 2d5d4379932..6e5ccbb8d5c 100644 --- a/src/gallium/state_trackers/wgl/stw_st.c +++ b/src/gallium/state_trackers/wgl/stw_st.c @@ -136,7 +136,7 @@ stw_st_framebuffer_validate(struct st_context_iface *stctx, for (i = 0; i < count; i++) statt_mask |= 1 << statts[i]; - pipe_mutex_lock(stwfb->fb->mutex); + stw_framebuffer_lock(stwfb->fb); if (stwfb->fb->must_resize || (statt_mask & ~stwfb->texture_mask)) { stw_st_framebuffer_validate_locked(&stwfb->base, @@ -185,7 +185,7 @@ stw_st_framebuffer_flush_front(struct st_context_iface *stctx, boolean ret; HDC hDC; - pipe_mutex_lock(stwfb->fb->mutex); + stw_framebuffer_lock(stwfb->fb); /* We must not cache HDCs anywhere, as they can be invalidated by the * application, or screen resolution changes. */ -- 2.30.2