aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-04-23 23:38:44 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-04-23 23:39:37 +0900
commit4cf68bf728b5a858ce1c0efac25ded1a49ba8d9d (patch)
tree32f0e72c75b9885eb6d0ecfc7088aeaca984db03
parenteoid -> rjid 64bit bit allocations for.. not so much bloat. (diff)
downloadefl-4cf68bf728b5a858ce1c0efac25ded1a49ba8d9d.tar.gz
eoid -> use mmap for allocating id tables. makes it a separate memory
regions with page separations... this allows us more direct control over access and visibility.
-rw-r--r--src/lib/eo/eo_ptr_indirection.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/lib/eo/eo_ptr_indirection.c b/src/lib/eo/eo_ptr_indirection.c
index 19ca52b95e..19dc17b094 100644
--- a/src/lib/eo/eo_ptr_indirection.c
+++ b/src/lib/eo/eo_ptr_indirection.c
@@ -3,6 +3,12 @@
#endif
#include "eo_ptr_indirection.h"
+#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#endif
/* Start of pointer indirection:
*
@@ -74,6 +80,68 @@ typedef uintptr_t Table_Index;
#define MAX_IDS_PER_TABLE (1 << BITS_FOR_ID_IN_TABLE)
#define MAX_GENERATIONS (1 << BITS_FOR_GENERATION_COUNTER)
+#define MEM_HEADER_SIZE 16
+#define MEM_PAGE_SIZE 4096
+#define MEM_MAGIC 0x3f61ec8a
+
+typedef struct _Mem_Header
+{
+ size_t size;
+ size_t magic;
+} Mem_Header;
+
+static void *
+_eo_id_mem_alloc(size_t size)
+{
+#ifdef __linux__
+ void *ptr;
+ Mem_Header *hdr;
+ size_t newsize;
+ newsize = MEM_PAGE_SIZE * ((size + MEM_HEADER_SIZE + MEM_PAGE_SIZE - 1) /
+ MEM_PAGE_SIZE);
+ ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (ptr == MAP_FAILED)
+ {
+ ERR("mmap of eo id table region failed!");
+ return NULL;
+ }
+ hdr = ptr;
+ hdr->size = size;
+ hdr->magic = MEM_MAGIC;
+ return (void *)(((unsigned char *)ptr) + MEM_HEADER_SIZE);
+#else
+ return malloc(size);
+#endif
+}
+
+static void *
+_eo_id_mem_calloc(size_t num, size_t size)
+{
+ void *ptr = _eo_id_mem_alloc(num * size);
+ if (!ptr) return NULL;
+ memset(ptr, 0, num * size);
+ return ptr;
+}
+
+static void
+_eo_id_mem_free(void *ptr)
+{
+#ifdef __linux__
+ Mem_Header *hdr;
+ if (!ptr) return;
+ hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE);
+ if (hdr->magic != MEM_MAGIC)
+ {
+ ERR("unmap of eo table region has bad magic!");
+ return;
+ }
+ munmap(hdr, hdr->size);
+#else
+ free(ptr);
+#endif
+}
+
/* Table */
typedef struct
{
@@ -158,7 +226,7 @@ _eo_id_allocate(const _Eo *obj)
if (!_eo_ids_tables[table_id])
{
/* We allocate a new table */
- _eo_ids_tables[table_id] = calloc(MAX_IDS_INTER_TABLES, sizeof(_Eo_Ids_Table*));
+ _eo_ids_tables[table_id] = _eo_id_mem_calloc(MAX_IDS_INTER_TABLES, sizeof(_Eo_Ids_Table*));
}
for (Table_Index int_table_id = 0; int_table_id < MAX_IDS_INTER_TABLES; int_table_id++)
{
@@ -166,7 +234,7 @@ _eo_id_allocate(const _Eo *obj)
if (!ID_TABLE)
{
/* We allocate a new intermediate table */
- ID_TABLE = calloc(1, sizeof(_Eo_Ids_Table));
+ ID_TABLE = _eo_id_mem_calloc(1, sizeof(_Eo_Ids_Table));
eina_trash_init(&(ID_TABLE->queue));
/* We select directly the first entry of the new table */
ptr = &(ID_TABLE->ptrs[0]);
@@ -242,10 +310,10 @@ _eo_free_ids_tables()
{
if (ID_TABLE)
{
- free(ID_TABLE);
+ _eo_id_mem_free(ID_TABLE);
}
}
- free(_eo_ids_tables[table_id]);
+ _eo_id_mem_free(_eo_ids_tables[table_id]);
}
_eo_ids_tables[table_id] = NULL;
}