summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-09-14 16:37:10 +0200
committerAlexander Larsson <alexl@redhat.com>2010-09-20 10:25:17 +0200
commit55d64c02de69f49fc4d3e9f38fdfaf6ad8f606c9 (patch)
tree37fe67ab5cddcf628b8fd82aa87d9a3e9cb0a30b
parent1f2b0bc13355bb18454eebf45ba2bdb199ec4b13 (diff)
Protect palette cache agains concurrent access
-rw-r--r--display/qxldd.h1
-rw-r--r--display/res.c14
2 files changed, 15 insertions, 0 deletions
diff --git a/display/qxldd.h b/display/qxldd.h
index 8b07f1d..6fd84c4 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -189,6 +189,7 @@ typedef struct DevRes {
HSEMAPHORE surface_sem; /* Protects surfaces allocation */
HSEMAPHORE image_cache_sem; /* Protects image cache */
HSEMAPHORE cursor_cache_sem; /* Protects cursor cache */
+ HSEMAPHORE palette_cache_sem; /* Protects palette cache */
CacheImage cache_image_pool[IMAGE_POOL_SIZE];
Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index 93ab05b..3b8a81e 100644
--- a/display/res.c
+++ b/display/res.c
@@ -415,6 +415,10 @@ void CleanGlobalRes()
EngDeleteSemaphore(res->cursor_cache_sem);
res->cursor_cache_sem = NULL;
}
+ if (res->palette_cache_sem) {
+ EngDeleteSemaphore(res->palette_cache_sem);
+ res->palette_cache_sem = NULL;
+ }
EngFreeMem(res);
}
}
@@ -488,6 +492,10 @@ static void InitRes(PDev *pdev)
if (!pdev->Res->cursor_cache_sem) {
PANIC(pdev, "Res cache sem creation failed\n");
}
+ pdev->Res->palette_cache_sem = EngCreateSemaphore();
+ if (!pdev->Res->palette_cache_sem) {
+ PANIC(pdev, "Res cache sem creation failed\n");
+ }
InitMspace(pdev->Res, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
InitMspace(pdev->Res, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
@@ -1458,6 +1466,7 @@ static _inline void ReleasePalette(PDev *pdev, InternalPalette *palette)
}
}
+/* Called with palette_cache_sem held */
static _inline void PaletteCacheRemove(PDev *pdev, InternalPalette *palette)
{
InternalPalette **internal;
@@ -1489,6 +1498,7 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique)
if (!unique) {
return NULL;
}
+ EngAcquireSemaphore(pdev->Res->palette_cache_sem);
now = pdev->Res->palette_cache[PALETTE_HASH_VAL(unique)];
while (now) {
@@ -1496,12 +1506,14 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique)
RingRemove(pdev, &now->lru_link);
RingAdd(pdev, &pdev->Res->palette_lru, &now->lru_link);
now->refs++;
+ EngReleaseSemaphore(pdev->Res->palette_cache_sem);
DEBUG_PRINT((pdev, 13, "%s: found\n", __FUNCTION__));
return now;
}
now = now->next;
}
DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__));
+ EngReleaseSemaphore(pdev->Res->palette_cache_sem);
return NULL;
}
@@ -1516,6 +1528,7 @@ static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette)
return;
}
+ EngAcquireSemaphore(pdev->Res->palette_cache_sem);
if (pdev->Res->num_palettes == PALETTE_CACHE_SIZE) {
ASSERT(pdev, RingGetTail(pdev, &pdev->Res->palette_lru));
PaletteCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->palette_lru),
@@ -1529,6 +1542,7 @@ static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette)
RingAdd(pdev, &pdev->Res->palette_lru, &palette->lru_link);
palette->refs++;
pdev->Res->num_palettes++;
+ EngReleaseSemaphore(pdev->Res->palette_cache_sem);
DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__));
}