more todo items knocked off for cserve

SVN revision: 40509
This commit is contained in:
Carsten Haitzler 2009-05-05 14:37:18 +00:00
parent 07ec7509a9
commit 892c085276
6 changed files with 407 additions and 78 deletions

View File

@ -19,7 +19,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = @WIN32_CFLAGS@
bin_PROGRAMS = evas_cserve evas_cserve_test
bin_PROGRAMS = evas_cserve evas_cserve_tool
evas_cserve_SOURCES = \
evas_cserve_main.c
@ -27,14 +27,14 @@ evas_cserve_main.c
evas_cserve_LDADD = \
$(top_builddir)/src/lib/libevas.la
evas_cserve_test_LDFLAGS =
evas_cserve_tool_LDFLAGS =
evas_cserve_test_SOURCES = \
evas_cserve_test_main.c
evas_cserve_tool_SOURCES = \
evas_cserve_tool.c
evas_cserve_test_LDADD = \
evas_cserve_tool_LDADD = \
$(top_builddir)/src/lib/libevas.la
evas_cserve_test_LDFLAGS =
evas_cserve_tool_LDFLAGS =
endif

View File

@ -1,11 +1,15 @@
#include "Evas.h"
#include "evas_cs.h"
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#ifdef _WIN32
# include <windows.h>
#endif
// fixme:'s
//
// add ops to get/set cache size, check time and cache time (both)
// add ops to get internal state (both)
// add ops to get internal cache state (both)
// preload - make it work (both)
// monitor /proc/meminfo and if mem low - free items until cache empty (server)
//
@ -35,6 +39,10 @@ struct _Img
time_t modtime;
time_t last_stat;
} file;
struct {
int load1saved, load2saved;
double load1, load2;
} stats;
Lopt load_opts;
struct {
int w, h;
@ -57,12 +65,116 @@ static Eina_List *cache_images = NULL;
static int cache_usage = 0;
static int cache_max_usage = 1 * 1024 * 1024;
static int cache_item_timeout = -1;
static int cache_item_timeout_check = 10;
static int cache_item_timeout_check = -1;
static Mem *stat_mem = NULL;
static int stat_mem_num = 0;
static Eina_List *stat_mems = NULL;
#ifndef _WIN32
static double
get_time(void)
{
struct timeval timev;
gettimeofday(&timev, NULL);
return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
}
#else
static double
get_time(void)
{
return (double)GetTickCount()/1000.0;
}
#endif
static int stats_dirty = 0;
static int saved_loads = 0;
static double saved_load_time = 0;
static double saved_load_lifetime = 0;
static int saved_loaddatas = 0;
static double saved_loaddata_time = 0;
static double saved_loaddata_lifetime = 0;
static int saved_memory = 0;
static int saved_memory_peak = 0;
static int alloced_memory = 0;
static int alloced_memory_peak = 0;
static int real_memory = 0;
static int real_memory_peak = 0;
static Eina_Bool
stats_hash_image_cb(const Eina_Hash *hash __UNUSED__,
const void *key __UNUSED__,
void *data, void *fdata __UNUSED__)
{
Img *img = data;
saved_load_time += img->stats.load1 * img->stats.load1saved;
saved_loaddata_time += img->stats.load2 * img->stats.load2saved;
if (img->ref > 1)
saved_memory += img->image.w * img->image.h * sizeof(DATA32) * (img->ref - 1);
if (img->mem)
{
alloced_memory += img->image.w * img->image.h * sizeof(DATA32);
real_memory += (((img->image.w * img->image.h * sizeof(DATA32)) + 4095) >> 12) << 12;
}
return 1;
}
static void
stats_calc(void)
{
Img *img;
Eina_List *l;
if (!stats_dirty) return;
stats_dirty = 0;
saved_loads = 0;
saved_load_time = 0;
saved_loaddatas = 0;
saved_loaddata_time = 0;
saved_memory = 0;
alloced_memory = 0;
real_memory = 0;
if (active_images)
eina_hash_foreach(active_images, stats_hash_image_cb, NULL);
EINA_LIST_FOREACH(cache_images, l, img)
{
saved_loads += img->stats.load1saved;
saved_load_time += img->stats.load1 * img->stats.load1saved;
saved_loaddatas += img->stats.load2saved;
saved_loaddata_time += img->stats.load2 * img->stats.load2saved;
if (img->mem)
{
alloced_memory += img->image.w * img->image.h * sizeof(DATA32);
real_memory += (((img->image.w * img->image.h * sizeof(DATA32)) + 4095) >> 12) << 12;
}
}
if (saved_memory > saved_memory_peak)
saved_memory_peak = saved_memory;
if (real_memory > real_memory_peak)
real_memory_peak = real_memory;
if (alloced_memory > alloced_memory_peak)
alloced_memory_peak = alloced_memory;
}
static void
stats_update(void)
{
stats_dirty = 1;
}
static void
stats_lifetime_update(Img *img)
{
saved_load_lifetime += img->stats.load1 * img->stats.load1saved;
saved_loaddata_lifetime += img->stats.load2 * img->stats.load2saved;
}
static void
stat_clean(Mem *m)
{
@ -279,12 +391,16 @@ img_new(const char *file, const char *key, RGBA_Image_Loadopts *load_opts, const
int ret;
Image_Entry *ie;
int err = 0;
double t;
ret = stat(file, &st);
if (ret < 0) return NULL;
t = get_time();
ie = evas_cache_image_request(cache, file, key, load_opts, &err);
t = get_time() - t;
if (!ie) return NULL;
img = (Img *)ie;
img->stats.load1 = t;
img->key = eina_stringshare_add(bufkey);
img->file.modtime = st.st_mtime;
img->file.file = eina_stringshare_add(file);
@ -309,8 +425,13 @@ img_new(const char *file, const char *key, RGBA_Image_Loadopts *load_opts, const
static void
img_loaddata(Img *img)
{
double t;
// fixme: load img data
t = get_time();
evas_cache_image_load_data((Image_Entry *)img);
t = get_time() - t;
img->stats.load2 = t;
if (img->image.data)
msync(img->image.data, img->image.w * img->image.h * sizeof(DATA32), MS_SYNC | MS_INVALIDATE);
img->usage +=
@ -321,6 +442,8 @@ img_loaddata(Img *img)
static void
img_free(Img *img)
{
stats_lifetime_update(img);
stats_update();
eina_stringshare_del(img->key);
eina_stringshare_del(img->file.file);
eina_stringshare_del(img->file.key);
@ -437,7 +560,9 @@ img_load(const char *file, const char *key, RGBA_Image_Loadopts *load_opts)
img = eina_hash_find(active_images, buf);
if ((img) && (img_ok(img)))
{
img->stats.load1saved++;
img->ref++;
stats_update();
return img;
}
@ -448,9 +573,11 @@ img_load(const char *file, const char *key, RGBA_Image_Loadopts *load_opts)
{
if (img_ok(img))
{
img->stats.load1saved++;
img->ref++;
cache_images = eina_list_remove_list(cache_images, l);
eina_hash_direct_add(active_images, img->key, img);
stats_update();
return img;
}
}
@ -546,6 +673,8 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
msg.mem.id = img->mem->id;
msg.mem.offset = img->mem->offset;
msg.mem.size = img->mem->size;
img->stats.load2saved++;
stats_update();
}
else
msg.mem.id = msg.mem.offset = msg.mem.size = 0;
@ -574,12 +703,16 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
Op_Loaddata *rep;
Op_Loaddata_Reply msg;
Img *img;
// fixme: handle loadopts on loaddata
// RGBA_Image_Loadopts lopt = {0, 0.0, 0, 0};
rep = (Op_Loaddata *)data;
img = rep->handle;
img_loaddata(img);
if (img->mem)
{
img->stats.load2saved++;
stats_update();
}
else
img_loaddata(img);
memset(&msg, 0, sizeof(msg));
if (img->mem)
{
@ -614,6 +747,57 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
img_forcedunload(img);
}
break;
case OP_GETCONFIG:
{
Op_Getconfig_Reply msg;
msg.cache_max_usage = cache_max_usage;
msg.cache_item_timeout = cache_item_timeout;
msg.cache_item_timeout_check = cache_item_timeout_check;
evas_cserve_client_send(c, OP_GETCONFIG, sizeof(msg), (unsigned char *)(&msg));
}
break;
case OP_SETCONFIG:
{
Op_Setconfig *rep;
rep = (Op_Setconfig *)data;
cache_max_usage = rep->cache_max_usage;
cache_item_timeout = rep->cache_item_timeout;
cache_item_timeout_check = rep->cache_item_timeout_check;
cache_clean();
}
break;
case OP_GETSTATS:
{
Op_Getstats_Reply msg;
stats_calc();
msg.saved_memory = saved_memory;
msg.wasted_memory = (real_memory - alloced_memory);
msg.saved_memory_peak = saved_memory_peak;
msg.wasted_memory_peak = (real_memory_peak - alloced_memory_peak);
msg.saved_time_image_header_load = saved_load_lifetime + saved_load_time;
msg.saved_time_image_data_load = saved_loaddata_lifetime + saved_loaddata_time;
evas_cserve_client_send(c, OP_GETSTATS, sizeof(msg), (unsigned char *)(&msg));
}
break;
case OP_GETINFO:
{
// get a list of all images in active hash and cache list, and their info like
// file + key
// width, height and alpha flag
// refcount
// data loaded flag
// active ot cached
// last active timestamp
// dead
// mod time
// last checked mod time time
// memory footprint
// Op_Getstats_Reply msg;
}
break;
default:
break;
}

View File

@ -1,33 +0,0 @@
#include "evas_cs.h"
int
main(int argc, char **argv)
{
evas_init();
printf("evas_cserve_init = %i\n", evas_cserve_init());
{
Image_Entry *ie;
RGBA_Image_Loadopts lopt = { 0, 0.0, 0, 0};
ie = malloc(sizeof(Image_Entry));
if (evas_cserve_image_load(ie, argv[1], NULL, &lopt))
{
printf("load ok\n");
if (evas_cserve_image_data_load(ie))
{
Mem *m;
m = ie->data2;
printf("first pixel: %08x\n", *((int *)m->data));
printf("load data ok\n");
// evas_cserve_image_free(ie);
}
}
}
evas_cserve_shutdown();
evas_shutdown();
return 0;
}

View File

@ -0,0 +1,101 @@
#include "evas_cs.h"
int
main(int argc, char **argv)
{
int i;
evas_init();
if (!evas_cserve_init())
{
printf("ERROR: Cannot connect to cserve. abort\n");
exit(-1);
}
for (i = 1; i < argc; i++)
{
if ((!strcmp(argv[i], "-h")) ||
(!strcmp(argv[i], "-help")) ||
(!strcmp(argv[i], "--help")))
{
printf("Options:\n"
"\t-h This help\n"
"\tgetconfig Get configuration values\n"
"\tsetconfig csize ctimeout ctimecheck Set the config values\n"
"\tgetstats Get current cache statistics\n"
);
exit(0);
}
else if ((!strcmp(argv[i], "getconfig")))
{
Op_Getconfig_Reply config;
if (!evas_cserve_config_get(&config))
{
printf("ERROR: cannot fetch config.\n");
exit(-1);
}
printf("csize: %i\n", config.cache_max_usage / 1024);
printf("ctime: %i\n", config.cache_item_timeout);
printf("ctimecheck: %i\n", config.cache_item_timeout_check);
printf("-OK-\n");
}
else if ((!strcmp(argv[i], "setconfig")) && (i < (argc - 3)))
{
Op_Setconfig config;
i++;
config.cache_max_usage = atoi(argv[i]) * 1024;
i++;
config.cache_item_timeout = atoi(argv[i]);
i++;
config.cache_item_timeout_check = atoi(argv[i]);
if (!evas_cserve_config_set(&config))
{
printf("ERROR: cannot set config.\n");
exit(-1);
}
}
else if ((!strcmp(argv[i], "getstats")))
{
Op_Getstats_Reply stats;
if (!evas_cserve_stats_get(&stats))
{
printf("ERROR: cannot fetch stats.\n");
exit(-1);
}
printf("saved_memory: %i Kb\n", stats.saved_memory / 1024);
printf("wasted_memory: %i Kb\n", stats.wasted_memory / 1024);
printf("saved_memory_peak: %i Kb\n", stats.saved_memory_peak / 1024);
printf("wasted_memory_peak: %i Kb\n", stats.wasted_memory_peak / 1024);
printf("saved_time_image_header_load: %1.3f sec\n", stats.saved_time_image_header_load);
printf("saved_time_image_data_load: %1.3f sec\n", stats.saved_time_image_data_load);
printf("-OK-\n");
}
}
/*
{
Image_Entry *ie;
RGBA_Image_Loadopts lopt = { 0, 0.0, 0, 0};
ie = malloc(sizeof(Image_Entry));
if (evas_cserve_image_load(ie, argv[1], NULL, &lopt))
{
printf("load ok\n");
if (evas_cserve_image_data_load(ie))
{
Mem *m;
m = ie->data2;
printf("first pixel: %08x\n", *((int *)m->data));
printf("load data ok\n");
// evas_cserve_image_free(ie);
}
}
}
*/
evas_cserve_shutdown();
evas_shutdown();
return 0;
}

View File

@ -92,35 +92,6 @@ struct _Mem
};
//// for comms
// for clients to connect to cserve
EAPI Eina_Bool evas_cserve_init(void);
EAPI int evas_cserve_use_get(void);
EAPI void evas_cserve_shutdown(void);
EAPI Eina_Bool evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt);
EAPI Eina_Bool evas_cserve_image_data_load(Image_Entry *ie);
EAPI void evas_cserve_image_free(Image_Entry *ie);
// for the server
EAPI Server *evas_cserve_server_add(void);
EAPI void evas_cserve_server_del(Server *s);
EAPI void evas_cserve_client_send(Client *c, int opcode, int size, unsigned char *data);
EAPI void evas_cserve_server_message_handler_set(Server *s, int (*func) (void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *data), void *data);
EAPI void evas_cserve_server_wait(Server *s, int timeout);
//// for memory
// for server
EAPI Mem *evas_cserve_mem_new(int size, const char *name);
EAPI void evas_cserve_mem_free(Mem *m);
// for client
EAPI Mem *evas_cserve_mem_open(int pid, int id, const char *name, int size, int write);
EAPI void evas_cserve_mem_close(Mem *m);
// for both
EAPI Eina_Bool evas_cserve_mem_resize(Mem *m, int size);
EAPI void evas_cserve_mem_del(int pid, int id);
enum
{
OP_NOP, // 0
@ -132,6 +103,11 @@ enum
OP_PRELOAD, // 5
OP_FORCEDUNLOAD, // 6
OP_GETCONFIG, // 7
OP_SETCONFIG, // 8
OP_GETSTATS, // 9
OP_GETINFO, // 10
OP_INVALID // 6
};
@ -193,6 +169,59 @@ typedef struct
{
void *handle;
} Op_Forcedunload;
typedef struct
{
int cache_max_usage;
int cache_item_timeout;
int cache_item_timeout_check;
} Op_Getconfig_Reply;
typedef struct
{
int cache_max_usage;
int cache_item_timeout;
int cache_item_timeout_check;
} Op_Setconfig;
typedef struct
{
int saved_memory;
int wasted_memory;
int saved_memory_peak;
int wasted_memory_peak;
double saved_time_image_header_load;
double saved_time_image_data_load;
} Op_Getstats_Reply;
// for clients to connect to cserve
EAPI Eina_Bool evas_cserve_init(void);
EAPI int evas_cserve_use_get(void);
EAPI void evas_cserve_shutdown(void);
EAPI Eina_Bool evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt);
EAPI Eina_Bool evas_cserve_image_data_load(Image_Entry *ie);
EAPI void evas_cserve_image_free(Image_Entry *ie);
EAPI Eina_Bool evas_cserve_config_get(Op_Getconfig_Reply *config);
EAPI Eina_Bool evas_cserve_config_set(Op_Setconfig *config);
EAPI Eina_Bool evas_cserve_stats_get(Op_Getstats_Reply *stats);
// for the server
EAPI Server *evas_cserve_server_add(void);
EAPI void evas_cserve_server_del(Server *s);
EAPI void evas_cserve_client_send(Client *c, int opcode, int size, unsigned char *data);
EAPI void evas_cserve_server_message_handler_set(Server *s, int (*func) (void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *data), void *data);
EAPI void evas_cserve_server_wait(Server *s, int timeout);
//// for memory
// for server
EAPI Mem *evas_cserve_mem_new(int size, const char *name);
EAPI void evas_cserve_mem_free(Mem *m);
// for client
EAPI Mem *evas_cserve_mem_open(int pid, int id, const char *name, int size, int write);
EAPI void evas_cserve_mem_close(Mem *m);
// for both
EAPI Eina_Bool evas_cserve_mem_resize(Mem *m, int size);
EAPI void evas_cserve_mem_del(int pid, int id);
#endif

View File

@ -194,7 +194,7 @@ evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_
Op_Load msg;
Op_Load_Reply *rep;
unsigned char *buf;
char fbuf[PATH_MAX], wd[PATH_MAX];
char fbuf[PATH_MAX], wdb[PATH_MAX];
int flen, klen;
int opcode;
int size;
@ -210,13 +210,13 @@ evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_
msg.lopt.h = lopt->h;
if (file[0] != '/')
{
if (getcwd(wd, sizeof(wd)))
if (getcwd(wdb, sizeof(wdb)))
{
snprintf(fbuf, "%s/%s", wd, file);
snprintf(fbuf, sizeof(buf), "%s/%s", wdb, file);
file = fbuf;
}
}
if (!realpath(file, wd)) file = wd;
if (!realpath(file, wdb)) file = wdb;
flen = strlen(file) + 1;
klen = strlen(key) + 1;
buf = malloc(sizeof(msg) + flen + klen);
@ -288,4 +288,52 @@ evas_cserve_image_free(Image_Entry *ie)
ie->data1 = NULL;
}
EAPI Eina_Bool
evas_cserve_config_get(Op_Getconfig_Reply *config)
{
Op_Getconfig_Reply *rep;
int opcode;
int size;
if (csrve_init > 0) server_reinit();
else return 0;
if (!cserve) return 0;
if (!server_send(cserve, OP_GETCONFIG, 0, NULL)) return 0;
rep = (Op_Getconfig_Reply *)server_read(cserve, &opcode, &size);
if ((rep) && (opcode == OP_GETCONFIG) && (size == sizeof(Op_Getconfig_Reply)))
{
memcpy(config, rep, sizeof(Op_Getconfig_Reply));
return 1;
}
return 0;
}
EAPI Eina_Bool
evas_cserve_config_set(Op_Setconfig *config)
{
if (csrve_init > 0) server_reinit();
else return 0;
if (!cserve) return 0;
if (!server_send(cserve, OP_SETCONFIG, sizeof(Op_Setconfig), (unsigned char *)config)) return 0;
return 1;
}
EAPI Eina_Bool
evas_cserve_stats_get(Op_Getstats_Reply *stats)
{
Op_Getstats_Reply *rep;
int opcode;
int size;
if (csrve_init > 0) server_reinit();
else return 0;
if (!cserve) return 0;
if (!server_send(cserve, OP_GETSTATS, 0, NULL)) return 0;
rep = (Op_Getstats_Reply *)server_read(cserve, &opcode, &size);
if ((rep) && (opcode == OP_GETSTATS) && (size == sizeof(Op_Getstats_Reply)))
{
memcpy(stats, rep, sizeof(Op_Getstats_Reply));
return 1;
}
return 0;
}
#endif