eina: always put map in memory when requested and use HUGETLB when available.

SVN revision: 59366
This commit is contained in:
Cedric BAIL 2011-05-13 10:44:29 +00:00
parent 8315f9879c
commit 31e53c82bf
1 changed files with 50 additions and 11 deletions

View File

@ -92,6 +92,9 @@ void *alloca (size_t);
#endif #endif
#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__) #define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
#define EINA_SMALL_PAGE 4096
# define EINA_HUGE_PAGE 16 * 1024 * 1024
typedef struct _Eina_File_Iterator Eina_File_Iterator; typedef struct _Eina_File_Iterator Eina_File_Iterator;
typedef struct _Eina_File_Map Eina_File_Map; typedef struct _Eina_File_Map Eina_File_Map;
@ -113,7 +116,7 @@ struct _Eina_File
Eina_Hash *rmap; Eina_Hash *rmap;
void *global_map; void *global_map;
unsigned long length; unsigned long long length;
time_t mtime; time_t mtime;
int refcount; int refcount;
@ -416,22 +419,51 @@ _eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__)
^ eina_hash_int64(&key[1], sizeof (unsigned long int)); ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
} }
static void #ifndef MAP_POPULATE
static int
_eina_file_map_populate(char *map, unsigned int size)
{
int r = 0xDEADBEEF;
int i;
int s;
#ifdef MAP_HUGETLB
s = size > EINA_HUGE_PAGE ? EINA_HUGE_PAGE : EINA_SMALL_PAGE;
#else
s = EINA_SMALL_PAGE;
#endif
for (i = 0; i < size; i += s)
r ^= map[i];
r ^= map[size];
return r;
}
#endif
static int
_eina_file_map_rule_apply(Eina_File_Populate rule, void *addr, unsigned long int size) _eina_file_map_rule_apply(Eina_File_Populate rule, void *addr, unsigned long int size)
{ {
int flag; int tmp = 42;
int flag = MADV_RANDOM;
switch (rule) switch (rule)
{ {
case EINA_FILE_RANDOM: flag = MADV_RANDOM; break; case EINA_FILE_RANDOM: flag = MADV_RANDOM; break;
case EINA_FILE_SEQUENTIAL: flag = MADV_SEQUENTIAL; break; case EINA_FILE_SEQUENTIAL: flag = MADV_SEQUENTIAL; break;
case EINA_FILE_WILLNEED: case EINA_FILE_POPULATE: flag = MADV_WILLNEED; break;
case EINA_FILE_POPULATE: case EINA_FILE_WILLNEED: flag = MADV_WILLNEED; break;
flag = MADV_WILLNEED;
break;
} }
madvise(addr, size, flag); madvise(addr, size, flag);
#ifndef MAP_POPULATE
if (rule == EINA_FILE_POPULATE)
tmp ^= _eina_file_map_populate(addr, size);
#endif
return tmp;
} }
Eina_Bool Eina_Bool
@ -738,7 +770,7 @@ eina_file_open(const char *filename, Eina_Bool shared)
file = eina_hash_find(_eina_file_cache, filename); file = eina_hash_find(_eina_file_cache, filename);
if (file && (file->mtime != file_stat.st_mtime if (file && (file->mtime != file_stat.st_mtime
|| file->length != file_stat.st_size)) || file->length != (unsigned long long) file_stat.st_size))
{ {
create = EINA_TRUE; create = EINA_TRUE;
@ -839,10 +871,13 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
int flags = MAP_SHARED; int flags = MAP_SHARED;
// bsd people will lack this feature // bsd people will lack this feature
#ifdef MAP_POPULATE #ifdef MAP_POPULATE
if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE; if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
#endif #endif
#ifdef MAP_HUGETLB
if (file->length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB;
#endif
if (file->global_map == MAP_FAILED) if (file->global_map == MAP_FAILED)
file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0); file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0);
@ -879,9 +914,13 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
int flags = MAP_SHARED; int flags = MAP_SHARED;
// bsd people will lack this feature // bsd people will lack this feature
#ifdef MAP_POPULATE #ifdef MAP_POPULATE
if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE; if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
#endif #endif
#ifdef MAP_HUGETLB
if (length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB;
#endif
map = malloc(sizeof (Eina_File_Map)); map = malloc(sizeof (Eina_File_Map));
if (!map) return NULL; if (!map) return NULL;