aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2016-11-19 12:17:23 +0200
committerEli Zaretskii2016-11-19 12:17:23 +0200
commit4cdd14eabe5a6121691daa2d9c5e814c5f53f3e5 (patch)
treed6c342da22c57db99b6a6b65f15ed6e29b23e22f
parent6cdd1c333034b308e74e70c4fd10399fbb5329b9 (diff)
downloademacs-4cdd14eabe5a6121691daa2d9c5e814c5f53f3e5.tar.gz
emacs-4cdd14eabe5a6121691daa2d9c5e814c5f53f3e5.zip
Implement getrlimit and setrlimit for MS-Windows
* src/w32heap.c (getrlimit, setrlimit): New functions. Include w32.h. * src/emacs.c (main): Use 'rlim_t', not 'long', for values that should be compatible with 'struct rlimit' members. * nt/inc/sys/resource.h: New header file. * nt/mingw-cfg.site (ac_cv_func_getrlimit, ac_cv_func_setrlimit): Set to "yes".
-rw-r--r--nt/inc/sys/resource.h51
-rw-r--r--nt/mingw-cfg.site2
-rw-r--r--src/emacs.c4
-rw-r--r--src/w32heap.c85
4 files changed, 139 insertions, 3 deletions
diff --git a/nt/inc/sys/resource.h b/nt/inc/sys/resource.h
new file mode 100644
index 00000000000..dfa0318cb40
--- /dev/null
+++ b/nt/inc/sys/resource.h
@@ -0,0 +1,51 @@
1/* A limited emulation of sys/resource.h.
2
3Copyright (C) 2016 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef INC_SYS_RESOURCE_H_
21#define INC_SYS_RESOURCE_H_
22
23/* We only support RLIMIT_STACK and RLIMIT_NOFILE for now. */
24enum rlimit_resource {
25 RLIMIT_STACK = 0,
26#define RLIMIT_STACK RLIMIT_STACK
27
28 RLIMIT_NOFILE = 1,
29#define RLIMIT_NOFILE RLIMIT_NOFILE
30
31 RLIMIT_NLIMITS
32#define RLIMIT_NLIMITS RLIMIT_NLIMITS
33};
34
35typedef enum rlimit_resource rlimit_resource_t;
36
37/* We use a 64-bit data type because some values could potentially be
38 64-bit wide even in 32-bit builds. */
39typedef long long rlim_t;
40
41#define RLIMIT_INFINITY ((rlim_t) -1)
42
43struct rlimit {
44 rlim_t rlim_cur; /* current soft limit */
45 rlim_t rlim_max; /* hard limit */
46};
47
48extern int getrlimit (rlimit_resource_t, struct rlimit *);
49extern int setrlimit (rlimit_resource_t, const struct rlimit *);
50
51#endif /* INC_SYS_RESOURCE_H_ */
diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site
index 3e0cd40915c..a1067179797 100644
--- a/nt/mingw-cfg.site
+++ b/nt/mingw-cfg.site
@@ -131,5 +131,7 @@ ac_cv_func_random=yes
131gl_cv_func_svid_putenv=yes 131gl_cv_func_svid_putenv=yes
132# Implemented in w32heap.c 132# Implemented in w32heap.c
133ac_cv_func_sbrk=yes 133ac_cv_func_sbrk=yes
134ac_cv_func_getrlimit=yes
135ac_cv_func_setrlimit=yes
134# GCC warnings that produce too much noise 136# GCC warnings that produce too much noise
135gl_cv_warn_c__Wredundant_decls=no 137gl_cv_warn_c__Wredundant_decls=no
diff --git a/src/emacs.c b/src/emacs.c
index 92cbb086339..d86c34fd1fd 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -829,7 +829,7 @@ main (int argc, char **argv)
829 if (getrlimit (RLIMIT_STACK, &rlim) == 0 829 if (getrlimit (RLIMIT_STACK, &rlim) == 0
830 && 0 <= rlim.rlim_cur && rlim.rlim_cur <= LONG_MAX) 830 && 0 <= rlim.rlim_cur && rlim.rlim_cur <= LONG_MAX)
831 { 831 {
832 long lim = rlim.rlim_cur; 832 rlim_t lim = rlim.rlim_cur;
833 833
834 /* Approximate the amount regex.c needs per unit of 834 /* Approximate the amount regex.c needs per unit of
835 re_max_failures, then add 33% to cover the size of the 835 re_max_failures, then add 33% to cover the size of the
@@ -848,7 +848,7 @@ main (int argc, char **argv)
848 848
849 if (try_to_grow_stack) 849 if (try_to_grow_stack)
850 { 850 {
851 long newlim = re_max_failures * ratio + extra; 851 rlim_t newlim = re_max_failures * ratio + extra;
852 852
853 /* Round the new limit to a page boundary; this is needed 853 /* Round the new limit to a page boundary; this is needed
854 for Darwin kernel 15.4.0 (see Bug#23622) and perhaps 854 for Darwin kernel 15.4.0 (see Bug#23622) and perhaps
diff --git a/src/w32heap.c b/src/w32heap.c
index 43b5f352a1d..26a04413df1 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -50,9 +50,11 @@
50#include <errno.h> 50#include <errno.h>
51 51
52#include <sys/mman.h> 52#include <sys/mman.h>
53#include <sys/resource.h>
53#include "w32common.h" 54#include "w32common.h"
54#include "w32heap.h" 55#include "w32heap.h"
55#include "lisp.h" 56#include "lisp.h"
57#include "w32.h" /* for FD_SETSIZE */
56 58
57/* We chose to leave those declarations here. They are used only in 59/* We chose to leave those declarations here. They are used only in
58 this file. The RtlCreateHeap is available since XP. It is located 60 this file. The RtlCreateHeap is available since XP. It is located
@@ -317,6 +319,9 @@ init_heap (void)
317 cache_system_info (); 319 cache_system_info ();
318} 320}
319 321
322
323/* malloc, realloc, free. */
324
320#undef malloc 325#undef malloc
321#undef realloc 326#undef realloc
322#undef free 327#undef free
@@ -623,9 +628,12 @@ sbrk (ptrdiff_t increment)
623 return data_region_end; 628 return data_region_end;
624} 629}
625 630
626#define MAX_BUFFER_SIZE (512 * 1024 * 1024) 631
627 632
628/* MMAP allocation for buffers. */ 633/* MMAP allocation for buffers. */
634
635#define MAX_BUFFER_SIZE (512 * 1024 * 1024)
636
629void * 637void *
630mmap_alloc (void **var, size_t nbytes) 638mmap_alloc (void **var, size_t nbytes)
631{ 639{
@@ -788,3 +796,78 @@ mmap_realloc (void **var, size_t nbytes)
788 /* Not enlarging, not shrinking by more than one page. */ 796 /* Not enlarging, not shrinking by more than one page. */
789 return *var; 797 return *var;
790} 798}
799
800
801/* Emulation of getrlimit and setrlimit. */
802
803int
804getrlimit (rlimit_resource_t rltype, struct rlimit *rlp)
805{
806 int retval = -1;
807
808 switch (rltype)
809 {
810 case RLIMIT_STACK:
811 {
812 MEMORY_BASIC_INFORMATION m;
813 /* Implementation note: Posix says that RLIMIT_STACK returns
814 information about the stack size for the main thread. The
815 implementation below returns the stack size for the calling
816 thread, so it's more like pthread_attr_getstacksize. But
817 Emacs clearly wants the latter, given how it uses the
818 results, so the implementation below is more future-proof,
819 if what's now the main thread will become some other thread
820 at some future point. */
821 if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
822 errno = EPERM;
823 else
824 {
825 rlp->rlim_cur = (DWORD_PTR) &m - (DWORD_PTR) m.AllocationBase;
826 rlp->rlim_max =
827 (DWORD_PTR) m.BaseAddress + m.RegionSize
828 - (DWORD_PTR) m.AllocationBase;
829
830 /* The last page is the guard page, so subtract that. */
831 rlp->rlim_cur -= getpagesize ();
832 rlp->rlim_max -= getpagesize ();
833 retval = 0;
834 }
835 }
836 break;
837 case RLIMIT_NOFILE:
838 /* Implementation note: The real value is returned by
839 _getmaxstdio. But our FD_SETSIZE is smaller, to cater to
840 Windows 9X, and process.c includes some logic that's based on
841 the assumption that the handle resource is inherited to child
842 processes. We want to avoid that logic, so we tell process.c
843 our current limit is already equal to FD_SETSIZE. */
844 rlp->rlim_cur = FD_SETSIZE;
845 rlp->rlim_max = 2048; /* see _setmaxstdio documentation */
846 retval = 0;
847 break;
848 default:
849 /* Note: we could return meaningful results for other RLIMIT_*
850 requests, but Emacs doesn't currently need that, so we just
851 punt for them. */
852 errno = ENOSYS;
853 break;
854 }
855 return retval;
856}
857
858int
859setrlimit (rlimit_resource_t rltype, const struct rlimit *rlp)
860{
861 switch (rltype)
862 {
863 case RLIMIT_STACK:
864 case RLIMIT_NOFILE:
865 /* We cannot modfy these limits, so we always fail. */
866 errno = EPERM;
867 break;
868 default:
869 errno = ENOSYS;
870 break;
871 }
872 return -1;
873}