/[rdesktop]/sourceforge.net/trunk/rdesktop/cache.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/cache.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 828 by stargo, Sun Mar 6 21:11:18 2005 UTC revision 830 by jdmeijer, Tue Mar 8 00:23:02 2005 UTC
# Line 2  Line 2 
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Cache routines     Cache routines
4     Copyright (C) Matthew Chapman 1999-2005     Copyright (C) Matthew Chapman 1999-2005
5       Copyright (C) Jeroen Meijer 2005
6    
7     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 20  Line 21 
21    
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24    /* BITMAP CACHE */
25    extern int g_pstcache_fd[];
26    
27  #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))  #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
 #define TOUCH(id, idx) (g_bmpcache[id][idx].usage = ++g_stamp)  
28  #define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)  #define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
29    #define TO_TOP -1
30    #define NOT_SET -1
31    #define IS_SET(idx) (idx >= 0)
32    
33    /*
34     * TODO: Test for optimal value of BUMP_COUNT. TO_TOP gives lowest cpu utilisation but using
35     * a positive value will hopefully result in less frequently used bitmaps having a greater chance
36     * of being evicted from the cache, and therby reducing the need to load bitmaps from disk.
37     * (Jeroen)
38     */
39    #define BUMP_COUNT 40
40    
41  extern int g_pstcache_fd[];  struct bmpcache_entry
42  extern BOOL g_use_rdp5;  {
43            HBITMAP bitmap;
44            sint16 previous;
45            sint16 next;
46    };
47    
48  uint32 g_stamp;  static struct bmpcache_entry g_bmpcache[3][0xa00];
49    static HBITMAP g_volatile_bc[3];
50    
51  static int g_num_bitmaps_in_memory[3];  static int g_bmpcache_lru[3] = { NOT_SET, NOT_SET, NOT_SET };
52    static int g_bmpcache_mru[3] = { NOT_SET, NOT_SET, NOT_SET };
53    static int g_bmpcache_count[3];
54    
55  /* BITMAP CACHE */  /* Setup the bitmap cache lru/mru linked list */
56  static BMPCACHEENTRY g_bmpcache[3][0xa00];  void
57  static HBITMAP g_volatile_bc[3];  cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
58    {
59            int n = count, c = 0;
60            sint16 n_idx;
61    
62            /* find top, skip evicted bitmaps */
63            while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
64            if (n < 0)
65            {
66                    g_bmpcache_mru[id] = g_bmpcache_lru[id] = NOT_SET;
67                    return;
68            }
69    
70            g_bmpcache_mru[id] = idx[n];
71            g_bmpcache[id][idx[n]].next = NOT_SET;
72            n_idx = idx[n];
73            c++;
74    
75            /* link list */
76            while (n >= 0)
77            {
78                    /* skip evicted bitmaps */
79                    while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
80    
81                    if (n < 0)
82                            break;
83    
84                    g_bmpcache[id][n_idx].previous = idx[n];
85                    g_bmpcache[id][idx[n]].next = n_idx;
86                    n_idx = idx[n];
87                    c++;
88            }
89    
90  /* Remove the least-recently used bitmap from the cache */          g_bmpcache[id][n_idx].previous = NOT_SET;
91            g_bmpcache_lru[id] = n_idx;
92    
93            if (c != g_bmpcache_count[id])
94            {
95                    error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
96                          g_bmpcache_count[id]);
97                    exit(1);
98            }
99    }
100    
101    /* Move a bitmap to a new position in the linked list. */
102  void  void
103  cache_remove_lru_bitmap(uint8 cache_id)  cache_bump_bitmap(uint8 id, uint16 idx, int bump)
104  {  {
105          uint32 i;          int p_idx, n_idx, n;
106          uint16 cache_idx = 0;  
107          uint32 m = 0xffffffff;          if (!IS_PERSISTENT(id))
108          BMPCACHEENTRY *pbce;                  return;
109    
110            if (g_bmpcache_mru[id] == idx)
111                    return;
112    
113            DEBUG_RDP5(("bump bitmap: id=%d, idx=%d, bump=%d\n", id, idx, bump));
114    
115          for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++)          n_idx = g_bmpcache[id][idx].next;
116            p_idx = g_bmpcache[id][idx].previous;
117    
118            if (IS_SET(n_idx))
119          {          {
120                  if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m)                  /* remove */
121                    --g_bmpcache_count[id];
122                    if (IS_SET(p_idx))
123                            g_bmpcache[id][p_idx].next = n_idx;
124                    else
125                            g_bmpcache_lru[id] = n_idx;
126                    if (IS_SET(n_idx))
127                            g_bmpcache[id][n_idx].previous = p_idx;
128                    else
129                            g_bmpcache_mru[id] = p_idx;
130            }
131            else
132            {
133                    p_idx = NOT_SET;
134                    n_idx = g_bmpcache_lru[id];
135            }
136    
137            if (bump >= 0)
138            {
139                    for (n = 0; n < bump && IS_SET(n_idx); n++)
140                  {                  {
141                          cache_idx = i;                          p_idx = n_idx;
142                          m = g_bmpcache[cache_id][i].usage;                          n_idx = g_bmpcache[id][p_idx].next;
143                  }                  }
144          }          }
145            else
146            {
147                    p_idx = g_bmpcache_mru[id];
148                    n_idx = NOT_SET;
149            }
150    
151            /* insert */
152            ++g_bmpcache_count[id];
153            g_bmpcache[id][idx].previous = p_idx;
154            g_bmpcache[id][idx].next = n_idx;
155    
156          pbce = &g_bmpcache[cache_id][cache_idx];          if (p_idx >= 0)
157          ui_destroy_bitmap(pbce->bitmap);                  g_bmpcache[id][p_idx].next = idx;
158          --g_num_bitmaps_in_memory[cache_id];          else
159          pbce->bitmap = 0;                  g_bmpcache_lru[id] = idx;
160          pbce->usage = 0;  
161            if (n_idx >= 0)
162                    g_bmpcache[id][n_idx].previous = idx;
163            else
164                    g_bmpcache_mru[id] = idx;
165    }
166    
167    /* Evict the least-recently used bitmap from the cache */
168    void
169    cache_evict_bitmap(uint8 id)
170    {
171            uint16 idx;
172            int n_idx;
173    
174            if (!IS_PERSISTENT(id))
175                    return;
176    
177            idx = g_bmpcache_lru[id];
178            n_idx = g_bmpcache[id][idx].next;
179            DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=0x%x\n", id, idx, n_idx,
180                        g_bmpcache[id][idx].bitmap));
181    
182            ui_destroy_bitmap(g_bmpcache[id][idx].bitmap);
183            --g_bmpcache_count[id];
184            g_bmpcache[id][idx].bitmap = 0;
185    
186            g_bmpcache_lru[id] = n_idx;
187            g_bmpcache[id][n_idx].previous = NOT_SET;
188    
189            pstcache_touch_bitmap(id, idx, 0);
190  }  }
191    
192  /* Retrieve a bitmap from the cache */  /* Retrieve a bitmap from the cache */
193  HBITMAP  HBITMAP
194  cache_get_bitmap(uint8 cache_id, uint16 cache_idx)  cache_get_bitmap(uint8 id, uint16 idx)
195  {  {
196          HBITMAP *pbitmap;          if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
   
         if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))  
