mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-30 17:49:02 +00:00
cache-item: Simplify structure used for just memory optimization
RedCacheItem was using an union to reuse cache item memory as a pipe item to release that specific cache item. Instead of spreading that structure everywhere move the specific optimization all in cache-item.tmpl.cpp. This make also code less cluttered. Add some comment on specific code. Signed-off-by: Frediano Ziglio <freddy77@gmail.com> Acked-by: Julien Ropé <jrope@gmail.com>
This commit is contained in:
parent
a10e496c46
commit
255f6b2fd3
@ -23,17 +23,16 @@
|
||||
|
||||
#include "red-pipe-item.h"
|
||||
|
||||
typedef struct RedCacheItem RedCacheItem;
|
||||
/* pipe item used to release a specific cached item on the client */
|
||||
struct RedCachePipeItem {
|
||||
RedPipeItem base;
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
struct RedCacheItem {
|
||||
union {
|
||||
RedPipeItem pipe_data;
|
||||
struct {
|
||||
RingItem lru_link;
|
||||
RedCacheItem *next;
|
||||
size_t size;
|
||||
} cache_data;
|
||||
} u;
|
||||
RingItem lru_link;
|
||||
RedCacheItem *next;
|
||||
size_t size;
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
|
||||
@ -46,11 +46,11 @@ static RedCacheItem *FUNC_NAME(find)(CHANNELCLIENT *channel_client, uint64_t id)
|
||||
|
||||
while (item) {
|
||||
if (item->id == id) {
|
||||
ring_remove(&item->u.cache_data.lru_link);
|
||||
ring_add(&channel_client->priv->VAR_NAME(lru), &item->u.cache_data.lru_link);
|
||||
ring_remove(&item->lru_link);
|
||||
ring_add(&channel_client->priv->VAR_NAME(lru), &item->lru_link);
|
||||
break;
|
||||
}
|
||||
item = item->u.cache_data.next;
|
||||
item = item->next;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@ -64,16 +64,21 @@ static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, RedCacheItem *item)
|
||||
for (;;) {
|
||||
spice_assert(*now);
|
||||
if (*now == item) {
|
||||
*now = item->u.cache_data.next;
|
||||
*now = item->next;
|
||||
break;
|
||||
}
|
||||
now = &(*now)->u.cache_data.next;
|
||||
now = &(*now)->next;
|
||||
}
|
||||
ring_remove(&item->u.cache_data.lru_link);
|
||||
channel_client->priv->VAR_NAME(available) += item->u.cache_data.size;
|
||||
ring_remove(&item->lru_link);
|
||||
channel_client->priv->VAR_NAME(available) += item->size;
|
||||
|
||||
red_pipe_item_init(&item->u.pipe_data, RED_PIPE_ITEM_TYPE_INVAL_ONE);
|
||||
channel_client->pipe_add_tail(&item->u.pipe_data); // for now
|
||||
// see "Optimization" comment on add function below
|
||||
auto id = item->id;
|
||||
RedCachePipeItem *pipe_item = reinterpret_cast<RedCachePipeItem*>(item);
|
||||
|
||||
red_pipe_item_init(&pipe_item->base, RED_PIPE_ITEM_TYPE_INVAL_ONE);
|
||||
pipe_item->id = id;
|
||||
channel_client->pipe_add_tail(&pipe_item->base); // for now
|
||||
}
|
||||
|
||||
static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size)
|
||||
@ -81,13 +86,20 @@ static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t siz
|
||||
RedCacheItem *item;
|
||||
int key;
|
||||
|
||||
item = g_new(RedCacheItem, 1);
|
||||
/* Optimization: allocate memory in order to be able to store
|
||||
* both cache item and pipe item to be able to reuse it when
|
||||
* we need to remove cache telling client */
|
||||
union RedCachePoolItem {
|
||||
RedCacheItem cache_item;
|
||||
RedCachePipeItem pipe_item;
|
||||
};
|
||||
item = (RedCacheItem *) g_new(RedCachePoolItem, 1);
|
||||
|
||||
channel_client->priv->VAR_NAME(available) -= size;
|
||||
SPICE_VERIFY(SPICE_OFFSETOF(RedCacheItem, u.cache_data.lru_link) == 0);
|
||||
SPICE_VERIFY(SPICE_OFFSETOF(RedCacheItem, lru_link) == 0);
|
||||
while (channel_client->priv->VAR_NAME(available) < 0) {
|
||||
RedCacheItem *tail = SPICE_CONTAINEROF(ring_get_tail(&channel_client->priv->VAR_NAME(lru)),
|
||||
RedCacheItem, u.cache_data.lru_link);
|
||||
RedCacheItem, lru_link);
|
||||
if (!tail) {
|
||||
channel_client->priv->VAR_NAME(available) += size;
|
||||
g_free(item);
|
||||
@ -95,12 +107,12 @@ static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t siz
|
||||
}
|
||||
FUNC_NAME(remove)(channel_client, tail);
|
||||
}
|
||||
item->u.cache_data.next = channel_client->priv->CACHE_NAME[(key = CACHE_HASH_KEY(id))];
|
||||
item->next = channel_client->priv->CACHE_NAME[(key = CACHE_HASH_KEY(id))];
|
||||
channel_client->priv->CACHE_NAME[key] = item;
|
||||
ring_item_init(&item->u.cache_data.lru_link);
|
||||
ring_add(&channel_client->priv->VAR_NAME(lru), &item->u.cache_data.lru_link);
|
||||
ring_item_init(&item->lru_link);
|
||||
ring_add(&channel_client->priv->VAR_NAME(lru), &item->lru_link);
|
||||
item->id = id;
|
||||
item->u.cache_data.size = size;
|
||||
item->size = size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -111,7 +123,7 @@ static void FUNC_NAME(reset)(CHANNELCLIENT *channel_client, long size)
|
||||
for (i = 0; i < CACHE_HASH_SIZE; i++) {
|
||||
while (channel_client->priv->CACHE_NAME[i]) {
|
||||
RedCacheItem *item = channel_client->priv->CACHE_NAME[i];
|
||||
channel_client->priv->CACHE_NAME[i] = item->u.cache_data.next;
|
||||
channel_client->priv->CACHE_NAME[i] = item->next;
|
||||
g_free(item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,12 +166,12 @@ static void red_marshall_cursor(CursorChannelClient *ccc,
|
||||
|
||||
static inline void red_marshall_inval(RedChannelClient *rcc,
|
||||
SpiceMarshaller *base_marshaller,
|
||||
RedCacheItem *cach_item)
|
||||
RedCachePipeItem *cache_item)
|
||||
{
|
||||
SpiceMsgDisplayInvalOne inval_one;
|
||||
|
||||
rcc->init_send_data(SPICE_MSG_CURSOR_INVAL_ONE);
|
||||
inval_one.id = cach_item->id;
|
||||
inval_one.id = cache_item->id;
|
||||
|
||||
spice_marshall_msg_cursor_inval_one(base_marshaller, &inval_one);
|
||||
}
|
||||
@ -186,7 +186,7 @@ void CursorChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
red_marshall_cursor(ccc, m, SPICE_UPCAST(RedCursorPipeItem, pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_INVAL_ONE:
|
||||
red_marshall_inval(this, m, SPICE_CONTAINEROF(pipe_item, RedCacheItem, u.pipe_data));
|
||||
red_marshall_inval(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_CURSOR_INIT:
|
||||
reset_cursor_cache();
|
||||
|
||||
@ -1740,7 +1740,7 @@ static bool red_marshall_stream_data(DisplayChannelClient *dcc,
|
||||
|
||||
static inline void marshall_inval_palette(RedChannelClient *rcc,
|
||||
SpiceMarshaller *base_marshaller,
|
||||
RedCacheItem *cache_item)
|
||||
RedCachePipeItem *cache_item)
|
||||
{
|
||||
SpiceMsgDisplayInvalOne inval_one;
|
||||
|
||||
@ -2345,7 +2345,7 @@ void DisplayChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_INVAL_ONE:
|
||||
marshall_inval_palette(this, m, SPICE_CONTAINEROF(pipe_item, RedCacheItem, u.pipe_data));
|
||||
marshall_inval_palette(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_CREATE: {
|
||||
StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, pipe_item);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user