summaryrefslogtreecommitdiffstats
path: root/xrdp/xrdp_cache.c
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2014-03-14 18:41:52 -0700
committerJay Sorg <jay.sorg@gmail.com>2014-03-14 18:41:52 -0700
commitf66c5911a2ae57368e571643750c0b79aec5498f (patch)
tree2ed182a27a486b861e36a459037e1cc7eb18a2f2 /xrdp/xrdp_cache.c
parent261d35eaac7bb429ad21a7ee8bbe5623859730dd (diff)
downloadxrdp-proprietary-f66c5911a2ae57368e571643750c0b79aec5498f.tar.gz
xrdp-proprietary-f66c5911a2ae57368e571643750c0b79aec5498f.zip
xrdp: speed up bitmap cache lru using linked list
Diffstat (limited to 'xrdp/xrdp_cache.c')
-rw-r--r--xrdp/xrdp_cache.c188
1 files changed, 125 insertions, 63 deletions
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index 3510856d..b637a380 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -48,24 +48,22 @@ xrdp_cache_reset_lru(struct xrdp_cache *self)
lru = &(self->bitmap_lrus[index][0]);
lru->next = 1;
lru->prev = -1;
- lru->cacheid = -1;
/* middle items */
for (jndex = 1; jndex < XRDP_MAX_BITMAP_CACHE_IDX - 1; jndex++)
{
lru = &(self->bitmap_lrus[index][jndex]);
lru->next = jndex + 1;
lru->prev = jndex - 1;
- lru->cacheid = -1;
}
/* last item */
lru = &(self->bitmap_lrus[index][XRDP_MAX_BITMAP_CACHE_IDX - 1]);
lru->next = -1;
lru->prev = XRDP_MAX_BITMAP_CACHE_IDX - 2;
- lru->cacheid = -1;
self->lru_head[index] = 0;
self->lru_tail[index] = XRDP_MAX_BITMAP_CACHE_IDX - 1;
+ self->lru_reset[index] = 1;
}
return 0;
}
@@ -165,6 +163,16 @@ xrdp_cache_delete(struct xrdp_cache *self)
list_delete(self->xrdp_os_del_list);
+ /* free all crc lists */
+ for (i = 0; i < XRDP_MAX_BITMAP_CACHE_ID; i++)
+ {
+ for (j = 0; j < 64 * 1024; j++)
+ {
+ list_delete(self->crc16[i][j]);
+ self->crc16[i][j] = 0;
+ }
+ }
+
g_free(self);
}
@@ -219,20 +227,89 @@ xrdp_cache_reset(struct xrdp_cache *self,
return 0;
}
-#define COMPARE_WITH_CRC(_b1, _b2) \
+#define COMPARE_WITH_CRC32(_b1, _b2) \
((_b1 != 0) && (_b2 != 0) && (_b1->crc32 == _b2->crc32) && \
(_b1->bpp == _b2->bpp) && \
(_b1->width == _b2->width) && (_b1->height == _b2->height))
/*****************************************************************************/
+static int APP_CC
+xrdp_cache_update_lru(struct xrdp_cache *self, int cache_id, int lru_index)
+{
+ int tail_index;
+ struct xrdp_lru_item *nextlru;
+ struct xrdp_lru_item *prevlru;
+ struct xrdp_lru_item *thislru;
+ struct xrdp_lru_item *taillru;
+
+ LLOGLN(10, ("xrdp_cache_update_lru: lru_index %d", lru_index));
+ if ((lru_index < 0) || (lru_index >= XRDP_MAX_BITMAP_CACHE_IDX))
+ {
+ LLOGLN(0, ("xrdp_cache_update_lru: error"));
+ return 1;
+ }
+ if (self->lru_tail[cache_id] == lru_index)
+ {
+ /* nothing to do */
+ return 0;
+ }
+ else if (self->lru_head[cache_id] == lru_index)
+ {
+ /* moving head item to tail */
+
+ thislru = &(self->bitmap_lrus[cache_id][lru_index]);
+ nextlru = &(self->bitmap_lrus[cache_id][thislru->next]);
+ tail_index = self->lru_tail[cache_id];
+ taillru = &(self->bitmap_lrus[cache_id][tail_index]);
+
+ /* unhook old */
+ nextlru->prev = -1;
+
+ /* set head to next */
+ self->lru_head[cache_id] = thislru->next;
+
+ /* move to tail and hook up */
+ taillru->next = lru_index;
+ thislru->prev = tail_index;
+ thislru->next = -1;
+
+ /* update tail */
+ self->lru_tail[cache_id] = lru_index;
+
+ }
+ else
+ {
+ /* move middle item */
+
+ thislru = &(self->bitmap_lrus[cache_id][lru_index]);
+ prevlru = &(self->bitmap_lrus[cache_id][thislru->prev]);
+ nextlru = &(self->bitmap_lrus[cache_id][thislru->next]);
+ tail_index = self->lru_tail[cache_id];
+ taillru = &(self->bitmap_lrus[cache_id][tail_index]);
+
+ /* unhook old */
+ prevlru->next = thislru->next;
+ nextlru->prev = thislru->prev;
+
+ /* move to tail and hook up */
+ taillru->next = lru_index;
+ thislru->prev = tail_index;
+ thislru->next = -1;
+
+ /* update tail */
+ self->lru_tail[cache_id] = lru_index;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
/* returns cache id */
int APP_CC
xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
int hints)
{
- int i;
- int j;
- int oldest;
+ int index;
+ int jndex;
int cache_id;
int cache_idx;
int bmp_size;
@@ -241,9 +318,11 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
int crc16;
int iig;
int found;
- int cacheidx;
+ int cache_entries;
+ int lru_index;
struct list *ll;
struct xrdp_bitmap *lbm;
+ struct xrdp_lru_item *llru;
LLOGLN(10, ("xrdp_cache_add_bitmap:"));
LLOGLN(10, ("xrdp_cache_add_bitmap: crc16 0x%4.4x",
@@ -251,7 +330,8 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
e = (4 - (bitmap->width % 4)) & 3;
found = 0;
- i = 0;
+ cache_id = 0;
+ cache_entries = 0;
/* client Bpp, bmp_size */
Bpp = (bitmap->bpp + 7) / 8;
@@ -260,15 +340,18 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
if (bmp_size <= self->cache1_size)
{
- i = 0;
+ cache_id = 0;
+ cache_entries = self->cache1_entries;
}
else if (bmp_size <= self->cache2_size)
{
- i = 1;
+ cache_id = 1;
+ cache_entries = self->cache2_entries;
}
else if (bmp_size <= self->cache3_size)
{
- i = 2;
+ cache_id = 2;
+ cache_entries = self->cache3_entries;
}
else
{
@@ -278,73 +361,51 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
}
crc16 = bitmap->crc16;
- ll = self->crc16[i][crc16];
- for (j = 0; j < ll->count; j++)
+ ll = self->crc16[cache_id][crc16];
+ for (jndex = 0; jndex < ll->count; jndex++)
{
- cacheidx = list_get_item(ll, j);
- if (COMPARE_WITH_CRC(self->bitmap_items[i][cacheidx].bitmap, bitmap))
+ cache_idx = list_get_item(ll, jndex);
+ if (COMPARE_WITH_CRC32
+ (self->bitmap_items[cache_id][cache_idx].bitmap, bitmap))
{
- j = cacheidx;
- LLOGLN(10, ("found bitmap at %d %d", i, j));
+ LLOGLN(10, ("found bitmap at %d %d", index, jndex));
found = 1;
break;
}
}
if (found)
{
- self->bitmap_items[i][j].stamp = self->bitmap_stamp;
+ lru_index = self->bitmap_items[cache_id][cache_idx].lru_index;
+ self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
xrdp_bitmap_delete(bitmap);
- return MAKELONG(j, i);
+
+ /* update lru to end */
+ xrdp_cache_update_lru(self, cache_id, lru_index);
+
+ return MAKELONG(cache_idx, cache_id);
}
- /* look for oldest */
- cache_id = 0;
- cache_idx = 0;
- oldest = 0x7fffffff;
+ /* find lru */
- if (bmp_size <= self->cache1_size)
+ /* check for reset */
+ if (self->lru_reset[cache_id])
{
- i = 0;
-
- for (j = 0; j < self->cache1_entries; j++)
- {
- if (self->bitmap_items[i][j].stamp < oldest)
- {
- oldest = self->bitmap_items[i][j].stamp;
- cache_id = i;
- cache_idx = j;
- }
- }
+ self->lru_reset[cache_id] = 0;
+ LLOGLN(0, ("xrdp_cache_add_bitmap: reset detected cache_id %d",
+ cache_id));
+ self->lru_tail[cache_id] = cache_entries - 1;
+ index = self->lru_tail[cache_id];
+ llru = &(self->bitmap_lrus[cache_id][index]);
+ llru->next = -1;
}
- else if (bmp_size <= self->cache2_size)
- {
- i = 1;
- for (j = 0; j < self->cache2_entries; j++)
- {
- if (self->bitmap_items[i][j].stamp < oldest)
- {
- oldest = self->bitmap_items[i][j].stamp;
- cache_id = i;
- cache_idx = j;
- }
- }
- }
- else if (bmp_size <= self->cache3_size)
- {
- i = 2;
+ /* lru is item at head */
+ lru_index = self->lru_head[cache_id];
+ cache_idx = lru_index;
+
+ /* update lru to end */
+ xrdp_cache_update_lru(self, cache_id, lru_index);
- for (j = 0; j < self->cache3_entries; j++)
- {
- if (self->bitmap_items[i][j].stamp < oldest)
- {
- oldest = self->bitmap_items[i][j].stamp;
- cache_id = i;
- cache_idx = j;
- }
- }
- }
-
LLOGLN(10, ("xrdp_cache_add_bitmap: oldest %d %d", cache_id, cache_idx));
LLOGLN(10, ("adding bitmap at %d %d old ptr %p new ptr %p",
@@ -373,6 +434,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
+ self->bitmap_items[cache_id][cache_idx].lru_index = lru_index;
/* add to crc16 list */
crc16 = bitmap->crc16;