diff options
| author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2014-03-16 11:08:13 -0700 |
|---|---|---|
| committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2014-03-16 11:08:13 -0700 |
| commit | 40ec8a1714c0772c436db09e0678cc02000bd36f (patch) | |
| tree | c13bf3796166096ca42b53fa5315b0ebc07b2615 /xrdp/xrdp_cache.c | |
| parent | 9470b031aaf27e58b9eeb8df90574c30ac55935e (diff) | |
| parent | 8f05bee2389c08dd2abd630941b544425c5ba7f1 (diff) | |
| download | xrdp-proprietary-40ec8a1714c0772c436db09e0678cc02000bd36f.tar.gz xrdp-proprietary-40ec8a1714c0772c436db09e0678cc02000bd36f.zip | |
Merge branch 'devel' of github.com:/neutrinolabs/xrdp into devel
Diffstat (limited to 'xrdp/xrdp_cache.c')
| -rw-r--r-- | xrdp/xrdp_cache.c | 346 |
1 files changed, 241 insertions, 105 deletions
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index 22bbea3c..9c8098f6 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -20,6 +20,7 @@ #include "xrdp.h" #include "log.h" +#include "crc16.h" #define LLOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -34,6 +35,59 @@ while (0) /*****************************************************************************/ +static int APP_CC +xrdp_cache_reset_lru(struct xrdp_cache *self) +{ + int index; + int jndex; + struct xrdp_lru_item *lru; + + for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++) + { + /* fist item */ + lru = &(self->bitmap_lrus[index][0]); + lru->next = 1; + lru->prev = -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; + } + /* last item */ + lru = &(self->bitmap_lrus[index][XRDP_MAX_BITMAP_CACHE_IDX - 1]); + lru->next = -1; + lru->prev = XRDP_MAX_BITMAP_CACHE_IDX - 2; + + self->lru_head[index] = 0; + self->lru_tail[index] = XRDP_MAX_BITMAP_CACHE_IDX - 1; + + self->lru_reset[index] = 1; + } + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_cache_reset_crc(struct xrdp_cache *self) +{ + int index; + int jndex; + + for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++) + { + for (jndex = 0; jndex < 64 * 1024; jndex++) + { + /* it's ok it deinit a zero'ed out struct list16 */ + list16_deinit(&(self->crc16[index][jndex])); + list16_init(&(self->crc16[index][jndex])); + } + } + return 0; +} + +/*****************************************************************************/ struct xrdp_cache *APP_CC xrdp_cache_create(struct xrdp_wm *owner, struct xrdp_session *session, @@ -65,6 +119,8 @@ xrdp_cache_create(struct xrdp_wm *owner, self->bitmap_cache_version = client_info->bitmap_cache_version; self->pointer_cache_entries = client_info->pointer_cache_entries; self->xrdp_os_del_list = list_create(); + xrdp_cache_reset_lru(self); + xrdp_cache_reset_crc(self); LLOGLN(10, ("xrdp_cache_create: 0 %d 1 %d 2 %d", self->cache1_entries, self->cache2_entries, self->cache3_entries)); return self; @@ -108,6 +164,15 @@ 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++) + { + list16_deinit(&(self->crc16[i][j])); + } + } + g_free(self); } @@ -157,157 +222,228 @@ xrdp_cache_reset(struct xrdp_cache *self, self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; self->bitmap_cache_version = client_info->bitmap_cache_version; self->pointer_cache_entries = client_info->pointer_cache_entries; + xrdp_cache_reset_lru(self); + xrdp_cache_reset_crc(self); return 0; } -#define COMPARE_WITH_CRC(_b1, _b2) \ - ((_b1 != 0) && (_b2 != 0) && (_b1->crc == _b2->crc) && \ +#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)) /*****************************************************************************/ -/* returns cache id */ -int APP_CC -xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap, - int hints) +static int APP_CC +xrdp_cache_update_lru(struct xrdp_cache *self, int cache_id, int lru_index) { - int i = 0; - int j = 0; - int oldest = 0; - int cache_id = 0; - int cache_idx = 0; - int bmp_size = 0; - int e = 0; - int Bpp = 0; + 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 */ - e = bitmap->width % 4; + 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]); - if (e != 0) + /* 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 { - e = 4 - e; + /* 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 index; + int jndex; + int cache_id; + int cache_idx; + int bmp_size; + int e; + int Bpp; + int crc16; + int iig; + int found; + int cache_entries; + int lru_index; + struct list16 *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", + bitmap->crc16)); + + e = (4 - (bitmap->width % 4)) & 3; + found = 0; + cache_id = 0; + cache_entries = 0; + /* client Bpp, bmp_size */ Bpp = (bitmap->bpp + 7) / 8; bmp_size = (bitmap->width + e) * bitmap->height * Bpp; self->bitmap_stamp++; - /* look for match */ if (bmp_size <= self->cache1_size) { - i = 0; - - for (j = 0; j < self->cache1_entries; j++) - { -#ifdef USE_CRC - if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap)) -#else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) -#endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - LLOGLN(10, ("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } - } + cache_id = 0; + cache_entries = self->cache1_entries; } else if (bmp_size <= self->cache2_size) { - i = 1; - - for (j = 0; j < self->cache2_entries; j++) - { -#ifdef USE_CRC - if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap)) -#else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) -#endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - LLOGLN(10, ("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } - } + cache_id = 1; + cache_entries = self->cache2_entries; } else if (bmp_size <= self->cache3_size) { - i = 2; - - for (j = 0; j < self->cache3_entries; j++) - { -#ifdef USE_CRC - if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap)) -#else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) -#endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - LLOGLN(10, ("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } - } + cache_id = 2; + cache_entries = self->cache3_entries; } else { - log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d) bpp %d", bmp_size, bitmap->bpp); + log_message(LOG_LEVEL_ERROR, "error in xrdp_cache_add_bitmap, " + "too big(%d) bpp %d", bmp_size, bitmap->bpp); + return 0; } - /* look for oldest */ - cache_id = 0; - cache_idx = 0; - oldest = 0x7fffffff; - - if (bmp_size <= self->cache1_size) + crc16 = bitmap->crc16; + ll = &(self->crc16[cache_id][crc16]); + for (jndex = 0; jndex < ll->count; jndex++) { - i = 0; - - for (j = 0; j < self->cache1_entries; j++) + cache_idx = list16_get_item(ll, jndex); + if (COMPARE_WITH_CRC32 + (self->bitmap_items[cache_id][cache_idx].bitmap, bitmap)) { - if (self->bitmap_items[i][j].stamp < oldest) - { - oldest = self->bitmap_items[i][j].stamp; - cache_id = i; - cache_idx = j; - } + LLOGLN(10, ("found bitmap at %d %d", index, jndex)); + found = 1; + break; } } - else if (bmp_size <= self->cache2_size) + if (found) { - i = 1; + 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); - 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; - } - } + /* update lru to end */ + xrdp_cache_update_lru(self, cache_id, lru_index); + + return MAKELONG(cache_idx, cache_id); } - else if (bmp_size <= self->cache3_size) + + /* find lru */ + + /* check for reset */ + if (self->lru_reset[cache_id]) { - i = 2; + 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; + } + + /* 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); + + 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", + cache_id, cache_idx, + self->bitmap_items[cache_id][cache_idx].bitmap, + bitmap)); - for (j = 0; j < self->cache3_entries; j++) + /* remove old, about to be deleted, from crc16 list */ + lbm = self->bitmap_items[cache_id][cache_idx].bitmap; + if (lbm != 0) + { + crc16 = lbm->crc16; + ll = &(self->crc16[cache_id][crc16]); + iig = list16_index_of(ll, cache_idx); + if (iig == -1) { - if (self->bitmap_items[i][j].stamp < oldest) - { - oldest = self->bitmap_items[i][j].stamp; - cache_id = i; - cache_idx = j; - } + LLOGLN(0, ("xrdp_cache_add_bitmap: error removing cache_idx")); } + LLOGLN(10, ("xrdp_cache_add_bitmap: removing index %d from crc16 %d", + iig, crc16)); + list16_remove_item(ll, iig); + xrdp_bitmap_delete(lbm); } - LLOGLN(10, ("adding bitmap at %d %d ptr %p", cache_id, cache_idx, - self->bitmap_items[cache_id][cache_idx].bitmap)); /* set, send bitmap and return */ - xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].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; + ll = &(self->crc16[cache_id][crc16]); + list16_add_item(ll, cache_idx); + if (ll->count > 1) + { + LLOGLN(10, ("xrdp_cache_add_bitmap: count %d", ll->count)); + } if (self->use_bitmap_comp) { |
