diff --git a/src/lib/eina/eina_debug_chunk.c b/src/lib/eina/eina_debug_chunk.c index 1c6c028647..58b6e9bf7c 100644 --- a/src/lib/eina/eina_debug_chunk.c +++ b/src/lib/eina/eina_debug_chunk.c @@ -54,6 +54,8 @@ static int chunk2_num = 0; static int chunk3_size = 0; static int chunk3_num = 0; +static int no_anon = -1; + // get a new chunk of "anonymous mmaped memory" static void * _eina_debug_chunk_need(int size) @@ -65,9 +67,18 @@ _eina_debug_chunk_need(int size) else #endif { - ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) return NULL; + if (no_anon == -1) + { + if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1; + else no_anon = 0; + } + if (no_anon == 1) ptr = malloc(size); + else + { + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) return NULL; + } } return ptr; } @@ -80,7 +91,10 @@ _eina_debug_chunk_noneed(void *ptr, int size) if (RUNNING_ON_VALGRIND) free(ptr); else #endif - munmap(ptr, size); + { + if (no_anon == 1) free(ptr); + else munmap(ptr, size); + } } // push a new bit of mem on our growing stack of mem - given our workload, diff --git a/src/lib/eina/eina_evlog.c b/src/lib/eina/eina_evlog.c index c0fe64fe22..b9081876ce 100644 --- a/src/lib/eina/eina_evlog.c +++ b/src/lib/eina/eina_evlog.c @@ -94,6 +94,8 @@ get_time(void) #endif } +static int no_anon = -1; + static void alloc_buf(Eina_Evlog_Buf *b, unsigned int size) { @@ -106,9 +108,18 @@ alloc_buf(Eina_Evlog_Buf *b, unsigned int size) else # endif { - b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (b->buf == MAP_FAILED) b->buf = NULL; + if (no_anon == -1) + { + if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1; + else no_anon = 0; + } + if (no_anon == 1) b->buf = malloc(size); + else + { + b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (b->buf == MAP_FAILED) b->buf = NULL; + } } #else b->buf = malloc(size); @@ -125,7 +136,10 @@ free_buf(Eina_Evlog_Buf *b) if (RUNNING_ON_VALGRIND) free(b->buf); else # endif - munmap(b->buf, b->size); + { + if (no_anon == 1) free(b->buf); + else munmap(b->buf, b->size); + } #else free(b->buf); #endif diff --git a/src/lib/eina/eina_safepointer.c b/src/lib/eina/eina_safepointer.c index fc88b6c63e..dd832b68d6 100644 --- a/src/lib/eina/eina_safepointer.c +++ b/src/lib/eina/eina_safepointer.c @@ -72,6 +72,8 @@ static Eina_Spinlock sl; #define MEM_PAGE_SIZE 4096 #define SAFEPOINTER_MAGIC 0x7DEADC03 +static int no_anon = -1; + static void * _eina_safepointer_calloc(int number, size_t size) { @@ -89,12 +91,21 @@ _eina_safepointer_calloc(int number, size_t size) (size % MEM_PAGE_SIZE ? 1 : 0)) * MEM_PAGE_SIZE; - header = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (header == MAP_FAILED) + if (no_anon == -1) { - ERR("mmap of Eina_Safepointer table region failed."); - return NULL; + if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1; + else no_anon = 0; + } + if (no_anon == 1) header = calloc(number, size); + else + { + header = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (header == MAP_FAILED) + { + ERR("mmap of Eina_Safepointer table region failed."); + return NULL; + } } header->size = newsize; @@ -120,12 +131,15 @@ _eina_safepointer_free(void *pointer) if (!pointer) return; - header = (Eina_Memory_Header*)(pointer) - 1; - if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) - EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); - - EINA_MAGIC_SET(header, 0); - munmap(header, header->size); + if (no_anon == 1) free((void *)((uintptr_t) pointer & ~0x3)); + else + { + header = (Eina_Memory_Header*)(pointer) - 1; + if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) + EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); + EINA_MAGIC_SET(header, 0); + munmap(header, header->size); + } } #else free((void *)((uintptr_t) pointer & ~0x3)); diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index b7f10faad8..f96972d79b 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1488,6 +1488,8 @@ eo_class_free(_Efl_Class *klass) eina_freeq_ptr_main_add(klass, free, 0); } +int _eo_no_anon = -1; + static inline void _eo_classes_release(void) { @@ -1497,10 +1499,14 @@ _eo_classes_release(void) else # endif { - size_t size; + if (_eo_no_anon == 1) free(_eo_classes); + else + { + size_t size; - size = _eo_classes_alloc * sizeof(_Efl_Class *); - if (_eo_classes) munmap(_eo_classes, size); + size = _eo_classes_alloc * sizeof(_Efl_Class *); + if (_eo_classes) munmap(_eo_classes, size); + } } #else free(_eo_classes); @@ -1535,17 +1541,36 @@ _eo_classes_expand(void) else # endif { - _eo_classes_alloc += (MEM_PAGE_SIZE / sizeof(_Efl_Class *)); - newsize = _eo_classes_alloc * sizeof(_Efl_Class *); - ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) + if (_eo_no_anon == -1) { - ERR("mmap of eo class table region failed!"); - abort(); + if (getenv("EFL_NO_MMAP_ANON")) _eo_no_anon = 1; + else _eo_no_anon = 0; + } + if (_eo_no_anon == 1) + { + _eo_classes_alloc += 128; + newsize = _eo_classes_alloc * sizeof(_Efl_Class *); + ptr = realloc(_eo_classes, newsize); + if (!ptr) + { + ERR("realloc of eo class table region faile!!"); + abort(); + } + } + else + { + _eo_classes_alloc += (MEM_PAGE_SIZE / sizeof(_Efl_Class *)); + newsize = _eo_classes_alloc * sizeof(_Efl_Class *); + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("mmap of eo class table region failed!"); + abort(); + } + if (psize > 0) memcpy(ptr, _eo_classes, psize); + if (_eo_classes) munmap(_eo_classes, psize); } - if (psize > 0) memcpy(ptr, _eo_classes, psize); - if (_eo_classes) munmap(_eo_classes, psize); } #else _eo_classes_alloc += 128; diff --git a/src/lib/eo/eo_add_fallback.c b/src/lib/eo/eo_add_fallback.c index f349b336b4..32a736a02a 100644 --- a/src/lib/eo/eo_add_fallback.c +++ b/src/lib/eo/eo_add_fallback.c @@ -42,20 +42,29 @@ _eo_call_stack_mem_alloc(size_t size) else # endif { - // allocate eo call stack via mmped anon segment if on linux - more - // secure and safe. also gives page aligned memory allowing madvise - void *ptr; - size_t newsize; - newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) / - MEM_PAGE_SIZE); - ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) + if (_eo_no_anon == -1) { - ERR("eo call stack mmap failed."); - return NULL; + if (getenv("EFL_NO_MMAP_ANON")) _eo_no_anon = 1; + else _eo_no_anon = 0; + } + if (_eo_no_anon == 1) return calloc(1, size); + else + { + // allocate eo call stack via mmped anon segment if on linux - more + // secure and safe. also gives page aligned memory allowing madvise + void *ptr; + size_t newsize; + newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) / + MEM_PAGE_SIZE); + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("eo call stack mmap failed."); + return NULL; + } + return ptr; } - return ptr; } #else //in regular cases just use malloc @@ -71,7 +80,10 @@ _eo_call_stack_mem_free(void *ptr, size_t size) if (RUNNING_ON_VALGRIND) free(ptr); else # endif - munmap(ptr, size); + { + if (_eo_no_anon == 1) free(ptr); + else munmap(ptr, size); + } #else (void) size; free(ptr); diff --git a/src/lib/eo/eo_ptr_indirection.x b/src/lib/eo/eo_ptr_indirection.x index f0f34e0bc6..fc50c42096 100644 --- a/src/lib/eo/eo_ptr_indirection.x +++ b/src/lib/eo/eo_ptr_indirection.x @@ -153,6 +153,8 @@ typedef struct _Mem_Header size_t magic; } Mem_Header; +extern int _eo_no_anon; + static void * _eo_id_mem_alloc(size_t size) { @@ -162,23 +164,32 @@ _eo_id_mem_alloc(size_t size) else # endif { - 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_ANON, -1, 0); - if (ptr == MAP_FAILED) + if (_eo_no_anon == -1) { - ERR("mmap of eo id table region failed!"); - return NULL; + if (getenv("EFL_NO_MMAP_ANON")) _eo_no_anon = 1; + else _eo_no_anon = 0; + } + if (_eo_no_anon == 1) return malloc(size); + else + { + 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_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("mmap of eo id table region failed!"); + return NULL; + } + hdr = ptr; + hdr->size = newsize; + hdr->magic = MEM_MAGIC; + /* DBG("asked:%lu allocated:%lu wasted:%lu bytes", size, newsize, (newsize - size)); */ + return (void *)(((unsigned char *)ptr) + MEM_HEADER_SIZE); } - hdr = ptr; - hdr->size = newsize; - hdr->magic = MEM_MAGIC; - /* DBG("asked:%lu allocated:%lu wasted:%lu bytes", size, newsize, (newsize - size)); */ - return (void *)(((unsigned char *)ptr) + MEM_HEADER_SIZE); } #else return malloc(size); @@ -203,15 +214,19 @@ _eo_id_mem_free(void *ptr) else # endif { - Mem_Header *hdr; - if (!ptr) return; - hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE); - if (hdr->magic != MEM_MAGIC) + if (_eo_no_anon == 1) free(ptr); + else { - ERR("unmap of eo table region has bad magic!"); - return; + 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); } - munmap(hdr, hdr->size); } #else free(ptr); diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index a94be359e3..6d3e09fd84 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -103,10 +103,14 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, if (EINA_UNLIKELY(evas_image_no_mmap == -1)) { - const char *s = getenv("EVAS_IMAGE_NO_MMAP"); - evas_image_no_mmap = s && (atoi(s)); - if (evas_image_no_mmap) - WRN("EVAS_IMAGE_NO_MMAP is set, use this only for debugging!"); + if (getenv("EFL_NO_MMAP_ANON")) evas_image_no_mmap = 1; + else + { + const char *s = getenv("EVAS_IMAGE_NO_MMAP"); + evas_image_no_mmap = s && (atoi(s)); + if (evas_image_no_mmap) + WRN("EVAS_IMAGE_NO_MMAP is set, use this only for debugging!"); + } } switch (cspace)