diff options
Diffstat (limited to 'src/w32heap.c')
-rw-r--r-- | src/w32heap.c | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/src/w32heap.c b/src/w32heap.c index a59162aee08..54de9617494 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -50,9 +50,11 @@ #include <errno.h> #include <sys/mman.h> +#include <sys/resource.h> #include "w32common.h" #include "w32heap.h" #include "lisp.h" +#include "w32.h" /* for FD_SETSIZE */ /* We chose to leave those declarations here. They are used only in this file. The RtlCreateHeap is available since XP. It is located @@ -114,7 +116,7 @@ typedef struct _RTL_HEAP_PARAMETERS { to build only the first bootstrap-emacs.exe with the large size, and reset that to a lower value afterwards. */ #if defined _WIN64 || defined WIDE_EMACS_INT -# define DUMPED_HEAP_SIZE (20*1024*1024) +# define DUMPED_HEAP_SIZE (21*1024*1024) #else # define DUMPED_HEAP_SIZE (12*1024*1024) #endif @@ -189,7 +191,7 @@ free_fn the_free_fn; claims for new memory. Before dumping, we allocate space from the fixed size dumped_data[] array. */ -NTSTATUS NTAPI +static NTSTATUS NTAPI dumped_data_commit (PVOID Base, PVOID *CommitAddress, PSIZE_T CommitSize) { /* This is used before dumping. @@ -317,15 +319,18 @@ init_heap (void) cache_system_info (); } + +/* malloc, realloc, free. */ + #undef malloc #undef realloc #undef free /* FREEABLE_P checks if the block can be safely freed. */ #define FREEABLE_P(addr) \ - ((unsigned char *)(addr) > 0 \ - && ((unsigned char *)(addr) < dumped_data \ - || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE)) + ((DWORD_PTR)(unsigned char *)(addr) > 0 \ + && ((unsigned char *)(addr) < dumped_data \ + || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE)) void * malloc_after_dump (size_t size) @@ -623,9 +628,12 @@ sbrk (ptrdiff_t increment) return data_region_end; } -#define MAX_BUFFER_SIZE (512 * 1024 * 1024) + /* MMAP allocation for buffers. */ + +#define MAX_BUFFER_SIZE (512 * 1024 * 1024) + void * mmap_alloc (void **var, size_t nbytes) { @@ -708,7 +716,7 @@ mmap_realloc (void **var, size_t nbytes) if (memInfo.RegionSize < nbytes) { memset (&m2, 0, sizeof (m2)); - if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0) + if (VirtualQuery ((char *)*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0) DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ())); /* If there is enough room in the current reserved area, then @@ -778,7 +786,7 @@ mmap_realloc (void **var, size_t nbytes) } /* We still can decommit pages. */ - if (VirtualFree (*var + nbytes + get_page_size(), + if (VirtualFree ((char *)*var + nbytes + get_page_size(), memInfo.RegionSize - nbytes - get_page_size(), MEM_DECOMMIT) == 0) DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ())); @@ -788,3 +796,78 @@ mmap_realloc (void **var, size_t nbytes) /* Not enlarging, not shrinking by more than one page. */ return *var; } + + +/* Emulation of getrlimit and setrlimit. */ + +int +getrlimit (rlimit_resource_t rltype, struct rlimit *rlp) +{ + int retval = -1; + + switch (rltype) + { + case RLIMIT_STACK: + { + MEMORY_BASIC_INFORMATION m; + /* Implementation note: Posix says that RLIMIT_STACK returns + information about the stack size for the main thread. The + implementation below returns the stack size for the calling + thread, so it's more like pthread_attr_getstacksize. But + Emacs clearly wants the latter, given how it uses the + results, so the implementation below is more future-proof, + if what's now the main thread will become some other thread + at some future point. */ + if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m)) + errno = EPERM; + else + { + rlp->rlim_cur = (DWORD_PTR) &m - (DWORD_PTR) m.AllocationBase; + rlp->rlim_max = + (DWORD_PTR) m.BaseAddress + m.RegionSize + - (DWORD_PTR) m.AllocationBase; + + /* The last page is the guard page, so subtract that. */ + rlp->rlim_cur -= getpagesize (); + rlp->rlim_max -= getpagesize (); + retval = 0; + } + } + break; + case RLIMIT_NOFILE: + /* Implementation note: The real value is returned by + _getmaxstdio. But our FD_SETSIZE is smaller, to cater to + Windows 9X, and process.c includes some logic that's based on + the assumption that the handle resource is inherited to child + processes. We want to avoid that logic, so we tell process.c + our current limit is already equal to FD_SETSIZE. */ + rlp->rlim_cur = FD_SETSIZE; + rlp->rlim_max = 2048; /* see _setmaxstdio documentation */ + retval = 0; + break; + default: + /* Note: we could return meaningful results for other RLIMIT_* + requests, but Emacs doesn't currently need that, so we just + punt for them. */ + errno = ENOSYS; + break; + } + return retval; +} + +int +setrlimit (rlimit_resource_t rltype, const struct rlimit *rlp) +{ + switch (rltype) + { + case RLIMIT_STACK: + case RLIMIT_NOFILE: + /* We cannot modfy these limits, so we always fail. */ + errno = EPERM; + break; + default: + errno = ENOSYS; + break; + } + return -1; +} |