197          {          {
198                  pbitmap = &g_bmpcache[cache_id][cache_idx].bitmap;                  if (g_bmpcache[id][idx].bitmap || pstcache_load_bitmap(id, idx))
                 if ((*pbitmap != 0) || pstcache_load_bitmap(cache_id, cache_idx))  
199                  {                  {
200                          if (IS_PERSISTENT(cache_id))                          if (IS_PERSISTENT(id))
201                                  TOUCH(cache_id, cache_idx);                                  cache_bump_bitmap(id, idx, BUMP_COUNT);
202    
203                          return *pbitmap;                          return g_bmpcache[id][idx].bitmap;
204                  }                  }
205          }          }
206          else if ((cache_id < NUM_ELEMENTS(g_volatile_bc)) && (cache_idx == 0x7fff))          else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
207          {          {
208                  return g_volatile_bc[cache_id];                  return g_volatile_bc[id];
209          }          }
210    
211          error("get bitmap %d:%d\n", cache_id, cache_idx);          error("get bitmap %d:%d\n", id, idx);
212          return NULL;          return NULL;
213  }  }
214    
215  /* Store a bitmap in the cache */  /* Store a bitmap in the cache */
216  void  void
217  cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp)  cache_put_bitmap(uint8 id, uint16 idx, HBITMAP bitmap)
218  {  {
219          HBITMAP old;          HBITMAP old;
220    
221          if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))          if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
222          {          {
223                  old = g_bmpcache[cache_id][cache_idx].bitmap;                  old = g_bmpcache[id][idx].bitmap;
224                  if (old != NULL)                  if (old != NULL)
                 {  
225                          ui_destroy_bitmap(old);                          ui_destroy_bitmap(old);
226                  }                  g_bmpcache[id][idx].bitmap = bitmap;
227                  else if (g_use_rdp5)  
228                    if (IS_PERSISTENT(id))
229                  {                  {
230                          if (++g_num_bitmaps_in_memory[cache_id] > BMPCACHE2_C2_CELLS)                          if (old == NULL)
231                                  cache_remove_lru_bitmap(cache_id);                                  g_bmpcache[id][idx].previous = g_bmpcache[id][idx].next = NOT_SET;
                 }  
232    
233                  g_bmpcache[cache_id][cache_idx].bitmap = bitmap;                          cache_bump_bitmap(id, idx, TO_TOP);
234                  g_bmpcache[cache_id][cache_idx].usage = stamp;                          if (g_bmpcache_count[id] > BMPCACHE2_C2_CELLS)
235                                    cache_evict_bitmap(id);
236                    }
237          }          }
238          else if ((cache_id < NUM_ELEMENTS(g_volatile_bc)) && (cache_idx == 0x7fff))          else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
239          {          {
240                  old = g_volatile_bc[cache_id];                  old = g_volatile_bc[id];
241                  if (old != NULL)                  if (old != NULL)
242                          ui_destroy_bitmap(old);                          ui_destroy_bitmap(old);
243                  g_volatile_bc[cache_id] = bitmap;                  g_volatile_bc[id] = bitmap;
244          }          }
245          else          else
246          {          {
247                  error("put bitmap %d:%d\n", cache_id, cache_idx);                  error("put bitmap %d:%d\n", id, idx);
248          }          }
249  }  }
250    
# Line 125  cache_put_bitmap(uint8 cache_id, uint16 Line 252  cache_put_bitmap(uint8 cache_id, uint16
252  void  void
253  cache_save_state(void)  cache_save_state(void)
254  {  {
255          uint32 id, idx;          uint32 id = 0, t = 0;
256            int idx;
257    
258          for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)          for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
259                  if (IS_PERSISTENT(id))                  if (IS_PERSISTENT(id))
260                          for (idx = 0; idx < NUM_ELEMENTS(g_bmpcache[id]); idx++)                  {
261                                  pstcache_touch_bitmap(id, idx, g_bmpcache[id][idx].usage);                          DEBUG_RDP5(("Saving cache state for bitmap cache %d...", id));
262                            idx = g_bmpcache_lru[id];
263                            while (idx >= 0)
264                            {
265                                    pstcache_touch_bitmap(id, idx, ++t);
266                                    idx = g_bmpcache[id][idx].next;
267                            }
268                            DEBUG_RDP5((" %d stamps written.\n", t));
269                    }
270  }  }
271    
272    

Legend:
Removed from v.828  
changed lines
  Added in v.830

  ViewVC Help
Powered by ViewVC 1.1.26