/[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 774 by jsorg71, Sat Oct 2 00:40:13 2004 UTC revision 963 by astrand, Wed Aug 3 10:56:16 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Cache routines     Cache routines
4     Copyright (C) Matthew Chapman 1999-2002     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  extern int g_pstcache_fd[];  /*
34  extern BOOL g_use_rdp5;   * 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  uint32 g_stamp;   * of being evicted from the cache, and therby reducing the need to load bitmaps from disk.
37  int g_num_bitmaps_in_memory[3];   * (Jeroen)
38     */
39    #define BUMP_COUNT 40
40    
41    struct bmpcache_entry
42    {
43            HBITMAP bitmap;
44            sint16 previous;
45            sint16 next;
46    };
47    
48  /* BITMAP CACHE */  static struct bmpcache_entry g_bmpcache[3][0xa00];
 static BMPCACHEENTRY g_bmpcache[3][0xa00];  
49  static HBITMAP g_volatile_bc[3];  static HBITMAP g_volatile_bc[3];
50    
51  /* Remove the least-recently used bitmap from the cache */  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    /* Setup the bitmap cache lru/mru linked list */
56  void  void
57  cache_remove_lru_bitmap(uint8 cache_id)  cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
58  {  {
59          int i;          int n = count, c = 0;
60          uint16 cache_idx = 0;          sint16 n_idx;
61          uint32 m = (uint32) - 1;  
62          BMPCACHEENTRY *pbce;          /* 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          for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++)          /* link list */
76            while (n >= 0)
77          {          {
78                  if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m)                  /* 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            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
103    cache_bump_bitmap(uint8 id, uint16 idx, int bump)
104    {
105            int p_idx, n_idx, n;
106    
107            if (!IS_PERSISTENT(id))
108                    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            n_idx = g_bmpcache[id][idx].next;
116            p_idx = g_bmpcache[id][idx].previous;
117    
118            if (IS_SET(n_idx))
119            {
120                    /* 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            if (p_idx >= 0)
157                    g_bmpcache[id][p_idx].next = idx;
158            else
159                    g_bmpcache_lru[id] = idx;
160    
161          pbce = &g_bmpcache[cache_id][cache_idx];          if (n_idx >= 0)
162          ui_destroy_bitmap(pbce->bitmap);                  g_bmpcache[id][n_idx].previous = idx;
163          --g_num_bitmaps_in_memory[cache_id];          else
164          pbce->bitmap = 0;                  g_bmpcache_mru[id] = idx;
165          pbce->usage = 0;  }
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          int 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    
# Line 189  cache_get_text(uint8 cache_id) Line 325  cache_get_text(uint8 cache_id)
325  {  {
326          DATABLOB *text;          DATABLOB *text;
327    
328          if (cache_id < NUM_ELEMENTS(g_textcache))          text = &g_textcache[cache_id];
329          {          return text;
                 text = &g_textcache[cache_id];  
                 if (text->data != NULL)  
                         return text;  
         }  
   
         error("get text %d\n", cache_id);  
         return NULL;  
330  }  }
331    
332  /* Store a text item in the cache */  /* Store a text item in the cache */
# Line 206  cache_put_text(uint8 cache_id, void *dat Line 335  cache_put_text(uint8 cache_id, void *dat
335  {  {
336          DATABLOB *text;          DATABLOB *text;
337    
338          if (cache_id < NUM_ELEMENTS(g_textcache))          text = &g_textcache[cache_id];
339          {          if (text->data != NULL)
340                  text = &g_textcache[cache_id];                  xfree(text->data);
341                  if (text->data != NULL)          text->data = xmalloc(length);
342                          xfree(text->data);          text->size = length;
343            memcpy(text->data, data, length);
                 text->data = xmalloc(length);  
                 text->size = length;  
                 memcpy(text->data, data, length);  
         }  
         else  
         {  
                 error("put text %d\n", cache_id);  
         }  
344  }  }
345    
346    

Legend:
Removed from v.774  
changed lines
  Added in v.963

  ViewVC Help
Powered by ViewVC 1.1.26